source: cpp/frams/virtfile/virtfile.h @ 301

Last change on this file since 301 was 301, checked in by Maciej Komosinski, 9 years ago

VirtFILE can have fields and still be used as a DLL thanks to declspec(dllimport)

  • Property svn:eol-style set to native
File size: 5.4 KB
Line 
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>
12using 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
24class DLLEXP VirtFileSystem;
25
26class DLLEXP VirtFILE
27{
28  protected:
29string path;
30  public:
31virtual size_t Vread(void *ptr, size_t size, size_t nmemb)=0;
32virtual size_t Vwrite(const void *ptr, size_t size, size_t nmemb)=0;
33virtual int Veof()=0;
34virtual int Vputc(int c) {unsigned char data=(unsigned char)c; return (Vwrite(&data,1,1)==1)?data:EOF;}
35virtual int Vputs(const char *s)=0;
36virtual int Vgetc() {unsigned char data; if (Vread(&data,1,1)==1) return data; else return EOF;}
37virtual int Vseek(long offset, int whence)=0;
38virtual long Vtell()=0;
39virtual void Vrewind() {Vseek(0,SEEK_SET);}
40virtual int Vflush()=0;
41virtual char *Vgets(char *s, int size)=0;
42virtual int Vprintf(const char *format, va_list args);
43int printf(const char *format, ...);
44virtual const char *VgetPath() {return path.c_str();}
45virtual int getSize();
46VirtFILE(const char* _path):path(_path) {}
47virtual ~VirtFILE();
48static VirtFILE *Vstdin,*Vstdout,*Vstderr;
49static void setVstdin(VirtFILE *);
50static void setVstdout(VirtFILE *);
51static void setVstderr(VirtFILE *);
52static VirtFILE* getVstdin();
53static VirtFILE* getVstdout();
54static VirtFILE* getVstderr();
55static VirtFileSystem *vfs;
56static 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 */
60class DLLEXP DelegatedFILE: public VirtFILE
61{
62VirtFILE *delegate;
63  public:
64size_t Vread(void *ptr, size_t size, size_t nmemb) {return delegate->Vread(ptr,size,nmemb);}
65size_t Vwrite(const void *ptr, size_t size, size_t nmemb) {return delegate->Vwrite(ptr,size,nmemb);}
66int Veof() {return delegate->Veof();}
67int Vputc(int c) {return delegate->Vputc(c);}
68int Vputs(const char *s) {return delegate->Vputs(s);}
69int Vgetc() {return delegate->Vgetc();}
70int Vseek(long offset, int whence) {return delegate->Vseek(offset,whence);}
71long Vtell() {return delegate->Vtell();}
72void Vrewind() {delegate->Vrewind();}
73int Vflush() {return delegate->Vflush();}
74char *Vgets(char *s, int size) {return delegate->Vgets(s,size);}
75int Vprintf(const char *format, va_list args) {return delegate->Vprintf(format,args);}
76int getSize() {return delegate->getSize();}
77// not overriden: VgetPath()
78
79DelegatedFILE(const char* _path,VirtFILE *_delegate):VirtFILE(_path),delegate(_delegate) {}
80virtual ~DelegatedFILE() {if (delegate) delete delegate; delegate=NULL;}
81};
82
83class DLLEXP VirtDIR
84{
85  public:
86virtual ~VirtDIR() {}
87virtual dirent* Vreaddir() {return 0;}
88};
89
90class DLLEXP VirtFileSystem
91{
92public:
93virtual VirtFILE *Vfopen(const char* path,const char*mode);
94virtual bool Vfexists(const char* path);
95virtual VirtDIR *Vopendir(const char* path);
96virtual bool Vmkdir(const char* path);
97virtual bool Vmkdirs(const char* path);
98virtual bool Vdirexists(const char* path,bool is_writable);
99};
100
101/// base class for chained filesystems - redirect unimplemented calls -> chain
102class DLLEXP ChainFileSystem : public VirtFileSystem
103{
104public:
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
116DLLEXP VirtFILE *Vfopen(const char* path,const char*mode);
117DLLEXP VirtDIR *Vopendir(const char* path);
118DLLEXP bool Vfexists(const char* path);
119DLLEXP bool Vmkdir(const char* path);
120DLLEXP bool Vmkdirs(const char* path);
121DLLEXP bool Vdirexists(const char* path,bool is_writable);
122
123DLLEXP int fread(void *ptr, size_t size, size_t nmemb, VirtFILE* f);
124DLLEXP 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 
136DLLEXP 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
147DLLEXP int fputc(int c,VirtFILE* f);
148DLLEXP int fputs(const char *s,VirtFILE* f);
149DLLEXP int fgetc(VirtFILE* f);
150DLLEXP int fseek(VirtFILE* f,long offset, int whence);
151DLLEXP int ftell(VirtFILE* f);
152DLLEXP void rewind(VirtFILE* f);
153DLLEXP int fflush(VirtFILE* f);
154DLLEXP char *fgets(char *s, int size, VirtFILE* f);
155DLLEXP int fprintf(VirtFILE* f,const char *format, ...);
156DLLEXP int fclose(VirtFILE* f);
157
158DLLEXP dirent* readdir(VirtDIR* d);
159DLLEXP int closedir(VirtDIR* d);
160
161#endif
162
Note: See TracBrowser for help on using the repository browser.