os/mm/mmlibs/mmfw/src/Plugin/StdSourceAndSink/Mmfdes.cpp
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/mm/mmlibs/mmfw/src/Plugin/StdSourceAndSink/Mmfdes.cpp	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,566 @@
     1.4 +// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
     1.5 +// All rights reserved.
     1.6 +// This component and the accompanying materials are made available
     1.7 +// under the terms of "Eclipse Public License v1.0"
     1.8 +// which accompanies this distribution, and is available
     1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
    1.10 +//
    1.11 +// Initial Contributors:
    1.12 +// Nokia Corporation - initial contribution.
    1.13 +//
    1.14 +// Contributors:
    1.15 +//
    1.16 +// Description:
    1.17 +//
    1.18 +
    1.19 +
    1.20 +#include <f32file.h>
    1.21 +#include <e32std.h>
    1.22 +#include <mmf/server/mmfdes.h>
    1.23 +#include <mmf/server/mmfdatabuffer.h>
    1.24 +#include <mmf/common/mmfpaniccodes.h>
    1.25 +
    1.26 +void Panic(TMMFDescriptorPanicCode aPanicCode)
    1.27 +	{
    1.28 +	_LIT(KMMFDescriptorPanicCategory, "MMFDescriptor");
    1.29 +	User::Panic(KMMFDescriptorPanicCategory, aPanicCode);
    1.30 +	}
    1.31 +
    1.32 +/**
    1.33 +Protected constructor.
    1.34 +
    1.35 +Sets the offset to zero.
    1.36 +*/
    1.37 +CMMFDescriptor::CMMFDescriptor( ) : CMMFClip( KUidMmfDescriptorSource, KUidMmfDescriptorSink ) 
    1.38 +	{
    1.39 +	}
    1.40 +
    1.41 +/**
    1.42 +Destructor.
    1.43 +
    1.44 +The default implementation closes the descriptor thread.
    1.45 +*/
    1.46 +CMMFDescriptor::~CMMFDescriptor()
    1.47 +	{
    1.48 +	iDesThread.Close() ;
    1.49 +	}
    1.50 +
    1.51 +/**
    1.52 +Constructs a CMMFDescriptor MDataSource.
    1.53 +
    1.54 +@return A pointer to a new CMMFDescriptor.
    1.55 +*/
    1.56 +MDataSource* CMMFDescriptor::NewSourceL( )
    1.57 +	{
    1.58 +	CMMFDescriptor* self = new (ELeave) CMMFDescriptor( ) ;
    1.59 +	return STATIC_CAST( MDataSource*, self ) ;
    1.60 +	}
    1.61 +
    1.62 +/**
    1.63 +Constructs a CMMFDescriptor MDataSink.
    1.64 +
    1.65 +@return A pointer to a new CMMFDescriptor.
    1.66 +*/
    1.67 +MDataSink* CMMFDescriptor::NewSinkL( )
    1.68 +	{
    1.69 +	CMMFDescriptor* self = new (ELeave) CMMFDescriptor( ) ;
    1.70 +	return STATIC_CAST( MDataSink*, self ) ;
    1.71 +	}
    1.72 +
    1.73 +/**
    1.74 +Performs source construction dependant on the source construction
    1.75 +initialisation data aInitData.
    1.76 +
    1.77 +@param  aInitData
    1.78 +        The TPckgC<TMMFDescriptorParams> descriptor package containing the descriptor and the thread 
    1.79 +        ID for the descriptor.
    1.80 +*/
    1.81 +void CMMFDescriptor::ConstructSourceL( const TDesC8& aInitData )
    1.82 +	{
    1.83 +	ConstructL( aInitData ) ;
    1.84 +	}
    1.85 +
    1.86 +
    1.87 +/***
    1.88 +Sets how much of the underlying descriptor will be used, up	to the underlying descriptor's maximum
    1.89 +length.
    1.90 +
    1.91 +@param  aSize
    1.92 +        The size of the descriptor.
    1.93 +
    1.94 +@return An error code indicating if the function call was successful. KErrNone on success, otherwise
    1.95 +        another of the system-wide error codes.
    1.96 +*/
    1.97 +TInt CMMFDescriptor::SetSize( TInt aSize )
    1.98 +	{
    1.99 +	//[ precondition aSize >= 0
   1.100 +	// precondition sSize < MaxSize()
   1.101 +	// iDes is not null]
   1.102 +	 if(!iDes )
   1.103 +		 return KErrNotReady;
   1.104 +
   1.105 +     if( aSize > MaxLength() )
   1.106 +		 return KErrOverflow;
   1.107 +
   1.108 +	 if( aSize < 0 )
   1.109 +		 return KErrUnderflow;
   1.110 +
   1.111 +	 // [ actually do the work ]
   1.112 +	 iDes->SetLength( aSize );
   1.113 +
   1.114 +	 //[ assert the post condition
   1.115 +	 // aSize == Length()
   1.116 +	 // descriptor is still ok]
   1.117 +     ASSERT( aSize == iDes->Length());
   1.118 +	 ASSERT( iDes );
   1.119 +
   1.120 +	 return KErrNone;
   1.121 +	}
   1.122 +
   1.123 +
   1.124 +/**
   1.125 +Performs sink construction dependant on the sink construction initialisation data aInitData.
   1.126 +
   1.127 +@param  aInitData
   1.128 +        The TPckgC<TMMFDescriptorParams> descriptor package containing
   1.129 +        the descriptor and the thread ID for the descriptor.
   1.130 +*/
   1.131 +void CMMFDescriptor::ConstructSinkL( const TDesC8& aInitData )
   1.132 +	{
   1.133 +	ConstructL( aInitData ) ;
   1.134 +	}
   1.135 +
   1.136 +void CMMFDescriptor::ConstructL( const TDesC8& aInitData )
   1.137 +	{
   1.138 +	TMMFDescriptorParams params;
   1.139 +	TPckgC<TMMFDescriptorParams> config(params);
   1.140 +	if (aInitData.Length() < config.Length())
   1.141 +		User::Leave(KErrGeneral);
   1.142 +	config.Set(aInitData);
   1.143 +	iDes = STATIC_CAST( TDes8*, config().iDes);
   1.144 +	User::LeaveIfError( iDesThread.Open( config().iDesThreadId ) );
   1.145 +	}
   1.146 +
   1.147 +
   1.148 +/** 
   1.149 +Loads aBuffer from iDes.
   1.150 +
   1.151 +File read is asynchronous.  CReadRequest is created to respond to completion.
   1.152 +
   1.153 +@param  aBuffer
   1.154 +        The buffer to be filled from the descriptor.
   1.155 +@param  aConsumer
   1.156 +        The data sink consumer of the buffer.
   1.157 +@param  aMediaId
   1.158 +        Not used.
   1.159 +*/
   1.160 +void CMMFDescriptor::FillBufferL( CMMFBuffer* aBuffer, MDataSink* aConsumer, TMediaId /*aMediaId*/  ) 
   1.161 +	{
   1.162 +	// Current position in Descriptor is iOffset.
   1.163 +
   1.164 +	// Read from iDes in iDesThread into Des in aBuffer.
   1.165 +
   1.166 +	// Assume that the amount to be read is the size of the buffer descriptor
   1.167 +	// Should check that there is sufficient data in the source buffer
   1.168 +	// If there is not enough to fill the target then copy what there is
   1.169 +	// How should the function deal with no data in the source buffer?
   1.170 +
   1.171 +	// Use of a single iOffset will preclude use by more than one client (use ReadBufferL())
   1.172 +	if (CMMFBuffer::IsSupportedDataBuffer(aBuffer->Type()))
   1.173 +		{
   1.174 +		TDes8& bufferDes = STATIC_CAST(CMMFDataBuffer*, aBuffer)->Data();
   1.175 +
   1.176 +		//if request size is set, use it, else use max length of buffer
   1.177 +		TInt targetMaxLength = aBuffer->RequestSize() ? aBuffer->RequestSize() : bufferDes.MaxLength();
   1.178 +
   1.179 +		//ensure RequestSize was within bounds
   1.180 +		if(targetMaxLength > bufferDes.MaxLength())
   1.181 +			targetMaxLength = bufferDes.MaxLength();
   1.182 +
   1.183 +		TInt sourceLengthRemaining = iDes->Length() - iOffset;
   1.184 +		if ( ( sourceLengthRemaining - targetMaxLength ) > 0 )
   1.185 +			{
   1.186 +			bufferDes = iDes->Mid(iOffset,targetMaxLength);
   1.187 +			iOffset += targetMaxLength;
   1.188 +			}
   1.189 +		else if (sourceLengthRemaining > 0)
   1.190 +			{
   1.191 +			bufferDes = iDes->Mid(iOffset,sourceLengthRemaining);
   1.192 +			iOffset += sourceLengthRemaining;
   1.193 +			aBuffer->SetLastBuffer(ETrue);
   1.194 +			}
   1.195 +		else
   1.196 +			{
   1.197 +			bufferDes.SetLength(0);
   1.198 +			aBuffer->SetLastBuffer(ETrue);
   1.199 +			}
   1.200 +
   1.201 +		aConsumer->BufferFilledL( aBuffer ) ;
   1.202 +		}
   1.203 +	else
   1.204 +		User::Leave(KErrNotSupported);
   1.205 +	}
   1.206 +
   1.207 +/**
   1.208 +Empties aBuffer into iDes.
   1.209 +
   1.210 +@param  aBuffer
   1.211 +        The buffer to be written to the descriptor.
   1.212 +@param  aSupplier
   1.213 +        The data source supplier of the buffer.
   1.214 +@param  aMediaId
   1.215 +        The Media ID.
   1.216 +*/
   1.217 +void CMMFDescriptor::EmptyBufferL( CMMFBuffer* aBuffer, MDataSource* aSupplier, TMediaId /*aMediaId*/ )
   1.218 +	{
   1.219 +	// Does the buffer type need to be checked?
   1.220 +
   1.221 +	// Assume that the amount to be read is the size of the buffer descriptor
   1.222 +	// Should check that there is sufficient data in the source buffer
   1.223 +	// If there is not enough to fill the target then copy what there is
   1.224 +	// How should the function deal with no data in the source buffer?
   1.225 +	if (CMMFBuffer::IsSupportedDataBuffer(aBuffer->Type()))
   1.226 +		{
   1.227 +		TDes8& bufferDes = STATIC_CAST(CMMFDataBuffer*, aBuffer)->Data();
   1.228 +
   1.229 +		TInt sourceLength = bufferDes.Length() ;	
   1.230 +		TInt targetLength = iDes->MaxLength() - iDes->Length();
   1.231 +		if ( targetLength>0 )
   1.232 +			{
   1.233 +			if (sourceLength>targetLength)
   1.234 +				{
   1.235 +				sourceLength = targetLength;
   1.236 +				bufferDes.SetLength(targetLength);
   1.237 +				}
   1.238 +
   1.239 +			iDes->Append(bufferDes) ;
   1.240 +			}
   1.241 +		else
   1.242 +			bufferDes.SetLength(0);
   1.243 +
   1.244 +		aSupplier->BufferEmptiedL( aBuffer ) ;
   1.245 +		}
   1.246 +	else
   1.247 +		User::Leave(KErrNotSupported);
   1.248 +	}
   1.249 +
   1.250 +/** 
   1.251 +Loads aLength number of bytes into aBuffer from specified point in iDes.
   1.252 +
   1.253 +@param  aLength
   1.254 +        The number of bytes to be read into buffer.
   1.255 +@param  aBuffer
   1.256 +        The buffer to be filled from the descriptor.
   1.257 +@param  aPosition
   1.258 +        The offset into the descriptor at which to start reading.
   1.259 +@param  aConsumer
   1.260 +        The data sink consumer of the buffer
   1.261 +*/
   1.262 +void CMMFDescriptor::ReadBufferL(TInt aLength, CMMFBuffer* aBuffer, TInt aPosition, MDataSink* aConsumer)
   1.263 +	{
   1.264 +	if (!aBuffer)
   1.265 +		User::Leave(KErrArgument);
   1.266 +
   1.267 +	if (CMMFBuffer::IsSupportedDataBuffer(aBuffer->Type()))
   1.268 +		{
   1.269 +		TDes8& bufferDes = STATIC_CAST(CMMFDataBuffer*, aBuffer)->Data();
   1.270 +
   1.271 +		if (aLength>bufferDes.MaxLength())
   1.272 +			User::Leave(KErrOverflow);
   1.273 +
   1.274 +		if ((aLength<0) || (aPosition<0))
   1.275 +			User::Leave(KErrArgument);
   1.276 +
   1.277 +		TInt sourceLength = iDes->Length() ;
   1.278 +
   1.279 +		//ensure not trying to read more than is available
   1.280 +		if(aPosition + aLength > sourceLength)
   1.281 +			aLength = sourceLength - aPosition;
   1.282 +
   1.283 +		if (aLength>0)
   1.284 +			{
   1.285 +			TPtrC8 srcPtr(iDes->Mid(aPosition,aLength));
   1.286 +			bufferDes.Copy(srcPtr.Ptr(),aLength);
   1.287 +			}
   1.288 +		else
   1.289 +			bufferDes.SetLength(0);
   1.290 +
   1.291 +		//have we read all the available data
   1.292 +		if(aPosition + aLength >= sourceLength)
   1.293 +			aBuffer->SetLastBuffer(ETrue);
   1.294 +
   1.295 +		if (aConsumer)
   1.296 +			aConsumer->BufferFilledL(aBuffer);
   1.297 +		}
   1.298 +	else
   1.299 +		User::Leave(KErrNotSupported);
   1.300 +	}
   1.301 +
   1.302 +/**
   1.303 +Loads aBuffer from specified point in iDes
   1.304 +
   1.305 +@param  aBuffer
   1.306 +        The buffer to be filled from the descriptor.
   1.307 +@param  aPosition
   1.308 +        The offset into the descriptor at which to start reading.
   1.309 +@param  aConsumer
   1.310 +        The data sink consumer of the buffer.
   1.311 +*/
   1.312 +void CMMFDescriptor::ReadBufferL(CMMFBuffer* aBuffer, TInt aPosition, MDataSink* aConsumer)
   1.313 +	{
   1.314 +	if (!aBuffer)
   1.315 +		User::Leave(KErrArgument);
   1.316 +
   1.317 +	if (aPosition<0)
   1.318 +		User::Leave(KErrArgument);
   1.319 +
   1.320 +	if (CMMFBuffer::IsSupportedDataBuffer(aBuffer->Type()))
   1.321 +		{
   1.322 +		TDes8& bufferDes = STATIC_CAST(CMMFDataBuffer*, aBuffer)->Data();
   1.323 +		//if request size is set, use it, else use max length of buffer
   1.324 +		TUint copyLength = aBuffer->RequestSize() ? aBuffer->RequestSize() : bufferDes.MaxLength();
   1.325 +
   1.326 +		ReadBufferL(copyLength, aBuffer, aPosition, aConsumer);
   1.327 +		}
   1.328 +	else
   1.329 +		User::Leave(KErrNotSupported);
   1.330 +	}
   1.331 +
   1.332 + /** 
   1.333 +Loads aBuffer from specified point in iDes.  Note that this is a synchronous read.
   1.334 +
   1.335 +@param  aBuffer
   1.336 +        The buffer to be filled from the descriptor.
   1.337 +@param  aPosition
   1.338 +        The offset into the descriptor at which to start reading.
   1.339 +*/
   1.340 +void CMMFDescriptor::ReadBufferL(CMMFBuffer* aBuffer, TInt aPosition)
   1.341 +	{
   1.342 +	ReadBufferL(aBuffer, aPosition, NULL);
   1.343 +	}
   1.344 +
   1.345 +/**
   1.346 +Empties aBuffer into iDes at specified location.
   1.347 +
   1.348 +@param  aBuffer
   1.349 +        The data buffer containing bytes to be written.
   1.350 +@param  aPosition
   1.351 +        The offset into the descriptor at which to start writing.
   1.352 +@param  aSupplier
   1.353 +        The data source to be notified when the write has been completed.
   1.354 +*/
   1.355 +void CMMFDescriptor::WriteBufferL(CMMFBuffer* aBuffer, TInt aPosition, MDataSource* aSupplier) 
   1.356 +	{
   1.357 +	if (CMMFBuffer::IsSupportedDataBuffer(aBuffer->Type()))
   1.358 +		{
   1.359 +		TDes8& bufferDes = STATIC_CAST(CMMFDataBuffer*, aBuffer)->Data();
   1.360 +
   1.361 +		WriteBufferL(bufferDes.Length(), aBuffer, aPosition, aSupplier);
   1.362 +		}
   1.363 +	else
   1.364 +		User::Leave(KErrNotSupported);
   1.365 +	}
   1.366 +
   1.367 +/**
   1.368 +Empties aLength bytes from aBuffer into iDes at specified location.
   1.369 +
   1.370 +@param  aLength
   1.371 +        The number of bytes to be emptied from buffer.
   1.372 +@param  aBuffer
   1.373 +        The data buffer containing bytes to be written.
   1.374 +@param  aPosition
   1.375 +        The offset into the descriptor at which to start writing.
   1.376 +@param  aSupplier
   1.377 +        The data source to be notified when the write has been completed.
   1.378 +
   1.379 +@leave  KErrNotReady
   1.380 +        If SinkPrimeL() and SinkThreadLogon() have not been called.
   1.381 +@leave  KErrArgument
   1.382 +        If aLength<0 or aPosition<0 or aSupplier is NULL.
   1.383 +@leave  KErrNotSupported 
   1.384 +        If aBuffer is not of type KMMFDataBuffer.
   1.385 +*/
   1.386 +void CMMFDescriptor::WriteBufferL(TInt aLength, CMMFBuffer* aBuffer, TInt aPosition, MDataSource* aSupplier)
   1.387 +	{
   1.388 +	if (CMMFBuffer::IsSupportedDataBuffer(aBuffer->Type()))
   1.389 +		{
   1.390 +		TDes8& bufferDes = STATIC_CAST(CMMFDataBuffer*, aBuffer)->Data();
   1.391 +
   1.392 +		if (aLength>bufferDes.Length() || (aLength<0) || (aPosition<0))
   1.393 +			User::Leave(KErrArgument);
   1.394 +
   1.395 +		TInt sourceLength = aLength;
   1.396 +		TPtr8 bufferPtr(((sourceLength) ? &bufferDes[0] : NULL), sourceLength, sourceLength);
   1.397 +		TInt targetLength = iDes->MaxLength() - aPosition;
   1.398 +		if (targetLength>0 && sourceLength > 0)
   1.399 +			{
   1.400 +			if (sourceLength>targetLength)
   1.401 +				User::Leave(KErrOverflow);
   1.402 +
   1.403 +			if ((iDes->Length() - aPosition) > 0)
   1.404 +				{
   1.405 +				TInt bytesToReplace = iDes->Length() - aPosition;
   1.406 +				if (sourceLength > bytesToReplace) 
   1.407 +					{
   1.408 +					TPtrC8 replaceBuf = bufferPtr.Left(bytesToReplace);
   1.409 +					TPtrC8 appendBuf = bufferPtr.Right(sourceLength-bytesToReplace);
   1.410 +					iDes->Replace(aPosition, bytesToReplace, replaceBuf);
   1.411 +					iDes->Append(appendBuf);
   1.412 +					} 
   1.413 +				else
   1.414 +					iDes->Replace(aPosition, sourceLength, bufferPtr);
   1.415 +
   1.416 +				} 
   1.417 +			else
   1.418 +				iDes->Append(bufferPtr.Ptr(),sourceLength);
   1.419 +			}
   1.420 +		else if (targetLength<0)
   1.421 +			User::Leave(KErrArgument);
   1.422 +		else if (aLength != 0)
   1.423 +			User::Leave(KErrOverflow);
   1.424 +
   1.425 +		if (aSupplier)
   1.426 +			aSupplier->BufferEmptiedL(aBuffer);
   1.427 +		}
   1.428 +	else
   1.429 +		User::Leave(KErrNotSupported);
   1.430 +	}
   1.431 +
   1.432 +/** 
   1.433 +Empties aBuffer into iFile at specified location.  Note that this is a synchronous write
   1.434 +
   1.435 +@param  aBuffer
   1.436 +        The data buffer containing bytes to be written.
   1.437 +@param  aPosition
   1.438 +        The offset into file at which to start writing.
   1.439 +*/
   1.440 +void CMMFDescriptor::WriteBufferL( CMMFBuffer* aBuffer, TInt aPosition)
   1.441 +	{
   1.442 +	WriteBufferL( aBuffer, aPosition, NULL );
   1.443 +	}
   1.444 +
   1.445 +/**
   1.446 +Returns the amount of space available for the clip.
   1.447 +
   1.448 +@return The space available in descriptor (difference between length and maxlength).
   1.449 +*/
   1.450 +TInt64 CMMFDescriptor::BytesFree() 
   1.451 +	{
   1.452 +	TInt64 length = iDes->Length() ;
   1.453 +	TInt64 maxLength =  iDes->MaxLength() ;
   1.454 +	return( maxLength - length ) ;
   1.455 +	}
   1.456 +
   1.457 +/**
   1.458 +Returns the length of the clip.
   1.459 +
   1.460 +@return The length (not max length) of the descriptor.
   1.461 +*/
   1.462 +TInt CMMFDescriptor::Size() 
   1.463 +	{
   1.464 +	TInt length = iDes->Length();
   1.465 +	return(length);
   1.466 +	}
   1.467 +
   1.468 +/**
   1.469 +Returns the data type as a fourCC code for the CMMFDescriptor data source.
   1.470 +
   1.471 +@param  aMediaId
   1.472 +        The ID of the media for which the codec is obtained.
   1.473 +
   1.474 +@return The data type fourCC code.
   1.475 +*/
   1.476 +TFourCC CMMFDescriptor::SourceDataTypeCode(TMediaId /*aMediaId*/) 
   1.477 +	{
   1.478 +	return iSourceFourCC ;
   1.479 +	}
   1.480 +
   1.481 +/**
   1.482 +Returns the data type as a fourCC code of the CMMFDescriptor data sink.
   1.483 +
   1.484 +Used by MDataSource and MDataSink.
   1.485 +
   1.486 +@return The data type fourCC code.
   1.487 +*/
   1.488 +TFourCC CMMFDescriptor::SinkDataTypeCode(TMediaId /*aMediaId*/) 
   1.489 +	{
   1.490 +	return iSinkFourCC ;
   1.491 +	}
   1.492 +
   1.493 +/**
   1.494 +CMMFDescriptor as a source is always passive so this function is not supported.
   1.495 +
   1.496 +@param  aBuffer
   1.497 +        The emptied buffer.
   1.498 +*/
   1.499 +void CMMFDescriptor::BufferEmptiedL( CMMFBuffer* /*aBuffer*/ )
   1.500 +	{
   1.501 +	Panic(EMMFDescriptorPanicBufferEmptiedLNotSupported);
   1.502 +	}
   1.503 +
   1.504 +/**
   1.505 +Tests whether a source buffer can be created.
   1.506 +
   1.507 +@return	A boolean indicating if the buffer can be created. EFalse if a CMMFDescriptor cannot create 
   1.508 +        it's own buffer
   1.509 +*/
   1.510 +TBool CMMFDescriptor::CanCreateSourceBuffer()
   1.511 +	{
   1.512 +	return EFalse ;
   1.513 +	}
   1.514 +
   1.515 +/**
   1.516 +Creates a source buffer.
   1.517 +
   1.518 +@param  aMediaId
   1.519 +        The Media ID.
   1.520 +@param  aReference
   1.521 +        A boolean indicating if MDataSource owns the buffer. ETrue if MDataSource owns the buffer,
   1.522 +        EFalse if the caller owns the buffer.
   1.523 +
   1.524 +@return	NULL as a CMMFFile cannot create it's own buffer
   1.525 +*/
   1.526 +CMMFBuffer* CMMFDescriptor::CreateSourceBufferL(  TMediaId /*aMediaId*/, TBool& /*aReference*/ )
   1.527 +	{
   1.528 +	User::Leave(KErrNotSupported);
   1.529 +	return NULL;
   1.530 +	}
   1.531 +
   1.532 +/**
   1.533 +CMMFDescriptor as a sink is always passive so this function is not supported.
   1.534 +
   1.535 +@param  aBuffer
   1.536 +        The filled buffer.
   1.537 +*/
   1.538 +void CMMFDescriptor::BufferFilledL( CMMFBuffer* /*aBuffer*/ )
   1.539 +	{
   1.540 +	Panic(EMMFDescriptorPanicBufferFilledLNotSupported);
   1.541 +	}
   1.542 +
   1.543 +/**
   1.544 +Tests whether a sink buffer can be created.
   1.545 +
   1.546 +@return A boolean indicating if the sink buffer can be created. EFalse if a CMMFDescriptor cannot 
   1.547 +        create it's own buffer.
   1.548 +*/
   1.549 +TBool CMMFDescriptor::CanCreateSinkBuffer()
   1.550 +	{
   1.551 +	return EFalse ;
   1.552 +	}
   1.553 +
   1.554 +/**
   1.555 +Creates a sink buffer.
   1.556 +
   1.557 +@param  aMediaId
   1.558 +        The Media ID.
   1.559 +@param  aReference
   1.560 +        A boolean indicating if MDataSource owns the buffer. ETrue if MDataSource owns the buffer,
   1.561 +        EFalse if the caller owns the buffer.
   1.562 +
   1.563 +@return	NULL as a CMMFDescriptor cannot create it's own buffer
   1.564 + */
   1.565 +CMMFBuffer* CMMFDescriptor::CreateSinkBufferL( TMediaId /*aMediaId*/ , TBool& /*aReference*/)
   1.566 +	{
   1.567 +	User::Leave(KErrNotSupported);
   1.568 +	return NULL;
   1.569 +	}