resourcemanager.cpp

Go to the documentation of this file.
00001 /*
00002  *  The Mana World
00003  *  Copyright 2004 The Mana World Development Team
00004  *
00005  *  This file is part of The Mana World.
00006  *
00007  *  The Mana World is free software; you can redistribute it and/or modify
00008  *  it under the terms of the GNU General Public License as published by
00009  *  the Free Software Foundation; either version 2 of the License, or
00010  *  any later version.
00011  *
00012  *  The Mana World is distributed in the hope that it will be useful,
00013  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  *  GNU General Public License for more details.
00016  *
00017  *  You should have received a copy of the GNU General Public License
00018  *  along with The Mana World; if not, write to the Free Software
00019  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00020  *
00021  *  $Id: resourcemanager.cpp 3010 2007-01-05 20:12:51Z gmelquio $
00022  */
00023 
00024 #include "resourcemanager.h"
00025 
00026 #include <physfs.h>
00027 
00028 #include "utils/logger.h"
00029 
00030 #ifdef WIN32
00031 #include <io.h>
00032 #include <direct.h>
00033 #else
00034 #include <unistd.h>
00035 #include <dirent.h>
00036 #endif
00037 
00038 #define TMWSERV_DATADIR ""
00039 
00040 ResourceManager *ResourceManager::instance = NULL;
00041 
00042 ResourceManager::ResourceManager()
00043 {
00044     // Add zip files to PhysicsFS
00045     searchAndAddZipFiles();
00046 }
00047 
00048 ResourceManager::~ResourceManager()
00049 {
00050 }
00051 
00052 ResourceManager*
00053 ResourceManager::getInstance()
00054 {
00055     // Create a new instance if necessary.
00056     if (instance == NULL) instance = new ResourceManager();
00057     return instance;
00058 }
00059 
00060 void
00061 ResourceManager::deleteInstance()
00062 {
00063     if (instance != NULL) {
00064         delete instance;
00065         instance = NULL;
00066     }
00067 }
00068 
00069 void
00070 ResourceManager::searchAndAddZipFiles()
00071 {
00072     // Add the main data directory to our PhysicsFS search path
00073     PHYSFS_addToSearchPath("data", 1);
00074     PHYSFS_addToSearchPath(TMWSERV_DATADIR "data", 1);
00075 
00076 #ifdef _WIN32
00077     // Define the path in which to search
00078     std::string searchString = std::string("data/*.zip");
00079 
00080     // Create our find file data structure
00081     struct _finddata_t findFileInfo;
00082 
00083     // Find the first zipped file
00084     long handle =
00085         static_cast<long>(::_findfirst(searchString.c_str(), &findFileInfo));
00086     long file = handle;
00087 
00088     // Loop until all files we're searching for are found
00089     while (file >= 0) {
00090         // Define the file path string
00091         std::string filePath = std::string("data/") +
00092             std::string(findFileInfo.name);
00093 
00094         LOG_INFO("Adding to PhysicsFS: " << findFileInfo.name);
00095 
00096         // Add the zip file to our PhysicsFS search path
00097         PHYSFS_addToSearchPath(filePath.c_str(), 1);
00098 
00099         // Find the next file
00100         file = ::_findnext(handle, &findFileInfo);
00101     }
00102 
00103     // Shutdown findfile stuff
00104     ::_findclose(handle);
00105 #else
00106     // Retrieve the current path
00107     char programPath[256];
00108     getcwd(programPath, 256);
00109     strncat(programPath, "/data", 256 - strlen(programPath) - 1);
00110 
00111     // Create our directory structure
00112     DIR *dir = opendir(programPath);
00113 
00114     // Return if the directory is invalid
00115     if (dir == NULL) {
00116         return;
00117     }
00118 
00119     struct dirent *direntry;
00120     while ((direntry = readdir(dir)) != NULL)
00121     {
00122         char *ext = strstr(direntry->d_name, ".zip");
00123 
00124         if (ext != NULL && strcmp(ext, ".zip") == 0)
00125         {
00126             // Define the file path string
00127             std::string filePath = std::string(programPath) +
00128                 std::string("/") + std::string(direntry->d_name);
00129 
00130             LOG_INFO("Adding to PhysicsFS: " << filePath);
00131 
00132             // Add the zip file to our PhysicsFS search path
00133             PHYSFS_addToSearchPath(filePath.c_str(), 1);
00134         }
00135     }
00136 
00137     closedir(dir);
00138 #endif
00139 }
00140 
00141 void*
00142 ResourceManager::loadFile(const std::string &fileName, int &fileSize)
00143 {
00144     // If the file doesn't exist indicate failure
00145     if (!PHYSFS_exists(fileName.c_str())) {
00146         LOG_WARN("Warning: " << fileName << " not found!");
00147         return NULL;
00148     }
00149 
00150     // Attempt to open the specified file using PhysicsFS
00151     PHYSFS_file* file = PHYSFS_openRead(fileName.c_str());
00152 
00153     // If the handler is an invalid pointer indicate failure
00154     if (file == NULL) {
00155         LOG_WARN("Warning: " << fileName << " failed to load!");
00156         return NULL;
00157     }
00158 
00159     // Get the size of the file
00160     fileSize = PHYSFS_fileLength(file);
00161 
00162     // Allocate memory and load the file
00163     void *buffer = malloc(fileSize);
00164     PHYSFS_read(file, buffer, 1, fileSize);
00165 
00166     // Close the file and let the user deallocate the memory
00167     PHYSFS_close(file);
00168 
00169     return buffer;
00170 }
00171 
00172 std::vector<std::string>
00173 ResourceManager::loadTextFile(const std::string &fileName)
00174 {
00175     int contentsLength;
00176     char *fileContents = (char*)loadFile(fileName, contentsLength);
00177     std::vector<std::string> lines;
00178 
00179     if (!fileContents)
00180     {
00181         LOG_ERROR("Couldn't load text file: " << fileName);
00182         return lines;
00183     }
00184 
00185     // Reallocate and include terminating 0 character
00186     fileContents = (char*)realloc(fileContents, contentsLength + 1);
00187     fileContents[contentsLength] = '\0';
00188 
00189     // Tokenize and add each line separately
00190     char *line = strtok(fileContents, "\n");
00191     while (line != NULL)
00192     {
00193         lines.push_back(line);
00194         line = strtok(NULL, "\n");
00195     }
00196 
00197     free(fileContents);
00198     return lines;
00199 }

Generated on Fri Mar 30 15:39:16 2007 for TMW Server by  doxygen 1.3.9.1