--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/pkiutilities/PKCS12/CrBer/Src/Crberset.cpp Tue Jan 26 15:20:08 2010 +0200
@@ -0,0 +1,1367 @@
+/*
+* 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 CCrBerSet class.
+*
+*/
+
+
+
+// INCLUDE FILES
+
+#include "crber.h"
+
+
+// -----------------------------------------------------------------------------
+//CCrBerSet
+//Constructor
+// -----------------------------------------------------------------------------
+CCrBerSet::CCrBerSet(TInt aGranularity)
+ : CArrayPtrSeg<CCrBer>(aGranularity), iLevel(0)
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CCrBerSet
+// Destructor
+// This function destructs CCrBerSet object
+// -----------------------------------------------------------------------------
+CCrBerSet::~CCrBerSet()
+ {
+ ResetAndDestroy();
+ }
+
+// -----------------------------------------------------------------------------
+// CCrBerSet::ConstructL
+// This function initializes CCrBerSet object's member objects.
+// -----------------------------------------------------------------------------
+TAny CCrBerSet::ConstructL()
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CCrBerSet::NewLC
+// -----------------------------------------------------------------------------
+EXPORT_C CCrBerSet* CCrBerSet::NewLC(TInt aGranularity)
+ {
+ CCrBerSet* self = new (ELeave) CCrBerSet(aGranularity);
+ CleanupStack::PushL(self);
+
+ self->ConstructL();
+
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CCrBerSet::NewL
+// -----------------------------------------------------------------------------
+EXPORT_C CCrBerSet* CCrBerSet::NewL(TInt aGranularity)
+ {
+ CCrBerSet* self = NewLC(aGranularity);
+ CleanupStack::Pop();
+
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CCrBerSet::OpenL
+//
+// Opens next BER encoded object from the current position of
+// given CCrData to this object set. Opens also all nested BER
+// objects as deep as aRecursionLevel tells. If it is zero, one
+// object is read, if it is one, all objects at first level are
+// read, and if it is 0xff, all objects at 255 first levels are
+// extracted. This function cannot be used to extract deeper
+// structures than that, if you want to go deeper, implement
+// a function of your own. Returns the amount of extracted
+// objects. The data pointer of CCrData points right after the
+// opened BER object after this function is finished.
+// Parameters: CCrData* aData Data object containing the BER
+// object to be opened.
+// Returns: TUint Amount of BER objects extracted.
+// -----------------------------------------------------------------------------
+EXPORT_C TUint CCrBerSet::OpenL(
+ CCrData* aData,
+ TUint8 aRecursionLevel /* = 1 */)
+ {
+ TInt i = 0;
+ TUint level = 0;
+ TUint8 amount = 0;
+ TInt definiteObjectEnd [255]= {0};
+ TBerTag type = KBerEndOfContent;
+ CCrBer* newObject = 0;
+
+ while (type != KBerUnknown)
+ {
+ // Don't create new object if old is to be recycled.
+ if (newObject == 0)
+ {
+ newObject = CCrBer::NewLC(level);
+ }
+
+ // Read next BER object.
+ if ((type = newObject->Read(aData)) != KBerUnknown)
+ {
+ i = 0;
+ // check definite seq(e.g) end, and if so, take away 1 level.
+ while (definiteObjectEnd[i] != 0)
+ {
+ if ((definiteObjectEnd[i] <= newObject->ObjectLen()
+ + newObject->ObjectBegin()) &&
+ (definiteObjectEnd[i]) &&
+ !(newObject->IsSeqOrSet(type)))
+ {
+ level--;
+ definiteObjectEnd[i] = 0;
+ }
+ i++;
+ }
+ // If type is explicit or implicit constructed or sequence
+ // or set with indefinite length, we are one level deeper.
+ if (CCrBer::IsSeqOrSet(type))
+ {
+ if (newObject->Indefinite())
+ {
+ level++;
+ }
+ else
+ {
+ level++;
+ i = 0;
+ while (definiteObjectEnd[i] != 0)
+ {
+ i++;
+ }
+ definiteObjectEnd[i] = newObject->ObjectLen()
+ + newObject->ObjectBegin();
+ }
+ // Changed by junuutin on 3.5.2004:
+ if ((type == KBerImplicit) || (type == KBerExplicit))
+ {
+ // Don't try to parse the content of context-specified stuff
+ // Jump to next object.
+ TInt currentPos = 0;
+ aData->Seek(ESeekCurrent, currentPos);
+ TInt pos = currentPos + newObject->ContentLen();
+ aData->Seek(ESeekStart, pos);
+ level--;
+ }
+ else if ((type == KBerImplicitConstructed) || (type == KBerExplicitConstructed))
+ {
+ TInt currentPos = 0;
+ aData->Seek(ESeekCurrent, currentPos);
+ CCrBer* tempObject = CCrBer::NewL();
+
+ // Read next BER object.
+ TBerTag tempType = tempObject->Read(aData);
+ if (!(CCrBer::IsKnownType(tempType)))
+ {
+ // Jump to next object.
+ TInt pos = currentPos + newObject->ContentLen();
+ aData->Seek(ESeekStart, pos);
+ level--;
+
+ }
+ else // return current position.
+ {
+ aData->Seek(ESeekStart, currentPos);
+ }
+
+ delete tempObject;
+ tempObject = NULL;
+ }
+ }
+
+ // If type is end-of-content tag, last constructed object,
+ // sequence or set with indefinite length has ended, we
+ // are one level lower.
+ if (type == KBerEndOfContent)
+ {
+ level--;
+
+ // Also set new object's level to current,
+ // because that's where it actually belongs.
+ newObject->SetLevel(level);
+
+
+ // Close last sequence or set.
+ CloseLastSeqOrSet(level);
+ }
+
+ // If it is of known type, append object to this set,
+ // null the pointer and continue to look for next objects.
+ // Append only if wanted recursion level not exceeded.
+ if ((level <= aRecursionLevel) || (aRecursionLevel == 255))
+ {
+ AppendAndUpdateL(newObject);
+ CleanupStack::Pop(); //newObject
+ newObject = NULL;
+ }
+ else
+ {
+ // Anyway previous open objects have to be
+ // updated with the length of this object.
+ Update(newObject);
+ }
+
+ // Anyway we have one item more.
+
+ amount++;
+ }
+ else
+ {
+ // Otherwise delete object and stop the whole thing.
+ // Don't return those bloody errors, because we cannot
+ // know what the caller was looking for, let him evaluate
+ // the results and decide whether this was a failure or not.
+ //delete newObject;
+ CleanupStack::PopAndDestroy();
+
+ // go to return
+ type = KBerUnknown;
+ }
+ }
+
+ return amount;
+ }
+
+// -----------------------------------------------------------------------------
+// CCrBerSet::AppendAndUpdateL
+// Appends given new object into this set. Updates all previous
+// items in this set, which have indefinite length, with the
+// length of the new object.
+// Parameters: CCrBer* aBerObject New BER object to be added to this set
+// -----------------------------------------------------------------------------
+EXPORT_C TAny CCrBerSet::AppendAndUpdateL(CCrBer* aBerObject)
+ {
+ Update(aBerObject);
+
+ AppendL(aBerObject);
+ }
+
+// -----------------------------------------------------------------------------
+// CCrBerSet::Update
+// Updates all previous items in this set, which have
+// indefinite length, with the length of the new object.
+// Parameters: CCrBer* aBerObject New BER object with whom
+// this set is updated.
+// -----------------------------------------------------------------------------
+EXPORT_C TAny CCrBerSet::Update(CCrBer* aBerObject)
+ {
+ TInt add = 0;
+ TInt index = 0;
+ TInt size = 0;
+ TUint berObjectLevel = 0;
+
+ CCrBer* obj;
+
+ if (aBerObject == 0)
+ {
+ return;
+ }
+
+ // Loop backwards through set and append length of the new object
+ // to the lengths of each found upper constructed, sequence or set
+ // objects with indefinite lengths, until first 'closed' from upper
+ // level found.
+
+ // Use object length, unless this is an object, whose total length is
+ // not yet known. In that case use tag length (always 1) combined with
+ // the amount of the length bytes.
+ if ((add = aBerObject->ObjectLen()) == 0)
+ {
+ add = 1 + aBerObject->LenLen();
+
+ // If new object is of indefinite length, still
+ // add two more bytes for the end-of-content tag.
+ if (aBerObject->Indefinite())
+ {
+ add += 2;
+ }
+ }
+
+ berObjectLevel = aBerObject->Level();
+
+ size = Count();
+
+ for (index = size - 1; index >= 0; index--)
+ {
+ obj = At(index);
+
+ if ((obj != 0) &&
+ (obj->Level() < berObjectLevel) &&
+ (obj->Indefinite()))
+ {
+ if ((obj->Type() == KBerSeq) ||
+ (obj->Type() == KBerSet) ||
+ (obj->Type() == KBerImplicitConstructed) ||
+ (obj->Type() == KBerExplicitConstructed))
+ {
+ if (obj->ObjectLen() == 0)
+ {
+ obj->AddToContentLen(add);
+ }
+ else
+ {
+ index = -1; // break;
+ }
+ }
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CCrBerSet::CloseLastSeqOrSet
+// Finds last open indefinite length sequence
+// or set from this set at given level and closes it.
+// -----------------------------------------------------------------------------
+EXPORT_C TAny CCrBerSet::CloseLastSeqOrSet(TUint aLevel)
+ {
+ TInt index = 0;
+ TInt size = 0;
+ TBerTag type = KBerUnknown;
+
+ CCrBer* obj = NULL;
+
+ // Loop backwards through set and find first sequence or set with
+ // indefinite length at same level. 'Close' it by setting its object
+ // length.
+ size = Count();
+
+ for (index = size - 1; index >= 0; index--)
+ {
+ obj = At(index);
+
+ if ((obj != 0) &&
+ (obj->Level() == aLevel) &&
+ (obj->Indefinite()))
+ {
+ type = obj->Type();
+
+ if ((type == KBerSeq) ||
+ (type == KBerSet) ||
+ (type == KBerImplicitConstructed) ||
+ (type == KBerExplicitConstructed))
+ {
+ obj->SetObjectLen();
+
+ // Update upper objects with closed object.
+ Update(obj);
+
+ index = -1; // break;
+ }
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// Encoding
+// -----------------------------------------------------------------------------
+
+// -----------------------------------------------------------------------------
+// CCrBerSet::AppendBool
+// Write boolean object to CCrData.
+// Parameters: Boolean value. ETrue or EFalse ( 0 / 1 ).
+// Return Values: Error code
+// -----------------------------------------------------------------------------
+TInt CCrBerSet::AppendBoolL(TBool aBool)
+ {
+ TInt err = KErrNone;
+ TBuf8<1> value;
+
+ if (aBool)
+ {
+ value.Append(KBerBooleanTrue);
+ }
+ else
+ {
+ value.Append(KBerBooleanFalse);
+ }
+
+ err = AppendStringL(KBerBoolean, value);
+
+ return err;
+ }
+
+// -----------------------------------------------------------------------------
+// CCrBerSet::AppendInt
+// Write integer (0x02) object to CCrData. Parameter is either
+// a positive whole number, or a negative whole number, or zero.
+// value : from - 0xFFFFFFF to +0xFFF FFFF
+// Parameters: Integer value e.g. 1024 or 0xABC.
+// Return Values: Error code
+// -----------------------------------------------------------------------------
+TInt CCrBerSet::AppendIntL(TInt aData)
+ {
+ TInt err = KErrNone;
+ TBuf8<8> indexBuf;
+ TUint len = 0;
+
+ HBufC8* buf = NULL;
+
+ buf = HBufC8::NewLC(KIntBufSize);
+ TPtr8 data = buf->Des();
+
+ if (aData >= 0)
+ {
+ if (aData >= KBerLongLengthBit)
+ {
+ while (aData > 0)
+ {
+ TInt8 byte;
+ byte = TInt8(aData); // Take byte
+ indexBuf.Append(byte); // and add it to indexBuf
+ aData >>= KOctetWidth; // Next byte
+ len++;
+ }
+ if (indexBuf[len-1] >= KBerLongLengthBit) // if high order bit=1
+ {
+ indexBuf.Append(0); // e.g. content 00 FF no FF
+ len++; // (FF = neg num)
+ }
+ }
+ else // only one byte
+ {
+ indexBuf.Append(aData); // so add directly
+ len++;
+ }
+ }
+
+ else
+ {
+ aData = -(aData + 1); // convert to positive
+
+ while ((aData > 0) || (len < 1)) // (len < 1) because -1 -> 0 ->FF
+ {
+ TInt8 byte;
+ byte = TInt8(aData); // Take byte
+ indexBuf.Append(~byte); // and add complement to buf
+ aData >>= KOctetWidth; // Next byte
+ len++;
+ }
+ if (indexBuf[len-1] < KBerLongLengthBit) // if high order bit=0
+ {
+ indexBuf.Append(0xFF);
+ len++;
+ }
+ }
+
+ for (TInt i=len ; i > 0 ; i--)
+ {
+ data.Append(indexBuf[i - 1]); // add data to buffer
+ }
+
+ err = AppendStringL(KBerInteger, data); // write data to file
+
+ CleanupStack::PopAndDestroy();
+ buf = NULL;
+
+ return err;
+ }
+
+
+
+TInt CCrBerSet::AppendLongIntL(RInteger& aData)
+ {
+ TInt err = KErrNone;
+
+ err = AppendStringL(KBerInteger, *aData.BufferLC());
+
+ CleanupStack::PopAndDestroy();
+
+ return err;
+ }
+
+
+// -----------------------------------------------------------------------------
+// CCrBerSet::AppendNull
+// Write null (05 00) object to CCrData.
+// Parameters: None
+// Return Values: Error code
+// -----------------------------------------------------------------------------
+TInt CCrBerSet::AppendNull()
+ {
+ TInt err = KErrNone;
+ TBuf8<2> data;
+
+ data.Append(KBerNull); // Add Null tag 05
+ data.Append(KBerNullContent); // and null; 00
+
+ err = iTarget->Write(data); // write data-buffer to CCrData
+
+ return err;
+ }
+
+// -----------------------------------------------------------------------------
+// CCrBerSet::CloseIndefinite
+// Write end of indefinite length (add 00 00) to CCrData.
+// Return Values: Error code
+// -----------------------------------------------------------------------------
+TInt CCrBerSet::CloseIndefinite()
+ {
+ TInt err = KErrNone;
+ TBuf8<2> data;
+ data.Append(KBerEndOfContent); // add end of indefinite length
+ data.Append(KBerEndOfContent); // ( 00 00 )
+ err = iTarget->Write(data); // write data-buffer to file
+
+ return err;
+ }
+
+// -----------------------------------------------------------------------------
+// CCrBerSet::AppendConstructed
+// Write constructed type to CCrData.
+// Parameters: First param is type of constructed tag
+// e.g. 04 for octetS. Second parameter is length or 0 for
+// indefinite length. e.g. if params are 4 and 0 --> 24 00
+// Return Values: Error code
+// -----------------------------------------------------------------------------
+TInt CCrBerSet::AppendConstructedL(TBerTag aTag, TUint aLength)
+ {
+ TInt err = KErrNone;
+ HBufC8* buf = NULL;
+
+ buf = HBufC8::NewLC(8);
+ TPtr8 data = buf->Des();
+
+ if (aTag < KBerConstructedBit) // if tag not consist ConstructedBit
+ {
+ aTag += KBerConstructedBit; // add ConstructedBit
+ }
+
+ if (aLength == KBerEndOfContent) // indefinite length
+ {
+ data.Append(aTag); // add Tag
+ data.Append(KBerLongLengthBit); // add indefinite length
+ }
+
+ else if (aLength < KBerLongLengthBit) // if short len
+ {
+ data.Append(aTag); // add Tag
+ data.Append(aLength); // add len
+ }
+
+ else // else we have long len
+ {
+ TBuf8<6> indexBuf;
+ TInt lenlen = 0; // number of length bytes
+
+ while (aLength > 0)
+ {
+ TInt8 byte;
+ byte = TInt8(aLength);
+ indexBuf.Append(byte);
+ aLength >>= KOctetWidth;
+ lenlen++;
+ }
+
+ data.Append(aTag); // Add Tag
+ data.Append(lenlen + KBerLongLengthBit); // Lenlen byte
+
+ for (TInt i = lenlen ; i > 0 ; i--)
+ {
+ data.Append(indexBuf[i - 1]); // length bytes
+ }
+ }
+
+ err = iTarget->Write(data); // write to CCrData
+
+ CleanupStack::PopAndDestroy();
+ buf = NULL;
+
+ return err;
+ }
+
+// -----------------------------------------------------------------------------
+// CCrBerSet::AppendObjectId
+// Write object id object to CCrData.
+// Parameters: Object ID. e.g. _L8("1.2.3.4.5"). Second parameter is
+// true if you don't want write object to CCrData.
+// Return Values: Error code (or length of object if aOnlyLen is true).
+// -----------------------------------------------------------------------------
+TInt CCrBerSet::AppendObjectIdL(const TDesC8& aString, TBool aOnlyLen)
+ {
+ TChar ch = NULL;
+ TUint num = 0;
+ TUint sum = 0;
+ TInt index = 0;
+ TInt len = 0;
+ TInt i = 0;
+ TInt start = 0;
+ TInt err = KErrNone;
+ TBuf8<16> outbuf;
+
+ HBufC8* fileBuf = NULL;
+ HBufC8* str = NULL;
+
+ fileBuf = HBufC8::NewLC(aString.Length() + 1);
+ str = aString.AllocLC();
+
+ TPtr8 ptrFileBuf = fileBuf->Des();
+ TPtr8 strptr = str->Des();
+
+ // Check valid ( string must start "x.z.*", x < 10 and z < 10)
+ if ((len = strptr.Locate('.')) == KObjectIDDot)
+ {
+ ch = strptr[i]; // take first number
+ num = ch.GetNumericValue(); // convert ascii to num
+
+ // First byte = (first number * 40) + second number
+ sum = num * KObjectIDFirstFactor; // num * 4
+
+ strptr.Delete(start, len + 1); // delete 'x.'
+
+ // also second num must be smaller than 10
+ if (!((strptr.Locate('.')) == KObjectIDDot))
+ {
+ err = KErrArgument;
+ }
+
+ while (strptr.Length() > 0)
+ {
+ len = strptr.Locate('.'); // Find next dot
+
+ if (len == KErrNotFound) // if not found: take all
+ {
+ len = strptr.Length(); // string len
+ }
+
+ for (i = 0; i < len; i++)
+ {
+ ch = strptr[i];
+ num = ch.GetNumericValue();
+ sum = sum * KObjectIDSecondFactor + num; // sum * 10 + num
+ num = 0;
+ }
+
+ strptr.Delete(start, len + 1); // delete also dot
+
+ for (index = 0; (sum >= KBerLongLengthBit); index++)
+ {
+ outbuf.Append(sum % KBerLongLengthBit); // add remainder
+ sum = (sum - outbuf[index]) / KBerLongLengthBit;// take new
+ }
+
+ outbuf.Append(sum);
+
+ for (; index >= 0 ; index--)
+ {
+ if (!index)
+ {
+ ptrFileBuf.Append(outbuf[index]);
+ }
+ else
+ {
+ ptrFileBuf.Append(outbuf[index] + KBerLongLengthBit);
+ }
+ }
+
+ sum = 0;
+ outbuf.Delete(start, outbuf.Length());
+ }
+
+ if ((!aOnlyLen && ptrFileBuf.Length()) && (err == KErrNone))
+ {
+ err = AppendStringL(KBerOid, ptrFileBuf); // write object to CCrData
+ }
+ else if (err == KErrNone)
+ {
+ len = ptrFileBuf.Length(); // return object length
+ err = len;
+ } // else return error
+ }
+ else
+ {
+ err = KErrArgument; // return argument error
+ }
+
+ CleanupStack::PopAndDestroy(2); // delete fileBuf, str;
+ return err; // return error code
+ }
+
+// -----------------------------------------------------------------------------
+// CCrBerSet::AppendString
+// Write string object to CCrData.
+// Parameters: Object type (tag) and string. e.g. (KBerIA5S, _L("Hello"))
+// Return Values: Error code
+// -----------------------------------------------------------------------------
+TInt CCrBerSet::AppendStringL(TBerTag aTag, const TDesC8& aString)
+ {
+ TInt err = KErrNone;
+ TInt len = aString.Length();
+
+ HBufC8* buf = NULL;
+
+ buf = HBufC8::NewLC(KBerShortLen + LEN_BYTES_MAX);
+ TPtr8 data = buf->Des();
+
+ if (len < KBerLongLengthBit) // If short len:
+ {
+ data.Append(aTag); // Add Tag
+ data.Append(len); // length
+ }
+ else // Else long
+ {
+ TBuf8<8> indexBuf;
+ TUint lenlen = 0; // number of len bytes
+
+ while (len > 0)
+ {
+ TInt8 byte;
+ byte = TInt8(len); // Take byte
+ indexBuf.Append(byte); // append it to buf
+ len >>= KOctetWidth; // next byte
+ lenlen++;
+ }
+
+ data.Append(aTag); // Add tag
+ data.Append(lenlen + KBerLongLengthBit); // now add lenlen byte
+ // 0x80 + lenlen
+
+ for (TInt i=lenlen ; i > 0 ; i--)
+ {
+ data.Append(indexBuf[i - 1]); // add len bytes
+ }
+
+ len = aString.Length();
+ }
+
+ err = iTarget->Write(data); // write buffer to file
+ err = iTarget->Write(aString); // write buffer to file
+
+ CleanupStack::PopAndDestroy(); // delete buf;
+ buf = NULL;
+
+ return err;
+ }
+
+// -----------------------------------------------------------------------------
+// CCrBerSet::AppendString
+// Write string object to CCrData.
+// Parameters: Object type (tag) and CCrData
+// Return Values: Error code
+// -----------------------------------------------------------------------------
+TInt CCrBerSet::AppendStringL(TBerTag aTag, CCrData* const aData)
+ {
+ TInt err = KErrNone;
+ TInt len = 0;
+ aData->Size(len);
+
+ HBufC8* buf = NULL;
+ buf = HBufC8::NewLC(KBerShortLen + LEN_BYTES_MAX);
+ TPtr8 data = buf->Des();
+
+ if (len < KBerLongLengthBit) // If short len:
+ {
+ data.Append(aTag); // Add Tag
+ data.Append(len); // length
+
+ }
+ else // Else long
+ {
+ TBuf8<8> indexBuf;
+ TUint lenlen = 0; // number of len bytes
+
+ while (len > 0)
+ {
+ TInt8 byte;
+ byte = TInt8(len); // Take byte
+ indexBuf.Append(byte); // append it to buf
+ len >>= KOctetWidth; // next byte
+ lenlen++;
+ }
+
+ data.Append(aTag); // Add tag
+ data.Append(lenlen + KBerLongLengthBit); // now add lenlen byte
+ // 0x80 + lenlen
+
+ for (TInt i=lenlen ; i > 0 ; i--)
+ {
+ data.Append(indexBuf[i - 1]); // add len bytes
+ }
+
+ aData->Size(len);
+
+ }
+
+ err = iTarget->Write(data); // write buffer to file
+
+ // Write aData to iTarget
+ HBufC8* tempBuf = tempBuf = HBufC8::NewLC(KBufSize);
+
+ // write aData to iTarget in loop.
+ TPtr8 ptr = tempBuf->Des();
+ TInt size = 0;
+ aData->Size(size);
+ TInt left = size;
+ TInt handleThisTime = 0;
+ TInt handled = 0;
+
+ while (left > 0)
+ {
+ if (left > KBufSize)
+ {
+ handleThisTime = KBufSize;
+ }
+ else
+ {
+ handleThisTime = left;
+ }
+ aData->Read(handled, ptr, handleThisTime);
+ iTarget->Write(ptr);
+ ptr.Zero();
+
+ handled = handled + handleThisTime;
+ left = size - handled;
+ }
+
+ CleanupStack::PopAndDestroy(2);
+ return err;
+ }
+
+// -----------------------------------------------------------------------------
+// CCrBerSet::AppendBerEncodedObject
+// Write BER encoded object to CCrData.
+// Parameters: Buffer containing BER encoded object.
+// Return Values: Error code
+// -----------------------------------------------------------------------------
+TInt CCrBerSet::AppendBerEncodedObject(const TDesC8& aString)
+ {
+ TInt err = KErrNone;
+
+ err = iTarget->Write(aString); // write buffer to file
+
+ return err;
+ }
+
+
+// -----------------------------------------------------------------------------
+// CCrBerSet::CreateBoolL
+// Function creates Ber encoded boolean object (CCrBer object).
+// Write a object to CCrData (file) by Flush(..)
+// Parameters: Value of the object
+// Return Values: None
+// -----------------------------------------------------------------------------
+EXPORT_C TAny CCrBerSet::CreateBoolL(TBool aValue)
+ {
+ CCrBer* newObject = CCrBer::NewLC(iLevel);
+ newObject->CreateBool(aValue);
+
+ AppendL(newObject); // add to set
+
+ CleanupStack::Pop();
+ }
+
+// -----------------------------------------------------------------------------
+// CCrBerSet::CreateIntL
+// Function creates Ber encoded integer object (CCrBer object).
+// Write a object to CCrData (file) by Flush(..)
+// Parameters: Value of the object
+// Return Values: None
+// -----------------------------------------------------------------------------
+EXPORT_C TAny CCrBerSet::CreateIntL(TInt aValue)
+ {
+ CCrBer* newObject = CCrBer::NewLC(iLevel);
+ newObject->CreateInt(aValue);
+
+ AppendL(newObject); // add to set
+
+ CleanupStack::Pop();
+ }
+
+
+EXPORT_C TAny CCrBerSet::CreateLongIntL(RInteger& aValue)
+ {
+ CCrBer* newObject = CCrBer::NewLC(iLevel);
+
+ newObject->CreateLongInt(aValue);
+
+ AppendL(newObject); // add to set
+
+ CleanupStack::Pop();
+ }
+
+
+// -----------------------------------------------------------------------------
+// CCrBerSet::CreateNullL
+// Function creates Ber encoded null object (CCrBer object).
+// Write a object to CCrData (file) by Flush(..)
+// -----------------------------------------------------------------------------
+EXPORT_C TAny CCrBerSet::CreateNullL()
+ {
+ CCrBer* newObject = CCrBer::NewLC(iLevel);
+ newObject->CreateNull();
+
+ AppendL(newObject); // add to set
+
+ CleanupStack::Pop();
+ }
+
+// -----------------------------------------------------------------------------
+// CCrBerSet::CreateIA5L
+// Function creates Ber encoded IA5 string object (CCrBer object).
+// Write a object to CCrData by Flush(..)
+// Parameters: IA5 string
+// -----------------------------------------------------------------------------
+EXPORT_C TAny CCrBerSet::CreateIA5L(TDesC8& aString)
+ {
+ CCrBer* newObject = CCrBer::NewLC(iLevel);
+ newObject->CreateString(KBerIA5S, &aString);
+
+ AppendL(newObject); // add to set
+
+ CleanupStack::Pop();
+ }
+
+
+
+// -----------------------------------------------------------------------------
+// CCrBerSet::CreateNumericL
+// Function creates Ber encoded Numeric string object (CCrBer object).
+// Write a object to CCrData (file) by Flush(..)
+// Parameters: Numeric string
+// -----------------------------------------------------------------------------
+EXPORT_C TAny CCrBerSet::CreateNumericL(TDesC8& aString)
+ {
+ CCrBer* newObject = CCrBer::NewLC(iLevel);
+ newObject->CreateString(KBerNumS, &aString);
+
+ AppendL(newObject); // add to set
+
+ CleanupStack::Pop();
+ }
+
+// -----------------------------------------------------------------------------
+// CCrBerSet::CreatePrintableL
+// Function creates Ber encoded Printable string object (CCrBer object).
+// Write a object to CCrData (file) by Flush(..)
+// Parameters: Printable string
+// -----------------------------------------------------------------------------
+EXPORT_C TAny CCrBerSet::CreatePrintableL(TDesC8& aString)
+ {
+ CCrBer* newObject = CCrBer::NewLC(iLevel);
+ newObject->CreateString(KBerPrS, &aString);
+ AppendL(newObject); // add to set
+
+ CleanupStack::Pop();
+ }
+
+// -----------------------------------------------------------------------------
+// CCrBerSet::CreateT61L
+// Function creates Ber encoded T61 string object (CCrBer object).
+// Write a object to CCrData (file) by Flush(..)
+// Parameters: T61 string (= a teletext string)
+// -----------------------------------------------------------------------------
+EXPORT_C TAny CCrBerSet::CreateT61L(TDesC8& aString)
+ {
+ CCrBer* newObject = CCrBer::NewLC(iLevel);
+ newObject->CreateString(KBerT61S, &aString);
+ AppendL(newObject); // add to set
+
+ CleanupStack::Pop();
+ }
+
+// -----------------------------------------------------------------------------
+// CCrBerSet::CreateVideoTexL
+// Function creates Ber encoded Video text object (CCrBer object).
+// Write a object to CCrData (file) by Flush(..)
+// Parameters: VideoTex string
+// -----------------------------------------------------------------------------
+EXPORT_C TAny CCrBerSet::CreateVideoTexL(TDesC8& aString)
+ {
+ CCrBer* newObject = CCrBer::NewLC(iLevel);
+ newObject->CreateString(KBerVideoS, &aString);
+ AppendL(newObject); // add to set
+
+ CleanupStack::Pop();
+ }
+
+// -----------------------------------------------------------------------------
+// CCrBerSet::CreateUTCL
+// Function creates Ber encoded UTC time object (CCrBer object).
+// Write a object to CCrData (file) by Flush(..)
+// Parameters: UTC time (string)
+// -----------------------------------------------------------------------------
+EXPORT_C TAny CCrBerSet::CreateUTCL(TDesC8& aString)
+ {
+ CCrBer* newObject = CCrBer::NewLC(iLevel);
+ newObject->CreateString(KBerUtc, &aString);
+ AppendL(newObject); // add to set
+
+ CleanupStack::Pop();
+ }
+
+// -----------------------------------------------------------------------------
+// CCrBerSet::CreateGenTimeL
+// Function creates Ber encoded generalised time object (CCrBer object).
+// Write a object to CCrData (file) by Flush(..)
+// Parameters: Generalised time (string)
+// -----------------------------------------------------------------------------
+EXPORT_C TAny CCrBerSet::CreateGenTimeL(TDesC8& aString)
+ {
+ CCrBer* newObject = CCrBer::NewLC(iLevel);
+ newObject->CreateString(KBerGenTime, &aString);
+ AppendL(newObject); // add to set
+
+ CleanupStack::Pop();
+ }
+
+// -----------------------------------------------------------------------------
+// CCrBerSet::CreateGraphicalL
+// Function creates Ber encoded graphical string object (CCrBer object).
+// Write a object to CCrData (file) by Flush(..)
+// Parameters: Graphical string
+// -----------------------------------------------------------------------------
+EXPORT_C TAny CCrBerSet::CreateGraphicalL(TDesC8& aString)
+ {
+ CCrBer* newObject = CCrBer::NewLC(iLevel);
+ newObject->CreateString(KBerGraphS, &aString);
+ AppendL(newObject); // add to set
+
+ CleanupStack::Pop();
+ }
+
+// -----------------------------------------------------------------------------
+// CCrBerSet::CreateVisibleL
+// Function creates Ber encoded visible string object (CCrBer object).
+// Write a object to CCrData (file) by Flush(..)
+// Parameters: Visible string
+// -----------------------------------------------------------------------------
+EXPORT_C TAny CCrBerSet::CreateVisibleL(TDesC8& aString)
+ {
+ CCrBer* newObject = CCrBer::NewLC(iLevel);
+ newObject->CreateString(KBerVisibleS, &aString); // save type & pointer
+ AppendL(newObject); // add to set
+
+ CleanupStack::Pop();
+ }
+
+// -----------------------------------------------------------------------------
+// CCrBerSet::CreateGeneralL
+// Function creates Ber encoded general string object (CCrBer object).
+// Write a object to CCrData (file) by Flush(..)
+// Parameters: Generalised string
+// -----------------------------------------------------------------------------
+EXPORT_C TAny CCrBerSet::CreateGeneralL(TDesC8& aString)
+ {
+ CCrBer* newObject = CCrBer::NewLC(iLevel);
+ newObject->CreateString(KBerGeneralS, &aString); // save type & pointer
+ AppendL(newObject); // add to set
+ CleanupStack::Pop();
+ }
+
+// -----------------------------------------------------------------------------
+// CCrBerSet::CreateOctetL
+// Function creates Ber encoded octet string object (CCrBer object).
+// Write a object to CCrData (file) by Flush(..)
+// Parameters: Octet string
+// -----------------------------------------------------------------------------
+EXPORT_C TAny CCrBerSet::CreateOctetL(TDesC8& aString)
+ {
+ CCrBer* newObject = CCrBer::NewLC(iLevel);
+ newObject->CreateString(KBerOctetString, &aString); // save type & pointer
+ AppendL(newObject); // add to set
+
+ CleanupStack::Pop();
+ }
+
+// -----------------------------------------------------------------------------
+// CCrBerSet::CreateOctetL
+// Function creates Ber encoded octet string object (CCrBer object).
+// Write a object to CCrData (file) by Flush(..)
+// Parameters: CCrData*
+// -----------------------------------------------------------------------------
+EXPORT_C TAny CCrBerSet::CreateOctetL(CCrData* aData)
+ {
+ CCrBer* newObject = CCrBer::NewLC(iLevel);
+ newObject->CreateString(KBerOctetString, aData); // save type & pointer
+ AppendL(newObject); // add to set
+
+ CleanupStack::Pop();
+ }
+
+// -----------------------------------------------------------------------------
+// CCrBerSet::CreateOIdL
+// Function creates Ber encoded object identifier object (CCrBer object).
+// Write a object to CCrData (file) by Flush(..)
+// Parameters: object identifier content e.g.(_L8("1.2.3.4445"))
+// -----------------------------------------------------------------------------
+EXPORT_C TAny CCrBerSet::CreateOIdL(TDesC8& aString)
+ {
+ CCrBer* newObject = CCrBer::NewLC(iLevel);
+ newObject->CreateOIdL(&aString); // save type and pointer to data
+
+ AppendL(newObject); // add to set
+
+ CleanupStack::Pop();
+ }
+
+// -----------------------------------------------------------------------------
+// CCrBerSet::CreateSeqStartL
+// Function creates start of sequence (0x30). End this by EndL().
+// Parameters: True for definite length sequence, false for indefinite
+// length
+// -----------------------------------------------------------------------------
+EXPORT_C TAny CCrBerSet::CreateSeqStartL(TBool aDefinite)
+ {
+ CCrBer* newObject = CCrBer::NewLC(++iLevel);
+ newObject->CreateStart(KBerSeq, aDefinite);
+
+ if (iLevel > iMaxLevel)
+ {
+ iMaxLevel = iLevel; // iMaxLevel is used in Flush(..)
+ }
+
+ AppendL(newObject); // add to set
+
+ CleanupStack::Pop();
+ }
+
+
+
+// -----------------------------------------------------------------------------
+// CCrBerSet::CreateSetStartL
+// Start set (31 xx) object. End this set by EndL().
+// Parameters: Parameter is true for definite length, false for
+// indefinite length.
+// -----------------------------------------------------------------------------
+EXPORT_C TAny CCrBerSet::CreateSetStartL(TBool aDefinite)
+ {
+ CCrBer* newObject = CCrBer::NewLC(++iLevel);
+ newObject->CreateStart(KBerSet, aDefinite);
+
+ if (iLevel > iMaxLevel)
+ {
+ iMaxLevel = iLevel; // iMaxLevel is used in Flush(..)
+ }
+
+ AppendL(newObject); // add to set
+
+ CleanupStack::Pop();
+ }
+
+// -----------------------------------------------------------------------------
+// CCrBerSet::CreateConstructedStartL
+// Function creates start of constructed type object. End this by EndL().
+// Parameters: First parameter is object type (tag), Second parameter is
+// true for definite length, false for indefinite length.
+// -----------------------------------------------------------------------------
+EXPORT_C TAny CCrBerSet::CreateConstructedStartL(TBerTag aTag, TBool aDefinite)
+ {
+ CCrBer* newObject = CCrBer::NewLC(++iLevel);
+ if (aTag < KBerConstructed)
+ {
+ aTag += KBerConstructedBit; // e.g. 0x04 --> 0x24
+ }
+
+ newObject->CreateStart(aTag, aDefinite);
+
+ if (iLevel > iMaxLevel)
+ {
+ iMaxLevel = iLevel; // iMaxLevel is used in Flush(..)
+ }
+ AppendL(newObject); // add to set
+ CleanupStack::Pop();
+ }
+
+
+
+// -----------------------------------------------------------------------------
+// CCrBerSet::CreateEndL
+// Function close last constructed (e.g. seq) object.
+// (definite or indefinite).
+// -----------------------------------------------------------------------------
+EXPORT_C TAny CCrBerSet::CreateEndL()
+ {
+ CCrBer* newObject = CCrBer::NewLC(iLevel--);
+ newObject->CreateEnd();
+
+ AppendL(newObject); // add to set
+ CleanupStack::Pop();
+ }
+
+// -----------------------------------------------------------------------------
+// CCrBerSet::CreateBEREncodedObjectL
+// This fuction can be used to create a BER object
+// from buffer, which already contains a full BER
+// encoded object.
+// Parameters: Buffer containing BER encoded object.
+// -----------------------------------------------------------------------------
+EXPORT_C TAny CCrBerSet::CreateBEREncodedObjectL(TDesC8& aString)
+ {
+ CCrBer* newObject = CCrBer::NewLC(iLevel);
+ newObject->CreateBEREncodedObject(&aString); // save pointer
+ AppendL(newObject); // add to set
+ CleanupStack::Pop(); // newObject
+ }
+
+// -----------------------------------------------------------------------------
+// CCrBerSet::Flush
+// Function writes all created crber objects (which are AppendL to set)
+// to file. Function also set length for definite lengths.
+// Call this function then crberSet is ready (all berObjects are given).
+// Parameters: Reference to target CCrData (file)
+// Return Values: Number of written objects or error code.
+// -----------------------------------------------------------------------------
+EXPORT_C TInt CCrBerSet::FlushL(CCrData* aTarget)
+ {
+ TInt index = 0;
+ TInt i = 0;
+ TUint level = 0;
+ TUint8 type = 0;
+ TInt err = KErrNone;
+ CCrBer* berObject = NULL;
+ CCrBer* newObject = NULL;
+ TInt size = Count(); // number of the ber-objects
+
+ iTarget = aTarget;
+
+ if (iLevel || !size) // end count != start count
+ { // or if no CrBer objects
+ return KErrArgument;
+ }
+
+ // Set definite lengths
+ for (level = iMaxLevel; level > 0; level--) // check levels (except 0)
+ {
+ for (index = 0 ; index < size ; index++) // all objects
+ {
+ berObject = At(index);
+
+ if ((berObject->Type() >= KBerConstructed) && // Constructed
+ (!berObject->ObjectLen()) && // definite len
+ (berObject->Level() == level)) // same level
+ {
+ for (i = index + 1; i < size; i++)
+ {
+ newObject = At(i);
+
+ if ((newObject->Type() == KBerEndOfContent) &&
+ (newObject->Level() == berObject->Level()) &&
+ (newObject->Value() >= 0))
+ {
+ berObject->SetObjLenWithOutContent(
+ berObject->ContentLen());
+ newObject->SetValue(-1); // this end is now used
+ i = size; // end found, go away
+ }
+ else
+ {
+ berObject->AddToContentLen(newObject->ObjectLen());
+ }
+ }
+ }
+ }
+ }
+
+
+ // Write objects to file
+ for (index = 0; index < size; index++)
+ {
+ berObject = At(index);
+ type = berObject->Type();
+
+ if (type > KBerConstructed && type != KBerEncodedObject )
+ {
+ type = KBerConstructed;
+ }
+
+ switch (type)
+ {
+ case KBerBoolean:
+ {
+ err += AppendBoolL(berObject->Value());
+ break;
+ }
+ case KBerInteger:
+ {
+ if (!berObject->Value() && (berObject->GetBigInt() != NULL))
+ {
+ RInteger integer = berObject->GetBigInt();
+ err += AppendLongIntL(integer);
+ }
+ else
+ {
+ err += AppendIntL(berObject->Value());
+ }
+ break;
+ }
+ case KBerNull:
+ {
+ err += AppendNull();
+ break;
+ }
+ case KBerOid:
+ {
+ err += AppendObjectIdL(*berObject->ValuePtr());
+ break;
+ }
+ case KBerBitString:
+ case KBerOctetString:
+ case KBerNumS:
+ case KBerPrS:
+ case KBerT61S:
+ case KBerVideoS:
+ case KBerIA5S:
+ case KBerUtc:
+ case KBerGenTime:
+ case KBerGraphS:
+ case KBerVisibleS:
+ case KBerGeneralS:
+ {
+ CCrData* tempData = berObject->Data();
+ if (tempData != NULL)
+ {
+ err += AppendStringL((berObject->Type()),
+ (berObject->Data()));
+ }
+ else
+ {
+ err += AppendStringL((berObject->Type()),
+ (*berObject->ValuePtr()));
+ }
+ break;
+ }
+ case KBerSeq:
+ case KBerSet:
+ case KBerConstructed:
+ {
+ err += AppendConstructedL((berObject->Type()),
+ (berObject->ContentLen()));
+ break;
+ }
+ case KBerEncodedObject:
+ {
+ err += AppendBerEncodedObject(
+ (*berObject->ValuePtr()));
+ break;
+ }
+ case KBerEndOfContent:
+ {
+ if (!berObject->Value()) // Indefinite len
+ {
+ err += CloseIndefinite();
+ }
+ break;
+ }
+ }
+ }
+ if (err < KErrNone)
+ {
+ return KErrGeneral;
+ }
+ else
+ {
+ return size;
+ }
+ }