00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00032 #include "SO3ScolFileSystem.h"
00033 #include <io.h>
00034 #include "scol.h"
00035
00036 namespace SO3
00037 {
00038
00039
00040 SO3ScolFileSystemArchive::SO3ScolFileSystemArchive(const Ogre::String& name, const Ogre::String& archType) : Ogre::Archive(name, archType)
00041 {
00042 if(!is_absolute_path(name.c_str()))
00043 {
00044
00045 char* tempPath = (char*) malloc(name.size()+1);
00046 char* tempReturnPath = (char*) malloc(SO3_MAX_PATH);
00047
00048 *tempPath = *name.c_str();
00049 if(SPfindfile((packdir)SCgetExtra("FirstPack"), tempPath, 0, tempReturnPath) == -1)
00050 {
00051 free(tempPath);
00052 free(tempReturnPath);
00053 OGRE_EXCEPT(Ogre::Exception::ERR_FILE_NOT_FOUND, "The archive \""+ name +"\" was not found in any of the defined Scol partitions", "SO3ScolFileSystemArchive::SO3ScolFileSystemArchive");
00054 }
00055
00056 scolPartitionPath = Ogre::String(tempReturnPath);
00057 free(tempReturnPath);
00058 free(tempPath);
00059 }
00060 else
00061 {
00062
00063 scolPartitionPath = "";
00064 }
00065 }
00066
00067
00068 bool SO3ScolFileSystemArchive::isCaseSensitive() const
00069 {
00070 return false;
00071 }
00072
00073
00074 bool SO3ScolFileSystemArchive::is_reserved_dir(const char*fn)
00075 {
00076 return (fn [0] == '.' && (fn [1] == 0 || (fn [1] == '.' && fn [2] == 0)));
00077 }
00078
00079
00080 bool SO3ScolFileSystemArchive::is_absolute_path(const char* path) const
00081 {
00082 if(isalpha(unsigned char(path[0])) && path[1] == ':')
00083 return true;
00084
00085 return path[0] == '/' || path[0] == '\\';
00086 }
00087
00088
00089 Ogre::String SO3ScolFileSystemArchive::scolToAbsolutePath(const Ogre::String& base, const Ogre::String& name) const
00090 {
00091 if(base.empty() || is_absolute_path(name.c_str()))
00092 return name;
00093 else
00094 {
00095 return scolPartitionPath + base + '/' + name;
00096 }
00097 }
00098
00099
00100 void SO3ScolFileSystemArchive::findFiles(const Ogre::String& pattern, bool recursive, bool dirs, Ogre::StringVector* simpleList, Ogre::FileInfoList* detailList)
00101 {
00102 long lHandle, res;
00103 struct _finddata_t tagData;
00104
00105
00106 size_t pos1 = pattern.rfind ('/');
00107 size_t pos2 = pattern.rfind ('\\');
00108 if(pos1 == pattern.npos || ((pos2 != pattern.npos) && (pos1 < pos2)))
00109 pos1 = pos2;
00110
00111 Ogre::String directory;
00112 if(pos1 != pattern.npos)
00113 directory = pattern.substr (0, pos1 + 1);
00114
00115 Ogre::String full_pattern = scolToAbsolutePath(mName, pattern);
00116
00117 lHandle = _findfirst(full_pattern.c_str(), &tagData);
00118 res = 0;
00119 while (lHandle != -1 && res != -1)
00120 {
00121 if((dirs == ((tagData.attrib & _A_SUBDIR) != 0)) &&
00122 ((tagData.attrib & _A_HIDDEN) == 0) &&
00123 (!dirs || !is_reserved_dir (tagData.name)))
00124 {
00125 if(simpleList)
00126 {
00127 simpleList->push_back(directory + tagData.name);
00128 }
00129 else if(detailList)
00130 {
00131 Ogre::FileInfo fi;
00132 fi.archive = this;
00133 fi.filename = directory + tagData.name;
00134 fi.basename = tagData.name;
00135 fi.path = directory;
00136 fi.compressedSize = tagData.size;
00137 fi.uncompressedSize = tagData.size;
00138 detailList->push_back(fi);
00139 }
00140 }
00141 res = _findnext( lHandle, &tagData );
00142 }
00143
00144
00145 if(lHandle != -1)
00146 _findclose(lHandle);
00147
00148
00149 if(recursive)
00150 {
00151 Ogre::String base_dir = mName;
00152 if(!directory.empty ())
00153 {
00154 base_dir = scolToAbsolutePath(mName, directory);
00155
00156 base_dir.erase (base_dir.length () - 1);
00157 }
00158 base_dir.append ("/*");
00159
00160
00161 Ogre::String mask ("/");
00162 if(pos1 != pattern.npos)
00163 mask.append (pattern.substr (pos1 + 1));
00164 else
00165 mask.append (pattern);
00166
00167 lHandle = _findfirst(base_dir.c_str (), &tagData);
00168 res = 0;
00169 while (lHandle != -1 && res != -1)
00170 {
00171 if((tagData.attrib & _A_SUBDIR) &&
00172 ((tagData.attrib & _A_HIDDEN) == 0 ) &&
00173 !is_reserved_dir (tagData.name))
00174 {
00175
00176 base_dir = directory;
00177 base_dir.append (tagData.name).append (mask);
00178 findFiles(base_dir, recursive, dirs, simpleList, detailList);
00179 }
00180 res = _findnext( lHandle, &tagData );
00181 }
00182
00183
00184 if(lHandle != -1)
00185 _findclose(lHandle);
00186 }
00187 }
00188
00189
00190 SO3ScolFileSystemArchive::~SO3ScolFileSystemArchive()
00191 {
00192 unload();
00193 }
00194
00195
00196 void SO3ScolFileSystemArchive::load()
00197 {
00198
00199 }
00200
00201
00202 void SO3ScolFileSystemArchive::unload()
00203 {
00204
00205 }
00206
00207
00208
00209 #if OGRE_VERSION < ((1 << 16) | (7 << 8) | 0)
00210 Ogre::DataStreamPtr SO3ScolFileSystemArchive::open(const Ogre::String& filename) const
00211 #else
00212 Ogre::DataStreamPtr SO3ScolFileSystemArchive::open(const Ogre::String& filename, bool readOnly) const
00213 #endif
00214 {
00215 Ogre::String full_path = scolToAbsolutePath(mName, filename);
00216
00217
00218
00219 struct stat tagStat;
00220 int ret = stat(full_path.c_str(), &tagStat);
00221 assert(ret == 0 && "Problem getting file size" );
00222
00223
00224 std::ifstream *origStream = OGRE_NEW_T(std::ifstream, Ogre::MEMCATEGORY_GENERAL)();
00225 origStream->open(full_path.c_str(), std::ios::in | std::ios::binary);
00226
00227
00228 if(origStream->fail())
00229 {
00230 OGRE_DELETE_T(origStream, basic_ifstream, Ogre::MEMCATEGORY_GENERAL);
00231 OGRE_EXCEPT(Ogre::Exception::ERR_FILE_NOT_FOUND, "Cannot open file: " + filename, "SO3ScolFileSystemArchive::open");
00232 }
00233
00234
00235 Ogre::FileStreamDataStream* stream = OGRE_NEW Ogre::FileStreamDataStream(filename, origStream, tagStat.st_size, true);
00236 return Ogre::DataStreamPtr(stream);
00237 }
00238
00239
00240 Ogre::StringVectorPtr SO3ScolFileSystemArchive::list(bool recursive, bool dirs)
00241 {
00242
00243
00244 Ogre::StringVectorPtr ret(OGRE_NEW_T(Ogre::StringVector, Ogre::MEMCATEGORY_GENERAL)(), Ogre::SPFM_DELETE_T);
00245
00246 findFiles("*", recursive, dirs, ret.getPointer(), 0);
00247
00248 return ret;
00249 }
00250
00251
00252 Ogre::FileInfoListPtr SO3ScolFileSystemArchive::listFileInfo(bool recursive, bool dirs)
00253 {
00254
00255 Ogre::FileInfoListPtr ret(OGRE_NEW_T(Ogre::FileInfoList, Ogre::MEMCATEGORY_GENERAL)(), Ogre::SPFM_DELETE_T);
00256
00257 findFiles("*", recursive, dirs, 0, ret.getPointer());
00258
00259 return ret;
00260 }
00261
00262
00263 Ogre::StringVectorPtr SO3ScolFileSystemArchive::find(const Ogre::String& pattern, bool recursive, bool dirs)
00264 {
00265
00266 Ogre::StringVectorPtr ret(OGRE_NEW_T(Ogre::StringVector, Ogre::MEMCATEGORY_GENERAL)(), Ogre::SPFM_DELETE_T);
00267
00268 findFiles(pattern, recursive, dirs, ret.getPointer(), 0);
00269
00270 return ret;
00271 }
00272
00273
00274
00275 #if OGRE_VERSION < ((1 << 16) | (7 << 8) | 0)
00276 Ogre::FileInfoListPtr SO3ScolFileSystemArchive::findFileInfo(const Ogre::String& pattern, bool recursive, bool dirs)
00277 #else
00278 Ogre::FileInfoListPtr SO3ScolFileSystemArchive::findFileInfo(const Ogre::String& pattern, bool recursive, bool dirs) const
00279 #endif
00280 {
00281
00282 Ogre::FileInfoListPtr ret(OGRE_NEW_T(Ogre::FileInfoList, Ogre::MEMCATEGORY_GENERAL)(), Ogre::SPFM_DELETE_T);
00283
00284 const_cast <SO3ScolFileSystemArchive*> (this)->findFiles(pattern, recursive, dirs, 0, ret.getPointer());
00285 return ret;
00286 }
00287
00288
00289 bool SO3ScolFileSystemArchive::exists(const Ogre::String& filename)
00290 {
00291 Ogre::String full_path = scolToAbsolutePath(mName, filename);
00292
00293 struct stat tagStat;
00294 bool ret = (stat(full_path.c_str(), &tagStat) == 0);
00295
00296
00297
00298 if(ret && is_absolute_path(filename.c_str()))
00299 {
00300
00301
00302 Ogre::String lowerCaseName = mName;
00303 Ogre::StringUtil::toLowerCase(lowerCaseName);
00304 ret = Ogre::StringUtil::startsWith(full_path, lowerCaseName, true);
00305
00306
00307
00308 }
00309
00310 return ret;
00311 }
00312
00313
00314 time_t SO3ScolFileSystemArchive::getModifiedTime(const Ogre::String& filename)
00315 {
00316 Ogre::String full_path = scolToAbsolutePath(mName, filename);
00317
00318 struct stat tagStat;
00319 bool ret = (stat(full_path.c_str(), &tagStat) == 0);
00320
00321 if(ret)
00322 return tagStat.st_mtime;
00323 else
00324 return 0;
00325 }
00326
00327 }