| 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;
 
- }
 
 
  |