diff --git a/source/src/stream.cpp b/source/src/stream.cpp index 1e2a008a..c87b66f6 100644 --- a/source/src/stream.cpp +++ b/source/src/stream.cpp @@ -818,11 +818,70 @@ struct vecstream : stream } }; +struct memstream : stream +{ + const uchar *data; + int memsize; + int pointer; + int *refcount; + + memstream(const uchar *s, int size, int *refcnt) : data(s), memsize(size), pointer(0), refcount(refcnt) { if(refcnt) (*refcnt)++; } + ~memstream() { close(); } + + void close() + { + if(data && refcount) + { + (*refcount)--; + data = NULL; + } + else DELETEA(data); + memsize = -1; + } + bool end() { return data ? pointer >= memsize : true; } + long tell() { return data ? pointer : -1; } + long size() { return data ? memsize : -1; } + + bool seek(long offset, int whence) + { + int newpointer = -1; + if(data) switch(whence) + { + case SEEK_SET: newpointer = 0; break; + case SEEK_CUR: newpointer = pointer; break; + case SEEK_END: newpointer = memsize; break; + } + if(newpointer >= 0) newpointer += offset; + if(newpointer >= 0 && newpointer <= memsize) + { + pointer = newpointer; + return true; + } + return false; + } + + int read(void *buf, int len) + { + int got = 0; + if(data && pointer >= 0 && pointer < memsize) + { + got = min(len, memsize - pointer); + memcpy(buf, data + pointer, got); + pointer += got; + } + return got; + } +}; + stream *openvecfile(vector *s) { return new vecstream(s ? s : new vector); } +stream *openmemfile(const uchar *buf, int size, int *refcnt) +{ + return new memstream(buf, size, refcnt); +} stream *openrawfile(const char *filename, const char *mode) { diff --git a/source/src/tools.h b/source/src/tools.h index 2a5654f2..e5eaa73c 100644 --- a/source/src/tools.h +++ b/source/src/tools.h @@ -948,6 +948,7 @@ enum { FFL_WORKDIR = -1, FFL_HOME = 0 }; extern const char *findfile(const char *filename, const char *mode); extern int getfilesize(const char *filename); extern stream *openvecfile(vector *s = NULL); +extern stream *openmemfile(const uchar *buf, int size, int *refcnt); extern stream *openrawfile(const char *filename, const char *mode); extern stream *openzipfile(const char *filename, const char *mode); extern stream *openfile(const char *filename, const char *mode);