--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/pkiutilities/PKCS12/CrBer/Src/crber.cpp Tue Jan 26 15:20:08 2010 +0200
@@ -0,0 +1,1735 @@
+/*
+* Copyright (c) 2000, 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: This module contains the implementation of CCrBer class.
+*
+*/
+
+
+
+// INCLUDE FILES
+#include "crber.h"
+#include <e32math.h> // Pow
+
+
+// -----------------------------------------------------------------------------
+// CCrBer
+// Constructor
+// This function constructs CCrBer object
+// -----------------------------------------------------------------------------
+CCrBer::CCrBer(TInt aLevel /* = 0 */)
+ {
+ TReal size = 0;
+
+ Math::Pow(size, 256, sizeof(TUint));
+ iMaxUint = STATIC_CAST(TUint, size - 1);
+
+ Math::Pow(size, 128, sizeof(TInt));
+ iMaxInt = STATIC_CAST(TInt, size - 1);
+
+
+ iEOCBytes[0] = 0x00;
+ iEOCBytes[1] = 0x00;
+
+ iType = KBerUnknown;
+
+ iIndefinite = EFalse;
+
+ iObjectBegin = 0;
+ iContentBegin = 0;
+ iContentLen = 0;
+ iObjectLen = 0;
+
+ iLevel = aLevel;
+
+ iData = NULL;
+ }
+
+// -----------------------------------------------------------------------------
+// CCrBer
+// Destructor
+// This function destructs CCrBer object
+// -----------------------------------------------------------------------------
+EXPORT_C CCrBer::~CCrBer()
+ {
+ iData = NULL;
+ iInt.Close();
+ }
+
+// -----------------------------------------------------------------------------
+// CCrBer::ConstructL
+// This function initializes CCrBer object's member objects.
+// -----------------------------------------------------------------------------
+TAny CCrBer::ConstructL()
+ {
+ }
+// -----------------------------------------------------------------------------
+// CCrBer::NewLC
+// -----------------------------------------------------------------------------
+EXPORT_C CCrBer* CCrBer::NewLC(TInt aLevel /* = 0 */)
+ {
+ CCrBer* self = new (ELeave) CCrBer(aLevel);
+ CleanupStack::PushL(self);
+
+ self->ConstructL();
+
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CCrBer::NewL
+// -----------------------------------------------------------------------------
+EXPORT_C CCrBer* CCrBer::NewL(TInt aLevel /* = 0 */)
+ {
+ CCrBer* self = NewLC(aLevel);
+ CleanupStack::Pop();
+
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CCrBer::Read
+// Read next BER encoded object from the current position of
+// given CCrData to this object. Return the type of the BER
+// object, or KBerUnknown, if not of any known type. Only pointer
+// to aData is stored into this object, so Get* functions are
+// meaningful only if original data object is still existing,
+// when these functions are used.
+// -----------------------------------------------------------------------------
+EXPORT_C TUint8 CCrBer::Read(CCrData* aData)
+ {
+ if ((iType = ReadType(aData)) != KBerUnknown)
+ {
+ TInt move;
+ TInt pos = 0;
+ TBool conLenKnown;
+
+
+ // If type is known, this object begins right here,
+ // well, to be exact, one byte before this point.
+ if ((aData->Seek(ESeekCurrent, pos)) == KErrNone)
+ {
+ conLenKnown = ETrue;
+
+ // Now we have at least something sensible. Store pointer to
+ // the data object (and hope that the caller doesn't delete it :)
+ iData = aData;
+
+ iObjectBegin = pos - 1;
+
+ // Read length.
+ iContentLen = ReadLen(aData, iIndefinite, &iLenLen);
+
+ // Content begins right after type tag and length bytes.
+ iContentBegin = pos + iLenLen;
+
+ // If length is indefinite and type isn't set, sequence,
+ // or explicit/implicit constructed, find next end-of-content
+ // tag to define exact length.
+ if (iIndefinite)
+ {
+ if ((iType != KBerSeq) &&
+ (iType != KBerSet) &&
+ (iType != KBerImplicitConstructed) &&
+ (iType != KBerExplicitConstructed))
+ {
+ // Give special treatment to constructed encoding.
+ if ((iType & KBerConstructedBit) ||
+ (iType & KBerImplicitConstructed))
+ {
+ iContentLen = OpenConstructedEncodingWithTagL(
+ aData, *this);
+
+ }
+ else
+ {
+ iContentLen = FindEndOfContent(aData);
+ }
+ }
+ else
+ {
+ // We really can't know what the length is,
+ // until we open up the whole inner content.
+ conLenKnown = EFalse;
+ }
+ }
+
+ // Now, if we know content length, then we can calculate whole
+ // object's length; it is tag + length bytes + content length.
+ if (conLenKnown)
+ {
+ SetObjectLen();
+
+ // Also move data pointer at the end of this object, except
+ // if object was set or sequence, in which case don't move,
+ // because we still have to open inner items.
+ // At indefinite case this is already done (other than
+ // sequence or set) or this can't be done (sequence or
+ // set). So, if not indefinite and not sequence or set,
+ // move data pointer the amount of content length.
+ if (!(iIndefinite) && !(IsSeqOrSet(iType)))
+ {
+ move = iContentLen;
+
+ aData->Seek(ESeekCurrent, move);
+ }
+ }
+
+ // If tag was end-of-content tag, check that also length
+ // was 0 and not indefinite, this guarantees that we really
+ // have an end-of-content tag (00 00).
+ if (iType == KBerEndOfContent)
+ {
+ if ((iContentLen != 0) || (iIndefinite))
+ {
+ iType = KBerUnknown;
+ }
+ }
+ }
+
+
+
+ }
+ return iType;
+ }
+
+
+
+// -----------------------------------------------------------------------------
+// CCrBer::ReadType
+// Read type tag from current position in given CCrData.
+// Returns type tag or KBerUnknown, if not of any known type.
+// -----------------------------------------------------------------------------
+EXPORT_C TUint8 CCrBer::ReadType(CCrData* aData)
+ {
+ TBuf8<1> byte;
+ TUint8 type = KBerUnknown; // By default we are pessimists.
+
+ // Read type.
+ if ((aData != 0) &&
+ (aData->Read(byte, 1) == KErrNone) &&
+ (byte.Length() > 0))
+ {
+ type = byte[0];
+
+ if (!IsKnownType(type))
+ {
+ // Don't let type to be whatever byte happened to be
+ // at that place. Set it to unknown, which we all know.
+ type = KBerUnknown;
+ }
+ }
+
+ return type;
+ }
+
+// -----------------------------------------------------------------------------
+// CCrBer::ReadLen
+// Read length tags from current position in given CCrData.
+// Returns length. If length is indefinite, aIndefinite is set
+// to true, otherwise to false. In indefinite case length is 0.
+// Also sets amount of length bytes in aLenLen, if given.
+// -----------------------------------------------------------------------------
+EXPORT_C TUint CCrBer::ReadLen(
+ CCrData* aData,
+ TBool& aIndefinite,
+ TUint8* aLenLen/* = 0 */)
+ {
+ TBuf8<LEN_BYTES_MAX> bytes;
+ TUint8 byte = 0;
+ TUint len = 0;
+
+ // Originally assume that length is definite,
+ aIndefinite = EFalse;
+
+ // First byte tells if the length bytes are in short or in long form.
+ if ((aData != 0) && (aData->Read(bytes, 1) == KErrNone))
+ {
+ if (bytes.Length() <= 0)
+ {
+ User::Leave(KErrArgument);
+ }
+ byte = bytes[0];
+
+ // We have at least one length byte.
+ if (aLenLen != 0)
+ {
+ *aLenLen = 1;
+ }
+
+ if (byte & KBerLongLengthBit)
+ {
+ // We have length bytes, but how many?
+ TUint8 lenBytes = (TUint8)(byte & ~KBerLongLengthBit);
+
+ // If length is in long form, but there are zero
+ // length bytes, then length is indefinite.
+ if (lenBytes == 0)
+ {
+ aIndefinite = ETrue;
+ }
+ else
+ {
+ if (aLenLen != 0)
+ {
+ // Add amount of actual length bytes to one,
+ // which was for long length form byte.
+ for (TInt i = 0; i < lenBytes; i++)
+ {
+ (*aLenLen)++;
+ }
+ }
+
+ // Otherwise we have to interpret length bytes and
+ // move the result into len variable. First check
+ // that there aren't more bytes than fits to
+ // unsigned integer, we don't want any troubles here.
+ if (lenBytes > sizeof(TUint))
+ {
+ // Return max uint, caller can then decide
+ // what to do with this huge pile of...
+ return iMaxUint;
+ }
+
+ // Read length bytes
+ if (aData->Read(bytes, lenBytes) == KErrNone)
+ {
+ TUint8 i;
+
+ // and move them to len.
+ for (i = 0; i < lenBytes; i++)
+ {
+ len = len << 8;
+
+ len += bytes[i];
+ }
+ }
+ }
+ }
+ else
+ {
+ // Otherwise length was in short form and length
+ // byte alone tells us the length of the contens.
+ len = byte;
+ }
+ }
+
+ return len;
+ }
+
+
+// -----------------------------------------------------------------------------
+// CCrBer::IsKnownType
+// Returns true if given BER tag is identified one.
+// Returns: ETrue of EFalse.
+// -----------------------------------------------------------------------------
+EXPORT_C TBool CCrBer::IsKnownType(TBerTag aTag)
+ {
+ TBool isKnown = EFalse;
+
+ // Remove constructed bit, if it is on without other upper byte tags.
+ if ((aTag & 0xF0) == KBerConstructedBit)
+ {
+ aTag &= ~KBerConstructedBit;
+ }
+
+ // Remove implicit/explicit constructed bit,
+ // if it is on without other upper byte tags.
+ if ((aTag & 0xF0) == KBerImplicitConstructed)
+ {
+ aTag &= ~KBerImplicitConstructed;
+ }
+
+ switch (aTag)
+ {
+ case KBerEndOfContent:
+ case KBerBoolean:
+ case KBerInteger:
+ case KBerBitString:
+ case KBerOctetString:
+ case KBerNull:
+ case KBerOid:
+ case KBerNumS:
+ case KBerPrS:
+ case KBerT61S:
+ case KBerVideoS:
+ case KBerIA5S:
+ case KBerUtc:
+ case KBerGenTime:
+ case KBerGraphS:
+ case KBerVisibleS:
+ case KBerGeneralS:
+ case KBerBmpS:
+ case KBerSeq:
+ case KBerSet:
+ case KBerImplicitConstructed:
+ // Same as KBerExplicitConstructed
+ case KBerImplicit:
+ // Same as KBerExplicit
+ {
+ isKnown = ETrue;
+ break;
+ }
+ default:
+ {
+ isKnown = EFalse;
+ break;
+ }
+ }
+
+ return isKnown;
+ }
+
+
+
+// -----------------------------------------------------------------------------
+// CCrBer::IsSeqOrSet
+// Returns true if given BER tag is set, sequence,
+// implicit contructed, or explicit constructed tag.
+// -----------------------------------------------------------------------------
+EXPORT_C TBool CCrBer::IsSeqOrSet(TBerTag aTag)
+ {
+ TBool isSeqOrSet = EFalse;
+
+ if ((aTag == KBerSeq) ||
+ (aTag == KBerSet) ||
+ (aTag == KBerImplicit) ||
+ (aTag == KBerExplicit) ||
+ (aTag == KBerImplicitConstructed) ||
+ (aTag == KBerExplicitConstructed))
+
+ {
+ isSeqOrSet = ETrue;
+ }
+
+ return isSeqOrSet;
+ }
+
+// -----------------------------------------------------------------------------
+// CCrBer::FindEndOfContent
+// Finds next end-of-content (00 00) tag from given data.
+// Returns the distance between current place and the tag,
+// or 0, if not found. Moves data pointer to the next byte
+// _after_ the tag, i.e. two bytes longer than you might
+// except from the return value.
+// -----------------------------------------------------------------------------
+EXPORT_C TUint CCrBer::FindEndOfContent(CCrData* aData)
+ {
+ TBool go = ETrue;
+ TInt bufferOffset = 0;
+ TInt dataOffset = 0;
+ TInt move = 0;
+
+ TBuf8<KReadBufMax> bytes;
+
+ if (aData == 0)
+ {
+ return dataOffset;
+ }
+
+ // Read buffer of data. Go on, if there is something to go with.
+ while ((aData->Read(bytes, KReadBufMax) == KErrNone) &&
+ (bytes.Length() != 0) && go)
+ {
+ TBuf8<2> EOCBytes;
+
+ EOCBytes.Append(iEOCBytes[0]);
+ EOCBytes.Append(iEOCBytes[1]);
+
+ // Try to find end-of-content tag.
+ bufferOffset = bytes.Find(EOCBytes);
+
+ // If found, move data pointer right _after_
+ // the place of founded tag, and break.
+ if (bufferOffset != KErrNotFound)
+ {
+ move = bufferOffset -
+ bytes.Length() +
+ EOCBytes.Length();
+
+ aData->Seek(ESeekCurrent, move);
+
+ dataOffset += bufferOffset;
+
+ go = EFalse; //break;
+ }
+ else
+ {
+ // Otherwise keep searching. First check that the last
+ // character of the buffer isn't 00. If it is, move the
+ // data pointer one byte backwards to prevent us from
+ // missing end-of-content tag, if it is divided between
+ // buffers.
+ if (bytes[bytes.Length() - 1] == KBerEndOfContent)
+ {
+ move = -1;
+
+ aData->Seek(ESeekCurrent, move);
+
+ dataOffset--;
+ }
+
+ dataOffset += bytes.Length();
+ }
+ }
+
+ // If nothing was found, move data pointer back
+ // to where it was and return 0.
+ if (bytes.Length() == 0)
+ {
+ dataOffset = -dataOffset;
+
+ aData->Seek(ESeekCurrent, dataOffset);
+
+ dataOffset = 0;
+ }
+
+ return dataOffset;
+ }
+
+// -----------------------------------------------------------------------------
+// CCrBer::OpenConstructedEncodingL
+// Open constructed encoding from this object.
+// Parameters: aTarget; target for contentbytes.
+// Return Values: Number of objects in this contructed object.
+// -----------------------------------------------------------------------------
+EXPORT_C TInt CCrBer::OpenConstructedEncodingL(CCrData& aTarget)
+ {
+ TInt err = KErrNone;
+ TInt count = 0;
+ TInt offset = iContentBegin;
+ TInt objectNum = 0;
+ TInt type = Type();
+ CCrBer* object = NULL;
+
+ if (type <= KBerConstructed) // not valid type
+ {
+ User::Leave(KErrArgument);
+ }
+ else
+ {
+ type -= KBerConstructed; // type what we are looking for
+ }
+
+ CCrBerSet* newSet = CCrBerSet::NewL(1);
+ CleanupStack::PushL(newSet);
+ iData->Seek(ESeekStart, offset); // seek right place; content begin
+ newSet->OpenL(iData, KOpenAllLevels);
+ count = newSet->Count();
+
+ HBufC8* obj = NULL; // buffer for CCrBer-objects
+
+ for (objectNum = 0; (objectNum < count); objectNum++)
+ {
+ object = newSet->At(objectNum); // select object
+
+ if (object->Type() == type)
+ {
+ obj = HBufC8::NewLC(object->ContentLen());
+ TPtr8 pObj = obj->Des();
+
+ err = iData->Read(object->ContentBegin(), pObj, object->ContentLen());
+
+ if (err < KErrNone) // if error -> leave
+ {
+ CleanupStack::PopAndDestroy(2); // delete newSet, obj;
+ User::Leave(err);
+ }
+ err = aTarget.Write(pObj); // write content to CCrData
+
+ CleanupStack::PopAndDestroy(); // delete obj;
+ obj = NULL;
+
+ if (err < KErrNone) // if error -> leave
+ {
+ CleanupStack::PopAndDestroy(); // delete newSet;
+ User::Leave(err);
+ }
+
+ }
+ else
+ {
+ count = objectNum;
+ }
+ }
+ CleanupStack::PopAndDestroy(); // delete newSet;
+
+ return count;
+ }
+
+// -----------------------------------------------------------------------------
+// CCrBer::OpenConstructedEncodingWithTagL
+// Open constructed encoding with given tag from given data.
+// Add all founded octets into the parameter string, if given.
+// Return amount of bytes read.
+// -----------------------------------------------------------------------------
+EXPORT_C TUint CCrBer::OpenConstructedEncodingWithTagL(
+ CCrData* aData,
+ CCrBer& parentObj,
+ HBufC8* aBuf /* = 0 */)
+ {
+ TInt read = 0;
+ CCrBer temp;
+ TBerTag parentTag = KBerUnknown;
+ TBerTag tempTag = KBerUnknown;
+ HBufC8* tempBuf = NULL;
+
+ parentTag = parentObj.Type();
+
+ // Check given object. It should have constructed tag.
+ if (parentTag & KBerConstructedBit)
+ {
+ TUint len = 0;
+ TUint totalLen = iMaxUint;
+ TBool isIndefinite = parentObj.Indefinite();
+
+ TBufC8<4> buf = _L8("Test");
+ TPtr8 ptr = buf.Des();
+
+ if (aBuf != 0)
+ {
+ ptr = aBuf->Des();
+ }
+
+ tempBuf = HBufC8::NewLC(KReadBufMax);
+
+ // After that we know that object either contains length or
+ // it is indefinite. Set max int to len even in the case of
+ // indefinite length to prevent this loop from going on forever.
+ if (!isIndefinite)
+ {
+ totalLen = parentObj.ContentLen();
+ }
+
+ while (len < totalLen)
+ {
+ // Read objects one by one, calculate content lengths together,
+ // add contents to target buffer, if given, and calculate also
+ // total object lengths together to know when stop. In indefinite
+ // case stop when end-of-content tag found.
+ temp.Read(aData);
+
+ tempTag = temp.Type();
+
+ if ((tempTag == KBerEndOfContent) ||
+ (tempTag == KBerUnknown) ||
+ (!(tempTag & parentTag)))
+ {
+ CleanupStack::PopAndDestroy(); // delete tempBuf;
+ return read; // break
+ }
+
+ len += temp.ObjectLen();
+ read += temp.ContentLen();
+
+ if (aBuf != 0)
+ {
+ // Resize buffer, if needed, and append data to it.
+ if (aBuf->Length() < read)
+ {
+ // It is impossible to know how long buffer should be,
+ // but add some extra space, so reallocation won't occur
+ // each time.
+ aBuf->ReAllocL(read + (read / 5));
+ ptr = aBuf->Des();
+ }
+
+ temp.Content(tempBuf);
+ ptr.Append(*tempBuf);
+ }
+ }
+
+ CleanupStack::PopAndDestroy(); // delete tempBuf;
+ }
+
+ return read;
+ }
+
+
+
+// -----------------------------------------------------------------------------
+// CCrBer::Type
+// Get type of the object.
+// -----------------------------------------------------------------------------
+EXPORT_C TBerTag CCrBer::Type()
+ {
+ return iType;
+ }
+
+// -----------------------------------------------------------------------------
+// CCrBer::Value
+// Get value of the object. Used in encoding.
+// -----------------------------------------------------------------------------
+TInt CCrBer::Value()
+ {
+ return iValue;
+ }
+// -----------------------------------------------------------------------------
+// CCrBer::GetBigInt
+// -----------------------------------------------------------------------------
+RInteger CCrBer::GetBigInt()
+ {
+ return iInt;
+ }
+
+// -----------------------------------------------------------------------------
+// CCrBer::SetValue
+// Set value of the object.
+// -----------------------------------------------------------------------------
+TAny CCrBer::SetValue(TInt aInt)
+ {
+ iValue = aInt;
+ }
+
+// -----------------------------------------------------------------------------
+// CCrBer::ValuePtr
+// Get valuePtr of the object. (encoding)
+// -----------------------------------------------------------------------------
+TDesC8* CCrBer::ValuePtr()
+ {
+ return iValuePtr;
+ }
+
+// -----------------------------------------------------------------------------
+// CCrBer::LenLen
+// Get amount of length bytes.
+// -----------------------------------------------------------------------------
+EXPORT_C TInt CCrBer::LenLen()
+ {
+ return iLenLen;
+ }
+
+// -----------------------------------------------------------------------------
+// CCrBer::ObjectBegin
+// Return begin of the whole object.
+// -----------------------------------------------------------------------------
+EXPORT_C TInt CCrBer::ObjectBegin()
+ {
+ return iObjectBegin;
+ }
+
+// -----------------------------------------------------------------------------
+// CCrBer::ContentBegin
+// Return begin of the content.
+// -----------------------------------------------------------------------------
+EXPORT_C TInt CCrBer::ContentBegin()
+ {
+ return iContentBegin;
+ }
+
+// -----------------------------------------------------------------------------
+// CCrBer::ObjectLen
+// Get length of the whole object.
+// -----------------------------------------------------------------------------
+EXPORT_C TInt CCrBer::ObjectLen()
+ {
+ return iObjectLen;
+ }
+
+// -----------------------------------------------------------------------------
+// CCrBer::ContentLen
+// Get length of the content.
+// -----------------------------------------------------------------------------
+EXPORT_C TInt CCrBer::ContentLen()
+ {
+ return iContentLen;
+ }
+
+// -----------------------------------------------------------------------------
+// CCrBer::Indefinite
+// Returns true if this object is indefinite length.
+// -----------------------------------------------------------------------------
+EXPORT_C TBool CCrBer::Indefinite()
+ {
+ return iIndefinite;
+ }
+
+// -----------------------------------------------------------------------------
+// CCrBer::Data
+// Return pointer to data object.
+// -----------------------------------------------------------------------------
+EXPORT_C CCrData* CCrBer::Data()
+ {
+ return iData;
+ }
+
+// -----------------------------------------------------------------------------
+// CCrBer::Object
+// Return whole BER object with tag and stuff. For implementation
+// reasons ObjectL returns only max 255 bytes of data.
+// -----------------------------------------------------------------------------
+
+EXPORT_C TInt CCrBer::Object(HBufC8* aBuf)
+ {
+ return BufferL(aBuf, iData, iObjectBegin, iObjectLen);
+ }
+
+// -----------------------------------------------------------------------------
+// CCrBer::Object
+// Return whole BER object with tag and stuff. For implementation
+// reasons ObjectL returns only max 255 bytes of data.
+// -----------------------------------------------------------------------------
+EXPORT_C TInt CCrBer::ObjectL(HBufC* aBuf)
+ {
+ TUint8 len = 255;
+
+
+ if (iObjectLen < 255)
+ {
+ len = (TUint8)iObjectLen;
+ }
+
+ return BufferL(aBuf, iData, iObjectBegin, len);
+ }
+
+// -----------------------------------------------------------------------------
+// CCrBer::Content
+// Return content of this object. For implementation reasons
+// ContentL returns only max 255 bytes of data.
+// -----------------------------------------------------------------------------
+EXPORT_C TInt CCrBer::Content(HBufC8* aBuf)
+ {
+ return BufferL(aBuf, iData, iContentBegin, iContentLen);
+ }
+
+// -----------------------------------------------------------------------------
+// CCrBer::ContentL
+// -----------------------------------------------------------------------------
+EXPORT_C TInt CCrBer::ContentL(HBufC* aBuf)
+ {
+ TUint8 len = 255;
+
+ if (iContentLen < 255)
+ {
+ len = (TUint8)iContentLen;
+ }
+
+ return BufferL(aBuf, iData, iContentBegin, len);
+ }
+
+// -----------------------------------------------------------------------------
+// CCrBer::BufferL
+// Read aAmount of data starting from begin to the buffer.
+// Return amount of data read. For implementation reasons
+// BufferL can be used only to read max 256 bytes of data.
+// -----------------------------------------------------------------------------
+EXPORT_C TInt CCrBer::BufferL(
+ HBufC8* aBuf,
+ CCrData* aData,
+ TUint aBegin /* = 0 */,
+ TUint aAmount /* = KReadBufMax */)
+ {
+ TInt pos = 0;
+ TInt begin = aBegin;
+ TInt amount = aAmount;
+ TInt read = 0;
+
+ if ((aBuf == 0) || (aData == 0))
+ {
+ // Don't bother to continue.
+ return read;
+ }
+
+ // Store current position,
+ if ((aData->Seek(ESeekCurrent, pos)) != KErrNone)
+ {
+ // Don't bother to continue.
+ return read;
+ }
+
+ // Set data pointer to wanted position.
+ if (aData->Seek(ESeekStart, begin) == KErrNone)
+ {
+ // Resize buffer, if needed, and read data.
+ if (aBuf->Length() < amount)
+ {
+ aBuf->ReAllocL(amount);
+ }
+
+ TPtr8 ptr = aBuf->Des();
+
+ if (aData->Read(ptr, amount) == KErrNone)
+ {
+ read = aBuf->Length();
+ }
+ }
+
+ // Put data pointer back to previous position.
+ aData->Seek(ESeekStart, pos);
+
+ return read;
+ }
+
+EXPORT_C TInt CCrBer::BufferL(
+ HBufC* aBuf,
+ CCrData* aData,
+ TUint aBegin /* = 0 */,
+ TUint8 aAmount /* = 255 */)
+ {
+ TInt index = 0;
+ TInt len = 0;
+ TInt amount = NULL;
+ TBuf<255> buf;
+ HBufC8* heapBuf = NULL;
+
+ heapBuf = HBufC8::NewLC(255);
+
+ amount = BufferL(heapBuf, aData, aBegin, aAmount);
+
+ len = heapBuf->Length();
+
+ for (index = 0; index < len; index++)
+ {
+ buf.Append((*heapBuf)[index]);
+ }
+
+ *aBuf = buf;
+
+ CleanupStack::PopAndDestroy(); // delete heapBuf;
+ // heapBuf = NULL;
+
+ return amount;
+ }
+
+
+// -----------------------------------------------------------------------------
+// CCrBer::Level
+// Return nesting level of this object.
+// -----------------------------------------------------------------------------
+EXPORT_C TUint CCrBer::Level()
+ {
+ return iLevel;
+ }
+
+// -----------------------------------------------------------------------------
+// CCrBer::SetLevel
+// Set nesting level of this object.
+// -----------------------------------------------------------------------------
+EXPORT_C TUint CCrBer::SetLevel(TUint aLevel)
+ {
+ iLevel = aLevel;
+
+ return iLevel;
+ }
+
+// -----------------------------------------------------------------------------
+// CCrBer::AddToContentLen
+// Add given integer to content length of this object.
+// -----------------------------------------------------------------------------
+EXPORT_C TAny CCrBer::AddToContentLen(TInt iLen)
+ {
+ iContentLen += iLen;
+ }
+
+// -----------------------------------------------------------------------------
+// CCrBer::SetObjectLen
+// Calculate object length from tag, length's length, and
+// content's length. Used to 'close' indefinite objects, meaning
+// that their end-of-contents tag is finally found, so their
+// length can be calculated.
+// -----------------------------------------------------------------------------
+EXPORT_C TAny CCrBer::SetObjectLen()
+ {
+ // Objects length is tag len (always 1) + length byte
+ // amount + content length.
+ iObjectLen = 1 + iLenLen + iContentLen;
+
+ // If object was of indefinite length, there are
+ // two additional end-of-contents bytes at the end.
+ if (iIndefinite)
+ {
+ iObjectLen += 2;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CCrBer::SetObjLenWithOutContent
+// Parameters: Content length.
+// -----------------------------------------------------------------------------
+TAny CCrBer::SetObjLenWithOutContent(TUint aContentLen)
+ {
+ iObjectLen = KBerShortLen; // Tag + len
+ if (aContentLen >= KBerLongLengthBit)
+ {
+ while (aContentLen > 0)
+ {
+ aContentLen >>= 8; // Next byte
+ iObjectLen++;
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// Get content functions.
+// -----------------------------------------------------------------------------
+
+// -----------------------------------------------------------------------------
+// CCrBer::GetBooleanL
+// Returns value of Boolean object.
+// -----------------------------------------------------------------------------
+EXPORT_C TBool CCrBer::GetBooleanL()
+ {
+ TInt err = KErrNone;
+ TASN1DecBoolean dec; // ASN1 lib (Symbian)
+ TInt pos = NULL;
+ TBool ret = EFalse;
+
+ HBufC8* buf = HBufC8::NewLC(iObjectLen); // buffer to object
+
+ TPtr8 ptr = buf->Des();
+
+ err = iData->Read(iObjectBegin,ptr,iObjectLen); // Read object
+
+ if (err == KErrNone)
+ {
+ ret = dec.DecodeDERL(ptr, pos); // decode object
+ }
+ else
+ {
+ CleanupStack::PopAndDestroy(); // delete buf;
+ User::Leave(err);
+ }
+
+ CleanupStack::PopAndDestroy(); // delete buf;
+
+ return ret;
+ }
+
+// -----------------------------------------------------------------------------
+// CCrBer::GetIntegerL
+// Returns value of Integer object.
+// -----------------------------------------------------------------------------
+EXPORT_C TInt CCrBer::GetIntegerL()
+ {
+ TInt err = KErrNone;
+ TASN1DecInteger dec; // ASN1 lib (Symbian)
+ TInt pos = NULL;
+ TInt ret = NULL;
+
+ HBufC8* buf = HBufC8::NewLC(iObjectLen); // buffer to object
+
+ TPtr8 ptr = buf->Des();
+
+ err = iData->Read(iObjectBegin,ptr,iObjectLen); // Read object
+
+ if (err == KErrNone)
+ {
+ ret = dec.DecodeDERShortL(ptr, pos); // decode object
+ }
+ else
+ {
+ CleanupStack::PopAndDestroy(); // delete buf;
+ User::Leave(err);
+ }
+
+ CleanupStack::PopAndDestroy(); // delete buf;
+
+ return ret;
+ }
+
+// -----------------------------------------------------------------------------
+// CCrBer::GetIntegerL
+// Returns value of Long Integer object.
+// -----------------------------------------------------------------------------
+EXPORT_C RInteger CCrBer::GetLongIntegerL()
+ {
+ TInt err = KErrNone;
+ TInt pos = NULL;
+ TASN1DecInteger dec; // ASN1 lib (Symbian)
+
+ HBufC8* buf = HBufC8::NewLC(iObjectLen); // buffer to object
+
+ TPtr8 ptr = buf->Des();
+ RInteger value;
+
+ // Read object to buf
+ err = iData->Read(iObjectBegin,ptr,iObjectLen);
+
+ if (err == KErrNone)
+ {
+ value = dec.DecodeDERLongL(ptr, pos); // decode object
+ }
+ else
+ {
+ CleanupStack::PopAndDestroy(); // delete buf;
+ User::Leave(err);
+ }
+
+ CleanupStack::PopAndDestroy(); // delete buf;
+
+ return value;
+ }
+
+// -----------------------------------------------------------------------------
+// HBufC* CCrBer::GetOidL
+// Returns value of object identifier.
+// -----------------------------------------------------------------------------
+EXPORT_C HBufC* CCrBer::GetOidL()
+ {
+ TInt err = KErrNone;
+ TInt pos = NULL;
+ HBufC* ret = NULL;
+ TASN1DecObjectIdentifier dec; // ASN1 lib (Symbian)
+
+ HBufC8* buf = HBufC8::NewLC(iObjectLen); // buffer to object
+
+ TPtr8 ptr = buf->Des();
+
+ // Read object to buf
+ err = iData->Read(iObjectBegin,ptr,iObjectLen);
+
+ if (err == KErrNone)
+ {
+ ret = dec.DecodeDERL(ptr, pos); // decode object
+ }
+ else
+ {
+ CleanupStack::PopAndDestroy(); // delete buf;
+ User::Leave(err);
+ }
+
+ CleanupStack::PopAndDestroy(); // delete buf;
+
+ return ret;
+ }
+
+// -----------------------------------------------------------------------------
+// HBufC8* CCrBer::GetOctetStringL
+// Returns value of octet string.
+// -----------------------------------------------------------------------------
+EXPORT_C HBufC8* CCrBer::GetOctetStringL()
+ {
+ TInt pos = NULL;
+ HBufC8* ret = NULL;
+ TInt err = KErrNone;
+ TASN1DecOctetString dec; // ASN1 lib (Symbian)
+
+ HBufC8* buf = HBufC8::NewLC(iObjectLen); // buffer to object
+
+ TPtr8 ptr = buf->Des();
+
+ // Read object to buf
+ err = iData->Read(iObjectBegin,ptr,iObjectLen);
+
+ if (err == KErrNone)
+ {
+ ret = dec.DecodeDERL(ptr, pos); // decode object
+ }
+ else
+ {
+ CleanupStack::PopAndDestroy(buf); // delete buf;
+ User::Leave(err);
+ }
+
+ CleanupStack::PopAndDestroy(buf); // delete buf;
+
+ return ret;
+ }
+
+// -----------------------------------------------------------------------------
+// HBufC8* CCrBer::GetOctetStringL
+// Returns value of octet string.
+// -----------------------------------------------------------------------------
+EXPORT_C TAny CCrBer::GetOctetStringL(CCrData& Trg)
+ {
+ TUint pos = iContentBegin;
+ TUint end = iContentBegin + iContentLen;
+ TInt err = KErrNone;
+ TInt len = KBufSize;
+ HBufC8* buf = HBufC8::NewL(KBufSize); // buffer to object
+ CleanupStack::PushL(buf);
+
+ TPtr8 ptr = buf->Des();
+ // Read object to buf
+ while (pos < end)
+ {
+ len = end - pos;
+
+ if (len > KBufSize)
+ {
+ len = KBufSize;
+ }
+
+ err = iData->Read(pos, ptr, len);
+
+ if (err == KErrNone)
+ {
+ Trg.Write(ptr);
+ }
+ if (err < KErrNone)
+ {
+ CleanupStack::PopAndDestroy();
+ // buf = NULL;
+ User::Leave(err);
+ }
+ pos += KBufSize;
+ }
+ CleanupStack::PopAndDestroy(); // buf
+ }
+
+// -----------------------------------------------------------------------------
+// HBufC8* CCrBer::GetContentStringLC
+// Note buf is left to CleanupStack.
+// Returns value of content string.
+// -----------------------------------------------------------------------------
+EXPORT_C HBufC8* CCrBer::GetContentStringLC()
+ {
+ HBufC8* buf = HBufC8::NewL(iContentLen); // buffer to Content
+ CleanupStack::PushL(buf);
+
+ TPtr8 ptr = buf->Des();
+
+ // Read object to buf
+ iData->Read(iContentBegin, ptr, iContentLen);
+
+ return buf;
+ }
+
+// -----------------------------------------------------------------------------
+// HBufC* CCrBer::GetIA5StringL
+// Returns value of IA5 string object.
+// -----------------------------------------------------------------------------
+EXPORT_C HBufC* CCrBer::GetIA5StringL()
+ {
+ TInt err = KErrNone;
+ TInt pos = NULL;
+ HBufC* ret = NULL;
+ TASN1DecIA5String dec; // ASN1 lib (Symbian)
+
+ HBufC8* buf = HBufC8::NewLC(iObjectLen); // buffer to object
+ TPtr8 ptr = buf->Des();
+
+ // Read object to buf
+ err = iData->Read(iObjectBegin,ptr,iObjectLen);
+
+ if (err == KErrNone)
+ {
+ ret = dec.DecodeDERL(ptr, pos); // decode object
+ }
+ else
+ {
+ CleanupStack::PopAndDestroy(); // delete buf;
+ User::Leave(err);
+ }
+
+ CleanupStack::PopAndDestroy(); // delete buf;
+
+ return ret;
+ }
+
+// -----------------------------------------------------------------------------
+// TTime CCrBer::GetUTCTimeL
+// Returns value of UTC time object.
+// -----------------------------------------------------------------------------
+EXPORT_C TTime CCrBer::GetUTCTimeL()
+ {
+ TInt err = KErrNone;
+ TInt pos = NULL;
+ TTime ret = TTime(0);
+ TASN1DecUTCTime dec; // ASN1 lib (Symbian)
+
+ HBufC8* buf = HBufC8::NewLC(iObjectLen); // buffer to object
+ TPtr8 ptr = buf->Des();
+
+ // Read object to buf
+ err = iData->Read(iObjectBegin,ptr,iObjectLen);
+
+ if (err == KErrNone)
+ {
+ ret = dec.DecodeDERL(ptr, pos); // decode object
+ }
+ else
+ {
+ CleanupStack::PopAndDestroy(); // delete buf;
+ User::Leave(err);
+ }
+
+ CleanupStack::PopAndDestroy(); // delete buf;
+
+ return ret;
+ }
+
+
+
+// -----------------------------------------------------------------------------
+// TTime CCrBer::GetGeneralizedTimeL
+// Returns value of generalised time object.
+// -----------------------------------------------------------------------------
+EXPORT_C TTime CCrBer::GetGeneralizedTimeL()
+ {
+ TInt err = KErrNone;
+ TInt pos = NULL;
+ TTime ret = TTime(0);
+ TASN1DecGeneralizedTime dec; // ASN1 lib (Symbian)
+
+ HBufC8* buf = HBufC8::NewLC(iObjectLen); // buffer to object
+ TPtr8 ptr = buf->Des();
+
+ // Read object to buf
+ err = iData->Read(iObjectBegin,ptr,iObjectLen);
+
+ if (err == KErrNone)
+ {
+ ret = dec.DecodeDERL(ptr, pos); // decode object
+ }
+ else
+ {
+ CleanupStack::PopAndDestroy(); // delete buf;
+ User::Leave(err);
+ }
+
+ CleanupStack::PopAndDestroy(); // delete buf;
+
+ return ret;
+ }
+
+// -----------------------------------------------------------------------------
+// HBufC* CCrBer::GetPrintStringL
+// Returns value of printable string object.
+// -----------------------------------------------------------------------------
+EXPORT_C HBufC* CCrBer::GetPrintStringL()
+ {
+ HBufC* ret = NULL;
+ TInt err = KErrNone;
+ TInt pos = NULL;
+ TASN1DecPrintableString dec; // ASN1 lib (Symbian)
+
+ HBufC8* buf = HBufC8::NewLC(iObjectLen); // buffer to object
+ TPtr8 ptr = buf->Des();
+
+ // Read object to buf
+ err = iData->Read(iObjectBegin,ptr,iObjectLen);
+
+ if (err == KErrNone)
+ {
+ ret = dec.DecodeDERL(ptr, pos); // decode object
+ }
+ else
+ {
+ CleanupStack::PopAndDestroy(); // delete buf;
+ User::Leave(err);
+ }
+
+ CleanupStack::PopAndDestroy(); // delete buf;
+
+ return ret;
+ }
+
+// -----------------------------------------------------------------------------
+// HBufC* CCrBer::GetTeletextStringL
+// Returns value of teletext string object.
+// -----------------------------------------------------------------------------
+EXPORT_C HBufC* CCrBer::GetTeletextStringL()
+ {
+ TInt err = KErrNone;
+ TInt pos = NULL;
+ HBufC* ret = NULL;
+ TASN1DecTeletexString dec; // ASN1 lib (Symbian)
+
+ HBufC8* buf = HBufC8::NewLC(iObjectLen); // buffer to object
+ TPtr8 ptr = buf->Des();
+
+ // Read object to buf
+ err = iData->Read(iObjectBegin,ptr,iObjectLen);
+
+ if (err == KErrNone)
+ {
+ ret = dec.DecodeDERL(ptr, pos); // decode object
+ }
+ else
+ {
+ CleanupStack::PopAndDestroy(); // delete buf;
+ User::Leave(err);
+ }
+
+ CleanupStack::PopAndDestroy(); // delete buf;
+
+ return ret;
+ }
+
+
+
+// -----------------------------------------------------------------------------
+// HBufC8* CCrBer::GetSequence
+// Returns value of segunce object.
+// -----------------------------------------------------------------------------
+EXPORT_C HBufC8* CCrBer::GetSequenceL()
+ {
+ TInt err = KErrNone;
+ HBufC8* buf = HBufC8::NewLC(iObjectLen); // buffer to object
+ TPtr8 ptr = buf->Des();
+
+ // Read object to buf
+ err = iData->Read(ContentBegin(),ptr,ContentLen());
+
+ if (err < KErrNone)
+ {
+ CleanupStack::PopAndDestroy(); // delete buf;
+ // buf = NULL;
+ User::Leave(err);
+ }
+ CleanupStack::PopAndDestroy(); // delete buf;
+ // buf = NULL;
+
+ return ptr.AllocL();
+ }
+
+// -----------------------------------------------------------------------------
+// HBufC* CCrBer::GetVideoString
+// Returns value of video string object.
+// -----------------------------------------------------------------------------
+EXPORT_C HBufC* CCrBer::GetVideoStringL()
+ {
+ TInt err = KErrNone;
+ HBufC* ret = NULL;
+ TInt pos = NULL;
+ TASN1DecVideotexString dec; // ASN1 lib (Symbian)
+
+ HBufC8* buf = HBufC8::NewLC(iObjectLen); // buffer to object
+ TPtr8 ptr = buf->Des();
+
+ // Read object to buf
+ err = iData->Read(iObjectBegin,ptr,iObjectLen);
+
+ if (err == KErrNone)
+ {
+ ret = dec.DecodeDERL(ptr, pos); // decode object
+ }
+ else
+ {
+ CleanupStack::PopAndDestroy(); // delete buf;
+ User::Leave(err);
+ }
+
+ CleanupStack::PopAndDestroy(); // delete buf;
+
+ return ret;
+ }
+
+// -----------------------------------------------------------------------------
+// HBufC* CCrBer::GetGeneralString
+// Returns value of general string object.
+// -----------------------------------------------------------------------------
+EXPORT_C HBufC* CCrBer::GetGeneralStringL()
+ {
+ TInt err = KErrNone;
+ TInt pos = NULL;
+ HBufC* ret = NULL;
+ TASN1DecGeneralString dec; // ASN1 lib (Symbian)
+
+ HBufC8* buf = HBufC8::NewLC(iObjectLen); // buffer to object
+ TPtr8 ptr = buf->Des();
+
+ // Read object to buf
+ err = iData->Read(iObjectBegin,ptr,iObjectLen);
+
+ if (err == KErrNone)
+ {
+ ret = dec.DecodeDERL(ptr, pos); // decode object
+ }
+ else
+ {
+ CleanupStack::PopAndDestroy(); // delete buf;
+ User::Leave(err);
+ }
+
+ CleanupStack::PopAndDestroy(); // delete buf;
+
+ return ret;
+ }
+
+// -----------------------------------------------------------------------------
+// HBufC* CCrBer::GetVisibleStringL
+// Returns value of visible string object.
+// -----------------------------------------------------------------------------
+EXPORT_C HBufC* CCrBer::GetVisibleStringL()
+ {
+ TInt err = KErrNone;
+ HBufC* ret = NULL;
+ TInt pos = NULL;
+ TASN1DecVisibleString dec; // ASN1 lib (Symbian)
+
+ HBufC8* buf = HBufC8::NewLC(iObjectLen); // buffer to object
+ TPtr8 ptr = buf->Des();
+
+ // Read object to buf
+ err = iData->Read(iObjectBegin,ptr,iObjectLen);
+
+ if (err == KErrNone)
+ {
+ ret = dec.DecodeDERL(ptr, pos); // decode object
+ }
+ else
+ {
+ CleanupStack::PopAndDestroy(); // delete buf;
+ User::Leave(err);
+ }
+
+ CleanupStack::PopAndDestroy(); // delete buf;
+
+ return ret;
+ }
+
+// -----------------------------------------------------------------------------
+// HBufC* CCrBer::GetGraphicsStringL
+// Returns value of graphical string object.
+// -----------------------------------------------------------------------------
+EXPORT_C HBufC* CCrBer::GetGraphicsStringL()
+ {
+ TInt err = KErrNone;
+ HBufC* ret = NULL;
+ TInt pos = NULL;
+ TASN1DecGraphicString dec; // ASN1 lib (Symbian)
+
+ HBufC8* buf = HBufC8::NewLC(iObjectLen); // buffer to object
+ TPtr8 ptr = buf->Des();
+
+ // Read object to buf
+ err = iData->Read(iObjectBegin,ptr,iObjectLen);
+
+ if (err == KErrNone)
+ {
+ ret = dec.DecodeDERL(ptr, pos); // decode object
+ }
+ else
+ {
+ CleanupStack::PopAndDestroy(); // delete buf;
+ User::Leave(err);
+ }
+
+ CleanupStack::PopAndDestroy(); // delete buf;
+
+ return ret;
+ }
+
+
+
+// -----------------------------------------------------------------------------
+// HBufC* CCrBer::GetNumericStringL
+// Returns value of numeric string object.
+// -----------------------------------------------------------------------------
+EXPORT_C HBufC* CCrBer::GetNumericStringL()
+ {
+ TInt err = KErrNone;
+ HBufC* ret = NULL;
+ TInt pos = NULL;
+ TASN1DecNumericString dec; // ASN1 lib (Symbian)
+
+ HBufC8* buf = HBufC8::NewLC(iObjectLen); // buffer to object
+ TPtr8 ptr = buf->Des();
+
+ // Read object to buf
+ err = iData->Read(iObjectBegin,ptr,iObjectLen);
+
+ if (err == KErrNone)
+ {
+ ret = dec.DecodeDERL(ptr, pos); // decode object
+ }
+ else
+ {
+ CleanupStack::PopAndDestroy(); // delete buf;
+ User::Leave(err);
+ }
+
+ CleanupStack::PopAndDestroy(); // delete buf;
+
+ return ret;
+ }
+
+// -----------------------------------------------------------------------------
+// Encoding
+// -----------------------------------------------------------------------------
+
+// -----------------------------------------------------------------------------
+// CCrBer::CreateBool
+// Paremeters: Value of the boolean object. True or False.
+// -----------------------------------------------------------------------------
+TAny CCrBer::CreateBool(TBool aBool)
+ {
+ iType = KBerBoolean;
+ iObjectLen = KBerBooleanLen; // Boolean object len is always 3
+ iValue = aBool;
+ }
+
+// -----------------------------------------------------------------------------
+// CCrBer::CreateInt
+// Paremeters: Value of the object (positive, null or negative)
+// e.g. 234 or 0xFFF or -45676.
+// -----------------------------------------------------------------------------
+TAny CCrBer::CreateInt(TInt aInt)
+ {
+ iType = KBerInteger;
+ iValue = aInt;
+
+ // Find out object len. Tag + len + value.
+ if (aInt == 0 || (aInt > (-0x81) && aInt < 0x80 ))
+ iObjectLen = 0x03;
+
+ else if (aInt > (-0x8001) && aInt < 0x8000)
+ iObjectLen = 0x04;
+
+ else if (aInt > (-0x800001) && aInt < 0x800000)
+ iObjectLen = 0x05;
+
+ else
+ iObjectLen = 0x06;
+ }
+
+// -----------------------------------------------------------------------------
+// CCrBer::CreateInt
+// Paremeters: Value of the object (positive, null or negative)
+// e.g. 234 or 0xFFF or -45676.
+// -----------------------------------------------------------------------------
+TAny CCrBer::CreateLongInt(RInteger& aData)
+ {
+ TInt len = aData.ByteCount();
+ iType = KBerInteger;
+ iValue = NULL;
+ iInt = RInteger::NewL(aData);
+
+ iObjectLen = KBerShortLen + len; // Tag + len(lenlen) + string
+
+ if (len >= KBerLongLengthBit)
+ {
+ while (len > NULL) // add number of lenbytes
+ {
+ len >>= KOctetWidth; // Next byte
+ iObjectLen++;
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CCrBer::CreateNull
+// -----------------------------------------------------------------------------
+TAny CCrBer::CreateNull()
+ {
+ iType = KBerNull; // Tag
+ iObjectLen = KBerNullLen; // 05 00
+ }
+
+// -----------------------------------------------------------------------------
+// CCrBer::CreateOId
+// Paremeters: Pointer to string. e.g.(1.2.43.4335.242)
+// -----------------------------------------------------------------------------
+TAny CCrBer::CreateOIdL(TDesC8* aString)
+ {
+ CCrBerSet* set = CCrBerSet::NewLC(1);
+ TInt len = set->AppendObjectIdL(*aString, ETrue);// ask Oid content len
+ iType = KBerOid;
+ iValuePtr = aString;
+
+ iObjectLen = (len > NULL) ? KBerShortLen + len : 0; // tag + len + content
+
+ CleanupStack::PopAndDestroy(); // delete set;
+ // set = NULL;
+ }
+
+
+
+// -----------------------------------------------------------------------------
+// CCrBer::CreateString
+// Paremeters: Type of object and pointer to string.
+// -----------------------------------------------------------------------------
+TAny CCrBer::CreateString(TBerTag aTag, TDesC8* aString)
+ {
+ TInt len = aString->Length();
+ iType = aTag;
+ iValuePtr = aString;
+ iObjectLen = KBerShortLen + len; // Tag + len(lenlen) + string
+
+ if (len >= KBerLongLengthBit)
+ {
+ while (len > NULL) // add number of lenbytes
+ {
+ len >>= KOctetWidth; // Next byte
+ iObjectLen++;
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CCrBer::CreateString
+// -----------------------------------------------------------------------------
+TAny CCrBer::CreateString(TBerTag aTag, CCrData* aData)
+ {
+ TInt len = 0;
+ aData->Size(len);
+ iType = aTag;
+ iData = aData;
+ iObjectLen = KBerShortLen + len; // Tag + len(lenlen) + string
+
+ if (len >= KBerLongLengthBit)
+ {
+ while (len > NULL) // add number of lenbytes
+ {
+ len >>= KOctetWidth; // Next byte
+ iObjectLen++;
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CCrBer::CreateStart
+// Paremeters: First parameter is tag type (e.g. seq). Second param is
+// True if definite length is wanted.
+// False if indefinite (xx 80) .
+// -----------------------------------------------------------------------------
+TAny CCrBer::CreateStart(TBerTag aTag, TBool aDefinite)
+ {
+ iType = aTag;
+
+ // Definite object length = 0 (set rigth length later).
+ // Indefinite object length is always 4 (Tag + 80 + 00 + 00)
+ if (!aDefinite)
+ {
+ iObjectLen = KBerIndefiniteLen;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CCrBer::CreateEnd
+// -----------------------------------------------------------------------------
+TAny CCrBer::CreateEnd()
+ {
+ iType = KBerEndOfContent; // =0x00
+ iValue = KBerEndOfContent;
+ }
+
+// -----------------------------------------------------------------------------
+// CCrBer::CreateBEREncodedObject
+// This fuction can be used to create a BER object
+// from buffer, which already contains a full BER
+// encoded object.
+// Paremeters: Buffer containing BER encoded object.
+// -----------------------------------------------------------------------------
+TAny CCrBer::CreateBEREncodedObject(TDesC8* aBuffer)
+ {
+ iType = KBerEncodedObject;
+ iValuePtr = aBuffer;
+ iObjectLen = aBuffer->Length();
+ }
+
+// ========================== OTHER EXPORTED FUNCTIONS =========================
+
+// ---------------------------------------------------------
+// E32Dll
+// DLL entry point
+// ---------------------------------------------------------
+//
+#ifndef EKA2
+GLDEF_C TInt E32Dll(TDllReason /*aReason*/)
+ {
+ return KErrNone;
+ }
+#endif