1 | // This file is a part of Framsticks SDK. http://www.framsticks.com/ |
---|
2 | // Copyright (C) 1999-2015 Maciej Komosinski and Szymon Ulatowski. |
---|
3 | // See LICENSE.txt for details. |
---|
4 | |
---|
5 | #ifndef _VIRTFILE_H_ |
---|
6 | #define _VIRTFILE_H_ |
---|
7 | |
---|
8 | #include <stdio.h> |
---|
9 | #include <stdarg.h> |
---|
10 | #include <common/nonstd_dir.h> |
---|
11 | #include <string> |
---|
12 | using std::string; |
---|
13 | |
---|
14 | #ifdef DLLEXPORTACTIVE //defined in the project that makes the DLL |
---|
15 | #define DLLEXP __declspec(dllexport) |
---|
16 | #else |
---|
17 | #ifdef __BORLANDC__ //assuming that all executables produced by borland use the DLL |
---|
18 | #define DLLEXP __declspec(dllimport) //without dllimport, fields in objects would have separate instances in DLL and in EXE |
---|
19 | #else |
---|
20 | #define DLLEXP |
---|
21 | #endif |
---|
22 | #endif |
---|
23 | |
---|
24 | class DLLEXP VirtFileSystem; |
---|
25 | |
---|
26 | class DLLEXP VirtFILE |
---|
27 | { |
---|
28 | protected: |
---|
29 | string path; |
---|
30 | public: |
---|
31 | virtual size_t Vread(void *ptr, size_t size, size_t nmemb) = 0; |
---|
32 | virtual size_t Vwrite(const void *ptr, size_t size, size_t nmemb) = 0; |
---|
33 | virtual int Veof() = 0; |
---|
34 | virtual int Vputc(int c) { unsigned char data = (unsigned char)c; return (Vwrite(&data, 1, 1) == 1) ? data : EOF; } |
---|
35 | virtual int Vputs(const char *s) = 0; |
---|
36 | virtual int Vgetc() { unsigned char data; if (Vread(&data, 1, 1) == 1) return data; else return EOF; } |
---|
37 | virtual int Vseek(long offset, int whence) = 0; |
---|
38 | virtual long Vtell() = 0; |
---|
39 | virtual void Vrewind() { Vseek(0, SEEK_SET); } |
---|
40 | virtual int Vflush() = 0; |
---|
41 | virtual char *Vgets(char *s, int size) = 0; |
---|
42 | virtual int Vprintf(const char *format, va_list args); |
---|
43 | int printf(const char *format, ...); |
---|
44 | virtual const char *VgetPath() { return path.c_str(); } |
---|
45 | virtual int getSize(); |
---|
46 | VirtFILE(const char* _path) :path(_path) {} |
---|
47 | virtual ~VirtFILE(); |
---|
48 | static VirtFILE *Vstdin, *Vstdout, *Vstderr; |
---|
49 | static void setVstdin(VirtFILE *); |
---|
50 | static void setVstdout(VirtFILE *); |
---|
51 | static void setVstderr(VirtFILE *); |
---|
52 | static VirtFILE* getVstdin(); |
---|
53 | static VirtFILE* getVstdout(); |
---|
54 | static VirtFILE* getVstderr(); |
---|
55 | static VirtFileSystem *vfs; |
---|
56 | static void selectFileSystem(VirtFileSystem *s); |
---|
57 | }; |
---|
58 | |
---|
59 | /** can be used directly or as a base class for implementations delegating VirtFILE calls to another VirtFILE object */ |
---|
60 | class DLLEXP DelegatedFILE : public VirtFILE |
---|
61 | { |
---|
62 | VirtFILE *delegate; |
---|
63 | public: |
---|
64 | size_t Vread(void *ptr, size_t size, size_t nmemb) { return delegate->Vread(ptr, size, nmemb); } |
---|
65 | size_t Vwrite(const void *ptr, size_t size, size_t nmemb) { return delegate->Vwrite(ptr, size, nmemb); } |
---|
66 | int Veof() { return delegate->Veof(); } |
---|
67 | int Vputc(int c) { return delegate->Vputc(c); } |
---|
68 | int Vputs(const char *s) { return delegate->Vputs(s); } |
---|
69 | int Vgetc() { return delegate->Vgetc(); } |
---|
70 | int Vseek(long offset, int whence) { return delegate->Vseek(offset, whence); } |
---|
71 | long Vtell() { return delegate->Vtell(); } |
---|
72 | void Vrewind() { delegate->Vrewind(); } |
---|
73 | int Vflush() { return delegate->Vflush(); } |
---|
74 | char *Vgets(char *s, int size) { return delegate->Vgets(s, size); } |
---|
75 | int Vprintf(const char *format, va_list args) { return delegate->Vprintf(format, args); } |
---|
76 | int getSize() { return delegate->getSize(); } |
---|
77 | // not overriden: VgetPath() |
---|
78 | |
---|
79 | DelegatedFILE(const char* _path, VirtFILE *_delegate) :VirtFILE(_path), delegate(_delegate) {} |
---|
80 | virtual ~DelegatedFILE() { if (delegate) delete delegate; delegate = NULL; } |
---|
81 | }; |
---|
82 | |
---|
83 | class DLLEXP VirtDIR |
---|
84 | { |
---|
85 | public: |
---|
86 | virtual ~VirtDIR() {} |
---|
87 | virtual dirent* Vreaddir() { return 0; } |
---|
88 | }; |
---|
89 | |
---|
90 | class DLLEXP VirtFileSystem |
---|
91 | { |
---|
92 | public: |
---|
93 | virtual VirtFILE *Vfopen(const char* path, const char*mode); |
---|
94 | virtual bool Vfexists(const char* path); |
---|
95 | virtual VirtDIR *Vopendir(const char* path); |
---|
96 | virtual bool Vmkdir(const char* path); |
---|
97 | virtual bool Vmkdirs(const char* path); |
---|
98 | virtual bool Vdirexists(const char* path, bool is_writable); |
---|
99 | }; |
---|
100 | |
---|
101 | /// base class for chained filesystems - redirect unimplemented calls -> chain |
---|
102 | class DLLEXP ChainFileSystem : public VirtFileSystem |
---|
103 | { |
---|
104 | public: |
---|
105 | VirtFileSystem *chain; |
---|
106 | ChainFileSystem(VirtFileSystem *_chain = NULL); |
---|
107 | VirtFILE *Vfopen(const char* path, const char*mode); |
---|
108 | bool Vfexists(const char* path); |
---|
109 | VirtDIR *Vopendir(const char* path); |
---|
110 | bool Vmkdir(const char* path); |
---|
111 | bool Vmkdirs(const char* path); |
---|
112 | bool Vdirexists(const char* path, bool is_writable); |
---|
113 | }; |
---|
114 | |
---|
115 | |
---|
116 | DLLEXP VirtFILE *Vfopen(const char* path, const char*mode); |
---|
117 | DLLEXP VirtDIR *Vopendir(const char* path); |
---|
118 | DLLEXP bool Vfexists(const char* path); |
---|
119 | DLLEXP bool Vmkdir(const char* path); |
---|
120 | DLLEXP bool Vmkdirs(const char* path); |
---|
121 | DLLEXP bool Vdirexists(const char* path, bool is_writable); |
---|
122 | |
---|
123 | DLLEXP int fread(void *ptr, size_t size, size_t nmemb, VirtFILE* f); |
---|
124 | DLLEXP int fwrite(const void *ptr, size_t size, size_t nmemb, VirtFILE* f); |
---|
125 | |
---|
126 | |
---|
127 | //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 |
---|
128 | #if defined _MSC_VER || defined __CYGWIN__ || defined SHP || defined __ANDROID__ |
---|
129 | #pragma push_macro("feof") |
---|
130 | #undef feof |
---|
131 | #endif |
---|
132 | #if defined __BORLANDC__ //does not support #pragma push_macro/pop_macro |
---|
133 | #undef feof |
---|
134 | #endif |
---|
135 | |
---|
136 | DLLEXP int feof(VirtFILE* f);// {return f->Veof();} |
---|
137 | |
---|
138 | //...and then restore the original macro: |
---|
139 | #if defined _MSC_VER || defined __CYGWIN__ || defined SHP || defined __ANDROID__ |
---|
140 | #pragma pop_macro("feof") |
---|
141 | #endif |
---|
142 | #if defined __BORLANDC__ |
---|
143 | #define feof(__f) ((__f)->flags & _F_EOF) |
---|
144 | #endif |
---|
145 | |
---|
146 | |
---|
147 | DLLEXP int fputc(int c, VirtFILE* f); |
---|
148 | DLLEXP int fputs(const char *s, VirtFILE* f); |
---|
149 | DLLEXP int fgetc(VirtFILE* f); |
---|
150 | DLLEXP int fseek(VirtFILE* f, long offset, int whence); |
---|
151 | DLLEXP int ftell(VirtFILE* f); |
---|
152 | DLLEXP void rewind(VirtFILE* f); |
---|
153 | DLLEXP int fflush(VirtFILE* f); |
---|
154 | DLLEXP char *fgets(char *s, int size, VirtFILE* f); |
---|
155 | DLLEXP int fprintf(VirtFILE* f, const char *format, ...); |
---|
156 | DLLEXP int fclose(VirtFILE* f); |
---|
157 | |
---|
158 | DLLEXP dirent* readdir(VirtDIR* d); |
---|
159 | DLLEXP int closedir(VirtDIR* d); |
---|
160 | |
---|
161 | #endif |
---|
162 | |
---|