sfxMemoryStream.cpp
Engine/source/sfx/sfxMemoryStream.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/sfxMemoryStream.h" 25#include "platform/typetraits.h" 26#include "console/console.h" 27 28 29SFXMemoryStream::SFXMemoryStream( const SFXFormat& format, 30 SourceStreamType* stream, 31 U32 numSamples ) 32 : IInputStreamFilter< U8, SourceStreamType* >( stream ), 33 mFormat( format ), 34 mNumSamplesTotal( numSamples ), 35 mNumSamplesLeft( numSamples ), 36 mCurrentPacket( NULL ), 37 mCurrentPacketOffset( 0 ) 38{ 39} 40 41void SFXMemoryStream::reset() 42{ 43 if( dynamic_cast< IResettable* >( getSourceStream() ) ) 44 { 45 reinterpret_cast< IResettable* >( getSourceStream() )->reset(); 46 47 if( mCurrentPacket ) 48 destructSingle( mCurrentPacket ); 49 50 mCurrentPacket = NULL; 51 mCurrentPacketOffset = 0; 52 mNumSamplesLeft = mNumSamplesTotal; 53 } 54 else 55 Con::errorf( "SFXMemoryStream - cannot reset source stream" ); 56} 57 58U32 SFXMemoryStream::read( U8* buffer, U32 length ) 59{ 60 U32 bufferOffset = 0; 61 62 // Determine how much we're supposed to read. 63 64 U32 numBytesToCopy = length; 65 if( mNumSamplesLeft != U32_MAX ) 66 numBytesToCopy = getMin( length, mNumSamplesLeft * mFormat.getBytesPerSample() ); 67 numBytesToCopy -= numBytesToCopy % mFormat.getBytesPerSample(); 68 69 // Copy the data. 70 71 U32 numBytesLeftToCopy = numBytesToCopy; 72 while( numBytesLeftToCopy ) 73 { 74 // If we have a current packet, use its data. 75 76 if( mCurrentPacket ) 77 { 78 U32 numBytesLeftInCurrentPacket = mCurrentPacket->size - mCurrentPacketOffset; 79 80 // Copy data. 81 82 if( numBytesLeftInCurrentPacket ) 83 { 84 const U32 remainingNumBytesToCopy = getMin( numBytesLeftInCurrentPacket, numBytesLeftToCopy ); 85 dMemcpy( &buffer[ bufferOffset ], &mCurrentPacket->data[ mCurrentPacketOffset ], remainingNumBytesToCopy); 86 87 bufferOffset += remainingNumBytesToCopy; 88 mCurrentPacketOffset += remainingNumBytesToCopy; 89 numBytesLeftInCurrentPacket -= remainingNumBytesToCopy; 90 numBytesLeftToCopy -= remainingNumBytesToCopy; 91 } 92 93 // Discard the packet if there's no data left. 94 95 if( !numBytesLeftInCurrentPacket ) 96 { 97 destructSingle( mCurrentPacket ); 98 mCurrentPacket = NULL; 99 mCurrentPacketOffset = 0; 100 } 101 } 102 else 103 { 104 // Read a new packet. 105 106 if( !getSourceStream()->read( &mCurrentPacket, 1 ) ) 107 break; 108 } 109 } 110 111 // Update count of remaining samples. 112 113 U32 numBytesCopied = numBytesToCopy - numBytesLeftToCopy; 114 if( mNumSamplesLeft != U32_MAX ) 115 mNumSamplesLeft -= ( numBytesCopied / mFormat.getBytesPerSample() ); 116 117 return numBytesCopied; 118} 119