opennurbs_compress.h
1 /* $NoKeywords: $ */
2 /*
3 //
4 // Copyright (c) 1993-2012 Robert McNeel & Associates. All rights reserved.
5 // OpenNURBS, Rhinoceros, and Rhino3D are registered trademarks of Robert
6 // McNeel & Associates.
7 //
8 // THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
9 // ALL IMPLIED WARRANTIES OF FITNESS FOR ANY PARTICULAR PURPOSE AND OF
10 // MERCHANTABILITY ARE HEREBY DISCLAIMED.
11 //
12 // For complete openNURBS copyright information see <http://www.opennurbs.org>.
13 //
14 ////////////////////////////////////////////////////////////////
15 */
16 
17 #if !defined(OPENNURBS_COMPRESS_INC_)
18 #define OPENNURBS_COMPRESS_INC_
19 
20 typedef bool (*ON_StreamCallbackFunction)( void* context, ON__UINT32 size, const void* buffer );
21 
22 class ON_CLASS ON_CompressStream
23 {
24 public:
26  virtual ~ON_CompressStream();
27 
28  /*
29  Description:
30  ON_CompressStream delivers the compressed stream by calling
31  a compressed stream output handler function. There are two
32  options for specifying the compressed stream output handler
33  function.
34  1. Overriding the virtual Out() function.
35  2. Providing a callback function.
36  SetCallback() is used to specify a callback function to handle
37  the compressed stream and to specify a context pointer to be
38  passed to either option of the handler.
39  Parameters:
40  callback_function - [in]
41  Function to call with sections of the compressed stream.
42  If callback_function is null, then the virtual Out()
43  function will be called. When callback_function
44  is specified, it must return true if the compression
45  calculation should continue and false to cancel the
46  compression calculation.
47  callback_context - [in]
48  This value is passed as the first argument when calling
49  callback_function or the virutal Out() function.
50  Returns:
51  True if successful.
52  Remarks:
53  Once compression has started, it would be unusual to
54  intentionally change the compressed stream output handler,
55  but you can do this if you need to.
56  */
57  bool SetCallback(
58  ON_StreamCallbackFunction callback_function,
59  void* callback_context
60  );
61 
62  /*
63  Returns:
64  Current value of the callback function for handling
65  the compressed stream. If the callback function is
66  null, the the virtual Out() function is used to
67  handle
68  */
69  ON_StreamCallbackFunction CallbackFunction() const;
70 
71  /*
72  Returns:
73  Current value of the context pointer passed as the first
74  argument to the compressed stream output handler function.
75  */
76  void* CallbackContext() const;
77 
78  /*
79  Description:
80  Call Begin() one time to initialize the compression
81  calculation. Then call In() one or more times
82  to submit the uncompressed stream to the compression calculation.
83  When you reach the end of the uncompressed stream, call
84  End().
85  Returns:
86  true if successful, false if an error occured.
87  */
88  bool Begin();
89 
90  /*
91  Description:
92  Call In() one or more times to compress a stream of uncompressed
93  bytes. After the last call to In(), call End(). Calling In()
94  may generate zero or more calls to the output stream handler.
95  Parameters:
96  in_buffer_size - [in]
97  number of bytes in in_buffer
98  in_buffer - [in]
99  Returns:
100  true if successful, false if an error occured.
101  */
102  bool In(
103  ON__UINT64 in_buffer_size,
104  const void* in_buffer
105  );
106 
107  /*
108  Description:
109  If an explicit compressed stream output handler is not specified
110  ( CallbackFunction() returns null ), then the virtual Out()
111  function is called to handle the compressed output stream.
112  As the input stream is compressed, one or more calls to Out()
113  will occur.
114  Returns:
115  True to continue compressing and false to cancel the compression
116  calculation.
117  Remarks:
118  In general, it is probably going to be easier to test and debug
119  your code if you ignore the callback_context parameter and add
120  a member variable to your derived class to make additional
121  information accessable to your Out function.
122  */
123  virtual bool Out(
124  void* callback_context,
125  ON__UINT32 out_buffer_size,
126  const void* out_buffer
127  );
128 
129  /*
130  Description:
131  After the last call to In(), call End().
132  Calling End() may generate zero or more
133  calls to the output stream handler.
134  Returns:
135  true if successful, false if an error occured.
136  */
137  bool End();
138 
139  /*
140  Returns:
141  Then the returned value is the total number bytes in the input
142  stream. The size is updated every time In() is called before
143  any calls are made to the output stream handler. If the
144  calculation is finished ( End() has been called ), then the
145  returned value is the total number of bytes in the entire
146  input stream.
147  */
148  ON__UINT64 InSize() const;
149 
150  /*
151  Returns:
152  Then the returned value is the total number bytes in the output
153  stream. The size is incremented immediately after each call to
154  the output stream handler. If the compression calculation is
155  finished ( End() has been called ), then the returned value is
156  the total number of bytes in the entire output stream.
157  */
158  ON__UINT64 OutSize() const;
159 
160  /*
161  Returns:
162  Then the returned value is the 32-bit crc of the input stream.
163  The crc is updated every time In() is called before any calls
164  are made to the output stream handler. If the compression
165  calculation is finished ( End() has been called ), then the
166  returned value is the 32-bit crc of the entire input stream.
167  */
168  ON__UINT32 InCRC() const;
169 
170  /*
171  Returns:
172  Then the returned value is the 32bit crc of the output stream.
173  The crc is updated immediately after each call to the output
174  stream handler. If the calculation is finished ( End() has
175  been called ), then the returned value is the 32-bit crc of
176  the entire output stream.
177  */
178  ON__UINT32 OutCRC() const;
179 
180 private:
181  ON_StreamCallbackFunction m_out_callback_function;
182  void* m_out_callback_context;
183  ON__UINT64 m_in_size;
184  ON__UINT64 m_out_size;
185  ON__UINT32 m_in_crc;
186  ON__UINT32 m_out_crc;
187  void* m_implementation;
188  void* m_reserved;
189 
190  void ErrorHandler();
191 
192 private:
193  // prohibit use - no implementation
195  ON_CompressStream& operator=(const ON_CompressStream&);
196 };
197 
198 
199 class ON_CLASS ON_UncompressStream
200 {
201 public:
203  virtual ~ON_UncompressStream();
204 
205  /*
206  Description:
207  ON_UncompressStream delivers the uncompressed stream by calling
208  an uncompressed stream output handler function. There are two
209  options for specifying the uncompressed stream output handler
210  function.
211  1. Overriding the virtual Out() function.
212  2. Providing a callback function.
213  SetCallback() is used to specify a callback function to handle
214  the uncompressed stream and to specify a context pointer to be
215  passed to either option of the handler.
216  Parameters:
217  callback_function - [in]
218  Function to call with sections of the uncompressed stream.
219  If callback_function is null, then the virtual Out()
220  function will be called. When callback_function
221  is specified, it must return true if the uncompression
222  calculation should continue and false to cancel the
223  uncompression calculation.
224  callback_context - [in]
225  This value is passed as the first argument when calling
226  callback_function or the virutal Out() function.
227  Returns:
228  True if successful.
229  Remarks:
230  Once uncompression has started, it would be unusual to
231  intentionally change the uncompressed stream output handler,
232  but you can do this if you need to.
233  */
234  bool SetCallback(
235  ON_StreamCallbackFunction callback_function,
236  void* callback_context
237  );
238 
239  /*
240  Returns:
241  Current value of the callback function for handling
242  the uncompressed stream. If the callback function is
243  null, the the virtual UncompressedStreamOut() function
244  is used.
245  */
246  ON_StreamCallbackFunction CallbackFunction() const;
247 
248  /*
249  Returns:
250  Current value of the context pointer passed as the first
251  argument to the uncompressed stream output handler function.
252  */
253  void* CallbackContext() const;
254 
255  /*
256  Description:
257  Call BeginUnompressStream() one time to initialize the compression
258  calculation. Then call In() one or more times
259  to submit the compressed stream to the uncompression calculation.
260  When you reach the end of the compressed stream, call
261  End().
262  Returns:
263  true if successful, false if an error occured.
264  */
265  bool Begin();
266 
267  /*
268  Description:
269  Call In() one or more times to uncompress a stream of compressed
270  bytes. After the last call to In(), call End(). Calling End()
271  may generate zero or more calls to the output stream handler.
272  Parameters:
273  in_buffer_size - [in]
274  number of bytes in in_buffer
275  in_buffer - [in]
276  Returns:
277  true if successful, false if an error occured.
278  */
279  bool In(
280  ON__UINT64 in_buffer_size,
281  const void* in_buffer
282  );
283 
284  /*
285  Description:
286  If an explicit uncompressed stream handler is not specified
287  ( CallbackFunction() returns null ), then the virtual Out()
288  function is called to handle the uncompressed output stream.
289  As the input stream is uncompressed, one or more calls to Out()
290  will occur.
291  Returns:
292  True to continue uncompressing and false to cancel the
293  uncompression calculation.
294  Remarks:
295  In general, it is probably going to be easier to test and debug
296  your code if you ignore the callback_context parameter and add
297  a member variable to your derived class to make additional
298  information accessable to your Out function.
299  */
300  virtual bool Out(
301  void* callback_context,
302  ON__UINT32 out_buffer_size,
303  const void* out_buffer
304  );
305 
306  /*
307  Description:
308  After the last call to In(), call End().
309  Calling End() may generate zero or more
310  calls to the output stream handler.
311  Returns:
312  true if successful, false if an error occured.
313  */
314  bool End();
315 
316  /*
317  Returns:
318  Then the returned value is the total number bytes in the input
319  stream. The size is updated every time In() is called before
320  any calls are made to the output stream handler. If the
321  calculation is finished ( End() has been called ), then the
322  returned value is the total number of bytes in the entire
323  input stream.
324  */
325  ON__UINT64 InSize() const;
326 
327  /*
328  Returns:
329  Then the returned value is the total number bytes in the output
330  stream. The size is incremented immediately after each call to
331  the output stream handler. If the compression calculation is
332  finished ( End() has been called ), then the returned value is
333  the total number of bytes in the entire output stream.
334  */
335  ON__UINT64 OutSize() const;
336 
337  /*
338  Returns:
339  Then the returned value is the 32-bit crc of the input stream.
340  The crc is updated every time In() is called before any calls
341  are made to the output stream handler. If the compression
342  calculation is finished ( End() has been called ), then the
343  returned value is the 32-bit crc of the entire input stream.
344  */
345  ON__UINT32 InCRC() const;
346 
347  /*
348  Returns:
349  Then the returned value is the 32bit crc of the output stream.
350  The crc is updated immediately after each call to the output
351  stream handler. If the calculation is finished ( End() has
352  been called ), then the returned value is the 32-bit crc of
353  the entire output stream.
354  */
355  ON__UINT32 OutCRC() const;
356 
357 private:
358  ON_StreamCallbackFunction m_out_callback_function;
359  void* m_out_callback_context;
360  ON__UINT64 m_in_size;
361  ON__UINT64 m_out_size;
362  ON__UINT32 m_in_crc;
363  ON__UINT32 m_out_crc;
364  void* m_implementation;
365  void* m_reserved;
366 
367  void ErrorHandler();
368 
369 private:
370  // prohibit use - no implementation
372  ON_UncompressStream& operator=(const ON_UncompressStream&);
373 };
374 
375 /*
376 Description:
377  Simple tool for uncompressing a buffer when the output
378  buffer size is known.
379 Parameters:
380  sizeof_compressed_buffer - [in]
381  byte count
382  compressed_buffer - [in]
383  sizeof_uncompressed_buffer
384  byte count
385  uncompressed_buffer - [out]
386 Returns:
387  Number of bytes written to uncompressed_buffer.
388 */
389 ON_DECL
390 size_t ON_UncompressBuffer(
391  size_t sizeof_compressed_buffer,
392  const void* compressed_buffer,
393  size_t sizeof_uncompressed_buffer,
394  void* uncompressed_buffer
395  );
396 
397 class ON_CLASS ON_CompressedBuffer
398 {
399 public:
403  ON_CompressedBuffer& operator=(const ON_CompressedBuffer& src);
404 
405  /*
406  Description:
407  Compress inbuffer.
408  Parameters:
409  sizeof__inbuffer - [in]
410  Number of bytes in inbuffer.
411  inbuffer - [in]
412  Uncompressed information.
413  sizeof_element - [out]
414  This parameter only matters if the buffer will be compressed,
415  and decompressed on CPUs with different endianness. If this
416  is the case, then the types in the buffer need to have the
417  same size (2,4, or 8).
418  Returns:
419  True if inbuffer is successfully compressed.
420  */
421  bool Compress(
422  size_t sizeof__inbuffer, // sizeof uncompressed input data
423  const void* inbuffer, // uncompressed input data
424  int sizeof_element
425  );
426 
427  /*
428  Returns:
429  Number of bytes in the uncompressed information.
430  */
431  size_t SizeOfUncompressedBuffer() const;
432 
433  /*
434  Description:
435  Uncompress the contents of this ON_CompressedBuffer.
436  Parameters:
437  outbuffer - [in/out]
438  This buffer must have at least SizeOfUncompressedBuffer() bytes.
439  If the function returns true, then the uncopressed information
440  is stored in this buffer.
441  bFailedCRC - [out]
442  If not null, then this boolean is set to true if the CRC
443  of the uncompressed information has changed.
444  Returns:
445  True if uncompressed information is returned in outbuffer.
446  */
447  bool Uncompress( // read and uncompress
448  void* outbuffer, // uncompressed output data returned here
449  int* bFailedCRC
450  ) const;
451 
452  /*
453  Description:
454  Destroy the current informtion in the ON_CompressedBuffer
455  so the class can be reused.
456  */
457  void Destroy();
458 
459  bool Write(ON_BinaryArchive& binary_archive) const;
460  bool Read(ON_BinaryArchive& binary_archive);
461 
462  /////////////////////////////////////////////////
463  //
464  // Implementation
465  //
466  bool CompressionInit(struct ON_CompressedBufferHelper*) const;
467  bool CompressionEnd(struct ON_CompressedBufferHelper*) const;
468  size_t DeflateHelper( // returns number of bytes written
469  struct ON_CompressedBufferHelper*,
470  size_t sizeof___inbuffer, // sizeof uncompressed input data ( > 0 )
471  const void* in___buffer // uncompressed input data ( != nullptr )
472  );
473  bool InflateHelper(
474  struct ON_CompressedBufferHelper*,
475  size_t sizeof___outbuffer, // sizeof uncompressed data
476  void* out___buffer // buffer for uncompressed data
477  ) const;
478  bool WriteChar(
479  size_t count,
480  const void* buffer
481  );
482 
483  size_t m_sizeof_uncompressed;
484  size_t m_sizeof_compressed;
485  ON__UINT32 m_crc_uncompressed;
486  ON__UINT32 m_crc_compressed;
487  int m_method; // 0 = copied, 1 = compressed
488  int m_sizeof_element;
489  size_t m_buffer_compressed_capacity;
490  void* m_buffer_compressed;
491 };
492 
493 #endif
Definition: opennurbs_compress.h:193
Definition: opennurbs_archive.h:1783
Definition: opennurbs_compress.h:22
Definition: opennurbs_compress.h:384