+ const void *data;
+ unsigned length;
+ unsigned pos;
+
+ MemorySource(const void *d, unsigned l): data(d), length(l), pos(0) { }
+};
+
+size_t memory_read(void *ptr, size_t size, size_t nmemb, void *src)
+{
+ MemorySource &memsrc=*reinterpret_cast<MemorySource *>(src);
+ unsigned len=min(size*nmemb, memsrc.length-memsrc.pos);
+ memcpy(ptr, reinterpret_cast<const char *>(memsrc.data)+memsrc.pos, len);
+ memsrc.pos+=len;
+
+ return len/size;
+}
+
+int memory_seek(void *src, ogg_int64_t offset, int whence)
+{
+ MemorySource &memsrc=*reinterpret_cast<MemorySource *>(src);
+ if(whence==SEEK_SET)
+ memsrc.pos=offset;
+ else if(whence==SEEK_CUR)
+ memsrc.pos+=offset;
+ else if(whence==SEEK_END)
+ memsrc.pos=memsrc.length-offset;
+ memsrc.pos=min(memsrc.pos, memsrc.length);
+
+ return memsrc.pos;
+}
+
+void memory_close(void *src)
+{
+ delete reinterpret_cast<MemorySource *>(src);
+}
+
+long memory_tell(void *src)
+{
+ MemorySource &memsrc=*reinterpret_cast<MemorySource *>(src);
+ return memsrc.pos;