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
00040
00041
00042
00043 #include <stdlib.h>
00044 #include <stdio.h>
00045
00046 #include <fstream>
00047
00048 #include "OSGConfig.h"
00049
00050 #include <OSGLog.h>
00051 #include <OSGBaseTypes.h>
00052 #include <OSGPathHandler.h>
00053 #include <OSGGraphOpSeq.h>
00054 #include <OSGStripeGraphOp.h>
00055 #include <OSGImageFileHandler.h>
00056
00057 #include "OSGSceneFileHandler.h"
00058 #include "OSGZStream.h"
00059
00060
00061 #include <OSGNode.h>
00062 #include <OSGThread.h>
00063 #include <OSGThreadManager.h>
00064 #include <OSGBaseFunctions.h>
00065
00066 OSG_USING_NAMESPACE
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097 GraphOpSeq *SceneFileHandler::_defaultgraphOpSeq = NULL;
00098 SceneFileHandler * SceneFileHandler::_the = NULL;
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131 SceneFileType *SceneFileHandler::getFileType(const Char8 *fileNameOrExtension)
00132 {
00133 const Char8 separator = '.';
00134
00135 if(fileNameOrExtension == NULL)
00136 return NULL;
00137
00138 std::string fe = fileNameOrExtension;
00139
00140 Int32 p = fe.rfind(separator);
00141
00142 std::string ext;
00143
00144 if(p != -1)
00145 ext = fe.substr(p+1, fe.length() - p - 1);
00146 else
00147 ext = fe;
00148
00149
00150 if(ext == "gz")
00151 {
00152 fe = fe.substr(0, p);
00153 p = fe.rfind(separator);
00154 if(p != -1)
00155 ext = fe.substr(p+1, fe.length() - p - 1);
00156 else
00157 ext = fe;
00158 }
00159
00160 IDString suffix;
00161 suffix.set(ext.c_str());
00162 suffix.toLower();
00163
00164 FileTypeMap::iterator sI = _suffixTypeMap.find(suffix);
00165 SceneFileType *type = (sI == _suffixTypeMap.end()) ? 0 : sI->second->front();
00166
00167 return type;
00168 }
00169
00170
00171 #ifdef OSG_WIN32_ICL
00172 #pragma warning (disable : 383)
00173 #endif
00174
00175 Int32 SceneFileHandler::getSuffixList(std::list<const Char8 *> & suffixList,
00176 UInt32 flags)
00177 {
00178 Int32 count = 0;
00179 FileTypeMap::iterator sI;
00180
00181 suffixList.clear();
00182
00183 for ( sI = _suffixTypeMap.begin(); sI != _suffixTypeMap.end(); ++sI)
00184 {
00185 SceneFileType *type = sI->second->front();
00186 if((type->getFlags() & flags) == flags)
00187 {
00188 suffixList.push_back(sI->first.str());
00189 count++;
00190 }
00191 }
00192
00193 return count;
00194 }
00195
00196 #ifdef OSG_WIN32_ICL
00197 #pragma warning (default : 383)
00198 #endif
00199
00200
00201 NodePtr SceneFileHandler::read(std::istream &is, const Char8* fileNameOrExtension,
00202 GraphOpSeq *graphOpSeq)
00203 {
00204 SceneFileType *type = getFileType(fileNameOrExtension);
00205 NodePtr scene = NullFC;
00206
00207 if(!fileNameOrExtension)
00208 {
00209 SWARNING << "cannot read NULL extension" << std::endl;
00210 return NullFC;
00211 }
00212
00213 if (type)
00214 {
00215 SINFO << "try to read stream as " << type->getName() << std::endl;
00216
00217
00218 if(_readFP != NULL)
00219 {
00220 initReadProgress(is);
00221 scene = _readFP(type, is, fileNameOrExtension);
00222 terminateReadProgress();
00223 }
00224 else
00225 {
00226 if(isGZip(is))
00227 {
00228 SINFO << "Detected gzip compressed stream." << std::endl;
00229
00230 #ifdef OSG_ZSTREAM_SUPPORTED
00231 initReadProgress(is);
00232 zip_istream unzipper(is);
00233 scene = type->read(unzipper, fileNameOrExtension);
00234 if(scene != NullFC)
00235 {
00236 if(unzipper.check_crc())
00237 SINFO << "Compressed stream has correct checksum." << std::endl;
00238 else
00239 SFATAL << "Compressed stream has wrong checksum." << std::endl;
00240 }
00241 terminateReadProgress();
00242 #else
00243 SFATAL << "Compressed streams are not supported! Configure with --enable-png --with-png=DIR options." << std::endl;
00244 #endif
00245 }
00246 else
00247 {
00248 initReadProgress(is);
00249 scene = type->read(is, fileNameOrExtension);
00250 terminateReadProgress();
00251 }
00252 }
00253
00254 if(scene != NullFC)
00255 {
00256 if(graphOpSeq != NULL)
00257 graphOpSeq->run(scene);
00258
00259 SINFO << "read ok:" << std::endl;
00260 }
00261 else
00262 {
00263 SWARNING << "could not read " << std::endl;
00264 }
00265 }
00266 else
00267 {
00268 SWARNING << "could not read unknown file format" << std::endl;
00269 }
00270
00271 return scene;
00272 }
00273
00274
00275 SceneFileHandler::FCPtrStore SceneFileHandler::readTopNodes(
00276 std::istream &is, const Char8 *fileNameOrExtension,
00277 GraphOpSeq *graphOpSeq)
00278 {
00279 std::vector<FieldContainerPtr> nodeVec;
00280 NodePtr scene = read(is, fileNameOrExtension);
00281 if(scene == NullFC)
00282 return nodeVec;
00283
00284 while(scene->getNChildren() > 0)
00285 {
00286 NodePtr child = scene->getChild(0);
00287 NodePtr newChild = Node::create();
00288 while(child->getNChildren() > 0)
00289 newChild->addChild(child->getChild(0));
00290 newChild->setCore(child->getCore());
00291 if(graphOpSeq != NULL)
00292 graphOpSeq->run(newChild);
00293 nodeVec.push_back(newChild);
00294 scene->subChild(child);
00295 }
00296
00297 return nodeVec;
00298 }
00299
00300 NodePtr SceneFileHandler::read(const Char8 *fileName,
00301 GraphOpSeq *graphOpSeq)
00302 {
00303 if(!fileName)
00304 {
00305 SWARNING << "cannot read NULL file" << std::endl;
00306 return NullFC;
00307 }
00308
00309 std::string fullFilePath = initPathHandler(fileName);
00310 if(fullFilePath.empty())
00311 {
00312 if(_readFP != NULL)
00313 {
00314
00315
00316 SceneFileType *type = getFileType(fileName);
00317 if(type != NULL)
00318 {
00319
00320 std::ifstream in;
00321 in.setstate(std::ios::badbit);
00322 return _readFP(type, in, fileName);
00323 }
00324 else
00325 {
00326 SWARNING << "Couldn't open file " << fileName << std::endl;
00327 return NullFC;
00328 }
00329 }
00330 else
00331 {
00332 SWARNING << "Couldn't open file " << fileName << std::endl;
00333 return NullFC;
00334 }
00335 }
00336
00337 SceneFileType *type = getFileType(fullFilePath.c_str());
00338 NodePtr scene = NullFC;
00339
00340 if (type)
00341 {
00342 triggerReadBegin(fullFilePath.c_str());
00343 updateReadProgress(0);
00344
00345 SINFO << "try to read " << fullFilePath
00346 << " as " << type->getName() << std::endl;
00347
00348 std::ifstream in(fullFilePath.c_str(), std::ios::binary);
00349
00350 if(in)
00351 {
00352 scene = read(in, fullFilePath.c_str(), graphOpSeq);
00353 in.close();
00354
00355 if(scene != NullFC)
00356 {
00357 triggerReadEnd(fullFilePath.c_str());
00358 return scene;
00359 }
00360 }
00361 else
00362 {
00363 SWARNING << "Couldn't open input stream for file " << fullFilePath << std::endl;
00364 }
00365
00366
00367
00368 #ifndef OSG_DISABLE_DEPRECATED
00369
00370 if(scene == NullFC)
00371 scene = type->readFile(fullFilePath.c_str());
00372
00373 if (scene != NullFC)
00374 {
00375 if(graphOpSeq != NULL)
00376 graphOpSeq->run(scene);
00377
00378 SINFO << "read ok:" << std::endl;
00379 }
00380 else
00381 {
00382 SWARNING << "could not read " << std::endl;
00383 }
00384 #endif
00385 }
00386 else
00387 {
00388 SWARNING << "could not read " << fullFilePath
00389 << "; unknown file format" << std::endl;
00390 }
00391
00392 return scene;
00393 }
00394
00395 SceneFileHandler::FCPtrStore SceneFileHandler::readTopNodes(
00396 const Char8 *fileName,
00397 GraphOpSeq *graphOpSeq)
00398 {
00399 std::vector<FieldContainerPtr> nodeVec;
00400
00401 if(!fileName)
00402 {
00403 SWARNING << "cannot read NULL file" << std::endl;
00404 return nodeVec;
00405 }
00406
00407 std::string fullFilePath = initPathHandler(fileName);
00408 if(fullFilePath.empty())
00409 {
00410 SWARNING << "Couldn't open file " << fileName << std::endl;
00411 return nodeVec;
00412 }
00413
00414 std::ifstream in(fullFilePath.c_str(), std::ios::binary);
00415
00416 if(in)
00417 {
00418 nodeVec = readTopNodes(in, fullFilePath.c_str(), graphOpSeq);
00419 in.close();
00420 }
00421 else
00422 {
00423 SWARNING << "Couldn't open input stream for file " << fullFilePath << std::endl;
00424 }
00425
00426
00427 if(nodeVec.empty())
00428 {
00429 NodePtr scene = read(fullFilePath.c_str());
00430 if(scene == NullFC)
00431 return nodeVec;
00432
00433 while(scene->getNChildren() > 0)
00434 {
00435 NodePtr child = scene->getChild(0);
00436 NodePtr newChild = Node::create();
00437 while(child->getNChildren() > 0)
00438 newChild->addChild(child->getChild(0));
00439 newChild->setCore(child->getCore());
00440 if(graphOpSeq != NULL)
00441 graphOpSeq->run(newChild);
00442 nodeVec.push_back(newChild);
00443 scene->subChild(child);
00444 }
00445 }
00446
00447 return nodeVec;
00448 }
00449
00450 void SceneFileHandler::setReadCB(fileioreadcbfp fp)
00451 {
00452 _readFP = fp;
00453 }
00454
00455 SceneFileHandler::fileioreadcbfp SceneFileHandler::getReadCB(void)
00456 {
00457 return _readFP;
00458 }
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480 bool SceneFileHandler::write(const NodePtr &node, std::ostream &os,
00481 const Char8 *fileNameOrExtension, bool compress)
00482 {
00483 bool retCode = false;
00484 SceneFileType *type = getFileType(fileNameOrExtension);
00485
00486 if(type)
00487 {
00488 updateWriteProgress(0);
00489 SINFO << "try to write stream as " << type->getName() << std::endl;
00490
00491 if(_writeFP != NULL)
00492 {
00493 retCode = _writeFP(type, node, os, fileNameOrExtension, compress);
00494 }
00495 else
00496 {
00497 if(compress)
00498 {
00499 #ifdef OSG_ZSTREAM_SUPPORTED
00500 SINFO << "writing compressed stream." << std::endl;
00501 zip_ostream zipper(os, true);
00502 retCode = type->write(node, zipper, fileNameOrExtension);
00503 zipper.zflush();
00504 #else
00505 SFATAL << "Compressed streams are not supported! Configure with --enable-png --with-png=DIR options." << std::endl;
00506 #endif
00507 }
00508 else
00509 {
00510 retCode = type->write(node, os, fileNameOrExtension);
00511 }
00512 }
00513 }
00514 else
00515 SWARNING << "can't write stream unknown scene format" << std::endl;
00516
00517 return retCode;
00518 }
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540 bool SceneFileHandler::write (const NodePtr &node, const Char8 *fileName, bool compress)
00541 {
00542 bool retCode = false;
00543 SceneFileType *type = getFileType(fileName);
00544
00545 if (type)
00546 {
00547 updateWriteProgress(0);
00548 triggerWriteBegin(fileName);
00549 SINFO << "try to write " << fileName << " as " << type->getName() << std::endl;
00550
00551 std::ofstream out(fileName, std::ios::binary);
00552 if(out)
00553 {
00554 retCode = write(node, out, fileName, compress);
00555 out.close();
00556 }
00557 else
00558 {
00559 SWARNING << "Can not open output stream for file '" << fileName << "'!" << std::endl;
00560 }
00561
00562 #ifndef OSG_DISABLE_DEPRECATED
00563 if(!retCode)
00564 retCode = type->writeFile(node, fileName);
00565 #endif
00566
00567 if(!retCode)
00568 SWARNING << "Couldn't write " << fileName << std::endl;
00569 else
00570 triggerWriteEnd(fileName);
00571 }
00572 else
00573 SWARNING << "can't write " << fileName << "; unknown scene format" << std::endl;
00574
00575 return retCode;
00576 }
00577
00578 void SceneFileHandler::setWriteCB(fileiowritecbfp fp)
00579 {
00580 _writeFP = fp;
00581 }
00582
00583 SceneFileHandler::fileiowritecbfp SceneFileHandler::getWriteCB(void)
00584 {
00585 return _writeFP;
00586 }
00587
00591 PathHandler *SceneFileHandler::getPathHandler(void)
00592 {
00593 if(_pathHandler == NULL)
00594 return &_defaultPathHandler;
00595 else
00596 return _pathHandler;
00597 }
00598
00599
00603 void SceneFileHandler::setPathHandler(PathHandler *pathHandler)
00604 {
00605 _pathHandler = pathHandler;
00606 }
00607
00611 std::string SceneFileHandler::initPathHandler(const Char8 *fileName)
00612 {
00613 std::string fullFilePath;
00614 if(_pathHandler != NULL)
00615 {
00616
00617 if(ImageFileHandler::the().getPathHandler() == NULL)
00618 ImageFileHandler::the().setPathHandler(_pathHandler);
00619
00620 fullFilePath = _pathHandler->findFile(fileName);
00621 }
00622 else
00623 {
00624
00625 if(ImageFileHandler::the().getPathHandler() == NULL)
00626 ImageFileHandler::the().setPathHandler(&_defaultPathHandler);
00627
00628 _defaultPathHandler.clearPathList();
00629 _defaultPathHandler.clearBaseFile();
00630 _defaultPathHandler.push_frontCurrentDir();
00631 fullFilePath = _defaultPathHandler.findFile(fileName);
00632 _defaultPathHandler.setBaseFile(fullFilePath.c_str());
00633 }
00634
00635 return fullFilePath;
00636 }
00637
00638 GraphOpSeq *SceneFileHandler::getDefaultGraphOp(void)
00639 {
00640 return _defaultgraphOpSeq;
00641 }
00642
00643 void SceneFileHandler::setDefaultGraphOp(GraphOpSeq *graphOpSeq)
00644 {
00645 _defaultgraphOpSeq = graphOpSeq;
00646 }
00647
00648
00649 bool SceneFileHandler::setOptions(const Char8 *suffix, const Char8 *options)
00650 {
00651 if(suffix == NULL)
00652 return false;
00653
00654 SceneFileType *type = getFileType(suffix);
00655 if(type == NULL)
00656 return false;
00657
00658 type->setOptions(options);
00659
00660 return true;
00661 }
00662
00663 const Char8 *SceneFileHandler::getOptions(const Char8 *suffix)
00664 {
00665 if(suffix == NULL)
00666 return NULL;
00667
00668 SceneFileType *type = getFileType(suffix);
00669
00670 if(type == NULL)
00671 return NULL;
00672
00673 return type->getOptions();
00674 }
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696 void SceneFileHandler::print (void )
00697 {
00698 FileTypeMap::iterator sI;
00699
00700 for(sI = _suffixTypeMap.begin(); sI != _suffixTypeMap.end(); sI++)
00701 {
00702 std::string rw;
00703 SceneFileType *type = sI->second->front();
00704 if((type->getFlags() & SceneFileType::OSG_READ_SUPPORTED) &&
00705 (type->getFlags() & SceneFileType::OSG_WRITE_SUPPORTED))
00706 {
00707 rw = "reader and writer";
00708 }
00709 else
00710 {
00711 if(type->getFlags() & SceneFileType::OSG_READ_SUPPORTED)
00712 rw = "reader";
00713 if(type->getFlags() & SceneFileType::OSG_WRITE_SUPPORTED)
00714 rw = "writer";
00715 }
00716
00717 std::cerr << "suffix: " << sI->first.str()
00718 << ", type: " << sI->second->front()->getName()
00719 << " " << rw << std::endl;
00720 }
00721 }
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754 bool SceneFileHandler::FindOverride::operator() (SceneFileType *fileTypeP)
00755 {
00756 if(fileTypeP == NULL)
00757 return false;
00758
00759 if(fileTypeP->doOverride() == false)
00760 return true;
00761
00762 if(fileTypeP->getOverridePriority() <= uiRefPriority)
00763 return true;
00764
00765 return false;
00766 }
00767
00768
00769 #ifdef OSG_WIN32_ICL
00770 #pragma warning (disable : 383)
00771 #endif
00772
00773 bool SceneFileHandler::addSceneFileType(SceneFileType &fileType)
00774 {
00775 bool retCode = false;
00776
00777 std::list<IDString>::iterator sI;
00778 FileTypeMap ::iterator smI;
00779
00780 IDString suffix;
00781
00782 for( sI = fileType.suffixList().begin();
00783 sI != fileType.suffixList().end();
00784 ++sI)
00785 {
00786 suffix.set(sI->str());
00787 suffix.toLower();
00788
00789 smI = the()._suffixTypeMap.find(suffix);
00790
00791 if (smI != the()._suffixTypeMap.end())
00792 {
00793 if(fileType.doOverride() == true)
00794 {
00795 FindOverride overrideFinder;
00796 FileTypeList::iterator lIt;
00797
00798 overrideFinder.uiRefPriority = fileType.getOverridePriority();
00799
00800 lIt = std::find_if(the()._suffixTypeMap[suffix]->begin(),
00801 the()._suffixTypeMap[suffix]->end(),
00802 overrideFinder);
00803
00804 the()._suffixTypeMap[suffix]->insert(lIt, &fileType);
00805
00806 SWARNING << "Added an file type with suffix "
00807 << suffix
00808 << " overriding "
00809 << std::endl;
00810 }
00811 else
00812 {
00813 the()._suffixTypeMap[suffix]->push_back(&fileType);
00814
00815 SWARNING << "Added an file type with suffix "
00816 << suffix
00817 << " non overriding at the end of the list"
00818 << std::endl;
00819 }
00820 }
00821 else
00822 {
00823 FileTypeList *pTmpList = new FileTypeList;
00824
00825 pTmpList->push_back(&fileType);
00826
00827 the()._suffixTypeMap[suffix] = pTmpList;
00828
00829 retCode = true;
00830 }
00831 }
00832
00833 return retCode;
00834 }
00835
00836 bool SceneFileHandler::subSceneFileType(SceneFileType &fileType)
00837 {
00838 bool retCode = false;
00839
00840 std::list<IDString>::iterator sI;
00841 FileTypeMap ::iterator smI;
00842
00843 IDString suffix;
00844
00845 for( sI = fileType.suffixList().begin();
00846 sI != fileType.suffixList().end();
00847 ++sI)
00848 {
00849 suffix.set(sI->str());
00850 suffix.toLower();
00851
00852 smI = the()._suffixTypeMap.find(suffix);
00853 if (smI != the()._suffixTypeMap.end())
00854 {
00855 the()._suffixTypeMap.erase(smI);
00856 retCode = true;
00857 }
00858 }
00859 return retCode;
00860 }
00861
00862 #ifdef OSG_WIN32_ICL
00863 #pragma warning (default : 383)
00864 #endif
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899 SceneFileHandler::SceneFileHandler (void) :
00900 _readProgressFP(NULL),
00901 _readBeginFP(NULL),
00902 _readEndFP(NULL),
00903 _progressData(),
00904 _readReady(false),
00905 _useProgressThread(false),
00906 _writeProgressFP(NULL),
00907 _writeBeginFP(NULL),
00908 _writeEndFP(NULL),
00909 _pathHandler(NULL),
00910 _defaultPathHandler(),
00911 _readFP(NULL),
00912 _writeFP(NULL)
00913 {
00914 _progressData.length = 0;
00915 _progressData.is = NULL;
00916
00917 if(_defaultgraphOpSeq == NULL)
00918 {
00919
00920 _defaultgraphOpSeq = new GraphOpSeq;
00921 _defaultgraphOpSeq->setGraphOps("Stripe() SharePtr(includes=Material,StateChunk)");
00922 }
00923
00924 }
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946 SceneFileHandler::SceneFileHandler (const SceneFileHandler & )
00947 {
00948 SWARNING << "In copy constructor; I shouldn't be in this corner" << std::endl;
00949 }
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972 SceneFileHandler::~SceneFileHandler(void)
00973 {
00974 }
00975
00976 SceneFileHandler &SceneFileHandler::the(void)
00977 {
00978 if(_the == NULL)
00979 _the = new SceneFileHandler;
00980
00981 return *_the;
00982 }
00983
00984
00985
00986 void SceneFileHandler::setReadProgressCB(progresscbfp fp, bool use_thread)
00987 {
00988 if(use_thread)
00989 {
00990 terminateReadProgress();
00991 }
00992 else
00993 {
00994
00995 if(_useProgressThread)
00996 terminateReadProgress();
00997 }
00998
00999 _readProgressFP = fp;
01000 _useProgressThread = use_thread;
01001 }
01002
01003 SceneFileHandler::progresscbfp SceneFileHandler::getReadProgressCB(void)
01004 {
01005 return _readProgressFP;
01006 }
01007
01008 void SceneFileHandler::setReadBeginCB(SceneFileHandler::filenamecbfp fp)
01009 {
01010 _readBeginFP = fp;
01011 }
01012
01013 SceneFileHandler::filenamecbfp SceneFileHandler::getReadBeginCB(void)
01014 {
01015 return _readBeginFP;
01016 }
01017
01018 void SceneFileHandler::setReadEndCB(SceneFileHandler::filenamecbfp fp)
01019 {
01020 _readEndFP = fp;
01021 }
01022
01023 SceneFileHandler::filenamecbfp SceneFileHandler::getReadEndCB(void)
01024 {
01025 return _readEndFP;
01026 }
01027
01028 void SceneFileHandler::triggerReadBegin(const Char8 *fname)
01029 {
01030 if(_readBeginFP != NULL)
01031 _readBeginFP(fname);
01032 }
01033
01034 void SceneFileHandler::triggerReadEnd(const Char8 *fname)
01035 {
01036 if(_readEndFP != NULL)
01037 _readEndFP(fname);
01038 }
01039
01040 void SceneFileHandler::initReadProgress(std::istream &is)
01041 {
01042 if(_readProgressFP == NULL)
01043 return;
01044
01045
01046 _progressData.is = &is;
01047 is.seekg(0, std::ios::end);
01048 _progressData.length = is.tellg();
01049 is.seekg(0, std::ios::beg);
01050
01051 _readReady = false;
01052 if(_useProgressThread)
01053 {
01054 Thread *pt = Thread::find("osg::FileIOReadProgressThread");
01055 if(pt == NULL)
01056 pt = OSG::Thread::get("osg::FileIOReadProgressThread");
01057
01058 if(pt != NULL)
01059 pt->runFunction(readProgress, 0, NULL);
01060 else
01061 SWARNING << "Couldn't create read progress thread!" << std::endl;
01062 }
01063 }
01064
01065 void SceneFileHandler::terminateReadProgress(void)
01066 {
01067 if(_readProgressFP == NULL)
01068 return;
01069
01070 _readReady = true;
01071 Thread *pt = Thread::find("osg::FileIOReadProgressThread");
01072 if(pt != NULL)
01073 {
01074
01075 Thread::join(pt);
01076 }
01077
01078 _progressData.length = 0;
01079 _progressData.is = NULL;
01080 }
01081
01082 void SceneFileHandler::readProgress(void * OSG_CHECK_ARG(data))
01083 {
01084 if(the()._readProgressFP == NULL || the()._progressData.is == NULL)
01085 return;
01086
01087 UInt32 p = 0;
01088 while(p < 100 && !the()._readReady)
01089 {
01090 if(!the()._progressData.is->eof() &&
01091 !the()._progressData.is->bad())
01092 {
01093 UInt64 pos = the()._progressData.is->tellg();
01094 p = UInt32((pos * 100) / the()._progressData.length);
01095 if(p > 100)
01096 p = 100;
01097 }
01098 else
01099 {
01100 p = 100;
01101 }
01102
01103 the()._readProgressFP(p);
01104
01105 if(the()._useProgressThread)
01106 osgsleep(100);
01107 else
01108 break;
01109 }
01110
01111 if(the()._useProgressThread && p < 100)
01112 {
01113 the()._readProgressFP(100);
01114 }
01115 }
01116
01117 void SceneFileHandler::updateReadProgress(void)
01118 {
01119 if(_readProgressFP == NULL)
01120 return;
01121
01122 if(_useProgressThread)
01123 return;
01124
01125 readProgress(NULL);
01126 }
01127
01128 void SceneFileHandler::updateReadProgress(UInt32 p)
01129 {
01130 if(_readProgressFP == NULL)
01131 return;
01132
01133 _readProgressFP(p);
01134 }
01135
01136
01137
01138 void SceneFileHandler::setWriteProgressCB(progresscbfp fp)
01139 {
01140 _writeProgressFP = fp;
01141 }
01142
01143 SceneFileHandler::progresscbfp SceneFileHandler::getWriteProgressCB(void)
01144 {
01145 return _writeProgressFP;
01146 }
01147
01148 void SceneFileHandler::setWriteBeginCB(SceneFileHandler::filenamecbfp fp)
01149 {
01150 _writeBeginFP = fp;
01151 }
01152
01153 SceneFileHandler::filenamecbfp SceneFileHandler::getWriteBeginCB(void)
01154 {
01155 return _writeBeginFP;
01156 }
01157
01158 void SceneFileHandler::setWriteEndCB(SceneFileHandler::filenamecbfp fp)
01159 {
01160 _writeEndFP = fp;
01161 }
01162
01163 SceneFileHandler::filenamecbfp SceneFileHandler::getWriteEndCB(void)
01164 {
01165 return _writeEndFP;
01166 }
01167
01168 void SceneFileHandler::triggerWriteBegin(const Char8 *fname)
01169 {
01170 if(_writeBeginFP != NULL)
01171 _writeBeginFP(fname);
01172 }
01173
01174 void SceneFileHandler::triggerWriteEnd(const Char8 *fname)
01175 {
01176 if(_writeEndFP != NULL)
01177 _writeEndFP(fname);
01178 }
01179
01180
01181 void SceneFileHandler::updateWriteProgress(UInt32 p)
01182 {
01183 if(_writeProgressFP == NULL)
01184 return;
01185
01186 _writeProgressFP(p);
01187 }
01188
01189
01190
01191
01192
01193 #ifdef __sgi
01194 #pragma set woff 1174
01195 #endif
01196
01197 #ifdef OSG_LINUX_ICC
01198 #pragma warning( disable : 177 )
01199 #endif
01200
01201 namespace
01202 {
01203 static Char8 cvsid_cpp[] = "@(#)$Id: $";
01204 static Char8 cvsid_hpp[] = OSGSCENEFILEHANDLER_HEADER_CVSID;
01205 }