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; 657 class ON_InstanceDefinition; 658 class ON_HatchPattern; 659 class ON_Linetype; 660 661 struct ON_3DM_CHUNK 662 { 663 std::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 676 struct ON_3DM_BIG_CHUNK 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; 722 class ON_3dmObjectAttributes; 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 std::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 std::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, std::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( std::size_t, void* ); // must fail if mode is not read or readwrite 793 794 bool WriteByte( std::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 // std::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( std::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 std::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 std::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 std::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 std::size_t, // number of chars to read 894 char* 895 ); 896 bool ReadChar( // Read an array of 8 bit unsigned chars 897 std::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 std::size_t, // number of shorts to read 909 short* 910 ); 911 bool ReadShort( // Read an array of 16 bit unsigned shorts 912 std::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 std::size_t, // number of ints to read 924 int* 925 ); 926 bool ReadInt( // Read an array of 32 bit integers 927 std::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 std::size_t, // number of ints to read 939 ON__INT64* 940 ); 941 bool ReadBigInt( // Read an array of 64 bit integers 942 std::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 std::size_t, // number of ints to read 954 long* 955 ); 956 bool ReadLong( // Read an array of 32 bit integers 957 std::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 std::size_t 967 std::size_t* 968 ); 969 970 bool ReadBigSize( std::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 std::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 std::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 std::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 std::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 std::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 std::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 std::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 std::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 std::size_t, // number of chars to write 1177 const char* 1178 ); 1179 bool WriteChar( // Write an array of 8 bit unsigned chars 1180 std::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 std::size_t, // number of shorts to write 1192 const short* 1193 ); 1194 bool WriteShort( // Write an array of 16 bit unsigned shorts 1195 std::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 std::size_t, // number of ints to write 1207 const int* 1208 ); 1209 bool WriteInt( // Write an array of 32 bit integers 1210 std::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 std::size_t, // number of ints to write 1222 const ON__INT64* 1223 ); 1224 bool WriteBigInt( // Write an array of 64 bit integers 1225 std::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 std::size_t, // number of ints to write 1237 const long* 1238 ); 1239 bool WriteLong( // Write an array of 32 bit integers 1240 std::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 std::size_t 1250 std::size_t 1251 ); 1252 1253 bool WriteBigSize( std::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 std::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 std::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( 1545 ON_3dmProperties& 1546 ); 1547 1548 /////////////////////////////////////////////////////////////////// 1549 // Step 3: REQUIRED - Write/Read settings table 1550 // 1551 bool Write3dmSettings( 1552 const ON_3dmSettings& 1553 ); 1554 bool Read3dmSettings( 1555 ON_3dmSettings& 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 std::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 std::size_t ArchiveStartOffset() const; 2380 2381 enum table_type 2382 { 2383 no_active_table = 0, 2384 properties_table, 2385 settings_table, 2386 bitmap_table, 2387 texture_mapping_table, 2388 material_table, 2389 linetype_table, 2390 layer_table, 2391 light_table, 2392 object_table, 2393 group_table, 2394 font_table, 2395 dimstyle_table, 2396 hatchpattern_table, 2397 instance_definition_table, 2398 historyrecord_table, 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 std::size_t Read( std::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 std::size_t Write( std::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 Applications (like Rhino) override this function to load plug-ins 2489 Description: 2490 When ON_BinaryArchive::ReadObject() encounters userdata and 2491 the user data class id is not present, LoadUserDataApplication 2492 is called to load the application that created user data. 2493 Returns: 2494 0 - could not load the application 2495 1 - successfully loaded the application 2496 2 - the application was already loaded 2497 */ 2498 virtual LoadUserDataApplication(ON_UUID)2499 int LoadUserDataApplication( 2500 ON_UUID /*application_id*/ 2501 ) 2502 { 2503 return 0; 2504 } 2505 2506 bool SetArchive3dmVersion(int); 2507 2508 private: 2509 // 16 bit integer IO 2510 bool WriteInt8( std::size_t, const ON__INT8* ); 2511 bool ReadInt8( std::size_t, ON__INT8* ); 2512 2513 // 16 bit integer IO 2514 bool WriteInt16( std::size_t, const ON__INT16* ); 2515 bool ReadInt16( std::size_t, ON__INT16* ); 2516 2517 // 32 bit integer IO 2518 bool WriteInt32( std::size_t, const ON__INT32* ); 2519 bool ReadInt32( std::size_t, ON__INT32* ); 2520 2521 // 64 bit integer IO 2522 bool WriteInt64( std::size_t, const ON__INT64* ); 2523 bool ReadInt64( std::size_t, ON__INT64* ); 2524 2525 bool BeginWrite3dmTable( 2526 unsigned int // tcode 2527 ); 2528 bool EndWrite3dmTable( 2529 unsigned int // tcode 2530 ); 2531 bool BeginRead3dmTable( 2532 unsigned int // tcode 2533 ); 2534 bool EndRead3dmTable( 2535 unsigned int // tcode 2536 ); 2537 2538 bool Read3dmV1Layer( ON_Layer*& ); 2539 int Read3dmV1Light( // returns 0 at end of light table 2540 // 1 light successfully read 2541 // -1 if file is corrupt 2542 ON_Light**, // light returned here 2543 ON_3dmObjectAttributes* // optional - if NOT NULL, object attributes are 2544 // returned here 2545 ); 2546 int Read3dmV1Material( ON_Material** ); 2547 int Read3dmV1Object( // returns 0 at end of object table 2548 // 1 if object is read 2549 // 2 if object is skipped because it does not match filter 2550 // -1 if file is corrupt 2551 ON_Object**, // object returned here (NULL if skipped) 2552 ON_3dmObjectAttributes*, // optional - if NOT NULL, object attributes are 2553 // returned here 2554 unsigned int = 0 // optional filter made by setting ON::object_type bits 2555 ); // returns NULL at end of object table 2556 2557 bool Read3dmV1AttributesOrMaterial( 2558 ON_3dmObjectAttributes*, // attributes, 2559 ON_Material*, // material, 2560 ON_BOOL32&, // bHaveMat 2561 unsigned int, // end_mark_tcode 2562 class ON__3dmV1_XDATA* = 0 // v1 "xdata" 2563 ); 2564 bool Read3dmV1String( ON_String& ); 2565 int Read3dmV1LayerIndex( const char* ) const; 2566 2567 public: 2568 // helpers for reading V1 objects 2569 bool ReadV1_TCODE_RH_POINT(ON_Object**,ON_3dmObjectAttributes*); 2570 bool ReadV1_TCODE_MESH_OBJECT(ON_Object**,ON_3dmObjectAttributes*); 2571 bool ReadV1_TCODE_LEGACY_CRV(ON_Object**,ON_3dmObjectAttributes*); 2572 bool ReadV1_TCODE_LEGACY_FAC(ON_Object**,ON_3dmObjectAttributes*); 2573 bool ReadV1_TCODE_LEGACY_SHL(ON_Object**,ON_3dmObjectAttributes*); 2574 bool ReadV1_TCODE_RHINOIO_OBJECT_NURBS_CURVE(ON_Object**,ON_3dmObjectAttributes*); 2575 bool ReadV1_TCODE_RHINOIO_OBJECT_NURBS_SURFACE(ON_Object**,ON_3dmObjectAttributes*); 2576 bool ReadV1_TCODE_RHINOIO_OBJECT_BREP(ON_Object**,ON_3dmObjectAttributes*); 2577 bool ReadV1_TCODE_ANNOTATION(unsigned int,ON_Object**,ON_3dmObjectAttributes*); 2578 2579 private: 2580 ON::archive_mode Mode() const; // current read/write mode 2581 void UpdateCRC( std::size_t, const void* ); 2582 int ReadObjectHelper(ON_Object**); 2583 2584 int m_3dm_version; 2585 int m_3dm_v1_layer_index; 2586 int m_3dm_v1_material_index; 2587 2588 // The bits in m_error_message_mask are used to mask errors 2589 // when we know we are doing something that may generate an 2590 // error. 2591 // 2592 // bit 0x00000001 2593 // V1 files do not have a table structure and are read using 2594 // multiple passes and there are valid situations where a 2595 // 4 byte read is attempted at the end of a file. 2596 // 2597 // bit 0x00000002 2598 // Some v1 files do not have an end mark. When reading 2599 // these v1 files bit 0x02 is set. 2600 // 2601 // bit 0x00000004 2602 // Requested read may go beyond end of file. 2603 // One situation where this happens is when a table is not at the 2604 // expected location in a file, 2605 2606 unsigned int m_error_message_mask; 2607 protected: 2608 unsigned int ErrorMessageMask() const; 2609 /* 2610 Paramters: 2611 sizeof_request - [in] 2612 value of count parameter passed to virtual Read() function. 2613 sizeof_read - [in] 2614 number of bytes actually read by the virtual Read() function. 2615 Returns: 2616 True if a call to Read() is permitted to ask for more bytes 2617 than are left in the file. This value varies as the file 2618 is read and must be checked at each failure. 2619 */ 2620 bool MaskReadError( ON__UINT64 sizeof_request, ON__UINT64 sizeof_read ) const; 2621 private: 2622 2623 2624 // When a 3DM archive is read, m_3dm_opennurbs_version records the version of 2625 // OpenNURBS used to create the archive. Otherwise, m_3dm_opennurbs_version 2626 // is zero. 2627 // 2628 // Read3dmProperties() sets this to the version of OpenNURBS that was 2629 // used to write file file. If the file was created using a version 2630 // of OpenNURBS before 200012210, this number will be zero. 2631 // 2632 // Write3dmProperties() stores the value returned by ON::Version() in 2633 // the archive's properties table. 2634 friend void ON_SetBinaryArchiveOpenNURBSVersion(ON_BinaryArchive&,int); 2635 int m_3dm_opennurbs_version; 2636 2637 // When a 3dm archive is saved from an MFC application that supports 2638 // Windows linking/embedding, the first 5kb to 1mb of the file contains 2639 // information that is put there by MFC. m_3dm_start_section_offset 2640 // records the offset into the file where the 3dm archive actually begins. 2641 std::size_t m_3dm_start_section_offset; 2642 2643 table_type m_active_table; 2644 2645 table_type TableTypeFromTypecode( unsigned int ); // table type from tcode 2646 2647 ON_SimpleArray<ON_3DM_BIG_CHUNK> m_chunk; 2648 2649 // stack of chunks 2650 bool PushBigChunk( ON__UINT32 typecode, ON__INT64 value ); 2651 2652 bool WriteChunkTypecode( ON__UINT32 ); 2653 bool ReadChunkTypecode( ON__UINT32* ); 2654 bool WriteChunkValue( ON__UINT32 typecode, ON__INT64 ); 2655 bool WriteChunkLength( ON__UINT64 ); 2656 bool ReadChunkValue( ON__UINT32 typecode, ON__INT64* value64 ); 2657 bool FindMisplacedTable( 2658 ON__UINT64 filelength, 2659 const ON__UINT32 table_tocde, 2660 const ON__UINT32 table_record_record, 2661 const ON_UUID class_uuid, 2662 const ON__UINT64 min_length_data 2663 ); 2664 2665 bool ReadObjectUserDataAnonymousChunk( 2666 const ON__UINT64 length_TCODE_ANONYMOUS_CHUNK, 2667 const int archive_3dm_version, 2668 const int archive_opennurbs_version, 2669 class ON_UserData* ud ); 2670 2671 public: 2672 std::size_t SizeofChunkLength() const; 2673 2674 private: 2675 bool WriteEOFSizeOfFile( ON__UINT64 ); 2676 bool ReadEOFSizeOfFile( ON__UINT64* ); 2677 2678 bool m_bDoChunkCRC; // true if active chunk crc status should be checked 2679 // and updated. 2680 int m_bad_CRC_count; // number of chunks that have a bad crc 2681 2682 2683 private: 2684 // compressed buffer I/O uses zlib 1.1.3 inflate()/deflate() 2685 struct 2686 { 2687 ON::archive_mode mode; // ON::read = read and inflate, ON::write = deflate and write 2688 enum 2689 { 2690 sizeof_x_buffer = 16384 2691 }; 2692 unsigned char buffer[sizeof_x_buffer]; 2693 z_stream strm; 2694 } m_zlib; 2695 2696 // returns number of bytes written 2697 std::size_t WriteDeflate( 2698 std::size_t, // sizeof uncompressed input data 2699 const void* // uncompressed input data 2700 ); 2701 bool ReadInflate( 2702 std::size_t, // sizeof uncompressed input data 2703 void* // buffer to hold uncompressed data 2704 ); 2705 bool CompressionInit(); 2706 void CompressionEnd(); 2707 2708 private: 2709 // endian-ness of the cpu reading this file. 2710 // 3dm files are alwasy saved with little endian byte order. 2711 ON::endian m_endian; 2712 2713 ON::archive_mode m_mode; 2714 2715 // 3dm write options 2716 bool m_bSaveUserData; // true to save user data (increases file size) 2717 bool m_bSavePreviewImage; // true to save 200x200 preview bitmap (increases file size) 2718 bool m_bEmbedTextureBitmaps; // true to embed texture, bump, trace, and wallpaper bitmaps (increases file size) 2719 bool m_bSaveRenderMeshes; // true to save meshes used to render B-rep objects (increases file size) 2720 bool m_bSaveAnalysisMeshes; // true to save meshes used in surface analysis (increases file size) 2721 2722 // ids of plug-ins that support saving older (V3) versions 2723 // of user data. This information is filled in from the 2724 // list of plug-ins passed in whenteh settings are saved. 2725 ON_SimpleArray< ON_UUID > m_V3_plugin_id_list; 2726 2727 struct ON__3dmV1LayerIndex* m_V1_layer_list; 2728 2729 // prohibit default construction, copy construction, and operator= 2730 ON_BinaryArchive(); 2731 ON_BinaryArchive( const ON_BinaryArchive& ); // no implementation 2732 ON_BinaryArchive& operator=( const ON_BinaryArchive& ); // no implementation 2733 2734 }; 2735 2736 class ON_CLASS ON_3dmGoo 2737 { 2738 // used to store goo 2739 public: 2740 ON_3dmGoo(); 2741 ~ON_3dmGoo(); 2742 ON_3dmGoo( const ON_3dmGoo& ); 2743 ON_3dmGoo& operator=( const ON_3dmGoo& ); 2744 2745 void Dump(ON_TextLog&) const; 2746 2747 unsigned int m_typecode; 2748 int m_value; 2749 unsigned char* m_goo; 2750 ON_3dmGoo* m_next_goo; 2751 ON_3dmGoo* m_prev_goo; 2752 }; 2753 2754 2755 class ON_CLASS ON_BinaryFile : public ON_BinaryArchive 2756 { 2757 public: 2758 ON_BinaryFile( ON::archive_mode ); 2759 2760 /* 2761 Description: 2762 Create an ON_BinaryArchive that reads/writes from an ordinary file. 2763 Parameters: 2764 mode - [in] 2765 fp - [in] 2766 If a file is being read, fp is the pointer returned 2767 from ON_FileStream::Open(...,"rb"). 2768 If a file is being written, fp is the pointer returned 2769 from ON_FileStream::Open(...,"wb"). 2770 */ 2771 ON_BinaryFile( ON::archive_mode, FILE* fp ); 2772 2773 virtual ~ON_BinaryFile(); 2774 2775 // ON_BinaryArchive overrides 2776 std::size_t CurrentPosition() const; 2777 bool SeekFromCurrentPosition(int); 2778 bool SeekFromStart(std::size_t); 2779 bool AtEnd() const; 2780 2781 // fseek from end (since the file has an end) 2782 bool SeekFromEnd( int ); 2783 2784 ////////// 2785 // To use custom memory buffering instead of relying 2786 // on fread()/fwrite()'s build in buffering, call 2787 // EnableMemoryBuffer() with the buffer size immediately 2788 // after constructing the ON_BinaryFile. There appear 2789 // to be enough bugs in existing Windows NT/2000 NETWORK 2790 // I/O that using this hack will speed up I/O by factors 2791 // of 10 to 100. 2792 void EnableMemoryBuffer( 2793 int=16384 // capacity of memory buffer 2794 ); 2795 2796 protected: 2797 std::size_t Read( std::size_t, void* ); 2798 std::size_t Write( std::size_t, const void* ); 2799 bool Flush(); 2800 2801 private: 2802 // Implementation 2803 FILE* m_fp; 2804 2805 // if m_memory_buffer_capacity is zero, then Write() uses 2806 // fwrite() directly. If m_memory_buffer_capacity is 2807 // greater than zero, then Write() buffers its results 2808 // into m_memory_buffer. This is provided to work around 2809 // bugs in some networks that result in extremely slow 2810 // performance when seeking is used. 2811 std::size_t m_memory_buffer_capacity; 2812 std::size_t m_memory_buffer_size; 2813 std::size_t m_memory_buffer_ptr; 2814 unsigned char* m_memory_buffer; 2815 2816 private: 2817 // prohibit default construction, copy construction, and operator= 2818 ON_BinaryFile( ); // no implementation 2819 ON_BinaryFile( const ON_BinaryFile& ); // no implementation 2820 ON_BinaryFile& operator=( const ON_BinaryFile& ); // no implementation 2821 }; 2822 2823 class ON_CLASS ON_BinaryArchiveBuffer : public ON_BinaryArchive 2824 { 2825 public: 2826 /* 2827 Description: 2828 Create an ON_BinaryArchive that reads/writes from an ON_Buffer. 2829 Parameters: 2830 mode - [in] 2831 buffer - [in] 2832 Remarks: 2833 If a non-null buffer is specifed, then do not call SetBuffer() 2834 */ 2835 ON_BinaryArchiveBuffer( ON::archive_mode, ON_Buffer* buffer ); 2836 2837 virtual ~ON_BinaryArchiveBuffer(); 2838 2839 /* 2840 Description: 2841 If the ON_BinaryArchiveBuffer class is created with the constructor 2842 that has a single "mode" parameter, then use SetBuffer() 2843 to specify the buffer to read/write from before using 2844 the ON_BinaryArchiveBuffer. 2845 Parameters: 2846 buffer - [in] 2847 Returns: 2848 True if the buffer is set. Once the buffer is set it 2849 cannot be changed. 2850 */ 2851 bool SetBuffer( ON_Buffer* buffer ); 2852 2853 /* 2854 Returns: 2855 Buffer being read/written. 2856 */ 2857 ON_Buffer* Buffer() const; 2858 2859 // virtual ON_BinaryArchive overrides 2860 std::size_t CurrentPosition() const; 2861 bool SeekFromCurrentPosition(int); 2862 bool SeekFromStart(std::size_t); 2863 bool AtEnd() const; 2864 2865 bool SeekFromEnd( ON__INT64 ); 2866 2867 protected: 2868 std::size_t Read( std::size_t, void* ); 2869 std::size_t Write( std::size_t, const void* ); 2870 bool Flush(); 2871 2872 private: 2873 // Buffer being read/written. 2874 ON_Buffer* m_buffer; 2875 2876 private: 2877 // prohibit use - you should specify a buffer. 2878 ON_BinaryArchiveBuffer( ON::archive_mode ); 2879 private: 2880 // prohibit default construction, copy construction, and operator= 2881 ON_BinaryArchiveBuffer( ); // no implementation 2882 ON_BinaryArchiveBuffer( const ON_BinaryArchiveBuffer& ); // no implementation 2883 ON_BinaryArchiveBuffer& operator=( const ON_BinaryArchiveBuffer& ); // no implementation 2884 }; 2885 2886 2887 class ON_CLASS ON_Read3dmBufferArchive : public ON_BinaryArchive 2888 { 2889 public: 2890 2891 /* 2892 Description: 2893 Construct an ON_BinaryArchive for reading information from a memory buffer. 2894 Parameters: 2895 sizeof_buffer - [in] size of buffer in bytes (>0) 2896 buffer - [in] memory buffer containing binary archive 2897 bCopyBuffer - [in] 2898 true - copy the input buffer. 2899 Useful when the buffer may be destroyed while this class is still in use. 2900 false - Do not copy the input buffer. 2901 In this case you are responsible for making certain the input buffer 2902 is valid while this class is in use. 2903 archive_3dm_version - [in] (1,2,3,4 or 5) 2904 archive_opennurbs_version - [in] YYYYMMDDn 2905 */ 2906 ON_Read3dmBufferArchive( 2907 std::size_t sizeof_buffer, 2908 const void* buffer, 2909 bool bCopyBuffer, 2910 int archive_3dm_version, 2911 int archive_opennurbs_version 2912 ); 2913 2914 ~ON_Read3dmBufferArchive(); 2915 2916 /* 2917 Returns: 2918 value of m_sizeof_buffer 2919 */ 2920 std::size_t SizeOfBuffer() const; 2921 2922 /* 2923 Returns: 2924 value of m_buffer 2925 */ 2926 const void* Buffer() const; 2927 2928 // ON_BinaryArchive overrides 2929 std::size_t CurrentPosition() const; 2930 bool SeekFromCurrentPosition(int); 2931 bool SeekFromStart(std::size_t); 2932 bool AtEnd() const; 2933 2934 protected: 2935 // ON_BinaryArchive overrides 2936 std::size_t Read( std::size_t, void* ); // return actual number of bytes read (like fread()) 2937 std::size_t Write( std::size_t, const void* ); 2938 bool Flush(); 2939 2940 private: 2941 void* m_p; 2942 const unsigned char* m_buffer; 2943 std::size_t m_sizeof_buffer; 2944 std::size_t m_buffer_position; 2945 ON__INT_PTR m_reserved1; 2946 ON__INT_PTR m_reserved2; 2947 ON__INT_PTR m_reserved3; 2948 ON__INT_PTR m_reserved4; 2949 2950 private: 2951 // prohibit use - no implementation 2952 ON_Read3dmBufferArchive(); 2953 ON_Read3dmBufferArchive( const ON_Read3dmBufferArchive& ); 2954 ON_Read3dmBufferArchive& operator=(const ON_Read3dmBufferArchive&); 2955 }; 2956 2957 class ON_CLASS ON_Write3dmBufferArchive : public ON_BinaryArchive 2958 { 2959 public: 2960 2961 /* 2962 Description: 2963 Construct an ON_BinaryArchive for writing information to a memory buffer. 2964 Parameters: 2965 initial_sizeof_buffer - [in] 2966 initial size of buffer in bytes (>=0) 2967 If you are unable to estimate the size you will need, pass in zero. 2968 max_sizeof_buffer - [in] 2969 maximum size of buffer in bytes (>=0) 2970 If max_sizeof_buffer > 0 and the amount of information saved 2971 requires a buffer larger than this size, then writing fails. 2972 If max_sizeof_buffer <= 0, then no buffer size limits are enforced. 2973 archive_3dm_version - [in] (0, ,2,3,4 or 50) 2974 Pass 0 or ON_BinaryArchive::CurrentArchiveVersion() to write the 2975 version of opennurbs archives used by lastest version of Rhino. 2976 archive_opennurbs_version - [in] YYYYMMDDn 2977 */ 2978 ON_Write3dmBufferArchive( 2979 std::size_t initial_sizeof_buffer, 2980 std::size_t max_sizeof_buffer, 2981 int archive_3dm_version, 2982 int archive_opennurbs_version 2983 ); 2984 2985 ~ON_Write3dmBufferArchive(); 2986 2987 /* 2988 Returns: 2989 Size of the archive in bytes. 2990 */ 2991 std::size_t SizeOfArchive() const; 2992 2993 /* 2994 Returns: 2995 value of m_sizeof_buffer 2996 */ 2997 std::size_t SizeOfBuffer() const; 2998 2999 /* 3000 Returns: 3001 value of m_buffer. 3002 SizeOfArchive() reports the number of bytes 3003 written to this buffer. 3004 SizeOfBuffer() reports the number of bytes 3005 allocated in this buffer. 3006 3007 */ 3008 const void* Buffer() const; 3009 3010 /* 3011 Returns: 3012 The pointer to the buffer and sets all 3013 members on this archive back to zero. 3014 The caller is responsible for calling onfree() on 3015 the pointer when finished with the buffer. 3016 */ 3017 void* HarvestBuffer(); 3018 3019 // ON_BinaryArchive overrides 3020 std::size_t CurrentPosition() const; 3021 bool SeekFromCurrentPosition(int); 3022 bool SeekFromStart(std::size_t); 3023 bool AtEnd() const; 3024 3025 protected: 3026 // ON_BinaryArchive overrides 3027 std::size_t Read( std::size_t, void* ); 3028 std::size_t Write( std::size_t, const void* ); // return actual number of bytes written (like fwrite()) 3029 bool Flush(); 3030 3031 private: 3032 void AllocBuffer(std::size_t); 3033 void* m_p; 3034 unsigned char* m_buffer; 3035 std::size_t m_sizeof_buffer; 3036 const std::size_t m_max_sizeof_buffer; 3037 std::size_t m_sizeof_archive; 3038 std::size_t m_buffer_position; 3039 ON__INT_PTR m_reserved1; 3040 ON__INT_PTR m_reserved2; 3041 ON__INT_PTR m_reserved3; 3042 ON__INT_PTR m_reserved4; 3043 3044 private: 3045 // prohibit use - no implementation 3046 ON_Write3dmBufferArchive(); 3047 ON_Write3dmBufferArchive( const ON_Write3dmBufferArchive& ); 3048 ON_Write3dmBufferArchive& operator=(const ON_Write3dmBufferArchive&); 3049 }; 3050 3051 /* 3052 Description: 3053 Create a simple archive that contains a single geometric object. 3054 Parameters: 3055 archive - [in] destination archive. 3056 version - [in] (0, 2, 3, 4, or 50) format version.archive version number. 3057 Version 2 format can be read by Rhino 2 and Rhino 3. Version 3058 3 format can be read by Rhino 3. 3059 Pass 0 or ON_BinaryArchive::CurrentArchiveVersion() to write 3060 the latest version of archives supported by Rhino. 3061 object - [in] object to be saved in the archive's object table. 3062 This is typically some type of ON_Curve, ON_Surface, ON_Mesh, 3063 or ON_Brep. 3064 Returns: 3065 @untitled table 3066 true archive successfully written. 3067 false archive not successfully written. 3068 Example: 3069 3070 const char* filename = "myfile.3dm"; 3071 FILE* fp = ON::OpenFile( filename, "wb" ); 3072 ON_BinaryFile file( fp, ON::write3dm ); 3073 ON_BOOL32 ok = ON_WriteArchive( archive, geometry ); 3074 ON::CloseFile( fp ); 3075 3076 Remarks: 3077 The object table in the archive will contain a single 3078 object. 3079 */ 3080 ON_DECL 3081 bool ON_WriteOneObjectArchive( 3082 ON_BinaryArchive& archive, 3083 int version, 3084 const ON_Object& object 3085 ); 3086 3087 #endif 3088 3089