diff options
author | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
---|---|---|
committer | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
commit | 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch) | |
tree | 12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/replicant/nx/win/nxdata.c | |
parent | 537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff) | |
download | winamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz |
Initial community commit
Diffstat (limited to 'Src/replicant/nx/win/nxdata.c')
-rw-r--r-- | Src/replicant/nx/win/nxdata.c | 276 |
1 files changed, 276 insertions, 0 deletions
diff --git a/Src/replicant/nx/win/nxdata.c b/Src/replicant/nx/win/nxdata.c new file mode 100644 index 00000000..065eddbe --- /dev/null +++ b/Src/replicant/nx/win/nxdata.c @@ -0,0 +1,276 @@ +#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; +} |