Index: /cpp/common/virtfile/stdiofile.cpp
===================================================================
--- /cpp/common/virtfile/stdiofile.cpp	(revision 381)
+++ /cpp/common/virtfile/stdiofile.cpp	(revision 381)
@@ -0,0 +1,63 @@
+// This file is a part of Framsticks SDK.  http://www.framsticks.com/
+// Copyright (C) 1999-2015  Maciej Komosinski and Szymon Ulatowski.
+// See LICENSE.txt for details.
+
+#include "stdiofile.h"
+#include <common/nonstd_dir.h>
+#include <common/nonstd_stdio.h>
+#include <common/log.h>
+#include <common/Convert.h>
+
+VirtFILE* StdioFileSystem::Vfopen(const char *path, const char *mode)
+{
+	//log_printf("Vfopen %s %s",path,mode);
+#if defined USE_MFILE || defined _WIN32
+	MFILE *f = mfopen(path, mode);
+#else
+	FILE *f = fopen(path, mode);
+#endif
+	//log_printf("%p",f);
+	if (f) return new StdioFILE(f, path); else return NULL;
+}
+
+VirtDIR* StdioFileSystem::Vopendir(const char* path)
+{
+	//log_printf("Vopendir %s",path);
+#ifdef _WIN32
+	DIRTYPE *d = wopendir(Convert::utf8ToUtf16(path).c_str());
+#else
+	DIR *d = opendir(path);
+#endif
+	//log_printf("%p",d);
+	if (d) return new StdioDIR(d); else return NULL;
+}
+
+bool StdioFileSystem::Vfexists(const char* path)
+{
+	return fileExists(path);
+}
+
+void StdioFILE::setStdio()
+{
+#ifndef NO_STD_IN_OUT_ERR
+	static StdioFILEDontClose si(stdin);
+	static StdioFILEDontClose so(stdout);
+	static StdioFILEDontClose se(stderr);
+	setVstdin(&si);
+	setVstdout(&so);
+	setVstderr(&se);
+#endif
+}
+
+dirent* StdioDIR::Vreaddir()
+{
+	//log_printf("Vreaddir %s",dir);
+#ifdef _WIN32
+	wdirent *wde=wreaddir(dir);
+	if (wde==NULL) return NULL;
+	strcpy(de.d_name, Convert::wstrToUtf8(wde->d_name).c_str());
+	return &de;
+#else
+	return readdir(dir);
+#endif
+}
Index: /cpp/common/virtfile/stdiofile.h
===================================================================
--- /cpp/common/virtfile/stdiofile.h	(revision 381)
+++ /cpp/common/virtfile/stdiofile.h	(revision 381)
@@ -0,0 +1,118 @@
+// This file is a part of Framsticks SDK.  http://www.framsticks.com/
+// Copyright (C) 1999-2015  Maciej Komosinski and Szymon Ulatowski.
+// See LICENSE.txt for details.
+
+#ifndef _STDIOFILE_H_
+#define _STDIOFILE_H_
+
+#include "virtfile.h"
+#include <common/nonstd_stdio.h>
+#include <common/nonstd_dir.h>
+
+class StdioFileSystem : public VirtFileSystem
+{
+public:
+	VirtFILE *Vfopen(const char *path, const char *mode);
+	bool Vfexists(const char* path);
+	VirtDIR *Vopendir(const char* path);
+	bool Vmkdir(const char* path) { return makeDirectory(path); }
+	bool Vdirexists(const char* path,bool is_writable) { return directoryExists(path,is_writable); }
+};
+
+#ifdef USE_MFILE
+class StdioFILE : public VirtFILE
+{
+protected:
+	MFILE *file;
+public:
+	StdioFILE(MFILE *f):VirtFILE("") { file = f; }
+	StdioFILE(MFILE *f, const char* p):VirtFILE(p) { file = f; }
+	static void setStdio();
+	size_t Vread(void *ptr, size_t size, size_t nmemb) { return mfread(ptr, size, nmemb, file); }
+	size_t Vwrite(const void *ptr, size_t size, size_t nmemb) { return mfwrite(ptr, size, nmemb, file); }
+	int Veof() { return mfeof(file); }
+	int Vputs(const char *s) { return mfputs(s, file); }
+	char *Vgets(char *s, int size) { return mfgets(s, size, file); }
+	int Vseek(long offset, int whence) { return mfseek(file, offset, whence); }
+	long Vtell() { return mftell(file); }
+	int Vflush() { return 0; /*NOT IMPLEMENTED!*/ }
+
+	~StdioFILE() { if (file) mfclose(file); }
+};
+#else
+class StdioFILE : public VirtFILE
+{
+protected:
+	FILE *file;
+public:
+	StdioFILE(FILE *f):VirtFILE("") { file = f; }
+	StdioFILE(FILE *f, const char* p):VirtFILE(p) { file = f; }
+	static void setStdio();
+	size_t Vread(void *ptr, size_t size, size_t nmemb) { return fread(ptr, size, nmemb, file); }
+	size_t Vwrite(const void *ptr, size_t size, size_t nmemb) { return fwrite(ptr, size, nmemb, file); }
+	int Veof() { return feof(file); }
+	int Vputc(int c) { return fputc(c, file); }
+	int Vputs(const char *s) { return fputs(s, file); }
+	int Vgetc() { return fgetc(file); }
+	char *Vgets(char *s, int size) { return fgets(s, size, file); }
+	int Vprintf(const char *format, va_list args) { return vfprintf(file, format, args); }
+	int Vseek(long offset, int whence) { return fseek(file, offset, whence); }
+	long Vtell() { return ftell(file); }
+	void Vrewind() { rewind(file); }
+	int Vflush() { return fflush(file); }
+
+	~StdioFILE() { if (file) fclose(file); }
+};
+#endif
+
+
+#ifdef _WIN32
+#ifdef __BORLANDC__
+ typedef wDIR DIRTYPE;
+#else
+ typedef WDIR DIRTYPE;
+#endif
+#else
+ typedef DIR DIRTYPE;
+#endif
+
+class StdioDIR : public VirtDIR
+{
+	DIRTYPE *dir;
+#ifdef _WIN32
+	dirent de; //only used to convert wide string names (wdirent) to utf8 (dirent)
+#endif
+public:
+	StdioDIR(DIRTYPE *d) : dir(d) {}
+	~StdioDIR()
+	{
+#ifdef _WIN32
+		if (dir) wclosedir(dir);
+#else
+		if (dir) closedir(dir);
+#endif
+	}
+	dirent* Vreaddir();
+};
+
+class StdioFILEDontClose : public StdioFILE
+{
+public:
+#ifdef USE_MFILE
+	StdioFILEDontClose(MFILE *f) : StdioFILE(f) {}
+#else
+	StdioFILEDontClose(FILE *f) : StdioFILE(f) {}
+#endif
+	~StdioFILEDontClose() { file = 0; }
+};
+
+class StdioFileSystem_autoselect: public StdioFileSystem
+{
+public:
+StdioFileSystem_autoselect()
+	{
+	VirtFILE::selectFileSystem(this);
+	}
+};
+
+#endif
Index: /cpp/common/virtfile/stringfile.cpp
===================================================================
--- /cpp/common/virtfile/stringfile.cpp	(revision 381)
+++ /cpp/common/virtfile/stringfile.cpp	(revision 381)
@@ -0,0 +1,72 @@
+// This file is a part of Framsticks SDK.  http://www.framsticks.com/
+// Copyright (C) 1999-2015  Maciej Komosinski and Szymon Ulatowski.
+// See LICENSE.txt for details.
+
+#include "stringfile.h"
+#include <stdio.h>
+#include <errno.h> //EINVAL
+
+size_t StringFILE::Vread(void *ptr, size_t size, size_t nmemb)
+{
+	int have = (int)(str.len() - pos);
+	if (have <= 0) return 0;
+	int need = (int)(size*nmemb);
+	if (need > have) { nmemb = have / size; need = (int)(size*nmemb); }
+	memcpy(ptr, str.c_str() + pos, need);
+	pos += need;
+	return nmemb;
+}
+
+int StringFILE::Vgetc()
+{
+	if (pos >= str.len()) //...i znowu byl bug roku! :O
+		return EOF;
+	else
+		return str.operator[]((int)pos++);
+}
+
+char *StringFILE::Vgets(char *s, int size)
+{
+	int have = str.len() - (int)pos;
+	if (have <= 0) return 0;
+	if (size < 0) size = 0;
+	if (have > size) have = size - 1;
+	const char* src = str.c_str() + pos;
+	char *dest = s;
+	while (have-- > 0)
+	{
+		*(dest++) = *(src++); pos++;
+		if (dest[-1] == '\n') break;
+	}
+	*dest = 0;
+	return s;
+}
+
+int StringFILE::Vseek(long offset, int whence)
+{
+	switch (whence)
+	{
+	case SEEK_SET: pos = offset; break;
+	case SEEK_CUR: pos += offset; break;
+	case SEEK_END: pos = str.len() - offset; break;
+	default: return EINVAL;
+	}
+	if (pos < 0) pos = 0; else if (pos>str.len()) pos = str.len();
+	return 0;
+}
+
+const char StringFileSystem::PREFIX[] = "string://";
+
+bool StringFileSystem::isStringPath(const char* path)
+{
+	return !strncmp(path, PREFIX, sizeof(PREFIX) - 1);
+}
+
+VirtFILE *StringFileSystem::Vfopen(const char* path, const char*mode)
+{
+	if ((*mode == 'r') && isStringPath(path))
+	{
+		return new StringFILE2(SString(path + sizeof(PREFIX) - 1));
+	}
+	return (chain != NULL) ? chain->Vfopen(path, mode) : NULL;
+}
Index: /cpp/common/virtfile/stringfile.h
===================================================================
--- /cpp/common/virtfile/stringfile.h	(revision 381)
+++ /cpp/common/virtfile/stringfile.h	(revision 381)
@@ -0,0 +1,49 @@
+// This file is a part of Framsticks SDK.  http://www.framsticks.com/
+// Copyright (C) 1999-2015  Maciej Komosinski and Szymon Ulatowski.
+// See LICENSE.txt for details.
+
+#ifndef _STRINGFILE_H_
+#define _STRINGFILE_H_
+
+#include "virtfile.h"
+#include <frams/util/sstring.h>
+
+class StringFILE : public VirtFILE
+{
+protected:
+	SString& str;
+	long pos;
+public:
+	StringFILE(SString& s): VirtFILE(""), str(s), pos(0) {}
+	size_t Vread(void *ptr, size_t size, size_t nmemb);
+	size_t Vwrite(const void *ptr, size_t size, size_t nmemb) { str.append((const char*)ptr, (int)(size*nmemb)); return size*nmemb; }
+	int Veof() { return pos >= str.len(); }
+	int Vputc(int c) { str += (char)c; return c; }
+	int Vputs(const char *s) { str.append(s, (int)strlen(s)); return 0; }
+	int Vgetc();
+	char *Vgets(char *s, int size);
+	int Vseek(long offset, int whence);
+	long Vtell() { return pos; }
+	int Vflush() { return 0; }
+};
+
+/** this version owns the string object */
+class StringFILE2 : public StringFILE
+{
+	SString string;
+public:
+	StringFILE2(const SString& s) :StringFILE(string), string(s) {}
+	StringFILE2() :StringFILE(string) {}
+	const SString& getString() { return string; }
+};
+
+class StringFileSystem : public ChainFileSystem
+{
+public:
+	StringFileSystem(VirtFileSystem *_chain = NULL):ChainFileSystem(_chain) {}
+	VirtFILE *Vfopen(const char* path, const char*mode);
+	static const char PREFIX[];
+	static bool isStringPath(const char* path);
+};
+
+#endif
Index: /cpp/common/virtfile/virtfile.cpp
===================================================================
--- /cpp/common/virtfile/virtfile.cpp	(revision 381)
+++ /cpp/common/virtfile/virtfile.cpp	(revision 381)
@@ -0,0 +1,207 @@
+// This file is a part of Framsticks SDK.  http://www.framsticks.com/
+// Copyright (C) 1999-2015  Maciej Komosinski and Szymon Ulatowski.
+// See LICENSE.txt for details.
+
+#include "virtfile.h"
+#include <common/stl-util.h>
+
+VirtFILE *VirtFILE::Vstdin = NULL;
+VirtFILE *VirtFILE::Vstdout = NULL;
+VirtFILE *VirtFILE::Vstderr = NULL;
+
+VirtFileSystem *VirtFILE::vfs = NULL;
+
+//#define DEBUG_VIRTFILE
+
+VirtFILE *Vfopen(const char* path, const char* mode)
+{
+#ifdef DEBUG_VIRTFILE
+	printf("VirtFILE::Vfopen %s %s (vfs=%p)\n",path,mode,VirtFILE::vfs);
+#endif
+	return VirtFILE::vfs ? VirtFILE::vfs->Vfopen(path, mode) : NULL;
+}
+
+VirtDIR *Vopendir(const char* path)
+{
+#ifdef DEBUG_VIRTFILE
+	printf("VirtFILE::Vfopendir %s (vfs=%p)\n",path,VirtFILE::vfs);
+#endif
+	return VirtFILE::vfs ? VirtFILE::vfs->Vopendir(path) : NULL;
+}
+
+bool Vfexists(const char* path)
+{
+	return VirtFILE::vfs ? VirtFILE::vfs->Vfexists(path) : false;
+}
+
+bool Vdirexists(const char* path, bool is_writable)
+{
+	return VirtFILE::vfs ? VirtFILE::vfs->Vdirexists(path, is_writable) : false;
+}
+
+bool Vmkdir(const char* path)
+{
+	return VirtFILE::vfs ? VirtFILE::vfs->Vmkdir(path) : false;
+}
+
+bool Vmkdirs(const char* path)
+{
+	return VirtFILE::vfs ? VirtFILE::vfs->Vmkdirs(path) : false;
+}
+
+VirtFILE::~VirtFILE()
+{}
+
+void VirtFILE::selectFileSystem(VirtFileSystem *s)
+{
+	vfs = s;
+#ifdef DEBUG_VIRTFILE
+	::printf("VirtFILE::selectFileSystem: %p := %p\n",vfs,s);
+#endif
+}
+
+int VirtFILE::Vprintf(const char *format, va_list args)
+{
+	string s = ssprintf_va(format, args);
+	return Vwrite(s.c_str(), 1, s.size());
+}
+
+int VirtFILE::printf(const char *format, ...)
+{
+	int ret; va_list argptr;
+	va_start(argptr, format);
+	ret = Vprintf(format, argptr);
+	va_end(argptr);
+	return ret;
+}
+
+int VirtFILE::getSize()
+{
+	int saved_pos = Vtell();
+	Vseek(0, SEEK_END);
+	int size = Vtell();
+	Vseek(saved_pos, SEEK_SET);
+	return size;
+}
+
+void VirtFILE::setVstdin(VirtFILE *f) { Vstdin = f; }
+void VirtFILE::setVstdout(VirtFILE *f) { Vstdout = f; }
+void VirtFILE::setVstderr(VirtFILE *f) { Vstderr = f; }
+VirtFILE* VirtFILE::getVstdin() { return Vstdin; }
+VirtFILE* VirtFILE::getVstdout() { return Vstdout; }
+VirtFILE* VirtFILE::getVstderr() { return Vstderr; }
+//////////////////////////////////////////////////////////////////////////
+
+// base class only returns NULL/false/not supported - implementations perform the actual work
+VirtFILE* VirtFileSystem::Vfopen(const char* path, const char* mode) { return NULL; }
+bool VirtFileSystem::Vfexists(const char* path) { return false; }
+VirtDIR* VirtFileSystem::Vopendir(const char* path) { return NULL; }
+bool VirtFileSystem::Vmkdir(const char* path) { return false; }
+bool VirtFileSystem::Vdirexists(const char* path, bool is_writable) { return false; }
+
+//////////////////////////////////////////////////////////////////////////
+
+
+
+int fread(void *ptr, size_t size, size_t nmemb, VirtFILE* f) { return f->Vread(ptr, size, nmemb); }
+int fwrite(const void *ptr, size_t size, size_t nmemb, VirtFILE* f) { return f->Vwrite(ptr, size, nmemb); }
+
+
+//since we want our own feof(VirtFILE*) function and some systems unfortunately define feof as a macro, we need to #undef it. Same as in virtfile.h
+#if defined _MSC_VER || defined __CYGWIN__ || defined SHP || defined __ANDROID__
+#pragma push_macro("feof")
+#undef feof
+#endif
+#if defined __BORLANDC__ //does not support #pragma push_macro/pop_macro 
+#undef feof
+#endif
+
+int feof(VirtFILE* f) { return f->Veof(); }
+
+//...and then restore the original macro:
+#if defined _MSC_VER || defined __CYGWIN__ || defined SHP || defined __ANDROID__
+#pragma pop_macro("feof")
+#endif
+#if defined __BORLANDC__
+#define feof(__f)     ((__f)->flags & _F_EOF)
+#endif
+
+
+int fputc(int c, VirtFILE* f) { return f->Vputc(c); }
+int fputs(const char *s, VirtFILE* f) { return f->Vputs(s); }
+int fgetc(VirtFILE* f) { return f->Vgetc(); }
+int fseek(VirtFILE* f, long offset, int whence) { return f->Vseek(offset, whence); }
+int ftell(VirtFILE* f) { return f->Vtell(); }
+void rewind(VirtFILE* f) { f->Vrewind(); }
+int fflush(VirtFILE* f) { return f->Vflush(); }
+char *fgets(char *s, int size, VirtFILE* f) { return f->Vgets(s, size); }
+int fprintf(VirtFILE* f, const char *format, ...)
+{
+	int ret; va_list argptr;
+	va_start(argptr, format);
+	ret = f->Vprintf(format, argptr);
+	va_end(argptr);
+	return ret;
+}
+int fclose(VirtFILE* f) { delete f; return 0; }
+
+int closedir(VirtDIR* d) { delete d; return 0; }
+dirent* readdir(VirtDIR* d) { return d->Vreaddir(); }
+
+/////////
+
+bool VirtFileSystem::Vmkdirs(const char* path)
+{
+	if (Vdirexists(path, true)) return true;
+	string parentdir = getFileDir(path);
+	if (!Vmkdirs(parentdir.c_str())) return false;
+	return Vmkdir(path);
+}
+
+//////////
+
+
+ChainFileSystem::ChainFileSystem(VirtFileSystem *_chain)
+{
+	chain = _chain;
+#ifdef DEBUG_VIRTFILE
+	printf("ChainFileSystem constructor: %p := %p\n",chain,_chain);
+#endif
+}
+
+
+VirtFILE *ChainFileSystem::Vfopen(const char* path, const char* mode)
+{
+#ifdef DEBUG_VIRTFILE
+	printf("ChainFileSystem::Vfopen %s %s (chain=%p)\n",path,mode,chain);
+#endif
+	return (chain != NULL) ? chain->Vfopen(path, mode) : NULL;
+}
+
+bool ChainFileSystem::Vfexists(const char* path)
+{
+	return (chain != NULL) ? chain->Vfexists(path) : false;
+}
+
+VirtDIR *ChainFileSystem::Vopendir(const char* path)
+{
+#ifdef DEBUG_VIRTFILE
+	printf("ChainFileSystem::Vfopendir %s (chain=%p)\n",path,chain);
+#endif
+	return (chain != NULL) ? chain->Vopendir(path) : NULL;
+}
+
+bool ChainFileSystem::Vmkdir(const char* path)
+{
+	return (chain != NULL) ? chain->Vmkdir(path) : false;
+}
+
+bool ChainFileSystem::Vmkdirs(const char* path)
+{
+	return (chain != NULL) ? chain->Vmkdirs(path) : false;
+}
+
+bool ChainFileSystem::Vdirexists(const char* path, bool is_writable)
+{
+	return (chain != NULL) ? chain->Vdirexists(path, is_writable) : false;
+}
Index: /cpp/common/virtfile/virtfile.h
===================================================================
--- /cpp/common/virtfile/virtfile.h	(revision 381)
+++ /cpp/common/virtfile/virtfile.h	(revision 381)
@@ -0,0 +1,162 @@
+// This file is a part of Framsticks SDK.  http://www.framsticks.com/
+// Copyright (C) 1999-2015  Maciej Komosinski and Szymon Ulatowski.
+// See LICENSE.txt for details.
+
+#ifndef _VIRTFILE_H_
+#define _VIRTFILE_H_
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <common/nonstd_dir.h>
+#include <string>
+using std::string;
+
+#ifdef DLLEXPORTACTIVE  //defined in the project that makes the DLL
+#define DLLEXP __declspec(dllexport)
+#else
+#ifdef __BORLANDC__ //assuming that all executables produced by borland use the DLL
+#define DLLEXP __declspec(dllimport) //without dllimport, fields in objects would have separate instances in DLL and in EXE
+#else
+#define DLLEXP
+#endif
+#endif
+
+class DLLEXP VirtFileSystem;
+
+class DLLEXP VirtFILE
+{
+protected:
+	string path;
+public:
+	virtual size_t Vread(void *ptr, size_t size, size_t nmemb) = 0;
+	virtual size_t Vwrite(const void *ptr, size_t size, size_t nmemb) = 0;
+	virtual int Veof() = 0;
+	virtual int Vputc(int c) { unsigned char data = (unsigned char)c; return (Vwrite(&data, 1, 1) == 1) ? data : EOF; }
+	virtual int Vputs(const char *s) = 0;
+	virtual int Vgetc() { unsigned char data; if (Vread(&data, 1, 1) == 1) return data; else return EOF; }
+	virtual int Vseek(long offset, int whence) = 0;
+	virtual long Vtell() = 0;
+	virtual void Vrewind() { Vseek(0, SEEK_SET); }
+	virtual int Vflush() = 0;
+	virtual char *Vgets(char *s, int size) = 0;
+	virtual int Vprintf(const char *format, va_list args);
+	int printf(const char *format, ...);
+	virtual const char *VgetPath() { return path.c_str(); }
+	virtual int getSize();
+	VirtFILE(const char* _path) :path(_path) {}
+	virtual ~VirtFILE();
+	static VirtFILE *Vstdin, *Vstdout, *Vstderr;
+	static void setVstdin(VirtFILE *);
+	static void setVstdout(VirtFILE *);
+	static void setVstderr(VirtFILE *);
+	static VirtFILE* getVstdin();
+	static VirtFILE* getVstdout();
+	static VirtFILE* getVstderr();
+	static VirtFileSystem *vfs;
+	static void selectFileSystem(VirtFileSystem *s);
+};
+
+/** can be used directly or as a base class for implementations delegating VirtFILE calls to another VirtFILE object */
+class DLLEXP DelegatedFILE : public VirtFILE
+{
+	VirtFILE *delegate;
+public:
+	size_t Vread(void *ptr, size_t size, size_t nmemb) { return delegate->Vread(ptr, size, nmemb); }
+	size_t Vwrite(const void *ptr, size_t size, size_t nmemb) { return delegate->Vwrite(ptr, size, nmemb); }
+	int Veof() { return delegate->Veof(); }
+	int Vputc(int c) { return delegate->Vputc(c); }
+	int Vputs(const char *s) { return delegate->Vputs(s); }
+	int Vgetc() { return delegate->Vgetc(); }
+	int Vseek(long offset, int whence) { return delegate->Vseek(offset, whence); }
+	long Vtell() { return delegate->Vtell(); }
+	void Vrewind() { delegate->Vrewind(); }
+	int Vflush() { return delegate->Vflush(); }
+	char *Vgets(char *s, int size) { return delegate->Vgets(s, size); }
+	int Vprintf(const char *format, va_list args) { return delegate->Vprintf(format, args); }
+	int getSize() { return delegate->getSize(); }
+	// not overriden: VgetPath()
+
+	DelegatedFILE(const char* _path, VirtFILE *_delegate) :VirtFILE(_path), delegate(_delegate) {}
+	virtual ~DelegatedFILE() { if (delegate) delete delegate; delegate = NULL; }
+};
+
+class DLLEXP VirtDIR
+{
+public:
+	virtual ~VirtDIR() {}
+	virtual dirent* Vreaddir() { return 0; }
+};
+
+class DLLEXP VirtFileSystem
+{
+public:
+	virtual VirtFILE *Vfopen(const char* path, const char*mode);
+	virtual bool Vfexists(const char* path);
+	virtual VirtDIR *Vopendir(const char* path);
+	virtual bool Vmkdir(const char* path);
+	virtual bool Vmkdirs(const char* path);
+	virtual bool Vdirexists(const char* path, bool is_writable);
+};
+
+/// base class for chained filesystems - redirect unimplemented calls -> chain
+class DLLEXP ChainFileSystem : public VirtFileSystem
+{
+public:
+	VirtFileSystem *chain;
+	ChainFileSystem(VirtFileSystem *_chain = NULL);
+	VirtFILE *Vfopen(const char* path, const char*mode);
+	bool Vfexists(const char* path);
+	VirtDIR *Vopendir(const char* path);
+	bool Vmkdir(const char* path);
+	bool Vmkdirs(const char* path);
+	bool Vdirexists(const char* path, bool is_writable);
+};
+
+
+DLLEXP VirtFILE *Vfopen(const char* path, const char*mode);
+DLLEXP VirtDIR *Vopendir(const char* path);
+DLLEXP bool Vfexists(const char* path);
+DLLEXP bool Vmkdir(const char* path);
+DLLEXP bool Vmkdirs(const char* path);
+DLLEXP bool Vdirexists(const char* path, bool is_writable);
+
+DLLEXP int fread(void *ptr, size_t size, size_t nmemb, VirtFILE* f);
+DLLEXP int fwrite(const void *ptr, size_t size, size_t nmemb, VirtFILE* f);
+
+
+//since we want our own feof(VirtFILE*) function and some systems unfortunately define feof as a macro, we need to #undef it. Same as in virtfile.cpp
+#if defined _MSC_VER || defined __CYGWIN__ || defined SHP || defined __ANDROID__
+#pragma push_macro("feof")
+#undef feof
+#endif
+#if defined __BORLANDC__ //does not support #pragma push_macro/pop_macro 
+#undef feof
+#endif
+
+DLLEXP int feof(VirtFILE* f);// {return f->Veof();}
+
+//...and then restore the original macro:
+#if defined _MSC_VER || defined __CYGWIN__ || defined SHP || defined __ANDROID__
+#pragma pop_macro("feof")
+#endif
+#if defined __BORLANDC__
+#define feof(__f)     ((__f)->flags & _F_EOF)
+#endif
+
+
+DLLEXP int fputc(int c, VirtFILE* f);
+DLLEXP int fputs(const char *s, VirtFILE* f);
+DLLEXP int fgetc(VirtFILE* f);
+DLLEXP int fseek(VirtFILE* f, long offset, int whence);
+DLLEXP int ftell(VirtFILE* f);
+DLLEXP void rewind(VirtFILE* f);
+DLLEXP int fflush(VirtFILE* f);
+DLLEXP char *fgets(char *s, int size, VirtFILE* f);
+DLLEXP int fprintf(VirtFILE* f, const char *format, ...);
+DLLEXP int fclose(VirtFILE* f);
+
+DLLEXP dirent* readdir(VirtDIR* d);
+DLLEXP int closedir(VirtDIR* d);
+
+#endif
+
