Point Cloud Library (PCL)  1.9.1-dev
opennurbs_archive.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(ON_ARCHIVE_INC_)
18 #define ON_ARCHIVE_INC_
19 
20 class ON_CLASS ON_FileStream
21 {
22 public:
23  /*
24  Description:
25  Portable wrapper for C runtime fopen().
26  Parameters:
27  filename - [in]
28  mode - [in]
29  Remarks:
30  Use the ON_FileStream static functions for reading, writing,
31  seeking, position finding with the FILE pointer returned
32  by this function.
33  */
34  static FILE* Open( const wchar_t* filename, const wchar_t* mode );
35 
36  /*
37  Description:
38  Portable wrapper for C runtime fopen().
39  Parameters:
40  filename - [in]
41  mode - [in]
42  Remarks:
43  Use the ON_FileStream static functions for reading, writing,
44  seeking, position finding with the FILE pointer returned
45  by this function.
46  */
47  static FILE* Open( const char* filename, const char* mode );
48 
49  /*
50  Description:
51  Portable wrapper for C runtime fclose().
52  Parameters:
53  fp - [in]
54  FILE pointer returned by ON_FileStream::Open().
55  Returns:
56  0: successful
57  -1: null fp parameter
58  != 0: fclose() failure code
59  */
60  static int Close( FILE* fp );
61 
62  /*
63  Description:
64  Portable wrapper for C runtime ftell().
65  Parameters:
66  fp - [in]
67  FILE pointer returned by ON_FileStream::Open().
68  Returns:
69  >= 0: current file position
70  -1: an error occured
71  */
72  static ON__INT64 CurrentPosition( FILE* fp );
73 
74  /*
75  Description:
76  Portable wrapper for C runtime fseek(fp,offset,SEEK_CUR).
77  Parameters:
78  fp - [in]
79  FILE pointer returned by ON_FileStream::Open().
80  offset - [in]
81  */
82  static bool SeekFromCurrentPosition( FILE* fp, ON__INT64 offset );
83 
84  /*
85  Description:
86  Portable wrapper for C runtime fseek(fp,offset,SEEK_SET).
87  Parameters:
88  fp - [in]
89  FILE pointer returned by ON_FileStream::Open().
90  offset - [in]
91  */
92  static bool SeekFromStart( FILE* fp, ON__INT64 offset );
93 
94  /*
95  Description:
96  Portable wrapper for C runtime fseek(fp,offset,SEEK_END).
97  Parameters:
98  fp - [in]
99  FILE pointer returned by ON_FileStream::Open().
100  offset - [in]
101  */
102  static bool SeekFromEnd( FILE* fp, ON__INT64 offset );
103 
104  /*
105  Description:
106  Portable wrapper for C runtime fseek(fp,offset,origin).
107  Parameters:
108  fp - [in]
109  FILE pointer returned by ON_FileStream::Open().
110  offset - [in]
111  origin - [in]
112  SEEK_SET (0): seek from beginning of file.
113  SEEK_CUR (1): seek from current position of file pointer.
114  SEEK_END (2): seek from end of file.
115  */
116  static bool Seek( FILE* fp, ON__INT64 offset, int orgin );
117 
118  /*
119  Description:
120  Portable wrapper for C runtime fread(buffer,1,count,fp).
121  Parameters:
122  fp - [in]
123  FILE pointer returned by ON_FileStream::Open()
124  count - [in]
125  number of bytes to read.
126  buffer - [out]
127  read bytes are stored in this buffer
128  Returns:
129  number of bytes read
130  */
131  static ON__UINT64 Read( FILE* fp, ON__UINT64 count, void* buffer );
132 
133  /*
134  Description:
135  Portable wrapper for C runtime fwrite(buffer,1,count,fp).
136  Parameters:
137  fp - [in]
138  FILE pointer returned by ON_FileStream::Open()
139  count - [in]
140  number of bytes to write
141  buffer - [in]
142  data to be written
143  Returns:
144  number of bytes written.
145  */
146  static ON__UINT64 Write( FILE* fp, ON__UINT64 count, const void* buffer );
147 
148  /*
149  Description:
150  Portable wrapper for C runtime fflush(fp).
151  Parameters:
152  fp - [in]
153  FILE pointer returned by ON_FileStream::Open().
154  Returns:
155  true if flush was successful. False if an error occured.
156  */
157  static bool Flush( FILE* fp );
158 
159  /*
160  Description:
161  Portable wrapper for C runtime fstat().
162  Parameters:
163  fp - [in]
164  FILE pointer returned by ON_FileStream::Open().
165  file_size - [out]
166  If file_size is not null, the the size of the file
167  in bytes returned here
168  file_creation_time - [out]
169  If file_creation_time is not null, then the time the file
170  was created is returned here as the number of seconds since
171  midnight January 1, 1970.
172  file_last_modified_time - [out]
173  If file_last_modified_time is not null, then the time the file
174  was last modified is returned here as the number of seconds
175  since midnight January 1, 1970.
176  Returns:
177  true if the query was successful. False if an error occured.
178  */
179  static bool GetFileInformation(
180  FILE* fp,
181  ON__UINT64* file_size,
182  ON__UINT64* file_create_time,
183  ON__UINT64* file_last_modified_time
184  );
185 };
186 
187 class ON_CLASS ON_FileIterator
188 {
189 public:
190  ON_FileIterator();
191  ~ON_FileIterator();
192  void Destroy();
193 
194  /*
195  Description:
196  Find the first matching file in the directory.
197  Parameters:
198  directory_name - [in]
199  The directory to look in.
200  file_name_filter - [in]
201  If this paramter is null, then the iteration
202  includes all names in the directory.
203  The file name to search for. This parameter can
204  include wildcard characters, such as an
205  asterisk (*) or a question mark (?). For example,
206  "\rootdir\subdir\*.*" will iterate all files in
207  the \rootdir\subdir\ directory.
208 
209  Example:
210  // Iterate through the files in a directory named "\rootdir\subdir"
211  FILE* fp = 0;
212  ON_FileIterator fit;
213  const char* directory = "\\rootdir\\subdir";
214  for ( const wchar_t* filename = fit.FirstFile( directory, "*.3dm" );
215  0 != filename;
216  filename = fit.NextFile()
217  )
218  {
219  if ( fit.CurrentFileIsDirectory() )
220  continue;
221  ON_String fullpath = directory;
222  fullpath += '\\';
223  fullpath += filename;
224  FILE* fp = ON_FileStream::Open(fullpath,"rb");
225  if ( 0 == fp )
226  {
227  continue;
228  }
229  ...
230  ON_FileStream::Close(fp);
231  fp = 0;
232  }
233  }
234 
235  Returns:
236  NULL if no matching files are present in the directory.
237  */
238  const wchar_t* FirstFile(
239  const wchar_t* directory_name,
240  const wchar_t* file_name_filter
241  );
242 
243  const wchar_t* FirstFile(
244  const char* directory_name,
245  const char* file_name_filter
246  );
247 
248  /*
249  Description:
250  Find the next matching file in the directory.
251  Returns:
252  NULL if no more matching files are present in the directory.
253  */
254  const wchar_t* NextFile();
255 
256  const wchar_t* CurrentFileName() const;
257 
258  ON__UINT64 CurrentFileSize() const;
259 
260  /*
261  Returns
262  true if the current "file" is a directory.
263  */
264  bool CurrentFileIsDirectory() const;
265 
266  /*
267  Returns
268  true if the current file or directory is hidden.
269  This means its name begins with a '.' or it's
270  Windows hidden attribute is true.
271  */
272  bool CurrentFileIsHidden() const;
273 
274  bool GetCurrentFullPathFileName( ON_wString& filename ) const;
275 
276  /*
277  Returns:
278  File creation time in seconds since January 1, 1970
279  */
280  ON__UINT64 CurrentFileCreateTime() const;
281 
282  /*
283  Returns:
284  File last modified time in seconds since January 1, 1970
285  */
286  ON__UINT64 CurrentFileLastModifiedTime() const;
287 
288  /*
289  Returns:
290  File last access time in seconds since January 1, 1970
291  */
292  ON__UINT64 CurrentFileLastAccessTime() const;
293 
294  /*
295  Returns:
296  Number of matching files returned so far.
297  */
298  ON__UINT64 Count() const;
299 
300 private:
301  // Used by Windows ::Find
302  ON__UINT64 m_count;
303  ON_wString m_directory;
304 
305 #if defined(ON_COMPILER_MSC)
306  ON__UINT32 m_file_attributes_mask;
307  HANDLE m_h;
308  WIN32_FIND_DATA m_fd;
309 #else
310  ON_wString m_ws_file_name_filter;
311  ON_String m_utf8_file_name_filter;
312  DIR* m_dir;
313  struct dirent m_dirent;
314  char m_dirent_name_buffer[NAME_MAX+1]; // < this field provide storage for m_dirent.d_name[]
315 
316  // information about the current file
317  wchar_t m_current_name[1024];
318  ON__UINT64 m_current_file_attributes; // 1 = regular file, 2 = directory
319  ON__UINT64 m_current_file_size;
320  ON__UINT64 m_current_file_create_time;
321  ON__UINT64 m_current_last_modified_time;
322  ON__UINT64 m_current_last_access_time;
323 #endif
324 };
325 
326 
327 /////////////////////////////////////////////////////////////////////
328 //
329 // ON_Buffer
330 //
331 
332 typedef void (*ON_Buffer_ErrorHandler)(class ON_Buffer*);
333 
334 class ON_CLASS ON_Buffer
335 {
336 public:
337  ON_Buffer();
338  ~ON_Buffer();
339 
340  ON_Buffer(const ON_Buffer& src);
341  ON_Buffer& operator=(const ON_Buffer& src);
342 
343  /*
344  Description:
345  Compare contents of buffers.
346  Paramters:
347  a - [in]
348  b - [in]
349  Returns:
350  -1: a < b
351  0: a == b
352  1: a > b
353  */
354  static int Compare( const ON_Buffer& a, const ON_Buffer& b );
355 
356  void Destroy();
357  void EmergencyDestroy();
358 
359  /*
360  Returns:
361  True if Size() == CurrentPosition().
362  Remarks:
363  It is possible to seek beyond the end of the buffer.
364  In this case, the current position will be past the end
365  of the buffer and AtEnd() will return false.
366  */
367  bool AtEnd() const;
368 
369  /*
370  Returns:
371  Number of bytes currently in the buffer.
372  Remarks:
373  It is possible to seek beyond the end of the buffer.
374  In this case, the current position will be past the end
375  of the buffer and CurrentPosition() will be greater than
376  Size().
377  */
378  ON__UINT64 Size() const;
379 
380  /*
381  Returns:
382  32-bit CRC of the buffer contents.
383  Remarks:
384 
385  */
386  ON__UINT32 CRC32( ON__UINT32 current_remainder ) const;
387 
388 
389  /*
390  Returns:
391  Current position in the buffer.
392  Remarks:
393  It is possible to seek beyond the end of the buffer.
394  In this case, the current position will be past the end
395  of the buffer and CurrentPosition() will be greater than
396  Size().
397  */
398  ON__UINT64 CurrentPosition() const;
399 
400  /*
401  Parameters:
402  size - [in]
403  number of bytes to write.
404  buffer - [in]
405  values to write.
406  Returns:
407  Number of bytes written buffer.
408  */
409  ON__UINT64 Write( ON__UINT64 size, const void* buffer );
410 
411  /*
412  Parameters:
413  size - [in]
414  number of bytes to read.
415  buffer - [out]
416  read values are returned in buffer.
417  Returns:
418  Number of bytes read into buffer. For example,
419  if CurrentPosition() <= Size() and
420  size > (Size() - CurrentPosition()) and
421  buffer is not null, then the value
422  (Size() - CurrentPosition()) is returned.
423  Remarks:
424  If the size parameter is zero, then nothing is done.
425  When CurrentPosition() <= Size(), attempts to read more
426  than (Size() - CurrentPosition()) bytes do not generate
427  an error. When CurrentPosition() > Size(), any attempt
428  to read generates an error.
429  */
430  ON__UINT64 Read( ON__UINT64 size, void* buffer );
431 
432  enum
433  {
434  seek_from_beginning_of_file = 0,
435  seek_from_current_position = 1,
436  seek_from_end_of_file = 2
437  };
438 
439  /*
440  Parameters:
441  offset - [in]
442  number of bytes to seek from origin
443  origin - [in]
444  initial position.
445  0 (SEEK_SET) Seek from beginning of file.
446  1 (SEEK_CUR) Seek from current position.
447  2 (SEEK_END) Seek from end of file.
448  Returns:
449  True if successful.
450  False if the seek would result in a file position
451  before the beginning of the file. If false is
452  returned, the current position is not changed.
453  Remarks:
454  Seeking beyond the end of the buffer is succeeds.
455  Seeking before the beginning of the buffer fails.
456  */
457  bool Seek(
458  ON__INT64 offset,
459  int origin
460  );
461 
462  /*
463  Parameters:
464  offset - [in] (>= 0)
465  number of bytes to seek from the start of the buffer.
466  Returns:
467  True if successful.
468  False if the seek would result in a file position
469  before the beginning of the file. If false is
470  returned, the current position is not changed.
471  Remarks:
472  Seeking beyond the end of the buffer is succeeds.
473  Seeking before the beginning of the buffer fails.
474  */
475  bool SeekFromStart( ON__INT64 offset );
476 
477  /*
478  Parameters:
479  offset - [in]
480  number of bytes to seek from the current position.
481  Returns:
482  True if successful.
483  False if the seek would result in a file position
484  before the beginning of the file. If false is
485  returned, the current position is not changed.
486  Remarks:
487  Seeking beyond the end of the buffer is succeeds.
488  Seeking before the beginning of the buffer fails.
489  */
490  bool SeekFromCurrentPosition( ON__INT64 offset );
491 
492  /*
493  Parameters:
494  offset - [in]
495  number of bytes to seek from the end fo the buffer.
496  Returns:
497  True if successful.
498  False if the seek would result in a file position
499  before the beginning of the file. If false is
500  returned, the current position is not changed.
501  Remarks:
502  Seeking beyond the end of the buffer is succeeds.
503  Seeking before the beginning of the buffer fails.
504  */
505  bool SeekFromEnd( ON__INT64 offset );
506 
507  /*
508  Parameters:
509  buffer_size - [in]
510  new size of buffer.
511  Returns:
512  True if successful.
513  Remarks:
514  The current position is not changed and may be beyond the
515  end of the file. Use Seek to set the current position after
516  calling ChangeSize().
517  */
518  bool ChangeSize( ON__UINT64 buffer_size );
519 
520  /*
521  Description:
522  Return unused memory to heap.
523  Remarks:
524  Call this function after creating an ON_Buffer that will persist for
525  and extended amount of time. There are never more than 16 pages of
526  unsued memory (16*4096 bytes on most computers) in an ON_Buffer.
527  Compact() can be called at any time, but calling Compact() the then
528  writing at the end of the buffer is not an efficient use of time
529  or memory.
530  */
531  bool Compact();
532 
533  /*
534  Returns
535  True if the ON_Buffer is valid.
536  */
537  bool IsValid( const ON_TextLog* text_log ) const;
538 
539  /*
540  Returns:
541  Value that identifies most recent error.
542  0: no error
543  1: attempt to seek to a negative position
544  */
545  ON__UINT32 LastError() const;
546 
547  void ClearLastError();
548 
549  ON_Buffer_ErrorHandler ErrorHandler() const;
550 
551  void SetErrorHandler(ON_Buffer_ErrorHandler error_handler);
552 
553  /*
554  Description:
555  Use WriteToBinaryArchive() to save an entire ON_Buffer inside
556  a binary archive. Use ReadFromBinaryArchive() to retrieve
557  the ON_Buffer from the ON_BinaryArchive.
558  */
559  bool WriteToBinaryArchive( ON_BinaryArchive& ) const;
560 
561  /*
562  Description:
563  Use ReadFromBinaryArchive() to retrieve an entire ON_Buffer
564  that was written using WriteToBinaryArchive().
565  */
566  bool ReadFromBinaryArchive( ON_BinaryArchive& );
567 
568  /*
569  Description:
570  Compress this buffer
571 
572  Parameters:
573  compressed_buffer - [out]
574  (The reference can be *this)
575 
576  Example:
577 
578  // compress a buffer in place
579  ON_Buffer buffer;
580  buffer = ...;
581  if ( !buffer.Compress(buffer) )
582  {
583  // compression failed
584  }
585  else
586  {
587  // buffer is now compressed
588  }
589 
590  Returns:
591  True if successful. False if failed.
592  */
593  bool Compress( ON_Buffer& compressed_buffer ) const;
594 
595  /*
596  Description:
597  Uncompress this buffer which must have been compressed using
598  ON_Buffer::Compress().
599 
600  Parameters:
601  uncompressed_buffer - [out]
602  (The reference can be *this)
603 
604  Example:
605  // silly example that compresses and then uncompresses a buffer in place
606  // to show how to call the functions.
607  ON_Buffer buffer;
608  buffer = ...; // buffer is in it uncompressed form
609  if ( buffer.Compress(buffer) )
610  {
611  // buffer is now compressed
612  if ( buffer.Uncompress(buffer) )
613  {
614  // buffer is uncompressed again.
615  }
616  }
617 
618  Returns:
619  True if successful. False if failed.
620  */
621  bool Uncompress( ON_Buffer& uncompressed_buffer ) const;
622 
623 private:
624 
625  ON__UINT64 m_buffer_size; // total number of bytes in the buffer
626  ON__UINT64 m_current_position;
627 
628  struct ON_BUFFER_SEGMENT* m_first_segment;
629  struct ON_BUFFER_SEGMENT* m_last_segment;
630  struct ON_BUFFER_SEGMENT* m_current_segment;
631  bool SetCurrentSegment(bool);
632  void Copy( const ON_Buffer& );
633 
634  ON_MEMORY_POOL* m_heap;
635  ON_Buffer_ErrorHandler m_error_handler;
636 
637  ON__UINT32 m_last_error;
638  unsigned char m_reserved[12];
639 };
640 
641 /////////////////////////////////////////////////////////////////////
642 //
643 // ON_BinaryArchive
644 // virtual class for CPU independent serialization
645 //
646 // ON_BinaryFile
647 // simple class for CPU independent binary file I/O
648 // includes optional CRC support
649 //
650 
651 class ON_Object;
652 class ON_Group;
653 class ON_Font;
654 class ON_DimStyle;
655 class ON_Arc;
656 class ON_ObjectAttributes;
658 class ON_HatchPattern;
659 class ON_Linetype;
660 
662 {
663  size_t m_offset; // In read or write_using_fseek mode, this is the
664  // file position of first byte after chunk's length.
665  // In write_using_buffer mode, this of the m_buffer[]
666  // position of first byte after chunk's length.
667  unsigned int m_typecode;
668  int m_value;
669  int m_do_length; // true if chunk is a long chunk with length
670  ON__UINT16 m_do_crc16; // 16 bit CRC using CCITT polynomial
671  ON__UINT16 m_crc16;
672  ON__UINT32 m_do_crc32; // 32 bit CRC
673  ON__UINT32 m_crc32;
674 };
675 
677 {
678  ON__UINT64 m_big_offset; // In read or write_using_fseek mode, this is the
679  // file position of first byte after chunk's length.
680  // In write_using_buffer mode, this of the m_buffer[]
681  // position of first byte after chunk's length.
682 
683  ON__UINT64 Length() const; // 0 for short chunks
684 
685  ON__INT64 m_big_value;
686  ON__UINT32 m_typecode;
687 
688  ON__UINT8 m_bLongChunk; // true if chunk is a long chunk and m_big_value is a length.
689  ON__UINT8 m_reserved1;
690  ON__UINT8 m_reserved2;
691  ON__UINT8 m_reserved3;
692 
693  // CRC settings
694  ON__UINT8 m_do_crc16; // true (1) if we are calculating 16 bit CRC
695  ON__UINT8 m_do_crc32; // true (1) if we are calculating 32 bit CRC
696  ON__UINT16 m_crc16; // current 16 bit CRC value
697  ON__UINT32 m_crc32; // current 32 bit CRC value
698 };
699 
700 bool ON_IsLongChunkTypecode(ON__UINT32 typecode);
701 
702 bool ON_IsShortChunkTypecode(ON__UINT32 typecode);
703 
704 #if defined(ON_DLL_TEMPLATE)
705 // This stuff is here because of a limitation in the way Microsoft
706 // handles templates and DLLs. See Microsoft's knowledge base
707 // article ID Q168958 for details.
708 #pragma warning( push )
709 #pragma warning( disable : 4231 )
710 ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON_3DM_CHUNK>;
711 ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON_3DM_BIG_CHUNK>;
712 #pragma warning( pop )
713 #endif
714 
715 class ON_Light;
716 class ON_Bitmap;
717 class ON_TextureMapping;
718 class ON_Material;
719 class ON_Layer;
720 class ON_3dmProperties;
721 class ON_3dmSettings;
723 class ON_3dmGoo;
724 
725 class ON_BinaryArchive;
726 
727 // Used int ON_3dmProperties::Read() to set ON_BinaryArchive.m_3dm_opennurbs_version
728 // Do not call directly.
729 void ON_SetBinaryArchiveOpenNURBSVersion(ON_BinaryArchive&,int);
730 
731 class ON_CLASS ON_BinaryArchive // use for generic serialization of binary data
732 {
733 public:
734  ON_BinaryArchive( ON::archive_mode );
735  virtual ~ON_BinaryArchive();
736 
737  virtual
738  size_t CurrentPosition( // current offset (in bytes) into archive ( like ftell() )
739  ) const = 0;
740  virtual
741  bool SeekFromCurrentPosition( // seek from current position ( like fseek( ,SEEK_CUR) )
742  int // byte offset ( >= -CurrentPostion() )
743  ) = 0;
744  virtual
745  bool SeekFromStart( // seek from current position ( like fseek( ,SEEK_SET) )
746  size_t // byte offset ( >= 0 )
747  ) = 0;
748  virtual
749  bool AtEnd() const = 0; // true if at end of file
750 
751  bool BigSeekFromStart( ON__UINT64 offset );
752  bool BigSeekForward( ON__UINT64 offset );
753  bool BigSeekBackward( ON__UINT64 offset );
754  bool BigSeekFromCurrentPosition( ON__INT64 offset );
755 
756  /*
757  Description:
758  Tool for swapping bytes when doing I/O on
759  using big endian CPUs.
760  Remarks:
761  3dm files are always saved with little endian byte order.
762  See Also:
763  ON_BinaryArchive::Endian
764  */
765  static
766  bool ToggleByteOrder(
767  int, // number of elements
768  int, // size of element (2,4, or 8)
769  const void*, // source buffer
770  void* // destination buffer (can be same a source buffer)
771  );
772 
773  static
774  const char* TypecodeName( unsigned int tcode );
775 
776  static
777  char* ON_TypecodeParse( unsigned int tcode, char* typecode_name, size_t max_length );
778 
779  bool ReadMode() const; // true if reading is permitted
780  bool WriteMode() const; // true if writing is permitted
781 
782  /*
783  Returns:
784  Endian-ness of the cpu reading this file.
785  Remarks:
786  3dm files are alwasy saved with little endian byte order.
787  */
788  ON::endian Endian() const; // endian-ness of cpu
789 
790  int BadCRCCount() const; // number of chunks read with bad CRC
791 
792  bool ReadByte( size_t, void* ); // must fail if mode is not read or readwrite
793 
794  bool WriteByte( size_t, const void* ); // must fail if mode is not write or readwrite
795 
796  /*
797  Description:
798  Expert user function that uses Read() to load a buffer.
799  Paramters:
800  sizeof_buffer - [in] number of bytes to attempt to read.
801  buffer - [out] read bytes are stored in this buffer
802  Returns:
803  Number of bytes actually read, which may be less than
804  sizeof_buffer if the end of file is encountered.
805  */
806  ON__UINT64 ReadBuffer( ON__UINT64 sizeof_buffer, void* buffer );
807 
808  /*
809  Description:
810  Expert user function to control CRC calculation while reading and writing.
811  Typically this is used when seeking around and reading/writing information
812  in non-serial order.
813  Parameters:
814  bEnable - [in]
815  Returns:
816  Current state of CRC calculation. Use the returned value to restore the
817  CRC calculation setting after you are finished doing your fancy pants
818  expert IO.
819  */
820  bool EnableCRCCalculation( bool bEnable );
821 
822  // ReadCompressedBuffer()/WriteCompressedBuffer() use zlib 1.1.3
823  // to inflate/deflate the data buffer.
824  // Care must be used to get an endian independent file.
825  // See ON_Mesh::Read()/ON_Mesh::Write() for an example of an endian
826  // independent use of compression. See also ToggleByteOrder() and Endian().
827  //
828  // To read data archived by WriteCompressedBuffer( sizeof_buffer, buffer )
829  // do something like:
830  //
831  // size_t sizeof_buffer = 0;
832  // ReadCompressedBufferSize(&sizeof_buffer);
833  // buffer = something with sizeof_buffer bytes.
834  // int bFailedCRC = false;
835  // bool ok = ReadCompressedBuffer( sizeof_buffer, buffer, &bFailedCRC );
836  //
837 
838 
839  /*
840  Description:
841  Red the size of a compressed buffer.
842  Parameters:
843  sizeof__outbuffer - [out] size of the uncompressed buffer in bytes
844  Returns:
845  True if read was successful.
846  */
847  bool ReadCompressedBufferSize( size_t* sizeof__outbuffer );
848 
849  /*
850  Description:
851  Read compressed information from an archive and uncompress it.
852  Parameters:
853  sizeof__outbuffer - [in] size of the uncompressed buffer in bytes
854  outbuffer - [out] uncompressed buffer returned here
855  bFailedCRC - [out] true if cyclic redundancy check fails
856  on uncompressed buffer
857 
858  Example:
859 
860  size_t sizeof_buffer = 0;
861  ReadCompressedBufferSize(&sizeof_buffer);
862  buffer = ...; // something with sizeof_buffer bytes.
863  int bFailedCRC = false;
864  bool ok = ReadCompressedBuffer( sizeof_buffer, buffer, &bFailedCRC );
865 
866  Returns:
867  True if read was successful. You need to check the value
868  of bFailedCRC to see if the information that was read is valid.
869  */
870  bool ReadCompressedBuffer(
871  size_t sizeof__outbuffer,
872  void* outbuffer,
873  int* bFailedCRC
874  );
875 
876  /*
877  Description:
878  Compress buffer and write the compressed information to the archive.
879  Parameters:
880  sizeof__inbuffer - [in] size of the uncompressed buffer in bytes
881  inbuffer - [in] uncompressed buffer
882  Returns:
883  True if write was successful.
884  */
885  bool WriteCompressedBuffer(
886  size_t sizeof__inbuffer,
887  const void* inbuffer
888  );
889 
890  bool ReadBool( bool* );
891 
892  bool ReadChar( // Read an array of 8 bit chars
893  size_t, // number of chars to read
894  char*
895  );
896  bool ReadChar( // Read an array of 8 bit unsigned chars
897  size_t, // number of unsigned chars to read
898  unsigned char*
899  );
900  bool ReadChar( // Read a single 8 bit char
901  char*
902  );
903  bool ReadChar( // Read a single 8 bit unsigned char
904  unsigned char*
905  );
906 
907  bool ReadShort( // Read an array of 16 bit shorts
908  size_t, // number of shorts to read
909  short*
910  );
911  bool ReadShort( // Read an array of 16 bit unsigned shorts
912  size_t, // number of shorts to read
913  unsigned short*
914  );
915  bool ReadShort( // Read a single 16 bit short
916  short*
917  );
918  bool ReadShort( // Read a single 16 bit unsigned short
919  unsigned short*
920  );
921 
922  bool ReadInt( // Read an array of 32 bit integers
923  size_t, // number of ints to read
924  int*
925  );
926  bool ReadInt( // Read an array of 32 bit integers
927  size_t, // number of ints to read
928  unsigned int*
929  );
930  bool ReadInt( // Read a single 32 bit integer
931  int*
932  );
933  bool ReadInt( // Read a single 32 bit unsigned integer
934  unsigned int*
935  );
936 
937  bool ReadBigInt( // Read an array of 64 bit integers
938  size_t, // number of ints to read
939  ON__INT64*
940  );
941  bool ReadBigInt( // Read an array of 64 bit integers
942  size_t, // number of ints to read
943  ON__UINT64*
944  );
945  bool ReadBigInt( // Read a single 64 bit integer
946  ON__INT64*
947  );
948  bool ReadBigInt( // Read a single 64 bit unsigned integer
949  ON__UINT64*
950  );
951 
952  bool ReadLong( // Read an array of 32 bit integers
953  size_t, // number of ints to read
954  long*
955  );
956  bool ReadLong( // Read an array of 32 bit integers
957  size_t, // number of ints to read
958  unsigned long*
959  );
960  bool ReadLong( // Read a single 32 bit integer
961  long*
962  );
963  bool ReadLong( // Read a single 32 bit unsigned integer
964  unsigned long*
965  );
966  bool ReadSize( // Read a single size_t
967  size_t*
968  );
969 
970  bool ReadBigSize( size_t* ); // 64 bits
971 
972  bool ReadBigTime( time_t* ); // UCT seconds since 1 January 1970 (64 bits)
973 
974 
975  bool ReadFloat( // Read an array of floats
976  size_t, // number of floats
977  float*
978  );
979  bool ReadFloat( // Read a single float
980  float*
981  );
982  bool ReadDouble( // Read an array of IEEE doubles
983  size_t, // number of doubles
984  double*
985  );
986  bool ReadDouble( // Read a single double
987  double*
988  );
989 
990  bool ReadColor(
991  ON_Color&
992  );
993 
994  bool ReadPoint (
995  ON_2dPoint&
996  );
997  bool ReadPoint (
998  ON_3dPoint&
999  );
1000  bool ReadPoint (
1001  ON_4dPoint&
1002  );
1003  bool ReadVector (
1004  ON_2dVector&
1005  );
1006  bool ReadVector (
1007  ON_3dVector&
1008  );
1009 
1010  bool ReadBoundingBox(ON_BoundingBox&);
1011 
1012  bool ReadXform(ON_Xform&);
1013 
1014  bool ReadPlaneEquation(ON_PlaneEquation&);
1015 
1016  bool ReadPlane(ON_Plane&);
1017 
1018  bool ReadLine(ON_Line&);
1019 
1020  bool ReadArc(ON_Arc&);
1021 
1022  bool ReadCircle(ON_Circle&);
1023 
1024  bool ReadInterval( ON_Interval& );
1025 
1026  bool ReadUuid( ON_UUID& );
1027 
1028  bool ReadDisplayMaterialRef( ON_DisplayMaterialRef& );
1029 
1030  bool ReadLinetypeSegment( ON_LinetypeSegment& );
1031 
1032  // All times are stored in coordinated universal time
1033  // ( a.k.a GMT, UTC ). Use ANSI C time() and gmtime() calls.
1034  bool ReadTime( struct tm& );
1035 
1036  /*
1037  Parameters:
1038  str_array_count - [out]
1039  Number of elements in the string array. All ON_BinaryArchive string
1040  WriteString() functions write a null terminator to the file and
1041  the null terminator is included in the count. This means that
1042  if a string has a non-zero element, then str_array_count >= 2.
1043  Remarks:
1044  Modify your code to use ReadStringUTF8ElementCount() when reading
1045  UTF-8 encoded strings and ReadStringUTF16ElementCount()
1046  when reading UTF-16 encoded strings.
1047  */
1048  ON_DEPRECATED bool ReadStringSize(
1049  size_t* str_array_count
1050  );
1051 
1052  /*
1053  Parameters:
1054  string_utf8_element_count - [out]
1055  Number of bytes in the string array. All ON_BinaryArchive string
1056  WriteString() functions write a null terminator to the file and
1057  the null terminator is included in string_element_count. This means
1058  that if opennurbs wrote the string, either string_element_count = 0
1059  or string_element_count >= 2.
1060  */
1061  bool ReadStringUTF8ElementCount(
1062  size_t* string_utf8_element_count
1063  );
1064 
1065  /*
1066  Parameters:
1067  string_utf16_element_count - [out]
1068  Number of elements in the string array. All ON_BinaryArchive string
1069  WriteString() functions write a null terminator to the file and
1070  the null terminator is included in string_element_count. This means
1071  that if opennurbs wrote the string, either string_element_count = 0
1072  or string_element_count >= 2.
1073  */
1074  bool ReadStringUTF16ElementCount(
1075  size_t* string_utf16_element_count
1076  );
1077 
1078 
1079  /*
1080  Parameters:
1081  str_array_count - [in]
1082  Number of char elements in str_array[], including the null
1083  terminator. The value of str_array_count is returned by
1084  ReadCharStringElementCount().
1085  str_array - [in/out]
1086  Pass in an array with at least str_array_count elements.
1087  If true is returned and str_array_count > 0,
1088  then str_array[str_array_count-1] = 0. All strings with
1089  char elements written by Rhino are UTF-8 encoded
1090  unicode strings.
1091  */
1092  bool ReadString(
1093  size_t str_array_count,
1094  char* str_array
1095  );
1096 
1097  /*
1098  Parameters:
1099  str_array_count - [in]
1100  Number of unsignd char elements in str_array[], including
1101  the null terminator. The value of str_array_count is returned
1102  by ReadCharStringElementCount().
1103  str_array - [in/out]
1104  Pass in an array with at least str_array_count elements.
1105  If true is returned and str_array_count > 0,
1106  then str_array[str_array_count-1] = 0. All strings with
1107  unsigned char elements written by Rhino are UTF-8 encoded
1108  unicode strings.
1109  */
1110  bool ReadString(
1111  size_t str_array_count,
1112  unsigned char* str_array
1113  );
1114 
1115  /*
1116  Parameters:
1117  str_array_count - [in]
1118  Number of unsigned short elements in str_array[],
1119  including the null terminator. The value of
1120  str_array_count is returned by ReadWideCharStringElementCount().
1121  str_array - [in/out]
1122  Pass in an array with at least str_array_count elements.
1123  If true is returned and str_array_count > 0,
1124  then str_array[str_array_count-1] = 0. All strings with
1125  unsigned short elements written by Rhino are UTF-16 encoded
1126  unicode strings.
1127  */
1128  bool ReadString(
1129  size_t str_array_count,
1130  unsigned short* str_array
1131  );
1132 
1133  bool ReadString( ON_String& sUTF8 );
1134 
1135  bool ReadString( ON_wString& s );
1136 
1137  bool ReadComponentIndex( ON_COMPONENT_INDEX& );
1138 
1139  bool ReadArray( ON_SimpleArray<bool>& );
1140  bool ReadArray( ON_SimpleArray<char>& );
1141  bool ReadArray( ON_SimpleArray<short>& );
1142  bool ReadArray( ON_SimpleArray<int>& );
1143  bool ReadArray( ON_SimpleArray<float>& );
1144  bool ReadArray( ON_SimpleArray<double>& );
1145  bool ReadArray( ON_SimpleArray<ON_Color>& );
1146  bool ReadArray( ON_SimpleArray<ON_2dPoint>& );
1147  bool ReadArray( ON_SimpleArray<ON_3dPoint>& );
1148  bool ReadArray( ON_SimpleArray<ON_4dPoint>& );
1149  bool ReadArray( ON_SimpleArray<ON_2dVector>& );
1150  bool ReadArray( ON_SimpleArray<ON_3dVector>& );
1151  bool ReadArray( ON_SimpleArray<ON_Xform>& );
1152  bool ReadArray( ON_SimpleArray<ON_2fPoint>& );
1153  bool ReadArray( ON_SimpleArray<ON_3fPoint>& );
1154  bool ReadArray( ON_SimpleArray<ON_4fPoint>& );
1155  bool ReadArray( ON_SimpleArray<ON_2fVector>& );
1156  bool ReadArray( ON_SimpleArray<ON_3fVector>& );
1157  bool ReadArray( ON_SimpleArray<ON_UUID>& );
1158  bool ReadArray( ON_SimpleArray<ON_UuidIndex>& );
1159  bool ReadArray( ON_SimpleArray<ON_SurfaceCurvature>& );
1160  bool ReadArray( ON_ClassArray<ON_String>& );
1161  bool ReadArray( ON_ClassArray<ON_wString>& );
1162  bool ReadArray( ON_SimpleArray<ON_DisplayMaterialRef>& );
1163  bool ReadArray( ON_SimpleArray<ON_LinetypeSegment>& );
1164  bool ReadArray( ON_SimpleArray<ON_MappingChannel>& );
1165  bool ReadArray( ON_ClassArray<ON_MaterialRef>& );
1166  bool ReadArray( ON_ClassArray<ON_MappingRef>& );
1167  bool ReadArray( ON_ClassArray<class ON_ObjRef>& );
1168  bool ReadArray( ON_SimpleArray<class ON_ObjRef_IRefID>& );
1169  bool ReadArray( ON_SimpleArray<class ON_ClippingPlaneInfo>& );
1170  bool ReadArray( ON_ObjectArray<class ON_Layer>& );
1171  bool ReadArray( ON_SimpleArray<class ON_Layer*>& );
1172 
1173  bool WriteBool( bool );
1174 
1175  bool WriteChar( // Write an array of 8 bit chars
1176  size_t, // number of chars to write
1177  const char*
1178  );
1179  bool WriteChar( // Write an array of 8 bit unsigned chars
1180  size_t, // number of unsigned chars to write
1181  const unsigned char*
1182  );
1183  bool WriteChar( // Write a single 8 bit char
1184  char
1185  );
1186  bool WriteChar( // Write a single 8 bit unsigned char
1187  unsigned char
1188  );
1189 
1190  bool WriteShort( // Write an array of 16 bit shorts
1191  size_t, // number of shorts to write
1192  const short*
1193  );
1194  bool WriteShort( // Write an array of 16 bit unsigned shorts
1195  size_t, // number of shorts to write
1196  const unsigned short*
1197  );
1198  bool WriteShort( // Write a single 16 bit short
1199  short
1200  );
1201  bool WriteShort( // Write a single 16 bit unsigned short
1202  unsigned short
1203  );
1204 
1205  bool WriteInt( // Write an array of 32 bit integers
1206  size_t, // number of ints to write
1207  const int*
1208  );
1209  bool WriteInt( // Write an array of 32 bit integers
1210  size_t, // number of ints to write
1211  const unsigned int*
1212  );
1213  bool WriteInt( // Write a single 32 bit integer
1214  int
1215  );
1216  bool WriteInt( // Write a single 32 bit unsigned integer
1217  unsigned int
1218  );
1219 
1220  bool WriteBigInt( // Write an array of 64 bit integers
1221  size_t, // number of ints to write
1222  const ON__INT64*
1223  );
1224  bool WriteBigInt( // Write an array of 64 bit integers
1225  size_t, // number of ints to write
1226  const ON__UINT64*
1227  );
1228  bool WriteBigInt( // Write a single 64 bit integer
1229  ON__INT64
1230  );
1231  bool WriteBigInt( // Write a single 64 bit unsigned integer
1232  ON__UINT64
1233  );
1234 
1235  bool WriteLong( // Write an array of 32 bit integers
1236  size_t, // number of ints to write
1237  const long*
1238  );
1239  bool WriteLong( // Write an array of 32 bit integers
1240  size_t, // number of ints to write
1241  const unsigned long*
1242  );
1243  bool WriteLong( // Write a single 32 bit integer
1244  long
1245  );
1246  bool WriteLong( // Write a single 32 bit unsigned integer
1247  unsigned long
1248  );
1249  bool WriteSize( // Write a single size_t
1250  size_t
1251  );
1252 
1253  bool WriteBigSize( size_t ); // 64 bits
1254 
1255  bool WriteBigTime( time_t ); // UCT seconds since 1 January 1970 (64 bits)
1256 
1257  bool WriteFloat( // Write a number of IEEE floats
1258  size_t, // number of doubles
1259  const float*
1260  );
1261  bool WriteFloat( // Write a single float
1262  float
1263  );
1264  bool WriteDouble( // Write a single double
1265  size_t,
1266  const double*
1267  );
1268  bool WriteDouble( // Write a single double
1269  double
1270  );
1271 
1272  bool WriteColor (
1273  const ON_Color&
1274  );
1275 
1276  bool WritePoint (
1277  const ON_2dPoint&
1278  );
1279  bool WritePoint (
1280  const ON_3dPoint&
1281  );
1282  bool WritePoint (
1283  const ON_4dPoint&
1284  );
1285  bool WriteVector (
1286  const ON_2dVector&
1287  );
1288  bool WriteVector (
1289  const ON_3dVector&
1290  );
1291 
1292  bool WriteBoundingBox(const ON_BoundingBox&);
1293 
1294  bool WriteXform(const ON_Xform&);
1295 
1296  bool WritePlaneEquation(const ON_PlaneEquation&);
1297 
1298  bool WritePlane(const ON_Plane&);
1299 
1300  bool WriteLine(const ON_Line&);
1301 
1302  bool WriteArc(const ON_Arc&);
1303 
1304  bool WriteCircle(const ON_Circle&);
1305 
1306  bool WriteInterval( const ON_Interval& );
1307 
1308  bool WriteUuid( const ON_UUID& );
1309 
1310  bool WriteDisplayMaterialRef( const ON_DisplayMaterialRef& );
1311 
1312  bool WriteLinetypeSegment( const ON_LinetypeSegment& );
1313 
1314  // All times are stored in universal coordinated time
1315  // ( a.k.a GMT, UCT ). Use ANSI C time() and gmtime() calls.
1316  bool WriteTime( const struct tm& );
1317 
1318  /*
1319  Parameters:
1320  sUTF8 - [in]
1321  A null terminated UTF-8 encoded unicode string.
1322  Remarks:
1323  To read a string written with WriteString(const char*),
1324  call ReadStringUTF8ElementCount(&string_utf8_element_count)
1325  to get the number of char elements written in the file,
1326  obtain a buffer with at least string_utf8_element_count
1327  char elements and then call
1328  ReadString(string_utf8_element_count,buffer) to read the
1329  char elements.
1330 
1331  If 0 == sUTF8 or 0 == SUTF8[0], a 4 byte int with
1332  value = 0 is written, otherwise a 4 byte int with
1333  value = strlen + 1 is written, followed by the string,
1334  followed by the null terminator.
1335  */
1336  bool WriteString(
1337  const char* sUTF8
1338  );
1339 
1340  /*
1341  Parameters:
1342  sUTF8 - [in]
1343  A null terminated UTF-8 encoded unicode string.
1344  Remarks:
1345  To read a string written with WriteString(const unsigned char*),
1346  call ReadStringUTF8ElementCount(&string_utf8_element_count) to
1347  get the number of unsigned char elements written in the file,
1348  obtain a buffer with at least string_utf8_element_count
1349  unsigned char elements and then call
1350  ReadString(string_utf8_element_count,buffer) to read the
1351  unsigned charelements.
1352 
1353  If 0 == sUTF8 or 0 == SUTF8[0], a 4 byte int with
1354  value = 0 is written, otherwise a 4 byte int with
1355  value = strlen + 1 is written, followed by the string,
1356  followed by the null terminator.
1357  */
1358  bool WriteString(
1359  const unsigned char* sUTF8
1360  );
1361 
1362  /*
1363  Parameters:
1364  sUTF16 - [in]
1365  A null terminated UTF-16 encoded unicode string.
1366  Remarks:
1367  To read a string written with WriteString(const unsigned short*),
1368  call ReadStringUTF16ElementCount(&string_utf16_element_count) to
1369  get the number of unsigned short elements written in the file,
1370  obtain a buffer with at least string_utf16_element_count
1371  unsigned short elements and then call
1372  ReadString(string_utf16_element_count,buffer) to read the
1373  unsigned short elements.
1374 
1375  If 0 == sUTF8 or 0 == SUTF8[0], a 4 byte int with
1376  value = 0 is written, otherwise a 4 byte int with
1377  value = strlen + 1 is written, followed by the string,
1378  followed by the null terminator.
1379  */
1380  bool WriteString(
1381  const unsigned short* sUTF16
1382  );
1383 
1384  bool WriteString( const ON_String& sUTF8 );
1385 
1386  bool WriteString( const ON_wString& s);
1387 
1388  bool WriteComponentIndex( const ON_COMPONENT_INDEX& );
1389 
1390  bool WriteArray( const ON_SimpleArray<bool>& );
1391  bool WriteArray( const ON_SimpleArray<char>& );
1392  bool WriteArray( const ON_SimpleArray<short>& );
1393  bool WriteArray( const ON_SimpleArray<int>& );
1394  bool WriteArray( const ON_SimpleArray<float>& );
1395  bool WriteArray( const ON_SimpleArray<double>& );
1396 
1397  bool WriteArray( const ON_SimpleArray<ON_Color>& );
1398 
1399  bool WriteArray( const ON_SimpleArray<ON_2dPoint>& );
1400  bool WriteArray( const ON_SimpleArray<ON_3dPoint>& );
1401  bool WriteArray( const ON_SimpleArray<ON_4dPoint>& );
1402  bool WriteArray( const ON_SimpleArray<ON_2dVector>& );
1403  bool WriteArray( const ON_SimpleArray<ON_3dVector>& );
1404 
1405  bool WriteArray( const ON_SimpleArray<ON_2fPoint>& );
1406  bool WriteArray( const ON_SimpleArray<ON_3fPoint>& );
1407  bool WriteArray( const ON_SimpleArray<ON_4fPoint>& );
1408  bool WriteArray( const ON_SimpleArray<ON_2fVector>& );
1409  bool WriteArray( const ON_SimpleArray<ON_3fVector>& );
1410  bool WriteArray( const ON_SimpleArray<ON_Xform>& );
1411  bool WriteArray( const ON_SimpleArray<ON_UUID>& );
1412  bool WriteArray( const ON_SimpleArray<ON_UuidIndex>& );
1413  bool WriteArray( const ON_SimpleArray<ON_SurfaceCurvature>& );
1414  bool WriteArray( const ON_ClassArray<ON_String>& );
1415  bool WriteArray( const ON_ClassArray<ON_wString>& );
1416  bool WriteArray( const ON_SimpleArray<ON_DisplayMaterialRef>& );
1417  bool WriteArray( const ON_SimpleArray<ON_LinetypeSegment>& );
1418  bool WriteArray( const ON_SimpleArray<ON_MappingChannel>& );
1419  bool WriteArray( const ON_ClassArray<ON_MaterialRef>& );
1420  bool WriteArray( const ON_ClassArray<ON_MappingRef>& );
1421  bool WriteArray( const ON_ClassArray<class ON_ObjRef>& );
1422  bool WriteArray( const ON_SimpleArray<class ON_ObjRef_IRefID>& );
1423  bool WriteArray( const ON_SimpleArray<class ON_ClippingPlaneInfo>& );
1424  bool WriteArray( int count, const class ON_Layer* );
1425  bool WriteArray( int count, const class ON_Layer*const* );
1426 
1427  /////////////////////////////////////////////////////
1428  //
1429  // Read/Write classes derived from ON_Object
1430  //
1431 
1432  /*
1433  Description:
1434  Reads and object from a 3dm archive;
1435  Parameters:
1436  ppObject - [out] object is allocated and a pointer to the
1437  allocated object is returned as *ppObject;
1438  Returns:
1439  0: failure - unable to read object because of file IO problems
1440  1: success
1441  3: unable to read object because it's UUID is not registered
1442  this could happen in cases where old code is attempting to read
1443  new objects.
1444  */
1445  int ReadObject(
1446  ON_Object** ppObject
1447  );
1448 
1449 
1450  /*
1451  Description:
1452  Reads and object from a 3dm archive.
1453  Parameters:
1454  object - [in] The value of object.ON_ClassId()->Uuid() must
1455  exactly match the class uuid in of the next
1456  object in the archive.
1457  Returns:
1458  0: failure - unable to read object because of file IO problems.
1459  1: success
1460  2: unable to read object because the class id in the archive
1461  did not match pObject->ClassId.
1462  */
1463  int ReadObject(
1464  ON_Object& object
1465  );
1466 
1467  bool WriteObject( const ON_Object* ); // writes object definition
1468  bool WriteObject( const ON_Object& ); // writes object definition
1469 
1470 
1471  ///////////////////////////////////////////////////////////////////
1472  ///////////////////////////////////////////////////////////////////
1473  //
1474  // 3DM Interface - ignore if not reading/writing a 3DM file
1475  // this is here so that the infrastructure
1476  // for writing 3dm archives is available for
1477  // any type of serialization device.
1478  //
1479  bool EnableSave3dmRenderMeshes( ON_BOOL32 = true ); // returns previous state
1480  bool Save3dmRenderMeshes() const;
1481 
1482  bool EnableSave3dmAnalysisMeshes( ON_BOOL32 = true ); // returns previous state
1483  bool Save3dmAnalysisMeshes() const;
1484 
1485  bool EnableSaveUserData( ON_BOOL32 = true ); // returns previous state
1486  bool SaveUserData() const;
1487 
1488  /*
1489  Returns:
1490  50 (The Rhino 5.0 opennurbs file version.)
1491  This is the value of version to pass to ON_BinaryArchive
1492  functions like Write3dmStartSection() when you want to use the
1493  the current opennurbs version number and you do not want to have
1494  to update your code when this version number changes.
1495  */
1496  static int CurrentArchiveVersion();
1497 
1498  ///////////////////////////////////////////////////////////////////
1499  // Step 1: REQUIRED - Write/Read Start Section
1500  //
1501 
1502  /*
1503  Parameters:
1504  version - [in]
1505  0, 2, 3, 4, 5 or 50 (5 is treated as 50)
1506 
1507  If version is 0, then the value of ON_BinaryArchive::CurrentArchiveVersion()
1508  is used.
1509 
1510  Use either 0 or the value of ON_BinaryArchive::CurrentArchiveVersion()
1511  for the version parameter when you want your code to write the most
1512  up to date file version.
1513 
1514  sStartSectionComment - [in]
1515  NULL or ASCII string with application name, et cetera.
1516  This information is primarily used when debugging files
1517  that contain problems. McNeel and Associates stores
1518  application name, application version, compile date,
1519  and the OS in use when file was written.
1520  */
1521  bool Write3dmStartSection(
1522  int version,
1523  const char* sStartSectionComment
1524  );
1525 
1526  /*
1527  Parameters:
1528  version - [out]
1529  .3dm file version (2, 3, 4, 5 or 50)
1530  sStartSectionComment - [out]
1531  string passed to Write3dmStartSection()
1532  */
1533  bool Read3dmStartSection(
1534  int* version,
1535  ON_String& sStartSectionComment
1536  );
1537 
1538  ///////////////////////////////////////////////////////////////////
1539  // Step 2: REQUIRED - Write/Read properties table
1540  //
1541  bool Write3dmProperties(
1542  const ON_3dmProperties&
1543  );
1544  bool Read3dmProperties(
1546  );
1547 
1548  ///////////////////////////////////////////////////////////////////
1549  // Step 3: REQUIRED - Write/Read settings table
1550  //
1551  bool Write3dmSettings(
1552  const ON_3dmSettings&
1553  );
1554  bool Read3dmSettings(
1556  );
1557 
1558  ///////////////////////////////////////////////////////////////////
1559  // Step 4: REQUIRED - Write/Read bitmap table (it can be empty)
1560  //
1561  bool BeginWrite3dmBitmapTable();
1562  bool Write3dmBitmap( const ON_Bitmap& );
1563  bool EndWrite3dmBitmapTable();
1564 
1565  bool BeginRead3dmBitmapTable();
1566  int Read3dmBitmap( // returns 0 at end of light table
1567  // 1 bitmap successfully read
1568  ON_Bitmap** // bitmap returned here
1569  );
1570  bool EndRead3dmBitmapTable();
1571 
1572  ///////////////////////////////////////////////////////////////////
1573  // Step 5: REQUIRED - Write/Read render material table (it can be empty)
1574  //
1575  bool BeginWrite3dmTextureMappingTable();
1576  bool Write3dmTextureMapping( const ON_TextureMapping& );
1577  bool EndWrite3dmTextureMappingTable();
1578 
1579  bool BeginRead3dmTextureMappingTable();
1580  int Read3dmTextureMapping( // returns 0 at end of table
1581  ON_TextureMapping** // layer returned here
1582  );
1583  bool EndRead3dmTextureMappingTable();
1584 
1585  ///////////////////////////////////////////////////////////////////
1586  // Step 6: REQUIRED - Write/Read render material table (it can be empty)
1587  //
1588  bool BeginWrite3dmMaterialTable();
1589  bool Write3dmMaterial( const ON_Material& );
1590  bool EndWrite3dmMaterialTable();
1591 
1592  bool BeginRead3dmMaterialTable();
1593  int Read3dmMaterial( // returns 0 at end of table
1594  ON_Material** // layer returned here
1595  );
1596  bool EndRead3dmMaterialTable();
1597 
1598  ///////////////////////////////////////////////////////////////////
1599  // Step 7: REQUIRED - Write/Read linetype table (it can be empty)
1600  //
1601  bool BeginWrite3dmLinetypeTable();
1602  bool Write3dmLinetype( const ON_Linetype&);
1603  bool EndWrite3dmLinetypeTable();
1604 
1605  bool BeginRead3dmLinetypeTable();
1606  int Read3dmLinetype(ON_Linetype**);
1607  bool EndRead3dmLinetypeTable();
1608 
1609  ///////////////////////////////////////////////////////////////////
1610  // Step 8: REQUIRED - Write/Read layer table (it can be empty)
1611  //
1612  bool BeginWrite3dmLayerTable();
1613  bool Write3dmLayer( const ON_Layer& );
1614  bool EndWrite3dmLayerTable();
1615 
1616  bool BeginRead3dmLayerTable();
1617  int Read3dmLayer( // returns 0 at end of table
1618  ON_Layer** // layer returned here
1619  );
1620  bool EndRead3dmLayerTable();
1621 
1622  ///////////////////////////////////////////////////////////////////
1623  // Step 9: REQUIRED - Write/Read group table (it can be empty)
1624  //
1625  bool BeginWrite3dmGroupTable();
1626  bool Write3dmGroup( const ON_Group& );
1627  bool EndWrite3dmGroupTable();
1628 
1629  bool BeginRead3dmGroupTable();
1630 
1631  // Description:
1632  // Reads groups from group table. If the group definition is
1633  // read, a group is created by calling new ON_Group(),
1634  // initialized with values stored in the archive, and
1635  // returned.
1636  //
1637  // Parameters:
1638  // ppGroup - If the group definition is
1639  // read, a group is created by calling new ON_Group(),
1640  // initialized with values stored in the archive, and
1641  // a pointer to the new group is returned in *ppGroup.
1642  //
1643  // Returns:
1644  //
1645  // @untitled table
1646  // 0 at the end of the group table
1647  // 1 group definition was successfully read
1648  // -1 archive is corrupt at this point
1649  //
1650  // Example:
1651  // Calls to Read3dmGroup need to be bracketed by calls
1652  // to BeginRead3dmGroupTable() / EndRead3dmGroupTable().
1653  //
1654  // archive.BeginRead3dmGroupTable();
1655  // ON_Group* pGroup;
1656  // int rc = 1;
1657  // while(rc==1)
1658  // { //
1659  // pGroup = 0;
1660  // archive.Read3dmGroup(&pGroup);
1661  // if ( pGroup )
1662  // do something with pGroup
1663  // } //
1664  // archive.EndRead3dmGroupTable();
1665  //
1666  int Read3dmGroup(
1667  ON_Group** // ppGroup
1668  );
1669 
1670  bool EndRead3dmGroupTable();
1671 
1672 
1673  ///////////////////////////////////////////////////////////////////
1674  // Step 10: REQUIRED - Write/Read font table (it can be empty)
1675  //
1676  bool BeginWrite3dmFontTable();
1677  bool Write3dmFont( const ON_Font& );
1678  bool EndWrite3dmFontTable();
1679 
1680  bool BeginRead3dmFontTable();
1681 
1682  // Description:
1683  // Reads fonts from font table. If the font definition is
1684  // read, a font is created by calling new ON_Font(),
1685  // initialized with values stored in the archive, and
1686  // returned.
1687  //
1688  // Parameters:
1689  // ppFont - If the font definition is
1690  // read, a font is created by calling new ON_Font(),
1691  // initialized with values stored in the archive, and
1692  // a pointer to the new font is returned in *ppFont.
1693  //
1694  // Returns:
1695  //
1696  // @untitled table
1697  // 0 at the end of the font table
1698  // 1 font definition was successfully read
1699  // -1 archive is corrupt at this point
1700  //
1701  // Example:
1702  // Calls to Read3dmFont need to be bracketed by calls
1703  // to BeginRead3dmFontTable() / EndRead3dmFontTable().
1704  //
1705  // archive.BeginRead3dmFontTable();
1706  // int rc = 1;
1707  // ON_Font* pFont;
1708  // while(rc==1)
1709  // { //
1710  // pFont = 0;
1711  // archive.Read3dmFont(&pFont);
1712  // if ( pFont )
1713  // do something with pFont
1714  // } //
1715  // archive.EndRead3dmFontTable();
1716  //
1717  int Read3dmFont(
1718  ON_Font** // ppFont
1719  );
1720 
1721  bool EndRead3dmFontTable();
1722 
1723 
1724  ///////////////////////////////////////////////////////////////////
1725  // Step 11: REQUIRED - Write/Read dimstyle table (it can be empty)
1726  //
1727  bool BeginWrite3dmDimStyleTable();
1728  bool Write3dmDimStyle( const ON_DimStyle& );
1729  bool EndWrite3dmDimStyleTable();
1730 
1731  bool BeginRead3dmDimStyleTable();
1732 
1733  // Description:
1734  // Reads annotation dimension styles from dimension style table.
1735  // If the dimension style definition is read,
1736  // a dimension style is created by calling new ON_DimStyle(),
1737  // initialized with values stored in the archive, and
1738  // returned.
1739  //
1740  // Parameters:
1741  // ppDimStyle - If the dimstyle definition is
1742  // read, a dimstyle is created by calling new ON_DimStyle(),
1743  // initialized with values stored in the archive, and
1744  // a pointer to the new dimstyle is returned in *ppDimStyle.
1745  //
1746  // Returns:
1747  //
1748  // @untitled table
1749  // 0 at the end of the dimension style table
1750  // 1 dimension style definition was successfully read
1751  // -1 archive is corrupt at this point
1752  //
1753  // Example:
1754  // Calls to Read3dmDimStyle need to be bracketed by calls
1755  // to BeginRead3dmDimStyleTable() / EndRead3dmDimStyleTable().
1756  //
1757  // archive.BeginRead3dmDimStyleTable();
1758  // int rc = 1;
1759  // ON_DimStyle* pDimStyle;
1760  // while(rc==1)
1761  // { //
1762  // pDimStyle = 0;
1763  // archive.Read3dmDimStyle(&pDimStyle);
1764  // if ( pDimStyle )
1765  // do something with pDimStyle
1766  // } //
1767  // archive.EndRead3dmDimStyleTable();
1768  //
1769  int Read3dmDimStyle(
1770  ON_DimStyle** // ppDimStyle
1771  );
1772 
1773  bool EndRead3dmDimStyleTable();
1774 
1775 
1776  ///////////////////////////////////////////////////////////////////
1777  // Step 12: REQUIRED - Write/Read render light table (it can be empty)
1778  //
1779  bool BeginWrite3dmLightTable();
1780  bool Write3dmLight( const ON_Light&,
1781  const ON_3dmObjectAttributes* // optional
1782  );
1783  bool EndWrite3dmLightTable();
1784 
1785  bool BeginRead3dmLightTable();
1786  int Read3dmLight( // returns 0 at end of light table
1787  // 1 light successfully read
1788  // -1 if file is corrupt
1789  ON_Light**, // light returned here
1790  ON_3dmObjectAttributes* // optional - if NOT NULL, object attributes are
1791  // returned here
1792  );
1793  bool EndRead3dmLightTable();
1794 
1795 
1796  ///////////////////////////////////////////////////////////////////
1797  // Step 13: REQUIRED - Write/Read hatch pattern table (it can be empty)
1798  //
1799  bool BeginWrite3dmHatchPatternTable();
1800  bool Write3dmHatchPattern( const ON_HatchPattern&);
1801  bool EndWrite3dmHatchPatternTable();
1802 
1803  bool BeginRead3dmHatchPatternTable();
1804  int Read3dmHatchPattern(ON_HatchPattern**);
1805  bool EndRead3dmHatchPatternTable();
1806 
1807  ///////////////////////////////////////////////////////////////////
1808  // Step 14: REQUIRED - Write/Read instance definition table (it can be empty)
1809  //
1810  bool BeginWrite3dmInstanceDefinitionTable();
1811  bool Write3dmInstanceDefinition( const ON_InstanceDefinition& );
1812  bool EndWrite3dmInstanceDefinitionTable();
1813 
1814  bool BeginRead3dmInstanceDefinitionTable();
1815 
1816  /*
1817  Description:
1818  Reads instance definitions from instance defintion table.
1819 
1820  Parameters:
1821  ppInstanceDefinition - If an instance defintion is
1822  read, an instance defintion is created by calling new
1823  ON_InstanceDefinition(), initialized with values stored
1824  in the archive, and a pointer to the new instance defintion
1825  is returned in *ppInstanceDefinition.
1826 
1827  Returns:
1828 
1829  @untitled table
1830  0 at the end of the instance defintion table
1831  1 instance defintion was successfully read
1832  -1 archive is corrupt at this point
1833 
1834  Example:
1835  Calls to Read3dmInstanceDefinition need to be bracketed by calls
1836  to BeginRead3dmInstanceDefinitionTable() / EndRead3dmInstanceDefinitionTable().
1837 
1838  archive.BeginRead3dmInstanceDefinitionTable();
1839  int rc = 1;
1840  ON_InstanceDefinition* pInstanceDefinition;
1841  while(rc==1)
1842  {
1843  pInstanceDefinition = 0;
1844  archive.Read3dmInstanceDefinition(&pInstanceDefinition);
1845  if ( pInstanceDefinition )
1846  do something with pInstanceDefinition
1847  }
1848  archive.EndRead3dmInstanceDefinitionTable();
1849  */
1850  int Read3dmInstanceDefinition(
1851  ON_InstanceDefinition** // ppInstanceDefinition
1852  );
1853 
1854  bool EndRead3dmInstanceDefinitionTable();
1855 
1856  ///////////////////////////////////////////////////////////////////
1857  // Step 15: REQUIRED - Write/Read geometry and annotation table (it can be empty)
1858  //
1859  bool BeginWrite3dmObjectTable();
1860  bool Write3dmObject(
1861  const ON_Object&,
1862  const ON_3dmObjectAttributes* // optional
1863  );
1864  bool EndWrite3dmObjectTable();
1865 
1866  bool BeginRead3dmObjectTable();
1867  int Read3dmObject( // returns 0 at end of object table
1868  // 1 if object is read
1869  // 2 if object is skipped because it does not match filter
1870  // -1 if file is corrupt
1871  ON_Object**, // object returned here (NULL if skipped)
1872  ON_3dmObjectAttributes*, // optional - if NOT NULL, object attributes are
1873  // returned here
1874  unsigned int = 0 // optional filter made by setting ON::object_type bits
1875  ); // returns NULL at end of object table
1876  bool EndRead3dmObjectTable();
1877 
1878  ///////////////////////////////////////////////////////////////////
1879  // Step 16: REQUIRED - Write/Read history record table (it can be empty)
1880  //
1881  bool BeginWrite3dmHistoryRecordTable();
1882  bool Write3dmHistoryRecord(
1883  const class ON_HistoryRecord&
1884  );
1885  bool EndWrite3dmHistoryRecordTable();
1886 
1887  bool BeginRead3dmHistoryRecordTable();
1888 
1889  /*
1890  Returns:
1891  0 at end of object table
1892  1 if object is read
1893  -1 if file is corrupt
1894  */
1895  int Read3dmHistoryRecord(
1896  class ON_HistoryRecord*&
1897  );
1898  bool EndRead3dmHistoryRecordTable();
1899 
1900  ///////////////////////////////////////////////////////////////////
1901  // Step 17: OPTIONAL - Write/Read 0 or more user tables
1902  //
1903 
1904  /*
1905  Description:
1906  Write the user table header information that must precede
1907  the user table information written by a plug-in.
1908  Parameters:
1909  plugin_id - [in]
1910  bSavingGoo - [in]
1911  Set to false if a plug-in will be used to write
1912  the user table. Set to true if a user table written by
1913  a missing plug-in is being resaved. In this case,
1914  goo_3dm_version and goo_opennurbs_version must also be
1915  set. In practice, you should use Write3dmAnonymousUserTableRecord()
1916  to handle writing "goo" and use this function only when
1917  the plug-in in present.
1918  goo_3dm_version - [in]
1919  If bSavingGoo is false, this parameter must be zero and
1920  ON_BinaryArchive::Archive3dmVersion() will be used.
1921  If bSavingGoo is true, this parameter must be the version of
1922  the 3dm archive (1,2,3,4,5,50,...) the plug-in code used to
1923  write the user table.
1924  goo_opennurbs_version - [in]
1925  If bSavingGoo is false, this parameter must be zero and
1926  ON_BinaryArchive::ArchiveOpenNURBSVersion() will be used.
1927  If bSavingGoo is true, this parameter must be the version
1928  of the opennurbs (YYYYMMDDN) the plug-in code used to
1929  write the user table.
1930  Returns:
1931  True if the the user information can be written.
1932  False if user informtion should not be written.
1933  */
1934  bool BeginWrite3dmUserTable(
1935  const ON_UUID& plugin_id,
1936  bool bSavingGoo,
1937  int goo_3dm_version,
1938  int goo_opennurbs_version
1939  );
1940 
1941  bool EndWrite3dmUserTable();
1942 
1943  /*
1944  Description:
1945  If Read3dmAnaonymousUserTable() was used to read ON_3dmGoo because a
1946  plug-in was not present, then use Write3dmAnonymousUserTableRecord()
1947  to put than information back into the archive.
1948  Write3dmAnonymousUserTableRecord() writes the entire record.
1949  Do NOT call BeginWrite3dmUserTable() / EndWrite3dmUserTable() when
1950  using Write3dmAnonymousUserTableRecord().
1951  Parameters:
1952  plugin_id - [in]
1953  goo_version - [in]
1954  The version of the archive (1,2,3,4,5,50,...) that was used when
1955  the plug-in wrote the user table.
1956  goo_opennurbs_version - [in]
1957  The version of opennurbs ( YYYMMDDN ) that was used when the
1958  plug-in wrote the user table.
1959  goo - [in]
1960  Returns:
1961  True if the goo was written or skipped because it could not be robustly
1962  saved. False if a catastrophic IO error occured.
1963  */
1964  bool Write3dmAnonymousUserTableRecord(
1965  const ON_UUID& plugin_id,
1966  int goo_3dm_version,
1967  int goo_opennurbs_version,
1968  const ON_3dmGoo& goo
1969  );
1970 
1971  // OBSOLETE - use BeginWrite3dmUserTable(plugin_id, bSavingGoo, 3dm_version, opennurbs_version )
1972  ON_DEPRECATED bool BeginWrite3dmUserTable( const ON_UUID& );
1973 
1974  // OBSOLETE - use Write3dmAnonymousUserTableRecord(plugin_id, ..., goo)
1975  ON_DEPRECATED bool Write3dmAnonymousUserTable( const ON_3dmGoo& );
1976 
1977  /*
1978  Parameters:
1979  plugin_id - [out]
1980  id of plug-in that wrote the user table
1981  bLastSavedAsGoo - [out]
1982  True if this table was saved into this archive as goo because
1983  the plug-in was not present at the time of the save.
1984  archive_3dm_version - [out]
1985  Version of the archive the plug-in wrote to. When bLastSavedAsGoo
1986  is true, this number can be different from Archive3dmVersion().
1987  archive_opennurbs_version - [out]
1988  Version of opennurbs the plug-in used to write the archive.
1989  When bLastSavedAsGoo is true, this number can be different
1990  from ArchiveOpenNURBSVersion().
1991  Returns:
1992  False when there are no more user tables or an IO error occurs.
1993  */
1994  bool BeginRead3dmUserTable(
1995  ON_UUID& plugin_id,
1996  bool* bLastSavedAsGoo,
1997  int* archive_3dm_version,
1998  int* archive_opennurbs_version
1999  );
2000 
2001  /*
2002  Description:
2003  If the plug-in that wrote the user table is not present and you need
2004  to read and resave the user table, then use Read3dmAnonymousUserTable()
2005  to load the information into "goo".
2006  If you do not need to resave the information, then simply call EndRead3dmUserTable()
2007  to skip over this table.
2008  */
2009  bool Read3dmAnonymousUserTable(
2010  int archive_3dm_version,
2011  int archive_opennurbs_version,
2012  ON_3dmGoo& goo
2013  );
2014 
2015  bool EndRead3dmUserTable();
2016 
2017  // OBSOLETE - use BeginRead3dmUserTable( plugin_id, bLastSavedAsGoo, archive_3dm_version, ... )
2018  ON_DEPRECATED bool BeginRead3dmUserTable(
2019  ON_UUID&
2020  );
2021 
2022  // OBSOLETE - use Read3dmAnonymousUserTable( archive_3dm_version, archive_opennurbs_version, goo )
2023  ON_DEPRECATED bool Read3dmAnonymousUserTable( ON_3dmGoo& );
2024 
2025 
2026 
2027 
2028  ///////////////////////////////////////////////////////////////////
2029  // Step 18: REQUIRED when writing / OPTIONAL when reading
2030  // Write end of file marker. This information is primarily
2031  // used when debugging files to make sure the end of the file
2032  // hasn't been cut off.
2033  //
2034 
2035  // Description:
2036  // Writes a TCODE_ENDOFFILE chunk that contains the number
2037  // of bytes in the archive.
2038  //
2039  // Returns:
2040  // true if successful, false if unable to write to archive.
2041  bool Write3dmEndMark();
2042 
2043  // Description:
2044  // Checks for a TCODE_ENDOFFILE chunk at the current position.
2045  // If it finds one, it reads it and returns the number
2046  // of bytes in the archive. Comparing this number with
2047  // the current file position can help detect files that
2048  // have been damaged by loosing sections.
2049  //
2050  // Parameters:
2051  // sizeof_archive - [out] number of bytes written to archive
2052  //
2053  // Returns:
2054  // true if successful, false if unable to find or read
2055  // a TCODE_ENDOFFILE chunk.
2056  bool Read3dmEndMark(
2057  size_t* // sizeof_archive
2058  );
2059 
2060  ///////////////////////////////////////////////////////////////////
2061  ///////////////////////////////////////////////////////////////////
2062  // Low level tools to Write/Read chunks. See opennurbs_3dm.h for details
2063  // about the structure of chunks. Every chunk must begin with a
2064  // call to BeginWrite/ReadChunk().
2065  // If BeginWriteChunk()/BeginReadChunk() returns true, then
2066  // you must call EndWrite/ReadChunk() or cease using the archive.
2067 
2068  // Description:
2069  // Writes a chunk header containing 4 byte typecode and value.
2070  //
2071  // Parameters:
2072  // typecode - [in] a TCODE_* number from opennurbs_3dm.h
2073  // value - [in] if (typecode&TCODE_SHORT) is nonzero, then
2074  // this is the value to be saved. Othewise, pass
2075  // a zero and the EndWrite3dmChunk() call will
2076  // store the length of the chunk.
2077  //
2078  // Returns:
2079  // true if write was successful.
2080  bool BeginWrite3dmChunk(
2081  unsigned int, // typecode
2082  int // value
2083  );
2084 
2085  bool BeginWrite3dmBigChunk(
2086  ON__UINT32 typecode,
2087  ON__INT64 value
2088  );
2089 
2090  /*
2091  Description:
2092  Begins writing a chunk.
2093  Parameters:
2094  tcode - [in] chunk's typecode from opennurbs_3dm.h. This cannot be a short tcode.
2095  major_version - [in] ( >= 1)
2096  minor_version - [in] ( >= 0 )
2097  Returns:
2098  True if input was valid and chunk was started. In this case
2099  You must call EndWrite3dmChunk(), even if something goes wrong
2100  while you attempt to write the contents of the chunk.
2101  False if input was not valid or the write failed.
2102  */
2103  bool BeginWrite3dmChunk(
2104  unsigned int tcode,
2105  int major_version,
2106  int minor_version
2107  );
2108 
2109 
2110  // updates length in chunk header
2111  bool EndWrite3dmChunk();
2112 
2113  bool Write3dmGoo( const ON_3dmGoo& ); // call to write "goo"
2114 
2115  // OBSOLETE - Use BeginRead3dmBigChunk()
2116  ON_DEPRECATED bool BeginRead3dmChunk(
2117  unsigned int*, // typecode from opennurbs_3dm.h
2118  int* // value
2119  );
2120 
2121  // When the end of the 3dm file is reached, BeginReadChunk() will
2122  // return true with a typecode of TCODE_ENDOFFILE.
2123  bool BeginRead3dmBigChunk(
2124  unsigned int*, // typecode from opennurbs_3dm.h
2125  ON__INT64* // value
2126  );
2127  /*
2128  Description:
2129  Begins reading a chunk that must be in the archive at this location.
2130  Parameters:
2131  expected_tcode - [in] chunk's typecode from opennurbs_3dm.h
2132  major_version - [out]
2133  minor_version - [out]
2134  Returns:
2135  True if beginning of the chunk was read. In this case
2136  You must call EndRead3dmChunk(), even if something goes wrong
2137  while you attempt to read the interior of the chunk.
2138  False if the chunk did not exist at the current location in the file.
2139  */
2140  bool BeginRead3dmChunk(
2141  unsigned int expected_tcode,
2142  int* major_version,
2143  int* minor_version
2144  );
2145 
2146  /*
2147  Description:
2148  Calling this will skip rest of stuff in chunk if it was only partially read.
2149  Parameters:
2150  bSupressPartiallyReadChunkWarning - [in]
2151  Generally, a call to ON_WARNING is made when a chunk is partially
2152  read. If bSupressPartiallyReadChunkWarning is true, then
2153  no warning is issued for partially read chunks.
2154  */
2155  bool EndRead3dmChunk();
2156  bool EndRead3dmChunk(bool bSupressPartiallyReadChunkWarning);
2157 
2158 
2159  ///////////////////////////////////////////////////////////////////
2160  //
2161  // Tools for dictionary IO (used in .NET)
2162  //
2163 
2164  /*
2165  Description:
2166  Begins writing a dictionary.
2167  Parameters:
2168  dictionary_id - [in]
2169  version - [in]
2170  It is suggested that you use YYYYMMDD as the version number.
2171  dictionary_name - [in]
2172  You may pass NULL.
2173  Remarks:
2174  Begins a new chunk with tcode TCODE_DICTIONARY and then writes
2175  a TCODE_DICTIONARY_ID chunk containing the id, version and name.
2176  After calling this function, you may either write entries by
2177  calling
2178  BeginWriteDictionaryEntry();
2179  write entry definition...
2180  EndWriteDictionaryEntry();
2181  or you may finish writing the dictionay by calling
2182  EndWriteDictionary();
2183  */
2184  bool BeginWriteDictionary(
2185  ON_UUID dictionary_id,
2186  unsigned int version,
2187  const wchar_t* dictionary_name
2188  );
2189  /*
2190  Description:
2191  Begins writing a dictionary entry.
2192  Parameters:
2193  de_type - [in]
2194  entry_name - [in]
2195  Returns:
2196  true
2197  Entry header was written and you must call EndWriteDictionary()
2198  after writing the entry data.
2199  false
2200  Failed to write entry header. Do not call EndWriteDictionary().
2201  Remarks:
2202  Begins a new chunk with tcode TCODE_DICTIONARY_ENTRY,
2203  then writes the int, and then writes the string.
2204  */
2205  bool EndWriteDictionary();
2206 
2207  /*
2208  Description:
2209  Begins writing a dictionary entry.
2210  Parameters:
2211  de_type - [in]
2212  entry_name - [in]
2213  Returns:
2214  true
2215  Entry header was written and you must call EndWriteDictionary()
2216  after writing the entry data.
2217  false
2218  Failed to write entry header. Do not call EndWriteDictionary().
2219  Remarks:
2220  Begins a new chunk with tcode TCODE_DICTIONARY_ENTRY,
2221  then writes the int, and then writes the string.
2222  */
2223  bool BeginWriteDictionaryEntry(
2224  int de_type,
2225  const wchar_t* entry_name
2226  );
2227  bool EndWriteDictionaryEntry();
2228 
2229  bool BeginReadDictionary(
2230  ON_UUID* dictionary_id,
2231  unsigned int* version,
2232  ON_wString& dictionary_name
2233  );
2234  bool EndReadDictionary();
2235 
2236  /*
2237  Description:
2238  Begin reading a dictionary entry.
2239  Parameters:
2240  de_type - [out]
2241  entry_name - [out]
2242  Returns:
2243  0: serious IO error
2244  1: success
2245  read information and then call EndReadDictionaryEntry()
2246  2: at end of dictionary
2247  */
2248  int BeginReadDictionaryEntry(
2249  int* de_type,
2250  ON_wString& entry_name
2251  );
2252  bool EndReadDictionaryEntry();
2253 
2254  bool Read3dmGoo( ON_3dmGoo& ); // Call to read "goo"
2255 
2256  // OBSOLETE - Use PeekAt3dmBigChunkType()
2257  ON_DEPRECATED bool PeekAt3dmChunkType( // does not change file position
2258  unsigned int*, // typecode from opennurbs_3dm.h
2259  int* // value
2260  );
2261 
2262  bool PeekAt3dmBigChunkType( // does not change file position
2263  ON__UINT32* typecode,
2264  ON__INT64* big_value
2265  );
2266 
2267  bool Seek3dmChunkFromStart(
2268  // beginning at the start of the active chunk, search portion of
2269  // archive included in active chunk for the start of a subchunk
2270  // with the specified type.
2271  // if true is returned, then the position is set so the next call to
2272  // BeginRead3dmChunk() will read a chunk with the specified typecode
2273  unsigned int // typecode from opennurbs_3dm.h
2274  );
2275  bool Seek3dmChunkFromCurrentPosition(
2276  // beginning at the current position, search portion of archive
2277  // included in active chunk for the start of a subchunk with the
2278  // specified type.
2279  // if true is returned, then the position is set so the next call to
2280  // BeginRead3dmChunk() will read a chunk with the specified typecode
2281  unsigned int // typecode from opennurbs_3dm.h
2282  );
2283 
2284  // A chunk version is a single byte that encodes a major.minor
2285  // version number. Useful when creating I/O code for 3dm chunks
2286  // that may change in the future. Increment the minor version
2287  // number if new information is added to the end of the chunk.
2288  // Increment the major version if the format of the chunk changes
2289  // in some other way.
2290  bool Write3dmChunkVersion(
2291  int, // major // 0 to 15
2292  int // minor // 0 to 16
2293  );
2294  bool Read3dmChunkVersion(
2295  int*, // major // 0 to 15
2296  int* // minor // 0 to 16
2297  );
2298 
2299  /*
2300  Description:
2301  Low level tool to writes user data attached to the
2302  object. This function should never be called
2303  directly.
2304  Parameters:
2305  object - [in]
2306  Returns:
2307  True if successful.
2308  */
2309  bool WriteObjectUserData( const ON_Object& object );
2310 
2311  /*
2312  Description:
2313  Low level tool to read user data and attach it to
2314  the object. This function should never be called
2315  directly.
2316  Parameters:
2317  object - [in/out]
2318  Returns:
2319  True if successful.
2320  */
2321  bool ReadObjectUserData( ON_Object& object );
2322 
2323  /*
2324  Description:
2325  If a 3dm archive is being read or written, then this is the
2326  version of the 3dm archive format (1, 2, 3, 4 or 5).
2327  Returns:
2328  @untitle table
2329  0 a 3dm archive is not being read/written
2330  1 a version 1 3dm archive is being read/written
2331  2 a version 2 3dm archive is being read/written
2332  3 a version 3 3dm archive is being read/written
2333  4 a version 4 3dm archive is being read/written
2334  5 an old version 5 3dm archive is being read
2335  50 a version 5 3dm archive is being read/written
2336  See Also:
2337  ON_BinaryArchive::ArchiveOpenNURBSVersion
2338  */
2339  int Archive3dmVersion() const;
2340 
2341  /*
2342  Description:
2343  If a 3dm archive is being read, then this is the version
2344  of openNURBS that was used to write the archive. This value
2345  is only available after ON_BinaryArchive::Read3dmProperties
2346  is called.
2347  See Also:
2348  ON_BinaryArchive::Archive3dmVersion
2349  ON_BinaryArchive::Read3dmProperties
2350  Returns:
2351  Version of openNURBS used to write the archive. The openNURBS
2352  version is the value returned by ON::Version.
2353  See Also:
2354  ON::Version
2355  ON_BinaryArchive::Read3dmProperties
2356  ON_BinaryArchive::Archive3dmVersion
2357  Remarks:
2358  This value is rarely needed. You probably want to
2359  use ON_BinaryArchive::Archive3dmVersion.
2360  */
2361  int ArchiveOpenNURBSVersion() const;
2362 
2363  /*
2364  Description:
2365  When a 3dm archive is saved from an MFC application that
2366  supports Windows linking/embedding, the first 5kb to 1mb
2367  of the file contains information that is put there by MFC.
2368  ArchiveStartOffset() returns the offset into the file where
2369  the 3dm archive actually begins. The call to
2370  ON_BinaryArchive::Read3dmStartSection() calculates this
2371  offset and stores the value in m_3dm_start_section_offset.
2372  Returns:
2373  Offset into the binary "file" where the actual 3dm archive
2374  begins.
2375  Remarks:
2376  Generally, this value can be ignored. This function is
2377  a diagnostice tool that is used to analyzed damaged files.
2378  */
2379  size_t ArchiveStartOffset() const;
2380 
2382  {
2383  no_active_table = 0,
2399  user_table
2400  };
2401 
2402  /*
2403  Description:
2404  Expert user function for reading damaged files.
2405  Parameters:
2406  chunk - [out] current chunk.
2407  Returns:
2408  Level of the chunk or 0 if there is no current
2409  chunk.
2410  */
2411  int GetCurrentChunk(ON_3DM_CHUNK& chunk) const;
2412  int GetCurrentChunk(ON_3DM_BIG_CHUNK& big_chunk) const;
2413 
2414  /*
2415  Description:
2416  Expert user function for reading damaged files. The search starts
2417  at the beginning of the file.
2418  Parameters:
2419  tcode_table - [in] typecode of the table
2420  tcode_record - [in] typecode of the record
2421  class_uuid - [in] id of the opennurbs class in the record
2422  min_length_data - [in] minimum size of the opennurbs class data
2423  Returns:
2424  True if the table start is found. In this case the current
2425  position of the archive is at the start of the table and
2426  the standared BeginRead3dm...Table() function can be used.
2427  False if the table start is not found.
2428  */
2429  bool FindTableInDamagedArchive(
2430  unsigned int tcode_table,
2431  unsigned int tcode_record,
2432  ON_UUID class_uuid,
2433  int min_length_data
2434  );
2435 
2436  /*
2437  Description:
2438  Expert user function for studying contents of a file.
2439  The primary use is as an aid to help dig through files
2440  that have been damaged (bad disks, transmission errors, etc.)
2441  If an error is found, a line that begins with the word
2442  "ERROR" is printed.
2443  Parameters:
2444  text_log - [in] place to print informtion
2445  recursion_depth - [in] simply a counter
2446  to aid in debugging.
2447  Returns:
2448  0 if something went wrong, otherwise the typecode
2449  of the chunk that was just studied.
2450  */
2451  unsigned int
2452  Dump3dmChunk(
2453  ON_TextLog& text_log,
2454  int recursion_depth = 0
2455  );
2456 
2457 protected:
2458 
2459  /*
2460  Description:
2461  Works like the C runtrim fread().
2462  Returns:
2463  actual number of bytes read (like fread())
2464  */
2465  virtual
2466  size_t Read( size_t, void* ) = 0;
2467 
2468  /*
2469  Description:
2470  Works like the C runtrim fwrite().
2471  Returns:
2472  actual number of bytes written (like fwrite())
2473  */
2474  virtual
2475  size_t Write( size_t, const void* ) = 0;
2476 
2477  /*
2478  Description:
2479  Force Write() to flush any buffered data to physical archive.
2480  Returns:
2481  True if successful or if there is nothing to flush. False if
2482  information could not be flushed.
2483  */
2484  virtual
2485  bool Flush() = 0;
2486 
2487  /*
2488  Description:
2489  When ON_BinaryArchive::ReadObject() encounters userdata and
2490  the user data class id is not present, LoadUserDataApplication
2491  is called to load the application that created user data.
2492  Returns:
2493  0 - could not load the application
2494  1 - successfully loaded the application
2495  2 - the application was already loaded
2496  */
2497  virtual
2498  int LoadUserDataApplication(
2499  ON_UUID application_id
2500  );
2501 
2502  bool SetArchive3dmVersion(int);
2503 
2504 private:
2505  // 16 bit integer IO
2506  bool WriteInt8( size_t, const ON__INT8* );
2507  bool ReadInt8( size_t, ON__INT8* );
2508 
2509  // 16 bit integer IO
2510  bool WriteInt16( size_t, const ON__INT16* );
2511  bool ReadInt16( size_t, ON__INT16* );
2512 
2513  // 32 bit integer IO
2514  bool WriteInt32( size_t, const ON__INT32* );
2515  bool ReadInt32( size_t, ON__INT32* );
2516 
2517  // 64 bit integer IO
2518  bool WriteInt64( size_t, const ON__INT64* );
2519  bool ReadInt64( size_t, ON__INT64* );
2520 
2521  bool BeginWrite3dmTable(
2522  unsigned int // tcode
2523  );
2524  bool EndWrite3dmTable(
2525  unsigned int // tcode
2526  );
2527  bool BeginRead3dmTable(
2528  unsigned int // tcode
2529  );
2530  bool EndRead3dmTable(
2531  unsigned int // tcode
2532  );
2533 
2534  bool Read3dmV1Layer( ON_Layer*& );
2535  int Read3dmV1Light( // returns 0 at end of light table
2536  // 1 light successfully read
2537  // -1 if file is corrupt
2538  ON_Light**, // light returned here
2539  ON_3dmObjectAttributes* // optional - if NOT NULL, object attributes are
2540  // returned here
2541  );
2542  int Read3dmV1Material( ON_Material** );
2543  int Read3dmV1Object( // returns 0 at end of object table
2544  // 1 if object is read
2545  // 2 if object is skipped because it does not match filter
2546  // -1 if file is corrupt
2547  ON_Object**, // object returned here (NULL if skipped)
2548  ON_3dmObjectAttributes*, // optional - if NOT NULL, object attributes are
2549  // returned here
2550  unsigned int = 0 // optional filter made by setting ON::object_type bits
2551  ); // returns NULL at end of object table
2552 
2553  bool Read3dmV1AttributesOrMaterial(
2554  ON_3dmObjectAttributes*, // attributes,
2555  ON_Material*, // material,
2556  ON_BOOL32&, // bHaveMat
2557  unsigned int, // end_mark_tcode
2558  class ON__3dmV1_XDATA* = 0 // v1 "xdata"
2559  );
2560  bool Read3dmV1String( ON_String& );
2561  int Read3dmV1LayerIndex( const char* ) const;
2562 
2563 public:
2564  // helpers for reading V1 objects
2565  bool ReadV1_TCODE_RH_POINT(ON_Object**,ON_3dmObjectAttributes*);
2566  bool ReadV1_TCODE_MESH_OBJECT(ON_Object**,ON_3dmObjectAttributes*);
2567  bool ReadV1_TCODE_LEGACY_CRV(ON_Object**,ON_3dmObjectAttributes*);
2568  bool ReadV1_TCODE_LEGACY_FAC(ON_Object**,ON_3dmObjectAttributes*);
2569  bool ReadV1_TCODE_LEGACY_SHL(ON_Object**,ON_3dmObjectAttributes*);
2570  bool ReadV1_TCODE_RHINOIO_OBJECT_NURBS_CURVE(ON_Object**,ON_3dmObjectAttributes*);
2571  bool ReadV1_TCODE_RHINOIO_OBJECT_NURBS_SURFACE(ON_Object**,ON_3dmObjectAttributes*);
2572  bool ReadV1_TCODE_RHINOIO_OBJECT_BREP(ON_Object**,ON_3dmObjectAttributes*);
2573  bool ReadV1_TCODE_ANNOTATION(unsigned int,ON_Object**,ON_3dmObjectAttributes*);
2574 
2575 private:
2576  ON::archive_mode Mode() const; // current read/write mode
2577  void UpdateCRC( size_t, const void* );
2578  int ReadObjectHelper(ON_Object**);
2579 
2580  int m_3dm_version;
2581  int m_3dm_v1_layer_index;
2582  int m_3dm_v1_material_index;
2583 
2584  // The bits in m_error_message_mask are used to mask errors
2585  // when we know we are doing something that may generate an
2586  // error.
2587  //
2588  // bit 0x00000001
2589  // V1 files do not have a table structure and are read using
2590  // multiple passes and there are valid situations where a
2591  // 4 byte read is attempted at the end of a file.
2592  //
2593  // bit 0x00000002
2594  // Some v1 files do not have an end mark. When reading
2595  // these v1 files bit 0x02 is set.
2596  //
2597  // bit 0x00000004
2598  // Requested read may go beyond end of file.
2599  // One situation where this happens is when a table is not at the
2600  // expected location in a file,
2601 
2602  unsigned int m_error_message_mask;
2603 protected:
2604  unsigned int ErrorMessageMask() const;
2605  /*
2606  Paramters:
2607  sizeof_request - [in]
2608  value of count parameter passed to virtual Read() function.
2609  sizeof_read - [in]
2610  number of bytes actually read by the virtual Read() function.
2611  Returns:
2612  True if a call to Read() is permitted to ask for more bytes
2613  than are left in the file. This value varies as the file
2614  is read and must be checked at each failure.
2615  */
2616  bool MaskReadError( ON__UINT64 sizeof_request, ON__UINT64 sizeof_read ) const;
2617 private:
2618 
2619 
2620  // When a 3DM archive is read, m_3dm_opennurbs_version records the version of
2621  // OpenNURBS used to create the archive. Otherwise, m_3dm_opennurbs_version
2622  // is zero.
2623  //
2624  // Read3dmProperties() sets this to the version of OpenNURBS that was
2625  // used to write file file. If the file was created using a version
2626  // of OpenNURBS before 200012210, this number will be zero.
2627  //
2628  // Write3dmProperties() stores the value returned by ON::Version() in
2629  // the archive's properties table.
2630  friend void ON_SetBinaryArchiveOpenNURBSVersion(ON_BinaryArchive&,int);
2631  int m_3dm_opennurbs_version;
2632 
2633  // When a 3dm archive is saved from an MFC application that supports
2634  // Windows linking/embedding, the first 5kb to 1mb of the file contains
2635  // information that is put there by MFC. m_3dm_start_section_offset
2636  // records the offset into the file where the 3dm archive actually begins.
2637  size_t m_3dm_start_section_offset;
2638 
2639  table_type m_active_table;
2640 
2641  table_type TableTypeFromTypecode( unsigned int ); // table type from tcode
2642 
2644 
2645  // stack of chunks
2646  bool PushBigChunk( ON__UINT32 typecode, ON__INT64 value );
2647 
2648  bool WriteChunkTypecode( ON__UINT32 );
2649  bool ReadChunkTypecode( ON__UINT32* );
2650  bool WriteChunkValue( ON__UINT32 typecode, ON__INT64 );
2651  bool WriteChunkLength( ON__UINT64 );
2652  bool ReadChunkValue( ON__UINT32 typecode, ON__INT64* value64 );
2653  bool FindMisplacedTable(
2654  ON__UINT64 filelength,
2655  const ON__UINT32 table_tocde,
2656  const ON__UINT32 table_record_record,
2657  const ON_UUID class_uuid,
2658  const ON__UINT64 min_length_data
2659  );
2660 
2661  bool ReadObjectUserDataAnonymousChunk(
2662  const ON__UINT64 length_TCODE_ANONYMOUS_CHUNK,
2663  const int archive_3dm_version,
2664  const int archive_opennurbs_version,
2665  class ON_UserData* ud );
2666 
2667 public:
2668  size_t SizeofChunkLength() const;
2669 
2670 private:
2671  bool WriteEOFSizeOfFile( ON__UINT64 );
2672  bool ReadEOFSizeOfFile( ON__UINT64* );
2673 
2674  bool m_bDoChunkCRC; // true if active chunk crc status should be checked
2675  // and updated.
2676  int m_bad_CRC_count; // number of chunks that have a bad crc
2677 
2678 
2679 private:
2680  // compressed buffer I/O uses zlib 1.1.3 inflate()/deflate()
2681  struct
2682  {
2683  ON::archive_mode mode; // ON::read = read and inflate, ON::write = deflate and write
2684  enum
2685  {
2686  sizeof_x_buffer = 16384
2687  };
2688  unsigned char buffer[sizeof_x_buffer];
2690  } m_zlib;
2691 
2692  // returns number of bytes written
2693  size_t WriteDeflate(
2694  size_t, // sizeof uncompressed input data
2695  const void* // uncompressed input data
2696  );
2697  bool ReadInflate(
2698  size_t, // sizeof uncompressed input data
2699  void* // buffer to hold uncompressed data
2700  );
2701  bool CompressionInit();
2702  void CompressionEnd();
2703 
2704 private:
2705  // endian-ness of the cpu reading this file.
2706  // 3dm files are alwasy saved with little endian byte order.
2707  ON::endian m_endian;
2708 
2709  ON::archive_mode m_mode;
2710 
2711  // 3dm write options
2712  bool m_bSaveUserData; // true to save user data (increases file size)
2713  bool m_bSavePreviewImage; // true to save 200x200 preview bitmap (increases file size)
2714  bool m_bEmbedTextureBitmaps; // true to embed texture, bump, trace, and wallpaper bitmaps (increases file size)
2715  bool m_bSaveRenderMeshes; // true to save meshes used to render B-rep objects (increases file size)
2716  bool m_bSaveAnalysisMeshes; // true to save meshes used in surface analysis (increases file size)
2717 
2718  // ids of plug-ins that support saving older (V3) versions
2719  // of user data. This information is filled in from the
2720  // list of plug-ins passed in whenteh settings are saved.
2721  ON_SimpleArray< ON_UUID > m_V3_plugin_id_list;
2722 
2723  struct ON__3dmV1LayerIndex* m_V1_layer_list;
2724 
2725  // prohibit default construction, copy construction, and operator=
2726  ON_BinaryArchive();
2727  ON_BinaryArchive( const ON_BinaryArchive& ); // no implementation
2728  ON_BinaryArchive& operator=( const ON_BinaryArchive& ); // no implementation
2729 
2730 };
2731 
2732 class ON_CLASS ON_3dmGoo
2733 {
2734  // used to store goo
2735 public:
2736  ON_3dmGoo();
2737  ~ON_3dmGoo();
2738  ON_3dmGoo( const ON_3dmGoo& );
2739  ON_3dmGoo& operator=( const ON_3dmGoo& );
2740 
2741  void Dump(ON_TextLog&) const;
2742 
2743  unsigned int m_typecode;
2744  int m_value;
2745  unsigned char* m_goo;
2748 };
2749 
2750 
2751 class ON_CLASS ON_BinaryFile : public ON_BinaryArchive
2752 {
2753 public:
2754  ON_BinaryFile( ON::archive_mode );
2755 
2756  /*
2757  Description:
2758  Create an ON_BinaryArchive that reads/writes from an ordinary file.
2759  Parameters:
2760  mode - [in]
2761  fp - [in]
2762  If a file is being read, fp is the pointer returned
2763  from ON_FileStream::Open(...,"rb").
2764  If a file is being written, fp is the pointer returned
2765  from ON_FileStream::Open(...,"wb").
2766  */
2767  ON_BinaryFile( ON::archive_mode, FILE* fp );
2768 
2769  virtual ~ON_BinaryFile();
2770 
2771  // ON_BinaryArchive overrides
2772  size_t CurrentPosition() const;
2773  bool SeekFromCurrentPosition(int);
2774  bool SeekFromStart(size_t);
2775  bool AtEnd() const;
2776 
2777  // fseek from end (since the file has an end)
2778  bool SeekFromEnd( int );
2779 
2780  //////////
2781  // To use custom memory buffering instead of relying
2782  // on fread()/fwrite()'s build in buffering, call
2783  // EnableMemoryBuffer() with the buffer size immediately
2784  // after constructing the ON_BinaryFile. There appear
2785  // to be enough bugs in existing Windows NT/2000 NETWORK
2786  // I/O that using this hack will speed up I/O by factors
2787  // of 10 to 100.
2788  void EnableMemoryBuffer(
2789  int=16384 // capacity of memory buffer
2790  );
2791 
2792 protected:
2793  size_t Read( size_t, void* );
2794  size_t Write( size_t, const void* );
2795  bool Flush();
2796 
2797 private:
2798  // Implementation
2799  FILE* m_fp;
2800 
2801  // if m_memory_buffer_capacity is zero, then Write() uses
2802  // fwrite() directly. If m_memory_buffer_capacity is
2803  // greater than zero, then Write() buffers its results
2804  // into m_memory_buffer. This is provided to work around
2805  // bugs in some networks that result in extremely slow
2806  // performance when seeking is used.
2807  size_t m_memory_buffer_capacity;
2808  size_t m_memory_buffer_size;
2809  size_t m_memory_buffer_ptr;
2810  unsigned char* m_memory_buffer;
2811 
2812 private:
2813  // prohibit default construction, copy construction, and operator=
2814  ON_BinaryFile( ); // no implementation
2815  ON_BinaryFile( const ON_BinaryFile& ); // no implementation
2816  ON_BinaryFile& operator=( const ON_BinaryFile& ); // no implementation
2817 };
2818 
2820 {
2821 public:
2822  /*
2823  Description:
2824  Create an ON_BinaryArchive that reads/writes from an ON_Buffer.
2825  Parameters:
2826  mode - [in]
2827  buffer - [in]
2828  Remarks:
2829  If a non-null buffer is specifed, then do not call SetBuffer()
2830  */
2831  ON_BinaryArchiveBuffer( ON::archive_mode, ON_Buffer* buffer );
2832 
2833  virtual ~ON_BinaryArchiveBuffer();
2834 
2835  /*
2836  Description:
2837  If the ON_BinaryArchiveBuffer class is created with the constructor
2838  that has a single "mode" parameter, then use SetBuffer()
2839  to specify the buffer to read/write from before using
2840  the ON_BinaryArchiveBuffer.
2841  Parameters:
2842  buffer - [in]
2843  Returns:
2844  True if the buffer is set. Once the buffer is set it
2845  cannot be changed.
2846  */
2847  bool SetBuffer( ON_Buffer* buffer );
2848 
2849  /*
2850  Returns:
2851  Buffer being read/written.
2852  */
2853  ON_Buffer* Buffer() const;
2854 
2855  // virtual ON_BinaryArchive overrides
2856  size_t CurrentPosition() const;
2857  bool SeekFromCurrentPosition(int);
2858  bool SeekFromStart(size_t);
2859  bool AtEnd() const;
2860 
2861  bool SeekFromEnd( ON__INT64 );
2862 
2863 protected:
2864  size_t Read( size_t, void* );
2865  size_t Write( size_t, const void* );
2866  bool Flush();
2867 
2868 private:
2869  // Buffer being read/written.
2870  ON_Buffer* m_buffer;
2871 
2872 private:
2873  // prohibit use - you should specify a buffer.
2874  ON_BinaryArchiveBuffer( ON::archive_mode );
2875 private:
2876  // prohibit default construction, copy construction, and operator=
2877  ON_BinaryArchiveBuffer( ); // no implementation
2878  ON_BinaryArchiveBuffer( const ON_BinaryArchiveBuffer& ); // no implementation
2879  ON_BinaryArchiveBuffer& operator=( const ON_BinaryArchiveBuffer& ); // no implementation
2880 };
2881 
2882 
2884 {
2885 public:
2886 
2887  /*
2888  Description:
2889  Construct an ON_BinaryArchive for reading information from a memory buffer.
2890  Parameters:
2891  sizeof_buffer - [in] size of buffer in bytes (>0)
2892  buffer - [in] memory buffer containing binary archive
2893  bCopyBuffer - [in]
2894  true - copy the input buffer.
2895  Useful when the buffer may be destroyed while this class is still in use.
2896  false - Do not copy the input buffer.
2897  In this case you are responsible for making certain the input buffer
2898  is valid while this class is in use.
2899  archive_3dm_version - [in] (1,2,3,4 or 5)
2900  archive_opennurbs_version - [in] YYYYMMDDn
2901  */
2903  size_t sizeof_buffer,
2904  const void* buffer,
2905  bool bCopyBuffer,
2906  int archive_3dm_version,
2907  int archive_opennurbs_version
2908  );
2909 
2911 
2912  /*
2913  Returns:
2914  value of m_sizeof_buffer
2915  */
2916  size_t SizeOfBuffer() const;
2917 
2918  /*
2919  Returns:
2920  value of m_buffer
2921  */
2922  const void* Buffer() const;
2923 
2924  // ON_BinaryArchive overrides
2925  size_t CurrentPosition() const;
2926  bool SeekFromCurrentPosition(int);
2927  bool SeekFromStart(size_t);
2928  bool AtEnd() const;
2929 
2930 protected:
2931  // ON_BinaryArchive overrides
2932  size_t Read( size_t, void* ); // return actual number of bytes read (like fread())
2933  size_t Write( size_t, const void* );
2934  bool Flush();
2935 
2936 private:
2937  void* m_p;
2938  const unsigned char* m_buffer;
2939  size_t m_sizeof_buffer;
2940  size_t m_buffer_position;
2941  ON__INT_PTR m_reserved1;
2942  ON__INT_PTR m_reserved2;
2943  ON__INT_PTR m_reserved3;
2944  ON__INT_PTR m_reserved4;
2945 
2946 private:
2947  // prohibit use - no implementation
2951 };
2952 
2954 {
2955 public:
2956 
2957  /*
2958  Description:
2959  Construct an ON_BinaryArchive for writing information to a memory buffer.
2960  Parameters:
2961  initial_sizeof_buffer - [in]
2962  initial size of buffer in bytes (>=0)
2963  If you are unable to estimate the size you will need, pass in zero.
2964  max_sizeof_buffer - [in]
2965  maximum size of buffer in bytes (>=0)
2966  If max_sizeof_buffer > 0 and the amount of information saved
2967  requires a buffer larger than this size, then writing fails.
2968  If max_sizeof_buffer <= 0, then no buffer size limits are enforced.
2969  archive_3dm_version - [in] (0, ,2,3,4 or 50)
2970  Pass 0 or ON_BinaryArchive::CurrentArchiveVersion() to write the
2971  version of opennurbs archives used by lastest version of Rhino.
2972  archive_opennurbs_version - [in] YYYYMMDDn
2973  */
2975  size_t initial_sizeof_buffer,
2976  size_t max_sizeof_buffer,
2977  int archive_3dm_version,
2978  int archive_opennurbs_version
2979  );
2980 
2982 
2983  /*
2984  Returns:
2985  Size of the archive in bytes.
2986  */
2987  size_t SizeOfArchive() const;
2988 
2989  /*
2990  Returns:
2991  value of m_sizeof_buffer
2992  */
2993  size_t SizeOfBuffer() const;
2994 
2995  /*
2996  Returns:
2997  value of m_buffer.
2998  SizeOfArchive() reports the number of bytes
2999  written to this buffer.
3000  SizeOfBuffer() reports the number of bytes
3001  allocated in this buffer.
3002 
3003  */
3004  const void* Buffer() const;
3005 
3006  /*
3007  Returns:
3008  The pointer to the buffer and sets all
3009  members on this archive back to zero.
3010  The caller is responsible for calling onfree() on
3011  the pointer when finished with the buffer.
3012  */
3013  void* HarvestBuffer();
3014 
3015  // ON_BinaryArchive overrides
3016  size_t CurrentPosition() const;
3017  bool SeekFromCurrentPosition(int);
3018  bool SeekFromStart(size_t);
3019  bool AtEnd() const;
3020 
3021 protected:
3022  // ON_BinaryArchive overrides
3023  size_t Read( size_t, void* );
3024  size_t Write( size_t, const void* ); // return actual number of bytes written (like fwrite())
3025  bool Flush();
3026 
3027 private:
3028  void AllocBuffer(size_t);
3029  void* m_p;
3030  unsigned char* m_buffer;
3031  size_t m_sizeof_buffer;
3032  const size_t m_max_sizeof_buffer;
3033  size_t m_sizeof_archive;
3034  size_t m_buffer_position;
3035  ON__INT_PTR m_reserved1;
3036  ON__INT_PTR m_reserved2;
3037  ON__INT_PTR m_reserved3;
3038  ON__INT_PTR m_reserved4;
3039 
3040 private:
3041  // prohibit use - no implementation
3045 };
3046 
3047 /*
3048 Description:
3049  Create a simple archive that contains a single geometric object.
3050 Parameters:
3051  archive - [in] destination archive.
3052  version - [in] (0, 2, 3, 4, or 50) format version.archive version number.
3053  Version 2 format can be read by Rhino 2 and Rhino 3. Version
3054  3 format can be read by Rhino 3.
3055  Pass 0 or ON_BinaryArchive::CurrentArchiveVersion() to write
3056  the latest version of archives supported by Rhino.
3057  object - [in] object to be saved in the archive's object table.
3058  This is typically some type of ON_Curve, ON_Surface, ON_Mesh,
3059  or ON_Brep.
3060 Returns:
3061  @untitled table
3062  true archive successfully written.
3063  false archive not successfully written.
3064 Example:
3065 
3066  const char* filename = "myfile.3dm";
3067  FILE* fp = ON::OpenFile( filename, "wb" );
3068  ON_BinaryFile file( fp, ON::write3dm );
3069  ON_BOOL32 ok = ON_WriteArchive( archive, geometry );
3070  ON::CloseFile( fp );
3071 
3072 Remarks:
3073  The object table in the archive will contain a single
3074  object.
3075 */
3076 ON_DECL
3077 bool ON_WriteOneObjectArchive(
3078  ON_BinaryArchive& archive,
3079  int version,
3080  const ON_Object& object
3081  );
3082 
3083 #endif
3084 
ON__UINT16 m_crc16
ON_3dmGoo * m_prev_goo
ON_3dmGoo * m_next_goo
ON__UINT16 m_do_crc16
unsigned int m_typecode
ON::archive_mode mode
ON__UINT32 m_do_crc32
ON__UINT32 m_crc32
unsigned int m_typecode
unsigned char * m_goo