omadrm/drmengine/dcfrepository/client/src/DcfRep.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Fri, 16 Apr 2010 15:14:55 +0300
changeset 23 493788a4a8a4
parent 0 95b198f216e5
permissions -rw-r--r--
Revision: 201011 Kit: 201015

/*
* Copyright (c) 2002-2004 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:  API wrapper side implementation
*
*/


// INCLUDE FILES
#include    "DcfRep.h"
#include    "DcfEntry.h"
#include    "DcfRepCommon.h"
#include    <e32std.h>
#include    <e32base.h>
#include    <DRMRightsClient.h>

#ifdef RD_MULTIPLE_DRIVE
#include <driveinfo.h>
#endif

// EXTERNAL DATA STRUCTURES
// EXTERNAL FUNCTION PROTOTYPES
// CONSTANTS
_LIT(KSqlOrderList , "select filename,position,cid,group from dcf");
_LIT(KSqlOrderListStart , "select filename,position,cid,group from dcf where cid = '");
_LIT(KSqlOrderListEnd , "' order by filename");
_LIT(KSqlOrderListGroupStart , "select filename,position,cid,group from dcf where group = '");
_LIT(KSqlOrderListGroupEnd , "' order by filename");
_LIT(KSqlGetTtidStart , "select ttid from dcf where cid = '");
_LIT(KSqlGetTtidEnd , "' order by ttid");
_LIT(KSqlGetFileStart , "select filename from dcf where cid = '");
_LIT(KSqlGetFileEnd , "' order by filename");
_LIT(KSqlGetCidStart , "select cid from dcf where filename = '");
_LIT(KSqlGetCidEnd , "' order by cid");
_LIT(KSqlDeleteStart , "delete from dcf where filename = '");
_LIT(KSqlDeleteEnd , "'");
_LIT8(KFlkString, "flk:");
_LIT8(KCidString, "cid:");
// MACROS
// LOCAL CONSTANTS AND MACROS
static const TInt KDcfRepExtra( 100 );
#ifdef RD_MULTIPLE_DRIVE
_LIT( KDbFileLoc, "%c:\\system\\data\\DcfRepDb" );
#endif

// MODULE DATA STRUCTURES
// LOCAL FUNCTION PROTOTYPES
// FORWARD DECLARATIONS

// ============================= LOCAL FUNCTIONS ===============================

// -----------------------------------------------------------------------------
// From8To16
//
// -----------------------------------------------------------------------------
//
LOCAL_C TInt From8To16( const TDesC8& a8 , HBufC16*& a16 )
    {
    TInt err = KErrNone;
    a16 = HBufC::NewMax( a8.Length() );
    if ( a16 )
        {
        TPtr ptr( a16->Des() );
        ptr.SetLength( a8.Length() );
        for (TInt i = 0 ; i<a8.Length() ; i++ )
            {
            ptr[i] = ( unsigned char ) a8[i];
            }
        }
    else
        {
        err = KErrNoMemory;
        }
    return err;
    }

// -----------------------------------------------------------------------------
// From16To8
//
// -----------------------------------------------------------------------------
//
LOCAL_C TInt From16To8( const TDesC& a16 , HBufC8*& a8 )
    {
    TInt err = KErrNone;
    a8 = HBufC8::NewMax( a16.Length() );
    if ( a8 )
        {
        TPtr8 ptr( a8->Des() );
        ptr.SetLength(a16.Length());
        for (TInt i = 0 ; i<a16.Length() ; i++ )
            {
            ptr[i] = ( unsigned char ) a16[i];
            }
        }
    else
        {
        err = KErrNoMemory;
        }
    return err;
    }
// ============================ MEMBER FUNCTIONS ===============================

// -----------------------------------------------------------------------------
// CDcfRep::CDcfRep
// C++ default constructor can NOT contain any code, that
// might leave.
// -----------------------------------------------------------------------------
//
CDcfRep::CDcfRep()
    {
    }

// -----------------------------------------------------------------------------
// CDcfRep::ConstructL
// Symbian 2nd phase constructor can leave.
// -----------------------------------------------------------------------------
//
void CDcfRep::ConstructL()
    {
    User::LeaveIfError(iClient.Connect());
    OpenDatabaseL();
    }

