00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
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
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
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
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
00156 _inFileHandler.getValue(numOfRoots);
00157
00158
00159 for(i = 0; i != numOfRoots; ++i)
00160 {
00161 _inFileHandler.getValue(currentId);
00162 setOfRootIds.insert(currentId);
00163 }
00164
00165
00166 _inFileHandler.getValue(countTypes);
00167
00168
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
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
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
00271 _inFileHandler.getValue(mask);
00272
00273
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
00291
00294 BINLoader::FCInfoStruct::FCInfoStruct(void) :
00295 newId(0),
00296 ptr(NullFC),
00297 read(false)
00298 {
00299 }
00300
00301
00302
00303
00306 BINLoader::FCIdMapper::FCIdMapper(IDLookupMap *m) :
00307 ptrMap(m)
00308 {
00309 }
00310
00313 UInt32 BINLoader::FCIdMapper::map(UInt32 uiId)
00314 {
00315
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
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
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 }