00001 // mmfdes.cpp 00002 // 00003 // Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies). 00004 // All rights reserved. 00005 // This component and the accompanying materials are made available 00006 // under the terms of "Eclipse Public License v1.0" 00007 // which accompanies this distribution, and is available 00008 // at the URL "http://www.eclipse.org/legal/epl-v10.html". 00009 // 00010 // Initial Contributors: 00011 // Nokia Corporation - initial contribution. 00012 // 00013 // Contributors: 00014 // 00015 // Description: 00016 // 00017 00018 00019 00020 #include <f32file.h> 00021 #include <e32std.h> 00022 #include <mmfdatabuffer.h> 00023 00024 #include "mmfexdes.h" 00025 #include "MmfExSinkSourceUIDs.hrh" 00026 00027 // Panic function 00028 void Panic(TMMFExDescriptorPanicCode aPanicCode) 00029 { 00030 _LIT(KMMFExDescriptorPanicCategory, "MMFExDescriptor"); 00031 User::Panic(KMMFExDescriptorPanicCategory, aPanicCode); 00032 } 00033 00034 // 00035 // CMMFExDescriptor 00036 // 00037 00038 // Plugin implementation UIDs 00039 const TUid KDescriptorSourceUIDObject = {KDescriptorSourceUID}; 00040 const TUid KDescriptorSinkUIDObject = {KDescriptorSinkUID}; 00041 00042 // Constructor 00043 CMMFExDescriptor::CMMFExDescriptor( ) : CMMFClip( TUid(KDescriptorSourceUIDObject), TUid(KDescriptorSinkUIDObject )) 00044 { 00045 iOffset = 0 ; 00046 } 00047 00048 // Destructor 00049 CMMFExDescriptor::~CMMFExDescriptor() 00050 { 00051 iDesThread.Close() ; 00052 } 00053 00054 // Factory function for source plug-in 00055 MDataSource* CMMFExDescriptor::NewSourceL( ) 00056 { 00057 CMMFExDescriptor* self = new (ELeave) CMMFExDescriptor( ) ; 00058 return STATIC_CAST( MDataSource*, self ) ; 00059 } 00060 00061 // Factory function for sink plug-in 00062 MDataSink* CMMFExDescriptor::NewSinkL( ) 00063 { 00064 CMMFExDescriptor* self = new (ELeave) CMMFExDescriptor( ) ; 00065 return STATIC_CAST( MDataSink*, self ) ; 00066 } 00067 00068 // MDataSource factory 00069 // aInitData is a packaged TMMFExDescriptorParams 00070 void CMMFExDescriptor::ConstructSourceL( const TDesC8& aInitData ) 00071 { 00072 ConstructL( aInitData ) ; 00073 } 00074 00075 // MDataSink factory 00076 // aInitData is a packaged TMMFExDescriptorParams 00077 void CMMFExDescriptor::ConstructSinkL( const TDesC8& aInitData ) 00078 { 00079 ConstructL( aInitData ) ; 00080 } 00081 00082 // Construction helper 00083 // aInitData is a packaged TMMFExDescriptorParams 00084 void CMMFExDescriptor::ConstructL( const TDesC8& aInitData ) 00085 { 00086 // get descriptor to which to read/write, and the thread 00087 // to which it belongs 00088 TMMFExDescriptorParams params; 00089 TPckgC<TMMFExDescriptorParams> config(params); 00090 config.Set(aInitData); 00091 iDes = STATIC_CAST( TDes8*, config().iDes); 00092 User::LeaveIfError( iDesThread.Open( config().iDesThreadId ) ); 00093 } 00094 00095 00096 // From MDataSource 00097 00098 TFourCC CMMFExDescriptor::SourceDataTypeCode(TMediaId /*aMediaId*/) 00099 { 00100 return iSourceFourCC ; 00101 } 00102 00103 // Fills a buffer from the source descriptor 00104 void CMMFExDescriptor::FillBufferL( CMMFBuffer* aBuffer, MDataSink* aConsumer, TMediaId /*aMediaId*/ ) 00105 { 00106 // Current position in Descriptor is iOffset. 00107 00108 // Read from iDes in iDesThread into Des in aBuffer. 00109 00110 // Assume that the amount to be read is the size of the buffer descriptor 00111 // Should check that there is sufficient data in the source buffer 00112 // If there is not enough to fill the target then copy what there is 00113 00114 // Use of a single iOffset will preclude use by more than one client (use ReadBufferL()) 00115 if ( aBuffer->Type() == KUidMmfDataBuffer ) 00116 { 00117 TDes8& bufferDes = STATIC_CAST(CMMFDataBuffer*, aBuffer)->Data(); 00118 TInt targetMaxLength = bufferDes.MaxLength(); 00119 TInt sourceLength = iDes->Length(); 00120 00121 if ( ( sourceLength - iOffset - targetMaxLength ) > 0 ) 00122 { 00123 bufferDes = iDes->Mid(iOffset,targetMaxLength); 00124 iOffset += targetMaxLength; 00125 } 00126 else 00127 bufferDes.SetLength(0); 00128 00129 // Check if the buffer is the last buffer and if so set the last buffer flag on the CMMFDataBuffer 00130 TInt requestSize = aBuffer->RequestSize(); 00131 if (requestSize) 00132 { // The buffer has a request size - so assume last buffer if length is less than the request size 00133 if (bufferDes.Length() < requestSize) 00134 aBuffer->SetLastBuffer(ETrue); 00135 } 00136 else 00137 { // There is no request size so assume last buffer if length is less than the max length 00138 if (bufferDes.Length() < bufferDes.MaxLength()) 00139 aBuffer->SetLastBuffer(ETrue); 00140 } 00141 00142 aConsumer->BufferFilledL( aBuffer ) ; 00143 } 00144 else 00145 User::Leave(KErrNotSupported); 00146 } 00147 00148 // called by MDataSink to pass back emptied buffer to the source 00149 void CMMFExDescriptor::BufferEmptiedL( CMMFBuffer* /*aBuffer*/ ) 00150 { 00151 // not supported in this plug-in 00152 __ASSERT_DEBUG(EFalse, Panic(EMMFDescriptorPanicBufferEmptiedLNotSupported)); 00153 } 00154 00155 // tests if the plug-in can create a source buffer 00156 TBool CMMFExDescriptor::CanCreateSourceBuffer() 00157 { 00158 // this can't: it needs a descriptor from another thread 00159 return EFalse ; 00160 } 00161 00162 // creates a source buffer 00163 CMMFBuffer* CMMFExDescriptor::CreateSourceBufferL( TMediaId /*aMediaId*/, TBool& /*aReference*/ ) 00164 { 00165 // is not supported in this plug-in 00166 User::Leave(KErrNotSupported); 00167 return NULL; 00168 } 00169 00170 00171 // from MDataSink 00172 00173 // gets sink codec type 00174 TFourCC CMMFExDescriptor::SinkDataTypeCode(TMediaId /*aMediaId*/) 00175 { 00176 return iSinkFourCC ; 00177 } 00178 00179 // Empties supplied buffer into the sink descriptor 00180 void CMMFExDescriptor::EmptyBufferL( CMMFBuffer* aBuffer, MDataSource* aSupplier, TMediaId /*aMediaId*/ ) 00181 { 00182 // Current position in Descriptor is iOffset. 00183 00184 // Assume that the amount to be read is the size of the buffer descriptor 00185 // Should check that there is sufficient data in the source buffer 00186 // If there is not enough to fill the target then copy what there is 00187 00188 // Use of a single iOffset will preclude use by more than one client (use ReadBufferL()) 00189 00190 if ( aBuffer->Type() == KUidMmfDataBuffer ) 00191 { 00192 TDes8& bufferDes = STATIC_CAST(CMMFDataBuffer*, aBuffer)->Data(); 00193 00194 TInt sourceLength = bufferDes.Length() ; 00195 TInt targetLength = iDes->MaxLength() - iOffset; 00196 if ( targetLength>0 ) 00197 { 00198 if (sourceLength>targetLength) 00199 { 00200 sourceLength = targetLength; 00201 bufferDes.SetLength(targetLength); 00202 } 00203 00204 iDes->Append(bufferDes) ; 00205 00206 iOffset += sourceLength ; 00207 } 00208 else 00209 bufferDes.SetLength(0); 00210 00211 aSupplier->BufferEmptiedL( aBuffer ) ; 00212 } 00213 } 00214 00215 // called by MDataSource to pass back full buffer to the sink 00216 void CMMFExDescriptor::BufferFilledL( CMMFBuffer* /*aBuffer*/ ) 00217 { 00218 // not supported in this plug-in 00219 __ASSERT_DEBUG(EFalse, Panic(EMMFDescriptorPanicBufferFilledLNotSupported)); 00220 } 00221 00222 // tests if the plug-in can create a sink buffer 00223 TBool CMMFExDescriptor::CanCreateSinkBuffer() 00224 { 00225 // this can't: it needs a descriptor from another thread 00226 return EFalse ; 00227 } 00228 00229 // creates a sink buffer 00230 CMMFBuffer* CMMFExDescriptor::CreateSinkBufferL( TMediaId /*aMediaId*/ , TBool& /*aReference*/) 00231 { 00232 // not supported in this plug-in 00233 User::Leave(KErrNotSupported); 00234 return NULL; 00235 } 00236 00237 // from CMMFClip 00238 00239 // Loads aBuffer with specified amount of data from a specified point in the source descriptor 00240 void CMMFExDescriptor::ReadBufferL(TInt aLength, CMMFBuffer* aBuffer, TInt aPosition, MDataSink* aConsumer) 00241 { 00242 if (aBuffer->Type() == KUidMmfDataBuffer) 00243 { 00244 TDes8& bufferDes = STATIC_CAST(CMMFDataBuffer*, aBuffer)->Data(); 00245 00246 if (aLength>bufferDes.MaxLength()) 00247 User::Leave(KErrOverflow); 00248 00249 if ((aLength<0) || (aPosition<0)) 00250 User::Leave(KErrArgument); 00251 00252 ReadBufferL(aBuffer, aPosition, aConsumer); 00253 } 00254 else 00255 User::Leave(KErrNotSupported); 00256 } 00257 00258 // Loads aBuffer from a specified point in the source descriptor 00259 void CMMFExDescriptor::ReadBufferL(CMMFBuffer* aBuffer, TInt aPosition, MDataSink* aConsumer) 00260 { 00261 if (aBuffer->Type() == KUidMmfDataBuffer) 00262 { 00263 TDes8& bufferDes = STATIC_CAST(CMMFDataBuffer*, aBuffer)->Data(); 00264 00265 TInt sourceLength = iDes->Length() ; 00266 TInt destinationMaxLength = bufferDes.MaxLength(); 00267 TInt len = sourceLength - aPosition; 00268 if (len > destinationMaxLength) 00269 len = destinationMaxLength; 00270 00271 if (len>0) 00272 { 00273 TPtrC8 srcPtr(iDes->Mid(aPosition,len)); 00274 bufferDes.Copy(srcPtr); 00275 } 00276 else 00277 bufferDes.SetLength(0); 00278 00279 // Check if the buffer is the last buffer and if so set the last buffer flag on the CMMFDataBuffer 00280 TInt requestSize = aBuffer->RequestSize(); 00281 if (requestSize) 00282 { // The buffer has a request size - so assume last buffer if length is less than the request size 00283 if (bufferDes.Length() < requestSize) 00284 aBuffer->SetLastBuffer(ETrue); 00285 } 00286 else 00287 { // There is no request size so assume last buffer if length is less than the max length 00288 if (bufferDes.Length() < bufferDes.MaxLength()) 00289 aBuffer->SetLastBuffer(ETrue); 00290 } 00291 00292 if (aConsumer) 00293 aConsumer->BufferFilledL(aBuffer); 00294 } 00295 else 00296 User::Leave(KErrNotSupported); 00297 } 00298 00299 // Loads aBuffer from a specified point in the source descriptor 00300 // This is intended for synchronous usage 00301 void CMMFExDescriptor::ReadBufferL(CMMFBuffer* aBuffer, TInt aPosition) 00302 { 00303 ReadBufferL(aBuffer, aPosition, NULL); 00304 } 00305 00306 // Writes aBuffer at specified location into the sink descriptor 00307 void CMMFExDescriptor::WriteBufferL(CMMFBuffer* aBuffer, TInt aPosition, MDataSource* aSupplier) 00308 { 00309 if (aBuffer->Type() == KUidMmfDataBuffer) 00310 { 00311 TDes8& bufferDes = STATIC_CAST(CMMFDataBuffer*, aBuffer)->Data(); 00312 00313 WriteBufferL(bufferDes.Length(), aBuffer, aPosition, aSupplier); 00314 } 00315 else 00316 User::Leave(KErrNotSupported); 00317 } 00318 00319 // Writes specified length of aBuffer at specified location into the sink descriptor 00320 void CMMFExDescriptor::WriteBufferL(TInt aLength, CMMFBuffer* aBuffer, TInt aPosition, MDataSource* aSupplier) 00321 { 00322 if (aBuffer->Type() == KUidMmfDataBuffer) 00323 { 00324 TDes8& bufferDes = STATIC_CAST(CMMFDataBuffer*, aBuffer)->Data(); 00325 00326 if (aLength>bufferDes.Length() || (aLength<0) || (aPosition<0)) 00327 User::Leave(KErrArgument); 00328 00329 TInt sourceLength = aLength; 00330 TPtr8 bufferPtr(((sourceLength) ? &bufferDes[0] : NULL), sourceLength, sourceLength); 00331 TInt targetLength = iDes->MaxLength() - aPosition; 00332 if (targetLength>0 && sourceLength > 0) 00333 { 00334 if (sourceLength>targetLength) 00335 User::Leave(KErrOverflow); 00336 00337 if ((iDes->Length() - aPosition) > 0) 00338 { 00339 TInt bytesToReplace = iDes->Length() - aPosition; 00340 if (sourceLength > bytesToReplace) 00341 { 00342 TPtrC8 replaceBuf = bufferPtr.Left(bytesToReplace); 00343 TPtrC8 appendBuf = bufferPtr.Right(sourceLength-bytesToReplace); 00344 iDes->Replace(aPosition, bytesToReplace, replaceBuf); 00345 iDes->Append(appendBuf); 00346 } 00347 else 00348 iDes->Replace(aPosition, sourceLength, bufferPtr); 00349 00350 } 00351 else if (aPosition == iDes->Length()) 00352 iDes->Append(bufferPtr.Ptr(),sourceLength); 00353 else 00354 { 00355 iDes->AppendFill(0,aPosition - iDes->Length()); 00356 iDes->Append(bufferPtr.Ptr(),sourceLength); 00357 } 00358 } 00359 else if (targetLength<0) 00360 User::Leave(KErrArgument); 00361 else if (aLength != 0) 00362 User::Leave(KErrOverflow); 00363 00364 if (aSupplier) 00365 aSupplier->BufferEmptiedL(aBuffer); 00366 } 00367 else 00368 User::Leave(KErrNotSupported); 00369 } 00370 00371 // Writes aBuffer at specified location into the sink descriptor 00372 void CMMFExDescriptor::WriteBufferL( CMMFBuffer* aBuffer, TInt aPosition) 00373 { 00374 WriteBufferL( aBuffer, aPosition, NULL ); 00375 } 00376 00377 // Gets the space available in the clip 00378 TInt64 CMMFExDescriptor::BytesFree() 00379 { 00380 // get difference between length and maxlength 00381 TInt64 length = iDes->Length() ; 00382 TInt64 maxLength = iDes->MaxLength() ; 00383 return( maxLength - length ) ; 00384 } 00385 00386 // Gets the size of the clip 00387 TInt CMMFExDescriptor::Size() 00388 { 00389 // Length (not max length) of descriptor 00390 TInt length = iDes->Length(); 00391 return(length); 00392 }
Copyright ©2010 Nokia Corporation and/or its subsidiary(-ies).
All rights
reserved. Unless otherwise stated, these materials are provided under the terms of the Eclipse Public License
v1.0.