// -----------------------------------------------------------------------------
// CDcfRep::NewL
// Two-phased constructor.
// -----------------------------------------------------------------------------
//
EXPORT_C CDcfRep* CDcfRep::NewL()
    {
    CDcfRep* self = new( ELeave ) CDcfRep;

    CleanupStack::PushL( self );
    self->ConstructL();
    CleanupStack::Pop(self);
    return self;
    }


// Destructor
EXPORT_C CDcfRep::~CDcfRep()
    {
    iClient.Close();
    iView.Close();
    iDb.Close();
    iDbs.Close();
    }

// -----------------------------------------------------------------------------
// CDcfRep::UpdateL
// Add new entry to database
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
EXPORT_C void CDcfRep::UpdateL( const CDcfEntry* aEntry)
    {
    if ( !aEntry || ( aEntry->FileName().Length() <= 0 && aEntry->Cid().Length() <= 0 ) )
        {
        User::Leave(KErrArgument);
        }
    else if ( aEntry->FileName().Length() > 0)
        {
        // Filename is defined. If content ID is defined as well, we igore content ID
        TInt err = 0;
        HBufC8* buf8 = NULL;
        RPointerArray<HBufC8> list8;
        CleanupClosePushL(list8);
        User::LeaveIfError(iClient.AddFile(aEntry->FileName()));
        GetCidL(aEntry->FileName(),list8);
        for (TInt i = 0 ; i<list8.Count() && (!err) ; i++ )
            {
            TParse p;
            err = p.Set(aEntry->FileName(),NULL,NULL);
            if (!err)
                {
                buf8 = list8[i];
                err = SetName(*buf8,p.NameAndExt());
                }
            }
        // clean list first then leave if errors occured
        list8.ResetAndDestroy();
        User::LeaveIfError(err);
        CleanupStack::PopAndDestroy(&list8);
        }
    else
        {
        // only content ID is defined
        TInt err = 0;
        HBufC* buf16 = NULL;
        RPointerArray<HBufC> list16;
        CleanupClosePushL(list16);
        GetFilenameL(aEntry->Cid(),list16);
        for (TInt i = 0 ; i<list16.Count() && (!err) ; i++ )
            {
            if (i==0)
                {
                // set name with the first found file. the name is set only when there is no name set before
                TParse p;
                err = p.Set(*(list16[i]),NULL,NULL);
                if (!err)
                    {
                    err = SetName(aEntry->Cid(),p.NameAndExt());
                    }
                }
            buf16 = list16[i];
            if (!err)
                {
                err = iClient.AddFile(*buf16);
                }
            }
        // clean list first then leave if errors occured
        list16.ResetAndDestroy();
        User::LeaveIfError(err);
        CleanupStack::PopAndDestroy(&list16);
        }
    }


// -----------------------------------------------------------------------------
// CDcfRep::GetTtid
// Get transaction ID from database
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
EXPORT_C void CDcfRep::GetTtidL(RArray<TPair>& aList)
    {
    TInt i = 0;
    for (;i<aList.Count();i++)
        {
        if ( !(aList[i].iCid) )
            {
            User::Leave(KErrArgument);
            }
        GetTtidL( *(aList[i].iCid) , aList[i].iTtid);
        }
    }

