source: cpp/common/virtfile/virtfile.h @ 1331

Last change on this file since 1331 was 1328, checked in by Maciej Komosinski, 2 weeks ago

Added Vstat(), Vdelete(), Vsettime() to VirtFILE

  • Property svn:eol-style set to native
File size: 6.6 KB
Line 
1// This file is a part of Framsticks SDK.  http://www.framsticks.com/
2// Copyright (C) 1999-2024  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#include <set>
13using std::string;
14
15#ifdef DLLEXPORTACTIVE  //defined in the project that makes the DLL
16#define DLLEXP __declspec(dllexport)
17#else
18#ifdef __BORLANDC__ //assuming that all executables produced by borland use the DLL
19#define DLLEXP __declspec(dllimport) //without dllimport, fields in objects would have separate instances in DLL and in EXE
20#else
21#define DLLEXP
22#endif
23#endif
24
25class DLLEXP VirtFileSystem;
26
27class DLLEXP VirtFILE
28{
29protected:
30        string path;
31public:
32        virtual size_t Vread(void *ptr, size_t size, size_t nmemb) = 0;
33        virtual size_t Vwrite(const void *ptr, size_t size, size_t nmemb) = 0;
34        virtual int Veof() = 0;
35        virtual int Vputc(int c) { unsigned char data = (unsigned char)c; return (Vwrite(&data, 1, 1) == 1) ? data : EOF; }
36        virtual int Vputs(const char *s) = 0;
37        virtual int Vgetc() { unsigned char data; if (Vread(&data, 1, 1) == 1) return data; else return EOF; }
38        virtual int Vseek(long offset, int whence) = 0;
39        virtual long Vtell() = 0;
40        virtual void Vrewind() { Vseek(0, SEEK_SET); }
41        virtual int Vflush() = 0;
42        virtual char *Vgets(char *s, int size) = 0;
43        virtual int Vprintf(const char *format, va_list args);
44        int printf(const char *format, ...);
45        virtual const char *VgetPath() { return path.c_str(); }
46        virtual int getSize();
47        VirtFILE(const char* _path) :path(_path) {}
48        virtual ~VirtFILE();
49        static VirtFILE *Vstdin, *Vstdout, *Vstderr;
50        static void setVstdin(VirtFILE *);
51        static void setVstdout(VirtFILE *);
52        static void setVstderr(VirtFILE *);
53        static VirtFILE* getVstdin();
54        static VirtFILE* getVstdout();
55        static VirtFILE* getVstderr();
56        static VirtFileSystem *vfs;
57        static void selectFileSystem(VirtFileSystem *s);
58};
59
60/** can be used directly or as a base class for implementations delegating VirtFILE calls to another VirtFILE object */
61class DLLEXP DelegatedFILE : public VirtFILE
62{
63        VirtFILE *delegate;
64public:
65        size_t Vread(void *ptr, size_t size, size_t nmemb) { return delegate->Vread(ptr, size, nmemb); }
66        size_t Vwrite(const void *ptr, size_t size, size_t nmemb) { return delegate->Vwrite(ptr, size, nmemb); }
67        int Veof() { return delegate->Veof(); }
68        int Vputc(int c) { return delegate->Vputc(c); }
69        int Vputs(const char *s) { return delegate->Vputs(s); }
70        int Vgetc() { return delegate->Vgetc(); }
71        int Vseek(long offset, int whence) { return delegate->Vseek(offset, whence); }
72        long Vtell() { return delegate->Vtell(); }
73        void Vrewind() { delegate->Vrewind(); }
74        int Vflush() { return delegate->Vflush(); }
75        char *Vgets(char *s, int size) { return delegate->Vgets(s, size); }
76        int Vprintf(const char *format, va_list args) { return delegate->Vprintf(format, args); }
77        int getSize() { return delegate->getSize(); }
78        // not overriden: VgetPath()
79
80        DelegatedFILE(const char* _path, VirtFILE *_delegate) :VirtFILE(_path), delegate(_delegate) {}
81        virtual ~DelegatedFILE() { if (delegate) delete delegate; delegate = NULL; }
82};
83
84class DLLEXP VirtDIR
85{
86public:
87        virtual ~VirtDIR() {}
88        virtual dirent* Vreaddir() { return NULL; }
89};
90
91class DLLEXP VirtFileSystem
92{
93public:
94        virtual VirtFILE *Vfopen(const char* path, const char*mode);
95        virtual bool Vfexists(const char* path);
96        virtual VirtDIR *Vopendir(const char* path);
97        virtual bool Vmkdir(const char* path);
98        virtual bool Vmkdirs(const char* path);
99        virtual bool Vdirexists(const char* path, bool is_writable);
100        virtual bool Vdelete(const char* path);
101        struct Stat { bool is_file; time_t modification_time; };
102        virtual bool Vstat(const char* path, Stat* stat);
103        virtual bool Vsettime(const char* path, double timestamp);
104};
105
106/// base class for chained filesystems - redirect unimplemented calls -> chain
107class DLLEXP ChainFileSystem : public VirtFileSystem
108{
109public:
110        VirtFileSystem *chain;
111        ChainFileSystem(VirtFileSystem *_chain = NULL);
112        VirtFILE *Vfopen(const char* path, const char*mode);
113        bool Vfexists(const char* path);
114        VirtDIR *Vopendir(const char* path);
115        virtual VirtDIR *internalopendir(const char* path) { return NULL; }
116        bool Vmkdir(const char* path);
117        bool Vmkdirs(const char* path);
118        bool Vdirexists(const char* path, bool is_writable);
119        bool Vdelete(const char* path);
120        bool Vstat(const char* path, Stat* stat);
121        bool Vsettime(const char* path, double timestamp);
122
123        class Dir : public VirtDIR
124        {
125                ChainFileSystem *first;
126                VirtFileSystem *second;
127                string path;
128                std::set<string> duplicates;
129                VirtDIR *dir;
130        public:
131                Dir(string _path, ChainFileSystem *_first, VirtFileSystem *_second) :first(_first), second(_second), path(_path), dir(NULL) {}
132                ~Dir();
133                dirent* Vreaddir();
134        };
135};
136
137
138DLLEXP VirtFILE *Vfopen(const char* path, const char*mode);
139DLLEXP VirtDIR *Vopendir(const char* path);
140DLLEXP bool Vfexists(const char* path);
141DLLEXP bool Vmkdir(const char* path);
142DLLEXP bool Vmkdirs(const char* path);
143DLLEXP bool Vdirexists(const char* path, bool is_writable);
144DLLEXP bool Vdelete(const char* path);
145DLLEXP bool Vstat(const char* path, struct VirtFileSystem::Stat *stat);
146DLLEXP bool Vsettime(const char* path, double timestamp);
147
148#ifdef VIRTFILE_OVERLOADING
149//required for redefine_stdio.h and for building virtfile.dll, can also be used if someone prefers the standard f-functions instead of explicitly using virtfile objects
150
151DLLEXP size_t fread(void *ptr, size_t size, size_t nmemb, VirtFILE* f);
152DLLEXP size_t fwrite(const void *ptr, size_t size, size_t nmemb, VirtFILE* f);
153
154//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
155#if defined _MSC_VER || defined __CYGWIN__ || defined SHP || defined __ANDROID__
156#pragma push_macro("feof")
157#undef feof
158#endif
159#if defined __BORLANDC__ //does not support #pragma push_macro/pop_macro
160#undef feof
161#endif
162
163DLLEXP int feof(VirtFILE* f);// {return f->Veof();}
164
165//...and then restore the original macro:
166#if defined _MSC_VER || defined __CYGWIN__ || defined SHP || defined __ANDROID__
167#pragma pop_macro("feof")
168#endif
169#if defined __BORLANDC__
170#define feof(__f)     ((__f)->flags & _F_EOF)
171#endif
172
173
174DLLEXP int fputc(int c, VirtFILE* f);
175DLLEXP int fputs(const char *s, VirtFILE* f);
176DLLEXP int fgetc(VirtFILE* f);
177DLLEXP int fseek(VirtFILE* f, long offset, int whence);
178DLLEXP int ftell(VirtFILE* f);
179DLLEXP void rewind(VirtFILE* f);
180DLLEXP int fflush(VirtFILE* f);
181DLLEXP char *fgets(char *s, int size, VirtFILE* f);
182DLLEXP int fprintf(VirtFILE* f, const char *format, ...);
183DLLEXP int fclose(VirtFILE* f);
184
185DLLEXP dirent* readdir(VirtDIR* d);
186DLLEXP int closedir(VirtDIR* d);
187
188#endif //VIRTFILE_OVERLOADING
189
190#endif
Note: See TracBrowser for help on using the repository browser.