pkiutilities/PKCS12/CrBer/Src/crdata.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Fri, 19 Feb 2010 23:42:03 +0200
branchRCL_3
changeset 5 3b17fc5c9564
parent 0 164170e6151a
permissions -rw-r--r--
Revision: 201003 Kit: 201007

/*
* Copyright (c) 2000, 2004, 2010 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:   This module contains the implementation of CCrTemplate class. 
*
*/



//  INCLUDE FILES
#include "crdata.h"



// -----------------------------------------------------------------------------
// CCrData
// Constructors
// These functions construct CCrData object.
// -----------------------------------------------------------------------------
CCrData::CCrData()  : iIsFile(ETrue), iPointer(0), iBuffer(NULL)
    { 
    }

CCrData::CCrData(TBool aIsFile) : iIsFile(aIsFile), iPointer(0), iBuffer(NULL), iPath(NULL)
    {
    }

// -----------------------------------------------------------------------------
// CCrData
// Destructor
// This function destructs CCrData object.
// -----------------------------------------------------------------------------
CCrData::~CCrData()
    {
    if (iBuffer != NULL)
        {
        delete iBuffer;
        }
    if (iPath != NULL)
        {
        delete iPath;
        }
    }

// -----------------------------------------------------------------------------
// CCrData::ConstructL
// This function initializes CCrData object's member objects.
// -----------------------------------------------------------------------------
TAny CCrData::ConstructL()
    {
    if (iIsFile == EFalse)
        {
        iBuffer = HBufC8::NewL(0);
        iPath = HBufC::NewL(0);
        }
    }

// -----------------------------------------------------------------------------
// CCrData::NewLC
// -----------------------------------------------------------------------------
EXPORT_C CCrData* CCrData::NewLC(TBool aIsFile) // default value ETrue
    {
    CCrData* self = new CCrData(aIsFile);
    CleanupStack::PushL(self);

    self->ConstructL();

    return self; 
    }

// -----------------------------------------------------------------------------
// CCrData::NewL
// -----------------------------------------------------------------------------
EXPORT_C CCrData* CCrData::NewL(TBool aIsFile) // default value ETrue
    {
    CCrData* self = NewLC(aIsFile);
    CleanupStack::Pop();

    return self; 
    }

// -----------------------------------------------------------------------------
// CCrData::Open
// Opens an existing file for reading or writing. If the file 
// does not already exist, an error is returned.
// Parameters:    aFs The file server session
//                aName The name of the file. Any path 
//                      components which are not specified here will be 
//                      taken from the session path.
//                aFileMode The mode in which the file is opened. 
//                          For more information see EFileShareExclusive and 
//                          other file sharing and access modes.
// Return Values:  TInt KErrNone if successful, otherwise
//                 another of the system-wide error codes.
// -----------------------------------------------------------------------------
EXPORT_C TInt CCrData::Open(RFs& aFs,const TDesC& aName,TUint aFileMode)
    {
    if (iIsFile) // file
        {
        TInt result = iFile.Open(aFs, aName, aFileMode);
        SetPathL(aName);
        return result;
        }
    else // Buffer
        {
        return KErrNotSupported; 
        }
    
    }

EXPORT_C TInt CCrData::Open(RFs& aFs,TUint aFileMode)
    {
    TInt result = KErrNone;
    if (iIsFile) // file
        {
        if (iPath != NULL)
            {
            result = iFile.Open(aFs, *iPath, aFileMode);
            }
        else
            {
            result = KErrPathNotFound;
            }
        }
    else // Buffer
        {
        result = KErrNotSupported; 
        }
    return result;
    }


// -----------------------------------------------------------------------------
// CCrData::Replace
// Replaces a file. If there is an existing file with the same
// name, this function will overwrite it. If the file does not 
// already exist, this function creates it.
// Parameters:    aFs The file server session
//                aName The name of the file. 
//                      Any path components which are not specified 
//                      here will be taken from the session path.
//                 aFileMode The mode in which the file  is opened. 
//                           For more information see EFileShareExclusive and 
//                           other file sharing and access modes. Note that the 
//                           access mode is set to 
//                           EFileWrite whatever the caller specifies.
// Return Values:  KErrNone if successful, otherwise
//                 another of the system-wide error codes.
// -----------------------------------------------------------------------------
EXPORT_C TInt CCrData::Replace(RFs& aFs, const TDesC& aName, TUint aFileMode)
    {
    if (iIsFile) // File
        {
        TInt result = iFile.Replace(aFs, aName, aFileMode);
        return result;
        }
    else // Buffer
        {
        return KErrNotSupported; 
        }  
    }

