Mana
Loading...
Searching...
No Matches
zlib.cpp
Go to the documentation of this file.
1/*
2 * The Mana Client
3 * Copyright (C) 2004-2009 The Mana World Development Team
4 * Copyright (C) 2009-2012 The Mana Developers
5 *
6 * This file is part of The Mana Client.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22#include "utils/zlib.h"
23
24#include "log.h"
25
26#include <cassert>
27#include <cstdlib>
28#include <zlib.h>
29
34int inflateMemory(unsigned char *in, unsigned int inLength,
35 unsigned char *&out, unsigned int &outLength)
36{
37 int bufferSize = 256 * 1024;
38 int ret;
39 z_stream strm;
40
41 out = (unsigned char*) malloc(bufferSize);
42
43 strm.zalloc = Z_NULL;
44 strm.zfree = Z_NULL;
45 strm.opaque = Z_NULL;
46 strm.next_in = in;
47 strm.avail_in = inLength;
48 strm.next_out = out;
49 strm.avail_out = bufferSize;
50
51 ret = inflateInit2(&strm, 15 + 32);
52
53 if (ret != Z_OK)
54 return ret;
55
56 do
57 {
58 if (strm.next_out == nullptr)
59 {
60 inflateEnd(&strm);
61 return Z_MEM_ERROR;
62 }
63
64 ret = inflate(&strm, Z_NO_FLUSH);
65 assert(ret != Z_STREAM_ERROR);
66
67 switch (ret)
68 {
69 case Z_NEED_DICT:
70 ret = Z_DATA_ERROR;
71 case Z_DATA_ERROR:
72 case Z_MEM_ERROR:
73 (void) inflateEnd(&strm);
74 return ret;
75 }
76
77 if (ret != Z_STREAM_END)
78 {
79 out = (unsigned char*) realloc(out, bufferSize * 2);
80
81 if (out == nullptr)
82 {
83 inflateEnd(&strm);
84 return Z_MEM_ERROR;
85 }
86
87 strm.next_out = out + bufferSize;
88 strm.avail_out = bufferSize;
89 bufferSize *= 2;
90 }
91 }
92 while (ret != Z_STREAM_END);
93 assert(strm.avail_in == 0);
94
95 outLength = bufferSize - strm.avail_out;
96 (void) inflateEnd(&strm);
97 return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
98}
99
100int inflateMemory(unsigned char *in, unsigned int inLength,
101 unsigned char *&out)
102{
103 unsigned int outLength = 0;
104 int ret = inflateMemory(in, inLength, out, outLength);
105
106 if (ret != Z_OK || out == nullptr)
107 {
108 if (ret == Z_MEM_ERROR)
109 {
110 Log::error("Out of memory while decompressing data!");
111 }
112 else if (ret == Z_VERSION_ERROR)
113 {
114 Log::error("Incompatible zlib version!");
115 }
116 else if (ret == Z_DATA_ERROR)
117 {
118 Log::error("Incorrect zlib compressed data!");
119 }
120 else
121 {
122 Log::error("Unknown error while decompressing data!");
123 }
124
125 free(out);
126 out = nullptr;
127 outLength = 0;
128 }
129
130 return outLength;
131}
void error(const char *log_text,...) LOG_PRINTF_ATTR
int inflateMemory(unsigned char *in, unsigned int inLength, unsigned char *&out, unsigned int &outLength)
Inflates either zlib or gzip deflated memory.
Definition zlib.cpp:34