sfxFileStream.cpp
Engine/source/sfx/sfxFileStream.cpp
Detailed Description
1 2//----------------------------------------------------------------------------- 3// Copyright (c) 2012 GarageGames, LLC 4// 5// Permission is hereby granted, free of charge, to any person obtaining a copy 6// of this software and associated documentation files (the "Software"), to 7// deal in the Software without restriction, including without limitation the 8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9// sell copies of the Software, and to permit persons to whom the Software is 10// furnished to do so, subject to the following conditions: 11// 12// The above copyright notice and this permission notice shall be included in 13// all copies or substantial portions of the Software. 14// 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21// IN THE SOFTWARE. 22//----------------------------------------------------------------------------- 23 24#include "sfx/sfxFileStream.h" 25#include "core/stream/fileStream.h" 26#include "console/console.h" 27#include "core/util/safeDelete.h" 28 29 30SFXFileStream::ExtensionsVector SFXFileStream::smExtensions( __FILE__, __LINE__ ); 31SFXFileStream::CreateFnsVector SFXFileStream::smCreateFns( __FILE__, __LINE__ ); 32 33 34void SFXFileStream::registerExtension( String ext, SFXFILESTREAM_CREATE_FN create_fn ) 35{ 36 // Register the stream creation first. 37 smExtensions.push_back( ext ); 38 smCreateFns.push_back( create_fn ); 39} 40 41void SFXFileStream::unregisterExtension( String ext ) 42{ 43 for( ExtensionsVector::iterator iter = smExtensions.begin(); 44 iter != smExtensions.end(); ++ iter ) 45 if( ( *iter ).equal( ext, String::NoCase ) ) 46 { 47 smExtensions.erase( iter ); 48 return; 49 } 50} 51 52SFXFileStream* SFXFileStream::create( String filename ) 53{ 54 //RDTODO: if original file has an extension, we should try that first 55 56 // First strip off our current extension (validating 57 // against a list of known extensions so that we don't 58 // strip off the last part of a file name with a dot in it. 59 60 String noExtension = Platform::stripExtension( filename, smExtensions ); 61 62 SFXFileStream *sfxStream = NULL; 63 64 for( U32 i = 0; i < smExtensions.size(); i++ ) 65 { 66 String testName = noExtension + smExtensions[ i ]; 67 68 Stream *stream = FileStream::createAndOpen( testName, Torque::FS::File::Read ); 69 if ( !stream ) 70 continue; 71 72 // Note that the creation function swallows up the 73 // resource stream and will take care of deleting it. 74 sfxStream = smCreateFns[i]( stream ); 75 if ( sfxStream ) 76 return sfxStream; 77 } 78 79 return NULL; 80} 81 82bool SFXFileStream::exists( String filename ) 83{ 84 // First strip off our current extension (validating 85 // against a list of known extensions so that we don't 86 // strip off the last part of a file name with a dot in it. 87 88 String noExtension = Platform::stripExtension( filename, smExtensions ); 89 90 for( U32 i = 0; i < smExtensions.size(); i++ ) 91 { 92 String testName = noExtension + smExtensions[ i ]; 93 if( Torque::FS::IsFile( testName ) ) 94 return true; 95 } 96 97 return false; 98} 99 100SFXFileStream::SFXFileStream() 101 : mStream( NULL ), 102 mOwnStream( false ), 103 mFormat( 0, 0, 0 ), 104 mSamples( 0 ) 105{ 106} 107 108SFXFileStream::SFXFileStream( const SFXFileStream& cloneFrom ) 109{ 110 mStream = cloneFrom.mStream->clone(); 111 if( !mStream ) 112 { 113 Con::errorf( "SFXFileStream::SFXFileStream() - Failed to clone source stream" ); 114 return; 115 } 116 117 mOwnStream = true; 118 mFormat = cloneFrom.mFormat; 119 mSamples = cloneFrom.mSamples; 120} 121 122 123SFXFileStream::~SFXFileStream() 124{ 125 // If the stream is still open, close it now. _close() 126 // should usually be called by the destructor of derived classes, 127 // but it their constructor fails, these won't even run. 128 129 if( mStream && mOwnStream ) 130 SAFE_DELETE( mStream ); 131} 132 133bool SFXFileStream::open( Stream *stream, bool ownStream ) 134{ 135 AssertFatal( stream, "SFXFileStream::open() - Got null stream!" ); 136 137 close(); 138 139 mStream = stream; 140 mOwnStream = ownStream; 141 142 if( _readHeader() ) 143 { 144 reset(); // Make sure we're set to read sample data. 145 return true; 146 } 147 else 148 return false; 149} 150 151void SFXFileStream::close() 152{ 153 if ( !mStream ) 154 return; 155 156 // Let the overloaded class cleanup. 157 _close(); 158 159 // We only close it if we own it. 160 if ( mOwnStream ) 161 SAFE_DELETE( mStream ); 162 163 // Reset these to make it easier to detect bugs. 164 mFormat.set( 0, 0, 0 ); 165 mSamples = 0; 166} 167 168bool SFXFileStream::isEOS() const 169{ 170 if ( !mStream ) 171 return true; 172 173 return mStream->getStatus() != Stream::Ok; 174} 175