// -----------------------------------------------------------------------------
// CDcfRep::GetTtidL
// Get transaction ID from database
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CDcfRep::GetTtidL(const TDesC8& aCid , HBufC8*& aTtid)
    {
    TBool flag = ETrue;
    HBufC* temp = NULL;
    RDbView view;
    CleanupClosePushL(view);
    HBufC* buf = HBufC::NewLC(aCid.Length()+KDcfRepExtra);
    TPtr ptr(buf->Des());
    ptr.SetLength(0);


    User::LeaveIfError(From8To16(aCid,temp));
    CleanupStack::PushL(temp);
    ptr.Append(KSqlGetTtidStart);
    ptr.Append(*temp);
    ptr.Append(KSqlGetTtidEnd);
    CleanupStack::PopAndDestroy(temp); //temp

    User::LeaveIfError(view.Prepare(iDb,TDbQuery(ptr,EDbCompareNormal),TDbWindow::EUnlimited));
    User::LeaveIfError(view.EvaluateAll());
    CleanupStack::PopAndDestroy(buf); //buf
    flag = view.FirstL();
    if (!flag)
        {
        aTtid = NULL;
        }
    else
        {
        view.GetL();
        buf = HBufC::NewL(view.ColLength(1));
        *buf = view.ColDes(1);
        CleanupStack::PushL(buf);
        User::LeaveIfError(From16To8(*buf,aTtid));
        CleanupStack::PopAndDestroy(buf); //buf
        }
    CleanupStack::PopAndDestroy(&view);
    }

// -----------------------------------------------------------------------------
// CDcfRep::GetFileHandle
// Get File Handle for a Dcf associated with a specific CID
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
EXPORT_C void CDcfRep::GetFileHandleL(
            const TDesC8& aCid ,
            RFile& aFile , RFs& aFs )
    {
    TInt error = KErrNone;
    TPtr8 data(NULL,0);


    // Try to find the file and get a handle to it with the given string
    TRAP(error, DoGetFileHandleL( aCid, aFile, aFs ));


    // If we can't find a filehandle and the contentid starts with "cid:"
    // We may have a FL + SD content, so change the "cid:" to flk and search
    // again
    if( error == KErrNotFound &&
        !(aCid.Left(KCidString().Length()).Compare(KCidString()) ) )
        {
        HBufC8* url( aCid.AllocLC() );
        data.Set( const_cast<TUint8*>(url->Ptr()), url->Length(), url->Length() );
        data.Replace( 0, KCidString().Length(), KFlkString );

        DoGetFileHandleL( data, aFile, aFs );
        CleanupStack::PopAndDestroy( url );
        }
    else
        {
        User::LeaveIfError( error );
        }
    }



void CDcfRep::DoGetFileHandleL(
            const TDesC8& aCid ,
            RFile& aFile , RFs& aFs )
    {
    TBool flag = ETrue;
    HBufC* temp = NULL;
    RDbView view;
    CleanupClosePushL(view);
    HBufC* buf = HBufC::NewLC(aCid.Length()+KDcfRepExtra);
    TPtr ptr(buf->Des());
    ptr.SetLength(0);


    User::LeaveIfError(From8To16(aCid,temp));
    CleanupStack::PushL(temp);
    ptr.Append(KSqlGetFileStart);
    ptr.Append(*temp);
    ptr.Append(KSqlGetFileEnd);
    CleanupStack::PopAndDestroy(temp); //temp
    User::LeaveIfError(view.Prepare(iDb,TDbQuery(ptr,EDbCompareNormal),TDbWindow::EUnlimited));
    User::LeaveIfError(view.EvaluateAll());
    CleanupStack::PopAndDestroy(buf); //buf
    flag = view.FirstL();
    if (!flag)
        {
        User::Leave(KErrNotFound);
        }
    else
        {
        RDbColReadStream strm;
        TInt err = 0;
        TBool flag = ETrue;
        TUint len = 0;
        while (flag&&view.AtRow())
            {
            view.GetL();
            len = view.ColLength(1);
            temp = HBufC::NewLC(len);
            ptr.Set(temp->Des());
            strm.OpenLC(view,1);
            strm.ReadL(ptr,len);
            CleanupStack::PopAndDestroy(&strm);
            err = aFile.Open(aFs, ptr, EFileRead|EFileShareReadersOrWriters);
            CleanupStack::PopAndDestroy(temp); // temp
            if(err == KErrNotFound || err == KErrAccessDenied)
                {
                view.NextL();
                }
            else
                {
                flag = EFalse;
                }
            }
        User::LeaveIfError(err);
        }
    CleanupStack::PopAndDestroy(&view);
    }



