assert(res == 0); // fail
}
+static long FILE_Stream_GetLen (Stream *r) {
+ FILE_Stream *rd = (FILE_Stream*)r;
+ assert(rd != NULL);
+ assert(rd->fp != NULL);
+ long pos = ftell(rd->fp);
+ assert(pos != -1); // fail get cur pos
+ int res = fseek(rd->fp, 0, SEEK_END);
+ assert(res == 0); // fail jump to end
+ long len = ftell(rd->fp);
+ res = fseek(rd->fp, pos, SEEK_SET);
+ assert(res == 0); // fail return
+ assert(len != -1); // fail get length
+ return len;
+}
+
static void FILE_Stream_Read (Stream *r, void *data, size_t size, size_t n) {
FILE_Stream *rd = (FILE_Stream*)r;
assert(rd != NULL);
assert(fp != NULL);
r->base.getpos = FILE_Stream_GetPos;
r->base.setpos = FILE_Stream_SetPos;
+ r->base.getlen = FILE_Stream_GetLen;
r->base.read = FILE_Stream_Read;
r->base.write = FILE_Stream_Write;
r->fp = fp;
}
r->base.getpos = NULL;
r->base.setpos = NULL;
+ r->base.getlen = NULL;
r->base.read = NULL;
r->base.write = NULL;
r->fp = NULL;
s->setpos(s, pos);
}
+long stream_getlen (Stream *s) {
+ return s->getlen(s);
+}
+
void stream_read (void *data, size_t size, size_t n, Stream *r) {
r->read(r, data, size, n);
}
typedef struct Stream Stream;
struct Stream {
- long (*getpos)(Stream *r);
- void (*setpos)(Stream *r, long pos);
+ long (*getpos)(Stream *rw);
+ void (*setpos)(Stream *rw, long pos);
+ long (*getlen)(Stream *rw);
void (*read)(Stream *r, void *data, size_t size, size_t n);
void (*write)(Stream *w, const void *data, size_t size, size_t n);
};
long stream_getpos (Stream *s);
void stream_setpos (Stream *s, long pos);
+long stream_getlen (Stream *s);
+
void stream_read (void *data, size_t size, size_t n, Stream *r);
int8_t stream_read8 (Stream *r);
int16_t stream_read16 (Stream *r);