123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276 |
- #include "nx/nxdata.h"
- #include "foundation/atomics.h"
- #include "foundation/error.h"
- #include "nx/nxfile.h"
- #include <sys/stat.h>
- /* windows implementation */
- struct nx_data_struct_t
- {
- volatile size_t ref_count;
- nx_string_t mime_type;
- nx_string_t description;
- nx_uri_t source_uri;
- nx_file_stat_t source_stats;
- size_t len;
- uint8_t data[1];
- };
- static size_t NXDataMallocSize(size_t bytes)
- {
- /* TODO: overflow check? */
- const nx_data_t dummy=0;
- size_t header = (size_t)&dummy->data[0] - (size_t)dummy;
- return header + bytes;
- }
- nx_data_t NXDataRetain(nx_data_t data)
- {
- if (!data)
- return 0;
- nx_atomic_inc(&data->ref_count);
- return data;
- }
- void NXDataRelease(nx_data_t data)
- {
- if (data)
- {
- if (nx_atomic_dec(&data->ref_count) == 0)
- {
- free(data->source_stats);
- NXURIRelease(data->source_uri);
- NXStringRelease(data->mime_type);
- NXStringRelease(data->description);
- free(data);
- }
- }
- }
- int NXDataCreate(nx_data_t *out_data, const void *bytes, size_t length)
- {
- void *new_bytes;
- int ret = NXDataCreateWithSize(out_data, &new_bytes, length);
- if (ret != NErr_Success)
- return ret;
- memcpy(new_bytes, bytes, length);
- return NErr_Success;
- }
- int NXDataCreateWithSize(nx_data_t *out_data, void **bytes, size_t length)
- {
- nx_data_t data = 0;
- size_t data_length = NXDataMallocSize(length);
- data = (nx_data_t)malloc(data_length);
- if (!data)
- return NErr_OutOfMemory;
- data->ref_count = 1;
- data->len = length;
- data->mime_type=0;
- data->source_uri=0;
- data->source_stats=0;
- data->description=0;
- if (bytes)
- *bytes = data->data;
- *out_data=data;
- return NErr_Success;
- }
- int NXDataCreateEmpty(nx_data_t *out_data)
- {
- return NXDataCreateWithSize(out_data, 0, 0);
- }
- int NXDataCreateFromURI(nx_data_t *out_data, nx_uri_t filename)
- {
- nx_file_stat_s stat_buffer;
- nx_data_t data;
- size_t data_length;
- size_t bytes_read;
- uint64_t file_length;
- void *bytes;
- int ret;
- int fd;
- fd = NXFile_open(filename, nx_file_O_BINARY|nx_file_O_RDONLY);
- if (fd == -1)
- return NErr_FileNotFound;
- ret = NXFile_fstat(fd, &stat_buffer);
- if (ret != NErr_Success)
- {
- close(fd);
- return ret;
- }
- file_length = stat_buffer.file_size;
- if (file_length > SIZE_MAX)
- {
- close(fd);
- return NErr_IntegerOverflow;
- }
- data_length = (size_t)file_length;
- ret = NXDataCreateWithSize(&data, &bytes, data_length);
- if (ret != NErr_Success)
- {
- close(fd);
- return ret;
- }
- data->source_stats=(nx_file_stat_t)malloc(sizeof(nx_file_stat_s));
- if (!data->source_stats)
- {
- close(fd);
- NXDataRelease(data);
- return NErr_OutOfMemory;
- }
- bytes_read = read(fd, bytes, (int)data_length);
- close(fd);
- if (bytes_read != data_length)
- {
- NXDataRelease(data);
- return NErr_Error;
- }
- *data->source_stats=stat_buffer;
- data->source_uri=NXURIRetain(filename);
- *out_data = data;
- return NErr_Success;
- }
- int NXDataGet(nx_data_t data, const void **bytes, size_t *length)
- {
- if (!data)
- return NErr_BadParameter;
- if (data->len == 0)
- return NErr_Empty;
- *bytes = data->data;
- *length = data->len;
- return NErr_Success;
- }
- size_t NXDataSize(nx_data_t data)
- {
- if (!data)
- return 0;
- return data->len;
- }
- int NXDataSetMIME(nx_data_t data, nx_string_t mime_type)
- {
- nx_string_t old;
- if (!data)
- return NErr_BadParameter;
- old = data->mime_type;
- data->mime_type = NXStringRetain(mime_type);
- NXStringRelease(old);
- return NErr_Success;
- }
- int NXDataSetDescription(nx_data_t data, nx_string_t description)
- {
- nx_string_t old;
- if (!data)
- return NErr_BadParameter;
- old = data->description;
- data->description = NXStringRetain(description);
- NXStringRelease(old);
- return NErr_Success;
- }
- int NXDataSetSourceURI(nx_data_t data, nx_uri_t source_uri)
- {
- nx_uri_t old;
- if (!data)
- return NErr_BadParameter;
- old = data->source_uri;
- data->source_uri = NXURIRetain(source_uri);
- NXURIRelease(old);
- return NErr_Success;
- }
- int NXDataSetSourceStat(nx_data_t data, nx_file_stat_t source_stats)
- {
- nx_file_stat_t new_stats;
- if (!data)
- return NErr_BadParameter;
- if (source_stats)
- {
- new_stats=(nx_file_stat_t)malloc(sizeof(nx_file_stat_s));
- if (!new_stats)
- return NErr_OutOfMemory;
- *new_stats = *source_stats;
- free(data->source_stats);
- data->source_stats=new_stats;
- }
- else
- {
- free(data->source_stats);
- data->source_stats=0;
- }
- return NErr_Success;
- }
- int NXDataGetMIME(nx_data_t data, nx_string_t *mime_type)
- {
- if (!data)
- return NErr_BadParameter;
- if (!data->mime_type)
- return NErr_Empty;
- *mime_type = NXStringRetain(data->mime_type);
- return NErr_Success;
- }
- int NXDataGetDescription(nx_data_t data, nx_string_t *description)
- {
- if (!data)
- return NErr_BadParameter;
- if (!data->description)
- return NErr_Empty;
- *description = NXStringRetain(data->description);
- return NErr_Success;
- }
- int NXDataGetSourceURI(nx_data_t data, nx_uri_t *source_uri)
- {
- if (!data)
- return NErr_BadParameter;
- if (!data->source_uri)
- return NErr_Empty;
- *source_uri = NXURIRetain(data->source_uri);
- return NErr_Success;
- }
- int NXDataGetSourceStat(nx_data_t data, nx_file_stat_t *source_stats)
- {
- if (!data)
- return NErr_BadParameter;
-
- if (!data->source_stats)
- return NErr_Empty;
- *source_stats = data->source_stats;
- return NErr_Success;
- }
|