// -----------------------------------------------------------------------------
// CDcfRep::NextL
// Return entries as iteration.
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
EXPORT_C CDcfEntry* CDcfRep::NextL()
    {
    CDcfEntry* entry = NULL;
    HBufC16* buf = NULL;
    HBufC8* temp = NULL;
    if (iView.AtRow())
        {
        TInt len = 0;
        TUint position = 0;
        TPtr ptr(NULL,0,0);
        RDbColReadStream strm;

        entry = CDcfEntry::NewL();
        CleanupStack::PushL(entry);
        iView.GetL();

        //Set filename and postion
        len = iView.ColLength(KOrdFilename);
        buf = HBufC::NewLC(len);
        ptr.Set(buf->Des());
        strm.OpenLC(iView,KOrdFilename);
        strm.ReadL(ptr,len);
        position = iView.ColUint16(KOrdPosition);
        entry->SetLocationL(ptr,position);
        CleanupStack::PopAndDestroy(&strm);
        CleanupStack::PopAndDestroy(buf);


        // Set content ID
        len = iView.ColLength(KOrdCid);
        buf = HBufC::NewLC(len);
        ptr.Set(buf->Des());
        strm.OpenLC(iView,KOrdCid);
        strm.ReadL(ptr,len);
        CleanupStack::PopAndDestroy(&strm);
        User::LeaveIfError(From16To8(*buf,temp));
        CleanupStack::PopAndDestroy(buf); // buf
        CleanupStack::PushL(temp);
        entry->SetCidL(*temp);
        CleanupStack::PopAndDestroy(temp);


        //Set Group Id
        len = iView.ColLength(KOrdGroupId);
        buf = HBufC::NewLC(len);
        ptr.Set(buf->Des());
        if (len>0)
            {
            strm.OpenLC(iView,KOrdGroupId);
            strm.ReadL(ptr,len);
            CleanupStack::PopAndDestroy(&strm);
            }
        else
            {
            ptr.SetLength(0);
            }
        User::LeaveIfError(From16To8(*buf,temp));
        CleanupStack::PopAndDestroy(buf); // buf
        CleanupStack::PushL(temp);
        entry->SetGroupIdL(*temp);
        CleanupStack::PopAndDestroy(temp); // temp

        iView.NextL();
        CleanupStack::Pop(entry); //entry
        }
    else
        {
        iView.Reset();
        iView.Close();
        }
    return entry;
    }


// -----------------------------------------------------------------------------
// CDcfRep::OrderListL
// Order all entries from DB.
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
EXPORT_C void  CDcfRep::OrderListL()
    {
    TBool flag = ETrue;

    iView.Close();

    User::LeaveIfError(iView.Prepare(
        iDb,TDbQuery(KSqlOrderList(),EDbCompareNormal),
        TDbWindow::EUnlimited));
    User::LeaveIfError(iView.EvaluateAll());
    flag = iView.FirstL();
    if (!flag)
        {
        iView.Reset();
        iView.Close();
        User::Leave(KErrNotFound);
        }
    }

// -----------------------------------------------------------------------------
// CDcfRep::OrderListL
// Order all entries with specific CID from DB.
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
EXPORT_C void  CDcfRep::OrderListL(const TDesC8& aCid)
    {
    TBool flag = ETrue;
    HBufC* temp = NULL;
    HBufC* buf = NULL;
    TPtr ptr(NULL,0,0);

    iView.Close();

    User::LeaveIfError(From8To16(aCid,temp));
    CleanupStack::PushL(temp);
    buf = HBufC::NewLC(aCid.Length()+KDcfRepExtra);
    ptr.Set(buf->Des());
    ptr.SetLength(0);
    ptr.Append(KSqlOrderListStart);
    ptr.Append(*temp);
    ptr.Append(KSqlOrderListEnd);
    User::LeaveIfError(iView.Prepare(
        iDb,TDbQuery(ptr,EDbCompareNormal),
        TDbWindow::EUnlimited));
    User::LeaveIfError(iView.EvaluateAll());
    flag = iView.FirstL();
    if (!flag)
        {
        // try group id
        iView.Reset();
        iView.Close();
        CleanupStack::PopAndDestroy(buf);
        buf = HBufC::NewLC(aCid.Length()+KDcfRepExtra);
        ptr.Set(buf->Des());
        ptr.SetLength(0);
        ptr.Append(KSqlOrderListGroupStart);
        ptr.Append(*temp);
        ptr.Append(KSqlOrderListGroupEnd);
        User::LeaveIfError(iView.Prepare(
            iDb,TDbQuery(ptr,EDbCompareNormal),
            TDbWindow::EUnlimited));
        User::LeaveIfError(iView.EvaluateAll());
        flag = iView.FirstL();
        if (!flag)
            {
            // not group id
            iView.Reset();
            iView.Close();
            CleanupStack::PopAndDestroy( buf );
            CleanupStack::PopAndDestroy( temp );
            User::Leave(KErrNotFound);
            }
        }
    CleanupStack::PopAndDestroy( buf );
    CleanupStack::PopAndDestroy( temp );
    }

