00001 // 00002 // Copyright (c) 2000 by Tech Soft 3D, LLC. 00003 // The information contained herein is confidential and proprietary to 00004 // Tech Soft 3D, LLC., and considered a trade secret as defined under 00005 // civil and criminal statutes. Tech Soft 3D shall pursue its civil 00006 // and criminal remedies in the event of unauthorized use or misappropriation 00007 // of its trade secrets. Use of this information by anyone other than 00008 // authorized employees of Tech Soft 3D, LLC. is granted only under a 00009 // written non-disclosure agreement, expressly prescribing the scope and 00010 // manner of such use. 00011 // 00012 // $Id: 615d353db07cbb39014a1f155e38118261b50982 $ 00013 // 00014 00015 #ifndef BBINFILETK_TOOLKIT 00016 #define BBINFILETK_TOOLKIT 00017 00018 #ifndef _MSC_VER 00019 # define __wchar_t wchar_t 00020 #else 00021 # ifdef _DEBUG 00022 # include <crtdbg.h> 00023 # endif 00024 #endif 00025 00026 #if defined(WIN64) || defined(_M_X64) || defined(_WIN64) 00027 # define HLONG __int64 00028 #else 00029 # define HLONG long 00030 #endif 00031 00032 #include "BStreamMemory.h" 00033 00039 class BBINFILETK_API2 BControlledMemoryObject { 00040 public: 00041 void * operator new (size_t size); 00042 void operator delete (void * p); 00043 }; 00044 00045 class BBaseOpcodeHandler; 00046 00047 00048 #ifndef DOXYGEN_SHOULD_SKIP_THIS 00049 00050 /* 00051 Buffers data so basic handlers can deal with simple Get/Put calls of basic data types (and arrays of those types). 00052 Handles both reading and writing, ZLIB compressed or uncompressed. 00053 */ 00054 class BBINFILETK_API2 Internal_Data_Accumulator 00055 #ifdef HPS_CORE_BUILD 00056 : public CMO 00057 #else 00058 : public BControlledMemoryObject 00059 #endif 00060 { 00061 private: 00062 char * m_pending_buffer; /*< The whole burrito. */ 00063 int m_pending_buffer_allocated; /*< How big the buffer is (so we know when to reallocate) */ 00064 char * m_pending_position; /*< Start of actual data to be processed.*/ 00065 int m_pending_size; /*< Size of actual data. */ 00066 00067 char * m_buffer_data; /*< The buffer shown to the user (i.e. passed to GenerateBuffer or ParseBuffer) */ 00068 int m_buffer_size; /*< The size of the user's buffer */ 00069 00070 int m_failed_size; /*< When a read fails because of insufficient data, how much space would have been required for success? */ 00071 00072 int m_generated; /*< How much has been written into the user's buffer (after considering compression). */ 00073 00074 struct z_stream_s * m_z_stream; /*< The control structure for ZLIB */ 00075 bool m_compressed; /*< are we in compressed mode? */ 00076 bool m_writing; /*< are we compressing or decompressing? */ 00077 int m_original_size; /*< size of buffer originally passed in */ 00078 00079 public: 00080 Internal_Data_Accumulator () : m_pending_buffer (0), m_pending_buffer_allocated (0), 00081 m_pending_position (0), m_pending_size (0), 00082 m_failed_size (0), m_generated (0), 00083 m_z_stream (0), m_compressed (false), m_writing (false) {} 00084 ~Internal_Data_Accumulator (); 00085 00086 void set_data (char * b, int s) { m_buffer_data = b; m_original_size = m_buffer_size = s; } 00087 void save (); 00088 TK_Status consume (); 00089 00090 TK_Status read (char * b, int s); 00091 TK_Status write (char const * b, int s); 00092 TK_Status lookat (char & b); 00093 00094 int get_original_buffer_size(){return m_original_size; } 00095 00096 void restart (); 00097 void clean (); 00098 int unused () const { return m_buffer_size; } 00099 int generated () const { return m_generated; } 00100 00101 TK_Status start_compression (); 00102 TK_Status stop_compression (bool flush); 00103 TK_Status start_decompression (); 00104 TK_Status stop_decompression (bool force); 00105 bool compressed () const { return m_compressed; } 00106 00107 TK_Status error (char const * msg = 0) const; 00108 }; 00109 00110 00111 /* 00112 Provides index <-> key translation, plus storage of additional item-specific data, such as 00113 file offset and size and bounding volume. 00114 */ 00115 struct IT_Index_Key_Extra { 00116 int m_variants[8][2]; 00117 int m_options; 00118 float m_bounds[6]; 00119 }; 00120 00121 class BBINFILETK_API2 Internal_Translator 00122 #ifdef HPS_CORE_BUILD 00123 : public CMO 00124 #else 00125 : public BControlledMemoryObject 00126 #endif 00127 { 00128 friend class TK_Dictionary; // note, dictionary writer tied closely to this implementation 00129 private: 00130 // array -- index to key is trivial 00131 int m_size; 00132 int m_used; 00133 00134 struct Index_Key_Pair { 00135 int m_index; 00136 ID_Key m_key; 00137 IT_Index_Key_Extra *m_extra; 00138 } * m_pairs; 00139 00140 enum Options { 00141 Bounds_Valid = 0x0001, 00142 00143 Extended = 0x0080 // reserved 00144 }; 00145 00146 // hash of key to locate potential indices for key to index lookup 00147 struct Hash_Block { 00148 Hash_Block * m_next; 00149 int m_used; 00150 int m_indices[32]; 00151 } * m_blocks[1024]; 00152 00153 00154 public: 00155 Internal_Translator () : m_size (0), m_used (0), m_pairs (0) { memset (m_blocks, 0, 1024*sizeof(void *)); } 00156 ~Internal_Translator (); 00157 00158 TK_Status add_pair (int index, ID_Key key); 00159 TK_Status add_variant (ID_Key key, int variant, int value1, int value2 = 0); 00160 TK_Status add_bounds (ID_Key key, float const * bounds); 00161 TK_Status index_to_key (int index, ID_Key & key) const; 00162 TK_Status key_to_index (ID_Key key, int & index) const; 00163 TK_Status key_variant_offset (ID_Key key, int variant, 00164 int & offset, int & length, int & index) const; 00165 TK_Status key_bounds (ID_Key key, float * bounds) const; 00166 int used () const { return m_used; } 00167 00168 void clean (); 00169 00170 // older forms: 00171 TK_Status key_variant_offset (ID_Key key, int variant, int & offset) const { 00172 int length, index; 00173 return key_variant_offset (key, variant, offset, length, index); 00174 } 00175 TK_Status key_variant_offset (ID_Key key, int variant, int & offset, int & length) const { 00176 int index; 00177 return key_variant_offset (key, variant, offset, length, index); 00178 } 00179 00180 }; 00181 00182 00183 class BBINFILETK_API2 Internal_Key_Record 00184 #ifdef HPS_CORE_BUILD 00185 : public CMO 00186 #else 00187 : public BControlledMemoryObject 00188 #endif 00189 { 00190 private: 00191 // hash of key to list of recorded segments 00192 struct Hash_Block { 00193 Hash_Block * m_next; 00194 int m_used; 00195 ID_Key m_keys[32]; 00196 } * m_blocks[1024]; 00197 00198 00199 public: 00200 Internal_Key_Record () { memset (m_blocks, 0, 1024*sizeof(void *)); } 00201 ~Internal_Key_Record (); 00202 00203 TK_Status add_key (ID_Key key); 00204 TK_Status find_key (ID_Key key) const; 00205 00206 void clean (); 00207 }; 00208 00209 00210 00211 // control memory on these objects, not sure who might be creating/destroying them 00212 00213 class Internal_Segment_List 00214 #ifdef HPS_CORE_BUILD 00215 : public CMO 00216 #else 00217 : public BControlledMemoryObject 00218 #endif 00219 { 00220 public: 00221 Internal_Segment_List * m_next; 00222 ID_Key m_key; 00223 00224 public: 00225 Internal_Segment_List (ID_Key k) : m_next (0), m_key (k) {} 00226 00227 ID_Key key () const { return m_key; } 00228 }; 00229 00230 class Internal_Revisit_Item 00231 #ifdef HPS_CORE_BUILD 00232 : public CMO 00233 #else 00234 : public BControlledMemoryObject 00235 #endif 00236 { 00237 public: 00238 Internal_Revisit_Item * m_next; 00239 ID_Key m_key; 00240 ID_Key m_owner; 00241 int m_lod; 00242 float m_priority; 00243 char m_opcode; 00244 bool m_force_context; 00245 }; 00246 00247 00248 class Internal_ExRef_List 00249 #ifdef HPS_CORE_BUILD 00250 : public CMO 00251 #else 00252 : public BControlledMemoryObject 00253 #endif 00254 { 00255 public: 00256 Internal_ExRef_List * m_next; 00257 Internal_ExRef_List * m_caller; 00258 __wchar_t * m_ref; 00259 __wchar_t * m_actual; 00260 ID_Key m_context; 00261 00262 public: 00263 Internal_ExRef_List (char const * ref, ID_Key context, Internal_ExRef_List * caller); 00264 Internal_ExRef_List (__wchar_t const * ref, ID_Key context, Internal_ExRef_List * caller); 00265 #ifdef _MSC_VER 00266 Internal_ExRef_List (unsigned short const * ref, ID_Key context, Internal_ExRef_List * caller); 00267 #endif 00268 ~Internal_ExRef_List (); 00269 00270 __wchar_t const * Reference () const { return m_ref; } 00271 __wchar_t const * Actual () const { return m_actual; } 00272 ID_Key Context () const { return m_context; } 00273 Internal_ExRef_List * Caller () const { return m_caller; } 00274 void SetActual (__wchar_t const * actual); 00275 #ifdef _MSC_VER 00276 void SetActual (unsigned short const * actual); 00277 #endif 00278 }; 00279 00280 00281 class BBINFILETK_API Recorded_Instance 00282 #ifdef HPS_CORE_BUILD 00283 : public CMO 00284 #else 00285 : public BControlledMemoryObject 00286 #endif 00287 { 00288 public: 00289 Recorded_Instance * m_next; 00290 00291 ID_Key m_key; 00292 int m_variant; 00293 int m_values[3]; 00294 00295 float m_local_basis[16]; // matrix from our basis to identity 00296 int m_basis_indices[4]; 00297 float m_arbitrary_point[3]; 00298 int m_arbitrary_index; 00299 bool m_basis_valid; 00300 00301 unsigned char m_opcode; 00302 00303 #ifdef _DEBUG 00304 int m_times_used; 00305 #endif 00306 00307 Recorded_Instance (ID_Key key, int variant, unsigned char op, int val1, int val2, int val3) 00308 : m_next (0), m_key (key), m_variant (variant), m_basis_valid (false), m_opcode (op) { 00309 m_values[0] = val1; m_values[1] = val2; m_values[2] = val3; 00310 #ifdef _DEBUG 00311 m_times_used = 0; 00312 #endif 00313 } 00314 00315 bool basis_valid () const { return m_basis_valid; } 00316 bool generate_basis (int count, float const * points); 00317 }; 00318 00319 class Internal_Segment_Processor; 00320 00321 /* 00322 Callback which can be used for reporting progress during writing/reading. 00323 During writing: 00324 so_far is number of "objects" written, expected is the number the toolkit will likely write. 00325 Note: the toolkit won't know about objects in pre/post-walk handlers or extra objects due to 00326 overloading the default classes, so "so_far" may exceed "expected" 00327 During reading: 00328 so_far is the number of bytes processed, expected is the file size. 00329 user_data allows the application to pass any necessary values through. 00330 returns a flag which indicates whether the processing should continue. 00331 */ 00332 typedef bool (*TK_Progress_Callback) (unsigned HLONG so_far, unsigned HLONG expected, void * user_data); 00333 00334 #endif /* DOXYGEN_SHOULD_SKIP_THIS */ 00335 00336 00337 00339 00372 class BBINFILETK_API2 BStreamFileToolkit 00373 #ifdef HPS_CORE_BUILD 00374 : public CMO 00375 #else 00376 : public BControlledMemoryObject 00377 #endif 00378 { 00379 friend class BBaseOpcodeHandler; 00380 friend class TK_Default; 00381 friend class TK_Comment; 00382 friend class TK_Header; 00383 friend class TK_Compression; 00384 friend class TK_Dictionary; 00385 friend class Internal_Segment_Processor; 00386 friend class TK_Shell; 00387 00388 friend class TK_Tag; 00389 friend class TK_Instance; 00390 friend class HTK_Reference; 00391 protected: 00392 00393 #ifndef DOXYGEN_SHOULD_SKIP_THIS 00394 00395 Internal_Data_Accumulator m_accumulator; 00396 Internal_Translator m_translator; 00398 BBaseOpcodeHandler * m_objects[256]; 00399 BBaseOpcodeHandler * m_default_object; 00400 int m_prewalk_count; 00401 int m_postwalk_count; 00402 BBaseOpcodeHandler ** m_prewalk; 00403 BBaseOpcodeHandler ** m_postwalk; 00404 BBaseOpcodeHandler * m_current_object; 00405 Internal_Segment_List * m_active_segments; 00406 Internal_Key_Record m_visited_items; 00407 ID_Key m_context_key; 00408 ID_Key * m_last_keys; 00409 int m_last_keys_used; 00410 int m_last_keys_allocated; 00411 Internal_Revisit_Item * m_revisit; 00412 Internal_Revisit_Item * m_revisit_working; 00413 int m_stage; 00414 int m_substage; 00415 int m_pass; 00416 int m_tag_count; 00417 int m_position; 00418 unsigned int m_offset; 00419 int m_unused; 00420 int m_write_flags; 00421 int m_read_flags; 00422 int m_num_normal_bits; 00423 int m_num_vertex_bits; 00424 int m_num_parameter_bits; 00425 int m_num_color_bits; 00426 int m_num_index_bits; 00427 int m_file_version; 00428 int m_target_version; 00429 bool m_header_comment_seen; 00430 char * m_log_file; 00431 FILE * m_log_fp; 00432 bool m_logging; 00433 unsigned int m_logging_options; 00434 mutable unsigned int m_log_line_length; 00435 unsigned int m_opcode_sequence; 00436 unsigned int m_objects_written; 00437 TK_Progress_Callback m_progress_callback; 00438 void * m_progress_value; 00439 int m_buffer_limit; 00440 int m_nesting_level; 00441 int m_dictionary_format; 00442 int m_dictionary_options; 00443 int m_dictionary_size; 00444 int m_dictionary_offset; 00445 Recorded_Instance * m_instance_hash[256]; 00446 int m_jpeg_quality; 00447 int * m_pause_table; 00448 int m_pause_table_size; 00449 unsigned short m_num_pauses; 00450 float * m_world_bounding; 00451 Internal_ExRef_List * m_external_references; 00452 Internal_ExRef_List * m_external_ref_tail; 00453 Internal_ExRef_List * m_previous_exrefs; 00454 bool m_suppress_errors; 00456 __wchar_t ** m_file_names; 00457 int * m_file_indices; 00458 int m_file_count; 00459 int m_files_allocated; 00460 __wchar_t * m_current_filename; 00461 int m_index_base; 00462 float m_quantization_error; 00464 int m_save_write_flags; 00465 __wchar_t * m_wfilename; 00466 bool m_geometry_open; 00468 bool m_is_ascii; 00469 int m_num_tabs; 00471 /* Internal use. 00472 * A quick utility to verify that an array is in fact sorted. 00473 * FOR DEBUGGING ONLY 00474 */ 00475 bool issorted_revisit(Internal_Revisit_Item **array, int count); 00476 00481 void qsort_revisit(Internal_Revisit_Item **, Internal_Revisit_Item **); 00482 TK_Status sort_revisit(); 00483 00484 virtual void read_completed (); 00485 00486 bool add_exref (Internal_ExRef_List * exref); 00487 00488 #endif /* DOXYGEN_SHOULD_SKIP_THIS */ 00489 00490 00491 protected: 00492 00494 void * m_file; 00495 00496 public: 00497 00501 BStreamFileToolkit (); 00502 virtual ~BStreamFileToolkit (); 00503 00507 static bool SupportsAsciiMode() { 00508 #ifndef BSTREAM_DISABLE_ASCII 00509 return true; 00510 #else 00511 return false; 00512 #endif 00513 } 00514 00518 TK_Status SetAsciiMode(bool whether); 00519 00523 bool GetAsciiMode(); 00524 00525 void SetTabs(int); 00526 int GetTabs(); 00527 00533 static int ParseVersion (char const * block); 00534 00568 TK_Status ParseBuffer (char const * b, int s, TK_Status mode = TK_Normal); 00569 00570 00576 TK_Status PrepareBuffer(char * b, int s); 00577 00579 int CurrentBufferLength() {return m_accumulator.get_original_buffer_size() - 00580 m_accumulator.unused();} 00581 00587 virtual void ActivateContext (ID_Key key) { (void)key; } 00588 00594 virtual void DeactivateContext (ID_Key key) { (void)key; } 00595 00603 virtual void NewFileContext (ID_Key key) { (void)key; } 00604 00610 int GeneratedSoFar () const { return m_accumulator.generated(); } 00611 00616 unsigned int ObjectsSoFar () const { return m_objects_written; } 00617 00624 void SetOpcodeHandler (int which, BBaseOpcodeHandler * handler); 00625 00633 void SetPrewalkHandler (BBaseOpcodeHandler * handler); 00634 00635 00643 void SetPostwalkHandler (BBaseOpcodeHandler * handler); 00644 00646 BBaseOpcodeHandler * GetOpcodeHandler (int which) const { return m_objects[which]; } 00647 00653 virtual void Restart (); 00654 00655 // access to index <-> key tranlation 00662 TK_Status IndexToKey (int index, ID_Key & key) const; 00663 00670 TK_Status KeyToIndex (ID_Key key, int & index) const; 00671 00678 TK_Status AddIndexKeyPair (int index, ID_Key key) 00679 { return m_translator.add_pair (index, key); } 00680 00689 TK_Status AddVariant (ID_Key key, int variant, int value1, int value2 = -1) 00690 { return m_translator.add_variant (key, variant, value1, value2); } 00691 00698 TK_Status AddBounds (ID_Key key, float const * bounds) 00699 { return m_translator.add_bounds (key, bounds); } 00700 00708 TK_Status GetOffset (ID_Key key, int variant, int & offset) const 00709 { return m_translator.key_variant_offset (key, variant, offset); } 00710 00719 TK_Status GetOffset (ID_Key key, int variant, int & offset, int & length) const 00720 { return m_translator.key_variant_offset (key, variant, offset, length); } 00721 00731 TK_Status GetOffset (ID_Key key, int variant, 00732 int & offset, int & length, __wchar_t const *& filename) const; 00733 #ifdef _MSC_VER 00734 TK_Status GetOffset (ID_Key key, int variant, 00735 int & offset, int & length, unsigned short const *& filename) const; 00736 #endif 00737 00743 TK_Status GetBounds (ID_Key key, float * bounds) const 00744 { return m_translator.key_bounds (key, bounds); } 00745 00750 int NextTagIndex () { return m_tag_count++; } 00755 int PeekTagIndex () const { return m_tag_count; } 00756 00762 #ifndef SWIG 00763 void SetFilename (char const * name); 00764 #endif 00765 00770 void SetFilename (__wchar_t const * name); 00771 #ifdef _MSC_VER 00772 void SetFilename (unsigned short const * name); 00773 #endif 00774 00778 TK_Status Read_Stream_File (); 00779 00785 #ifndef SWIG 00786 void SetNewFile (char const * name); 00787 #endif 00788 00793 void SetNewFile (__wchar_t const * name); 00794 #ifdef _MSC_VER 00795 void SetNewFile (unsigned short const * name); 00796 #endif 00797 00801 __wchar_t const * GetCurrentFile () const { return (__wchar_t const*)m_current_filename; } 00808 #ifndef SWIG 00809 TK_Status SelectFile (char const * name); 00810 #endif 00811 00817 TK_Status SelectFile (__wchar_t const * name); 00818 #ifdef _MSC_VER 00819 TK_Status SelectFile (unsigned short const * name); 00820 #endif 00821 00828 #ifndef SWIG 00829 virtual TK_Status OpenFile (char const * name, bool write = false); 00830 #endif 00831 00838 virtual TK_Status OpenFile (__wchar_t const * name, bool write = false); 00839 #ifdef _MSC_VER 00840 virtual TK_Status OpenFile (unsigned short const * name, bool write = false); 00841 #endif 00842 00846 virtual TK_Status CloseFile (); 00847 00857 virtual TK_Status ReadBuffer (char * buffer, int size, int & amount_read); 00858 00867 virtual TK_Status WriteBuffer (char * buffer, int size); 00868 00878 virtual TK_Status PositionFile (int offset); 00879 00888 virtual TK_Status GetFileSize (unsigned HLONG & size); 00889 00890 00902 virtual TK_Status LocateDictionary (); 00903 00914 virtual TK_Status LocateEntity (ID_Key key, int variant); 00915 00916 int GetFlags () const { return GetWriteFlags(); } 00917 void SetFlags (int flags) { SetWriteFlags(flags); } 00921 void SetWriteFlags (int flags) { m_write_flags = flags; } 00927 int GetWriteFlags (int mask = ~0) const { return m_write_flags & mask; } 00928 00930 void SetReadFlags (int flags) { m_read_flags = flags; } 00936 int GetReadFlags (int mask = ~0) const { return m_read_flags & mask; } 00937 00938 00939 int GetNumNormalBits () const { return m_num_normal_bits; } 00945 void SetNumNormalBits (int numbits) { m_num_normal_bits = (numbits<=72) ? numbits : 72; } 00946 00947 int GetNumVertexBits () const { return m_num_vertex_bits; } 00949 void SetNumVertexBits (int numbits) { m_num_vertex_bits = (numbits<=72) ? numbits : 72; } 00950 int GetNumParameterBits () const { return m_num_parameter_bits; } 00955 void SetNumParameterBits (int numbits) { m_num_parameter_bits = (numbits<=72) ? numbits : 72; } 00956 int GetNumColorBits () const { return m_num_color_bits; } 00957 void SetNumColorBits (int numbits) { m_num_color_bits = (numbits<=72) ? numbits : 72; } 00958 int GetNumIndexBits () const { return m_num_index_bits; } 00959 void SetNumIndexBits (int numbits) { m_num_index_bits = (numbits<=24) ? numbits : 24; } 00962 void SetJpegQuality (int quality = 75) { m_jpeg_quality = quality; } 00964 int GetJpegQuality () const { return m_jpeg_quality; } 00965 00966 int GetVersion () const { return m_file_version; } 00967 void SetReadVersion (int version) { m_file_version = version; m_header_comment_seen = true; } 00975 void SetTargetVersion (int version) { m_target_version = version; } 00976 int GetTargetVersion () const { return m_target_version; } 00978 00979 unsigned int GetFileOffset () const { return m_offset; } 00981 void SetFileOffset (unsigned int offset) { m_offset = offset; } 00983 int Unused () const { return m_unused; } 00987 virtual TK_Status Error(char const * msg = 0) const; 00988 00990 char const *GetLogFile () const { return m_log_file; } 00992 void SetLogFile (char const * filename = 0); 00993 00995 bool GetLogging () const { return m_logging; } 00999 void SetLogging (bool setting) { m_logging = setting; } 01000 01002 unsigned int GetLoggingOptions (unsigned int mask = ~0) const 01003 { return m_logging_options & mask; } 01005 void SetLoggingOptions (unsigned int options = ~0) 01006 { m_logging_options = options; } 01007 01012 TK_Status OpenLogFile (char const * filename, char const * mode); 01014 #ifndef SWIG 01015 void LogEntry (char const * string) const; 01016 #endif 01017 01018 void LogEntry (__wchar_t const * string) const; 01019 #ifdef _MSC_VER 01020 void LogEntry (unsigned short const * string) const; 01021 #endif 01022 01023 void CloseLogFile (); 01024 01026 unsigned int NextOpcodeSequence () { return ++m_opcode_sequence; } 01028 void SetOpcodeSequence (unsigned int seq=0) { m_opcode_sequence = seq; } 01029 01031 bool HeaderCommentSeen() const { return m_header_comment_seen; } 01032 01034 TK_Progress_Callback GetProgressCallback () const { return m_progress_callback; } 01036 void SetProgressCallback (TK_Progress_Callback cb = 0) { m_progress_callback = cb; } 01037 01039 void * GetProgressValue () const { return m_progress_value; } 01041 void SetProgressValue (void * value) { m_progress_value = value; } 01042 01044 int GetBufferLimit () const { return m_buffer_limit; } 01046 void SetBufferLimit (int limit) { 01047 m_buffer_limit = (0 < limit && limit < TK_DEFAULT_BUFFER_SIZE) ? 01048 limit : TK_DEFAULT_BUFFER_SIZE; 01049 } 01050 01052 void SetLastKey (ID_Key key); 01054 TK_Status AppendLastKey (ID_Key key); 01056 void ClearLastKey (); 01058 TK_Status GetLastKey (ID_Key &key) const; 01059 01065 void SetDictionaryFormat (int format = 3, int options = TK_Dictionary_Bounding_Volumes) 01066 { m_dictionary_format = format; m_dictionary_options = options; } 01071 int GetDictionaryFormat () const { return m_dictionary_format; } 01076 int GetDictionaryOptions () const { return m_dictionary_options; } 01081 void SetDictionaryOffset (int offset) { m_dictionary_offset = offset; } 01086 int GetDictionaryOffset () const { return m_dictionary_offset; } 01091 void SetDictionarySize (int size) { m_dictionary_size = size; } 01096 int GetDictionarySize () const { return m_dictionary_size; } 01097 01102 void RecordPause (int offset); 01106 void ClearPauses () { m_num_pauses = 0; } 01111 int GetPauseCount () const { return m_num_pauses; } 01116 int const * GetPauseTable () const { return m_pause_table; } 01117 01119 void SetFirstPause (int offset) { if (GetPauseCount() == 0) RecordPause (offset); 01120 else m_pause_table[0] = offset; } 01122 int GetFirstPause () const { return (m_num_pauses > 0) ? m_pause_table[0] : 0; } 01123 01127 int GetPosition () const { return m_position; } 01128 01133 void SetWorldBounding (float const *bbox); 01134 01140 void SetWorldBoundingBySphere (float const *pt, float radius); 01141 01143 float const * GetWorldBounding () const { return m_world_bounding; } 01144 01145 01151 #ifndef SWIG 01152 bool AddExternalReference (char const * ref, ID_Key context); 01153 #endif 01154 01159 bool AddExternalReference (__wchar_t const * ref, ID_Key context); 01160 #ifdef _MSC_VER 01161 bool AddExternalReference (unsigned short const * ref, ID_Key context); 01162 #endif 01163 01166 bool NextExternalReference (); 01170 __wchar_t const *GetExternalReference () const { 01171 return (m_external_references != 0) ? (__wchar_t const*)m_external_references->Reference() : 0; 01172 } 01176 ID_Key GetExternalReferenceContext () const { 01177 return (m_external_references != 0) ? m_external_references->m_context : -1; 01178 } 01179 01183 virtual bool MatchPreviousExRef () const { return false; } 01184 01188 void AddSegment (ID_Key key); 01192 ID_Key RemoveSegment (); 01196 ID_Key CurrentSegment () { return (m_active_segments != 0) ? m_active_segments->key() : -1; } 01198 void ResetQuantizationError() { m_quantization_error = 0; } 01202 void ReportQuantizationError(float error) { if (error > m_quantization_error) m_quantization_error = error; }; 01206 void ReportQuantizationError(int bits_per_sample, float const *bounding, int num_dimensions = 3); 01210 float GetQuantizationError() const { return m_quantization_error; } 01211 01215 TK_Status OpenGeometry () { 01216 if (m_geometry_open) 01217 return Error ("recursive geometry open"); 01218 m_geometry_open = true; 01219 return TK_Normal; 01220 } 01224 TK_Status CloseGeometry () { 01225 if (!m_geometry_open) 01226 return Error ("no geometry open"); 01227 m_geometry_open = false; 01228 return TK_Normal; 01229 } 01230 01234 bool GeometryIsOpen () const { return m_geometry_open; } 01235 01236 ID_Key RevisitKey () const { return m_revisit_working ? m_revisit_working->m_key : -1; } 01237 ID_Key RevisitOwner () const { return m_revisit_working ? m_revisit_working->m_owner : -1; } 01238 01239 protected: 01240 01241 #ifndef DOXYGEN_SHOULD_SKIP_THIS 01242 01243 // normal data access for objects 01244 TK_Status read (char * b, int n) { return m_accumulator.read (b, n); } 01245 TK_Status write (char const * b, int n) { return m_accumulator.write (b, n); } 01246 TK_Status lookat (char & b) { return m_accumulator.lookat (b); } 01247 01248 // used by segment handlers to make sure we know which segment should be "open" 01249 void add_segment (ID_Key key) { AddSegment (key); } 01250 ID_Key remove_segment () { return RemoveSegment(); } 01251 01252 // used by renumber key, maybe by lookup functions (to be implemented...) 01254 void set_last_key (ID_Key key) { SetLastKey(key); } 01255 ID_Key context_key () const { return m_context_key; } 01256 void set_context_key (ID_Key key); 01258 ID_Key last_key () const { 01259 if(m_last_keys_used == 1) 01260 return m_last_keys[0]; 01261 else 01262 return -1; 01263 } 01264 01265 // keep track of visited segments (for things like include) 01266 void remember_item (ID_Key key); 01267 bool find_item (ID_Key key) const; 01268 01270 BBaseOpcodeHandler * opcode_handler (int index) const { return m_objects[index]; } 01271 01272 void adjust_written (int count) { m_objects_written += count; } 01273 01274 int pass () const { return m_pass; } 01275 01277 TK_Status revisit (unsigned char opcode, float priority, int lod=0); 01278 01280 void record_instance (ID_Key key, int variant, BBaseOpcodeHandler const * object, 01281 int val1, int val2 = 0, int val3 = 0); 01282 01284 bool find_instance (BBaseOpcodeHandler * object, int val1, int val2 = 0, int val3 = 0) const; 01285 01287 int position () const { return m_position; } 01288 void set_position (int pos) { m_position = pos; } 01289 void mark_position () { set_position (GeneratedSoFar()); } 01290 01295 virtual TK_Status tag (int variant); 01296 01297 void increase_nesting (int amount = 1) { m_nesting_level += amount; } 01298 void decrease_nesting (int amount = 1) { m_nesting_level -= amount; } 01299 01300 // utility 01301 TK_Status start_compression () { return m_accumulator.start_compression(); } 01302 TK_Status stop_compression () { return m_accumulator.stop_compression(true); } 01303 TK_Status start_decompression () { return m_accumulator.start_decompression(); } 01304 TK_Status stop_decompression (bool force = false) { return m_accumulator.stop_decompression(force); } 01305 virtual void empty_lists (); 01306 01307 #endif /* DOXYGEN_SHOULD_SKIP_THIS */ 01308 01309 }; 01310 01311 //TODO Documentation 01312 01313 #ifndef BSTREAM_DISABLE_ASCII 01314 class PutTab 01315 { 01316 public: 01317 PutTab(BStreamFileToolkit* tk) : m_tk(tk) 01318 { 01319 int n_tabs = m_tk->GetTabs(); 01320 m_tk->SetTabs(++n_tabs); 01321 } 01322 01323 ~PutTab() 01324 { 01325 int n_tabs = m_tk->GetTabs(); 01326 m_tk->SetTabs(--n_tabs); 01327 } 01328 01329 private: 01330 BStreamFileToolkit* m_tk; 01331 }; 01332 class Outdent 01333 { 01334 public: 01335 Outdent(BStreamFileToolkit* tk, int n_tabs = 1) : m_tk(tk) 01336 { 01337 int cur_tabs = m_tk->GetTabs(); 01338 if(cur_tabs >= n_tabs) 01339 { 01340 m_tabs = n_tabs; 01341 m_tk->SetTabs(cur_tabs-n_tabs); 01342 } 01343 else 01344 { 01345 m_tabs = cur_tabs; 01346 m_tk->SetTabs(0); 01347 } 01348 } 01349 01350 ~Outdent() 01351 { 01352 int cur_tabs = m_tk->GetTabs(); 01353 m_tk->SetTabs(cur_tabs+m_tabs); 01354 } 01355 01356 private: 01357 BStreamFileToolkit* m_tk; 01358 int m_tabs; 01359 }; 01360 01361 #endif //BSTREAM_DISABLE_ASCII 01362 01363 #endif //BBINFILETK_TOOLKIT