Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

OSGBINLoader.cpp

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002  *                                OpenSG                                     *
00003  *                                                                           *
00004  *                                                                           *
00005  *             Copyright (C) 2000-2002 by the OpenSG Forum                   *
00006  *                                                                           *
00007  *                            www.opensg.org                                 *
00008  *                                                                           *
00009  *   contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de          *
00010  *                                                                           *
00011 \*---------------------------------------------------------------------------*/
00012 /*---------------------------------------------------------------------------*\
00013  *                                License                                    *
00014  *                                                                           *
00015  * This library is free software; you can redistribute it and/or modify it   *
00016  * under the terms of the GNU Library General Public License as published    *
00017  * by the Free Software Foundation, version 2.                               *
00018  *                                                                           *
00019  * This library is distributed in the hope that it will be useful, but       *
00020  * WITHOUT ANY WARRANTY; without even the implied warranty of                *
00021  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU         *
00022  * Library General Public License for more details.                          *
00023  *                                                                           *
00024  * You should have received a copy of the GNU Library General Public         *
00025  * License along with this library; if not, write to the Free Software       *
00026  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                 *
00027  *                                                                           *
00028 \*---------------------------------------------------------------------------*/
00029 /*---------------------------------------------------------------------------*\
00030  *                                Changes                                    *
00031  *                                                                           *
00032  *                                                                           *
00033  *                                                                           *
00034  *                                                                           *
00035  *                                                                           *
00036  *                                                                           *
00037 \*---------------------------------------------------------------------------*/
00038 
00039 #include <OSGConfig.h>
00040 #include <stdio.h>
00041 
00042 #include <string>
00043 #include <map>
00044 #include <set>
00045 #include <vector>
00046 #include <fstream>
00047 
00048 #include <OSGFieldContainer.h>
00049 #include <OSGBinaryDataHandler.h>
00050 
00051 #include "OSGBINLoader.h"
00052 
00053 OSG_USING_NAMESPACE
00054 
00080 /*-------------------------------------------------------------------------*/
00081 /*                            Constructors/Destructor                      */
00082 
00085 BINLoader::BINLoader(std::istream &is) :
00086     _inFileHandler(is),
00087     _fcInfoMap(),
00088     _countContainers(0),
00089     _vec_pRootNodes(),
00090     _valid_stream(is != false)
00091 {
00092 }
00093 
00096 BINLoader::~BINLoader(void)
00097 {
00098 }
00099 
00100 /*-------------------------------------------------------------------------*/
00101 /*                             read / root access                          */
00102 
00105 void BINLoader::read(void)
00106 {
00107     if(!_valid_stream)
00108     {
00109         SFATAL << "BINLoader::read : Stream is invalid!" << std::endl;
00110         return;
00111     }
00112 
00113     _vec_pRootNodes.clear();
00114     if(!createFieldContainers())
00115     {
00116         _valid_stream = false;
00117         return;
00118     }
00119 
00120     chargeFieldContainers();
00121 }
00122 
00125 NodePtr BINLoader::getRootNode(void)
00126 {
00127     if(!_valid_stream)
00128     {
00129         return NullFC;
00130     }
00131 
00132     return _vec_pRootNodes[0];
00133 }
00134 
00137 std::vector<NodePtr> BINLoader::getRootNodes(void)
00138 {
00139     return _vec_pRootNodes;
00140 }
00141 
00142 /*-------------------------------------------------------------------------*/
00143 /*                         private helper functions                        */
00144 
00147 bool BINLoader::createFieldContainers(void)
00148 {
00149     UInt32 countTypes = 0, countCurrentType = 0, oldFCId = 0, numOfRoots = 0,
00150         currentId = 0, i, j;
00151     std::string fcTypeCName;
00152     FCInfoStruct newFCInfo;
00153     std::set < UInt32 > setOfRootIds;
00154 
00155     //fetch the number of roots
00156     _inFileHandler.getValue(numOfRoots);
00157 
00158     //fetch the root IDs
00159     for(i = 0; i != numOfRoots; ++i)
00160     {
00161         _inFileHandler.getValue(currentId);
00162         setOfRootIds.insert(currentId);
00163     }
00164 
00165     //fetch number of different types
00166     _inFileHandler.getValue(countTypes);
00167 
00168     //fetch number of and IDs themselves
00169     for(i = 0; i != countTypes; ++i)
00170     {
00171         _inFileHandler.getValue(fcTypeCName);
00172         _inFileHandler.getValue(countCurrentType);
00173         for(j = 0; j != countCurrentType; j++)
00174         {
00175             _inFileHandler.getValue(oldFCId);
00176             newFCInfo.ptr = FieldContainerFactory::the()->createFieldContainer(fcTypeCName.c_str());
00177 
00178             if(newFCInfo.ptr == NullFC)
00179             {
00180                 SFATAL << "Couldn't create unknown FieldContainer with type '" <<
00181                        fcTypeCName << "'!" << std::endl;
00182                 return false;
00183             }
00184             _countContainers++;
00185 
00186             //det. all RootNodes
00187             if(setOfRootIds.find(oldFCId) != setOfRootIds.end())
00188             {
00189                 _vec_pRootNodes.push_back(NodePtr::dcast(newFCInfo.ptr));
00190             }
00191 
00192             newFCInfo.newId = newFCInfo.ptr.getFieldContainerId();
00193 
00194             if(_fcInfoMap.insert(std::make_pair(oldFCId, newFCInfo)).second
00195                == false)
00196             {
00197                 std::cerr <<
00198                     "ERROR in BINLoader::createFieldContainers()" <<
00199                     std::endl;
00200             }
00201         }
00202     }
00203 
00204     SINFO << "created " << _countContainers << " containers" << std::endl;
00205     return true;
00206 }
00207 
00210 void BINLoader::chargeFieldContainers(void)
00211 {
00212     FCIdMapper                  mapper(&_fcInfoMap);
00213     IDLookupMap::iterator       fcInfoIter = _fcInfoMap.begin();
00214     const IDLookupMap::iterator fcInfoEnd = _fcInfoMap.end();
00215 
00216     UInt32 mapSize = _fcInfoMap.size(), currentFieldContainerOldId, count = 0;
00217     BitVector mask;
00218     FieldContainerFactory *factory = FieldContainerFactory::the();
00219 
00220     factory->setMapper(&mapper);
00221     while(count < mapSize)
00222     {
00223         count++;
00224 
00225         SINFO <<
00226             "loading container " <<
00227             std::setw(4) <<
00228             count <<
00229             "/" <<
00230             mapSize <<
00231             "..." <<
00232             std::endl;
00233 
00234         //fetch container id
00235         _inFileHandler.getValue(currentFieldContainerOldId);
00236         fcInfoIter = _fcInfoMap.find(currentFieldContainerOldId);
00237 
00238         if(fcInfoIter == fcInfoEnd)
00239         {
00240             SWARNING <<
00241                 "ERROR in BINLoader::chargeFieldContainers():" <<
00242                 std::endl <<
00243                 "no matching container found for ID " <<
00244                 currentFieldContainerOldId <<
00245                 std::endl <<
00246                 "THIS SHOULD NOT HAPPEN!!!" <<
00247                 std::endl;
00248 
00249             continue;
00250         }
00251 
00252         if(fcInfoIter->second.read)
00253         {
00254             SWARNING <<
00255                 "ERROR in BINLoader::chargeFieldContainers():" <<
00256                 std::endl <<
00257                 "original ID: " <<
00258                 currentFieldContainerOldId <<
00259                 std::endl <<
00260                 "new ID     : " <<
00261                 fcInfoIter->second.newId <<
00262                 std::endl <<
00263                 "CONTAINER ALREADY WRITTEN! CONTAINER " <<
00264                 "WILL BE OVERWRITTEN!" <<
00265                 std::endl <<
00266                 "THIS SHOULD NOT HAPPEN!!!" <<
00267                 std::endl;
00268         }
00269 
00270         // fetch mask
00271         _inFileHandler.getValue(mask);
00272 
00273         // fetch container data
00274         beginEditCP(fcInfoIter->second.ptr, mask,
00275                             ChangedOrigin::Abstract | ChangedOrigin::AbstrIncRefCount);
00276         {
00277             fcInfoIter->second.ptr->copyFromBin(_inFileHandler, BitVector(mask));
00278         }
00279 
00280         endEditCP(fcInfoIter->second.ptr, mask,
00281                           ChangedOrigin::Abstract | ChangedOrigin::AbstrIncRefCount);
00282 
00283         fcInfoIter->second.read = true;
00284     }
00285 
00286     factory->setMapper(NULL);
00287 }
00288 
00289 /*-------------------------------------------------------------------------*/
00290 /*                              FCInfoStruct                               */
00291 
00294 BINLoader::FCInfoStruct::FCInfoStruct(void) :
00295     newId(0),
00296     ptr(NullFC),
00297     read(false)
00298 {
00299 }
00300 
00301 /*-------------------------------------------------------------------------*/
00302 /*                              FCIdMapper                                 */
00303 
00306 BINLoader::FCIdMapper::FCIdMapper(IDLookupMap *m) :
00307     ptrMap(m)
00308 {
00309 }
00310 
00313 UInt32 BINLoader::FCIdMapper::map(UInt32 uiId)
00314 {
00315     //returns id=0 if nil
00316     UInt32 id = 0;
00317     IDLookupMap::const_iterator iterID = ptrMap->find(uiId);
00318     if(!(iterID == ptrMap->end()))
00319     {
00320         id = iterID->second.newId;
00321     }
00322 
00323     return id;
00324 }
00325 
00326 /*-------------------------------------------------------------------------*/
00327 /*                              BinaryFileHandler                          */
00328 
00331 BINLoader::BinaryFileHandler::BinaryFileHandler(std::istream &is) :
00332     BinaryDataHandler(0),
00333     _is(is)
00334 {
00335     _readMemory.resize(10000);
00336     readBufAdd(&_readMemory[0], _readMemory.size());
00337 }
00338 
00341 BINLoader::BinaryFileHandler::~BinaryFileHandler(void)
00342 {
00343 }
00344 
00347 void BINLoader::BinaryFileHandler::read(MemoryHandle mem, UInt32 size)
00348 {
00349     _is.read((char *) mem, size);
00350 }
00351 
00352 /*-------------------------------------------------------------------------*/
00353 /*                              cvs id's                                   */
00354 
00355 #ifdef __sgi
00356 #pragma set woff 1174
00357 #endif
00358 #ifdef OSG_LINUX_ICC
00359 #pragma warning(disable : 177)
00360 #endif
00361 
00362 namespace
00363 {
00364     static Char8 cvsid_cpp[] = "@(#)$Id: $";
00365     static Char8 cvsid_hpp[] = OSGBINLOADER_HEADER_CVSID;
00366 }

Generated on Thu Aug 25 04:01:19 2005 for OpenSG by  doxygen 1.4.3