summaryrefslogtreecommitdiff
path: root/src/resources
diff options
context:
space:
mode:
authorJared Adams <jaxad0127@gmail.com>2010-08-13 14:45:52 -0600
committerJared Adams <jaxad0127@gmail.com>2010-08-13 18:43:16 -0600
commit8eadc834ed3e8439836f7dc87390a56a1164ec11 (patch)
tree36cf9915914517b137d488a40d1f61265867723d /src/resources
parent6d315d0e61f419636021476582a49ab0b1f1b5e9 (diff)
downloadmana-8eadc834ed3e8439836f7dc87390a56a1164ec11.tar.gz
mana-8eadc834ed3e8439836f7dc87390a56a1164ec11.tar.bz2
mana-8eadc834ed3e8439836f7dc87390a56a1164ec11.tar.xz
mana-8eadc834ed3e8439836f7dc87390a56a1164ec11.zip
Simplify handling of compressed files
ResourceManager will now check for ".gz" and act appropriately (unless told not to). Compression handling functions are now in new utils/zlib files, along with a function to load a file from drive, uncompressing it if it ends in ".gz". Reviewed-by: Freeyorp
Diffstat (limited to 'src/resources')
-rw-r--r--src/resources/mapreader.cpp142
-rw-r--r--src/resources/resourcemanager.cpp45
-rw-r--r--src/resources/resourcemanager.h9
3 files changed, 44 insertions, 152 deletions
diff --git a/src/resources/mapreader.cpp b/src/resources/mapreader.cpp
index a8582c9b..b7c4fd72 100644
--- a/src/resources/mapreader.cpp
+++ b/src/resources/mapreader.cpp
@@ -33,10 +33,9 @@
#include "utils/base64.h"
#include "utils/stringutils.h"
#include "utils/xml.h"
+#include "utils/zlib.h"
-#include <cassert>
#include <iostream>
-#include <zlib.h>
// DO NOT CHANGE THESE STRINGS TO BE PASSED BY REFERENCE, AS THIS METHOD ALTERS
// (THAT IS, DESTROYS) THEM.
@@ -66,149 +65,12 @@ static std::string resolveRelativePath(std::string base, std::string relative)
return base + relative;
}
-/**
- * Inflates either zlib or gzip deflated memory. The inflated memory is
- * expected to be freed by the caller.
- */
-int inflateMemory(unsigned char *in, unsigned int inLength,
- unsigned char *&out, unsigned int &outLength)
-{
- int bufferSize = 256 * 1024;
- int ret;
- z_stream strm;
-
- out = (unsigned char*) malloc(bufferSize);
-
- strm.zalloc = Z_NULL;
- strm.zfree = Z_NULL;
- strm.opaque = Z_NULL;
- strm.next_in = in;
- strm.avail_in = inLength;
- strm.next_out = out;
- strm.avail_out = bufferSize;
-
- ret = inflateInit2(&strm, 15 + 32);
-
- if (ret != Z_OK)
- return ret;
-
- do
- {
- if (strm.next_out == NULL)
- {
- inflateEnd(&strm);
- return Z_MEM_ERROR;
- }
-
- ret = inflate(&strm, Z_NO_FLUSH);
- assert(ret != Z_STREAM_ERROR);
-
- switch (ret)
- {
- case Z_NEED_DICT:
- ret = Z_DATA_ERROR;
- case Z_DATA_ERROR:
- case Z_MEM_ERROR:
- (void) inflateEnd(&strm);
- return ret;
- }
-
- if (ret != Z_STREAM_END)
- {
- out = (unsigned char*) realloc(out, bufferSize * 2);
-
- if (out == NULL)
- {
- inflateEnd(&strm);
- return Z_MEM_ERROR;
- }
-
- strm.next_out = out + bufferSize;
- strm.avail_out = bufferSize;
- bufferSize *= 2;
- }
- }
- while (ret != Z_STREAM_END);
- assert(strm.avail_in == 0);
-
- outLength = bufferSize - strm.avail_out;
- (void) inflateEnd(&strm);
- return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
-}
-
-int inflateMemory(unsigned char *in, unsigned int inLength,
- unsigned char *&out)
-{
- unsigned int outLength = 0;
- int ret = inflateMemory(in, inLength, out, outLength);
-
- if (ret != Z_OK || out == NULL)
- {
- if (ret == Z_MEM_ERROR)
- {
- logger->log("Error: Out of memory while decompressing map data!");
- }
- else if (ret == Z_VERSION_ERROR)
- {
- logger->log("Error: Incompatible zlib version!");
- }
- else if (ret == Z_DATA_ERROR)
- {
- logger->log("Error: Incorrect zlib compressed data!");
- }
- else
- {
- logger->log("Error: Unknown error while decompressing map data!");
- }
-
- free(out);
- out = NULL;
- outLength = 0;
- }
-
- return outLength;
-}
-
Map *MapReader::readMap(const std::string &filename)
{
logger->log("Attempting to read map %s", filename.c_str());
- // Load the file through resource manager
- ResourceManager *resman = ResourceManager::getInstance();
- int fileSize;
- void *buffer = resman->loadFile(filename, fileSize);
Map *map = NULL;
- if (buffer == NULL)
- {
- logger->log("Map file not found (%s)", filename.c_str());
- return NULL;
- }
-
- unsigned char *inflated;
- unsigned int inflatedSize;
-
- if (filename.find(".gz", filename.length() - 3) != std::string::npos)
- {
- // Inflate the gzipped map data
- inflatedSize =
- inflateMemory((unsigned char*) buffer, fileSize, inflated);
- free(buffer);
-
- if (inflated == NULL)
- {
- logger->log("Could not decompress map file (%s)",
- filename.c_str());
- return NULL;
- }
- }
- else
- {
- inflated = (unsigned char*) buffer;
- inflatedSize = fileSize;
- }
-
- XML::Document doc((char*) inflated, inflatedSize);
- free(inflated);
+ XML::Document doc(filename);
xmlNodePtr node = doc.rootNode();
diff --git a/src/resources/resourcemanager.cpp b/src/resources/resourcemanager.cpp
index f785f20a..c63b626e 100644
--- a/src/resources/resourcemanager.cpp
+++ b/src/resources/resourcemanager.cpp
@@ -31,6 +31,8 @@
#include "resources/soundeffect.h"
#include "resources/spritedef.h"
+#include "utils/zlib.h"
+
#include <physfs.h>
#include <SDL_image.h>
@@ -411,34 +413,59 @@ void ResourceManager::deleteInstance()
instance = NULL;
}
-void *ResourceManager::loadFile(const std::string &fileName, int &fileSize)
+void *ResourceManager::loadFile(const std::string &filename, int &filesize,
+ bool inflate)
{
// Attempt to open the specified file using PhysicsFS
- PHYSFS_file *file = PHYSFS_openRead(fileName.c_str());
+ PHYSFS_file *file = PHYSFS_openRead(filename.c_str());
// If the handler is an invalid pointer indicate failure
if (file == NULL)
{
logger->log("Warning: Failed to load %s: %s",
- fileName.c_str(), PHYSFS_getLastError());
+ filename.c_str(), PHYSFS_getLastError());
return NULL;
}
// Log the real dir of the file
- logger->log("Loaded %s/%s", PHYSFS_getRealDir(fileName.c_str()),
- fileName.c_str());
+ logger->log("Loaded %s/%s", PHYSFS_getRealDir(filename.c_str()),
+ filename.c_str());
// Get the size of the file
- fileSize = PHYSFS_fileLength(file);
+ filesize = PHYSFS_fileLength(file);
// Allocate memory and load the file
- void *buffer = malloc(fileSize);
- PHYSFS_read(file, buffer, 1, fileSize);
+ void *buffer = malloc(filesize);
+ PHYSFS_read(file, buffer, 1, filesize);
// Close the file and let the user deallocate the memory
PHYSFS_close(file);
- return buffer;
+ unsigned char *inflated;
+ unsigned int inflatedSize;
+
+ if (inflate && filename.find(".gz", filename.length() - 3)
+ != std::string::npos)
+ {
+ // Inflate the gzipped map data
+ inflatedSize =
+ inflateMemory((unsigned char*) buffer, filesize, inflated);
+ free(buffer);
+
+ if (inflated == NULL)
+ {
+ logger->log("Could not decompress file: %s",
+ filename.c_str());
+ return NULL;
+ }
+
+ filesize = inflatedSize;
+ return inflated;
+ }
+ else
+ {
+ return buffer;
+ }
}
bool ResourceManager::copyFile(const std::string &src, const std::string &dst)
diff --git a/src/resources/resourcemanager.h b/src/resources/resourcemanager.h
index e1aed521..28ab4725 100644
--- a/src/resources/resourcemanager.h
+++ b/src/resources/resourcemanager.h
@@ -183,13 +183,16 @@ class ResourceManager
* Allocates data into a buffer pointer for raw data loading. The
* returned data is expected to be freed using <code>free()</code>.
*
- * @param fileName The name of the file to be loaded.
- * @param fileSize The size of the file that was loaded.
+ * @param filename The name of the file to be loaded.
+ * @param filesize The size of the file that was loaded.
+ * @param inflate True to uncompress the file if the filename ends in
+ * ".gz", false to ignore that.
*
* @return An allocated byte array containing the data that was loaded,
* or <code>NULL</code> on fail.
*/
- void *loadFile(const std::string &fileName, int &fileSize);
+ void *loadFile(const std::string &filename, int &filesize,
+ bool inflate = true);
/**
* Retrieves the contents of a text file.