// -----------------------------------------------------------------------------
// CDcfRep::RemoveDcfFromDbL
// Remove all the entries that have the filename in database.
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
EXPORT_C void CDcfRep::RemoveDcfFromDbL( const TDesC& aFileName )
    {

    TPtr ptr(NULL,0,0);
    HBufC* sql = NULL;
    sql= HBufC16::NewLC(KSqlDeleteStart().Length()+aFileName.Length()+KSqlDeleteEnd().Length());
    *sql = KNullDesC;
    ptr.Set(sql->Des());
    ptr.Append(KSqlDeleteStart);
    ptr.Append(aFileName);
    ptr.Append(KSqlDeleteEnd);
    TInt err =iDb.Execute(ptr);
    CleanupStack::PopAndDestroy(sql); // sql
    }

// -----------------------------------------------------------------------------
// CDcfRep::RefreshDcf
// let server scan file system for Dcfs
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
EXPORT_C void CDcfRep::RefreshDcf( TRequestStatus& aStatus )
    {
    iClient.ScanDcf(aStatus);
    }

// -----------------------------------------------------------------------------
// CDcfRep::RefreshDcf
// let server scan file system for Dcfs
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
EXPORT_C void CDcfRep::RefreshDcf( RPointerArray<HBufC8>& aList , TRequestStatus& aStatus )
    {
    iClient.ScanDcf( aList , aStatus );
    }

// -----------------------------------------------------------------------------
// CDcfRep::SetTtid
// Set transaction ID to all Dcfs associated with a specific CID
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
EXPORT_C void CDcfRep::SetTtid(
            RArray<TPair>& aList ,
            TRequestStatus& aStatus,
            TBool aRefresh)
    {
    if (aRefresh)
        {
        iClient.SetTtid( aList , aStatus );
        }
    }


// -----------------------------------------------------------------------------
// CDcfRep::NotifyServerIdle
// notify if server is in idle.
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
EXPORT_C void CDcfRep::NotifyServerIdle( TRequestStatus& aStatus )
    {
    iClient.NotifyServerIdle( aStatus );
    }


// -----------------------------------------------------------------------------
// CDcfRep::OpenDatabaseL
// connect database server and open session for it
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CDcfRep::OpenDatabaseL()
    {
    User::LeaveIfError(iDbs.Connect());

#ifndef RD_MULTIPLE_DRIVE

    User::LeaveIfError(iDb.Open(iDbs,KDbFileLocation()));

#else //RD_MULTIPLE_DRIVE

    RFs fs;
    TInt driveNumber( -1 );
    TChar driveLetter;
    DriveInfo::GetDefaultDrive( DriveInfo::EDefaultSystem, driveNumber );

    User::LeaveIfError( fs.Connect() );
    fs.DriveToChar( driveNumber, driveLetter );
    fs.Close();

    TFileName dbFile;
    dbFile.Format( KDbFileLoc, (TUint)driveLetter );

    User::LeaveIfError( iDb.Open( iDbs, dbFile ) );

#endif
    }

