diff options
author | Guillaume Melquiond <guillaume.melquiond@gmail.com> | 2007-01-02 22:41:02 +0000 |
---|---|---|
committer | Guillaume Melquiond <guillaume.melquiond@gmail.com> | 2007-01-02 22:41:02 +0000 |
commit | 6b7441516002d6e7cca424416bb67c6bc7d7c9d2 (patch) | |
tree | 6ce7822b0ca6e0abdfbbd938575a3c5bcf7b5614 /src | |
parent | 59df651232df73c56b5dae587fa68e1e9f824755 (diff) | |
download | manaserv-6b7441516002d6e7cca424416bb67c6bc7d7c9d2.tar.gz manaserv-6b7441516002d6e7cca424416bb67c6bc7d7c9d2.tar.bz2 manaserv-6b7441516002d6e7cca424416bb67c6bc7d7c9d2.tar.xz manaserv-6b7441516002d6e7cca424416bb67c6bc7d7c9d2.zip |
Simplified MapReader interface and code. Fixed some memory leaks.
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 12 | ||||
-rw-r--r-- | src/game-server/mapmanager.cpp | 2 | ||||
-rw-r--r-- | src/game-server/mapreader.cpp | 262 | ||||
-rw-r--r-- | src/game-server/mapreader.hpp | 43 | ||||
-rw-r--r-- | src/map.h | 5 | ||||
-rw-r--r-- | src/mapreader.cpp | 380 | ||||
-rw-r--r-- | src/mapreader.h | 109 | ||||
-rw-r--r-- | src/properties.h | 77 | ||||
-rw-r--r-- | src/utils/zlib.cpp | 114 | ||||
-rw-r--r-- | src/utils/zlib.hpp | 35 |
10 files changed, 462 insertions, 577 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 7b4e27ee..759927e5 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -18,7 +18,6 @@ tmwserv_account_SOURCES = \ player.h \ player.cpp \ point.h \ - properties.h \ resourcemanager.h \ resourcemanager.cpp \ skill.h \ @@ -86,14 +85,11 @@ tmwserv_game_SOURCES = \ item.cpp \ map.h \ map.cpp \ - mapreader.h \ - mapreader.cpp \ object.h \ object.cpp \ player.h \ player.cpp \ point.h \ - properties.h \ resourcemanager.h \ resourcemanager.cpp \ skill.h \ @@ -108,6 +104,8 @@ tmwserv_game_SOURCES = \ game-server/mapcomposite.cpp \ game-server/mapmanager.hpp \ game-server/mapmanager.cpp \ + game-server/mapreader.hpp \ + game-server/mapreader.cpp \ game-server/state.hpp \ game-server/state.cpp \ game-server/testing.cpp \ @@ -134,8 +132,10 @@ tmwserv_game_SOURCES = \ utils/stringfilter.cpp \ utils/timer.h \ utils/timer.cpp \ - utils/xml.h \ - utils/xml.cpp + utils/xml.hpp \ + utils/xml.cpp \ + utils/zlib.hpp \ + utils/zlib.cpp if BUILD_MYSQL tmwserv_account_SOURCES += \ diff --git a/src/game-server/mapmanager.cpp b/src/game-server/mapmanager.cpp index 1cef6281..d3f431b2 100644 --- a/src/game-server/mapmanager.cpp +++ b/src/game-server/mapmanager.cpp @@ -24,9 +24,9 @@ #include <cassert> #include "map.h" -#include "mapreader.h" #include "resourcemanager.h" #include "game-server/mapmanager.hpp" +#include "game-server/mapreader.hpp" #include "utils/logger.h" #include "utils/xml.hpp" diff --git a/src/game-server/mapreader.cpp b/src/game-server/mapreader.cpp new file mode 100644 index 00000000..d3a49a3c --- /dev/null +++ b/src/game-server/mapreader.cpp @@ -0,0 +1,262 @@ +/* + * The Mana World + * Copyright 2004 The Mana World Development Team + * + * This file is part of The Mana World. + * + * The Mana World 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. + * + * The Mana World 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 The Mana World; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + */ + +#include "map.h" +#include "resourcemanager.h" +#include "game-server/mapreader.hpp" +#include "utils/base64.h" +#include "utils/logger.h" +#include "utils/xml.hpp" +#include "utils/zlib.hpp" + +static std::vector< int > tilesetFirstGids; + +static Map* readMap(xmlNodePtr node, std::string const &path); +static void readLayer(xmlNodePtr node, Map *map); +static void setTileWithGid(Map *map, int x, int y, int gid); + +Map *MapReader::readMap(const std::string &filename) +{ + // Load the file through resource manager. + ResourceManager *resman = ResourceManager::getInstance(); + int fileSize; + char *buffer = (char *)resman->loadFile(filename, fileSize); + + if (buffer == NULL) + { + LOG_ERROR("Error: Map file not found (" << filename.c_str() << ")", 0); + return NULL; + } + + // Inflate the gzipped map data. + char *inflated; + unsigned inflatedSize = 0; + bool ret = inflateMemory(buffer, fileSize, inflated, inflatedSize); + free(buffer); + + xmlDocPtr doc = NULL; + + if (ret) + { + doc = xmlParseMemory(inflated, inflatedSize); + free(inflated); + } + + if (!doc) + { + LOG_ERROR("Error while parsing map file (" << filename << ")!", 0); + return NULL; + } + + Map *map = NULL; + xmlNodePtr node = xmlDocGetRootElement(doc); + + // Parse the inflated map data. + if (node && xmlStrEqual(node->name, BAD_CAST "map")) + { + map = ::readMap(node, filename); + } + else + { + LOG_ERROR("Error: Not a map file (" << filename << ")!", 0); + } + + xmlFreeDoc(doc); + return map; +} + +static Map *readMap(xmlNodePtr node, std::string const &path) +{ + // Take the filename off the path + std::string pathDir = path.substr(0, path.rfind("/") + 1); + + int w = XML::getProperty(node, "width", 0); + int h = XML::getProperty(node, "height", 0); + // We only support tile width of 32 at the moment + //int tilew = getProperty(node, "tilewidth", DEFAULT_TILE_WIDTH); + //int tileh = getProperty(node, "tileheight", DEFAULT_TILE_HEIGHT); + int layerNr = 0; + Map* map = new Map(w, h); + + for (node = node->xmlChildrenNode; node != NULL; node = node->next) + { + /* // Properties are useless server-side. + if (xmlStrEqual(node->name, BAD_CAST "property")) + { + // Example: <property name="name" value="value"/> + + xmlChar *name = xmlGetProp(node, BAD_CAST "name"); + xmlChar *value = xmlGetProp(node, BAD_CAST "value"); + + if (name && value) + { + map->setProperty((const char*)name, (const char*)value); + } + + if (name) xmlFree(name); + if (value) xmlFree(value); + } + else + */ + if (xmlStrEqual(node->name, BAD_CAST "tileset")) + { + if (xmlHasProp(node, BAD_CAST "source")) + { + LOG_WARN("Warning: External tilesets not supported yet.", 0); + } + else + { + tilesetFirstGids.push_back(XML::getProperty(node, "firstgid", 0)); + } + } + else if (xmlStrEqual(node->name, BAD_CAST "layer")) + { + // Layer 3 is collision layer. + if (layerNr++ == 3) + { + readLayer(node, map); + } + } + } + + // Clean up tilesets + tilesetFirstGids.clear(); + + return map; +} + +static void readLayer(xmlNodePtr node, Map *map) +{ + node = node->xmlChildrenNode; + int h = map->getHeight(); + int w = map->getWidth(); + int x = 0; + int y = 0; + + // Load the tile data. Layers are assumed to be map size, with (0,0) as + // origin. + while (node != NULL) + { + if (xmlStrEqual(node->name, BAD_CAST "data")) + { + if (XML::getProperty(node, "encoding", std::string()) == "base64") + { + if (xmlHasProp(node, BAD_CAST "compression")) + { + LOG_WARN("Warning: no layer compression supported!", 0); + return; + } + + // Read base64 encoded map file + xmlNodePtr dataChild = node->xmlChildrenNode; + if (!dataChild) continue; + + int len = strlen((char const *)dataChild->content) + 1; + char *charData = new char[len + 1]; + char const *charStart = (char const *)dataChild->content; + char *charIndex = charData; + + while (*charStart) + { + if (*charStart != ' ' && *charStart != '\t' && *charStart != '\n') + { + *charIndex = *charStart; + ++charIndex; + } + ++charStart; + } + *charIndex = '\0'; + + int binLen; + unsigned char *binData = + php_base64_decode((unsigned char *)charData, strlen(charData), &binLen); + + delete[] charData; + + if (binData) + { + for (int i = 0; i < binLen - 3; i += 4) + { + int gid = binData[i] | + (binData[i + 1] << 8) | + (binData[i + 2] << 16) | + (binData[i + 3] << 24); + + setTileWithGid(map, x, y, gid); + + if (++x == w) + { + x = 0; + ++y; + } + } + free(binData); + } + } + else + { + // Read plain XML map file + xmlNodePtr n2 = node->xmlChildrenNode; + + while (n2 != NULL) + { + if (xmlStrEqual(n2->name, BAD_CAST "tile") && y < h) + { + int gid = XML::getProperty(n2, "gid", -1); + setTileWithGid(map, x, y, gid); + + if (++x == w) + { + x = 0; + ++y; + } + } + + n2 = n2->next; + } + } + + // There can be only one data element + break; + } + + node = node->next; + } +} + +static void setTileWithGid(Map *map, int x, int y, int gid) +{ + // Find the tileset with the highest firstGid below/eq to gid + int set = gid; + for (std::vector< int >::const_iterator i = tilesetFirstGids.begin(), + i_end = tilesetFirstGids.end(); i != i_end; ++i) + { + if (gid < *i) + { + break; + } + set = *i; + } + + map->setWalk(x, y, gid == set); +} diff --git a/src/game-server/mapreader.hpp b/src/game-server/mapreader.hpp new file mode 100644 index 00000000..ed49b24d --- /dev/null +++ b/src/game-server/mapreader.hpp @@ -0,0 +1,43 @@ +/* + * The Mana World + * Copyright 2004 The Mana World Development Team + * + * This file is part of The Mana World. + * + * The Mana World 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. + * + * The Mana World 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 The Mana World; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + */ + +#ifndef _INCLUDED_MAPREADER_H +#define _INCLUDED_MAPREADER_H + +#include <string> + +class Map; + +/** + * Reader for XML map files (*.tmx) + */ +class MapReader +{ + public: + /** + * Read an XML map from a file. + */ + static Map *readMap(const std::string &filename); +}; + +#endif @@ -28,8 +28,6 @@ #include <map> #include <string> -#include "properties.h" - struct PATH_NODE { PATH_NODE(unsigned short u, unsigned short v) @@ -85,7 +83,7 @@ class Location /** * A tile map. */ -class Map : public Properties +class Map { public: /** @@ -168,7 +166,6 @@ class Map : public Properties int width, height; int tileWidth, tileHeight; MetaTile *metaTiles; - std::map<std::string, std::string> properties; // Pathfinding members int onClosedList, onOpenList; diff --git a/src/mapreader.cpp b/src/mapreader.cpp deleted file mode 100644 index f16886c9..00000000 --- a/src/mapreader.cpp +++ /dev/null @@ -1,380 +0,0 @@ -/* - * The Mana World - * Copyright 2004 The Mana World Development Team - * - * This file is part of The Mana World. - * - * The Mana World 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. - * - * The Mana World 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 The Mana World; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * $Id$ - */ - -#include "mapreader.h" - -#include <cassert> -#include <zlib.h> - -#include "map.h" -#include "resourcemanager.h" - -#include "utils/base64.h" -#include "utils/logger.h" - -const unsigned int DEFAULT_TILE_WIDTH = 32; -const unsigned int DEFAULT_TILE_HEIGHT = 32; - -/** - * 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; -} - -std::vector<Tileset*> MapReader::tilesets; - -Map *MapReader::readMap(const std::string &filename) -{ - // Load the file through resource manager - ResourceManager *resman = ResourceManager::getInstance(); - int fileSize; - void *buffer = resman->loadFile(filename, fileSize); - - if (buffer == NULL) - { - LOG_ERROR("Error: Map file not found (" << filename.c_str() << ")", 0); - return NULL; - } - - // Inflate the gzipped map data - unsigned char *inflated; - unsigned int inflatedSize = 0; - int ret = inflateMemory((unsigned char*)buffer, fileSize, - inflated, inflatedSize); - free(buffer); - - if (ret == Z_MEM_ERROR) - { - LOG_ERROR("Error: Out of memory while decompressing map data!", 0); - return NULL; - } - else if (ret == Z_VERSION_ERROR) - { - LOG_ERROR("Error: Incompatible zlib version!", 0); - return NULL; - } - else if (ret == Z_DATA_ERROR) - { - LOG_ERROR("Error: Incorrect zlib compressed data!", 0); - return NULL; - } - else if (ret != Z_OK || inflated == NULL) - { - LOG_ERROR("Error: Unknown error while decompressing map data!", 0); - return NULL; - } - - xmlDocPtr doc = xmlParseMemory((char*)inflated, inflatedSize); - free(inflated); - - // Parse the inflated map data - if (doc) { - xmlNodePtr node = xmlDocGetRootElement(doc); - - if (!node || !xmlStrEqual(node->name, BAD_CAST "map")) { - LOG_ERROR("Error: Not a map file (" << filename << ")!", 0); - return NULL; - } - - return readMap(node, filename); - xmlFreeDoc(doc); - } else { - LOG_ERROR("Error while parsing map file (" << filename << ")!", 0); - } - - return NULL; -} - -Map* MapReader::readMap(xmlNodePtr node, const std::string &path) -{ - xmlChar *prop; - - // Take the filename off the path - std::string pathDir = path.substr(0, path.rfind("/") + 1); - - prop = xmlGetProp(node, BAD_CAST "version"); - xmlFree(prop); - - int w = getProperty(node, "width", 0); - int h = getProperty(node, "height", 0); - // We only support tile width of 32 at the moment - //int tilew = getProperty(node, "tilewidth", DEFAULT_TILE_WIDTH); - //int tileh = getProperty(node, "tileheight", DEFAULT_TILE_HEIGHT); - int layerNr = 0; - Map* map = new Map(w, h); - - for (node = node->xmlChildrenNode; node != NULL; node = node->next) - { - if (xmlStrEqual(node->name, BAD_CAST "property")) - { - // Example: <property name="name" value="value"/> - - xmlChar *name = xmlGetProp(node, BAD_CAST "name"); - xmlChar *value = xmlGetProp(node, BAD_CAST "value"); - - if (name && value) - { - map->setProperty((const char*)name, (const char*)value); - } - - if (name) xmlFree(name); - if (value) xmlFree(value); - } - else if (xmlStrEqual(node->name, BAD_CAST "tileset")) - { - Tileset *tileset = readTileset(node, pathDir, map); - if (tileset) { - tilesets.push_back(tileset); - } - } - else if (xmlStrEqual(node->name, BAD_CAST "layer")) - { - readLayer(node, map, layerNr); - layerNr++; - } - } - - // Clean up tilesets - // TODO: Dereference them somewhere - tilesets.clear(); - - return map; -} - -void MapReader::readLayer(xmlNodePtr node, Map *map, int layer) -{ - node = node->xmlChildrenNode; - int h = map->getHeight(); - int w = map->getWidth(); - int x = 0; - int y = 0; - - // Load the tile data. Layers are assumed to be map size, with (0,0) as - // origin. - while (node != NULL) - { - if (xmlStrEqual(node->name, BAD_CAST "data")) - { - xmlChar *encoding = xmlGetProp(node, BAD_CAST "encoding"); - xmlChar *compression = xmlGetProp(node, BAD_CAST "compression"); - - if (encoding && xmlStrEqual(encoding, BAD_CAST "base64")) - { - xmlFree(encoding); - - if (compression) { - LOG_WARN("Warning: no layer compression supported!", 0); - xmlFree(compression); - return; - } - - // Read base64 encoded map file - xmlNodePtr dataChild = node->xmlChildrenNode; - if (!dataChild) continue; - - int len = strlen((const char*)dataChild->content) + 1; - unsigned char *charData = new unsigned char[len + 1]; - const char *charStart = (const char*)dataChild->content; - unsigned char *charIndex = charData; - - while (*charStart) { - if (*charStart != ' ' && *charStart != '\t' && - *charStart != '\n') - { - *charIndex = *charStart; - charIndex++; - } - charStart++; - } - *charIndex = '\0'; - - int binLen; - unsigned char *binData = - php_base64_decode(charData, strlen((char*)charData), - &binLen); - - delete[] charData; - - if (binData) { - for (int i = 0; i < binLen - 3; i += 4) { - int gid = binData[i] | - binData[i + 1] << 8 | - binData[i + 2] << 16 | - binData[i + 3] << 24; - - setTileWithGid(map, x, y, layer, gid); - - x++; - if (x == w) {x = 0; y++;} - } - free(binData); - } - } - else { - // Read plain XML map file - xmlNodePtr n2 = node->xmlChildrenNode; - - while (n2 != NULL) - { - if (xmlStrEqual(n2->name, BAD_CAST "tile") && y < h) - { - int gid = getProperty(n2, "gid", -1); - setTileWithGid(map, x, y, layer, gid); - - x++; - if (x == w) {x = 0; y++;} - } - - n2 = n2->next; - } - } - - // There can be only one data element - break; - } - - node = node->next; - } -} - -Tileset* -MapReader::readTileset(xmlNodePtr node, const std::string &path, Map *map) -{ - if (xmlHasProp(node, BAD_CAST "source")) { - LOG_WARN("Warning: External tilesets not supported yet.", 0); - return NULL; - } - - int firstGid = getProperty(node, "firstgid", 0); - int tw = getProperty(node, "tilewidth", map->getTileWidth()); - int th = getProperty(node, "tileheight", map->getTileHeight()); - - return new Tileset(tw, th, firstGid); -} - -int MapReader::getProperty(xmlNodePtr node, const char* name, int def) -{ - xmlChar *prop = xmlGetProp(node, BAD_CAST name); - if (prop) { - int val = atoi((char*)prop); - xmlFree(prop); - return val; - } - else { - return def; - } -} - -Tileset *MapReader::getTilesetWithGid(int gid) -{ - std::vector<Tileset*>::iterator i; - Tileset *set = NULL; - - // Find the tileset with the highest firstGid below/eq to gid - for (i = tilesets.begin(); i != tilesets.end(); ++i) - { - if ((*i)->getFirstGid() <= gid) { - set = (*i); - } - else { - break; - } - } - - return set; -} - -void MapReader::setTileWithGid(Map *map, int x, int y, int layer, int gid) -{ - // Only load obstacle layer - if (layer == 3) - { - Tileset *set = getTilesetWithGid(gid); - map->setWalk(x, y, !set || (gid - set->getFirstGid() == 0)); - } -} diff --git a/src/mapreader.h b/src/mapreader.h deleted file mode 100644 index fe395e35..00000000 --- a/src/mapreader.h +++ /dev/null @@ -1,109 +0,0 @@ -/* - * The Mana World - * Copyright 2004 The Mana World Development Team - * - * This file is part of The Mana World. - * - * The Mana World 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. - * - * The Mana World 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 The Mana World; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * $Id$ - */ - -#ifndef _INCLUDED_MAPREADER_H -#define _INCLUDED_MAPREADER_H - -#include <libxml/tree.h> -#include <vector> - -class Map; - - -/** - * A tileset, which is on the server only used to store a firstgid. - */ -class Tileset -{ - public: - /** - * Constructor. - */ - Tileset(int w, int h, int firstGid): - mFirstGid(firstGid) - { - } - - /** - * Returns the first gid. - */ - int - getFirstGid() { return mFirstGid; } - - private: - int mFirstGid; -}; - -/** - * Reader for XML map files (*.tmx) - */ -class MapReader -{ - public: - /** - * Read an XML map from a file. - */ - static Map *readMap(const std::string &filename); - - /** - * Read an XML map from a parsed XML tree. The path is used to find the - * location of referenced tileset images. - */ - static Map *readMap(xmlNodePtr node, const std::string &path); - - private: - /** - * Reads a map layer. - */ - static void - readLayer(xmlNodePtr node, Map *map, int layer); - - /** - * Reads a tile set. - */ - static Tileset* - readTileset(xmlNodePtr node, const std::string &path, Map *map); - - /** - * Gets an integer property from an xmlNodePtr. - */ - static int - getProperty(xmlNodePtr node, const char* name, int def); - - /** - * Finds the tile set that a tile with the given global id is part of. - */ - static Tileset* - getTilesetWithGid(int gid); - - /** - * Sets a tile using a global tile id. Used by the layer loading - * routine. - */ - static void - setTileWithGid(Map *map, int x, int y, int layer, int gid); - - static std::vector<Tileset*> tilesets; -}; - -#endif diff --git a/src/properties.h b/src/properties.h deleted file mode 100644 index 5f8d751d..00000000 --- a/src/properties.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * The Mana World - * Copyright 2004 The Mana World Development Team - * - * This file is part of The Mana World. - * - * The Mana World 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. - * - * The Mana World 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 The Mana World; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * $Id$ - */ - -#ifndef _TMW_PROPERTIES_H_ -#define _TMW_PROPERTIES_H_ - -#include <map> -#include <string> - -/** - * A class holding a set of properties. - */ -class Properties -{ - public: - virtual - ~Properties() {} - - /** - * Get a map property. - * - * @return the value of the given property or an empty string when it - * doesn't exist. - */ - const std::string& - getProperty(const std::string &name) - { - const static std::string undefined = ""; - PropertyMap::const_iterator i = mProperties.find(name); - - return (i != mProperties.end()) ? i->second : undefined; - } - - /** - * Returns whether a certain property is available. - */ - bool - hasProperty(const std::string &name) - { - return mProperties.find(name) != mProperties.end(); - } - - /** - * Set a map property. - */ - void - setProperty(const std::string &name, const std::string &value) - { - mProperties[name] = value; - } - - private: - typedef std::map<std::string, std::string> PropertyMap; - PropertyMap mProperties; -}; - -#endif diff --git a/src/utils/zlib.cpp b/src/utils/zlib.cpp new file mode 100644 index 00000000..b72c70f5 --- /dev/null +++ b/src/utils/zlib.cpp @@ -0,0 +1,114 @@ +/* + * The Mana World + * Copyright 2006 The Mana World Development Team + * + * This file is part of The Mana World. + * + * The Mana World 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. + * + * The Mana World 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 The Mana World; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + */ + +#include <zlib.h> + +#include "utils/logger.h" +#include "utils/zlib.hpp" + +static void logZlibError(int error) +{ + switch (error) + { + case Z_MEM_ERROR: + LOG_ERROR("Out of memory while decompressing data!", 0); + break; + case Z_VERSION_ERROR: + LOG_ERROR("Incompatible zlib version!", 0); + break; + case Z_DATA_ERROR: + LOG_ERROR("Incorrect zlib compressed data!", 0); + break; + default: + LOG_ERROR("Unknown error while decompressing data!", 0); + } +} + +bool inflateMemory(char *in, unsigned inLength, + char *&out, unsigned &outLength) +{ + int bufferSize = 256 * 1024; + int ret; + z_stream strm; + + out = (char *)malloc(bufferSize); + + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + strm.next_in = (Bytef *)in; + strm.avail_in = inLength; + strm.next_out = (Bytef *)out; + strm.avail_out = bufferSize; + + ret = inflateInit2(&strm, 15 + 32); + + if (ret != Z_OK) + { + logZlibError(ret); + return false; + } + + do + { + ret = inflate(&strm, Z_SYNC_FLUSH); + + switch (ret) { + case Z_NEED_DICT: + case Z_STREAM_ERROR: + ret = Z_DATA_ERROR; + case Z_DATA_ERROR: + case Z_MEM_ERROR: + inflateEnd(&strm); + logZlibError(ret); + return false; + } + + if (ret != Z_STREAM_END) + { + out = (char *)realloc(out, bufferSize * 2); + + if (!out) + { + inflateEnd(&strm); + logZlibError(Z_MEM_ERROR); + return false; + } + + strm.next_out = (Bytef *)(out + bufferSize); + strm.avail_out = bufferSize; + bufferSize *= 2; + } + } + while (ret != Z_STREAM_END); + + if (strm.avail_in != 0) + { + logZlibError(Z_DATA_ERROR); + return false; + } + + outLength = bufferSize - strm.avail_out; + inflateEnd(&strm); + return true; +} diff --git a/src/utils/zlib.hpp b/src/utils/zlib.hpp new file mode 100644 index 00000000..330dd8ca --- /dev/null +++ b/src/utils/zlib.hpp @@ -0,0 +1,35 @@ +/* + * The Mana World + * Copyright 2006 The Mana World Development Team + * + * This file is part of The Mana World. + * + * The Mana World 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. + * + * The Mana World 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 The Mana World; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + */ + +#ifndef _TMWSERV_ZLIB +#define _TMWSERV_ZLIB + +/** + * Inflates either zlib or gzip deflated memory. The inflated memory is + * expected to be freed by the caller. Returns true if the inflation was + * sucessful. + */ +bool inflateMemory(char *in, unsigned inLength, + char *&out, unsigned &outLength); + +#endif |