// -----------------------------------------------------------------------------
// CCrData::Close
// Closes the file. Any open files are closed when the file server 
// session is closed. Close() is guaranteed to return, and provides 
// no indication of whether it completed successfully or not. When 
// closing a file that you have written to, you should ensure that
// data is committed to the file by invoking RFile::Flush() before 
// closing. If Flush() completes successfully, Close() is essentially 
// a no-operation.
// -----------------------------------------------------------------------------
EXPORT_C void CCrData::Close()
    {
    if (iIsFile) // File
        {
        iFile.Close();
        return; 
        }
    else // Buffer
        {
        return; 
        }      
    }

// -----------------------------------------------------------------------------
// CCrData::Read
// Reading transfers data from a file (or a buffer) to a descriptor.
// If CCrData object is created to be a file function only call 
// RFile::Read(.), but if CCrData is buffer, function makes same things
// to buffer as RFile::Read make to file. (See EPOC documentation)
// -----------------------------------------------------------------------------
EXPORT_C TInt CCrData::Read(TDes8& aDes)
    {
    TInt err = KErrNone;

    if (!iIsFile)                            // CCrData is buf 
        {       
        if (aDes.MaxLength() < iBuffer->Length())
            {
            err = KErrOverflow;
            }
        else 
            {
            aDes.Copy(*iBuffer);            // Copy iBuffer to aDes
            iPointer = aDes.Length();       // Set pointer to end of buf
            }           
        }
    else                                    // else it is file
        {  
        err = iFile.Read(aDes); 
        }
    return err;                             // error code
    }


EXPORT_C TInt CCrData::Read(TDes8& aDes,TInt aLength)
    {
    TInt err = KErrNone;
    TInt i;

    if (!iIsFile)                           // CCrData is buffer
        {       
        if ((aLength < NULL) || (aLength > aDes.MaxLength())) 
            {
            err = KErrGeneral;
            }
        else 
            {
            aDes.Zero();
            for (i = iPointer; (i < (aLength + iPointer)) &&
                (i < iBuffer->Length()); i++)
                {
                aDes.Append((*iBuffer)[i]);        // append data to aDes
                }
            iPointer = i;                   // set pointer to next byte
            }
        }
    else                                    // else CCrData is file
        {
        err = iFile.Read(aDes, aLength);
        }

    return err;
    }


EXPORT_C TInt CCrData::Read(TInt aPos,TDes8& aDes,TInt aLength)
    {
    TInt i;
    TInt err = KErrNone;

    if (!iIsFile)                           // CCrDAta is buffer 
        {       
        if (aLength < NULL)                 // aLength must be positive 
            {   
            err = KErrArgument;
            }
        else if (aLength > aDes.MaxLength()) // if buffer is too small 
            {
            err = KErrOverflow;            
            }
        else 
            {
            aDes.Delete(0, aDes.Length());  // delete old string
            TPtr8 ptr = iBuffer->Des();         
        
            for (i = aPos; (i < (aLength + aPos)) &&
                (i < iBuffer->Length()); i++)
                {
                aDes.Append(ptr[i]);
                }
            iPointer  = i;                  // set pointer to end of read       
            }
        }
    else                                    // CCrData is file
        { 
        err = iFile.Read(aPos, aDes, aLength);
        }

    return err;
    }

// -----------------------------------------------------------------------------
// CCrData::Write
// Writing transfers data from a descriptor to a buffer or file.
// If CCrData object is created to be a file function only call 
// RFile::Write(.), but if CCrData is buffer, function makes same things
// to buffer as RFile::Write make to file. After Write(..) iPointer is moved
// to end of the buffer. 
// -----------------------------------------------------------------------------
EXPORT_C TInt CCrData::Write(const TDesC8& aDes)
    { 
    TInt err = KErrNone;
    if (!iIsFile)                           // buf
        {
        err = Write(aDes, aDes.Length()); 
        }

     else                                    // file
        {
        err = iFile.Write(aDes);
        }

    return err;
    }

