Changeset 295


Ignore:
Timestamp:
01/15/15 22:43:01 (7 years ago)
Author:
Maciej Komosinski
Message:

Reorganizations and extensions of directory/file/filesystem IO classes

Location:
cpp
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • cpp/common/nonstd.h

    r286 r295  
    6161#endif
    6262
    63 #ifdef IPHONE
    64  #include <string>
    65  std::string getAppHome();
    66  std::string getAppResources();
    67  #define GET_APP_HOME getAppHome()
    68  #define GET_APP_RESOURCES getAppResources()
    69 #endif
    70 
    71 #ifdef SHP
    72  #define GET_APP_HOME "/Home/"
    73  #define GET_APP_RESOURCES "/Res/"
    74 #endif
    75 
    76 #ifdef TIZEN
    77  #define GET_APP_HOME "/data/"
    78  #define GET_APP_RESOURCES "/res/"
    79 #endif
    80 
    81 #ifdef __ANDROID__
    82  #define GET_APP_HOME getAppHome()
    83  #define GET_APP_RESOURCES "/resrc/" //inside APK, resources are kept in the "assets" subdirectory (in the "res" subdirectory there is no support for subdirectories nor accessing files by name). The prefix /resrc/ is just an indication that lets mfile easily discriminate between HOME (r/w) and RESOURCES (r) locations
    84 #endif
    85 
    86 #ifdef LINUX
    87  #define GET_APP_HOME "./"
    88  #define GET_APP_RESOURCES "./"
    89 #endif
    90 
    91 #ifdef MACOS
    92 #ifdef MACOS_APP_DIR //separate home/resources
    93  #include <string>
    94  std::string getAppHome();
    95  #define GET_APP_HOME getAppHome()
    96 #else //old style
    97  #define GET_APP_HOME "./"
    98 #endif
    99  #define GET_APP_RESOURCES "./"
    100 #endif
    101 
    102 #if defined(_WIN32) && !defined(SHP)
    103     #define GET_APP_HOME ".\\"
    104     #define GET_APP_RESOURCES ".\\"
    105 #endif
    106 
    107 #ifdef INITIAL_DIR_IS_HOME
    108  #include "cwd.h"
    109  #ifdef GET_APP_HOME
    110   #undef GET_APP_HOME
    111  #endif
    112  #define GET_APP_HOME getAppHome()
    113 #endif
    114 
    115 #ifdef INITIAL_DIR_IS_RES
    116  #include "cwd.h"
    117  #ifdef GET_APP_RESOURCES
    118   #undef GET_APP_RESOURCES
    119  #endif
    120  #define GET_APP_RESOURCES getAppResources()
    121 #endif
    122 
    12363//typedef unsigned char boolean; //niestety nie mozna uzyc 'bool' bo VC w rpcndr.h wlasnie tak definiuje booleana, jako unsigned char
    12464//typedef char byte; //rozne srodowiska c++ definiuja byte jako unsigned char! w javie jest inaczej -> trzeba i tak zmienic w portowanych zrodlach byte na char.
  • cpp/common/nonstd_stdio.cpp

    r286 r295  
    88#include <common/stl-util.h>
    99
    10 #if defined _WIN32 && !defined SHP
    11 //<unistd.h> not needed for unlink()
     10#ifdef _WIN32
    1211#include "Shlwapi.h" //PathIsRelative()
     12#ifdef __BORLANDC__
     13#pragma link "Shlwapi.lib" //PathIsRelative()
     14#endif
    1315#include <sys/stat.h> //_stat
    1416#else
     
    2931}
    3032
    31 bool directoryExists(const char* path)
     33#ifdef _WIN32
     34bool isDirWritable(const char* path) //dir must not end with '\'
     35{
     36        wstring dir = Convert::utf8ToUtf16(path);
     37        CreateDirectoryW(dir.c_str(), 0);
     38        dir += L"\\test_file.write";
     39        _wunlink(dir.c_str());
     40        FILE *f = _wfopen(dir.c_str(), L"wt");
     41        if (f)
     42        {
     43                fclose(f);
     44                _wunlink(dir.c_str());
     45                return true;
     46        }
     47        else
     48                return false;
     49}
     50#endif
     51
     52bool directoryExists(const char* path, bool is_writable)
    3253{
    3354        struct _stat s;
     55        if (path[0] == 0) path = ".";
    3456#ifdef _WIN32
    3557        if (_wstat(Convert::utf8ToUtf16(path).c_str(), &s) != 0) return false;
     
    3759        if (_stat(path, &s) != 0) return false;
    3860#endif
    39         return S_ISDIR(s.st_mode);
     61        if (S_ISDIR(s.st_mode))
     62        {
     63                if (is_writable)
     64                {
     65#ifdef _WIN32
     66#ifndef W_OK
     67#define W_OK 2 //http://msdn.microsoft.com/en-us/library/1w06ktdy.aspx
     68#endif
     69                        //under Windows, access() is not a reliable way to check if a directory is writable
     70                        //http://stackoverflow.com/questions/198071/code-for-checking-write-permissions-for-directories-in-win2k-xp
     71                        //bool writable_access = _waccess(Convert::utf8ToUtf16(path).c_str(), W_OK) == 0;
     72                        bool writable_trial = isDirWritable(path);
     73                        //printf("Checking '%s' for writing(%d) using access(): result=%d\n", path, is_writable, writable_access);
     74                        //printf("File creation test: result=%d\n", writable_trial);
     75                        //return writable_access;
     76                        return writable_trial;
     77#else
     78                        return access(path, W_OK) == 0;
     79#endif
     80                }
     81                else
     82                        return true;
     83        }
     84        return false;
    4085}
    4186
     
    5196bool makeDirectories(const char* path)
    5297{
    53         if (directoryExists(path)) return true;
     98        if (directoryExists(path,false)) return true;
    5499        string parentdir = getFileDir(path);
    55100        if (!makeDirectories(parentdir.c_str())) return false;
     
    92137{
    93138        if (fname == NULL) return false; //SplitFileSystem never passes NULL but this function is public so we never know
    94 #if defined _WIN32
     139#ifdef _WIN32
    95140        return PathIsRelativeW(Convert::utf8ToUtf16(fname).c_str()) == FALSE; //http://msdn.microsoft.com/en-us/library/bb773660%28v=vs.85%29.aspx
    96141#else
     
    201246MFILE *mfopen(const char *path, const char *mode)
    202247{
    203         string respath=GET_APP_RESOURCES; //the macro can be char* or std::string, we don't know (nonstd.h, INITIAL_DIR_IS_RES, cwd.cpp) so we convert it to std::string
     248        string respath=getAppResources();
    204249        //printFM("Opening '%s', mode='%s'",path,mode);
    205         //printFM("GET_APP_RESOURCES='%s'",respath.c_str());
     250        //printFM("getAppResources()='%s'",respath.c_str());
    206251        NvFile *rfile=NULL; //can only read
    207252        FILE *rwfile=NULL;
  • cpp/common/nonstd_stdio.h

    r286 r295  
    77
    88bool fileExists(const char* path);
    9 bool directoryExists(const char* path);
     9bool directoryExists(const char* path,bool is_writable);
    1010bool makeDirectory(const char* path);
    1111bool makeDirectories(const char* path);
  • cpp/frams/virtfile/stdiofile.cpp

    r293 r295  
    3737}
    3838
    39 int StdioFileSystem::Vfexists(const char* path)
     39bool StdioFileSystem::Vfexists(const char* path)
    4040{
    4141        return fileExists(path);
  • cpp/frams/virtfile/stdiofile.h

    r286 r295  
    88#include "virtfile.h"
    99#include <frams/util/sstring.h>
    10 #ifdef USE_MFILE
    1110#include <common/nonstd_stdio.h>
    12 #else
    13 #include <stdio.h>
    14 #endif
    1511#include <common/nonstd_dir.h>
    1612
     
    1915public:
    2016        VirtFILE *Vfopen(const char *path, const char *mode);
    21         int Vfexists(const char* path);
     17        bool Vfexists(const char* path);
    2218        VirtDIR *Vopendir(const char* path);
     19        bool Vmkdir(const char* path) { return makeDirectory(path); }
     20        bool Vdirexists(const char* path,bool is_writable) { return directoryExists(path,is_writable); }
    2321};
    2422
     
    2826protected:
    2927        MFILE *file;
    30         SString path;
    3128public:
    32         StdioFILE(MFILE *f) { file = f; }
    33         StdioFILE(MFILE *f, const SString& p) { file = f; path = p; }
     29        StdioFILE(MFILE *f):VirtFILE("") { file = f; }
     30        StdioFILE(MFILE *f, const SString& p):VirtFILE(p) { file = f; }
    3431        static void setStdio();
    3532        size_t Vread(void *ptr, size_t size, size_t nmemb) { return mfread(ptr, size, nmemb, file); }
     
    4138        long Vtell() { return mftell(file); }
    4239        int Vflush() { return 0; /*NOT IMPLEMENTED!*/ }
    43         const char* VgetPath() { return path; }
    4440
    4541        ~StdioFILE() { if (file) mfclose(file); }
     
    5046protected:
    5147        FILE *file;
    52         SString path;
    5348public:
    54         StdioFILE(FILE *f) { file = f; }
    55         StdioFILE(FILE *f, const SString& p) { file = f; path = p; }
     49        StdioFILE(FILE *f):VirtFILE("") { file = f; }
     50        StdioFILE(FILE *f, const SString& p):VirtFILE(p) { file = f; }
    5651        static void setStdio();
    5752        size_t Vread(void *ptr, size_t size, size_t nmemb) { return fread(ptr, size, nmemb, file); }
     
    6762        void Vrewind() { rewind(file); }
    6863        int Vflush() { return fflush(file); }
    69         const char* VgetPath() { return path; }
    7064
    7165        ~StdioFILE() { if (file) fclose(file); }
  • cpp/frams/virtfile/stringfile.cpp

    r286 r295  
    7171        return (chain != NULL) ? chain->Vfopen(path, mode) : NULL;
    7272}
    73 
    74 int StringFileSystem::Vfexists(const char* path)
    75 {
    76         return (chain != NULL) ? chain->Vfexists(path) : 0;
    77 }
    78 
    79 VirtDIR *StringFileSystem::Vopendir(const char* path)
    80 {
    81         return (chain != NULL) ? chain->Vopendir(path) : NULL;
    82 }
  • cpp/frams/virtfile/stringfile.h

    r286 r295  
    1515        long pos;
    1616public:
    17         StringFILE(SString& s) :str(s), pos(0) {}
     17        StringFILE(SString& s): VirtFILE(""), str(s), pos(0) {}
    1818        size_t Vread(void *ptr, size_t size, size_t nmemb);
    1919        size_t Vwrite(const void *ptr, size_t size, size_t nmemb) { str.append((const char*)ptr, (int)(size*nmemb)); return size*nmemb; }
     
    3838};
    3939
    40 class StringFileSystem : public VirtFileSystem
     40class StringFileSystem : public ChainFileSystem
    4141{
    4242public:
    43         VirtFileSystem *chain;
    44         StringFileSystem(VirtFileSystem *_chain = NULL) :chain(_chain) {}
     43        StringFileSystem(VirtFileSystem *_chain = NULL):ChainFileSystem(_chain) {}
    4544        VirtFILE *Vfopen(const char* path, const char*mode);
    46         int Vfexists(const char* path);
    47         VirtDIR *Vopendir(const char* path);
    4845        static const char PREFIX[];
    4946        static bool isStringPath(const char* path);
  • cpp/frams/virtfile/virtfile.cpp

    r286 r295  
    2222}
    2323
    24 int Vfexists(const char* path)
     24bool Vfexists(const char* path)
    2525{
    26 return VirtFILE::vfs ? VirtFILE::vfs->Vfexists(path) : 0;
     26return VirtFILE::vfs ? VirtFILE::vfs->Vfexists(path) : false;
     27}
     28
     29bool Vdirexists(const char* path,bool is_writable)
     30{
     31return VirtFILE::vfs ? VirtFILE::vfs->Vdirexists(path,is_writable) : false;
     32}
     33
     34bool Vmkdir(const char* path)
     35{
     36return VirtFILE::vfs ? VirtFILE::vfs->Vmkdir(path) : false;
     37}
     38
     39bool Vmkdirs(const char* path)
     40{
     41return VirtFILE::vfs ? VirtFILE::vfs->Vmkdirs(path) : false;
    2742}
    2843
     
    6580
    6681VirtFILE* VirtFileSystem::Vfopen(const char* path,const char*mode) {return 0;}
    67 int VirtFileSystem::Vfexists(const char* path) {return 0;}
     82bool VirtFileSystem::Vfexists(const char* path) {return 0;}
    6883VirtDIR* VirtFileSystem::Vopendir(const char* path) {return 0;}
     84bool VirtFileSystem::Vmkdir(const char* path) {return false;} //error - not supported
     85bool VirtFileSystem::Vdirexists(const char* path,bool is_writable) {return false;}
    6986
    7087//////////////////////////////////////////////////////////////////////////
     
    117134dirent* readdir(VirtDIR* d) {return d->Vreaddir();}
    118135
     136/////////
     137
     138bool VirtFileSystem::Vmkdirs(const char* path)
     139{
     140if (Vdirexists(path,true)) return true;
     141string parentdir = getFileDir(path);
     142if (!Vmkdirs(parentdir.c_str())) return false;
     143return Vmkdir(path);
     144}
     145
     146//////////
     147
     148VirtFILE *ChainFileSystem::Vfopen(const char* path, const char*mode)
     149{
     150        return (chain != NULL) ? chain->Vfopen(path, mode) : NULL;
     151}
     152
     153bool ChainFileSystem::Vfexists(const char* path)
     154{
     155        return (chain != NULL) ? chain->Vfexists(path) : false;
     156}
     157
     158VirtDIR *ChainFileSystem::Vopendir(const char* path)
     159{
     160        return (chain != NULL) ? chain->Vopendir(path) : NULL;
     161}
     162
     163bool ChainFileSystem::Vmkdir(const char* path)
     164{
     165        return (chain != NULL) ? chain->Vmkdir(path) : false;
     166}
     167
     168bool ChainFileSystem::Vmkdirs(const char* path)
     169{
     170        return (chain != NULL) ? chain->Vmkdirs(path) : false;
     171}
     172
     173bool ChainFileSystem::Vdirexists(const char* path,bool is_writable)
     174{
     175        return (chain != NULL) ? chain->Vdirexists(path,is_writable) : false;
     176}
  • cpp/frams/virtfile/virtfile.h

    r286 r295  
    99#include <stdarg.h>
    1010#include <common/nonstd_dir.h>
     11#include <string>
     12using std::string;
    1113//#include <dirent.h> //to jest inkludowane przez powyzsze
    1214//struct dirent; //kiedys byla ta linia jak nie bylo jeszcze implementacji windowsowej dirent, ale borlandowi sie nie podoba jak s¹ obie
     
    2224class DLLEXP VirtFILE
    2325{
     26  protected:
     27string path;
    2428  public:
    2529virtual size_t Vread(void *ptr, size_t size, size_t nmemb)=0;
     
    3640virtual int Vprintf(const char *format, va_list args);
    3741int printf(const char *format, ...);
    38 virtual const char *VgetPath() {return 0;} // 0=unspecified path
     42virtual const char *VgetPath() {return path.c_str();}
    3943virtual int getSize();
     44VirtFILE(const char* _path):path(_path) {}
    4045virtual ~VirtFILE();
    4146static VirtFILE *Vstdin,*Vstdout,*Vstderr;
     
    4853static VirtFileSystem *vfs;
    4954static void selectFileSystem(VirtFileSystem *s);
     55};
     56
     57/** can be used directly or as a base class for implementations delegating VirtFILE calls to another VirtFILE object */
     58class DLLEXP DelegatedFILE: public VirtFILE
     59{
     60VirtFILE *delegate;
     61  public:
     62size_t Vread(void *ptr, size_t size, size_t nmemb) {return delegate->Vread(ptr,size,nmemb);}
     63size_t Vwrite(const void *ptr, size_t size, size_t nmemb) {return delegate->Vwrite(ptr,size,nmemb);}
     64int Veof() {return delegate->Veof();}
     65int Vputc(int c) {return delegate->Vputc(c);}
     66int Vputs(const char *s) {return delegate->Vputs(s);}
     67int Vgetc() {return delegate->Vgetc();}
     68int Vseek(long offset, int whence) {return delegate->Vseek(offset,whence);}
     69long Vtell() {return delegate->Vtell();}
     70void Vrewind() {delegate->Vrewind();}
     71int Vflush() {return delegate->Vflush();}
     72char *Vgets(char *s, int size) {return delegate->Vgets(s,size);}
     73int Vprintf(const char *format, va_list args) {return delegate->Vprintf(format,args);}
     74int getSize() {return delegate->getSize();}
     75// not overriden: VgetPath()
     76
     77DelegatedFILE(const char* _path,VirtFILE *_delegate):VirtFILE(_path),delegate(_delegate) {}
     78virtual ~DelegatedFILE() {if (delegate) delete delegate; delegate=NULL;}
    5079};
    5180
     
    6190public:
    6291virtual VirtFILE *Vfopen(const char* path,const char*mode);
    63 virtual int Vfexists(const char* path);
     92virtual bool Vfexists(const char* path);
    6493virtual VirtDIR *Vopendir(const char* path);
     94virtual bool Vmkdir(const char* path);
     95virtual bool Vmkdirs(const char* path);
     96virtual bool Vdirexists(const char* path,bool is_writable);
    6597};
     98
     99/// base class for chained filesystems - redirect unimplemented calls -> chain
     100class DLLEXP ChainFileSystem : public VirtFileSystem
     101{
     102public:
     103        VirtFileSystem *chain;
     104        ChainFileSystem(VirtFileSystem *_chain = NULL) :chain(_chain) {}
     105        VirtFILE *Vfopen(const char* path, const char*mode);
     106        bool Vfexists(const char* path);
     107        VirtDIR *Vopendir(const char* path);
     108        bool Vmkdir(const char* path);
     109        bool Vmkdirs(const char* path);
     110        bool Vdirexists(const char* path,bool is_writable);
     111};
     112
    66113
    67114DLLEXP VirtFILE *Vfopen(const char* path,const char*mode);
    68115DLLEXP VirtDIR *Vopendir(const char* path);
    69 DLLEXP int Vfexists(const char* path);
     116DLLEXP bool Vfexists(const char* path);
     117DLLEXP bool Vmkdir(const char* path);
     118DLLEXP bool Vmkdirs(const char* path);
     119DLLEXP bool Vdirexists(const char* path,bool is_writable);
    70120
    71121DLLEXP int fread(void *ptr, size_t size, size_t nmemb, VirtFILE* f);
Note: See TracChangeset for help on using the changeset viewer.