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

Last change on this file since 1258 was 891, checked in by Maciej Komosinski, 5 years ago

Fixed return integer type discrepancy

  • Property svn:eol-style set to native
File size: 6.1 KB
RevLine 
[286]1// This file is a part of Framsticks SDK.  http://www.framsticks.com/
[891]2// Copyright (C) 1999-2019  Maciej Komosinski and Szymon Ulatowski.
[286]3// See LICENSE.txt for details.
[109]4
5#ifndef _VIRTFILE_H_
6#define _VIRTFILE_H_
7
8#include <stdio.h>
9#include <stdarg.h>
10#include <common/nonstd_dir.h>
[295]11#include <string>
[410]12#include <set>
[295]13using std::string;
[109]14
[301]15#ifdef DLLEXPORTACTIVE  //defined in the project that makes the DLL
[109]16#define DLLEXP __declspec(dllexport)
17#else
[301]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
[109]21#define DLLEXP
22#endif
[301]23#endif
[109]24
25class DLLEXP VirtFileSystem;
26
27class DLLEXP VirtFILE
28{
[302]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);
[109]58};
59
[295]60/** can be used directly or as a base class for implementations delegating VirtFILE calls to another VirtFILE object */
[302]61class DLLEXP DelegatedFILE : public VirtFILE
[295]62{
[302]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()
[295]79
[302]80        DelegatedFILE(const char* _path, VirtFILE *_delegate) :VirtFILE(_path), delegate(_delegate) {}
81        virtual ~DelegatedFILE() { if (delegate) delete delegate; delegate = NULL; }
[295]82};
83
[109]84class DLLEXP VirtDIR
85{
[302]86public:
87        virtual ~VirtDIR() {}
[427]88        virtual dirent* Vreaddir() { return NULL; }
[109]89};
90
91class DLLEXP VirtFileSystem
92{
93public:
[302]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);
[109]100};
101
[295]102/// base class for chained filesystems - redirect unimplemented calls -> chain
103class DLLEXP ChainFileSystem : public VirtFileSystem
104{
105public:
106        VirtFileSystem *chain;
[301]107        ChainFileSystem(VirtFileSystem *_chain = NULL);
[295]108        VirtFILE *Vfopen(const char* path, const char*mode);
109        bool Vfexists(const char* path);
110        VirtDIR *Vopendir(const char* path);
[891]111        virtual VirtDIR *internalopendir(const char* path) { return NULL; }
[295]112        bool Vmkdir(const char* path);
113        bool Vmkdirs(const char* path);
[302]114        bool Vdirexists(const char* path, bool is_writable);
[410]115
[891]116        class Dir : public VirtDIR
[410]117        {
[891]118                ChainFileSystem *first;
119                VirtFileSystem *second;
120                string path;
121                std::set<string> duplicates;
122                VirtDIR *dir;
123        public:
124                Dir(string _path, ChainFileSystem *_first, VirtFileSystem *_second) :first(_first), second(_second), path(_path), dir(NULL) {}
125                ~Dir();
126                dirent* Vreaddir();
[410]127        };
[295]128};
129
130
[302]131DLLEXP VirtFILE *Vfopen(const char* path, const char*mode);
[109]132DLLEXP VirtDIR *Vopendir(const char* path);
[295]133DLLEXP bool Vfexists(const char* path);
134DLLEXP bool Vmkdir(const char* path);
135DLLEXP bool Vmkdirs(const char* path);
[302]136DLLEXP bool Vdirexists(const char* path, bool is_writable);
[109]137
[523]138#ifdef VIRTFILE_OVERLOADING
[655]139//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
[523]140
[891]141DLLEXP size_t fread(void *ptr, size_t size, size_t nmemb, VirtFILE* f);
142DLLEXP size_t fwrite(const void *ptr, size_t size, size_t nmemb, VirtFILE* f);
[123]143
[131]144//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
[225]145#if defined _MSC_VER || defined __CYGWIN__ || defined SHP || defined __ANDROID__
[302]146#pragma push_macro("feof")
147#undef feof
[123]148#endif
[131]149#if defined __BORLANDC__ //does not support #pragma push_macro/pop_macro
[302]150#undef feof
[131]151#endif
[302]152
[123]153DLLEXP int feof(VirtFILE* f);// {return f->Veof();}
154
155//...and then restore the original macro:
[225]156#if defined _MSC_VER || defined __CYGWIN__ || defined SHP || defined __ANDROID__
[302]157#pragma pop_macro("feof")
[131]158#endif
[225]159#if defined __BORLANDC__
[302]160#define feof(__f)     ((__f)->flags & _F_EOF)
[109]161#endif
162
[123]163
[302]164DLLEXP int fputc(int c, VirtFILE* f);
165DLLEXP int fputs(const char *s, VirtFILE* f);
[109]166DLLEXP int fgetc(VirtFILE* f);
[302]167DLLEXP int fseek(VirtFILE* f, long offset, int whence);
[109]168DLLEXP int ftell(VirtFILE* f);
169DLLEXP void rewind(VirtFILE* f);
170DLLEXP int fflush(VirtFILE* f);
171DLLEXP char *fgets(char *s, int size, VirtFILE* f);
[302]172DLLEXP int fprintf(VirtFILE* f, const char *format, ...);
[109]173DLLEXP int fclose(VirtFILE* f);
174
175DLLEXP dirent* readdir(VirtDIR* d);
176DLLEXP int closedir(VirtDIR* d);
177
[523]178#endif //VIRTFILE_OVERLOADING
179
[109]180#endif
Note: See TracBrowser for help on using the repository browser.