From 6d315d0e61f419636021476582a49ab0b1f1b5e9 Mon Sep 17 00:00:00 2001 From: Jared Adams Date: Thu, 5 Aug 2010 16:28:30 -0600 Subject: Add better XML error logging and do some related cleanup Error details from libxml2 are no longer ignored and are properly logged now. XML initialization code is now in the XML namespace. The XML::Document constructor that took a data pointer was removed because it wasn't being used and it would make the new logging less useful (no filename). Signed-off-by: Chuck Miller --- src/utils/xml.cpp | 51 ++++++++++++++++++++++++++++++++++++++++++++++----- src/utils/xml.h | 14 +++++--------- 2 files changed, 51 insertions(+), 14 deletions(-) (limited to 'src/utils') diff --git a/src/utils/xml.cpp b/src/utils/xml.cpp index 341f34c0..8d444fab 100644 --- a/src/utils/xml.cpp +++ b/src/utils/xml.cpp @@ -25,14 +25,30 @@ #include "resources/resourcemanager.h" -#include +#include +#include + #include +#include namespace XML { + static void xmlLogger(void *ctx, xmlErrorPtr error); + + struct XMLContext + { + std::string file; + bool resman; + }; + Document::Document(const std::string &filename, bool useResman): mDoc(0) { + XMLContext *ctx = new XMLContext(); + ctx->file = filename; + ctx->resman = useResman; + xmlSetStructuredErrorFunc(ctx, xmlLogger); + int size; char *data = NULL; if (useResman) @@ -75,11 +91,8 @@ namespace XML { logger->log("Error loading %s", filename.c_str()); } - } - Document::Document(const char *data, int size) - { - mDoc = xmlParseMemory(data, size); + xmlSetStructuredErrorFunc(NULL, xmlLogger); } Document::~Document() @@ -144,4 +157,32 @@ namespace XML return NULL; } + static void xmlLogger(void *ctx, xmlErrorPtr error) + { + XMLContext *context = static_cast(ctx); + + if (context) + logger->log("Error in XML file '%s' on line %d", + context->file.c_str(), error->line); + else + logger->log("Error in unknown xml file on line %d", + error->line); + + logger->log(error->message); + + // No need to keep errors around + xmlCtxtResetLastError(error->ctxt); + } + + void init() + { + // Initialize libxml2 and check for potential ABI mismatches between + // compiled version and the shared library actually used. + xmlInitParser(); + LIBXML_TEST_VERSION; + + // Handle libxml2 error messages + xmlSetStructuredErrorFunc(NULL, xmlLogger); + } + } // namespace XML diff --git a/src/utils/xml.h b/src/utils/xml.h index 72745501..8ffecb76 100644 --- a/src/utils/xml.h +++ b/src/utils/xml.h @@ -44,15 +44,6 @@ namespace XML */ Document(const std::string &filename, bool useResman = true); - /** - * Constructor that attempts to load an XML document from memory. - * Does not log errors. - * - * @param data the string to parse as XML - * @param size the length of the string in bytes - */ - Document(const char *data, int size); - /** * Destructor. Frees the loaded XML file. */ @@ -88,6 +79,11 @@ namespace XML * Finds the first child node with the given name */ xmlNodePtr findFirstChildByName(xmlNodePtr parent, const char *name); + + /** + * Initializes the XML engine. + */ + void init(); } #define for_each_xml_child_node(var, parent) \ -- cgit v1.2.3-70-g09d2 From 8eadc834ed3e8439836f7dc87390a56a1164ec11 Mon Sep 17 00:00:00 2001 From: Jared Adams Date: Fri, 13 Aug 2010 14:45:52 -0600 Subject: 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 --- mana.cbp | 2 + mana.files | 99 ++++++++++---------- src/CMakeLists.txt | 2 + src/Makefile.am | 2 + src/resources/mapreader.cpp | 142 +---------------------------- src/resources/resourcemanager.cpp | 45 ++++++++-- src/resources/resourcemanager.h | 9 +- src/utils/xml.cpp | 25 +----- src/utils/zlib.cpp | 184 ++++++++++++++++++++++++++++++++++++++ src/utils/zlib.h | 48 ++++++++++ 10 files changed, 338 insertions(+), 220 deletions(-) create mode 100644 src/utils/zlib.cpp create mode 100644 src/utils/zlib.h (limited to 'src/utils') diff --git a/mana.cbp b/mana.cbp index cc12f237..0f6e06c1 100644 --- a/mana.cbp +++ b/mana.cbp @@ -592,6 +592,8 @@ + + diff --git a/mana.files b/mana.files index 1a6026f3..e4547905 100644 --- a/mana.files +++ b/mana.files @@ -12,6 +12,9 @@ ./data/graphics/images/CMakeLists.txt ./data/graphics/images/Makefile.am ./data/graphics/Makefile.am +./data/graphics/sprites/CMakeLists.txt +./data/graphics/sprites/error.xml +./data/graphics/sprites/Makefile.am ./data/help/about.txt ./data/help/changes.txt ./data/help/CMakeLists.txt @@ -310,52 +313,6 @@ ./src/net/chathandler.h ./src/net/download.cpp ./src/net/download.h -./src/net/tmwa/adminhandler.cpp -./src/net/tmwa/adminhandler.h -./src/net/tmwa/beinghandler.cpp -./src/net/tmwa/beinghandler.h -./src/net/tmwa/buysellhandler.cpp -./src/net/tmwa/buysellhandler.h -./src/net/tmwa/charserverhandler.cpp -./src/net/tmwa/charserverhandler.h -./src/net/tmwa/chathandler.cpp -./src/net/tmwa/chathandler.h -./src/net/tmwa/gamehandler.cpp -./src/net/tmwa/gamehandler.h -./src/net/tmwa/generalhandler.cpp -./src/net/tmwa/generalhandler.h -./src/net/tmwa/gui/guildtab.cpp -./src/net/tmwa/gui/guildtab.h -./src/net/tmwa/guildhandler.cpp -./src/net/tmwa/guildhandler.h -./src/net/tmwa/gui/partytab.cpp -./src/net/tmwa/gui/partytab.h -./src/net/tmwa/inventoryhandler.cpp -./src/net/tmwa/inventoryhandler.h -./src/net/tmwa/itemhandler.cpp -./src/net/tmwa/itemhandler.h -./src/net/tmwa/loginhandler.cpp -./src/net/tmwa/loginhandler.h -./src/net/tmwa/messagehandler.cpp -./src/net/tmwa/messagehandler.h -./src/net/tmwa/messagein.cpp -./src/net/tmwa/messagein.h -./src/net/tmwa/messageout.cpp -./src/net/tmwa/messageout.h -./src/net/tmwa/network.cpp -./src/net/tmwa/network.h -./src/net/tmwa/npchandler.cpp -./src/net/tmwa/npchandler.h -./src/net/tmwa/partyhandler.cpp -./src/net/tmwa/partyhandler.h -./src/net/tmwa/playerhandler.cpp -./src/net/tmwa/playerhandler.h -./src/net/tmwa/protocol.h -./src/net/tmwa/specialhandler.cpp -./src/net/tmwa/specialhandler.h -./src/net/tmwa/token.h -./src/net/tmwa/tradehandler.cpp -./src/net/tmwa/tradehandler.h ./src/net/gamehandler.h ./src/net/generalhandler.h ./src/net/guildhandler.h @@ -423,6 +380,52 @@ ./src/net/playerhandler.h ./src/net/serverinfo.h ./src/net/specialhandler.h +./src/net/tmwa/adminhandler.cpp +./src/net/tmwa/adminhandler.h +./src/net/tmwa/beinghandler.cpp +./src/net/tmwa/beinghandler.h +./src/net/tmwa/buysellhandler.cpp +./src/net/tmwa/buysellhandler.h +./src/net/tmwa/charserverhandler.cpp +./src/net/tmwa/charserverhandler.h +./src/net/tmwa/chathandler.cpp +./src/net/tmwa/chathandler.h +./src/net/tmwa/gamehandler.cpp +./src/net/tmwa/gamehandler.h +./src/net/tmwa/generalhandler.cpp +./src/net/tmwa/generalhandler.h +./src/net/tmwa/gui/guildtab.cpp +./src/net/tmwa/gui/guildtab.h +./src/net/tmwa/guildhandler.cpp +./src/net/tmwa/guildhandler.h +./src/net/tmwa/gui/partytab.cpp +./src/net/tmwa/gui/partytab.h +./src/net/tmwa/inventoryhandler.cpp +./src/net/tmwa/inventoryhandler.h +./src/net/tmwa/itemhandler.cpp +./src/net/tmwa/itemhandler.h +./src/net/tmwa/loginhandler.cpp +./src/net/tmwa/loginhandler.h +./src/net/tmwa/messagehandler.cpp +./src/net/tmwa/messagehandler.h +./src/net/tmwa/messagein.cpp +./src/net/tmwa/messagein.h +./src/net/tmwa/messageout.cpp +./src/net/tmwa/messageout.h +./src/net/tmwa/network.cpp +./src/net/tmwa/network.h +./src/net/tmwa/npchandler.cpp +./src/net/tmwa/npchandler.h +./src/net/tmwa/partyhandler.cpp +./src/net/tmwa/partyhandler.h +./src/net/tmwa/playerhandler.cpp +./src/net/tmwa/playerhandler.h +./src/net/tmwa/protocol.h +./src/net/tmwa/specialhandler.cpp +./src/net/tmwa/specialhandler.h +./src/net/tmwa/token.h +./src/net/tmwa/tradehandler.cpp +./src/net/tmwa/tradehandler.h ./src/net/tradehandler.h ./src/net/worldinfo.h ./src/npc.cpp @@ -531,9 +534,13 @@ ./src/utils/stringutils.h ./src/utils/xml.cpp ./src/utils/xml.h +./src/utils/zlib.cpp +./src/utils/zlib.h ./src/vector.cpp ./src/vector.h ./src/winver.h +./tools/dyecmd/CMakeLists.txt +./tools/dyecmd/src/CMakeLists.txt ./tools/dyecmd/src/dyecmd.cpp ./tools/dyecmd/src/dye.cpp ./tools/dyecmd/src/dye.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9b38b496..6c470aef 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -402,6 +402,8 @@ SET(SRCS utils/mkdir.h utils/xml.cpp utils/xml.h + utils/zlib.cpp + utils/zlib.h animatedsprite.cpp animatedsprite.h animationparticle.cpp diff --git a/src/Makefile.am b/src/Makefile.am index d12a9a56..1f2391a8 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -301,6 +301,8 @@ mana_SOURCES = gui/widgets/avatarlistbox.cpp \ utils/mutex.h \ utils/xml.cpp \ utils/xml.h \ + utils/zlib.cpp \ + utils/zlib.h \ animatedsprite.cpp \ animatedsprite.h \ animationparticle.cpp \ 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 #include -#include // 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 #include @@ -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 free(). * - * @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 NULL 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. diff --git a/src/utils/xml.cpp b/src/utils/xml.cpp index 8d444fab..9835f88c 100644 --- a/src/utils/xml.cpp +++ b/src/utils/xml.cpp @@ -25,12 +25,11 @@ #include "resources/resourcemanager.h" +#include "utils/zlib.h" + #include #include -#include -#include - namespace XML { static void xmlLogger(void *ctx, xmlErrorPtr error); @@ -58,25 +57,7 @@ namespace XML } else { - std::ifstream file; - file.open(filename.c_str(), std::ios::in); - - if (file.is_open()) - { - // Get length of file - file.seekg (0, std::ios::end); - size = file.tellg(); - file.seekg(0, std::ios::beg); - - data = (char*) malloc(size); - - file.read(data, size); - file.close(); - } - else - { - logger->log("Error loading XML file %s", filename.c_str()); - } + data = (char *) loadCompressedFile(filename, size); } if (data) diff --git a/src/utils/zlib.cpp b/src/utils/zlib.cpp new file mode 100644 index 00000000..8e2a1795 --- /dev/null +++ b/src/utils/zlib.cpp @@ -0,0 +1,184 @@ +/* + * The Mana Client + * Copyright (C) 2004-2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * + * This file is part of The Mana Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "utils/zlib.h" + +#include "log.h" + +#include +#include +#include +#include +#include + +/** + * 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 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 data!"); + } + + free(out); + out = NULL; + outLength = 0; + } + + return outLength; +} + +void *loadCompressedFile(const std::string &filename, int &filesize) +{ + std::ifstream file; + file.open(filename.c_str(), std::ios::in); + + if (file.is_open()) + { + // Get length of file + file.seekg (0, std::ios::end); + filesize = file.tellg(); + file.seekg(0, std::ios::beg); + + char *buffer = (char *) malloc(filesize); + + file.read(buffer, filesize); + file.close(); + + unsigned char *inflated; + unsigned int inflatedSize; + + if (inflated && 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; + } + } + else + { + logger->log("Error loading file from drive: %s", filename.c_str()); + } + + return NULL; +} diff --git a/src/utils/zlib.h b/src/utils/zlib.h new file mode 100644 index 00000000..003e64b6 --- /dev/null +++ b/src/utils/zlib.h @@ -0,0 +1,48 @@ +/* + * The Mana Client + * Copyright (C) 2007-2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * + * This file is part of The Mana Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef UTILS_ZLIB_H +#define UTILS_ZLIB_H + +#include + +/** + * 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 inflateMemory(unsigned char *in, unsigned int inLength, + unsigned char *&out); + +/** + * Loads the given file from the filesystem, uncompressing if it ends in ".gz". + * + * @param filename The name of the file to be loaded and uncompressed + * @param filesize The size of the file that was loaded and uncompressed. + * + * @return An allocated byte array containing the data that was loaded and + * uncompressed, or NULL on fail. + */ +void *loadCompressedFile(const std::string &filename, int &filesize); + +#endif // UTILS_ZLIB_H -- cgit v1.2.3-70-g09d2