From 807c43b20ead76ce369539c7758d86de970dc83a Mon Sep 17 00:00:00 2001 From: Vreixo Formoso Date: Fri, 11 Jan 2008 16:42:18 +0100 Subject: [PATCH] Implementation of a IsoStream to read from a memory buffer. --- src/fsource.h | 1 + src/stream.c | 156 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/stream.h | 9 +++ 3 files changed, 166 insertions(+) diff --git a/src/fsource.h b/src/fsource.h index e70e1b1..38c7792 100644 --- a/src/fsource.h +++ b/src/fsource.h @@ -22,6 +22,7 @@ #define ISO_LOCAL_FS_ID 1 #define ISO_IMAGE_FS_ID 2 #define ISO_ELTORITO_FS_ID 3 +#define ISO_MEM_FS_ID 4 typedef struct Iso_File_Source IsoFileSource; typedef struct Iso_Filesystem IsoFilesystem; diff --git a/src/stream.c b/src/stream.c index 3d12908..8d20ffe 100644 --- a/src/stream.c +++ b/src/stream.c @@ -10,11 +10,13 @@ #include "stream.h" #include "fsource.h" #include "error.h" +#include "util.h" #include #include ino_t serial_id = (ino_t)1; +ino_t mem_serial_id = (ino_t)1; typedef struct { @@ -201,6 +203,160 @@ int iso_file_source_stream_new(IsoFileSource *src, IsoStream **stream) return ISO_SUCCESS; } + + +typedef struct +{ + uint8_t *buf; + ssize_t offset; /* -1 if stream closed */ + ino_t ino_id; + size_t size; +} MemStreamData; + +static +int mem_open(IsoStream *stream) +{ + MemStreamData *data; + if (stream == NULL) { + return ISO_NULL_POINTER; + } + data = (MemStreamData*)stream->data; + if (data->offset != -1) { + return ISO_FILE_ALREADY_OPENNED; + } + data->offset = 0; + return ISO_SUCCESS; +} + +static +int mem_close(IsoStream *stream) +{ + MemStreamData *data; + if (stream == NULL) { + return ISO_NULL_POINTER; + } + data = (MemStreamData*)stream->data; + if (data->offset == -1) { + return ISO_FILE_NOT_OPENNED; + } + data->offset = -1; + return ISO_SUCCESS; +} + +static +off_t mem_get_size(IsoStream *stream) +{ + MemStreamData *data; + data = (MemStreamData*)stream->data; + + return (off_t)data->size; +} + +static +int mem_read(IsoStream *stream, void *buf, size_t count) +{ + size_t len; + MemStreamData *data; + if (stream == NULL || buf == NULL) { + return ISO_NULL_POINTER; + } + if (count == 0) { + return ISO_WRONG_ARG_VALUE; + } + data = stream->data; + + if (data->offset == -1) { + return ISO_FILE_NOT_OPENNED; + } + + len = MIN(count, data->size - data->offset); + memcpy(buf, data->buf + data->offset, len); + return len; +} + +static +int mem_is_repeatable(IsoStream *stream) +{ + return 1; +} + +static +void mem_get_id(IsoStream *stream, unsigned int *fs_id, dev_t *dev_id, + ino_t *ino_id) +{ + MemStreamData *data; + data = (MemStreamData*)stream->data; + *fs_id = ISO_MEM_FS_ID; + *dev_id = 0; + *ino_id = data->ino_id; +} + +static +char *mem_get_name(IsoStream *stream) +{ + return strdup("[MEMORY SOURCE]"); +} + +static +void mem_free(IsoStream *stream) +{ + MemStreamData *data; + data = (MemStreamData*)stream->data; + free(data->buf); + free(data); +} + +IsoStreamIface mem_stream_class = { + mem_open, + mem_close, + mem_get_size, + mem_read, + mem_is_repeatable, + mem_get_id, + mem_get_name, + mem_free +}; + +/** + * Create a stream for reading from a arbitrary memory buffer. + * When the Stream refcount reach 0, the buffer is free(3). + * + * @return + * 1 sucess, < 0 error + */ +int iso_memory_stream_new(unsigned char *buf, size_t size, IsoStream **stream) +{ + IsoStream *str; + MemStreamData *data; + + if (buf == NULL || stream == NULL) { + return ISO_NULL_POINTER; + } + + str = malloc(sizeof(IsoStream)); + if (str == NULL) { + return ISO_MEM_ERROR; + } + data = malloc(sizeof(MemStreamData)); + if (str == NULL) { + free(str); + return ISO_MEM_ERROR; + } + + /* fill data */ + data->buf = buf; + data->size = size; + data->offset = -1; + data->ino_id = mem_serial_id++; + + str->refcount = 1; + str->data = data; + str->class = &mem_stream_class; + + *stream = str; + return ISO_SUCCESS; +} + void iso_stream_ref(IsoStream *stream) { ++stream->refcount; diff --git a/src/stream.h b/src/stream.h index 70e2ef0..b7f76cd 100644 --- a/src/stream.h +++ b/src/stream.h @@ -162,4 +162,13 @@ char *iso_stream_get_name(IsoStream *stream) */ int iso_file_source_stream_new(IsoFileSource *src, IsoStream **stream); +/** + * Create a stream for reading from a arbitrary memory buffer. + * When the Stream refcount reach 0, the buffer is free(3). + * + * @return + * 1 sucess, < 0 error + */ +int iso_memory_stream_new(unsigned char *buf, size_t size, IsoStream **stream); + #endif /*STREAM_H_*/