Update contrib.
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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
19 #include <mmf/server/mmfdes.h>
20 #include <mmf/server/mmfdatabuffer.h>
21 #include <mmf/common/mmfpaniccodes.h>
23 void Panic(TMMFDescriptorPanicCode aPanicCode)
25 _LIT(KMMFDescriptorPanicCategory, "MMFDescriptor");
26 User::Panic(KMMFDescriptorPanicCategory, aPanicCode);
30 Protected constructor.
32 Sets the offset to zero.
34 CMMFDescriptor::CMMFDescriptor( ) : CMMFClip( KUidMmfDescriptorSource, KUidMmfDescriptorSink )
41 The default implementation closes the descriptor thread.
43 CMMFDescriptor::~CMMFDescriptor()
49 Constructs a CMMFDescriptor MDataSource.
51 @return A pointer to a new CMMFDescriptor.
53 MDataSource* CMMFDescriptor::NewSourceL( )
55 CMMFDescriptor* self = new (ELeave) CMMFDescriptor( ) ;
56 return STATIC_CAST( MDataSource*, self ) ;
60 Constructs a CMMFDescriptor MDataSink.
62 @return A pointer to a new CMMFDescriptor.
64 MDataSink* CMMFDescriptor::NewSinkL( )
66 CMMFDescriptor* self = new (ELeave) CMMFDescriptor( ) ;
67 return STATIC_CAST( MDataSink*, self ) ;
71 Performs source construction dependant on the source construction
72 initialisation data aInitData.
75 The TPckgC<TMMFDescriptorParams> descriptor package containing the descriptor and the thread
76 ID for the descriptor.
78 void CMMFDescriptor::ConstructSourceL( const TDesC8& aInitData )
80 ConstructL( aInitData ) ;
85 Sets how much of the underlying descriptor will be used, up to the underlying descriptor's maximum
89 The size of the descriptor.
91 @return An error code indicating if the function call was successful. KErrNone on success, otherwise
92 another of the system-wide error codes.
94 TInt CMMFDescriptor::SetSize( TInt aSize )
96 //[ precondition aSize >= 0
97 // precondition sSize < MaxSize()
102 if( aSize > MaxLength() )
106 return KErrUnderflow;
108 // [ actually do the work ]
109 iDes->SetLength( aSize );
111 //[ assert the post condition
113 // descriptor is still ok]
114 ASSERT( aSize == iDes->Length());
122 Performs sink construction dependant on the sink construction initialisation data aInitData.
125 The TPckgC<TMMFDescriptorParams> descriptor package containing
126 the descriptor and the thread ID for the descriptor.
128 void CMMFDescriptor::ConstructSinkL( const TDesC8& aInitData )
130 ConstructL( aInitData ) ;
133 void CMMFDescriptor::ConstructL( const TDesC8& aInitData )
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 ) );
146 Loads aBuffer from iDes.
148 File read is asynchronous. CReadRequest is created to respond to completion.
151 The buffer to be filled from the descriptor.
153 The data sink consumer of the buffer.
157 void CMMFDescriptor::FillBufferL( CMMFBuffer* aBuffer, MDataSink* aConsumer, TMediaId /*aMediaId*/ )
159 // Current position in Descriptor is iOffset.
161 // Read from iDes in iDesThread into Des in aBuffer.
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?
168 // Use of a single iOffset will preclude use by more than one client (use ReadBufferL())
169 if (CMMFBuffer::IsSupportedDataBuffer(aBuffer->Type()))
171 TDes8& bufferDes = STATIC_CAST(CMMFDataBuffer*, aBuffer)->Data();
173 //if request size is set, use it, else use max length of buffer
174 TInt targetMaxLength = aBuffer->RequestSize() ? aBuffer->RequestSize() : bufferDes.MaxLength();
176 //ensure RequestSize was within bounds
177 if(targetMaxLength > bufferDes.MaxLength())
178 targetMaxLength = bufferDes.MaxLength();
180 TInt sourceLengthRemaining = iDes->Length() - iOffset;
181 if ( ( sourceLengthRemaining - targetMaxLength ) > 0 )
183 bufferDes = iDes->Mid(iOffset,targetMaxLength);
184 iOffset += targetMaxLength;
186 else if (sourceLengthRemaining > 0)
188 bufferDes = iDes->Mid(iOffset,sourceLengthRemaining);
189 iOffset += sourceLengthRemaining;
190 aBuffer->SetLastBuffer(ETrue);
194 bufferDes.SetLength(0);
195 aBuffer->SetLastBuffer(ETrue);
198 aConsumer->BufferFilledL( aBuffer ) ;
201 User::Leave(KErrNotSupported);
205 Empties aBuffer into iDes.
208 The buffer to be written to the descriptor.
210 The data source supplier of the buffer.
214 void CMMFDescriptor::EmptyBufferL( CMMFBuffer* aBuffer, MDataSource* aSupplier, TMediaId /*aMediaId*/ )
216 // Does the buffer type need to be checked?
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()))
224 TDes8& bufferDes = STATIC_CAST(CMMFDataBuffer*, aBuffer)->Data();
226 TInt sourceLength = bufferDes.Length() ;
227 TInt targetLength = iDes->MaxLength() - iDes->Length();
228 if ( targetLength>0 )
230 if (sourceLength>targetLength)
232 sourceLength = targetLength;
233 bufferDes.SetLength(targetLength);
236 iDes->Append(bufferDes) ;
239 bufferDes.SetLength(0);
241 aSupplier->BufferEmptiedL( aBuffer ) ;
244 User::Leave(KErrNotSupported);
248 Loads aLength number of bytes into aBuffer from specified point in iDes.
251 The number of bytes to be read into buffer.
253 The buffer to be filled from the descriptor.
255 The offset into the descriptor at which to start reading.
257 The data sink consumer of the buffer
259 void CMMFDescriptor::ReadBufferL(TInt aLength, CMMFBuffer* aBuffer, TInt aPosition, MDataSink* aConsumer)
262 User::Leave(KErrArgument);
264 if (CMMFBuffer::IsSupportedDataBuffer(aBuffer->Type()))
266 TDes8& bufferDes = STATIC_CAST(CMMFDataBuffer*, aBuffer)->Data();
268 if (aLength>bufferDes.MaxLength())
269 User::Leave(KErrOverflow);
271 if ((aLength<0) || (aPosition<0))
272 User::Leave(KErrArgument);
274 TInt sourceLength = iDes->Length() ;
276 //ensure not trying to read more than is available
277 if(aPosition + aLength > sourceLength)
278 aLength = sourceLength - aPosition;
282 TPtrC8 srcPtr(iDes->Mid(aPosition,aLength));
283 bufferDes.Copy(srcPtr.Ptr(),aLength);
286 bufferDes.SetLength(0);
288 //have we read all the available data
289 if(aPosition + aLength >= sourceLength)
290 aBuffer->SetLastBuffer(ETrue);
293 aConsumer->BufferFilledL(aBuffer);
296 User::Leave(KErrNotSupported);
300 Loads aBuffer from specified point in iDes
303 The buffer to be filled from the descriptor.
305 The offset into the descriptor at which to start reading.
307 The data sink consumer of the buffer.
309 void CMMFDescriptor::ReadBufferL(CMMFBuffer* aBuffer, TInt aPosition, MDataSink* aConsumer)
312 User::Leave(KErrArgument);
315 User::Leave(KErrArgument);
317 if (CMMFBuffer::IsSupportedDataBuffer(aBuffer->Type()))
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();
323 ReadBufferL(copyLength, aBuffer, aPosition, aConsumer);
326 User::Leave(KErrNotSupported);
330 Loads aBuffer from specified point in iDes. Note that this is a synchronous read.
333 The buffer to be filled from the descriptor.
335 The offset into the descriptor at which to start reading.
337 void CMMFDescriptor::ReadBufferL(CMMFBuffer* aBuffer, TInt aPosition)
339 ReadBufferL(aBuffer, aPosition, NULL);
343 Empties aBuffer into iDes at specified location.
346 The data buffer containing bytes to be written.
348 The offset into the descriptor at which to start writing.
350 The data source to be notified when the write has been completed.
352 void CMMFDescriptor::WriteBufferL(CMMFBuffer* aBuffer, TInt aPosition, MDataSource* aSupplier)
354 if (CMMFBuffer::IsSupportedDataBuffer(aBuffer->Type()))
356 TDes8& bufferDes = STATIC_CAST(CMMFDataBuffer*, aBuffer)->Data();
358 WriteBufferL(bufferDes.Length(), aBuffer, aPosition, aSupplier);
361 User::Leave(KErrNotSupported);
365 Empties aLength bytes from aBuffer into iDes at specified location.
368 The number of bytes to be emptied from buffer.
370 The data buffer containing bytes to be written.
372 The offset into the descriptor at which to start writing.
374 The data source to be notified when the write has been completed.
377 If SinkPrimeL() and SinkThreadLogon() have not been called.
379 If aLength<0 or aPosition<0 or aSupplier is NULL.
380 @leave KErrNotSupported
381 If aBuffer is not of type KMMFDataBuffer.
383 void CMMFDescriptor::WriteBufferL(TInt aLength, CMMFBuffer* aBuffer, TInt aPosition, MDataSource* aSupplier)
385 if (CMMFBuffer::IsSupportedDataBuffer(aBuffer->Type()))
387 TDes8& bufferDes = STATIC_CAST(CMMFDataBuffer*, aBuffer)->Data();
389 if (aLength>bufferDes.Length() || (aLength<0) || (aPosition<0))
390 User::Leave(KErrArgument);
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)
397 if (sourceLength>targetLength)
398 User::Leave(KErrOverflow);
400 if ((iDes->Length() - aPosition) > 0)
402 TInt bytesToReplace = iDes->Length() - aPosition;
403 if (sourceLength > bytesToReplace)
405 TPtrC8 replaceBuf = bufferPtr.Left(bytesToReplace);
406 TPtrC8 appendBuf = bufferPtr.Right(sourceLength-bytesToReplace);
407 iDes->Replace(aPosition, bytesToReplace, replaceBuf);
408 iDes->Append(appendBuf);
411 iDes->Replace(aPosition, sourceLength, bufferPtr);
415 iDes->Append(bufferPtr.Ptr(),sourceLength);
417 else if (targetLength<0)
418 User::Leave(KErrArgument);
419 else if (aLength != 0)
420 User::Leave(KErrOverflow);
423 aSupplier->BufferEmptiedL(aBuffer);
426 User::Leave(KErrNotSupported);
430 Empties aBuffer into iFile at specified location. Note that this is a synchronous write
433 The data buffer containing bytes to be written.
435 The offset into file at which to start writing.
437 void CMMFDescriptor::WriteBufferL( CMMFBuffer* aBuffer, TInt aPosition)
439 WriteBufferL( aBuffer, aPosition, NULL );
443 Returns the amount of space available for the clip.
445 @return The space available in descriptor (difference between length and maxlength).
447 TInt64 CMMFDescriptor::BytesFree()
449 TInt64 length = iDes->Length() ;
450 TInt64 maxLength = iDes->MaxLength() ;
451 return( maxLength - length ) ;
455 Returns the length of the clip.
457 @return The length (not max length) of the descriptor.
459 TInt CMMFDescriptor::Size()
461 TInt length = iDes->Length();
466 Returns the data type as a fourCC code for the CMMFDescriptor data source.
469 The ID of the media for which the codec is obtained.
471 @return The data type fourCC code.
473 TFourCC CMMFDescriptor::SourceDataTypeCode(TMediaId /*aMediaId*/)
475 return iSourceFourCC ;
479 Returns the data type as a fourCC code of the CMMFDescriptor data sink.
481 Used by MDataSource and MDataSink.
483 @return The data type fourCC code.
485 TFourCC CMMFDescriptor::SinkDataTypeCode(TMediaId /*aMediaId*/)
491 CMMFDescriptor as a source is always passive so this function is not supported.
496 void CMMFDescriptor::BufferEmptiedL( CMMFBuffer* /*aBuffer*/ )
498 Panic(EMMFDescriptorPanicBufferEmptiedLNotSupported);
502 Tests whether a source buffer can be created.
504 @return A boolean indicating if the buffer can be created. EFalse if a CMMFDescriptor cannot create
507 TBool CMMFDescriptor::CanCreateSourceBuffer()
513 Creates a source buffer.
518 A boolean indicating if MDataSource owns the buffer. ETrue if MDataSource owns the buffer,
519 EFalse if the caller owns the buffer.
521 @return NULL as a CMMFFile cannot create it's own buffer
523 CMMFBuffer* CMMFDescriptor::CreateSourceBufferL( TMediaId /*aMediaId*/, TBool& /*aReference*/ )
525 User::Leave(KErrNotSupported);
530 CMMFDescriptor as a sink is always passive so this function is not supported.
535 void CMMFDescriptor::BufferFilledL( CMMFBuffer* /*aBuffer*/ )
537 Panic(EMMFDescriptorPanicBufferFilledLNotSupported);
541 Tests whether a sink buffer can be created.
543 @return A boolean indicating if the sink buffer can be created. EFalse if a CMMFDescriptor cannot
544 create it's own buffer.
546 TBool CMMFDescriptor::CanCreateSinkBuffer()
552 Creates a sink buffer.
557 A boolean indicating if MDataSource owns the buffer. ETrue if MDataSource owns the buffer,
558 EFalse if the caller owns the buffer.
560 @return NULL as a CMMFDescriptor cannot create it's own buffer
562 CMMFBuffer* CMMFDescriptor::CreateSinkBufferL( TMediaId /*aMediaId*/ , TBool& /*aReference*/)
564 User::Leave(KErrNotSupported);