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 
size_t ReadBuffer(void *Buffer, size_t Count)
Reads a block of bytes from the stream into Buffer.
Definition: CStream.cpp:45
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values, timewatch, extensions to STL.
Definition: zip.h:16
std::vector< uint8_t > vector_byte
Definition: types_simple.h:26
#define MRPT_END_WITH_CLEAN_UP(stuff)
GLuint buffer
Definition: glext.h:3775
#define THROW_EXCEPTION(msg)
void WriteBuffer(const void *Buffer, size_t Count)
Writes a block of bytes to the stream from Buffer.
Definition: CStream.cpp:67
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:
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
voidp gzFile
Definition: zlib.h:1045
This base class is used to provide a unified interface to files,memory buffers,..Please see the deriv...
Definition: CStream.h:38
std::string BASE_IMPEXP getTempFileName()
Returns the name of a proposed temporary file name.
Definition: filesystem.cpp:273
Transparently opens a compressed "gz" file and reads uncompressed data from it.
std::string BASE_IMPEXP format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
Definition: format.cpp:21
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
uint64_t getTotalBytesCount() MRPT_OVERRIDE
Method for getting the total number of compressed bytes of in the file (the physical size of the comp...
GLsizei const GLchar ** string
Definition: glext.h:3919
#define MRPT_START
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
#define CFileGZOutputStream
Saves data to a file and transparently compress the data using the given compression level...
bool fileOpenCorrectly()
Returns true if the file was open without errors.
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 open(const std::string &fileName)
Open a file for reading.
#define ASSERT_(f)
#define Z_OK
Definition: zlib.h:149
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
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.
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
Compression using the "zip" algorithm and from/to gzip (gz) files.
Definition: zip.h:22
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



Page generated by Doxygen 1.8.14 for MRPT 1.5.7 Git: 5902e14cc Wed Apr 24 15:04:01 2019 +0200 at lun oct 28 01:39:17 CET 2019