Browse Source

improved FileSystem
- ZipFileSystem is thread safe now
- added "s" Streaming mode support for opened zip files
- added FileSystem::read

dmuratshin 9 years ago
parent
commit
ef1d5d71e7

+ 19 - 0
oxygine/src/core/FileSystem.cpp

@@ -2,6 +2,7 @@
 #include "utils/stringUtils.h"
 #include <string.h>
 #include <algorithm>
+#include "file.h"
 
 namespace oxygine
 {
@@ -85,6 +86,11 @@ namespace oxygine
             FUNC(open, _open, write, file, (file, mode, ep, fh));
         }
 
+        FileSystem::status FileSystem::read(const char* file, file::buffer& bf, error_policy ep)
+        {
+            FUNC(read, _read, false, file, (file, bf, ep));
+        }
+
         void FileSystem::mount(FileSystem* fs)
         {
             filesystems::iterator i = std::find(_filesystems.begin(), _filesystems.end(), fs);
@@ -101,6 +107,19 @@ namespace oxygine
             }
         }
 
+        /*
+        FileSystem::status FileSystem::_read(const char* file, file::buffer &bf, error_policy ep)
+        {
+            fileHandle* fh = 0;
+            status s = _open(file, "rb", ep_ignore_error, fh);
+            if (!fh)
+                return status_error;
+            fh->
+            fh->read()
+            fh->release();
+        }
+        */
+
         bool FileSystem::_isExists(const char* file)
         {
             fileHandle* fh = 0;

+ 4 - 0
oxygine/src/core/FileSystem.h

@@ -6,6 +6,8 @@ namespace oxygine
 {
     namespace file
     {
+        class buffer;
+
         class fileHandle: public ObjectBase
         {
         public:
@@ -42,12 +44,14 @@ namespace oxygine
             status deleteDirectory(const char* path);
 
             status open(const char* file, const char* mode, error_policy ep, fileHandle*& fh);
+            status read(const char* file, file::buffer& bf, error_policy ep);
 
             void mount(FileSystem* fs);
             void unmount(FileSystem* fs);
 
         protected:
             virtual status _open(const char* file, const char* mode, error_policy ep, fileHandle*&) = 0;
+            virtual status _read(const char* file, file::buffer&, error_policy ep) = 0;
             virtual bool _isExists(const char* file);
             virtual status _deleteFile(const char* file) = 0;
             virtual status _makeDirectory(const char* path) = 0;

+ 30 - 8
oxygine/src/core/STDFileSystem.cpp

@@ -105,6 +105,19 @@ namespace oxygine
 
         class STDFileSystem;
 
+        unsigned int oxGetSize(oxHandle* h)
+        {
+
+#if OXYGINE_SDL && !OXYGINE_FILESYSTEM_USE_STDIO
+            return (int)SDL_RWsize((SDL_RWops*)h);
+#else
+            oxFileSeek(h, 0, ox_FILESEEK_END);
+            unsigned int size = (unsigned int)oxFileTell(h);
+            oxFileSeek(h, 0, ox_FILESEEK_SET);
+            return size;
+#endif
+        }
+
         class fileHandleSTD: public fileHandle
         {
         public:
@@ -144,14 +157,7 @@ namespace oxygine
 
             virtual unsigned int getSize() const
             {
-#if OXYGINE_SDL && !OXYGINE_FILESYSTEM_USE_STDIO
-                return (int)SDL_RWsize((SDL_RWops*)_handle);
-#else
-                oxFileSeek(_handle, 0, ox_FILESEEK_END);
-                unsigned int size  = (unsigned int)oxFileTell(_handle);
-                oxFileSeek(_handle, 0, ox_FILESEEK_SET);
-                return size;
-#endif
+                return oxGetSize(_handle);
             }
 
         private:
@@ -190,6 +196,22 @@ namespace oxygine
         }
 
 
+        FileSystem::status STDFileSystem::_read(const char* file, file::buffer& dest, error_policy ep)
+        {
+            char buff[512];
+
+            oxHandle* h = oxFileOpen(_getFullPath(file, buff), "rb");
+            if (!h)
+                return status_error;
+            unsigned int size = oxGetSize(h);
+            dest.data.resize(size);
+            if (size)
+                oxFileRead(&dest.data[0], size, 1, h);
+
+            oxFileClose(h);
+            return status_ok;
+        }
+
         FileSystem::status STDFileSystem::_open(const char* file, const char* mode, error_policy ep, fileHandle*& fh)
         {
             char buff[512];

+ 1 - 0
oxygine/src/core/STDFileSystem.h

@@ -17,6 +17,7 @@ namespace oxygine
             std::string _path;
             char* _getFullPath(const char* path, char buff[512]);
 
+            status _read(const char* file, file::buffer&, error_policy ep);
             status _open(const char* file_, const char* mode, error_policy ep, fileHandle*& fh);
             status _deleteFile(const char* file);
             status _renameFile(const char* src, const char* dest);

+ 46 - 4
oxygine/src/core/ZipFileSystem.cpp

@@ -52,6 +52,8 @@ namespace oxygine
 
         void Zips::read(unzFile zp)
         {
+            //MutexAutoLock al(_lock);
+
             do
             {
                 unz_file_pos pos;
@@ -72,6 +74,8 @@ namespace oxygine
 
         void Zips::add(const unsigned char* data, unsigned int size)
         {
+            MutexAutoLock al(_lock);
+
             zlib_filefunc_def ff;
             fill_memory_filefunc(&ff);
 
@@ -94,6 +98,8 @@ namespace oxygine
 
         void Zips::add(std::vector<char>& data)
         {
+            MutexAutoLock al(_lock);
+
             zlib_filefunc_def ff;
             fill_memory_filefunc(&ff);
 
@@ -157,6 +163,8 @@ namespace oxygine
 
         void Zips::add(const char* name)
         {
+            MutexAutoLock al(_lock);
+
             zlib_filefunc_def zpfs;
             memset(&zpfs, 0, sizeof(zpfs));
 
@@ -195,8 +203,16 @@ namespace oxygine
             log::messageln("ZipFS, total files: %d", _files.size());
         }
 
+        bool Zips::isExists(const char* name)
+        {
+            MutexAutoLock al(_lock);
+            return getEntryByName(name) != 0;
+        }
+
         bool Zips::read(const char* name, file::buffer& bf)
         {
+            MutexAutoLock al(_lock);
+
             const file_entry* entry = getEntryByName(name);
             if (!entry)
                 return false;
@@ -205,11 +221,13 @@ namespace oxygine
 
         bool Zips::read(const file_entry* entry, file::buffer& bf)
         {
+            MutexAutoLock al(_lock);
             return readEntry(entry, bf);
         }
 
         void Zips::reset()
         {
+            MutexAutoLock al(_lock);
             for (zips::iterator i = _zps.begin(); i != _zps.end(); ++i)
             {
                 zpitem& f = *i;
@@ -261,6 +279,7 @@ namespace oxygine
             return _files.size();
         }
 
+
         class fileHandleZip: public fileHandle
         {
         public:
@@ -319,8 +338,9 @@ namespace oxygine
             file::handle _h;
             long _pos;
             long _size;
+            long _cpos;
 
-            fileHandleZipStreaming(const file_entry* entry, const Zips& z)
+            fileHandleZipStreaming(const file_entry* entry, const Zips& z): _cpos(0)
             {
                 int r = 0;
                 r = unzGoToFilePos(entry->zp, const_cast<unz_file_pos*>(&entry->pos));
@@ -351,7 +371,13 @@ namespace oxygine
 
             unsigned int read(void* dest, unsigned int size)
             {
-                return file::read(_h, dest, size);
+                if (_cpos + size > _size)
+                    size = _size - _cpos;
+
+                unsigned int ret = file::read(_h, dest, size);
+                _cpos += ret;
+
+                return ret;
             }
 
             unsigned int write(const void* src, unsigned int size)
@@ -370,10 +396,13 @@ namespace oxygine
                 switch (whence)
                 {
                     case SEEK_SET:
+                        _cpos = offset;
                         return file::seek(_h, _pos + offset, SEEK_SET);
                     case SEEK_CUR:
+                        _cpos += offset;
                         return file::seek(_h, offset, SEEK_CUR);
                     case SEEK_END:
+                        _cpos = _size;
                         return file::seek(_h, offset, SEEK_END);
                     default:
                         break;
@@ -384,7 +413,7 @@ namespace oxygine
 
             unsigned int tell() const
             {
-                return file::tell(_h) - _pos;
+                return _cpos;
             }
 
         };
@@ -412,12 +441,20 @@ namespace oxygine
             _zips.reset();
         }
 
+        FileSystem::status ZipFileSystem::_read(const char* file, file::buffer& bf, error_policy ep)
+        {
+            if (_zips.read(file, bf))
+                return status_ok;
+
+            return status_error;
+        }
+
         FileSystem::status ZipFileSystem::_open(const char* file, const char* mode, error_policy ep, file::fileHandle*& fh)
         {
             const file_entry* entry = _zips.getEntryByName(file);
             if (entry)
             {
-                if (*mode == '.')
+                if (*mode == 's')
                     fh = new fileHandleZipStreaming(entry, _zips);
                 else
                     fh = new fileHandleZip(entry);
@@ -428,6 +465,11 @@ namespace oxygine
             return status_error;
         }
 
+        bool ZipFileSystem::_isExists(const char* file)
+        {
+            return _zips.isExists(file);
+        }
+
         FileSystem::status ZipFileSystem::_deleteFile(const char* file)
         {
             return status_error;

+ 3 - 0
oxygine/src/core/ZipFileSystem.h

@@ -33,6 +33,7 @@ namespace oxygine
 
             bool read(const char* name, file::buffer& bf);
             bool read(const file_entry* entry, file::buffer& bf);
+            bool isExists(const char* name);
 
             const file_entry*   getEntryByName(const char* name);
             const file_entry*   getEntry(int index);
@@ -82,11 +83,13 @@ namespace oxygine
 
             Zips _zips;
 
+            status _read(const char* file, file::buffer&, error_policy ep);
             status _open(const char* file, const char* mode, error_policy ep, file::fileHandle*& fh);
             status _deleteFile(const char* file);
             status _makeDirectory(const char* file);
             status _deleteDirectory(const char* file);
             status _renameFile(const char* src, const char* dest);
+            bool _isExists(const char* file);
 
         };
     }

+ 9 - 5
oxygine/src/core/file.cpp

@@ -169,15 +169,19 @@ namespace oxygine
             return fh->read(dest, destSize);
         }
 
-        void read(const char* file, buffer& dest, error_policy ep)
+        bool read(const char* file_, buffer& dest, error_policy ep)
         {
-            dest.data.clear();
+            LOGD("open file: %s %s %d", file_, mode, _openedFiles);
+            char file[512];
+            path::normalize(file_, file);
 
-            autoClose ac(open(file, "rb", ep));
-            if (ac.getHandle())
+            dest.data.clear();
+            bool ok = _nfs.read(file, dest, ep) == FileSystem::status_ok;
+            if (!ok)
             {
-                read(ac.getHandle(), dest);
+                handleErrorPolicy(ep, "can't read file: %s to buffer", file);
             }
+            return ok;
         }
 
         unsigned int read(handle fh_, buffer& dest)

+ 1 - 1
oxygine/src/core/file.h

@@ -62,7 +62,7 @@ namespace oxygine
         unsigned int read(handle, void* dest, unsigned int size);
 
         /**Reads bytes into destination buffer with stdio flags = "rb". Clears existing buffer*/
-        void read(const char* file, buffer& dest, error_policy ep = ep_show_error);
+        bool read(const char* file, buffer& dest, error_policy ep = ep_show_error);
 
         /**Reads bytes into destination buffer with stdio flags = "wb"*/
         unsigned int read(handle, buffer& dest);