Main MRPT website > C++ reference for MRPT 1.5.7
zip.cpp
Go to the documentation of this file.
1 /* +---------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2017, Individual contributors, see AUTHORS file |
6  | See: http://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See details in http://www.mrpt.org/License |
8  +---------------------------------------------------------------------------+ */
9 
10 #include "base-precomp.h" // Precompiled headers
11 
12 #include "zlib.h"
13 
14 // For named pipes:
15 #ifdef MRPT_OS_WINDOWS
16  #define WIN32_LEAN_AND_MEAN
17  #include <windows.h>
18 #endif
19 
20 #include <mrpt/compress/zip.h>
21 #include <mrpt/system/datetime.h>
22 #include <mrpt/system/filesystem.h>
24 
28 
29 using namespace mrpt;
30 using namespace mrpt::utils;
31 using namespace mrpt::compress::zip;
32 
33 /*---------------------------------------------------------------
34  compress
35 ---------------------------------------------------------------*/
37  void *inData,
38  size_t inDataSize,
39  std::vector<unsigned char> &outData)
40 {
41  int ret=0;
43 
44  unsigned long resSize;
45 
46  outData.resize(inDataSize+inDataSize/1000+50);
47  resSize = (unsigned long)outData.size();
48  ret = ::compress(
49  &outData[0],
50  &resSize,
51  (unsigned char*)inData,
52  (unsigned long)inDataSize
53  );
54  ASSERT_(ret==Z_OK);
55 
56  outData.resize(resSize);
57 
59  printf("[zlib] Error code=%i\n",ret);\
60  );
61 }
62 
63 /*---------------------------------------------------------------
64  compress
65 ---------------------------------------------------------------*/
67  const std::vector<unsigned char> &inData,
68  std::vector<unsigned char> &outData)
69 {
70  int ret=0;
72 
73  unsigned long resSize;
74 
75  outData.resize(inData.size()+inData.size()/1000+50);
76  resSize = (unsigned long)outData.size();
77  ret = ::compress(
78  &outData[0],
79  &resSize,
80  &inData[0],
81  (unsigned long)inData.size()
82  );
83  ASSERT_(ret==Z_OK);
84 
85  outData.resize(resSize);
86 
88  printf("[zlib] Error code=%i\n",ret);\
89  );
90 }
91 
92 /*---------------------------------------------------------------
93  compress
94 ---------------------------------------------------------------*/
96  void *inData,
97  size_t inDataSize,
98  CStream &out)
99 {
100  int ret=0;
101  MRPT_START
102 
103  unsigned long resSize;
104  std::vector<unsigned char> outData;
105 
106  outData.resize(inDataSize+inDataSize/1000+50);
107  resSize = (unsigned long)outData.size();
108 
109  ret = ::compress(
110  &outData[0],
111  &resSize,
112  (unsigned char*)inData,
113  (unsigned long)inDataSize
114  );
115  ASSERT_(ret==Z_OK);
116 
117  outData.resize(resSize);
118 
119  // Write to stream:
120  out.WriteBuffer( &outData[0], resSize );
121 
123  printf("[zlib] Error code=%i\n",ret);\
124  );
125 }
126 
127 
128 /*---------------------------------------------------------------
129  compress
130 ---------------------------------------------------------------*/
132  const std::vector<unsigned char> &inData,
133  CStream &out)
134 {
135  int ret=0;
136  MRPT_START
137 
138  unsigned long resSize;
139  std::vector<unsigned char> outData;
140  outData.resize(inData.size()+inData.size()/1000+50);
141  resSize = (unsigned long)outData.size();
142 
143  ret = ::compress(
144  &outData[0],
145  &resSize,
146  &inData[0],
147  (unsigned long)inData.size()
148  );
149 
150  ASSERT_(ret==Z_OK);
151 
152  outData.resize(resSize);
153 
154  // Write to stream:
155  out.WriteBuffer( &outData[0], resSize );
156 
158  printf("[zlib] Error code=%i\n",ret);\
159  );
160 }
161 
162 /*---------------------------------------------------------------
163  decompress
164 ---------------------------------------------------------------*/
166  void *inData,
167  size_t inDataSize,
168  std::vector<unsigned char> &outData,
169  size_t outDataEstimatedSize)
170 {
171  int ret=0;
172  MRPT_START
173 
174  outData.resize( outDataEstimatedSize );
175  unsigned long actualOutSize;
176 
177  ret = ::uncompress(
178  &outData[0],
179  &actualOutSize,
180  (unsigned char*)inData,
181  (unsigned long)inDataSize
182  );
183 
184  ASSERT_(ret==Z_OK);
185 
186  outData.resize(actualOutSize);
187 
189  printf("[zlib] Error code=%i\n",ret);\
190  );
191 }
192 
193 /*---------------------------------------------------------------
194  decompress
195 ---------------------------------------------------------------*/
197  void *inData,
198  size_t inDataSize,
199  void *outData,
200  size_t outDataBufferSize,
201  size_t &outDataActualSize)
202 {
203  int ret=0;
204  MRPT_START
205 
206  unsigned long actualOutSize = (unsigned long)outDataBufferSize;
207 
208  ret = ::uncompress(
209  (unsigned char*)outData,
210  &actualOutSize,
211  (unsigned char*)inData,
212  (unsigned long)inDataSize
213  );
214 
215  ASSERT_(ret==Z_OK);
216 
217  outDataActualSize = actualOutSize;
218 
220  printf("[zlib] Error code=%i\n",ret);\
221  );
222 }
223 
224 /*---------------------------------------------------------------
225  decompress
226 ---------------------------------------------------------------*/
228  CStream &inStream,
229  size_t inDataSize,
230  void *outData,
231  size_t outDataBufferSize,
232  size_t &outDataActualSize)
233 {
234  int ret=0;
235  MRPT_START
236 
237  unsigned long actualOutSize = (unsigned long)outDataBufferSize;
238  std::vector<unsigned char> inData;
239 
240  inData.resize(inDataSize);
241  inStream.ReadBuffer( &inData[0], inDataSize );
242 
243  ret = ::uncompress(
244  (unsigned char*)outData,
245  &actualOutSize,
246  &inData[0],
247  (unsigned long)inDataSize
248  );
249 
250  ASSERT_(ret==Z_OK);
251 
252  outDataActualSize = actualOutSize;
253 
255  printf("[zlib] Error code=%i\n",ret);\
256  );
257 }
258 
259 
260 /*---------------------------------------------------------------
261  decompress_gz_file
262 ---------------------------------------------------------------*/
264 {
265  CFileGZInputStream iss(file_path);
266  if (!iss.fileOpenCorrectly())
267  return false;
268 
269  buffer.clear();
270 
271  const int bytes2read = 1 << 20;
272  int act_read;
273  size_t total_bytes = 0;
274 
275  buffer.reserve( iss.getTotalBytesCount() );
276 
277  do
278  {
279  buffer.resize( 1000+bytes2read + buffer.size() );
280  act_read = iss.ReadBuffer( &buffer[total_bytes], bytes2read );
281  total_bytes += act_read;
282  } while (act_read==bytes2read);
283 
284  buffer.resize( total_bytes );
285  return true;
286 }
287 
288 /*---------------------------------------------------------------
289  compress_gz_file
290 ---------------------------------------------------------------*/
292  const std::string &file_path,
293  const vector_byte &buffer,
294  const int compress_level
295  )
296 {
297 #if MRPT_HAS_GZ_STREAMS
299  oss.open(file_path,compress_level);
300  if (!oss.fileOpenCorrectly())
301  return false;
302 
303  if (!buffer.empty())
304  {
305  try
306  {
307  oss.WriteBuffer(&buffer[0], buffer.size());
308  return true;
309  }
310  catch(...) { return false; }
311  }
312  else
313  {
314  return true;
315  }
316 #else
317  THROW_EXCEPTION("MRPT has been compiled with MRPT_HAS_GZ_STREAMS=0")
318 #endif
319 }
320 
321 
322 /*---------------------------------------------------------------
323  compress_gz_data_block
324 ---------------------------------------------------------------*/
326  const vector_byte &in_data,
327  vector_byte &out_gz_data,
328  const int compress_level
329  )
330 {
331  out_gz_data.clear();
332  if (in_data.empty())
333  return true;
334 
335 #if MRPT_HAS_GZ_STREAMS
336 
337  const unsigned int nPipeName = static_cast<unsigned int>(mrpt::system::now());
338  std::string pipe_file_name;
339 
340  // Create an anonymous pipe for writing the data to:
341  #ifdef MRPT_OS_WINDOWS
342  // Windows:
343  pipe_file_name = format("\\\\.\\pipe\\mrpt_compress_gz_data_block_%u",nPipeName);
344 
345  HANDLE hPipe = CreateNamedPipeA(
346  pipe_file_name.c_str(),
347  PIPE_ACCESS_DUPLEX | 0x00080000 /* FILE_FLAG_FIRST_PIPE_INSTANCE */,
348  PIPE_TYPE_BYTE,
349  PIPE_UNLIMITED_INSTANCES,
350  in_data.size()+1000,
351  in_data.size()+1000,
352  0,
353  NULL);
354  if (hPipe==INVALID_HANDLE_VALUE) THROW_EXCEPTION("Error creating named pipe for gz-file compression");
355  #else
356  // Unix:
357  pipe_file_name = format("/tmp/mrpt_compress_gz_data_block_%u",nPipeName);
358  #endif
359 
360 
361  bool retVal = false;
362  try
363  {
364  // Write as gz
365  {
366  gzFile f = gzopen(pipe_file_name.c_str(),format("wb%i",compress_level).c_str() );
367  if (f)
368  {
369  retVal = (int)in_data.size() == gzwrite(f,&in_data[0], in_data.size());
370  gzclose(f);
371  }
372  else
373  {
374  std::cerr << "[compress_gz_data_block] Error writing to pipe: " << pipe_file_name << std::endl;
375  }
376  }
377  // Read it all:
378  if (retVal)
379  {
380  #ifdef MRPT_OS_WINDOWS
381  // Read (windows)
382  const size_t N = GetFileSize(hPipe,NULL);
383  if (N)
384  {
385  out_gz_data.resize(N);
386  DWORD nRead;
387  SetFilePointer(hPipe,0,NULL, FILE_BEGIN);
388  if (N)
389  {
390  ReadFile(hPipe,&out_gz_data[0],N,&nRead,NULL);
391  retVal= nRead == N;
392  }
393  }
394  else
395  {
396  retVal=false;
397  }
398  #else
399  // Read (Unix)
400  {
401  CFileInputStream iss;
402  if (iss.open(pipe_file_name))
403  {
404  const size_t M = iss.getTotalBytesCount();
405  out_gz_data.resize(M);
406  if (M)
407  retVal = M==iss.ReadBuffer(&out_gz_data[0],M);
408  }
409  }
410  #endif
411  }
412  }
413  catch(...)
414  {
415  retVal = false;
416  }
417 
418  // Close the pipe:
419  #ifdef MRPT_OS_WINDOWS
420  CloseHandle(hPipe);
421  #else
422  remove(pipe_file_name.c_str());
423  #endif
424 
425  return retVal;
426 #else
427  THROW_EXCEPTION("MRPT has been compiled with MRPT_HAS_GZ_STREAMS=0")
428 #endif
429 }
430 
431 
432 /*---------------------------------------------------------------
433  decompress_gz_data_block
434 ---------------------------------------------------------------*/
436  const vector_byte &in_gz_data,
437  vector_byte &out_data)
438 {
439  out_data.clear();
440  if (in_gz_data.empty()) return true;
441 
442  // JL: I tried to do this with pipes but had no luck... :-(
443 
444  const std::string tmp_file_name = mrpt::system::getTempFileName();
445  if (!mrpt::system::vectorToBinaryFile(in_gz_data,tmp_file_name)) return false;
446  bool retVal = mrpt::compress::zip::decompress_gz_file(tmp_file_name,out_data);
447 
448  remove(tmp_file_name.c_str()); // Delete tmp file
449 
450  return retVal;
451 }
452 
453 
Transparently opens a compressed "gz" file and reads uncompressed data from it.
uint64_t getTotalBytesCount() MRPT_OVERRIDE
Method for getting the total number of compressed bytes of in the file (the physical size of the comp...
bool fileOpenCorrectly()
Returns true if the file was open without errors.
This CStream derived class allow using a file as a read-only, binary stream.
uint64_t getTotalBytesCount() MRPT_OVERRIDE
Method for getting the total number of bytes in the buffer.
bool open(const std::string &fileName)
Open a file for reading.
This base class is used to provide a unified interface to files,memory buffers,..Please see the deriv...
Definition: CStream.h:39
void WriteBuffer(const void *Buffer, size_t Count)
Writes a block of bytes to the stream from Buffer.
Definition: CStream.cpp:67
size_t ReadBuffer(void *Buffer, size_t Count)
Reads a block of bytes from the stream into Buffer.
Definition: CStream.cpp:45
GLuint buffer
Definition: glext.h:3775
GLenum GLsizei GLenum format
Definition: glext.h:3513
GLsizei const GLchar ** string
Definition: glext.h:3919
std::string BASE_IMPEXP getTempFileName()
Returns the name of a proposed temporary file name.
Definition: filesystem.cpp:273
#define CFileGZOutputStream
Saves data to a file and transparently compress the data using the given compression level.
std::vector< uint8_t > vector_byte
Definition: types_simple.h:26
mrpt::system::TTimeStamp now()
A shortcut for system::getCurrentTime.
Definition: datetime.h:70
bool BASE_IMPEXP vectorToBinaryFile(const vector_byte &vec, const std::string &fileName)
Saves a vector directly as a binary dump to a file:
#define MRPT_START
Definition: mrpt_macros.h:366
#define ASSERT_(f)
Definition: mrpt_macros.h:278
#define MRPT_END_WITH_CLEAN_UP(stuff)
Definition: mrpt_macros.h:373
#define THROW_EXCEPTION(msg)
Definition: mrpt_macros.h:154
Compression using the "zip" algorithm and from/to gzip (gz) files.
Definition: zip.h:23
bool BASE_IMPEXP compress_gz_file(const std::string &file_path, const vector_byte &buffer, const int compress_level=9)
Compress a memory buffer into a gzip file (xxxx.gz).
Definition: zip.cpp:291
bool BASE_IMPEXP decompress_gz_file(const std::string &file_path, vector_byte &buffer)
Decompress a gzip file (xxxx.gz) into a memory buffer.
Definition: zip.cpp:263
void BASE_IMPEXP compress(void *inData, size_t inDataSize, std::vector< unsigned char > &outData)
Compress an array of bytes into another one.
Definition: zip.cpp:36
bool BASE_IMPEXP decompress_gz_data_block(const vector_byte &in_gz_data, vector_byte &out_data)
Decompress an array of bytes storing a gz-compressed stream of data into a memory buffer.
Definition: zip.cpp:435
bool BASE_IMPEXP compress_gz_data_block(const vector_byte &in_data, vector_byte &out_gz_data, const int compress_level=9)
Compress a memory buffer in gz-file format and return it as a block a memory.
Definition: zip.cpp:325
void BASE_IMPEXP decompress(void *inData, size_t inDataSize, std::vector< unsigned char > &outData, size_t outDataEstimatedSize)
Decompress an array of bytes into another one.
Definition: zip.cpp:165
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values,...
Definition: zip.h:16
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
std::string BASE_IMPEXP format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
Definition: format.cpp:21
#define Z_OK
Definition: zlib.h:149
voidp gzFile
Definition: zlib.h:1045



Page generated by Doxygen 1.9.1 for MRPT 1.5.7 Git: 5902e14cc Wed Apr 24 15:04:01 2019 +0200 at mar 26 may 2026 13:12:03 CEST