EXPORT_C TInt CCrData::Write(const TDesC8& aDes, TInt aLength)
    { 
    TInt err = KErrNone;
    if (aLength < NULL)                     // aLen must be positive 
        {                                   
        err = KErrArgument;           
        }
     
    if (!iIsFile)                           // buf
        { 
        TInt bufferLength = iBuffer->Length();
        TInt neededBufferLength = iPointer + aLength;
        if (neededBufferLength > bufferLength) // Reallocation is needed
            {
            TRAP(err, iBuffer = iBuffer->ReAllocL(neededBufferLength)); 
            if (err != KErrNone)
                    {
                    return KErrNoMemory;
                    }
            }
            
        TPtr8 ptr = iBuffer->Des();             
        // append new data, ONLY the amount of aLength
        if (aLength == aDes.Length())
            {
            ptr.Append(aDes); 
            }
        else // aLength < a.Des.Length()
            {
            ptr.Append(aDes.Left(aLength));
            }
        // iPointer is moved to the end of the buffer.        
        iPointer = iBuffer->Length();
        }
    else                                    // file
        {
        err = iFile.Write(aDes);
        }

    return err;
    }

// -----------------------------------------------------------------------------
// CCrData::Zero
// -----------------------------------------------------------------------------
EXPORT_C TInt CCrData::Zero(const TInt aPos, const TInt aLength)
    {
	TPtr8 ptr = iBuffer->Des();
	if (ptr.Length() < aPos + aLength)
	    {
		// Out of bounds
		return KErrArgument;
	    }
	for (TInt i = 0; i < aLength; i++)
	    {
		ptr[aPos+i] = 0;
	    }
	return KErrNone;
    }

// -----------------------------------------------------------------------------
// CCrData::Seek
// If CCrData object is created to be a file function only call 
// RFile::Seek(.), but if CCrData is buffer, function makes same things
// to buffer as RFile::Seek make to file. (See EPOC documentation)
// -----------------------------------------------------------------------------
EXPORT_C TInt CCrData::Seek(TSeek aMode,TInt& aPos)
    {
    TInt err = KErrNone;

    if (aPos < NULL)                        // aPos must be positive
        {
        err = KErrArgument;
        }

    else if (!iIsFile)                      // CCrData is buffer
        {
        switch (aMode)
            {
            case (ESeekCurrent):            // this place
                {
                iPointer += aPos;              
                break;
                }
            case (ESeekStart):              // from start of buf
                {                
                iPointer = aPos;   
                break;
                }
            case (ESeekEnd):                // from end of buf 
                {
                iPointer = iBuffer->Length() - aPos;
                break;
                }
            default:
                {
                break;                      // ESeekAddress
                }
            }
    
            if (iPointer < NULL)            // iPointer must be positive
                {
                iPointer = NULL;            // set pointer to start of buf
                }

            else if (iPointer > iBuffer->Length())
                {
                iPointer = iBuffer->Length();   // set pointer to end of buf
                }
          
            aPos = iPointer;
            
        }

    else                                    // CCrData is file
        {       
        err = iFile.Seek(aMode, aPos);
        }
    
    return err;
    }

// -----------------------------------------------------------------------------
// CCrData::Size
// Reading the size of data.
// If CCrData is a buffer, returns length of the buffer. Otherwise 
// calls RFile::Size( TInt ).
// -----------------------------------------------------------------------------
EXPORT_C TInt CCrData::Size(TInt& aSize)
    {
    TInt err = KErrNone;

    if (!iIsFile)                            // CCrData is buf 
        {       
        aSize = iBuffer->Length();
        }
    else                                    // else it is file
        {  
        err = iFile.Size(aSize); 
        }
    return err;                             // error code
    }


