EXPORT_C CWritePropPipe& CWritePropPipe::operator<<(const TDesC16& aSrc)
//
// Write the string to the buffer. If there is insufficient space, then leave with 
// KErrOverflow
//
	{
	__ASSERT_DEBUG(iBuf, User::Invariant());
	
	TPtr8 p = iBuf->Des();
	if(p.MaxSize() < (p.Size() + aSrc.Size() + sizeof(TInt32)))
		{
		User::Leave(KErrOverflow);
		}
	
	TPckgBuf<TInt32> size(aSrc.Size());
	p.Append(size);	
	
	TUint8* pTgt = new(ELeave)TUint8[aSrc.Size()+8];
	const TAny* pSrc = &aSrc[0];
		
	Mem::Copy(pTgt, pSrc, aSrc.Size());
	
	TPtr8 p2(pTgt, aSrc.Size(), aSrc.Size());
	p.Append(p2);
	delete pTgt;
	
	return *this;	
	}
EXPORT_C CWritePropPipe& CWritePropPipe::operator<<(const TInt32& aSrc)
	{
	__ASSERT_DEBUG(iBuf, User::Invariant());
	
	TPtr8 p = iBuf->Des();
	if(p.MaxSize() < (p.Size() + sizeof(TInt32)))
		{
		User::Leave(KErrOverflow);
		}
	
	TPckgBuf<TInt32> i(aSrc);
	p.Append(i);	
	
	return *this;	
	}
// ---------------------------------------------------------------------------
// CTransactionIDGenerator::BuildInputDataL
// ---------------------------------------------------------------------------
//
HBufC8* CTransactionIDGenerator::BuildInputDataLC( TAny* aObject,
                                                   TInt aObjectSize )
    {
    const TInt KAmountOfRandomNbrsToFill = 10;

    //Size of the input data buffer. It contains the following items:
    //
    //item                        item's size
    //----                        -----------
    //iCounter                       sizeof( iCounter )
    //aObject's state              aObjectSize    
    //checksum of this               sizeof( TUint16 )
    //clock info                  sizeof( TInt64 ) + sizeof( TUint )
    //system info                  sizeof( TUint16 ) + sizeof( TUint8 )
    //KAmountOfRandomNbrsToFill
    //random integer values     KAmountOfRandomNbrsToFill * sizeof( TInt )
    TInt dataSize = sizeof( iCounter ) + aObjectSize +
                    sizeof( TUint16 ) + sizeof( TInt64 ) + sizeof( TUint ) +
                    sizeof( TUint16 ) + sizeof( TUint8 ) +
                    KAmountOfRandomNbrsToFill * sizeof( TInt );
    HBufC8* buf = HBufC8::NewLC( dataSize );

    TPtr8 ptr = buf->Des();

    ptr.Append( reinterpret_cast<const TUint8*>( &iCounter ),
                sizeof( iCounter ) );
    ptr.Append( reinterpret_cast<const TUint8*>( aObject ), aObjectSize );
    
    ComputeChecksum( ptr, this, sizeof( this ) );

    AddClockInfo( ptr );
    AddSystemInfo( ptr );    

    TInt random = 0;
    TInt randomNumberSize = sizeof( random );
    while ( ptr.Size() <= ( ptr.MaxSize() - randomNumberSize ) )
        {
        random = Math::Rand( iSeed );
        ptr.Append( reinterpret_cast<const TUint8*>( &random ),
                    sizeof( random ) );
        }

    return buf;
    }
EXPORT_C CWritePropPipe& CWritePropPipe::operator<<(const TDesC8& aSrc)
//
// Write the string to the buffer. If there is insufficient space, then leave with 
// KErrOverflow
//
	{
	__ASSERT_DEBUG(iBuf, User::Invariant());
	
	TPtr8 p = iBuf->Des();
	if(p.MaxSize() < (p.Size() + aSrc.Size() + sizeof(TInt32)))
		{
		User::Leave(KErrOverflow);
		}
	
	TPckgBuf<TInt32> size(aSrc.Size());
	p.Append(size);	
	p.Append(aSrc);
	return *this;	
	}
