Alphabetical Class Index   Class Hierarchy   Compound Members   File Members   File List  

BStreamFileToolkit.h
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