mmlibs/mmfw/src/Plugin/StdSourceAndSink/Mmfdes.cpp
changeset 0 b8ed18f6c07b
equal deleted inserted replaced
-1:000000000000 0:b8ed18f6c07b
       
     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 	}