SimpleW3DStreamProcessor/SimpleW3DStreamProcessor.cpp

This is an example of how to override W3D stream graphics (DWFToolkit::DWFEModelSection) op-code handlers and extract text (TK_Comment, TK_Text) data from the stream, examine shells (TK_Shell) and custom user data (TK_User_Data).

00001 // SimpleEnumReader.cpp : Defines the entry point for the console application.
00002 //
00003 
00004 #include "stdafx.h"
00005 
00006 using namespace std;
00007 using namespace DWFCore;
00008 using namespace DWFToolkit;
00009 
00010 
00011 class CommentHandler : public TK_Comment
00012 {
00013 public:
00014     CommentHandler() : TK_Comment() {;}
00015     virtual ~CommentHandler() {;}
00016 
00017     TK_Status Execute( BStreamFileToolkit& rW3DParser )
00018     {
00019         TK_Status eStatus = TK_Comment::Execute( rW3DParser );
00020         if (eStatus == TK_Normal)
00021         {
00022             cout << "Found Comment: ";
00023             cout << this->GetComment() << endl;
00024         }
00025 
00026         return eStatus;
00027     }
00028 };
00029 
00030 class TextOpcodeHandler : public TK_Text
00031 {
00032 public:
00033     TextOpcodeHandler() : TK_Text( TKE_Text ) {;}
00034     virtual ~TextOpcodeHandler() {;}
00035 
00036     TK_Status Execute( BStreamFileToolkit& rW3DParser )
00037     {
00038         TK_Status eStatus = TK_Text::Execute( rW3DParser );
00039         if (eStatus == TK_Normal)
00040         {
00041             cout << "Found Text: ";
00042             cout << this->GetString() << endl;
00043 
00044             FILE* fp = fopen( "text.txt", "a+" );
00045             fprintf( fp, "%s\n", this->GetString() );
00046             fclose( fp );
00047         }
00048 
00049         return eStatus;
00050     }
00051 };
00052 
00053 class TextWithEncodingOpcodeHandler : public TK_Text
00054 {
00055 
00056 public:
00057     TextWithEncodingOpcodeHandler() : TK_Text( TKE_Text_With_Encoding ) {;}
00058     virtual ~TextWithEncodingOpcodeHandler() {;}
00059 
00060     TK_Status Execute( BStreamFileToolkit& rW3DParser )
00061     {
00062         TK_Status eStatus = TK_Text::Execute( rW3DParser );
00063         if (eStatus == TK_Normal)
00064         {
00065             if (this->GetEncoding() == TKO_Enc_Unicode)
00066             {
00067                 wcout << "Found Unicode Text: ";
00068                 wcout << (const wchar_t*)(this->GetString()) << endl;
00069 
00070                 DWFString text( (const wchar_t*)(this->GetString()) );
00071                 char* utf8;
00072                 text.getUTF8( &utf8 );
00073 
00074                 FILE* fp = fopen( "text.txt", "a+" );
00075                 fprintf( fp, "%s\n", utf8 );
00076                 fclose( fp );
00077 
00078                 delete utf8;
00079 
00080             }
00081         }
00082 
00083         return eStatus;
00084     }
00085 };
00086 
00087 class ShellHandler : public TK_Shell
00088 {
00089 public:
00090     ShellHandler() : TK_Shell() {;}
00091     virtual ~ShellHandler() {;}
00092 
00093     TK_Status Execute( BStreamFileToolkit& parser )
00094     {
00095         TK_Status status = TK_Shell::Execute(parser);
00096         if (status == TK_Normal)
00097         {
00098             ;
00099         }
00100         return status;
00101     }
00102     TK_Status Clone (BStreamFileToolkit & tk, BBaseOpcodeHandler **newhandler) const 
00103     {
00104         tk;
00105         *newhandler = new ShellHandler;
00106         return TK_Normal;
00107     }
00108 };
00109 
00110 class StartUserDataHandler : public TK_User_Data
00111 {
00112     FILE* _fp;
00113     int _stage;
00114     int _bytes;
00115 
00116 public:
00117     StartUserDataHandler() : TK_User_Data() 
00118     {
00119         _stage = 0;
00120         _bytes = 0;
00121         _fp = fopen( "userdata.bin", "wb+" );
00122     }
00123     virtual ~StartUserDataHandler() 
00124     {
00125         fclose(_fp);
00126     }
00127 
00128     TK_Status   Read (BStreamFileToolkit & tk)
00129     {
00130     auto        TK_Status       status = TK_Normal;
00131 
00132     switch (m_stage) {
00133         case 0: {
00134             if ((status = GetData (tk, m_size)) != TK_Normal)
00135                 return status;
00136             set_data (m_size);      // allocate space
00137             m_stage++;
00138         }
00139 
00140         case 1: {
00141             if ((status = GetData (tk, m_data, m_size)) != TK_Normal)
00142                 return status;
00143             m_stage++;
00144 
00145             fwrite( m_data, m_size, 1, _fp );
00146         }
00147 
00148         case 2: {
00149             int loops = 0;
00150             auto        unsigned char       stop_code = 0;
00151 
00152             while (stop_code != TKE_Stop_User_Data)
00153             {
00154                 if ((status = GetData (tk, stop_code)) != TK_Normal)
00155                     return status;
00156                 loops++;
00157             }
00158 
00159             //if (stop_code != TKE_Stop_User_Data)    // sanity check
00160             //    return tk.Error();
00161 
00162             m_stage = -1;
00163         }   break;
00164 
00165         default:
00166             return tk.Error();
00167     }
00168 
00169     return status;
00170 }
00171 
00172 };
00173 
00174 int main(int argc, char* argv[])
00175 {
00176 
00177     if (argc < 2)
00178     {
00179         wcout << L"Usage:" << argv[0] << L" file.dwf" << endl;
00180         return ( 0 );
00181     }
00182 
00183     try
00184     {
00185         DWFFile oDWF( argv[1] );
00186         DWFToolkit::DWFPackageReader oReader( oDWF );
00187 
00188         DWFPackageReader::tPackageInfo tInfo;
00189         oReader.getPackageInfo( tInfo );
00190 
00191         wchar_t zBuffer[256] = {0};
00192 
00193         if (tInfo.eType != DWFPackageReader::eDWFPackage)
00194             
00195         {
00196             _DWFCORE_SWPRINTF( zBuffer, 256, L"File is not a DWF package [%s]",
00197                         (tInfo.eType == DWFPackageReader::eW2DStream) ? L"W2D Stream" :
00198                         (tInfo.eType == DWFPackageReader::eDWFStream) ? L"DWF Stream (<6.0)" :
00199                         (tInfo.eType == DWFPackageReader::eZIPFile) ? L"ZIP Archive" : L"Unknown" );
00200 
00201             wcout << zBuffer << endl;
00202             exit( 0 );
00203         }
00204         else if (tInfo.nVersion < _DWF_FORMAT_VERSION_INTRO_3D)
00205         {
00206             wcout << L"DWF package specified is not a 3D DWF" << endl;
00207             exit( 0 );
00208         }
00209 
00210         //
00211         // read and parse the manifest
00212         //
00213         DWFToolkit::DWFManifest& rManifest = oReader.getManifest();
00214 
00215         //
00216         // obtain the emodel section
00217         //
00218         DWFToolkit::DWFManifest::SectionIterator* piSections = rManifest.findSectionsByType( _DWF_FORMAT_EMODEL_TYPE_WIDE_STRING );
00219 
00220             //
00221             // make sure we got a section
00222             //
00223         if ((piSections == NULL) || (piSections->valid() == false))
00224         {
00225             if (piSections)
00226             {
00227                 DWFCORE_FREE_OBJECT( piSections );
00228             }
00229 
00230             wcout << L"Malformed or unexpected 3D DWF, cannot continue without an EModel section" << endl;
00231             exit( 0 );
00232         }
00233 
00234         //
00235         // get the EModel Section
00236         //
00237         DWFToolkit::DWFEModelSection* pSection = dynamic_cast<DWFEModelSection*>(piSections->get());
00238 
00239         //
00240         // done with the iterator
00241         //
00242         DWFCORE_FREE_OBJECT( piSections );
00243 
00244         if (pSection == NULL)
00245         {
00246             wcout << L"Type mismatch - not an EModel Section" << endl;
00247             exit( 0 );
00248         }
00249 
00250         //
00251         // read the descriptor to get all the details
00252         //
00253         pSection->readDescriptor();
00254 
00255         //
00256         // get the graphics stream
00257         //
00258         DWFToolkit::DWFResourceContainer::ResourceIterator* piResources = pSection->findResourcesByRole( DWFXML::kzRole_Graphics3d );
00259 
00260         if ((piResources == NULL) || (piResources->valid() == false))
00261         {
00262             if (piResources)
00263             {
00264                 DWFCORE_FREE_OBJECT( piResources );
00265             }
00266 
00267             wcout << "Illegal EModel section - no graphics" << endl;
00268             exit( 0 );
00269         }
00270 
00271         //
00272         // get the w3d resource
00273         //
00274         DWFToolkit::DWFGraphicResource* pW3D = dynamic_cast<DWFGraphicResource*>(piResources->get());
00275 
00276         //
00277         // done with the iterator
00278         //
00279         DWFCORE_FREE_OBJECT( piResources );
00280 
00281         if (pW3D == NULL)
00282         {
00283             wcout << L"Type mismatch - not a W3D resource" << endl;
00284             exit( 0 );
00285         }
00286 
00287         //
00288         // get the data stream
00289         //
00290         DWFCore::DWFInputStream* pW3DStream = pW3D->getInputStream();
00291 
00292         //
00293         // Create the HSF toolkit object that does the stream I/O
00294         //
00295         BStreamFileToolkit oW3DStreamParser;
00296 
00297         //
00298         // For this sample, we are interested in those op-codes that might contain
00299         // some interesting text.  Here is where we hook these handlers.
00300         // Also note that the parser object will delete this object on it's own destruction
00301         //
00302         oW3DStreamParser.SetOpcodeHandler( TKE_Start_User_Data,     new StartUserDataHandler );
00303         oW3DStreamParser.SetOpcodeHandler( TKE_Stop_User_Data,      new StartUserDataHandler );
00304 
00305         oW3DStreamParser.SetOpcodeHandler( TKE_Shell,               new ShellHandler );
00306         
00307         oW3DStreamParser.SetOpcodeHandler( TKE_Comment,             new CommentHandler );
00308         oW3DStreamParser.SetOpcodeHandler( TKE_Text,                new TextOpcodeHandler );
00309         oW3DStreamParser.SetOpcodeHandler( TKE_Text_With_Encoding,  new TextWithEncodingOpcodeHandler ); 
00310 
00311         //
00312         // Attach the stream to the parser
00313         //
00314         oW3DStreamParser.OpenStream( *pW3DStream );
00315 
00316         size_t  nBytesRead = 0;
00317         char    aBuffer[16384] = {0};
00318 
00319             //
00320             // read and process the stream
00321             //
00322         while (pW3DStream->available() > 0)
00323         {
00324             //
00325             // read from the stream ourselves, we could also use ReadBuffer()
00326             // but it basically just performs this same action.
00327             //
00328             nBytesRead = pW3DStream->read( aBuffer, 16384 );
00329 
00330                 //
00331                 // use the parser to process the buffer
00332                 //
00333             if (oW3DStreamParser.ParseBuffer(aBuffer, nBytesRead, TK_Normal) == TK_Error)
00334             {
00335                 wcout << L"Error occured parsing buffer" << endl;
00336                 break;
00337             }
00338         }
00339 
00340         //
00341         // Done with the stream, we must delete it
00342         //
00343         oW3DStreamParser.CloseStream();
00344         DWFCORE_FREE_OBJECT( pW3DStream );
00345 
00346         wcout << L"OK\n";
00347     }
00348     catch (DWFException& ex)
00349     {
00350         wcout << ex.type() << endl;
00351         wcout << ex.message() << endl;
00352         wcout << ex.function() << endl;
00353         wcout << ex.file() << endl;
00354         wcout << ex.line() << endl;
00355     }
00356 
00357     return 0;
00358 }
00359 
00360 

Generated on Tue Jan 6 22:40:01 2009 for Autodesk DWF Toolkit by  doxygen 1.4.5