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 #include "OSDLEmbeddedFileSystemManager.h"
00028
00029
00030 #include "OSDLEmbeddedFile.h"
00031 #include "OSDLEmbeddedDirectory.h"
00032
00033
00034 #ifdef OSDL_USES_CONFIG_H
00035 #include "OSDLConfig.h"
00036 #endif // OSDL_USES_CONFIG_H
00037
00038
00039 #if OSDL_ARCH_NINTENDO_DS
00040 #include "OSDLConfigForNintendoDS.h"
00041 #endif // OSDL_ARCH_NINTENDO_DS
00042
00043
00044 #if OSDL_USES_PHYSICSFS
00045 #include "physfs.h"
00046 #endif // OSDL_USES_PHYSICSFS
00047
00048
00049 #include "Ceylan.h"
00050
00051
00052
00053 using std::string ;
00054 using std::list ;
00055
00056 using namespace Ceylan::Log ;
00057 using namespace Ceylan::System ;
00058
00059 using namespace OSDL ;
00060
00061
00062
00063
00064
00065
00066
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 const Ceylan::Byte EmbeddedFileSystemManager::XORByte = 0x55 ;
00092
00093
00094
00095
00096 const string EmbeddedFileSystemManager::RootDirectoryPrefix = "" ;
00097 const Ceylan::Latin1Char EmbeddedFileSystemManager::Separator = '/' ;
00098
00099
00100
00101
00102 EmbeddedFileSystemManager *
00103 EmbeddedFileSystemManager::_EmbeddedFileSystemManager = 0 ;
00104
00105
00106
00107 string EmbeddedFileSystemManager::ArchivePathEnvironmentVariable =
00108 "ARCHIVE_PATH" ;
00109
00110 Ceylan::System::FileLocator EmbeddedFileSystemManager::ArchiveFileLocator(
00111 ArchivePathEnvironmentVariable ) ;
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121 void EmbeddedFileSystemManager::chooseBasicSettings(
00122 const string & organizationName,
00123 const string & applicationName,
00124 const string & archiveExtension,
00125 bool archiveFirst,
00126 bool includeInsertedMedia )
00127 {
00128
00129
00130
00131
00132
00133
00134
00135 send( "Selecting basic settings: organization name is '" + organizationName
00136 + "', application name is '" + applicationName
00137 + "', extension for archives is '" + archiveExtension
00138 + string( "', archives will be searched " )
00139 + ( archiveFirst ? "first" : "last" )
00140 + string( ", and any inserted media will be " )
00141 + ( includeInsertedMedia ? "" : "not " ) + string( "searched." ) ) ;
00142
00143 #if OSDL_USES_PHYSICSFS
00144
00145 int res = PHYSFS_setSaneConfig(
00146 organizationName.c_str(),
00147 applicationName.c_str(),
00148 archiveExtension.c_str(),
00149 (includeInsertedMedia ? 1 : 0 ),
00150 (archiveFirst ? 1 : 0 ) ) ;
00151
00152 if ( res == 0 )
00153 throw EmbeddedFileSystemManagerException(
00154 "EmbeddedFileSystemManager::chooseBasicSettings failed: "
00155 + GetBackendLastError() ) ;
00156
00157 #else // OSDL_USES_PHYSICSFS
00158
00159 throw EmbeddedFileSystemManagerException(
00160 "EmbeddedFileSystemManager::chooseBasicSettings failed: "
00161 "no PhysicsFS support available." ) ;
00162
00163 #endif // OSDL_USES_PHYSICSFS
00164
00165 }
00166
00167
00168
00169 bool EmbeddedFileSystemManager::hasWriteDirectory() const
00170 {
00171
00172
00173
00174
00175
00176
00177
00178 #if OSDL_USES_PHYSICSFS
00179
00180 const char * res = PHYSFS_getWriteDir() ;
00181
00182 return (res != 0) ;
00183
00184 #else // OSDL_USES_PHYSICSFS
00185
00186 throw EmbeddedFileSystemManagerException(
00187 "EmbeddedFileSystemManager::hasWriteDirectory failed: "
00188 "no PhysicsFS support available." ) ;
00189
00190 #endif // OSDL_USES_PHYSICSFS
00191
00192 }
00193
00194
00195
00196 std::string EmbeddedFileSystemManager::getWriteDirectory() const
00197 {
00198
00199
00200
00201
00202
00203
00204
00205 #if OSDL_USES_PHYSICSFS
00206
00207 const char * res = PHYSFS_getWriteDir() ;
00208
00209 if ( res == 0 )
00210 throw EmbeddedFileSystemManagerException(
00211 "EmbeddedFileSystemManager::getWriteDirectory failed: "
00212 "no write directory set." ) ;
00213
00214 return string( res ) ;
00215
00216 #else // OSDL_USES_PHYSICSFS
00217
00218 throw EmbeddedFileSystemManagerException(
00219 "EmbeddedFileSystemManager::getWriteDirectory failed: "
00220 "no PhysicsFS support available." ) ;
00221
00222 #endif // OSDL_USES_PHYSICSFS
00223
00224 }
00225
00226
00227
00228 void EmbeddedFileSystemManager::setWriteDirectory(
00229 const std::string & newWriteDirectory )
00230 {
00231
00232
00233
00234
00235
00236
00237
00238 #if OSDL_USES_PHYSICSFS
00239
00240 if ( PHYSFS_setWriteDir( newWriteDirectory.c_str() ) == 0 )
00241 throw EmbeddedFileSystemManagerException(
00242 "EmbeddedFileSystemManager::setWriteDirectory failed: "
00243 + GetBackendLastError() ) ;
00244
00245 send( "Write directory set to " + newWriteDirectory ) ;
00246
00247 #else // OSDL_USES_PHYSICSFS
00248
00249 throw EmbeddedFileSystemManagerException(
00250 "EmbeddedFileSystemManager::setWriteDirectory failed: "
00251 "no PhysicsFS support available." ) ;
00252
00253 #endif // OSDL_USES_PHYSICSFS
00254
00255 }
00256
00257
00258
00259 void EmbeddedFileSystemManager::mount(
00260 const string & newActualFilesystemElement,
00261 const string & mountPointInVirtualTree,
00262 bool append )
00263 {
00264
00265
00266
00267
00268
00269
00270
00271 #if OSDL_USES_PHYSICSFS
00272
00273 try
00274 {
00275
00276 StandardFileSystemManager & standardManager =
00277 StandardFileSystemManager::GetStandardFileSystemManager() ;
00278
00279 if ( ! standardManager.existsAsEntry( newActualFilesystemElement ) )
00280 throw EmbeddedFileSystemManagerException(
00281 "EmbeddedFileSystemManager::mount failed "
00282 "for non-existing filesystem element '"
00283 + newActualFilesystemElement + "'." ) ;
00284 }
00285 catch( const Ceylan::Exception & e )
00286 {
00287
00288 throw EmbeddedFileSystemManagerException(
00289 "EmbeddedFileSystemManager::mount failed for filesystem element '"
00290 + newActualFilesystemElement + "': "
00291 + e.toString() ) ;
00292 }
00293
00294
00295 if ( PHYSFS_mount(
00296 newActualFilesystemElement.c_str(),
00297 mountPointInVirtualTree.c_str(),
00298 append ) == 0 )
00299 throw EmbeddedFileSystemManagerException(
00300 "EmbeddedFileSystemManager::mount failed: "
00301 + GetBackendLastError() ) ;
00302
00303 send( "Element '" + newActualFilesystemElement + "' mounted." ) ;
00304
00305 #else // OSDL_USES_PHYSICSFS
00306
00307 throw EmbeddedFileSystemManagerException(
00308 "EmbeddedFileSystemManager::mount failed: "
00309 "no PhysicsFS support available." ) ;
00310
00311 #endif // OSDL_USES_PHYSICSFS
00312
00313 }
00314
00315
00316
00317 void EmbeddedFileSystemManager::umount(
00318 const std::string & actualFilesystemElement )
00319 {
00320
00321
00322
00323
00324
00325
00326
00327 #if OSDL_USES_PHYSICSFS
00328
00329 if ( PHYSFS_removeFromSearchPath( actualFilesystemElement.c_str() ) == 0 )
00330 throw EmbeddedFileSystemManagerException(
00331 "EmbeddedFileSystemManager::umount failed: "
00332 + GetBackendLastError() ) ;
00333
00334 send( "Element '" + actualFilesystemElement + "' unmounted." ) ;
00335
00336 #else // OSDL_USES_PHYSICSFS
00337
00338 throw EmbeddedFileSystemManagerException(
00339 "EmbeddedFileSystemManager::umount failed: "
00340 "no PhysicsFS support available." ) ;
00341
00342 #endif // OSDL_USES_PHYSICSFS
00343
00344 }
00345
00346
00347
00348 std::string EmbeddedFileSystemManager::getMountPointFor(
00349 const string & actualFilesystemElement ) const
00350 {
00351
00352
00353
00354
00355
00356
00357
00358 #if OSDL_USES_PHYSICSFS
00359
00360 const char * res = PHYSFS_getMountPoint( actualFilesystemElement.c_str() ) ;
00361
00362 if ( res == 0 )
00363 throw EmbeddedFileSystemManagerException(
00364 "EmbeddedFileSystemManager::getMountPointFor failed: "
00365 + GetBackendLastError() ) ;
00366
00367 return string( res ) ;
00368
00369 #else // OSDL_USES_PHYSICSFS
00370
00371 throw EmbeddedFileSystemManagerException(
00372 "EmbeddedFileSystemManager::getMountPointFor failed: "
00373 "no PhysicsFS support available." ) ;
00374
00375 #endif // OSDL_USES_PHYSICSFS
00376
00377 }
00378
00379
00380
00381 std::list<std::string> EmbeddedFileSystemManager::getSearchPath() const
00382 {
00383
00384
00385
00386
00387
00388
00389
00390 #if OSDL_USES_PHYSICSFS
00391
00392 char ** paths = PHYSFS_getSearchPath() ;
00393
00394 if ( paths == 0 )
00395 throw EmbeddedFileSystemManagerException(
00396 "EmbeddedFileSystemManager::getSearchPath failed: "
00397 + GetBackendLastError() ) ;
00398
00399 list<string> res ;
00400
00401
00402 for ( ; *paths != 0; paths++ )
00403 res.push_back( string( *paths ) ) ;
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415 return res ;
00416
00417 #else // OSDL_USES_PHYSICSFS
00418
00419 throw EmbeddedFileSystemManagerException(
00420 "EmbeddedFileSystemManager::getSearchPath failed: "
00421 "no PhysicsFS support available." ) ;
00422
00423 #endif // OSDL_USES_PHYSICSFS
00424
00425 }
00426
00427
00428
00429
00430
00431
00432
00433 bool EmbeddedFileSystemManager::existsAsEntry( const string & entryPath ) const
00434 {
00435
00436
00437
00438
00439
00440
00441
00442 #if OSDL_USES_PHYSICSFS
00443
00444
00445 return ( PHYSFS_exists( Ceylan::encodeToROT13(entryPath).c_str() ) != 0 ) ;
00446
00447 #else // OSDL_USES_PHYSICSFS
00448
00449 throw EmbeddedFileSystemManagerException(
00450 "EmbeddedFileSystemManager::existsAsEntry failed: "
00451 "no PhysicsFS support available." ) ;
00452
00453 #endif // OSDL_USES_PHYSICSFS
00454
00455 }
00456
00457
00458
00459 void EmbeddedFileSystemManager::createSymbolicLink(
00460 const string & linkTarget, const string & linkName )
00461 {
00462
00463 throw SymlinkFailed( "EmbeddedFileSystemManager::createSymbolicLink: "
00464 "symbolic link feature not available on PhysicsFS." ) ;
00465
00466 }
00467
00468
00469
00470 time_t EmbeddedFileSystemManager::getEntryChangeTime( const string & entryPath )
00471 {
00472
00473
00474
00475
00476
00477
00478
00479 #if OSDL_USES_PHYSICSFS
00480
00481 PHYSFS_sint64 time = PHYSFS_getLastModTime(
00482 Ceylan::encodeToROT13( entryPath ).c_str() ) ;
00483
00484 if ( time == -1 )
00485 throw GetChangeTimeFailed(
00486 "EmbeddedFileSystemManager::getEntryChangeTime failed: "
00487 + GetBackendLastError() ) ;
00488
00489 return static_cast<time_t>( time ) ;
00490
00491 #else // OSDL_USES_PHYSICSFS
00492
00493 throw GetChangeTimeFailed(
00494 "EmbeddedFileSystemManager::getEntryChangeTime failed: "
00495 "no PhysicsFS support available." ) ;
00496
00497 #endif // OSDL_USES_PHYSICSFS
00498
00499 }
00500
00501
00502
00503
00504
00505
00506
00507
00508 const string & EmbeddedFileSystemManager::getRootDirectoryPrefix() const
00509 {
00510
00511 return RootDirectoryPrefix ;
00512
00513 }
00514
00515
00516
00517 Ceylan::Latin1Char EmbeddedFileSystemManager::getSeparator() const
00518 {
00519
00520 return Separator ;
00521
00522 }
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532 File & EmbeddedFileSystemManager::createFile( const string & filename,
00533 OpeningFlag createFlag, PermissionFlag permissionFlag )
00534 {
00535
00536 return EmbeddedFile::Create( filename, createFlag, permissionFlag ) ;
00537
00538 }
00539
00540
00541
00542 File & EmbeddedFileSystemManager::openFile( const string & filename,
00543 OpeningFlag openFlag )
00544 {
00545
00546 send( "EmbeddedFileSystemManager::openFile: opening '" + filename + "'." ) ;
00547 return EmbeddedFile::Open( filename, openFlag ) ;
00548
00549 }
00550
00551
00552
00553 string EmbeddedFileSystemManager::getActualLocationFor(
00554 const string & filename ) const
00555 {
00556
00557 #if OSDL_USES_PHYSICSFS
00558
00559 const char * res = PHYSFS_getRealDir(
00560 Ceylan::encodeToROT13( filename ).c_str() ) ;
00561
00562 if ( res == 0 )
00563 throw Ceylan::System::FileLookupFailed(
00564 "EmbeddedFileSystemManager::getActualLocationFor failed: "
00565 + GetBackendLastError() ) ;
00566
00567 string actualRes( res ) ;
00568
00569 if ( actualRes.size() == 0 )
00570 throw EmbeddedFileSystemManagerException(
00571 "EmbeddedFileSystemManager::getActualLocationFor failed: "
00572 "file '" + actualRes + "' not found." ) ;
00573
00574 return actualRes ;
00575
00576 #else // OSDL_USES_PHYSICSFS
00577
00578 throw Ceylan::System::FileLookupFailed(
00579 "EmbeddedFileSystemManager::getActualLocationFor failed: "
00580 "no PhysicsFS support available." ) ;
00581
00582 #endif // OSDL_USES_PHYSICSFS
00583
00584 }
00585
00586
00587
00588 bool EmbeddedFileSystemManager::existsAsFileOrSymbolicLink(
00589 const string & filename ) const
00590 {
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601 #if OSDL_USES_PHYSICSFS
00602
00603 string actualPath = Ceylan::encodeToROT13( filename ) ;
00604
00605 return ( ( ::PHYSFS_exists( actualPath.c_str() ) != 0 )
00606 && ( ::PHYSFS_isDirectory( actualPath.c_str() ) == 0 ) ) ;
00607
00608 #else // OSDL_USES_PHYSICSFS
00609
00610 throw FileLookupFailed(
00611 "EmbeddedFileSystemManager::existsAsSymbolicLink failed: "
00612 "no PhysicsFS support available." ) ;
00613
00614 #endif // OSDL_USES_PHYSICSFS
00615
00616 }
00617
00618
00619
00620 bool EmbeddedFileSystemManager::existsAsSymbolicLink(
00621 const std::string & linkName ) const
00622 {
00623
00624
00625
00626
00627
00628
00629
00630 #if OSDL_USES_PHYSICSFS
00631
00632 return ( PHYSFS_isSymbolicLink(
00633 Ceylan::encodeToROT13( linkName ).c_str() ) != 0 ) ;
00634
00635 #else // OSDL_USES_PHYSICSFS
00636
00637 throw FileLookupFailed(
00638 "EmbeddedFileSystemManager::existsAsSymbolicLink failed: "
00639 "no PhysicsFS support available." ) ;
00640
00641 #endif // OSDL_USES_PHYSICSFS
00642
00643 }
00644
00645
00646
00647 void EmbeddedFileSystemManager::removeFile( const string & filename )
00648 {
00649
00650
00651
00652
00653
00654
00655
00656 #if OSDL_USES_PHYSICSFS
00657
00658 if ( PHYSFS_delete( Ceylan::encodeToROT13( filename ).c_str() ) == 0 )
00659 throw FileRemoveFailed(
00660 "EmbeddedFileSystemManager::removeFile failed: "
00661 + GetBackendLastError() ) ;
00662
00663 #else // OSDL_USES_PHYSICSFS
00664
00665 throw FileRemoveFailed( "EmbeddedFileSystemManager::removeFile failed: "
00666 "no PhysicsFS support available." ) ;
00667
00668 #endif // OSDL_USES_PHYSICSFS
00669
00670 }
00671
00672
00673
00674 void EmbeddedFileSystemManager::moveFile( const string & sourceFilename,
00675 const string & targetFilename )
00676 {
00677
00678 throw FileMoveFailed( "EmbeddedFileSystemManager::moveFile failed: "
00679 "not supported." ) ;
00680
00681 }
00682
00683
00684
00685 void EmbeddedFileSystemManager::copyFile( const string & sourceFilename,
00686 const string & targetFilename )
00687 {
00688
00689 try
00690 {
00691
00692 Size fileSize = getSize( sourceFilename ) ;
00693
00694 EmbeddedFile & sourceFile = EmbeddedFile::Open( sourceFilename ) ;
00695
00696
00697 EmbeddedFile & targetFile = EmbeddedFile::Create(
00698 targetFilename, File::CreateToWriteBinary, File::OwnerReadWrite ) ;
00699
00700 Size written = 0 ;
00701
00702 Size bufferSize = ( fileSize > File::BigBufferSize ?
00703 File::BigBufferSize: fileSize ) ;
00704
00705 char * buf = new char[ bufferSize ] ;
00706
00707 SignedSize readCount ;
00708
00709 while ( written < fileSize )
00710 {
00711
00712 Size toRead = fileSize - written ;
00713
00714 if ( toRead > bufferSize )
00715 toRead = bufferSize ;
00716
00717 try
00718 {
00719
00720 readCount = static_cast<SignedSize>(
00721 sourceFile.read( buf, toRead ) ) ;
00722
00723 }
00724 catch( const InputStream::ReadFailedException & e )
00725 {
00726
00727 delete [] buf ;
00728
00729 throw FileCopyFailed( "EmbeddedFileSystemManager::copyFile "
00730 "failed when copying '" + sourceFilename + "' to '"
00731 + targetFilename + "': " + e.toString() ) ;
00732
00733 }
00734
00735
00736 try
00737 {
00738
00739 targetFile.write( buf, readCount ) ;
00740
00741 }
00742 catch( const OutputStream::WriteFailedException & e )
00743 {
00744
00745 delete [] buf ;
00746
00747 throw FileCopyFailed( "EmbeddedFileSystemManager::copyFile "
00748 "failed when copying '" + sourceFilename + "' to '"
00749 + targetFilename + "': " + e.toString() ) ;
00750
00751 }
00752
00753 written += readCount ;
00754 }
00755
00756 delete [] buf ;
00757
00758 targetFile.close() ;
00759 sourceFile.close() ;
00760
00761 }
00762 catch ( const SystemException & e )
00763 {
00764
00765 throw FileCopyFailed( "EmbeddedFileSystemManager::copyFile "
00766 "failed when copying '" + sourceFilename + "' to '"
00767 + targetFilename + "': " + e.toString() ) ;
00768
00769 }
00770
00771
00772 }
00773
00774
00775
00776 Size EmbeddedFileSystemManager::getSize( const string & filename )
00777 {
00778
00779
00780
00781
00782
00783
00784
00785 #if OSDL_USES_PHYSICSFS
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796 File & tmpFile = File::Create( filename, Ceylan::System::File::Read ) ;
00797
00798 Size fileSize = tmpFile.size() ;
00799
00800 delete & tmpFile ;
00801
00802 return fileSize ;
00803
00804 #else // OSDL_USES_PHYSICSFS
00805
00806 throw FileSizeRequestFailed(
00807 "EmbeddedFileSystemManager::getSize failed: "
00808 "no PhysicsFS support available." ) ;
00809
00810 #endif // OSDL_USES_PHYSICSFS
00811
00812 }
00813
00814
00815
00816 time_t EmbeddedFileSystemManager::getLastChangeTimeFile(
00817 const string & filename )
00818 {
00819
00820
00821
00822
00823
00824
00825
00826 #if OSDL_USES_PHYSICSFS
00827
00828 PHYSFS_sint64 time = PHYSFS_getLastModTime(
00829 Ceylan::encodeToROT13( filename ).c_str() ) ;
00830
00831 if ( time == -1 )
00832 throw FileLastChangeTimeRequestFailed(
00833 "EmbeddedFileSystemManager::getLastChangeTimeFile failed: "
00834 + GetBackendLastError() ) ;
00835
00836 return static_cast<time_t>( time ) ;
00837
00838 #else // OSDL_USES_PHYSICSFS
00839
00840 throw FileLastChangeTimeRequestFailed(
00841 "EmbeddedFileSystemManager::getLastChangeTimeFile failed: "
00842 "no PhysicsFS support available." ) ;
00843
00844 #endif // OSDL_USES_PHYSICSFS
00845
00846 }
00847
00848
00849
00850 void EmbeddedFileSystemManager::touch( const string & filename )
00851 {
00852
00853 throw FileTouchFailed( "EmbeddedFileSystemManager::touch "
00854 "operation not available on embedded filesystems." ) ;
00855
00856 }
00857
00858
00859
00860 void EmbeddedFileSystemManager::allowSymbolicFiles( bool newStatus )
00861 {
00862
00863
00864
00865
00866
00867
00868
00869 #if OSDL_USES_PHYSICSFS
00870
00871 PHYSFS_permitSymbolicLinks( ( newStatus ? 1 : 0 ) ) ;
00872
00873 #else // OSDL_USES_PHYSICSFS
00874
00875 throw FileRemoveFailed(
00876 "EmbeddedFileSystemManager::allowSymbolicFiles failed: "
00877 "no PhysicsFS support available." ) ;
00878
00879 #endif // OSDL_USES_PHYSICSFS
00880
00881 }
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894 Directory & EmbeddedFileSystemManager::createDirectory(
00895 const string & newDirectoryName )
00896 {
00897
00898 return EmbeddedDirectory::Create( newDirectoryName ) ;
00899
00900 }
00901
00902
00903
00904 Directory & EmbeddedFileSystemManager::openDirectory(
00905 const string & directoryName )
00906 {
00907
00908 return EmbeddedDirectory::Open( directoryName ) ;
00909
00910 }
00911
00912
00913
00914 bool EmbeddedFileSystemManager::existsAsDirectory(
00915 const string & directoryPath ) const
00916 {
00917
00918
00919
00920
00921
00922
00923
00924 #if OSDL_USES_PHYSICSFS
00925
00926 return ( PHYSFS_isDirectory(
00927 Ceylan::encodeToROT13( directoryPath ).c_str() ) != 0 ) ;
00928
00929 #else // OSDL_USES_PHYSICSFS
00930
00931 throw DirectoryLookupFailed(
00932 "EmbeddedFileSystemManager::existsAsDirectory failed: "
00933 "no PhysicsFS support available." ) ;
00934
00935 #endif // OSDL_USES_PHYSICSFS
00936
00937 }
00938
00939
00940
00941 void EmbeddedFileSystemManager::removeDirectory( const string & directoryPath,
00942 bool recursive )
00943 {
00944
00945
00946
00947
00948
00949
00950
00951 #if OSDL_USES_PHYSICSFS
00952
00953 if ( directoryPath.empty() )
00954 throw DirectoryRemoveFailed(
00955 "EmbeddedFileSystemManager::removeDirectory: "
00956 "void directory specified" ) ;
00957
00958 if ( recursive )
00959 throw DirectoryRemoveFailed(
00960 "EmbeddedFileSystemManager::removeDirectory: "
00961 "no recursive operation supported" ) ;
00962
00963 if ( PHYSFS_delete( Ceylan::encodeToROT13( directoryPath ).c_str() ) == 0 )
00964 throw DirectoryRemoveFailed(
00965 "EmbeddedFileSystemManager::removeDirectory failed in 'rmdir' for "
00966 + directoryPath + ": " + GetBackendLastError() ) ;
00967
00968 #else // OSDL_USES_PHYSICSFS
00969
00970 throw EmbeddedFileSystemManagerException(
00971 "EmbeddedFileSystemManager::removeDirectory failed: "
00972 "no PhysicsFS support available." ) ;
00973
00974 #endif // OSDL_USES_PHYSICSFS
00975
00976 }
00977
00978
00979
00980 void EmbeddedFileSystemManager::moveDirectory(
00981 const string & sourceDirectoryPath, const string & targetDirectoryPath )
00982 {
00983
00984 throw DirectoryMoveFailed( "EmbeddedFileSystemManager::moveDirectory: "
00985 "operation not available on embedded filesystems." ) ;
00986
00987 }
00988
00989
00990
00991 void EmbeddedFileSystemManager::copyDirectory(
00992 const string & sourceDirectoryPath, const string & targetDirectoryPath )
00993 {
00994
00995 throw DirectoryCopyFailed( "EmbeddedFileSystemManager::copyDirectory: "
00996 "operation not available on embedded filesystems." ) ;
00997
00998 }
00999
01000
01001
01002 time_t EmbeddedFileSystemManager::getLastChangeTimeDirectory(
01003 const string & directoryPath )
01004 {
01005
01006
01007
01008
01009
01010
01011
01012 #if OSDL_USES_PHYSICSFS
01013
01014 PHYSFS_sint64 time = PHYSFS_getLastModTime(
01015 Ceylan::encodeToROT13( directoryPath ).c_str() ) ;
01016
01017 if ( time == -1 )
01018 throw DirectoryLastChangeTimeRequestFailed(
01019 "EmbeddedFileSystemManager::getLastChangeTimeDirectory failed: "
01020 + GetBackendLastError() ) ;
01021
01022 return static_cast<time_t>( time ) ;
01023
01024 #else // OSDL_USES_PHYSICSFS
01025
01026 throw DirectoryLastChangeTimeRequestFailed(
01027 "EmbeddedFileSystemManager::getLastChangeTimeDirectory failed: "
01028 "no PhysicsFS support available." ) ;
01029
01030 #endif // OSDL_USES_PHYSICSFS
01031
01032 }
01033
01034
01035
01036 bool EmbeddedFileSystemManager::isAValidDirectoryPath(
01037 const string & directoryString )
01038 {
01039
01040
01041 return true ;
01042
01043 }
01044
01045
01046
01047 bool EmbeddedFileSystemManager::isAbsolutePath( const string & path )
01048 {
01049
01050
01051
01052 if ( path.empty() )
01053 return false ;
01054
01055
01056
01057
01058
01059
01060
01061 return ( path[0] == Separator ) ;
01062
01063 }
01064
01065
01066
01067 std::string EmbeddedFileSystemManager::getCurrentWorkingDirectoryPath()
01068 {
01069
01070
01071
01072 #ifdef CEYLAN_USES_GETCWD
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087 char * buf = new char[ PATH_MAX + 1 ] ;
01088
01089 if ( ::getcwd( buf, PATH_MAX ) )
01090 {
01091
01092 string res( buf ) ;
01093 delete [] buf ;
01094
01095 return res ;
01096
01097 }
01098 else
01099 {
01100
01101 delete [] buf ;
01102
01103 throw DirectoryGetCurrentFailed(
01104 "EmbeddedFileSystemManager::getCurrentWorkingDirectoryPath: "
01105 "unable to determine current directory: " + explainError() ) ;
01106
01107 }
01108
01109 #else // CEYLAN_USES_GETCWD
01110
01111 #ifdef CEYLAN_USES__GETCWD
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127 char * buf = new char[ PATH_MAX + 1 ] ;
01128
01129 if ( ::_getcwd( buf, PATH_MAX ) )
01130 {
01131
01132 string res( buf ) ;
01133 delete [] buf ;
01134
01135 return res ;
01136
01137 }
01138 else
01139 {
01140
01141 delete [] buf ;
01142
01143 throw DirectoryGetCurrentFailed(
01144 "EmbeddedFileSystemManager::getCurrentWorkingdirectoryPath: "
01145 "unable to determine current directory: " + explainError() ) ;
01146
01147 }
01148
01149 #else // CEYLAN_USES__GETCWD
01150
01151 throw DirectoryGetCurrentFailed(
01152 "EmbeddedFileSystemManager::getCurrentWorkingdirectoryPath: "
01153 "not available on this platform" ) ;
01154
01155 #endif // CEYLAN_USES__GETCWD
01156
01157 #endif // CEYLAN_USES_GETCWD
01158
01159 }
01160
01161
01162
01163 void EmbeddedFileSystemManager::changeWorkingDirectory(
01164 const string & newWorkingDirectory )
01165 {
01166
01167
01168
01169 #ifdef CEYLAN_USES_CHDIR
01170
01171 if ( ::chdir( newWorkingDirectory.c_str() ) != 0 )
01172
01173 #else // CEYLAN_USES_CHDIR
01174
01175 #ifdef CEYLAN_USES__CHDIR
01176
01177 if ( ::_chdir( newWorkingDirectory.c_str() ) != 0 )
01178
01179 #else // CEYLAN_USES__CHDIR
01180
01181 throw DirectoryChangeFailed(
01182 "EmbeddedFileSystemManager::changeWorkingDirectory: "
01183 "not supported on this platform" ) ;
01184
01185 #endif // CEYLAN_USES__CHDIR
01186
01187 #endif // CEYLAN_USES_CHDIR
01188
01189
01190
01191 throw DirectoryChangeFailed(
01192 "EmbeddedFileSystemManager::changeWorkingDirectory: "
01193 "unable to change current working directory to "
01194 + newWorkingDirectory + ": " + explainError() ) ;
01195
01196 send( "Changed working directory to '" + newWorkingDirectory + "'." ) ;
01197
01198 }
01199
01200
01201
01202
01203
01204
01205
01206
01207 std::string EmbeddedFileSystemManager::GetBackendLastError()
01208 {
01209
01210
01211
01212 return string( PHYSFS_getLastError() ) ;
01213
01214 }
01215
01216
01217
01218 Ceylan::Byte EmbeddedFileSystemManager::GetXORByte()
01219 {
01220
01221 return XORByte ;
01222
01223 }
01224
01225
01226
01227 const string EmbeddedFileSystemManager::toString(
01228 Ceylan::VerbosityLevels level ) const
01229 {
01230
01231 return "Embedded filesystem manager, based on the PhysicsFS backend" ;
01232
01233 }
01234
01235
01236
01237
01238
01239
01240
01241
01242 EmbeddedFileSystemManager &
01243 EmbeddedFileSystemManager::GetEmbeddedFileSystemManager( bool cypher )
01244 {
01245
01246 if ( _EmbeddedFileSystemManager == 0 )
01247 _EmbeddedFileSystemManager = new EmbeddedFileSystemManager(
01248 cypher ) ;
01249
01250 return *_EmbeddedFileSystemManager ;
01251
01252 }
01253
01254
01255
01256 bool EmbeddedFileSystemManager::SecureEmbeddedFileSystemManager()
01257 {
01258
01259
01260 GetEmbeddedFileSystemManager( true ) ;
01261
01262
01263 return true ;
01264
01265 }
01266
01267
01268
01269 void EmbeddedFileSystemManager::RemoveEmbeddedFileSystemManager()
01270 {
01271
01272 if ( _EmbeddedFileSystemManager != 0 )
01273 {
01274
01275 if ( FileSystemManager::_CurrentDefaultFileSystemManager ==
01276 _EmbeddedFileSystemManager )
01277 FileSystemManager::_CurrentDefaultFileSystemManager = 0 ;
01278
01279 delete _EmbeddedFileSystemManager ;
01280 _EmbeddedFileSystemManager = 0 ;
01281
01282 }
01283
01284 }
01285
01286
01287
01288
01289 EmbeddedFileSystemManager::EmbeddedFileSystemManager( bool cypherWritings ) :
01290 _cypher( cypherWritings )
01291 {
01292
01293 #if OSDL_USES_PHYSICSFS
01294
01295 PHYSFS_Version compileTimePhysicsFSVersion ;
01296 PHYSFS_VERSION( &compileTimePhysicsFSVersion ) ;
01297
01298 PHYSFS_Version linkTimePhysicsFSVersion ;
01299 PHYSFS_getLinkedVersion( &linkTimePhysicsFSVersion ) ;
01300
01301 Ceylan::Version compiledAgainstVersion( compileTimePhysicsFSVersion.major,
01302 compileTimePhysicsFSVersion.minor, compileTimePhysicsFSVersion.patch ) ;
01303
01304 Ceylan::Version currentLinkedVersion( linkTimePhysicsFSVersion.major,
01305 linkTimePhysicsFSVersion.minor, linkTimePhysicsFSVersion.patch ) ;
01306
01307 send( "Using PhysicsFS backend, compiled against the "
01308 + compiledAgainstVersion.toString( Ceylan::low )
01309 + " version, linked against the "
01310 + currentLinkedVersion.toString( Ceylan::low ) + " version." ) ;
01311
01312 Ceylan::Version minLinkedVersion( "2.0.0" ) ;
01313
01314 if ( currentLinkedVersion < minLinkedVersion )
01315 {
01316
01317 throw EmbeddedFileSystemManagerException(
01318 "EmbeddedFileSystemManager constructor failed: currently "
01319 "linked against the PhysicsFS version "
01320 + currentLinkedVersion.toString( Ceylan::low )
01321 + ", whereas needing at least the "
01322 + minLinkedVersion.toString( Ceylan::low ) + " version." ) ;
01323
01324 }
01325 else
01326 {
01327
01328 send( "The version of PhysicsFS currently linked ("
01329 + currentLinkedVersion.toString( Ceylan::low )
01330 + ") is recent enough (needing at least the "
01331 + minLinkedVersion.toString( Ceylan::low ) + " version)." ) ;
01332
01333 }
01334
01335
01336 if ( PHYSFS_init( LogPlug::GetFullExecutablePath().c_str() ) == 0 )
01337 throw EmbeddedFileSystemManagerException(
01338 "EmbeddedFileSystemManager constructor failed: "
01339 + GetBackendLastError() ) ;
01340
01341 list<string> archiveTypes ;
01342
01343 string res = "Supported archive types are: " ;
01344
01345 const PHYSFS_ArchiveInfo ** i = PHYSFS_supportedArchiveTypes() ;
01346
01347 for ( ; *i != 0; i++ )
01348 {
01349
01350 archiveTypes.push_back( string( (*i)->extension ) + ", which is "
01351 + string( (*i)->description ) ) ;
01352
01353 }
01354
01355 res += Ceylan::formatStringList( archiveTypes ) ;
01356
01357 send( res ) ;
01358
01359 if ( _cypher )
01360 {
01361
01362 send( "Cyphered writes and reads will be performed." ) ;
01363
01364 }
01365 else
01366 {
01367
01368 send( "Raw (not cyphered) writes and reads will be performed." ) ;
01369
01370 }
01371
01372
01373 #else // OSDL_USES_PHYSICSFS
01374
01375 throw EmbeddedFileSystemManagerException(
01376 "EmbeddedFileSystemManager constructor failed: "
01377 "no PhysicsFS support available." ) ;
01378
01379 #endif // OSDL_USES_PHYSICSFS
01380
01381 }
01382
01383
01384
01385 EmbeddedFileSystemManager::~EmbeddedFileSystemManager() throw()
01386 {
01387
01388 #if OSDL_USES_PHYSICSFS
01389
01390 send( "Deleting embedded filesystem manager." ) ;
01391
01392 if ( PHYSFS_deinit() == 0 )
01393 LogPlug::error( "EmbeddedFileSystemManager destructor failed: "
01394 + GetBackendLastError() ) ;
01395
01396 #endif // OSDL_USES_PHYSICSFS
01397
01398 if ( _EmbeddedFileSystemManager == this )
01399 _EmbeddedFileSystemManager = 0 ;
01400
01401 }
01402
01403
01404
01405 string EmbeddedFileSystemManager::FindArchivePath(
01406 const std::string & archiveFilename )
01407 {
01408
01409 string archiveFullPath = archiveFilename ;
01410
01411
01412 if ( ! File::ExistsAsFileOrSymbolicLink( archiveFullPath ) )
01413 {
01414
01415
01416 try
01417 {
01418
01419 archiveFullPath = ArchiveFileLocator.find(
01420 archiveFullPath ) ;
01421
01422 }
01423 catch( const FileLocatorException & e )
01424 {
01425
01426
01427
01428 string currentDir ;
01429
01430 try
01431 {
01432 currentDir = Directory::GetCurrentWorkingDirectoryPath() ;
01433 }
01434 catch( const DirectoryException & exc )
01435 {
01436
01437 throw EmbeddedFileSystemManagerException(
01438 "Archive::FindArchivePath: unable to find '"
01439 + archiveFilename
01440 + "', exception generation triggered another failure: "
01441 + exc.toString() + "." ) ;
01442 }
01443
01444 throw EmbeddedFileSystemManagerException(
01445 "Archive::FindArchivePath: '" + archiveFilename
01446 + "' is not a regular file nor a symbolic link "
01447 "relative to the current directory (" + currentDir
01448 + ") and cannot be found through archive locator ("
01449 + ArchiveFileLocator.toString()
01450 + ") based on archive path environment variable ("
01451 + ArchivePathEnvironmentVariable + ")." ) ;
01452
01453 }
01454 }
01455
01456 return archiveFullPath ;
01457
01458 }
01459