00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <cstdlib>
00023 #include <zlib.h>
00024
00025 #include "utils/zlib.hpp"
00026
00027 #include "utils/logger.h"
00028
00029 static void logZlibError(int error)
00030 {
00031 switch (error)
00032 {
00033 case Z_MEM_ERROR:
00034 LOG_ERROR("Out of memory while decompressing data!");
00035 break;
00036 case Z_VERSION_ERROR:
00037 LOG_ERROR("Incompatible zlib version!");
00038 break;
00039 case Z_DATA_ERROR:
00040 LOG_ERROR("Incorrect zlib compressed data!");
00041 break;
00042 default:
00043 LOG_ERROR("Unknown error while decompressing data!");
00044 }
00045 }
00046
00047 bool inflateMemory(char *in, unsigned inLength,
00048 char *&out, unsigned &outLength)
00049 {
00050 int bufferSize = 256 * 1024;
00051 int ret;
00052 z_stream strm;
00053
00054 out = (char *)malloc(bufferSize);
00055
00056 strm.zalloc = Z_NULL;
00057 strm.zfree = Z_NULL;
00058 strm.opaque = Z_NULL;
00059 strm.next_in = (Bytef *)in;
00060 strm.avail_in = inLength;
00061 strm.next_out = (Bytef *)out;
00062 strm.avail_out = bufferSize;
00063
00064 ret = inflateInit2(&strm, 15 + 32);
00065
00066 if (ret != Z_OK)
00067 {
00068 logZlibError(ret);
00069 free(out);
00070 return false;
00071 }
00072
00073 do
00074 {
00075 ret = inflate(&strm, Z_SYNC_FLUSH);
00076
00077 switch (ret) {
00078 case Z_NEED_DICT:
00079 case Z_STREAM_ERROR:
00080 ret = Z_DATA_ERROR;
00081 case Z_DATA_ERROR:
00082 case Z_MEM_ERROR:
00083 inflateEnd(&strm);
00084 logZlibError(ret);
00085 free(out);
00086 return false;
00087 }
00088
00089 if (ret != Z_STREAM_END)
00090 {
00091 out = (char *)realloc(out, bufferSize * 2);
00092
00093 if (!out)
00094 {
00095 inflateEnd(&strm);
00096 logZlibError(Z_MEM_ERROR);
00097 free(out);
00098 return false;
00099 }
00100
00101 strm.next_out = (Bytef *)(out + bufferSize);
00102 strm.avail_out = bufferSize;
00103 bufferSize *= 2;
00104 }
00105 }
00106 while (ret != Z_STREAM_END);
00107
00108 if (strm.avail_in != 0)
00109 {
00110 logZlibError(Z_DATA_ERROR);
00111 free(out);
00112 return false;
00113 }
00114
00115 outLength = bufferSize - strm.avail_out;
00116 inflateEnd(&strm);
00117 return true;
00118 }