Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/bsp_model/src/lib/network/zip.cc @ 8359

Last change on this file since 8359 was 7954, checked in by patrick, 18 years ago

trunk: merged the network branche back to trunk.

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