os/mm/mmlibs/mmfw/src/Plugin/StdSourceAndSink/Mmfdes.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 // Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 //
    15 
    16 
    17 #include <f32file.h>
    18 #include <e32std.h>
    19 #include <mmf/server/mmfdes.h>
    20 #include <mmf/server/mmfdatabuffer.h>
    21 #include <mmf/common/mmfpaniccodes.h>
    22 
    23 void Panic(TMMFDescriptorPanicCode aPanicCode)
    24 	{
    25 	_LIT(KMMFDescriptorPanicCategory, "MMFDescriptor");
    26 	User::Panic(KMMFDescriptorPanicCategory, aPanicCode);
    27 	}
    28 
    29 /**
    30 Protected constructor.
    31 
    32 Sets the offset to zero.
    33 */
    34 CMMFDescriptor::CMMFDescriptor( ) : CMMFClip( KUidMmfDescriptorSource, KUidMmfDescriptorSink ) 
    35 	{
    36 	}
    37 
    38 /**
    39 Destructor.
    40 
    41 The default implementation closes the descriptor thread.
    42 */
    43 CMMFDescriptor::~CMMFDescriptor()
    44 	{
    45 	iDesThread.Close() ;
    46 	}
    47 
    48 /**
    49 Constructs a CMMFDescriptor MDataSource.
    50 
    51 @return A pointer to a new CMMFDescriptor.
    52 */
    53 MDataSource* CMMFDescriptor::NewSourceL( )
    54 	{
    55 	CMMFDescriptor* self = new (ELeave) CMMFDescriptor( ) ;
    56 	return STATIC_CAST( MDataSource*, self ) ;
    57 	}
    58 
    59 /**
    60 Constructs a CMMFDescriptor MDataSink.
    61 
    62 @return A pointer to a new CMMFDescriptor.
    63 */
    64 MDataSink* CMMFDescriptor::NewSinkL( )
    65 	{
    66 	CMMFDescriptor* self = new (ELeave) CMMFDescriptor( ) ;
    67 	return STATIC_CAST( MDataSink*, self ) ;
    68 	}
    69 
    70 /**
    71 Performs source construction dependant on the source construction
    72 initialisation data aInitData.
    73 
    74 @param  aInitData
    75         The TPckgC<TMMFDescriptorParams> descriptor package containing the descriptor and the thread 
    76         ID for the descriptor.
    77 */
    78 void CMMFDescriptor::ConstructSourceL( const TDesC8& aInitData )
    79 	{
    80 	ConstructL( aInitData ) ;
    81 	}
    82 
    83 
    84 /***
    85 Sets how much of the underlying descriptor will be used, up	to the underlying descriptor's maximum
    86 length.
    87 
    88 @param  aSize
    89         The size of the descriptor.
    90 
    91 @return An error code indicating if the function call was successful. KErrNone on success, otherwise
    92         another of the system-wide error codes.
    93 */
    94 TInt CMMFDescriptor::SetSize( TInt aSize )
    95 	{
    96 	//[ precondition aSize >= 0
    97 	// precondition sSize < MaxSize()
    98 	// iDes is not null]
    99 	 if(!iDes )
   100 		 return KErrNotReady;
   101 
   102      if( aSize > MaxLength() )
   103 		 return KErrOverflow;
   104 
   105 	 if( aSize < 0 )
   106 		 return KErrUnderflow;
   107 
   108 	 // [ actually do the work ]
   109 	 iDes->SetLength( aSize );
   110 
   111 	 //[ assert the post condition
   112 	 // aSize == Length()
   113 	 // descriptor is still ok]
   114      ASSERT( aSize == iDes->Length());
   115 	 ASSERT( iDes );
   116 
   117 	 return KErrNone;
   118 	}
   119 
   120 
   121 /**
   122 Performs sink construction dependant on the sink construction initialisation data aInitData.
   123 
   124 @param  aInitData
   125         The TPckgC<TMMFDescriptorParams> descriptor package containing
   126         the descriptor and the thread ID for the descriptor.
   127 */
   128 void CMMFDescriptor::ConstructSinkL( const TDesC8& aInitData )
   129 	{
   130 	ConstructL( aInitData ) ;
   131 	}
   132 
   133 void CMMFDescriptor::ConstructL( const TDesC8& aInitData )
   134 	{
   135 	TMMFDescriptorParams params;
   136 	TPckgC<TMMFDescriptorParams> config(params);
   137 	if (aInitData.Length() < config.Length())
   138 		User::Leave(KErrGeneral);
   139 	config.Set(aInitData);
   140 	iDes = STATIC_CAST( TDes8*, config().iDes);
   141 	User::LeaveIfError( iDesThread.Open( config().iDesThreadId ) );
   142 	}
   143 
   144 
   145 /** 
   146 Loads aBuffer from iDes.
   147 
   148 File read is asynchronous.  CReadRequest is created to respond to completion.
   149 
   150 @param  aBuffer
   151         The buffer to be filled from the descriptor.
   152 @param  aConsumer
   153         The data sink consumer of the buffer.
   154 @param  aMediaId
   155         Not used.
   156 */
   157 void CMMFDescriptor::FillBufferL( CMMFBuffer* aBuffer, MDataSink* aConsumer, TMediaId /*aMediaId*/  ) 
   158 	{
   159 	// Current position in Descriptor is iOffset.
   160 
   161 	// Read from iDes in iDesThread into Des in aBuffer.
   162 
   163 	// Assume that the amount to be read is the size of the buffer descriptor
   164 	// Should check that there is sufficient data in the source buffer
   165 	// If there is not enough to fill the target then copy what there is
   166 	// How should the function deal with no data in the source buffer?
   167 
   168 	// Use of a single iOffset will preclude use by more than one client (use ReadBufferL())
   169 	if (CMMFBuffer::IsSupportedDataBuffer(aBuffer->Type()))
   170 		{
   171 		TDes8& bufferDes = STATIC_CAST(CMMFDataBuffer*, aBuffer)->Data();
   172 
   173 		//if request size is set, use it, else use max length of buffer
   174 		TInt targetMaxLength = aBuffer->RequestSize() ? aBuffer->RequestSize() : bufferDes.MaxLength();
   175 
   176 		//ensure RequestSize was within bounds
   177 		if(targetMaxLength > bufferDes.MaxLength())
   178 			targetMaxLength = bufferDes.MaxLength();
   179 
   180 		TInt sourceLengthRemaining = iDes->Length() - iOffset;
   181 		if ( ( sourceLengthRemaining - targetMaxLength ) > 0 )
   182 			{
   183 			bufferDes = iDes->Mid(iOffset,targetMaxLength);
   184 			iOffset += targetMaxLength;
   185 			}
   186 		else if (sourceLengthRemaining > 0)
   187 			{
   188 			bufferDes = iDes->Mid(iOffset,sourceLengthRemaining);
   189 			iOffset += sourceLengthRemaining;
   190 			aBuffer->SetLastBuffer(ETrue);
   191 			}
   192 		else
   193 			{
   194 			bufferDes.SetLength(0);
   195 			aBuffer->SetLastBuffer(ETrue);
   196 			}
   197 
   198 		aConsumer->BufferFilledL( aBuffer ) ;
   199 		}
   200 	else
   201 		User::Leave(KErrNotSupported);
   202 	}
   203 
   204 /**
   205 Empties aBuffer into iDes.
   206 
   207 @param  aBuffer
   208         The buffer to be written to the descriptor.
   209 @param  aSupplier
   210         The data source supplier of the buffer.
   211 @param  aMediaId
   212         The Media ID.
   213 */
   214 void CMMFDescriptor::EmptyBufferL( CMMFBuffer* aBuffer, MDataSource* aSupplier, TMediaId /*aMediaId*/ )
   215 	{
   216 	// Does the buffer type need to be checked?
   217 
   218 	// Assume that the amount to be read is the size of the buffer descriptor
   219 	// Should check that there is sufficient data in the source buffer
   220 	// If there is not enough to fill the target then copy what there is
   221 	// How should the function deal with no data in the source buffer?
   222 	if (CMMFBuffer::IsSupportedDataBuffer(aBuffer->Type()))
   223 		{
   224 		TDes8& bufferDes = STATIC_CAST(CMMFDataBuffer*, aBuffer)->Data();
   225 
   226 		TInt sourceLength = bufferDes.Length() ;	
   227 		TInt targetLength = iDes->MaxLength() - iDes->Length();
   228 		if ( targetLength>0 )
   229 			{
   230 			if (sourceLength>targetLength)
   231 				{
   232 				sourceLength = targetLength;
   233 				bufferDes.SetLength(targetLength);
   234 				}
   235 
   236 			iDes->Append(bufferDes) ;
   237 			}
   238 		else
   239 			bufferDes.SetLength(0);
   240 
   241 		aSupplier->BufferEmptiedL( aBuffer ) ;
   242 		}
   243 	else
   244 		User::Leave(KErrNotSupported);
   245 	}
   246 
   247 /** 
   248 Loads aLength number of bytes into aBuffer from specified point in iDes.
   249 
   250 @param  aLength
   251         The number of bytes to be read into buffer.
   252 @param  aBuffer
   253         The buffer to be filled from the descriptor.
   254 @param  aPosition
   255         The offset into the descriptor at which to start reading.
   256 @param  aConsumer
   257         The data sink consumer of the buffer
   258 */
   259 void CMMFDescriptor::ReadBufferL(TInt aLength, CMMFBuffer* aBuffer, TInt aPosition, MDataSink* aConsumer)
   260 	{
   261 	if (!aBuffer)
   262 		User::Leave(KErrArgument);
   263 
   264 	if (CMMFBuffer::IsSupportedDataBuffer(aBuffer->Type()))
   265 		{
   266 		TDes8& bufferDes = STATIC_CAST(CMMFDataBuffer*, aBuffer)->Data();
   267 
   268 		if (aLength>bufferDes.MaxLength())
   269 			User::Leave(KErrOverflow);
   270 
   271 		if ((aLength<0) || (aPosition<0))
   272 			User::Leave(KErrArgument);
   273 
   274 		TInt sourceLength = iDes->Length() ;
   275 
   276 		//ensure not trying to read more than is available
   277 		if(aPosition + aLength > sourceLength)
   278 			aLength = sourceLength - aPosition;
   279 
   280 		if (aLength>0)
   281 			{
   282 			TPtrC8 srcPtr(iDes->Mid(aPosition,aLength));
   283 			bufferDes.Copy(srcPtr.Ptr(),aLength);
   284 			}
   285 		else
   286 			bufferDes.SetLength(0);
   287 
   288 		//have we read all the available data
   289 		if(aPosition + aLength >= sourceLength)
   290 			aBuffer->SetLastBuffer(ETrue);
   291 
   292 		if (aConsumer)
   293 			aConsumer->BufferFilledL(aBuffer);
   294 		}
   295 	else
   296 		User::Leave(KErrNotSupported);
   297 	}
   298 
   299 /**
   300 Loads aBuffer from specified point in iDes
   301 
   302 @param  aBuffer
   303         The buffer to be filled from the descriptor.
   304 @param  aPosition
   305         The offset into the descriptor at which to start reading.
   306 @param  aConsumer
   307         The data sink consumer of the buffer.
   308 */
   309 void CMMFDescriptor::ReadBufferL(CMMFBuffer* aBuffer, TInt aPosition, MDataSink* aConsumer)
   310 	{
   311 	if (!aBuffer)
   312 		User::Leave(KErrArgument);
   313 
   314 	if (aPosition<0)
   315 		User::Leave(KErrArgument);
   316 
   317 	if (CMMFBuffer::IsSupportedDataBuffer(aBuffer->Type()))
   318 		{
   319 		TDes8& bufferDes = STATIC_CAST(CMMFDataBuffer*, aBuffer)->Data();
   320 		//if request size is set, use it, else use max length of buffer
   321 		TUint copyLength = aBuffer->RequestSize() ? aBuffer->RequestSize() : bufferDes.MaxLength();
   322 
   323 		ReadBufferL(copyLength, aBuffer, aPosition, aConsumer);
   324 		}
   325 	else
   326 		User::Leave(KErrNotSupported);
   327 	}
   328 
   329  /** 
   330 Loads aBuffer from specified point in iDes.  Note that this is a synchronous read.
   331 
   332 @param  aBuffer
   333         The buffer to be filled from the descriptor.
   334 @param  aPosition
   335         The offset into the descriptor at which to start reading.
   336 */
   337 void CMMFDescriptor::ReadBufferL(CMMFBuffer* aBuffer, TInt aPosition)
   338 	{
   339 	ReadBufferL(aBuffer, aPosition, NULL);
   340 	}
   341 
   342 /**
   343 Empties aBuffer into iDes at specified location.
   344 
   345 @param  aBuffer
   346         The data buffer containing bytes to be written.
   347 @param  aPosition
   348         The offset into the descriptor at which to start writing.
   349 @param  aSupplier
   350         The data source to be notified when the write has been completed.
   351 */
   352 void CMMFDescriptor::WriteBufferL(CMMFBuffer* aBuffer, TInt aPosition, MDataSource* aSupplier) 
   353 	{
   354 	if (CMMFBuffer::IsSupportedDataBuffer(aBuffer->Type()))
   355 		{
   356 		TDes8& bufferDes = STATIC_CAST(CMMFDataBuffer*, aBuffer)->Data();
   357 
   358 		WriteBufferL(bufferDes.Length(), aBuffer, aPosition, aSupplier);
   359 		}
   360 	else
   361 		User::Leave(KErrNotSupported);
   362 	}
   363 
   364 /**
   365 Empties aLength bytes from aBuffer into iDes at specified location.
   366 
   367 @param  aLength
   368         The number of bytes to be emptied from buffer.
   369 @param  aBuffer
   370         The data buffer containing bytes to be written.
   371 @param  aPosition
   372         The offset into the descriptor at which to start writing.
   373 @param  aSupplier
   374         The data source to be notified when the write has been completed.
   375 
   376 @leave  KErrNotReady
   377         If SinkPrimeL() and SinkThreadLogon() have not been called.
   378 @leave  KErrArgument
   379         If aLength<0 or aPosition<0 or aSupplier is NULL.
   380 @leave  KErrNotSupported 
   381         If aBuffer is not of type KMMFDataBuffer.
   382 */
   383 void CMMFDescriptor::WriteBufferL(TInt aLength, CMMFBuffer* aBuffer, TInt aPosition, MDataSource* aSupplier)
   384 	{
   385 	if (CMMFBuffer::IsSupportedDataBuffer(aBuffer->Type()))
   386 		{
   387 		TDes8& bufferDes = STATIC_CAST(CMMFDataBuffer*, aBuffer)->Data();
   388 
   389 		if (aLength>bufferDes.Length() || (aLength<0) || (aPosition<0))
   390 			User::Leave(KErrArgument);
   391 
   392 		TInt sourceLength = aLength;
   393 		TPtr8 bufferPtr(((sourceLength) ? &bufferDes[0] : NULL), sourceLength, sourceLength);
   394 		TInt targetLength = iDes->MaxLength() - aPosition;
   395 		if (targetLength>0 && sourceLength > 0)
   396 			{
   397 			if (sourceLength>targetLength)
   398 				User::Leave(KErrOverflow);
   399 
   400 			if ((iDes->Length() - aPosition) > 0)
   401 				{
   402 				TInt bytesToReplace = iDes->Length() - aPosition;
   403 				if (sourceLength > bytesToReplace) 
   404 					{
   405 					TPtrC8 replaceBuf = bufferPtr.Left(bytesToReplace);
   406 					TPtrC8 appendBuf = bufferPtr.Right(sourceLength-bytesToReplace);
   407 					iDes->Replace(aPosition, bytesToReplace, replaceBuf);
   408 					iDes->Append(appendBuf);
   409 					} 
   410 				else
   411 					iDes->Replace(aPosition, sourceLength, bufferPtr);
   412 
   413 				} 
   414 			else
   415 				iDes->Append(bufferPtr.Ptr(),sourceLength);
   416 			}
   417 		else if (targetLength<0)
   418 			User::Leave(KErrArgument);
   419 		else if (aLength != 0)
   420 			User::Leave(KErrOverflow);
   421 
   422 		if (aSupplier)
   423 			aSupplier->BufferEmptiedL(aBuffer);
   424 		}
   425 	else
   426 		User::Leave(KErrNotSupported);
   427 	}
   428 
   429 /** 
   430 Empties aBuffer into iFile at specified location.  Note that this is a synchronous write
   431 
   432 @param  aBuffer
   433         The data buffer containing bytes to be written.
   434 @param  aPosition
   435         The offset into file at which to start writing.
   436 */
   437 void CMMFDescriptor::WriteBufferL( CMMFBuffer* aBuffer, TInt aPosition)
   438 	{
   439 	WriteBufferL( aBuffer, aPosition, NULL );
   440 	}
   441 
   442 /**
   443 Returns the amount of space available for the clip.
   444 
   445 @return The space available in descriptor (difference between length and maxlength).
   446 */
   447 TInt64 CMMFDescriptor::BytesFree() 
   448 	{
   449 	TInt64 length = iDes->Length() ;
   450 	TInt64 maxLength =  iDes->MaxLength() ;
   451 	return( maxLength - length ) ;
   452 	}
   453 
   454 /**
   455 Returns the length of the clip.
   456 
   457 @return The length (not max length) of the descriptor.
   458 */
   459 TInt CMMFDescriptor::Size() 
   460 	{
   461 	TInt length = iDes->Length();
   462 	return(length);
   463 	}
   464 
   465 /**
   466 Returns the data type as a fourCC code for the CMMFDescriptor data source.
   467 
   468 @param  aMediaId
   469         The ID of the media for which the codec is obtained.
   470 
   471 @return The data type fourCC code.
   472 */
   473 TFourCC CMMFDescriptor::SourceDataTypeCode(TMediaId /*aMediaId*/) 
   474 	{
   475 	return iSourceFourCC ;
   476 	}
   477 
   478 /**
   479 Returns the data type as a fourCC code of the CMMFDescriptor data sink.
   480 
   481 Used by MDataSource and MDataSink.
   482 
   483 @return The data type fourCC code.
   484 */
   485 TFourCC CMMFDescriptor::SinkDataTypeCode(TMediaId /*aMediaId*/) 
   486 	{
   487 	return iSinkFourCC ;
   488 	}
   489 
   490 /**
   491 CMMFDescriptor as a source is always passive so this function is not supported.
   492 
   493 @param  aBuffer
   494         The emptied buffer.
   495 */
   496 void CMMFDescriptor::BufferEmptiedL( CMMFBuffer* /*aBuffer*/ )
   497 	{
   498 	Panic(EMMFDescriptorPanicBufferEmptiedLNotSupported);
   499 	}
   500 
   501 /**
   502 Tests whether a source buffer can be created.
   503 
   504 @return	A boolean indicating if the buffer can be created. EFalse if a CMMFDescriptor cannot create 
   505         it's own buffer
   506 */
   507 TBool CMMFDescriptor::CanCreateSourceBuffer()
   508 	{
   509 	return EFalse ;
   510 	}
   511 
   512 /**
   513 Creates a source buffer.
   514 
   515 @param  aMediaId
   516         The Media ID.
   517 @param  aReference
   518         A boolean indicating if MDataSource owns the buffer. ETrue if MDataSource owns the buffer,
   519         EFalse if the caller owns the buffer.
   520 
   521 @return	NULL as a CMMFFile cannot create it's own buffer
   522 */
   523 CMMFBuffer* CMMFDescriptor::CreateSourceBufferL(  TMediaId /*aMediaId*/, TBool& /*aReference*/ )
   524 	{
   525 	User::Leave(KErrNotSupported);
   526 	return NULL;
   527 	}
   528 
   529 /**
   530 CMMFDescriptor as a sink is always passive so this function is not supported.
   531 
   532 @param  aBuffer
   533         The filled buffer.
   534 */
   535 void CMMFDescriptor::BufferFilledL( CMMFBuffer* /*aBuffer*/ )
   536 	{
   537 	Panic(EMMFDescriptorPanicBufferFilledLNotSupported);
   538 	}
   539 
   540 /**
   541 Tests whether a sink buffer can be created.
   542 
   543 @return A boolean indicating if the sink buffer can be created. EFalse if a CMMFDescriptor cannot 
   544         create it's own buffer.
   545 */
   546 TBool CMMFDescriptor::CanCreateSinkBuffer()
   547 	{
   548 	return EFalse ;
   549 	}
   550 
   551 /**
   552 Creates a sink buffer.
   553 
   554 @param  aMediaId
   555         The Media ID.
   556 @param  aReference
   557         A boolean indicating if MDataSource owns the buffer. ETrue if MDataSource owns the buffer,
   558         EFalse if the caller owns the buffer.
   559 
   560 @return	NULL as a CMMFDescriptor cannot create it's own buffer
   561  */
   562 CMMFBuffer* CMMFDescriptor::CreateSinkBufferL( TMediaId /*aMediaId*/ , TBool& /*aReference*/)
   563 	{
   564 	User::Leave(KErrNotSupported);
   565 	return NULL;
   566 	}