elementlist.cpp

来自「series60 应用程序开发的源代码 series60 应用程序开发的源代码」· C++ 代码 · 共 188 行

CPP
188
字号
/**
*
* @brief Abstract base class to represent a list of CChemicalElements
*
* Copyright (c) EMCC Software Ltd 2003
* @version 1.0
*/

// INCLUDE FILES

// Class include
#include "elementlist.h"

// User includes
#include "chemicalelement.h"

// ================= MEMBER FUNCTIONS =======================

TInt CElementList::ExtractUntilNextDelimiter(const TDesC& aString, TPtrC& aNextToken, 
    TPtrC& aRemainingTokens) const
//This function assumes that aString and aRemainingTokens may refer to the same descriptor!
{
    TInt delimiterPosition = aString.Find(KElementListDelimiter);
    if (delimiterPosition == KErrNotFound)
    {
        aNextToken.Set(aString);    //if there's no delimiter, the whole of the string must be the only token...
        aRemainingTokens.Set(KNullDesC);    //...and there's nothing remaining!
        return KErrNotFound;
    }
    //Set aNextToken to refer to the next token upto (but not including) the next delimiter
    aNextToken.Set(aString.Left(delimiterPosition));
    //Set aRemainingTokens to be the rest of the string
    aRemainingTokens.Set(aString.Right(aString.Length() - (delimiterPosition + 1)));
    return KErrNone;
}

void CElementList::AppendL(const TDesC& aElementCommaDelimitedString)
{
    TPtrC remainder;
    
    //Extract the name
    TPtrC name;
    TInt err = ExtractUntilNextDelimiter(aElementCommaDelimitedString, name, remainder);
    if (err)
    {
        User::Leave(KErrGeneral);
    }

    //Extract the symbol
    TPtrC symbol;
    err = ExtractUntilNextDelimiter(remainder, symbol, remainder);
    if (err)
    {
        User::Leave(KErrGeneral);
    }

    //Extract the atomic number
    TPtrC atomicNumber;
    err = ExtractUntilNextDelimiter(remainder, atomicNumber, remainder);
    if (err)
    {
        User::Leave(KErrGeneral);
    }

    //Extract the relative atomic mass
    TPtrC relativeAtomicMass;
    err = ExtractUntilNextDelimiter(remainder, relativeAtomicMass, remainder);
    if (err)
    {
        User::Leave(KErrGeneral);
    }

    //Extract the type (m, n, s for metallic, non-metallic or semi-metallic)
    TPtrC type;
    err = ExtractUntilNextDelimiter(remainder, type, remainder);
    if (err)
    {
        User::Leave(KErrGeneral);
    }

    //Extract the radioactivity
    //First, check there's something left in the remainder descriptor
    if (remainder.Length() == 0)
    {
        User::Leave(KErrGeneral);
    }
    TPtrC radioactive;
    err = ExtractUntilNextDelimiter(remainder, radioactive, remainder);
    //The function should return KErrNotFound since there should be no further delimiters
    if (err != KErrNotFound)
    {
        User::Leave(KErrGeneral);
    }
    

    //Construct and append the new element from the extracted string 
    AppendL(name, symbol, atomicNumber, relativeAtomicMass, type, radioactive);
}

void CElementList::AppendL(const TDesC& aName, const TDesC& aSymbol, const TDesC& aAtomicNumber,
        const TDesC& aRelativeAtomicMass, const TDesC& aType, const TDesC& aRadioactive)
{
    //Construct a TLex for the atomic number
    TLex lexAtomicNumber(aAtomicNumber);
    TInt atomicNumber;
    //Extract the atomic number into atomicNumber
    User::LeaveIfError(lexAtomicNumber.Val(atomicNumber));

    //Construct a TLex for the relative atomic mass
    TLex lexRelativeAtomicMassNumber(aRelativeAtomicMass);
    TReal relativeAtomicMass;
    //Extract the relative atomic mass into relativeAtomicMass
    User::LeaveIfError(lexRelativeAtomicMassNumber.Val(relativeAtomicMass));

    //Determine the element type
    CChemicalElement::TElementType type;
    switch (aType[0])
    {
    case 'n':
    case 'N':
        type = CChemicalElement::ENonmetallic;
        break;
    case 's':
    case 'S':
        type = CChemicalElement::ESemimetallic;
        break;
    default:
        type = CChemicalElement::EMetallic;    //the commonest case
    }

    //Determine the radioactivity state (r or R for radioactive, anything else for !radioactive)
    TBool radioactive = ((aRadioactive[0] == 'r') || (aRadioactive[0] == 'R'));

    //Construct a new element from the mixed data
    CChemicalElement* newElement = CChemicalElement::NewLC(aName, aSymbol, atomicNumber, relativeAtomicMass, 
        type, radioactive);
    //Append new element to the element array
    AppendL(newElement);

    //Remove the element pointer from the cleanup stack, since ownership has successfully passed to the array
    CleanupStack::Pop(newElement);    //Now owned by array
}


void CElementList::ExternalizeL(RWriteStream& aStream) const
{
    TInt32 elementCount = NumberOfElements();
    aStream << elementCount;

    for (TInt32 i = 0; i < elementCount; i++)
    {
        aStream << At(i);
    }
}

void CElementList::InternalizeL(RReadStream& aStream)
{
    TInt32 elementCount;
    aStream >> elementCount;

    for (TInt32 i = 0; i < elementCount; i++)
    {
        CChemicalElement* newElement = CChemicalElement::NewLC(aStream);
        AppendL(newElement);
        CleanupStack::Pop(newElement);        //now owned by array
    }
}

TStreamId CElementList::StoreL(CStreamStore& aStore) const
{
    RStoreWriteStream outStream;
    TStreamId id = outStream.CreateLC(aStore);    //Creates the write stream
    ExternalizeL(outStream);                    //Externalises the list of elements
    outStream.CommitL();                        //Commits the stream
    CleanupStack::PopAndDestroy();                //outStream
    return id;                                    //Returns the stream ID 
}

void CElementList::RestoreL(CStreamStore& aStore,TStreamId aStreamId)
{
    RStoreReadStream inStream;
    inStream.OpenLC(aStore, aStreamId);                //Creates the read stream
    InternalizeL(inStream);                        //Internalises the list of elements
    CleanupStack::PopAndDestroy();                //inStream
}

// End of File

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?