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) { m_target_version = version; } 00982 int GetTargetVersion () const { return m_target_version; } 00984 00985 unsigned int GetFileOffset () const { return m_offset; } 00987 void SetFileOffset (unsigned int offset) { m_offset = offset; } 00989 int Unused () const { return m_unused; } 00993 virtual TK_Status Error(char const * msg = 0) const; 00994 00996 char const *GetLogFile () const { return m_log_file; } 00998 void SetLogFile (char const * filename = 0); 00999 01001 bool GetLogging () const { return m_logging; } 01005 void SetLogging (bool setting) { m_logging = setting; } 01006 01008 unsigned int GetLoggingOptions (unsigned int mask = ~0) const 01009 { return m_logging_options & mask; } 01011 void SetLoggingOptions (unsigned int options = ~0) 01012 { m_logging_options = options; } 01013 01018 TK_Status OpenLogFile (char const * filename, char const * mode); 01020 #ifndef SWIG 01021 void LogEntry (char const * string) const; 01022 #endif 01023 01024 void LogEntry (__wchar_t const * string) const; 01025 #ifdef _MSC_VER 01026 void LogEntry (unsigned short const * string) const; 01027 #endif 01028 01029 void CloseLogFile (); 01030 01032 unsigned int NextOpcodeSequence () { return ++m_opcode_sequence; } 01034 void SetOpcodeSequence (unsigned int seq=0) { m_opcode_sequence = seq; } 01035 01037 bool HeaderCommentSeen() const { return m_header_comment_seen; } 01038 01040 TK_Progress_Callback GetProgressCallback () const { return m_progress_callback; } 01042 void SetProgressCallback (TK_Progress_Callback cb = 0) { m_progress_callback = cb; } 01043 01045 void * GetProgressValue () const { return m_progress_value; } 01047 void SetProgressValue (void * value) { m_progress_value = value; } 01048 01050 int GetBufferLimit () const { return m_buffer_limit; } 01052 void SetBufferLimit (int limit) { 01053 m_buffer_limit = (0 < limit && limit < TK_DEFAULT_BUFFER_SIZE) ? 01054 limit : TK_DEFAULT_BUFFER_SIZE; 01055 } 01056 01058 void SetLastKey (ID_Key key); 01060 TK_Status AppendLastKey (ID_Key key); 01062 void ClearLastKey (); 01064 TK_Status GetLastKey (ID_Key &key) const; 01065 01071 void SetDictionaryFormat (int format = 3, int options = TK_Dictionary_Bounding_Volumes) 01072 { m_dictionary_format = format; m_dictionary_options = options; } 01077 int GetDictionaryFormat () const { return m_dictionary_format; } 01082 int GetDictionaryOptions () const { return m_dictionary_options; } 01087 void SetDictionaryOffset (int offset) { m_dictionary_offset = offset; } 01092 int GetDictionaryOffset () const { return m_dictionary_offset; } 01097 void SetDictionarySize (int size) { m_dictionary_size = size; } 01102 int GetDictionarySize () const { return m_dictionary_size; } 01103 01108 void RecordPause (int offset); 01112 void ClearPauses () { m_num_pauses = 0; } 01117 int GetPauseCount () const { return m_num_pauses; } 01122 int const * GetPauseTable () const { return m_pause_table; } 01123 01125 void SetFirstPause (int offset) { if (GetPauseCount() == 0) RecordPause (offset); 01126 else m_pause_table[0] = offset; } 01128 int GetFirstPause () const { return (m_num_pauses > 0) ? m_pause_table[0] : 0; } 01129 01133 int GetPosition () const { return m_position; } 01134 01139 void SetWorldBounding (float const bbox[]); 01140 01146 void SetWorldBoundingBySphere (float const pt[], float radius); 01147 01149 float const * GetWorldBounding () const { return m_world_bounding; } 01150 01151 01157 #ifndef SWIG 01158 bool AddExternalReference (char const * ref, ID_Key context); 01159 #endif 01160 01165 bool AddExternalReference (__wchar_t const * ref, ID_Key context); 01166 #ifdef _MSC_VER 01167 bool AddExternalReference (unsigned short const * ref, ID_Key context); 01168 #endif 01169 01172 bool NextExternalReference (); 01176 wchar_t const * GetExternalReference () const { 01177 return (m_external_references != 0) ? (wchar_t const*)m_external_references->Reference() : 0; 01178 } 01182 void GetExternalReference (__wchar_t const *& exref) const { 01183 exref = (m_external_references != 0) ? (__wchar_t const *)m_external_references->Reference() : 0; 01184 } 01185 #ifdef _MSC_VER 01186 void GetExternalReference (unsigned short const *& exref) const { 01187 exref = (m_external_references != 0) ? (unsigned short const *)m_external_references->Reference() : 0; 01188 } 01189 #endif 01190 01194 ID_Key GetExternalReferenceContext () const { 01195 return (m_external_references != 0) ? m_external_references->m_context : -1; 01196 } 01197 01201 virtual bool MatchPreviousExRef () const { return false; } 01202 01206 void AddSegment (ID_Key key); 01210 ID_Key RemoveSegment (); 01214 ID_Key CurrentSegment () { return (m_active_segments != 0) ? m_active_segments->key() : -1; } 01216 void ResetQuantizationError() { m_quantization_error = 0; } 01220 void ReportQuantizationError(float error) { if (error > m_quantization_error) m_quantization_error = error; }; 01224 void ReportQuantizationError(int bits_per_sample, float const *bounding, int num_dimensions = 3); 01228 float GetQuantizationError() const { return m_quantization_error; } 01229 01233 TK_Status OpenGeometry () { 01234 if (m_geometry_open) 01235 return Error ("recursive geometry open"); 01236 m_geometry_open = true; 01237 return TK_Normal; 01238 } 01242 TK_Status CloseGeometry () { 01243 if (!m_geometry_open) 01244 return Error ("no geometry open"); 01245 m_geometry_open = false; 01246 return TK_Normal; 01247 } 01248 01252 bool GeometryIsOpen () const { return m_geometry_open; } 01253 01254 ID_Key RevisitKey () const { return m_revisit_working ? m_revisit_working->m_key : -1; } 01255 ID_Key RevisitOwner () const { return m_revisit_working ? m_revisit_working->m_owner : -1; } 01256 01257 protected: 01258 01259 #ifndef DOXYGEN_SHOULD_SKIP_THIS 01260 01261 // normal data access for objects 01262 TK_Status read (char * b, int n) { return m_accumulator.read (b, n); } 01263 TK_Status write (char const * b, int n) { return m_accumulator.write (b, n); } 01264 TK_Status lookat (char & b) { return m_accumulator.lookat (b); } 01265 01266 // used by segment handlers to make sure we know which segment should be "open" 01267 void add_segment (ID_Key key) { AddSegment (key); } 01268 ID_Key remove_segment () { return RemoveSegment(); } 01269 01270 // used by renumber key, maybe by lookup functions (to be implemented...) 01272 void set_last_key (ID_Key key) { SetLastKey(key); } 01273 ID_Key context_key () const { return m_context_key; } 01274 void set_context_key (ID_Key key); 01276 ID_Key last_key () const { 01277 if(m_last_keys_used == 1) 01278 return m_last_keys[0]; 01279 else 01280 return -1; 01281 } 01282 01283 // keep track of visited segments (for things like include) 01284 void remember_item (ID_Key key); 01285 bool find_item (ID_Key key) const; 01286 01288 BBaseOpcodeHandler * opcode_handler (int index) const { return m_objects[index]; } 01289 01290 void adjust_written (int count) { m_objects_written += count; } 01291 01292 int pass () const { return m_pass; } 01293 01295 TK_Status revisit (unsigned char opcode, float priority, int lod=0); 01296 01298 void record_instance (ID_Key key, int variant, BBaseOpcodeHandler const * object, 01299 int val1, int val2 = 0, int val3 = 0); 01300 01302 bool find_instance (BBaseOpcodeHandler * object, int val1, int val2 = 0, int val3 = 0) const; 01303 01305 int position () const { return m_position; } 01306 void set_position (int pos) { m_position = pos; } 01307 void mark_position () { set_position (GeneratedSoFar()); } 01308 01313 virtual TK_Status tag (int variant); 01314 01315 void increase_nesting (int amount = 1) { m_nesting_level += amount; } 01316 void decrease_nesting (int amount = 1) { m_nesting_level -= amount; } 01317 01318 // utility 01319 TK_Status start_compression () { return m_accumulator.start_compression(); } 01320 TK_Status stop_compression () { return m_accumulator.stop_compression(true); } 01321 TK_Status start_decompression () { return m_accumulator.start_decompression(); } 01322 TK_Status stop_decompression (bool force = false) { return m_accumulator.stop_decompression(force); } 01323 virtual void empty_lists (); 01324 01325 #endif /* DOXYGEN_SHOULD_SKIP_THIS */ 01326 01327 }; 01328 01329 //TODO Documentation 01330 01331 #ifndef BSTREAM_DISABLE_ASCII 01332 class PutTab 01333 { 01334 public: 01335 PutTab(BStreamFileToolkit* tk) : m_tk(tk) 01336 { 01337 int n_tabs = m_tk->GetTabs(); 01338 m_tk->SetTabs(++n_tabs); 01339 } 01340 01341 ~PutTab() 01342 { 01343 int n_tabs = m_tk->GetTabs(); 01344 m_tk->SetTabs(--n_tabs); 01345 } 01346 01347 private: 01348 BStreamFileToolkit* m_tk; 01349 }; 01350 class Outdent 01351 { 01352 public: 01353 Outdent(BStreamFileToolkit* tk, int n_tabs = 1) : m_tk(tk) 01354 { 01355 int cur_tabs = m_tk->GetTabs(); 01356 if(cur_tabs >= n_tabs) 01357 { 01358 m_tabs = n_tabs; 01359 m_tk->SetTabs(cur_tabs-n_tabs); 01360 } 01361 else 01362 { 01363 m_tabs = cur_tabs; 01364 m_tk->SetTabs(0); 01365 } 01366 } 01367 01368 ~Outdent() 01369 { 01370 int cur_tabs = m_tk->GetTabs(); 01371 m_tk->SetTabs(cur_tabs+m_tabs); 01372 } 01373 01374 private: 01375 BStreamFileToolkit* m_tk; 01376 int m_tabs; 01377 }; 01378 01379 #endif //BSTREAM_DISABLE_ASCII 01380 01381 #endif //BBINFILETK_TOOLKIT