Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/proxy/src/lib/network/zip.cc @ 9542

Last change on this file since 9542 was 8623, checked in by bensch, 18 years ago

orxonox/trunk: merged the network branche back here
merged with command:
svn merge -r8230:HEAD https://svn.orxonox.net/orxonox/branches/network .
conflicts resolved in favour of the network branche (conflicts were in network)

File size: 5.2 KB
Line 
1/*
2   orxonox - the future of 3D-vertical-scrollers
3
4   Copyright (C) 2004 orx
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2, or (at your option)
9   any later version.
10
11### File Specific:
12   main-programmer: Christoph Renner
13   co-programmer: ...
14*/
15
16#include "zip.h"
17
18#include "src/lib/util/loading/resource_manager.h"
19#include "debug.h"
20
21/**
22 *  the singleton reference to this class
23 */
24Zip* Zip::singletonRef = NULL;
25
26
27/**
28 * standard constructor
29 */
30Zip::Zip()
31{
32
33}
34
35
36/**
37 * @brief standard deconstructor
38 */
39Zip::~Zip()
40{
41  Zip::singletonRef = NULL;
42}
43
44/**
45 * load a dictionary to unzip. you can load more than one dictionary
46 * if you call unzip with data from zip without loading the same dictionary
47 * used with zip unzip will fail
48 * @param name name of dictionary
49 * @return true on success
50 */
51int Zip::loadDictionary( std::string name )
52{
53  std::string fileName = ResourceManager::getInstance()->getDataDir();
54  //PRINTF(0)("datadir: %s\n", fileName.c_str());
55  fileName = fileName + "/dicts/" + name;
56  //PRINTF(0)("filename: %s\n", fileName.c_str());
57
58  FILE * f = fopen( fileName.c_str(), "r" );
59
60  if ( !f )
61  {
62    PRINTF(1)("Could not open %d\n", fileName.c_str());
63    return -1;
64  }
65
66  byte buf[1024];
67
68  int nBytesRead = 0;
69
70  while ( !feof( f ) )
71  {
72    nBytesRead += fread( buf, 1, sizeof(buf), f );
73  }
74
75  DictionaryEntry entry;
76
77  entry.dictLen = nBytesRead;
78  entry.dict = new Byte[nBytesRead];
79
80  fseek( f, 0, SEEK_SET );
81
82  assert( fread( entry.dict, 1, nBytesRead, f ) == nBytesRead );
83
84  entry.adler = adler32( adler32( 0L, Z_NULL, 0 ), entry.dict, nBytesRead );
85
86  dicts.push_back( entry );
87
88  PRINTF(3)("Loaded dictionary '%s' with adler = %d\n", name.c_str(), entry.adler );
89
90  return dicts.size()-1;
91}
92
93/**
94 * zip data. you must call loadDictionary before
95 * @param from data to compress
96 * @param fromLength length of data to compress
97 * @param to pointer to compressed data
98 * @param maxLength max bytes to compress
99 * @param dict dictionary to use. default is 0
100 * @return num bytes writen to to
101 */
102int Zip::zip( byte * from, int fromLength, byte * to, int maxLength, int dict )
103{
104  if ( dicts.size() < dict+1 )
105  {
106    PRINTF(1)("you cannot use dict nr %d. num dicts: %d\n", dict, dicts.size() );
107    return -1;
108  }
109
110  int res;
111
112  z_stream strm;
113
114  strm.zalloc = Z_NULL;
115  strm.zfree = Z_NULL;
116  strm.opaque = Z_NULL;
117
118  res = deflateInit( &strm, 9 );
119
120  if ( res != Z_OK )
121  {
122    PRINTF(1)("deflateInit error: %s\n", strm.msg);
123    return -1;
124  }
125
126  res = deflateSetDictionary( &strm, (Bytef*)(dicts[dict].dict), dicts[dict].dictLen );
127
128  if ( res != Z_OK )
129  {
130    PRINTF(1)("deflateSetDictionary error: %s\n", strm.msg);
131    return -1;
132  }
133
134  strm.next_out = (Bytef*)to;
135  strm.avail_out = maxLength;
136  assert( strm.total_out == 0 );
137  strm.next_in = (Bytef*)from;
138  strm.avail_in = fromLength;
139  assert( strm.total_in == 0 );
140
141  res = deflate( &strm, Z_FINISH );
142
143  if ( res != Z_STREAM_END )
144  {
145    PRINTF(1)("buffer to small or deflate error: %s\n", strm.msg);
146    return -1;
147  }
148
149  assert( strm.avail_out != 0 );
150  assert( strm.avail_in == 0 );
151
152  int zippedlen = strm.total_out;
153
154  res = deflateEnd( &strm );
155
156  if ( res != Z_OK )
157  {
158    if ( res == Z_STREAM_ERROR )
159      PRINTF(1)("deflateEnd error: Z_STREAM_ERROR\n");
160    else if ( res == Z_DATA_ERROR )
161      PRINTF(1)("deflateEnd error: Z_DATA_ERROR %s\n", strm.msg);
162    else
163      PRINTF(1)("deflateEnd error: dont know\n");
164
165    return -1;
166  }
167
168  return zippedlen;
169
170}
171
172/**
173 * uncompress data. same dict as used in zip must be loaded
174 * @param from compressed data
175 * @param fromLength length of compressed data
176 * @param to buffer to copy uncompressed data to
177 * @param maxLength max bytes to copy to to
178 * @return num bytes writen to to
179 */
180int Zip::unZip( byte * from, int fromLength, byte * to, int maxLength )
181{
182  z_stream strm;
183  int res = 0;
184
185  strm.zalloc = Z_NULL;
186  strm.zfree = Z_NULL;
187  strm.opaque = Z_NULL;
188
189  res = inflateInit( &strm );
190
191  if ( res != Z_OK )
192  {
193    PRINTF(1)("inflateInit error: %s\n", strm.msg);
194    return -1;
195  }
196
197  strm.next_out = (Bytef*)to;
198  strm.avail_out = maxLength;
199  assert( strm.total_out == 0 );
200  strm.next_in = (Bytef*)from;
201  strm.avail_in = fromLength;
202  assert( strm.total_in == 0 );
203
204  assert( inflate( &strm, Z_NO_FLUSH ) == Z_NEED_DICT );
205
206  int dictId = -1;
207
208  for ( int i = 0; i < dicts.size(); i++ )
209  {
210    if ( dicts[i].adler == strm.adler )
211    {
212      dictId = i;
213      break;
214    }
215  }
216
217  if ( dictId == -1 )
218  {
219    PRINTF(1)("Could not find dict used to compress this packet! ( adler = %d )\n", strm.adler);
220    return -1;
221  }
222
223  res = inflateSetDictionary( &strm, (Bytef*)dicts[dictId].dict, dicts[dictId].dictLen );
224
225  if ( res != Z_OK )
226  {
227    PRINTF(1)("inflateSetDictionary error: %s\n", strm.msg);
228    return -1;
229  }
230
231
232  res = inflate( &strm, Z_FINISH );
233
234  if ( res != Z_STREAM_END )
235  {
236    PRINTF(1)("inflate error: %s\n", strm.msg);
237    return -1;
238  }
239
240  assert( strm.avail_out != 0 );
241  assert( strm.avail_in == 0 );
242
243  int unzippedlen = strm.total_out;
244
245  res = inflateEnd( &strm );
246
247  if ( res != Z_OK )
248  {
249    PRINTF(1)("inflateEnd error: %s\n", strm.msg);
250    return -1;
251  }
252
253  return unzippedlen;
254}
Note: See TracBrowser for help on using the repository browser.