Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/trunk/src/lib/network/zip.cc @ 8376

Last change on this file since 8376 was 8362, checked in by bensch, 18 years ago

orxonox/trunk: removed stupid included in base_object.h
this should lead to faster compile-times

File size: 5.2 KB
RevLine 
[7851]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"
[8362]19#include "debug.h"
[7851]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 */
51bool 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());
[8362]57
[7851]58  FILE * f = fopen( fileName.c_str(), "r" );
[8362]59
[7851]60  if ( !f )
61  {
62    PRINTF(1)("Could not open %d\n", fileName.c_str());
63    return false;
64  }
[8362]65
[7851]66  byte buf[1024];
[8362]67
[7851]68  int nBytesRead = 0;
[8362]69
[7851]70  while ( !feof( f ) )
71  {
72    nBytesRead += fread( buf, 1, sizeof(buf), f );
73  }
[8362]74
[7851]75  DictionaryEntry entry;
[8362]76
[7851]77  entry.dictLen = nBytesRead;
78  entry.dict = new Byte[nBytesRead];
[8362]79
[7851]80  fseek( f, 0, SEEK_SET );
[8362]81
[7851]82  assert( fread( entry.dict, 1, nBytesRead, f ) == nBytesRead );
[8362]83
[7851]84  entry.adler = adler32( adler32( 0L, Z_NULL, 0 ), entry.dict, nBytesRead );
[8362]85
[7851]86  dicts.push_back( entry );
[8362]87
[7851]88  PRINTF(3)("Loaded dictionary '%s' with adler = %d\n", name.c_str(), entry.adler );
[8362]89
[7851]90  return true;
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  }
[8362]109
[7851]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 );
[8362]127
[7851]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 );
[8362]142
[7851]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 );
[8362]155
[7851]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");
[8362]164
[7851]165    return -1;
166  }
[8362]167
[7851]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;
[8362]184
[7851]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  }
[8362]196
[7851]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 );
[8362]205
[7851]206  int dictId = -1;
[8362]207
[7851]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  }
[8362]216
[7851]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  }
[8362]222
[7851]223  res = inflateSetDictionary( &strm, (Bytef*)dicts[dictId].dict, dicts[dictId].dictLen );
[8362]224
[7851]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 );
[8362]233
[7851]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 );
[8362]246
[7851]247  if ( res != Z_OK )
248  {
249    PRINTF(1)("inflateEnd error: %s\n", strm.msg);
250    return -1;
251  }
[8362]252
[7851]253  return unzippedlen;
254}
Note: See TracBrowser for help on using the repository browser.