diff -r e8e63152f320 -r 2a9601315dfc javaextensions/satsa/apdu/src.s60/cstsasn1sequence.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/javaextensions/satsa/apdu/src.s60/cstsasn1sequence.cpp Mon May 03 12:27:20 2010 +0300 @@ -0,0 +1,212 @@ +/* +* Copyright (c) 2008 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: + * +*/ + + +// INCLUDE FILES +#include "cstsasn1sequence.h" + +namespace java +{ +namespace satsa +{ + +// CONSTANTS +const TInt KSTSDefaultGranularity = 5; +const TUint8 KSTSPaddingByte = 0xFF; +const TUint8 KSTSRemovedRecordTag = 0x00; +const TInt KSTSRecordHeaderLength = 2; + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CSTSASN1Sequence::CSTSASN1Sequence +// C++ default constructor can NOT contain any code, that +// might leave. +// ----------------------------------------------------------------------------- +// +CSTSASN1Sequence::CSTSASN1Sequence() +{ +} + +// ----------------------------------------------------------------------------- +// CSTSASN1Sequence::DecodeSequenceLC +// Decodes raw-data to ASN.1 modules, pushes items to cleanupstack +// ----------------------------------------------------------------------------- + +CArrayPtr* CSTSASN1Sequence::DecodeSequenceLC(TBool aCheckTag, + const TDesC8& aRawData) +{ + CArrayPtr* items = NULL; + + // Check we've got a sequence + TASN1DecGeneric decGen(aRawData); + decGen.InitL(); + TTagType tag = decGen.Tag(); + // Accept only sequences or set if tag must be checked + if ((tag != EASN1Sequence) && (tag != EASN1Set) && (aCheckTag)) + { + User::Leave(KErrArgument); + } + else + { + // Decode sequences to array + items = DecodeItemsLC(decGen); + } + return items; +} + +// ----------------------------------------------------------------------------- +// CSTSASN1Sequence::DecodeSequenceLC +// Decodes raw-data to ASN.1 modules, pushes items to cleanupstack +// Validates that there is right number of modules, leaves with KErrArgument if +// not. +// ----------------------------------------------------------------------------- + +CArrayPtr* CSTSASN1Sequence::DecodeSequenceLC(TBool aCheckTag, + const TDesC8& aRawData, TInt aMinTerms, TInt aMaxTerms) +{ + CArrayPtr* items = DecodeSequenceLC(aCheckTag, aRawData); + TInt count = items->Count(); + if ((count < aMinTerms) || (count > aMaxTerms)) + { + // not in the range, leave + User::Leave(KErrArgument); + } + + return items; +} + +// ----------------------------------------------------------------------------- +// CSTSASN1Sequence::DecodeSequenceLC +// Decodes raw-data to ASN.1 modules, pushes items to cleanupstack +// Validates that there is right number of modules, leaves with KErrArgument if +// not. +// ----------------------------------------------------------------------------- + +CArrayPtr* CSTSASN1Sequence::DecodeSequenceLC(TBool aCheckTag, + const TDesC8& aRawData, TInt aMinTerms) +{ + CArrayPtr* items = DecodeSequenceLC(aCheckTag, aRawData); + TInt count = items->Count(); + if (count < aMinTerms) + { + // not in the range, leave + User::Leave(KErrArgument); + } + + return items; +} + +// ----------------------------------------------------------------------------- +// CSTSASN1Sequence::DecodeItemsLC +// Decodes raw-data to ASN.1 modules, pushes items to cleanupstack +// Checks removed records and padding bytes and ignores them. +// ----------------------------------------------------------------------------- +CArrayPtrFlat* CSTSASN1Sequence::DecodeItemsLC( + const TASN1DecGeneric& aRawData) +{ + CArrayPtrFlat* items = new(ELeave) CArrayPtrFlat< + TASN1DecGeneric> (KSTSDefaultGranularity); + TCleanupItem cleanupSeq(CleanupSequence, items); + CleanupStack::PushL(cleanupSeq); + + TPtrC8 source(aRawData.GetContentDER()); + TInt sourceLength = source.Length(); + + TInt pos = 0; + while (pos < sourceLength) + { + TPtrC8 restOfData(source.Right(sourceLength - pos)); + TUint8 tag = restOfData[0];//first byte is tag + + TInt restOfDataLength = restOfData.Length(); + //check does contains removed record or padding bytes + if (tag == KSTSRemovedRecordTag) + { + //we can jump over this record + if (restOfDataLength >= KSTSRecordHeaderLength) + { + //2. byte is record length + TInt recordDataLength = restOfData[1]; + //update position after this record + pos += recordDataLength + KSTSRecordHeaderLength; + } + else + { + //there is only one byte left so in this Removed Tag case + //we can ignore this and continue without leaving + pos++; + } + } + else if (tag == KSTSPaddingByte) + { + //we can jump over padding bytes + TInt amountOfPaddingBytes = 1; //one padding byte is already found + TBool paddingByte = ETrue; + + //we start from second byte, because first is already read + for (TInt i = 1; (i < restOfDataLength) && (paddingByte); i++) + { + //take next value + TUint8 nextByte = restOfData[i]; + //if padding byte, increase amount of padding bytes + if (nextByte == KSTSPaddingByte) + { + amountOfPaddingBytes++; + } + else //end loop + { + paddingByte = EFalse; + } + } + //update position after padding bytes + pos += amountOfPaddingBytes; + } + else //we can append record to array + { + //take next record + TASN1DecGeneric* decGenRecord = + new(ELeave) TASN1DecGeneric(restOfData); + CleanupStack::PushL(decGenRecord); + decGenRecord->InitL(); + //append record to array + items->AppendL(decGenRecord); + //update position after record + pos += decGenRecord->LengthDER(); + CleanupStack::Pop(decGenRecord); + } + } + + return items; + +} + +// ----------------------------------------------------------------------------- +// CSTSASN1Sequence::CleanupSequence +// +// ----------------------------------------------------------------------------- +void CSTSASN1Sequence::CleanupSequence(TAny* aArray) +{ + CArrayPtrFlat< TASN1DecGeneric>* array = + REINTERPRET_CAST(CArrayPtrFlat< TASN1DecGeneric>*, aArray); + array->ResetAndDestroy(); + delete array; +} + +} // namespace satsa +} // namespace java +// End of File