// -----------------------------------------------------------------------------
// CCrData::LineL
// LineL sets data from the current place, where iPointer is, till next new
// line character to aLine. 
// iPointer moves to the following item from the found new line character.
// If no new line character is found, aLine is the rest of the data and 
// iPointer is moved to the end of the iBuffer or the iFile.
// Return Values:  KErrNone if everything succeeds
//                 KErrNoMemory if aLine is not length enough
//                 KErrEof if iPointer is at the end of file.
// -----------------------------------------------------------------------------
EXPORT_C TInt CCrData::LineL(TDes8& aLine)
    {
    TBufC8<2> newLine(KNewLine);  // New line

    // Area to find the new line
    TInt size = 0;
    Size(size);
    TInt currentPlace = iPointer;
    TInt neededLengthToFind = size - currentPlace;

    if(neededLengthToFind == 0) // If the area is empty
        {
        return KErrEof;
        }
    TInt newLinePlace = 0;

    if (!iIsFile) // CCrData is a buffer.
        {
        TPtrC8 temp = iBuffer->Mid(currentPlace, neededLengthToFind);

        // Find next new line.
        newLinePlace = temp.Find(newLine);
        // If not found, return the whole area.
        if (newLinePlace == KErrNotFound)
            {
            newLinePlace = neededLengthToFind;
            }
        else
            {
            newLinePlace = newLinePlace + newLine.Length();
            }

        
        if (aLine.MaxLength() < newLinePlace)
            {
            return KErrNoMemory;
            }

        // Put the line to aLine
        aLine = temp.Left(newLinePlace);
        }

    else // CCrData is a file.
        {

        HBufC8* tempBuf = HBufC8::NewL(neededLengthToFind);
        TDes8 tempDes = tempBuf->Des();

        // Read data to a buffer from iPointer to end of file
        TInt readErr = Read(currentPlace, tempDes, neededLengthToFind);
        if (readErr)
            {
            delete tempBuf;
            tempBuf = NULL;
            return readErr;
            }

        // Find the next new line character
        newLinePlace = tempDes.Find(newLine);
        // If not found, return the whole area.
        if (newLinePlace == KErrNotFound)
            {
            newLinePlace = neededLengthToFind;
            }
        else
            {
            newLinePlace = newLinePlace + newLine.Length();
            }

        // Is there enough memory
        if (aLine.MaxLength() < newLinePlace)
            {
            delete tempBuf;
            tempBuf = NULL;
            return KErrNoMemory;
            }

        // Put data to aLine
        aLine = tempBuf->Left(newLinePlace);
        
        delete tempBuf;
        tempBuf = NULL;
        }

    // Move iPointer to next place from newLine.
    iPointer = currentPlace + newLinePlace;

    return KErrNone;
            
    }

// -----------------------------------------------------------------------------
// CCrData::Path
// -----------------------------------------------------------------------------
EXPORT_C HBufC* CCrData::Path()
    {
    return iPath;
    }

// -----------------------------------------------------------------------------
// CCrData::SetPathL
// -----------------------------------------------------------------------------
EXPORT_C TAny CCrData::SetPathL(const TDesC& aPath )
    {
    delete iPath;
    iPath = NULL;
    iPath = HBufC::NewL( aPath.Length() );
    TPtr pointer = iPath->Des();
    pointer.Copy( aPath );
    }

// -----------------------------------------------------------------------------
// CCrData::IsFile
// -----------------------------------------------------------------------------
EXPORT_C TBool CCrData::IsFile()
    {
    return iIsFile;
    }

// -----------------------------------------------------------------------------
// CCrData::Delete
// -----------------------------------------------------------------------------
EXPORT_C TInt CCrData::Delete( TInt aPos, TInt aLength )
    {
    if (!iIsFile)                            // CCrData is buf 
        {       
        if(aPos >= 0)
            {
            TPtr8 pointer = iBuffer->Des();
            pointer.Delete(aPos, aLength);
            }
        else
            {
            return KErrArgument;
            }
        }
    else                                    // else it is file
        {  
        return KErrNotSupported;
        }
    return KErrNone;
    }

// -----------------------------------------------------------------------------
// CCrDataSet
// -----------------------------------------------------------------------------


// -----------------------------------------------------------------------------
// CCrDataSet
// Constructor.
// This function constructs CCrDataSet object.
// -----------------------------------------------------------------------------
CCrDataSet::CCrDataSet(TInt aGranularity)
    : CArrayPtrSeg<CCrData>(aGranularity)
    {
    }

// -----------------------------------------------------------------------------
// CCrDataSet
// Destructor.
// This function destructs CCrDataSet object.
// -----------------------------------------------------------------------------
CCrDataSet::~CCrDataSet()
    {
    ResetAndDestroy();
    }

// -----------------------------------------------------------------------------
// CCrDataSet::ConstructL
// This function initializes CCrDataSet object's member objects.
// -----------------------------------------------------------------------------
TAny CCrDataSet::ConstructL()
    {
    }

// -----------------------------------------------------------------------------
// CCrDataSet::NewLC
// -----------------------------------------------------------------------------
EXPORT_C CCrDataSet* CCrDataSet::NewLC(TInt aGranularity)
    {
    CCrDataSet* self = new CCrDataSet(aGranularity);
    CleanupStack::PushL(self);

    self->ConstructL();

    return self; 
    }

// -----------------------------------------------------------------------------
// CCrDataSet::NewL
// -----------------------------------------------------------------------------
EXPORT_C CCrDataSet* CCrDataSet::NewL(TInt aGranularity)
    {
    CCrDataSet* self = NewLC(aGranularity);
    CleanupStack::Pop();

    return self; 
    }

// End of file