00001 // Copyright (c) 1998-2014 by Tech Soft 3D, Inc. 00002 // 00003 // The information contained herein is confidential and proprietary to Tech Soft 3D, Inc., 00004 // and considered a trade secret as defined under civil and criminal statutes. 00005 // Tech Soft 3D, Inc. shall pursue its civil and criminal remedies in the event of 00006 // unauthorized use or misappropriation of its trade secrets. Use of this information 00007 // by anyone other than authorized employees of Tech Soft 3D, Inc. is granted only under 00008 // a written non-disclosure agreement, expressly prescribing the scope and manner of such use. 00009 00010 #ifndef BBINFILETK_TOOLKIT 00011 #define BBINFILETK_TOOLKIT 00012 00013 #ifndef _MSC_VER 00014 # define __wchar_t wchar_t 00015 #else 00016 # ifdef _DEBUG 00017 # include <crtdbg.h> 00018 # endif 00019 #endif 00020 00021 #if defined(WIN64) || defined(_M_X64) || defined(_WIN64) 00022 # define HLONG __int64 00023 #else 00024 # define HLONG long 00025 #endif 00026 00027 #include "BStreamMemory.h" 00028 00034 class BBINFILETK_API2 BControlledMemoryObject { 00035 public: 00036 void * operator new (size_t size); 00037 void operator delete (void * p); 00038 }; 00039 00040 class BBaseOpcodeHandler; 00041 00042 00043 #ifndef DOXYGEN_SHOULD_SKIP_THIS 00044 00045 /* 00046 Buffers data so basic handlers can deal with simple Get/Put calls of basic data types (and arrays of those types). 00047 Handles both reading and writing, ZLIB compressed or uncompressed. 00048 */ 00049 class BBINFILETK_API2 Internal_Data_Accumulator 00050 #ifdef HPS_CORE_BUILD 00051 : public CMO 00052 #else 00053 : public BControlledMemoryObject 00054 #endif 00055 { 00056 private: 00057 char * m_pending_buffer; /*< The whole burrito. */ 00058 int m_pending_buffer_allocated; /*< How big the buffer is (so we know when to reallocate) */ 00059 char * m_pending_position; /*< Start of actual data to be processed.*/ 00060 int m_pending_size; /*< Size of actual data. */ 00061 00062 char * m_buffer_data; /*< The buffer shown to the user (i.e. passed to GenerateBuffer or ParseBuffer) */ 00063 int m_buffer_size; /*< The size of the user's buffer */ 00064 00065 int m_failed_size; /*< When a read fails because of insufficient data, how much space would have been required for success? */ 00066 00067 int m_generated; /*< How much has been written into the user's buffer (after considering compression). */ 00068 00069 struct z_stream_s * m_z_stream; /*< The control structure for ZLIB */ 00070 bool m_compressed; /*< are we in compressed mode? */ 00071 bool m_writing; /*< are we compressing or decompressing? */ 00072 int m_original_size; /*< size of buffer originally passed in */ 00073 00074 public: 00075 Internal_Data_Accumulator () : m_pending_buffer (0), m_pending_buffer_allocated (0), 00076 m_pending_position (0), m_pending_size (0), 00077 m_failed_size (0), m_generated (0), 00078 m_z_stream (0), m_compressed (false), m_writing (false) {} 00079 ~Internal_Data_Accumulator (); 00080 00081 void set_data (char * b, int s) { m_buffer_data = b; m_original_size = m_buffer_size = s; } 00082 void save (); 00083 TK_Status consume (); 00084 00085 TK_Status read (char * b, int s); 00086 TK_Status write (char const * b, int s); 00087 TK_Status lookat (char & b); 00088 00089 int get_original_buffer_size () const {return m_original_size; } 00090 00091 void restart (); 00092 void clean (); 00093 int unused () const { return m_buffer_size; } 00094 int generated () const { return m_generated; } 00095 00096 TK_Status start_compression (); 00097 TK_Status stop_compression (bool flush); 00098 TK_Status start_decompression (); 00099 TK_Status stop_decompression (bool force); 00100 bool compressed () const { return m_compressed; } 00101 00102 TK_Status error (char const * msg = 0) const; 00103 }; 00104 00105 00106 /* 00107 Provides index <-> key translation, plus storage of additional item-specific data, such as 00108 file offset and size and bounding volume. 00109 */ 00110 struct IT_Index_Key_Extra { 00111 int m_variants[8][2]; 00112 int m_options; 00113 float m_bounds[6]; 00114 }; 00115 00116 class BBINFILETK_API2 Internal_Translator 00117 #ifdef HPS_CORE_BUILD 00118 : public CMO 00119 #else 00120 : public BControlledMemoryObject 00121 #endif 00122 { 00123 friend class TK_Dictionary; // note, dictionary writer tied closely to this implementation 00124 private: 00125 // array -- index to key is trivial 00126 int m_size; 00127 int m_used; 00128 00129 struct Index_Key_Pair { 00130 int m_index; 00131 ID_Key m_key; 00132 IT_Index_Key_Extra *m_extra; 00133 } * m_pairs; 00134 00135 enum Options { 00136 Bounds_Valid = 0x0001, 00137 00138 Extended = 0x0080 // reserved 00139 }; 00140 00141 // hash of key to locate potential indices for key to index lookup 00142 struct Hash_Block { 00143 Hash_Block * m_next; 00144 int m_used; 00145 int m_indices[32]; 00146 } * m_blocks[1024]; 00147 00148 00149 public: 00150 Internal_Translator () : m_size (0), m_used (0), m_pairs (0) { memset (m_blocks, 0, 1024*sizeof(void *)); } 00151 ~Internal_Translator (); 00152 00153 TK_Status add_pair (int index, ID_Key key); 00154 TK_Status add_variant (ID_Key key, int variant, int value1, int value2 = 0); 00155 TK_Status add_bounds (ID_Key key, float const bounds[]); 00156 TK_Status index_to_key (int index, ID_Key & key) const; 00157 TK_Status key_to_index (ID_Key key, int & index) const; 00158 TK_Status key_variant_offset (ID_Key key, int variant, 00159 int & offset, int & length, int & index) const; 00160 TK_Status key_bounds (ID_Key key, float bounds[]) const; 00161 int used () const { return m_used; } 00162 00163 void clean (); 00164 00165 // older forms: 00166 TK_Status key_variant_offset (ID_Key key, int variant, int & offset) const { 00167 int length, index; 00168 return key_variant_offset (key, variant, offset, length, index); 00169 } 00170 TK_Status key_variant_offset (ID_Key key, int variant, int & offset, int & length) const { 00171 int index; 00172 return key_variant_offset (key, variant, offset, length, index); 00173 } 00174 00175 }; 00176 00177 00178 class BBINFILETK_API2 Internal_Key_Record 00179 #ifdef HPS_CORE_BUILD 00180 : public CMO 00181 #else 00182 : public BControlledMemoryObject 00183 #endif 00184 { 00185 private: 00186 // hash of key to list of recorded segments 00187 struct Hash_Block { 00188 Hash_Block * m_next; 00189 int m_used; 00190 ID_Key m_keys[32]; 00191 } * m_blocks[1024]; 00192 00193 00194 public: 00195 Internal_Key_Record () { memset (m_blocks, 0, 1024*sizeof(void *)); } 00196 ~Internal_Key_Record (); 00197 00198 TK_Status add_key (ID_Key key); 00199 TK_Status find_key (ID_Key key) const; 00200 00201 void clean (); 00202 }; 00203 00204 00205 00206 // control memory on these objects, not sure who might be creating/destroying them 00207 00208 class Internal_Segment_List 00209 #ifdef HPS_CORE_BUILD 00210 : public CMO 00211 #else 00212 : public BControlledMemoryObject 00213 #endif 00214 { 00215 public: 00216 Internal_Segment_List * m_next; 00217 ID_Key m_key; 00218 00219 public: 00220 Internal_Segment_List (ID_Key k) : m_next (0), m_key (k) {} 00221 00222 ID_Key key () const { return m_key; } 00223 }; 00224 00225 class Internal_Revisit_Item 00226 #ifdef HPS_CORE_BUILD 00227 : public CMO 00228 #else 00229 : public BControlledMemoryObject 00230 #endif 00231 { 00232 public: 00233 Internal_Revisit_Item * m_next; 00234 ID_Key m_key; 00235 ID_Key m_owner; 00236 int m_lod; 00237 float m_priority; 00238 char m_opcode; 00239 bool m_force_context; 00240 }; 00241 00242 00243 class Internal_ExRef_List 00244 #ifdef HPS_CORE_BUILD 00245 : public CMO 00246 #else 00247 : public BControlledMemoryObject 00248 #endif 00249 { 00250 public: 00251 Internal_ExRef_List * m_next; 00252 Internal_ExRef_List * m_caller; 00253 wchar_t * m_ref; 00254 wchar_t * m_actual; 00255 ID_Key m_context; 00256 00257 public: 00258 Internal_ExRef_List (char const * ref, ID_Key context, Internal_ExRef_List * caller); 00259 Internal_ExRef_List (__wchar_t const * ref, ID_Key context, Internal_ExRef_List * caller); 00260 #ifdef _MSC_VER 00261 Internal_ExRef_List (unsigned short const * ref, ID_Key context, Internal_ExRef_List * caller); 00262 #endif 00263 ~Internal_ExRef_List (); 00264 00265 wchar_t const * Reference () const { return m_ref; } 00266 wchar_t const * Actual () const { return m_actual; } 00267 ID_Key Context () const { return m_context; } 00268 Internal_ExRef_List * Caller () const { return m_caller; } 00269 void SetActual (__wchar_t const * actual); 00270 #ifdef _MSC_VER 00271 void SetActual (unsigned short const * actual); 00272 #endif 00273 }; 00274 00275 00276 class BBINFILETK_API Recorded_Instance 00277 #ifdef HPS_CORE_BUILD 00278 : public CMO 00279 #else 00280 : public BControlledMemoryObject 00281 #endif 00282 { 00283 public: 00284 Recorded_Instance * m_next; 00285 00286 ID_Key m_key; 00287 int m_variant; 00288 int m_values[3]; 00289 00290 float m_local_basis[16]; // matrix from our basis to identity 00291 int m_basis_indices[4]; 00292 float m_arbitrary_point[3]; 00293 int m_arbitrary_index; 00294 bool m_basis_valid; 00295 00296 unsigned char m_opcode; 00297 00298 #ifdef _DEBUG 00299 int m_times_used; 00300 #endif 00301 00302 Recorded_Instance (ID_Key key, int variant, unsigned char op, int val1, int val2, int val3) 00303 : m_next (0), m_key (key), m_variant (variant), m_basis_valid (false), m_opcode (op) { 00304 m_values[0] = val1; m_values[1] = val2; m_values[2] = val3; 00305 #ifdef _DEBUG 00306 m_times_used = 0; 00307 #endif 00308 } 00309 00310 bool basis_valid () const { return m_basis_valid; } 00311 bool generate_basis (int count, float const points[]); 00312 }; 00313 00314 class Internal_Segment_Processor; 00315 00316 /* 00317 Callback which can be used for reporting progress during writing/reading. 00318 During writing: 00319 so_far is number of "objects" written, expected is the number the toolkit will likely write. 00320 Note: the toolkit won't know about objects in pre/post-walk handlers or extra objects due to 00321 overloading the default classes, so "so_far" may exceed "expected" 00322 During reading: 00323 so_far is the number of bytes processed, expected is the file size. 00324 user_data allows the application to pass any necessary values through. 00325 returns a flag which indicates whether the processing should continue. 00326 */ 00327 typedef bool (*TK_Progress_Callback) (unsigned HLONG so_far, unsigned HLONG expected, void * user_data); 00328 00329 #endif /* DOXYGEN_SHOULD_SKIP_THIS */ 00330 00331 00332 00334 00367 class BBINFILETK_API2 BStreamFileToolkit 00368 #ifdef HPS_CORE_BUILD 00369 : public CMO 00370 #else 00371 : public BControlledMemoryObject 00372 #endif 00373 { 00374 friend class BBaseOpcodeHandler; 00375 friend class TK_Default; 00376 friend class TK_Comment; 00377 friend class TK_Header; 00378 friend class TK_Compression; 00379 friend class TK_Dictionary; 00380 friend class Internal_Segment_Processor; 00381 friend class TK_Shell; 00382 00383 friend class TK_Tag; 00384 friend class TK_Instance; 00385 friend class HTK_Reference; 00386 protected: 00387 00388 #ifndef DOXYGEN_SHOULD_SKIP_THIS 00389 00390 Internal_Data_Accumulator m_accumulator; 00391 Internal_Translator m_translator; 00393 BBaseOpcodeHandler * m_objects[256]; 00394 BBaseOpcodeHandler * m_default_object; 00395 int m_prewalk_count; 00396 int m_postwalk_count; 00397 BBaseOpcodeHandler ** m_prewalk; 00398 BBaseOpcodeHandler ** m_postwalk; 00399 BBaseOpcodeHandler * m_current_object; 00400 Internal_Segment_List * m_active_segments; 00401 Internal_Key_Record m_visited_items; 00402 ID_Key m_context_key; 00403 ID_Key * m_last_keys; 00404 int m_last_keys_used; 00405 int m_last_keys_allocated; 00406 Internal_Revisit_Item * m_revisit; 00407 Internal_Revisit_Item * m_revisit_working; 00408 int m_stage; 00409 int m_substage; 00410 int m_pass; 00411 int m_tag_count; 00412 int m_position; 00413 unsigned int m_offset; 00414 int m_unused; 00415 int m_write_flags; 00416 int m_read_flags; 00417 int m_num_normal_bits; 00418 int m_num_vertex_bits; 00419 int m_num_parameter_bits; 00420 int m_num_color_bits; 00421 int m_num_index_bits; 00422 int m_file_version; 00423 int m_target_version; 00424 bool m_header_comment_seen; 00425 char * m_log_file; 00426 FILE * m_log_fp; 00427 bool m_logging; 00428 unsigned int m_logging_options; 00429 mutable unsigned int m_log_line_length; 00430 unsigned int m_opcode_sequence; 00431 unsigned int m_objects_written; 00432 TK_Progress_Callback m_progress_callback; 00433 void * m_progress_value; 00434 int m_buffer_limit; 00435 int m_nesting_level; 00436 int m_dictionary_format; 00437 int m_dictionary_options; 00438 int m_dictionary_size; 00439 int m_dictionary_offset; 00440 Recorded_Instance * m_instance_hash[256]; 00441 int m_jpeg_quality; 00442 int * m_pause_table; 00443 int m_pause_table_size; 00444 unsigned short m_num_pauses; 00445 float * m_world_bounding; 00446 Internal_ExRef_List * m_external_references; 00447 Internal_ExRef_List * m_external_ref_tail; 00448 Internal_ExRef_List * m_previous_exrefs; 00449 bool m_suppress_errors; 00451 wchar_t ** m_file_names; 00452 int * m_file_indices; 00453 int m_file_count; 00454 int m_files_allocated; 00455 wchar_t * m_current_filename; 00456 int m_index_base; 00457 float m_quantization_error; 00459 int m_save_write_flags; 00460 wchar_t * m_wfilename; 00461 bool m_geometry_open; 00463 bool m_is_ascii; 00464 int m_num_tabs; 00466 /* Internal use. 00467 * A quick utility to verify that an array is in fact sorted. 00468 * FOR DEBUGGING ONLY 00469 */ 00470 bool issorted_revisit(Internal_Revisit_Item *array[], int count); 00471 00476 void qsort_revisit(Internal_Revisit_Item **, Internal_Revisit_Item **); 00477 TK_Status sort_revisit(); 00478 00479 virtual void read_completed (); 00480 00481 bool add_exref (Internal_ExRef_List * exref); 00482 00483 #endif /* DOXYGEN_SHOULD_SKIP_THIS */ 00484 00485 00486 protected: 00487 00489 void * m_file; 00490 00491 public: 00492 00496 BStreamFileToolkit (); 00497 virtual ~BStreamFileToolkit (); 00498 00502 static bool SupportsAsciiMode() { 00503 #ifndef BSTREAM_DISABLE_ASCII 00504 return true; 00505 #else 00506 return false; 00507 #endif 00508 } 00509 00513 TK_Status SetAsciiMode(bool whether); 00514 00518 bool GetAsciiMode(); 00519 00520 void SetTabs(int); 00521 int GetTabs(); 00522 00528 static int ParseVersion (char const * block); 00529 00563 TK_Status ParseBuffer (char const * b, int s, TK_Status mode = TK_Normal); 00564 00565 00571 TK_Status PrepareBuffer(char * b, int s); 00572 00574 int CurrentBufferLength() {return m_accumulator.get_original_buffer_size() - 00575 m_accumulator.unused();} 00576 00582 virtual void ActivateContext (ID_Key key) { (void)key; } 00583 00589 virtual void DeactivateContext (ID_Key key) { (void)key; } 00590 00598 virtual void NewFileContext (ID_Key key) { (void)key; } 00599 00605 int GeneratedSoFar () const { return m_accumulator.generated(); } 00606 00611 unsigned int ObjectsSoFar () const { return m_objects_written; } 00612 00619 void SetOpcodeHandler (int which, BBaseOpcodeHandler * handler); 00620 00628 void SetPrewalkHandler (BBaseOpcodeHandler * handler); 00629 00630 00638 void SetPostwalkHandler (BBaseOpcodeHandler * handler); 00639 00641 BBaseOpcodeHandler * GetOpcodeHandler (int which) const { return m_objects[which]; } 00642 00648 virtual void Restart (); 00649 00650 // access to index <-> key tranlation 00657 TK_Status IndexToKey (int index, ID_Key & key) const; 00658 00665 TK_Status KeyToIndex (ID_Key key, int & index) const; 00666 00673 TK_Status AddIndexKeyPair (int index, ID_Key key) 00674 { return m_translator.add_pair (index, key); } 00675 00684 TK_Status AddVariant (ID_Key key, int variant, int value1, int value2 = -1) 00685 { return m_translator.add_variant (key, variant, value1, value2); } 00686 00693 TK_Status AddBounds (ID_Key key, float const bounds[]) 00694 { return m_translator.add_bounds (key, bounds); } 00695 00703 TK_Status GetOffset (ID_Key key, int variant, int & offset) const 00704 { return m_translator.key_variant_offset (key, variant, offset); } 00705 00714 TK_Status GetOffset (ID_Key key, int variant, int & offset, int & length) const 00715 { return m_translator.key_variant_offset (key, variant, offset, length); } 00716 00726 TK_Status GetOffset (ID_Key key, int variant, 00727 int & offset, int & length, __wchar_t const *& filename) const; 00728 #ifdef _MSC_VER 00729 TK_Status GetOffset (ID_Key key, int variant, 00730 int & offset, int & length, unsigned short const *& filename) const; 00731 #endif 00732 00738 TK_Status GetBounds (ID_Key key, float bounds[]) const 00739 { return m_translator.key_bounds (key, bounds); } 00740 00745 int NextTagIndex () { return m_tag_count++; } 00750 int PeekTagIndex () const { return m_tag_count; } 00751 00757 #ifndef SWIG 00758 void SetFilename (char const * name); 00759 #endif 00760 00765 void SetFilename (__wchar_t const * name); 00766 #ifdef _MSC_VER 00767 void SetFilename (unsigned short const * name); 00768 #endif 00769 00773 TK_Status Read_Stream_File (); 00774 00780 #ifndef SWIG 00781 void SetNewFile (char const * name); 00782 #endif 00783 00788 void SetNewFile (__wchar_t const * name); 00789 #ifdef _MSC_VER 00790 void SetNewFile (unsigned short const * name); 00791 #endif 00792 00796 __wchar_t const * GetCurrentFile () const { return (__wchar_t const *)m_current_filename; } 00801 void GetCurrentFile (__wchar_t const *& filename) const { filename = (__wchar_t const *)m_current_filename; } 00802 #ifdef _MSC_VER 00803 void GetCurrentFile (unsigned short const *& filename) const { filename = (unsigned short const *)m_current_filename; } 00804 #endif 00805 00806 00807 00814 #ifndef SWIG 00815 TK_Status SelectFile (char const * name); 00816 #endif 00817 00823 TK_Status SelectFile (__wchar_t const * name); 00824 #ifdef _MSC_VER 00825 TK_Status SelectFile (unsigned short const * name); 00826 #endif 00827 00834 #ifndef SWIG 00835 virtual TK_Status OpenFile (char const * name, bool write = false); 00836 #endif 00837 00844 virtual TK_Status OpenFile (__wchar_t const * name, bool write = false); 00845 #ifdef _MSC_VER 00846 virtual TK_Status OpenFile (unsigned short const * name, bool write = false); 00847 #endif 00848 00852 virtual TK_Status CloseFile (); 00853 00863 virtual TK_Status ReadBuffer (char * buffer, int size, int & amount_read); 00864 00873 virtual TK_Status WriteBuffer (char * buffer, int size); 00874 00884 virtual TK_Status PositionFile (int offset); 00885 00894 virtual TK_Status GetFileSize (unsigned HLONG & size); 00895 00896 00908 virtual TK_Status LocateDictionary (); 00909 00920 virtual TK_Status LocateEntity (ID_Key key, int variant); 00921 00922 int GetFlags () const { return GetWriteFlags(); } 00923 void SetFlags (int flags) { SetWriteFlags(flags); } 00927 void SetWriteFlags (int flags) { m_write_flags = flags; } 00933 int GetWriteFlags (int mask = ~0) const { return m_write_flags & mask; } 00934 00936 void SetReadFlags (int flags) { m_read_flags = flags; } 00942 int GetReadFlags (int mask = ~0) const { return m_read_flags & mask; } 00943 00944 00945 int GetNumNormalBits () const { return m_num_normal_bits; } 00951 void SetNumNormalBits (int numbits) { m_num_normal_bits = (numbits<=72) ? numbits : 72; } 00952 00953 int GetNumVertexBits () const { return m_num_vertex_bits; } 00955 void SetNumVertexBits (int numbits) { m_num_vertex_bits = (numbits<=72) ? numbits : 72; } 00956 int GetNumParameterBits () const { return m_num_parameter_bits; } 00961 void SetNumParameterBits (int numbits) { m_num_parameter_bits = (numbits<=72) ? numbits : 72; } 00962 int GetNumColorBits () const { return m_num_color_bits; } 00963 void SetNumColorBits (int numbits) { m_num_color_bits = (numbits<=72) ? numbits : 72; } 00964 int GetNumIndexBits () const { return m_num_index_bits; } 00965 void SetNumIndexBits (int numbits) { m_num_index_bits = (numbits<=24) ? numbits : 24; } 00968 void SetJpegQuality (int quality = 75) { m_jpeg_quality = quality; } 00970 int GetJpegQuality () const { return m_jpeg_quality; } 00971 00972 int GetVersion () const { return m_file_version; } 00973 void SetReadVersion (int version) { m_file_version = version; m_header_comment_seen = true; } 00981 void SetTargetVersion (int version) { 00982 m_target_version = version; 00983 if ((m_target_version < 1) || (m_target_version > TK_File_Format_Version)) 00984 m_target_version = TK_File_Format_Version; 00985 } 00986 int GetTargetVersion () const { return m_target_version; } 00988 00989 unsigned int GetFileOffset () const { return m_offset; } 00991 void SetFileOffset (unsigned int offset) { m_offset = offset; } 00993 int Unused () const { return m_unused; } 00997 virtual TK_Status Error(char const * msg = 0) const; 00998 01000 char const *GetLogFile () const { return m_log_file; } 01002 void SetLogFile (char const * filename = 0); 01003 01005 bool GetLogging () const { return m_logging; } 01009 void SetLogging (bool setting) { m_logging = setting; } 01010 01012 unsigned int GetLoggingOptions (unsigned int mask = ~0) const 01013 { return m_logging_options & mask; } 01015 void SetLoggingOptions (unsigned int options = ~0) 01016 { m_logging_options = options; } 01017 01022 TK_Status OpenLogFile (char const * filename, char const * mode); 01024 #ifndef SWIG 01025 void LogEntry (char const * string) const; 01026 #endif 01027 01028 void LogEntry (__wchar_t const * string) const; 01029 #ifdef _MSC_VER 01030 void LogEntry (unsigned short const * string) const; 01031 #endif 01032 01033 void CloseLogFile (); 01034 01036 unsigned int NextOpcodeSequence () { return ++m_opcode_sequence; } 01038 void SetOpcodeSequence (unsigned int seq=0) { m_opcode_sequence = seq; } 01039 01041 bool HeaderCommentSeen() const { return m_header_comment_seen; } 01042 01044 TK_Progress_Callback GetProgressCallback () const { return m_progress_callback; } 01046 void SetProgressCallback (TK_Progress_Callback cb = 0) { m_progress_callback = cb; } 01047 01049 void * GetProgressValue () const { return m_progress_value; } 01051 void SetProgressValue (void * value) { m_progress_value = value; } 01052 01054 int GetBufferLimit () const { return m_buffer_limit; } 01056 void SetBufferLimit (int limit) { 01057 m_buffer_limit = (0 < limit && limit < TK_DEFAULT_BUFFER_SIZE) ? 01058 limit : TK_DEFAULT_BUFFER_SIZE; 01059 } 01060 01062 void SetLastKey (ID_Key key); 01064 TK_Status AppendLastKey (ID_Key key); 01066 void ClearLastKey (); 01068 TK_Status GetLastKey (ID_Key &key) const; 01069 01075 void SetDictionaryFormat (int format = 3, int options = TK_Dictionary_Bounding_Volumes) 01076 { m_dictionary_format = format; m_dictionary_options = options; } 01081 int GetDictionaryFormat () const { return m_dictionary_format; } 01086 int GetDictionaryOptions () const { return m_dictionary_options; } 01091 void SetDictionaryOffset (int offset) { m_dictionary_offset = offset; } 01096 int GetDictionaryOffset () const { return m_dictionary_offset; } 01101 void SetDictionarySize (int size) { m_dictionary_size = size; } 01106 int GetDictionarySize () const { return m_dictionary_size; } 01107 01112 void RecordPause (int offset); 01116 void ClearPauses () { m_num_pauses = 0; } 01121 int GetPauseCount () const { return m_num_pauses; } 01126 int const * GetPauseTable () const { return m_pause_table; } 01127 01129 void SetFirstPause (int offset) { if (GetPauseCount() == 0) RecordPause (offset); 01130 else m_pause_table[0] = offset; } 01132 int GetFirstPause () const { return (m_num_pauses > 0) ? m_pause_table[0] : 0; } 01133 01137 int GetPosition () const { return m_position; } 01138 01143 void SetWorldBounding (float const bbox[]); 01144 01150 void SetWorldBoundingBySphere (float const pt[], float radius); 01151 01153 float const * GetWorldBounding () const { return m_world_bounding; } 01154 01155 01161 #ifndef SWIG 01162 bool AddExternalReference (char const * ref, ID_Key context); 01163 #endif 01164 01169 bool AddExternalReference (__wchar_t const * ref, ID_Key context); 01170 #ifdef _MSC_VER 01171 bool AddExternalReference (unsigned short const * ref, ID_Key context); 01172 #endif 01173 01176 bool NextExternalReference (); 01180 wchar_t const * GetExternalReference () const { 01181 return (m_external_references != 0) ? (wchar_t const*)m_external_references->Reference() : 0; 01182 } 01186 void GetExternalReference (__wchar_t const *& exref) const { 01187 exref = (m_external_references != 0) ? (__wchar_t const *)m_external_references->Reference() : 0; 01188 } 01189 #ifdef _MSC_VER 01190 void GetExternalReference (unsigned short const *& exref) const { 01191 exref = (m_external_references != 0) ? (unsigned short const *)m_external_references->Reference() : 0; 01192 } 01193 #endif 01194 01198 ID_Key GetExternalReferenceContext () const { 01199 return (m_external_references != 0) ? m_external_references->m_context : -1; 01200 } 01201 01205 virtual bool MatchPreviousExRef () const { return false; } 01206 01210 void AddSegment (ID_Key key); 01214 ID_Key RemoveSegment (); 01218 ID_Key CurrentSegment () { return (m_active_segments != 0) ? m_active_segments->key() : -1; } 01220 void ResetQuantizationError() { m_quantization_error = 0; } 01224 void ReportQuantizationError(float error) { if (error > m_quantization_error) m_quantization_error = error; }; 01228 void ReportQuantizationError(int bits_per_sample, float const *bounding, int num_dimensions = 3); 01232 float GetQuantizationError() const { return m_quantization_error; } 01233 01237 TK_Status OpenGeometry () { 01238 if (m_geometry_open) 01239 return Error ("recursive geometry open"); 01240 m_geometry_open = true; 01241 return TK_Normal; 01242 } 01246 TK_Status CloseGeometry () { 01247 if (!m_geometry_open) 01248 return Error ("no geometry open"); 01249 m_geometry_open = false; 01250 return TK_Normal; 01251 } 01252 01256 bool GeometryIsOpen () const { return m_geometry_open; } 01257 01258 ID_Key RevisitKey () const { return m_revisit_working ? m_revisit_working->m_key : -1; } 01259 ID_Key RevisitOwner () const { return m_revisit_working ? m_revisit_working->m_owner : -1; } 01260 01261 protected: 01262 01263 #ifndef DOXYGEN_SHOULD_SKIP_THIS 01264 01265 virtual void FileDone() { ; }; 01266 01267 // normal data access for objects 01268 TK_Status read (char * b, int n) { return m_accumulator.read (b, n); } 01269 TK_Status write (char const * b, int n) { return m_accumulator.write (b, n); } 01270 TK_Status lookat (char & b) { return m_accumulator.lookat (b); } 01271 01272 // used by segment handlers to make sure we know which segment should be "open" 01273 void add_segment (ID_Key key) { AddSegment (key); } 01274 ID_Key remove_segment () { return RemoveSegment(); } 01275 01276 // used by renumber key, maybe by lookup functions (to be implemented...) 01278 void set_last_key (ID_Key key) { SetLastKey(key); } 01279 ID_Key context_key () const { return m_context_key; } 01280 void set_context_key (ID_Key key); 01282 ID_Key last_key () const { 01283 if(m_last_keys_used == 1) 01284 return m_last_keys[0]; 01285 else 01286 return -1; 01287 } 01288 01289 // keep track of visited segments (for things like include) 01290 void remember_item (ID_Key key); 01291 bool find_item (ID_Key key) const; 01292 01294 BBaseOpcodeHandler * opcode_handler (int index) const { return m_objects[index]; } 01295 01296 void adjust_written (int count) { m_objects_written += count; } 01297 01298 int pass () const { return m_pass; } 01299 01301 TK_Status revisit (unsigned char opcode, float priority, int lod=0); 01302 01304 void record_instance (ID_Key key, int variant, BBaseOpcodeHandler const * object, 01305 int val1, int val2 = 0, int val3 = 0); 01306 01308 bool find_instance (BBaseOpcodeHandler * object, int val1, int val2 = 0, int val3 = 0) const; 01309 01311 int position () const { return m_position; } 01312 void set_position (int pos) { m_position = pos; } 01313 void mark_position () { set_position (GeneratedSoFar()); } 01314 01319 virtual TK_Status tag (int variant); 01320 01321 void increase_nesting (int amount = 1) { m_nesting_level += amount; } 01322 void decrease_nesting (int amount = 1) { m_nesting_level -= amount; } 01323 01324 // utility 01325 TK_Status start_compression () { return m_accumulator.start_compression(); } 01326 TK_Status stop_compression () { return m_accumulator.stop_compression(true); } 01327 TK_Status start_decompression () { return m_accumulator.start_decompression(); } 01328 TK_Status stop_decompression (bool force = false) { return m_accumulator.stop_decompression(force); } 01329 virtual void empty_lists (); 01330 01331 #endif /* DOXYGEN_SHOULD_SKIP_THIS */ 01332 01333 }; 01334 01335 //TODO Documentation 01336 01337 #ifndef BSTREAM_DISABLE_ASCII 01338 class PutTab 01339 { 01340 public: 01341 PutTab(BStreamFileToolkit* tk) : m_tk(tk) 01342 { 01343 int n_tabs = m_tk->GetTabs(); 01344 m_tk->SetTabs(++n_tabs); 01345 } 01346 01347 ~PutTab() 01348 { 01349 int n_tabs = m_tk->GetTabs(); 01350 m_tk->SetTabs(--n_tabs); 01351 } 01352 01353 private: 01354 BStreamFileToolkit* m_tk; 01355 }; 01356 class Outdent 01357 { 01358 public: 01359 Outdent(BStreamFileToolkit* tk, int n_tabs = 1) : m_tk(tk) 01360 { 01361 int cur_tabs = m_tk->GetTabs(); 01362 if(cur_tabs >= n_tabs) 01363 { 01364 m_tabs = n_tabs; 01365 m_tk->SetTabs(cur_tabs-n_tabs); 01366 } 01367 else 01368 { 01369 m_tabs = cur_tabs; 01370 m_tk->SetTabs(0); 01371 } 01372 } 01373 01374 ~Outdent() 01375 { 01376 int cur_tabs = m_tk->GetTabs(); 01377 m_tk->SetTabs(cur_tabs+m_tabs); 01378 } 01379 01380 private: 01381 BStreamFileToolkit* m_tk; 01382 int m_tabs; 01383 }; 01384 01385 #endif //BSTREAM_DISABLE_ASCII 01386 01387 #endif //BBINFILETK_TOOLKIT