// ---------------------------------------------------------------------------
// Run state machine for backup. Each file is opened and streamed to the
// BUR engine.
// ---------------------------------------------------------------------------
//
void CAknsSrvActiveBackupDataClient::GetBackupDataSectionL(
    TPtr8& aBuffer, TBool& aFinished)
    {
    AKNS_TRACE_DEBUG("CAknsSrvActiveBackupDataClient::GetBackupDataSectionL" );
    // Make sure that the buffer is empty and starts from the beginning
    aBuffer.SetLength(0);

    // don't assume they set it to false
    aFinished = EFalse;
    // any files to backup
    if( iFileArray.Count() == 0 )
        {
        // nothing to backup - just return the finished flag
        aFinished = ETrue;
        // clear the list and stop.
        iFileArray.Reset();
        AKNS_TRACE_DEBUG("CAknsSrvActiveBackupDataClient::GetBackupDataSectionL no files" );
        return;
        }

    // run the state machine
    while( ETrue )
        {
        switch( iBackupState )
            {
            // open a file for processing
            case EBackupNoFileOpen:
                {
                AKNS_TRACE_DEBUG1("CAknsSrvActiveBackupDataClient::GetBackupDataSectionL state %d", iBackupState );
                if( iFileIndex >= iFileArray.Count() )
                    {
                    // all files have been processed - send the finished flag
                    aFinished = ETrue;
                    // clear the list and stop.
                    iFileArray.Reset();
                    AKNS_TRACE_DEBUG("CAknsSrvActiveBackupDataClient::GetBackupDataSectionL all processed" );
                    return;
                    }

                // open file to send
                TInt rc=iFile.Open( iFsSession,
                                    iFileArray[iFileIndex].FullName(),
                                    ( EFileRead | EFileShareExclusive | EFileStream ) );
                if( rc != KErrNone )
                    {
                    // there's nothing we can do if we can't open the file
                    // so we just skip it
                    AKNS_TRACE_DEBUG("CAknsSrvActiveBackupDataClient::GetBackupDataSectionL skip file" );
                    ++iFileIndex;
                    break;
                    }
                iBackupState = EBackupOpenNothingSent;
                break;
                }
            // nothing sent (so far) for this file - send the header info
            case EBackupOpenNothingSent:
                {
                AKNS_TRACE_DEBUG1("CAknsSrvActiveBackupDataClient::GetBackupDataSectionL state %d", iBackupState );
                TInt fileSize;
                TInt retValue = iFile.Size( fileSize );
                if( retValue != KErrNone || fileSize == 0 )
                    {
                    // empty or unreadable - skip this file
                    iBackupState = EBackupEndOfFile;
                    AKNS_TRACE_DEBUG("CAknsSrvActiveBackupDataClient::GetBackupDataSectionL skip file2" );
                    break;
                    }

                // build the header - this is an instance member because it
                // has to persist over multiple calls to this method
                TPtr headerPtr = iBuffer->Des();

                // get the checksum - only grab last 4 bytes - enough to be satisfied that
                // the backup and restore worked ok
                TUint64 checksum = CheckSumL( iFile ) & 0xffffffff;

                // build the header - note NOT AppendFormat(); wipes out previous content.
                // <no of files><checksum><filesize><filenamelen><filename>
                headerPtr.Format(_L("%8x%8lx%8x%8x"),
                    iFileArray.Count(),
                    checksum,
                    fileSize,
                    iFileArray[iFileIndex].FullName().Length());
                headerPtr.Append( iFileArray[iFileIndex].FullName() );

                // we need it to look like an 8bit buffer
                TPtr8 headerPtr8(
                    (TUint8*)headerPtr.Ptr(),
                    headerPtr.Size(),
                    headerPtr.Size() );

                // Check how much room is left in the buffer.
                // it starts out empty when we get it from the BUE
                TInt available = aBuffer.MaxSize() - aBuffer.Size();

                // Check is there enough room for the whole header.
                TBool enoughRoom = headerPtr8.Size() < available;

                // append the header to the buffer (only till it's full)
                aBuffer.Append(
                    headerPtr8.Ptr(),
                    enoughRoom ? headerPtr8.Size() : available) ;

                // decide what needs to happen next
                // if complete then we need data, otherwise we need to put
                // the rest of the header in the next chunk
                if( enoughRoom )
                    {
                    iBackupState = EBackupOpenAllHeaderSent;
                    }
                else
                    {
                    // we need to keep track of how much of the header has
                    // been sent so that we only send the reminder on the next
                    // iteration
                    iHeaderSent = available;
                    iBackupState = EBackupOpenPartHeaderSent;
                    }

                // if the buffer's full we need to return control to the backup engine
                // Because the finishedFlag is not set, the BUE will process this
                // chunk and then ask for another
                if( aBuffer.Size() == aBuffer.MaxSize() )
                    {
                    return;
                    }
                break;
                }
            // need to send the rest of the header
            case EBackupOpenPartHeaderSent:
                {
                AKNS_TRACE_DEBUG1("CAknsSrvActiveBackupDataClient::GetBackupDataSectionL state %d", iBackupState );
                // get back the header - this is already loaded with the necessary info
                // from the previous state we were in
                TPtr headerPtr = iBuffer->Des();

                // we need it to look like an 8bit buffer
                TPtr8 headerPtr8(
                    (TUint8*)headerPtr.Ptr(),
                    headerPtr.Size(),
                    headerPtr.Size() );

                // Check how many bytes have we yet to send.
                TInt bytesRemaining = headerPtr.Size() - iHeaderSent;

                // Check how much room in the buffer.
                TInt available = aBuffer.MaxSize() - aBuffer.Size();

                // enough, if not send as much as we can
                TBool enoughRoom = bytesRemaining < available;
                aBuffer.Append(
                    headerPtr8.Ptr() + iHeaderSent,
                    enoughRoom ? bytesRemaining : available );

                if( enoughRoom )
                    {
                    iHeaderSent = 0; // ready for next header
                    iBackupState = EBackupOpenAllHeaderSent;
                    }
                else
                    {
                    iHeaderSent += available; // ready to do round again
                    // state remains as EBackupOpenPartHeaderSent
                    }

                // if the buffer's full we need to return control to the backup engine
                // Because the finishedFlag is not set, the BUE will process this
                // chunk and then ask for another
                if( aBuffer.Size() == aBuffer.MaxSize() )
                    {
                    return;
                    }
                break;
                }
            // need to send some data
            case EBackupOpenAllHeaderSent:
                {
                AKNS_TRACE_DEBUG1("CAknsSrvActiveBackupDataClient::GetBackupDataSectionL state %d", iBackupState );
                // how many bytes can we send
                TInt available = aBuffer.MaxSize() - aBuffer.Size();

                // create a buffer for this data (plus one for PtrZ)
                HBufC8* transferBuffer = HBufC8::NewLC( available + 1 );
                TPtr8 bufferToSend = transferBuffer->Des();

                // get the data
                User::LeaveIfError( iFile.Read( bufferToSend, available ) );

                // Check how much did we actually read.
                TInt bytesRead = bufferToSend.Size();

                // EOF
                if( bytesRead == 0 )
                    {
                    CleanupStack::PopAndDestroy( transferBuffer );
                    iBackupState = EBackupEndOfFile;
                    break;
                    }

                // add it to the aBuffer
                aBuffer.Append( bufferToSend.PtrZ(), bytesRead );

                // tidy up
                CleanupStack::PopAndDestroy( transferBuffer );

                // if the buffer's full we need to return control to the backup engine
                if( aBuffer.Size() == aBuffer.MaxSize() )
                    {
                    return;
                    }
                break;
                }
            // At the end of the current file.
            case EBackupEndOfFile:
                {
                AKNS_TRACE_DEBUG1("CAknsSrvActiveBackupDataClient::GetBackupDataSectionL state %d", iBackupState );

                // how many bytes can we send
                if ( aBuffer.Size() != 0 )
                    {
                    TInt available = aBuffer.MaxSize() - aBuffer.Size();
                    // pad the end of the buffer with NULL.
                    HBufC8* transferBuffer = HBufC8::NewLC( available + 1 );
                    TPtr8 bufferToSend = transferBuffer->Des();
                    bufferToSend.FillZ();
                    aBuffer.Append( bufferToSend.PtrZ(), available );
                    CleanupStack::PopAndDestroy( transferBuffer );
                    if( aBuffer.Size() != aBuffer.MaxSize() )
                        {
                        // Sanity check
                        User::Leave( KErrGeneral );
                        }
                    }
                // Close file and move on to next file.
                iFile.Close();
                ++iFileIndex;
                // Start all over again.
                iBackupState = EBackupNoFileOpen;
                break;
                }
            default:
                {
                // not reachable
                return;
                }
            }
        }
    }