// -----------------------------------------------------------------------------
// CDcfRep::SetName
// set name of CID into rights DB
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
TInt CDcfRep::SetName(const TDesC8& aCid , const TDesC16& aName)
    {
    RDRMRightsClient r;
    TInt err = 0;
    err = r.Connect();
    if (!err)
        {
        HBufC* buf = NULL;
        err = r.GetName(aCid,buf);
        if ( !err && buf->Des().Length()==0 )
            {
            err = r.SetName(aCid,aName);
            }
        if (err == KErrNotFound)
            {
            err = KErrNone; // if there is no cid, then just ignore adding name to it.
            }
        delete buf;
        }
    r.Close();
    return err;
    }

// -----------------------------------------------------------------------------
// CDcfRep::GetCidL
// get cid list for a filename from repository DB
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CDcfRep::GetCidL(const TDesC16& aName , RPointerArray<HBufC8>& aList)
    {
    TBool flag = EFalse;
    HBufC8* temp8 = NULL;
    HBufC* temp16 = NULL;
    RDbView view;
    TInt len = 0;
    CleanupClosePushL(view);
    HBufC* buf = HBufC::NewLC(aName.Length()+KDcfRepExtra);
    TPtr ptr(buf->Des());
    ptr.SetLength(0);
    ptr.Append(KSqlGetCidStart);
    ptr.Append(aName);
    ptr.Append(KSqlGetCidEnd);
    User::LeaveIfError(view.Prepare(iDb,TDbQuery(ptr,EDbCompareNormal),TDbWindow::EUnlimited));
    User::LeaveIfError(view.EvaluateAll());
    CleanupStack::PopAndDestroy(buf); //buf
    flag = view.FirstL();
    if (!flag)
        {
        User::Leave(KErrNotFound);
        }
    else
        {
        while (view.AtRow())
            {
            view.GetL();
            len = view.ColLength(1);
            temp16 = HBufC::NewLC(len);
            ptr.Set(temp16->Des());

            RDbColReadStream strm;
            strm.OpenLC(view,1);
            strm.ReadL(ptr,len);
            CleanupStack::PopAndDestroy(&strm);

            User::LeaveIfError(From16To8(*temp16,temp8));
            CleanupStack::PopAndDestroy(temp16); // temp16
            CleanupStack::PushL(temp8);
            User::LeaveIfError(aList.Append(temp8));
            CleanupStack::Pop(temp8); // temp8
            view.NextL();
            }
        }
    CleanupStack::PopAndDestroy(&view);
    }

// -----------------------------------------------------------------------------
// CDcfRep::GetFilenameL
// get filename list for a cid from repository DB
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CDcfRep::GetFilenameL(const TDesC8& aCid , RPointerArray<HBufC>& aList)
    {
    TBool flag = EFalse;
    HBufC* temp = NULL;
    RDbView view;
    TInt len = 0;
    CleanupClosePushL(view);
    HBufC* buf = HBufC::NewLC(aCid.Length()+KDcfRepExtra);
    TPtr ptr(buf->Des());
    ptr.SetLength(0);
    User::LeaveIfError(From8To16(aCid,temp));
    CleanupStack::PushL(temp);
    ptr.Append(KSqlGetFileStart);
    ptr.Append(*temp);
    ptr.Append(KSqlGetFileEnd);
    CleanupStack::PopAndDestroy(temp); //temp
    User::LeaveIfError(view.Prepare(iDb,TDbQuery(ptr,EDbCompareNormal),TDbWindow::EUnlimited));
    User::LeaveIfError(view.EvaluateAll());
    CleanupStack::PopAndDestroy(buf); //buf
    flag = view.FirstL();
    if (!flag)
        {
        User::Leave(KErrNotFound);
        }
    else
        {
        while (view.AtRow())
            {
            RDbColReadStream strm;
            view.GetL();
            len = view.ColLength(1);
            temp = HBufC::NewLC(len);
            ptr.Set(temp->Des());
            strm.OpenLC(view,1);
            strm.ReadL(ptr,len);
            CleanupStack::PopAndDestroy(&strm);
            User::LeaveIfError(aList.Append(temp));
            CleanupStack::Pop(temp); // temp
            view.NextL();
            }
        }
    CleanupStack::PopAndDestroy(&view);
    }

// ========================== OTHER EXPORTED FUNCTIONS =========================

//  End of File