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: d06076a5a20de72afaff569c8097bbe87d2dd380 $ 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 00037 class BBINFILETK_API2 BControlledMemoryObject { 00038 public: 00039 void * operator new (size_t size); 00040 void operator delete (void * p); 00041 }; 00042 00043 class BBaseOpcodeHandler; 00044 00045 00046 #ifndef DOXYGEN_SHOULD_SKIP_THIS 00047 00048 /* 00049 Buffers data so basic handlers can deal with simple Get/Put calls of basic data types (and arrays of those types). 00050 Handles both reading and writing, ZLIB compressed or uncompressed. 00051 */ 00052 class BBINFILETK_API2 Internal_Data_Accumulator { 00053 private: 00054 char * m_pending_buffer; /*< The whole burrito. */ 00055 int m_pending_buffer_allocated; /*< How big the buffer is (so we know when to reallocate) */ 00056 char * m_pending_position; /*< Start of actual data to be processed.*/ 00057 int m_pending_size; /*< Size of actual data. */ 00058 00059 char * m_buffer_data; /*< The buffer shown to the user (i.e. passed to GenerateBuffer or ParseBuffer) */ 00060 int m_buffer_size; /*< The size of the user's buffer */ 00061 00062 int m_failed_size; /*< When a read fails because of insufficient data, how much space would have been required for success? */ 00063 00064 int m_generated; /*< How much has been written into the user's buffer (after considering compression). */ 00065 00066 struct z_stream_s * m_z_stream; /*< The control structure for ZLIB */ 00067 bool m_compressed; /*< are we in compressed mode? */ 00068 bool m_writing; /*< are we compressing or decompressing? */ 00069 int m_original_size; /*< size of buffer originally passed in */ 00070 00071 public: 00072 Internal_Data_Accumulator () : m_pending_buffer (0), m_pending_buffer_allocated (0), 00073 m_pending_position (0), m_pending_size (0), 00074 m_failed_size (0), m_generated (0), 00075 m_z_stream (0), m_compressed (false), m_writing (false) {} 00076 ~Internal_Data_Accumulator (); 00077 00078 void set_data (char * b, int s) alter { m_buffer_data = b; m_original_size = m_buffer_size = s; } 00079 void save () alter; 00080 TK_Status consume () alter; 00081 00082 TK_Status read (char alter * b, int s) alter; 00083 TK_Status write (char const * b, int s) alter; 00084 TK_Status lookat (char alter & b) alter; 00085 00086 int get_original_buffer_size(){return m_original_size; } 00087 00088 void restart () alter; 00089 void clean () alter; 00090 int unused () const { return m_buffer_size; } 00091 int generated () const { return m_generated; } 00092 00093 TK_Status start_compression () alter; 00094 TK_Status stop_compression (bool flush) alter; 00095 TK_Status start_decompression () alter; 00096 TK_Status stop_decompression (bool force) alter; 00097 bool compressed () const { return m_compressed; } 00098 00099 TK_Status error (char const * msg = 0) const; 00100 }; 00101 00102 00103 /* 00104 Provides index <-> key translation, plus storage of additional item-specific data, such as 00105 file offset and size and bounding volume. 00106 */ 00107 struct IT_Index_Key_Extra { 00108 int m_variants[8][2]; 00109 int m_options; 00110 float m_bounds[6]; 00111 }; 00112 00113 class BBINFILETK_API2 Internal_Translator { 00114 friend class TK_Dictionary; // note, dictionary writer tied closely to this implementation 00115 private: 00116 // array -- index to key is trivial 00117 int m_size; 00118 int m_used; 00119 00120 struct Index_Key_Pair { 00121 int m_index; 00122 ID_Key m_key; 00123 IT_Index_Key_Extra *m_extra; 00124 } * m_pairs; 00125 00126 enum Options { 00127 Bounds_Valid = 0x0001, 00128 00129 Extended = 0x0080 // reserved 00130 }; 00131 00132 // hash of key to locate potential indices for key to index lookup 00133 struct Hash_Block { 00134 Hash_Block * m_next; 00135 int m_used; 00136 int m_indices[32]; 00137 } * m_blocks[1024]; 00138 00139 00140 public: 00141 Internal_Translator () : m_size (0), m_used (0), m_pairs (0) { memset (m_blocks, 0, 1024*sizeof(void *)); } 00142 ~Internal_Translator (); 00143 00144 TK_Status add_pair (int index, ID_Key key) alter; 00145 TK_Status add_variant (ID_Key key, int variant, int value1, int value2 = 0) alter; 00146 TK_Status add_bounds (ID_Key key, float const * bounds) alter; 00147 TK_Status index_to_key (int index, ID_Key alter & key) const; 00148 TK_Status key_to_index (ID_Key key, int alter & index) const; 00149 TK_Status key_variant_offset (ID_Key key, int variant, 00150 int alter & offset, int alter & length, int alter & index) const; 00151 TK_Status key_bounds (ID_Key key, float alter * bounds) const; 00152 int used () const { return m_used; } 00153 00154 void clean () alter; 00155 00156 // older forms: 00157 TK_Status key_variant_offset (ID_Key key, int variant, int alter & offset) const { 00158 int length, index; 00159 return key_variant_offset (key, variant, offset, length, index); 00160 } 00161 TK_Status key_variant_offset (ID_Key key, int variant, int alter & offset, int alter & length) const { 00162 int index; 00163 return key_variant_offset (key, variant, offset, length, index); 00164 } 00165 00166 }; 00167 00168 00169 class BBINFILETK_API2 Internal_Key_Record { 00170 private: 00171 // hash of key to list of recorded segments 00172 struct Hash_Block { 00173 Hash_Block * m_next; 00174 int m_used; 00175 ID_Key m_keys[32]; 00176 } * m_blocks[1024]; 00177 00178 00179 public: 00180 Internal_Key_Record () { memset (m_blocks, 0, 1024*sizeof(void *)); } 00181 ~Internal_Key_Record (); 00182 00183 TK_Status add_key (ID_Key key) alter; 00184 TK_Status find_key (ID_Key key) const; 00185 00186 void clean () alter; 00187 }; 00188 00189 00190 00191 // control memory on these objects, not sure who might be creating/destroying them 00192 00193 class Internal_Segment_List : public BControlledMemoryObject { 00194 public: 00195 Internal_Segment_List * m_next; 00196 ID_Key m_key; 00197 00198 public: 00199 Internal_Segment_List (ID_Key k) : m_next (0), m_key (k) {} 00200 00201 ID_Key key () const { return m_key; } 00202 }; 00203 00204 class Internal_Revisit_Item : public BControlledMemoryObject { 00205 public: 00206 Internal_Revisit_Item * m_next; 00207 ID_Key m_key; 00208 ID_Key m_owner; 00209 int m_lod; 00210 float m_priority; 00211 char m_opcode; 00212 bool m_force_context; 00213 }; 00214 00215 00216 class Internal_ExRef_List : public BControlledMemoryObject { 00217 public: 00218 Internal_ExRef_List * m_next; 00219 Internal_ExRef_List * m_caller; 00220 __wchar_t * m_ref; 00221 __wchar_t * m_actual; 00222 ID_Key m_context; 00223 00224 public: 00225 Internal_ExRef_List (char const * ref, ID_Key context, Internal_ExRef_List * caller); 00226 Internal_ExRef_List (__wchar_t const * ref, ID_Key context, Internal_ExRef_List * caller); 00227 #ifdef _MSC_VER 00228 Internal_ExRef_List (unsigned short const * ref, ID_Key context, Internal_ExRef_List * caller); 00229 #endif 00230 ~Internal_ExRef_List (); 00231 00232 __wchar_t const * Reference () const { return m_ref; } 00233 __wchar_t const * Actual () const { return m_actual; } 00234 ID_Key Context () const { return m_context; } 00235 Internal_ExRef_List * Caller () const { return m_caller; } 00236 void SetActual (__wchar_t const * actual) alter; 00237 #ifdef _MSC_VER 00238 void SetActual (unsigned short const * actual) alter; 00239 #endif 00240 }; 00241 00242 00243 class BBINFILETK_API Recorded_Instance : public BControlledMemoryObject { 00244 public: 00245 Recorded_Instance * m_next; 00246 00247 ID_Key m_key; 00248 int m_variant; 00249 int m_values[3]; 00250 00251 float m_local_basis[16]; // matrix from our basis to identity 00252 int m_basis_indices[4]; 00253 float m_arbitrary_point[3]; 00254 int m_arbitrary_index; 00255 bool m_basis_valid; 00256 00257 unsigned char m_opcode; 00258 00259 #ifdef _DEBUG 00260 int m_times_used; 00261 #endif 00262 00263 Recorded_Instance (ID_Key key, int variant, unsigned char op, int val1, int val2, int val3) 00264 : m_next (0), m_key (key), m_variant (variant), m_basis_valid (false), m_opcode (op) { 00265 m_values[0] = val1; m_values[1] = val2; m_values[2] = val3; 00266 #ifdef _DEBUG 00267 m_times_used = 0; 00268 #endif 00269 } 00270 00271 bool basis_valid () const { return m_basis_valid; } 00272 bool generate_basis (int count, float const * points) alter; 00273 }; 00274 00275 class Internal_Segment_Processor; 00276 00277 /* 00278 Callback which can be used for reporting progress during writing/reading. 00279 During writing: 00280 so_far is number of "objects" written, expected is the number the toolkit will likely write. 00281 Note: the toolkit won't know about objects in pre/post-walk handlers or extra objects due to 00282 overloading the default classes, so "so_far" may exceed "expected" 00283 During reading: 00284 so_far is the number of bytes processed, expected is the file size. 00285 user_data allows the application to pass any necessary values through. 00286 returns a flag which indicates whether the processing should continue. 00287 */ 00288 typedef bool (*TK_Progress_Callback) (unsigned HLONG so_far, unsigned HLONG expected, void * user_data); 00289 00290 #endif /* DOXYGEN_SHOULD_SKIP_THIS */ 00291 00292 00293 00295 00328 class BBINFILETK_API2 BStreamFileToolkit : public BControlledMemoryObject { 00329 friend class BBaseOpcodeHandler; 00330 friend class TK_Default; 00331 friend class TK_Comment; 00332 friend class TK_Header; 00333 friend class TK_Compression; 00334 friend class TK_Dictionary; 00335 friend class Internal_Segment_Processor; 00336 friend class TK_Shell; 00337 00338 friend class TK_Tag; 00339 friend class TK_Instance; 00340 friend class HTK_Reference; 00341 protected: 00342 00343 #ifndef DOXYGEN_SHOULD_SKIP_THIS 00344 00345 Internal_Data_Accumulator m_accumulator; 00346 Internal_Translator m_translator; 00348 BBaseOpcodeHandler * m_objects[256]; 00349 BBaseOpcodeHandler * m_default_object; 00350 int m_prewalk_count; 00351 int m_postwalk_count; 00352 BBaseOpcodeHandler ** m_prewalk; 00353 BBaseOpcodeHandler ** m_postwalk; 00354 BBaseOpcodeHandler * m_current_object; 00355 Internal_Segment_List * m_active_segments; 00356 Internal_Key_Record m_visited_items; 00357 ID_Key m_context_key; 00358 ID_Key * m_last_keys; 00359 int m_last_keys_used; 00360 int m_last_keys_allocated; 00361 Internal_Revisit_Item * m_revisit; 00362 Internal_Revisit_Item * m_revisit_working; 00363 int m_stage; 00364 int m_substage; 00365 int m_pass; 00366 int m_tag_count; 00367 int m_position; 00368 unsigned int m_offset; 00369 int m_unused; 00370 int m_write_flags; 00371 int m_read_flags; 00372 int m_num_normal_bits; 00373 int m_num_vertex_bits; 00374 int m_num_parameter_bits; 00375 int m_num_color_bits; 00376 int m_num_index_bits; 00377 int m_file_version; 00378 int m_target_version; 00379 bool m_header_comment_seen; 00380 char * m_log_file; 00381 FILE * m_log_fp; 00382 bool m_logging; 00383 unsigned int m_logging_options; 00384 mutable unsigned int m_log_line_length; 00385 unsigned int m_opcode_sequence; 00386 unsigned int m_objects_written; 00387 TK_Progress_Callback m_progress_callback; 00388 void * m_progress_value; 00389 int m_buffer_limit; 00390 int m_nesting_level; 00391 int m_dictionary_format; 00392 int m_dictionary_options; 00393 int m_dictionary_size; 00394 int m_dictionary_offset; 00395 Recorded_Instance * m_instance_hash[256]; 00396 int m_jpeg_quality; 00397 int * m_pause_table; 00398 int m_pause_table_size; 00399 unsigned short m_num_pauses; 00400 float * m_world_bounding; 00401 Internal_ExRef_List * m_external_references; 00402 Internal_ExRef_List * m_external_ref_tail; 00403 Internal_ExRef_List * m_previous_exrefs; 00404 bool m_suppress_errors; 00406 __wchar_t ** m_file_names; 00407 int * m_file_indices; 00408 int m_file_count; 00409 int m_files_allocated; 00410 __wchar_t * m_current_filename; 00411 int m_index_base; 00412 float m_quantization_error; 00414 int m_save_write_flags; 00415 __wchar_t * m_wfilename; 00416 bool m_geometry_open; 00418 bool m_is_ascii; 00419 int m_num_tabs; 00421 /* Internal use. 00422 * A quick utility to verify that an array is in fact sorted. 00423 * FOR DEBUGGING ONLY 00424 */ 00425 bool issorted_revisit(Internal_Revisit_Item **array, int count); 00426 00431 void qsort_revisit(Internal_Revisit_Item **, Internal_Revisit_Item **); 00432 TK_Status sort_revisit(); 00433 00434 virtual void read_completed () alter; 00435 00436 bool add_exref (Internal_ExRef_List * exref); 00437 00438 #endif /* DOXYGEN_SHOULD_SKIP_THIS */ 00439 00440 00441 protected: 00442 00444 void * m_file; 00445 00446 public: 00447 00451 BStreamFileToolkit (); 00452 virtual ~BStreamFileToolkit (); 00453 00457 static bool SupportsAsciiMode() { 00458 #ifndef BSTREAM_DISABLE_ASCII 00459 return true; 00460 #else 00461 return false; 00462 #endif 00463 } 00464 00468 TK_Status SetAsciiMode(bool whether); 00469 00473 bool GetAsciiMode(); 00474 00475 void SetTabs(int); 00476 int GetTabs(); 00477 00483 static int ParseVersion (char const * block); 00484 00518 TK_Status ParseBuffer (char const * b, int s, TK_Status mode = TK_Normal) alter; 00519 00520 00526 TK_Status PrepareBuffer(char * b, int s) alter; 00527 00529 int CurrentBufferLength() {return m_accumulator.get_original_buffer_size() - 00530 m_accumulator.unused();} 00531 00537 virtual void ActivateContext (ID_Key key) { (void)key; } 00538 00544 virtual void DeactivateContext (ID_Key key) { (void)key; } 00545 00553 virtual void NewFileContext (ID_Key key) { (void)key; } 00554 00560 int GeneratedSoFar () const { return m_accumulator.generated(); } 00561 00566 unsigned int ObjectsSoFar () const { return m_objects_written; } 00567 00574 void SetOpcodeHandler (int which, BBaseOpcodeHandler * handler) alter; 00575 00583 void SetPrewalkHandler (BBaseOpcodeHandler * handler) alter; 00584 00585 00593 void SetPostwalkHandler (BBaseOpcodeHandler * handler) alter; 00594 00596 BBaseOpcodeHandler * GetOpcodeHandler (int which) const { return m_objects[which]; } 00597 00603 virtual void Restart () alter; 00604 00605 // access to index <-> key tranlation 00612 TK_Status IndexToKey (int index, ID_Key alter & key) const; 00613 00620 TK_Status KeyToIndex (ID_Key key, int alter & index) const; 00621 00628 TK_Status AddIndexKeyPair (int index, ID_Key key) alter 00629 { return m_translator.add_pair (index, key); } 00630 00639 TK_Status AddVariant (ID_Key key, int variant, int value1, int value2 = -1) alter 00640 { return m_translator.add_variant (key, variant, value1, value2); } 00641 00648 TK_Status AddBounds (ID_Key key, float const * bounds) alter 00649 { return m_translator.add_bounds (key, bounds); } 00650 00658 TK_Status GetOffset (ID_Key key, int variant, int alter & offset) const 00659 { return m_translator.key_variant_offset (key, variant, offset); } 00660 00669 TK_Status GetOffset (ID_Key key, int variant, int alter & offset, int alter & length) const 00670 { return m_translator.key_variant_offset (key, variant, offset, length); } 00671 00681 TK_Status GetOffset (ID_Key key, int variant, 00682 int alter & offset, int alter & length, __wchar_t const * alter & filename) const; 00683 #ifdef _MSC_VER 00684 TK_Status GetOffset (ID_Key key, int variant, 00685 int alter & offset, int alter & length, unsigned short const * alter & filename) const; 00686 #endif 00687 00693 TK_Status GetBounds (ID_Key key, float alter * bounds) const 00694 { return m_translator.key_bounds (key, bounds); } 00695 00700 int NextTagIndex () alter { return m_tag_count++; } 00705 int PeekTagIndex () const { return m_tag_count; } 00706 00712 #ifndef SWIG 00713 void SetFilename (char const * name) alter; 00714 #endif 00715 00720 void SetFilename (__wchar_t const * name) alter; 00721 #ifdef _MSC_VER 00722 void SetFilename (unsigned short const * name) alter; 00723 #endif 00724 00728 TK_Status Read_Stream_File (); 00729 00735 #ifndef SWIG 00736 void SetNewFile (char const * name) alter; 00737 #endif 00738 00743 void SetNewFile (__wchar_t const * name) alter; 00744 #ifdef _MSC_VER 00745 void SetNewFile (unsigned short const * name) alter; 00746 #endif 00747 00751 __wchar_t const * GetCurrentFile () const { return (__wchar_t const*)m_current_filename; } 00758 #ifndef SWIG 00759 TK_Status SelectFile (char const * name) alter; 00760 #endif 00761 00767 TK_Status SelectFile (__wchar_t const * name) alter; 00768 #ifdef _MSC_VER 00769 TK_Status SelectFile (unsigned short const * name) alter; 00770 #endif 00771 00778 #ifndef SWIG 00779 virtual TK_Status OpenFile (char const * name, bool write = false) alter; 00780 #endif 00781 00788 virtual TK_Status OpenFile (__wchar_t const * name, bool write = false) alter; 00789 #ifdef _MSC_VER 00790 virtual TK_Status OpenFile (unsigned short const * name, bool write = false) alter; 00791 #endif 00792 00796 virtual TK_Status CloseFile () alter; 00797 00807 virtual TK_Status ReadBuffer (char alter * buffer, int size, int alter & amount_read) alter; 00808 00817 virtual TK_Status WriteBuffer (char alter * buffer, int size) alter; 00818 00828 virtual TK_Status PositionFile (int offset) alter; 00829 00838 virtual TK_Status GetFileSize (unsigned HLONG & size) alter; 00839 00840 00852 virtual TK_Status LocateDictionary () alter; 00853 00864 virtual TK_Status LocateEntity (ID_Key key, int variant) alter; 00865 00866 int GetFlags () const { return GetWriteFlags(); } 00867 void SetFlags (int flags) alter { SetWriteFlags(flags); } 00871 void SetWriteFlags (int flags) alter { m_write_flags = flags; } 00877 int GetWriteFlags (int mask = ~0) const { return m_write_flags & mask; } 00878 00880 void SetReadFlags (int flags) alter { m_read_flags = flags; } 00886 int GetReadFlags (int mask = ~0) const { return m_read_flags & mask; } 00887 00888 00889 int GetNumNormalBits () const { return m_num_normal_bits; } 00895 void SetNumNormalBits (int numbits) alter { m_num_normal_bits = (numbits<=72) ? numbits : 72; } 00896 00897 int GetNumVertexBits () const { return m_num_vertex_bits; } 00899 void SetNumVertexBits (int numbits) alter { m_num_vertex_bits = (numbits<=72) ? numbits : 72; } 00900 int GetNumParameterBits () const { return m_num_parameter_bits; } 00905 void SetNumParameterBits (int numbits) alter { m_num_parameter_bits = (numbits<=72) ? numbits : 72; } 00906 int GetNumColorBits () const { return m_num_color_bits; } 00907 void SetNumColorBits (int numbits) alter { m_num_color_bits = (numbits<=72) ? numbits : 72; } 00908 int GetNumIndexBits () const { return m_num_index_bits; } 00909 void SetNumIndexBits (int numbits) alter { m_num_index_bits = (numbits<=24) ? numbits : 24; } 00912 void SetJpegQuality (int quality = 75) alter { m_jpeg_quality = quality; } 00914 int GetJpegQuality () const { return m_jpeg_quality; } 00915 00916 int GetVersion () const { return m_file_version; } 00917 void SetReadVersion (int version) { m_file_version = version; m_header_comment_seen = true; } 00925 void SetTargetVersion (int version) alter { m_target_version = version; } 00926 int GetTargetVersion () const { return m_target_version; } 00928 00929 unsigned int GetFileOffset () const { return m_offset; } 00931 void SetFileOffset (unsigned int offset) alter { m_offset = offset; } 00933 int Unused () const { return m_unused; } 00937 virtual TK_Status Error(char const * msg = 0) const; 00938 00940 char const *GetLogFile () const { return m_log_file; } 00942 void SetLogFile (char const * filename = 0) alter; 00943 00945 bool GetLogging () const { return m_logging; } 00949 void SetLogging (bool setting) alter { m_logging = setting; } 00950 00952 unsigned int GetLoggingOptions (unsigned int mask = ~0) const 00953 { return m_logging_options & mask; } 00955 void SetLoggingOptions (unsigned int options = ~0) alter 00956 { m_logging_options = options; } 00957 00962 TK_Status OpenLogFile (char const * filename, char const * mode) alter; 00964 #ifndef SWIG 00965 void LogEntry (char const * string) const; 00966 #endif 00967 00968 void LogEntry (__wchar_t const * string) const; 00969 #ifdef _MSC_VER 00970 void LogEntry (unsigned short const * string) const; 00971 #endif 00972 00973 void CloseLogFile () alter; 00974 00976 unsigned int NextOpcodeSequence () alter { return ++m_opcode_sequence; } 00978 void SetOpcodeSequence (unsigned int seq=0) alter { m_opcode_sequence = seq; } 00979 00981 bool HeaderCommentSeen() const { return m_header_comment_seen; } 00982 00984 TK_Progress_Callback GetProgressCallback () const { return m_progress_callback; } 00986 void SetProgressCallback (TK_Progress_Callback cb = 0) alter { m_progress_callback = cb; } 00987 00989 void * GetProgressValue () const { return m_progress_value; } 00991 void SetProgressValue (void * value) alter { m_progress_value = value; } 00992 00994 int GetBufferLimit () const { return m_buffer_limit; } 00996 void SetBufferLimit (int limit) alter { 00997 m_buffer_limit = (0 < limit && limit < TK_DEFAULT_BUFFER_SIZE) ? 00998 limit : TK_DEFAULT_BUFFER_SIZE; 00999 } 01000 01002 void SetLastKey (ID_Key key) alter; 01004 TK_Status AppendLastKey (ID_Key key) alter; 01006 void ClearLastKey () alter; 01008 TK_Status GetLastKey (ID_Key &key) const; 01009 01015 void SetDictionaryFormat (int format = 3, int options = TK_Dictionary_Bounding_Volumes) alter 01016 { m_dictionary_format = format; m_dictionary_options = options; } 01021 int GetDictionaryFormat () const { return m_dictionary_format; } 01026 int GetDictionaryOptions () const { return m_dictionary_options; } 01031 void SetDictionaryOffset (int offset) alter { m_dictionary_offset = offset; } 01036 int GetDictionaryOffset () const { return m_dictionary_offset; } 01041 void SetDictionarySize (int size) alter { m_dictionary_size = size; } 01046 int GetDictionarySize () const { return m_dictionary_size; } 01047 01052 void RecordPause (int offset) alter; 01056 void ClearPauses () alter { m_num_pauses = 0; } 01061 int GetPauseCount () const { return m_num_pauses; } 01066 int const * GetPauseTable () const { return m_pause_table; } 01067 01069 void SetFirstPause (int offset) alter { if (GetPauseCount() == 0) RecordPause (offset); 01070 else m_pause_table[0] = offset; } 01072 int GetFirstPause () const { return (m_num_pauses > 0) ? m_pause_table[0] : 0; } 01073 01077 int GetPosition () const { return m_position; } 01078 01083 void SetWorldBounding (float const *bbox); 01084 01090 void SetWorldBoundingBySphere (float const *pt, float radius); 01091 01093 float const * GetWorldBounding () const { return m_world_bounding; } 01094 01095 01101 #ifndef SWIG 01102 bool AddExternalReference (char const * ref, ID_Key context) alter; 01103 #endif 01104 01109 bool AddExternalReference (__wchar_t const * ref, ID_Key context) alter; 01110 #ifdef _MSC_VER 01111 bool AddExternalReference (unsigned short const * ref, ID_Key context) alter; 01112 #endif 01113 01116 bool NextExternalReference () alter; 01120 __wchar_t const *GetExternalReference () const { 01121 return (m_external_references != 0) ? (__wchar_t const*)m_external_references->Reference() : 0; 01122 } 01126 ID_Key GetExternalReferenceContext () const { 01127 return (m_external_references != 0) ? m_external_references->m_context : -1; 01128 } 01129 01133 virtual bool MatchPreviousExRef () const { return false; } 01134 01138 void AddSegment (ID_Key key) alter; 01142 ID_Key RemoveSegment () alter; 01146 ID_Key CurrentSegment () alter { return (m_active_segments != 0) ? m_active_segments->key() : -1; } 01148 void ResetQuantizationError() { m_quantization_error = 0; } 01152 void ReportQuantizationError(float error) { if (error > m_quantization_error) m_quantization_error = error; }; 01156 void ReportQuantizationError(int bits_per_sample, float const *bounding, int num_dimensions = 3); 01160 float GetQuantizationError() const { return m_quantization_error; } 01161 01165 TK_Status OpenGeometry () alter { 01166 if (m_geometry_open) 01167 return Error ("recursive geometry open"); 01168 m_geometry_open = true; 01169 return TK_Normal; 01170 } 01174 TK_Status CloseGeometry () alter { 01175 if (!m_geometry_open) 01176 return Error ("no geometry open"); 01177 m_geometry_open = false; 01178 return TK_Normal; 01179 } 01180 01184 bool GeometryIsOpen () const { return m_geometry_open; } 01185 01186 ID_Key RevisitKey () const { return m_revisit_working ? m_revisit_working->m_key : -1; } 01187 ID_Key RevisitOwner () const { return m_revisit_working ? m_revisit_working->m_owner : -1; } 01188 01189 protected: 01190 01191 #ifndef DOXYGEN_SHOULD_SKIP_THIS 01192 01193 // normal data access for objects 01194 TK_Status read (char alter * b, int n) alter { return m_accumulator.read (b, n); } 01195 TK_Status write (char const * b, int n) alter { return m_accumulator.write (b, n); } 01196 TK_Status lookat (char alter & b) alter { return m_accumulator.lookat (b); } 01197 01198 // used by segment handlers to make sure we know which segment should be "open" 01199 void add_segment (ID_Key key) alter { AddSegment (key); } 01200 ID_Key remove_segment () alter { return RemoveSegment(); } 01201 01202 // used by renumber key, maybe by lookup functions (to be implemented...) 01204 void set_last_key (ID_Key key) alter { SetLastKey(key); } 01205 ID_Key context_key () const { return m_context_key; } 01206 void set_context_key (ID_Key key) alter; 01208 ID_Key last_key () const { 01209 if(m_last_keys_used == 1) 01210 return m_last_keys[0]; 01211 else 01212 return -1; 01213 } 01214 01215 // keep track of visited segments (for things like include) 01216 void remember_item (ID_Key key) alter; 01217 bool find_item (ID_Key key) const; 01218 01220 BBaseOpcodeHandler alter * opcode_handler (int index) const { return m_objects[index]; } 01221 01222 void adjust_written (int count) alter { m_objects_written += count; } 01223 01224 int pass () const { return m_pass; } 01225 01227 TK_Status revisit (unsigned char opcode, float priority, int lod=0) alter; 01228 01230 void record_instance (ID_Key key, int variant, BBaseOpcodeHandler const * object, 01231 int val1, int val2 = 0, int val3 = 0) alter; 01232 01234 bool find_instance (BBaseOpcodeHandler * object, int val1, int val2 = 0, int val3 = 0) const; 01235 01237 int position () const { return m_position; } 01238 void set_position (int pos) alter { m_position = pos; } 01239 void mark_position () alter { set_position (GeneratedSoFar()); } 01240 01245 virtual TK_Status tag (int variant) alter; 01246 01247 void increase_nesting (int amount = 1) alter { m_nesting_level += amount; } 01248 void decrease_nesting (int amount = 1) alter { m_nesting_level -= amount; } 01249 01250 // utility 01251 TK_Status start_compression () alter { return m_accumulator.start_compression(); } 01252 TK_Status stop_compression () alter { return m_accumulator.stop_compression(true); } 01253 TK_Status start_decompression () alter { return m_accumulator.start_decompression(); } 01254 TK_Status stop_decompression (bool force = false) alter { return m_accumulator.stop_decompression(force); } 01255 virtual void empty_lists () alter; 01256 01257 #endif /* DOXYGEN_SHOULD_SKIP_THIS */ 01258 01259 }; 01260 01261 //TODO Documentation 01262 01263 #ifndef BSTREAM_DISABLE_ASCII 01264 class PutTab 01265 { 01266 public: 01267 PutTab(BStreamFileToolkit* tk) : m_tk(tk) 01268 { 01269 int n_tabs = m_tk->GetTabs(); 01270 m_tk->SetTabs(++n_tabs); 01271 } 01272 01273 ~PutTab() 01274 { 01275 int n_tabs = m_tk->GetTabs(); 01276 m_tk->SetTabs(--n_tabs); 01277 } 01278 01279 private: 01280 BStreamFileToolkit* m_tk; 01281 }; 01282 class Outdent 01283 { 01284 public: 01285 Outdent(BStreamFileToolkit* tk, int n_tabs = 1) : m_tk(tk) 01286 { 01287 int cur_tabs = m_tk->GetTabs(); 01288 if(cur_tabs >= n_tabs) 01289 { 01290 m_tabs = n_tabs; 01291 m_tk->SetTabs(cur_tabs-n_tabs); 01292 } 01293 else 01294 { 01295 m_tabs = cur_tabs; 01296 m_tk->SetTabs(0); 01297 } 01298 } 01299 01300 ~Outdent() 01301 { 01302 int cur_tabs = m_tk->GetTabs(); 01303 m_tk->SetTabs(cur_tabs+m_tabs); 01304 } 01305 01306 private: 01307 BStreamFileToolkit* m_tk; 01308 int m_tabs; 01309 }; 01310 01311 #endif //BSTREAM_DISABLE_ASCII 01312 01313 #endif //BBINFILETK_TOOLKIT