--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/connectivitymodules/SeCon/services/csc/src/caputils.cpp Tue Aug 31 15:05:37 2010 +0300
@@ -0,0 +1,730 @@
+/*
+* Copyright (c) 2005-2009 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: CapUtil implementation
+*
+*/
+
+
+// INCLUDE FILES
+
+#include <pathinfo.h>
+#include <sysutil.h>
+#include <hal.h>
+#include <hal_data.h>
+#include <etelmm.h> // for etel
+#include <mmtsy_names.h> // for etel
+#include <utf.h>
+#include <eikenv.h>
+#include <driveinfo.h>
+#include <centralrepository.h>
+#include <sysutildomaincrkeys.h>
+
+#include "caputils.h"
+#include "capability.h"
+#include "debug.h"
+
+const TInt KPackageSize = 65536;
+const TInt KDefaultArrayGranularity = 5;
+// ============================= MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CapUtil::GetDefaultRootPathL( RFs& aFs, TDes& aRootPath )
+// Gets default root path
+// -----------------------------------------------------------------------------
+//
+void CapUtil::GetDefaultRootPathL( RFs& aFs, TDes& aRootPath )
+ {
+ TRACE_FUNC_ENTRY;
+ // Use the default mass storage if it is internal drive
+ TInt msDrive;
+ User::LeaveIfError( DriveInfo::GetDefaultDrive( DriveInfo::EDefaultMassStorage, msDrive ) );
+ LOGGER_WRITE_1("drive: %d", msDrive);
+
+ TUint msStatus( 0 );
+ TInt err = DriveInfo::GetDriveStatus( aFs, msDrive, msStatus );
+ LOGGER_WRITE_1("DriveInfo::GetDriveStatus err: %d", err);
+
+ // if no errors, also check drive status
+ if( !err && !( msStatus & DriveInfo::EDrivePresent )
+ || msStatus & DriveInfo::EDriveCorrupt )
+ {
+ LOGGER_WRITE( "Internal mass storage not present or corrupted" );
+ err = KErrNotFound;
+ }
+
+ if ( !err && ( msStatus & DriveInfo::EDriveInternal ) )
+ {
+ // Use internal mass storage
+ LOGGER_WRITE( "Use internal mass storage" );
+ User::LeaveIfError( PathInfo::GetRootPath( aRootPath, msDrive ) );
+ }
+ else
+ {
+ // Use phone memory
+ LOGGER_WRITE( "Use phone memory" );
+ StrCopy( aRootPath, PathInfo::PhoneMemoryRootPath() );
+ }
+ LOGGER_WRITE_1( "rootPath: %S", &aRootPath );
+ TRACE_FUNC_EXIT;
+ }
+
+// -----------------------------------------------------------------------------
+// CapUtil::GetMemoryType( RFs& aFs, TDes& aMemoryType, const TInt aDrive )
+// Gets drive memory type
+// -----------------------------------------------------------------------------
+//
+void CapUtil::GetMemoryType( RFs& aFs, TDes& aMemoryType, const TInt aDrive )
+ {
+ TRACE_FUNC_ENTRY;
+ LOGGER_WRITE_1("aDrive: %d", aDrive);
+ aMemoryType = KNullDesC;
+ TUint driveStatus;
+ TInt err = DriveInfo::GetDriveStatus( aFs, aDrive, driveStatus );
+ if( err )
+ {
+ LOGGER_WRITE_1( "CapUtil::GetMemoryType() : DriveInfo::GetDriveStatus err: %d", err );
+ return;
+ }
+ // search internal or removable drives
+ TBool searchInternalDrives;
+ if( driveStatus & DriveInfo::EDriveInternal )
+ {
+ aMemoryType = KMediaFlash;
+ searchInternalDrives = ETrue;
+ }
+ else
+ {
+ aMemoryType = KMediaMMC;
+ searchInternalDrives = EFalse;
+ }
+
+ TInt typeNumber(0);
+ TInt driveCount;
+ TDriveList driveList;
+
+ err = DriveInfo::GetUserVisibleDrives( aFs, driveList, driveCount );
+ if( err )
+ {
+ LOGGER_WRITE_1( "CapUtil::GetMemoryType() : DriveInfo::GetUserVisibleDrives err: %d", err );
+ return;
+ }
+
+ for( TInt i = EDriveA; i <= aDrive; i++ )
+ {
+ if( driveList[i] )
+ {
+ TUint driveStatus;
+ err = DriveInfo::GetDriveStatus( aFs, i, driveStatus );
+ if( err )
+ {
+ LOGGER_WRITE_1( "CapUtil::GetMemoryType() : DriveInfo::GetDriveStatus err: %d", err );
+ continue;
+ }
+
+ if( !(driveStatus & DriveInfo::EDrivePresent )
+ || driveStatus & DriveInfo::EDriveCorrupt )
+ {
+ LOGGER_WRITE( "not present or corrupted" );
+ continue;
+ }
+
+ if( driveStatus & DriveInfo::EDriveInternal )
+ {
+ if( searchInternalDrives )
+ {
+ typeNumber++;
+ }
+ }
+ else if( driveStatus & DriveInfo::EDriveRemovable )
+ {
+ if( !searchInternalDrives )
+ {
+ typeNumber++;
+ }
+ }
+ }
+ }
+
+ if( typeNumber > 1 )
+ {
+ aMemoryType.AppendNum( typeNumber );
+ }
+ TRACE_FUNC_EXIT;
+ }
+
+// -----------------------------------------------------------------------------
+// CapUtil::GetOperatornameL(TDes& aLongName, TDes& aCountryCode, TDes& aNetworkID)
+// Gets phone operator name, country code, networkID.
+// -----------------------------------------------------------------------------
+//
+void CapUtil::GetOperatorNameL(TDes& aLongName, TDes& aCountryCode, TDes& aNetworkID)
+ {
+ TRACE_FUNC_ENTRY;
+ TUint32 networkCaps;
+ RTelServer::TPhoneInfo phoneInfo;
+
+ RTelServer server;
+ RMobilePhone mobilePhone;
+ User::LeaveIfError( server.Connect() );
+ CleanupClosePushL( server );
+
+ TInt numPhones;
+ User::LeaveIfError( server.EnumeratePhones( numPhones ) );
+ server.GetPhoneInfo( 0, phoneInfo );
+
+ User::LeaveIfError( mobilePhone.Open( server, phoneInfo.iName ) );
+ CleanupClosePushL( mobilePhone );
+ User::LeaveIfError( mobilePhone.GetNetworkCaps( networkCaps ) );
+
+ RMobilePhone::TMobilePhoneNetworkInfoV1 mobilePhoneNetworkInfo;
+ RMobilePhone::TMobilePhoneNetworkInfoV1Pckg mobilePhoneNetworkInfoPckg(
+ mobilePhoneNetworkInfo );
+ RMobilePhone::TMobilePhoneLocationAreaV1 mobilePhoneLocationArea;
+
+ if (networkCaps & RMobilePhone::KCapsGetCurrentNetwork)
+ {
+ TRequestStatus status;
+ mobilePhone.GetCurrentNetwork(
+ status, mobilePhoneNetworkInfoPckg, mobilePhoneLocationArea );
+ User::WaitForRequest( status );
+ User::LeaveIfError( status.Int() );
+ }
+
+ CleanupStack::PopAndDestroy( &mobilePhone );
+ CleanupStack::PopAndDestroy( &server );
+ if ( mobilePhoneNetworkInfo.iLongName.Length() > 0 )
+ {
+ StrCopy( aLongName, mobilePhoneNetworkInfo.iLongName );
+ }
+ else if ( mobilePhoneNetworkInfo.iShortName.Length() > 0 )
+ {
+ StrCopy( aLongName, mobilePhoneNetworkInfo.iShortName );
+ }
+ else
+ {
+ StrCopy( aLongName, mobilePhoneNetworkInfo.iDisplayTag );
+ }
+ StrCopy( aCountryCode, mobilePhoneNetworkInfo.iCountryCode );
+ StrCopy( aNetworkID, mobilePhoneNetworkInfo.iNetworkId );
+
+ TRACE_FUNC_EXIT;
+ }
+// -----------------------------------------------------------------------------
+// CapUtil::GetManufacturer(TDes& aText)
+// Gets phone manufacturer from HAL. In case manufacturer is not known,
+// -----------------------------------------------------------------------------
+//
+void CapUtil::GetManufacturer(TDes& aText)
+ {
+ TRACE_FUNC_ENTRY;
+ TInt num(KErrNotFound);
+
+ HAL::Get(HALData::EManufacturer, num);
+
+ switch (num)
+ {
+ case HALData::EManufacturer_Ericsson:
+ aText=KManufacturerEricsson;
+ break;
+ case HALData::EManufacturer_Motorola:
+ aText=KManufacturerMotorola;
+ break;
+ case HALData::EManufacturer_Nokia:
+ aText=KManufacturerNokia;
+ break;
+ case HALData::EManufacturer_Panasonic:
+ aText=KManufacturerPanasonic;
+ break;
+ case HALData::EManufacturer_Psion:
+ aText=KManufacturerPsion;
+ break;
+ case HALData::EManufacturer_Intel:
+ aText=KManufacturerIntel;
+ break;
+ case HALData::EManufacturer_Cogent:
+ aText=KManufacturerCogent;
+ break;
+ case HALData::EManufacturer_Cirrus:
+ aText=KManufacturerCirrus;
+ break;
+ case HALData::EManufacturer_Linkup:
+ aText=KManufacturerLinkup;
+ break;
+ case HALData::EManufacturer_TexasInstruments:
+ aText=KManufacturerTexasInstruments;
+ break;
+ default:
+ aText=KNullDesC;
+ break;
+ }
+
+ TRACE_FUNC_EXIT;
+ }
+
+// -----------------------------------------------------------------------------
+// CapUtil::GetLanguage(TDes& aText)
+// Gets language
+// -----------------------------------------------------------------------------
+//
+void CapUtil::GetLanguage(TDes& aText)
+ {
+ TRACE_FUNC_ENTRY;
+ TLanguage lang=User::Language();
+ GetLanguageString(lang, aText);
+ TRACE_FUNC_EXIT;
+ }
+
+// -----------------------------------------------------------------------------
+// CapUtil::GetSWVersionL(TDes& aVersion, TDes& aDate, TDes& aModel)
+// Gets SW version, SW version date and device model from SysUtil.
+// -----------------------------------------------------------------------------
+//
+void CapUtil::GetSWVersionL(TDes& aVersion, TDes& aDate, TDes& aModel)
+ {
+ TRACE_FUNC_ENTRY;
+ TBuf<KBufSize> buf;
+ aVersion=KNullDesC;
+ aDate=KNullDesC;
+ aModel=KNullDesC;
+
+ User::LeaveIfError( SysUtil::GetSWVersion( buf ) );
+ RArray<TPtrC> arr(KDefaultArrayGranularity);
+ CleanupClosePushL( arr );
+
+ CapUtil::SplitL(buf, '\n', arr);
+ const TInt KFieldsToFind = 3;
+ if ( arr.Count() < KFieldsToFind )
+ {
+ User::Leave( KErrNotFound );
+ }
+
+ StrCopy( aVersion, arr[0] );
+ aVersion.Trim();
+
+ StrCopy(aModel,arr[2]);
+ aModel.Trim();
+
+ TBuf<KTagSize> date;
+ StrCopy(date, arr[1]);
+ TTime t;
+ t.UniversalTime(); // this is to avoid warnings
+ TRAPD( err, t = ParseDateL( date ) );
+ if ( err == KErrNone )
+ {
+ CapabilityDate( aDate, t );
+ }
+
+ CleanupStack::PopAndDestroy( &arr );
+
+ TRACE_FUNC_EXIT;
+ }
+
+// -----------------------------------------------------------------------------
+// CapUtil::InitMemoryInfo(TMemoryInfo& aInfo)
+// Initializes TMemoryInfo.
+// -----------------------------------------------------------------------------
+//
+void CapUtil::InitMemoryInfo(TMemoryInfo& aInfo)
+ {
+ aInfo.iDriveNum = KErrNotFound;
+ aInfo.iDriveLetter = KNoChar;
+ aInfo.iLocation = KNullDesC;
+ aInfo.iFree = KErrNotFound;
+ aInfo.iUsed = KErrNotFound;
+ aInfo.iShared = EFalse;
+ aInfo.iFileSize = KErrNotFound;
+ aInfo.iFolderSize = KErrNotFound;
+ aInfo.iFileNameSize = KMaxFileName; // TFileName 256
+ aInfo.iFolderNameSize = KMaxFileName; // TFileName 256
+ aInfo.iCaseSensitivity = EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// CapUtil::GetMemoryInfoL( const RFs& aFs, TInt aDriveNumber, TMemoryInfo& aInfo )
+// Get memory information for one drive.
+// -----------------------------------------------------------------------------
+//
+void CapUtil::GetMemoryInfoL( const RFs& aFs, const TInt aDriveNumber, TMemoryInfo& aInfo )
+ {
+ TRACE_FUNC_ENTRY;
+ LOGGER_WRITE_1(" aDriveNumber: %d", aDriveNumber);
+
+ TVolumeInfo volumeInfo;
+ TDriveInfo driveInfo;
+
+ InitMemoryInfo( aInfo );
+
+ User::LeaveIfError( aFs.Drive(driveInfo, aDriveNumber) );
+ if ( driveInfo.iDriveAtt == (TUint)KDriveAbsent )
+ {
+ LOGGER_WRITE(" iDriveAtt == (TUint)KDriveAbsent, Leave KErrNotFound");
+ User::Leave( KErrNotFound );
+ }
+
+ User::LeaveIfError( aFs.Volume(volumeInfo, aDriveNumber) );
+
+ User::LeaveIfError( aFs.DriveToChar(aDriveNumber, aInfo.iDriveLetter) );
+ aInfo.iDriveNum = aDriveNumber;
+ aInfo.iLocation.Append( aInfo.iDriveLetter );
+ aInfo.iLocation.Append( KDriveDelimiter );
+ aInfo.iLocation.Append( KPathDelimiter );
+ aInfo.iFree = volumeInfo.iFree;
+ aInfo.iUsed = volumeInfo.iSize - volumeInfo.iFree;
+
+ // set free memory up to critical level for all drives
+ CRepository* repository = CRepository::NewLC( KCRUidDiskLevel );
+ TInt criticalLevel(0);
+ User::LeaveIfError( repository->Get( KDiskCriticalThreshold, criticalLevel ) );
+ CleanupStack::PopAndDestroy( repository );
+ criticalLevel += KPackageSize; // add obex package size to critical level
+ LOGGER_WRITE_1( "CapUtil::GetMemoryInfoL() criticalLevel: %d", criticalLevel ) ;
+ if ( aInfo.iFree > criticalLevel )
+ {
+ aInfo.iFree = aInfo.iFree - criticalLevel;
+ }
+ else
+ {
+ aInfo.iFree = 0;
+ }
+
+ aInfo.iFileSize = aInfo.iFree;
+ aInfo.iFolderSize = aInfo.iFree;
+ TRACE_FUNC_EXIT;
+ }
+
+// -----------------------------------------------------------------------------
+// CapUtil::GetFileListL( RFs& aFs, const TDesC& aDir,
+// RArray<TFileName>& aList)
+// Finds all files in aDir.
+// -----------------------------------------------------------------------------
+//
+void CapUtil::GetFileListL( const RFs& aFs, const TDesC& aDir,
+ RArray<TFileName>& aList)
+ {
+ TRACE_FUNC_ENTRY;
+
+ aList.Reset();
+
+ CDir* dir( NULL );
+ User::LeaveIfError( aFs.GetDir( aDir, KEntryAttMatchMask, ESortByName, dir ) );
+ CleanupStack::PushL( dir );
+
+ for ( TInt i=0; i < dir->Count(); ++i )
+ {
+ TEntry entry = (*dir)[i];
+ if ( !entry.IsDir() )
+ {
+ User::LeaveIfError( aList.Append( entry.iName ) );
+ }
+ }
+ CleanupStack::PopAndDestroy( dir );
+ TRACE_FUNC_EXIT;
+ }
+
+// -----------------------------------------------------------------------------
+// CapUtil::CheckFileType(const TDesC& aFile, const TDesC& aExt)
+// Function checks file extension.
+// -----------------------------------------------------------------------------
+//
+TBool CapUtil::CheckFileType(const TDesC& aFile, const TDesC& aExt)
+ {
+ TRACE_FUNC_ENTRY;
+ TParse parse;
+ parse.Set(aFile, NULL, NULL);
+ TPtrC ptr=parse.Ext();
+
+ TBuf<KTagSize> buf1;
+ TBuf<KTagSize> buf2;
+
+ buf1=ptr;
+ buf2=aExt;
+
+ buf1.LowerCase();
+ buf2.LowerCase();
+
+ if (buf1.Compare(buf2)==0)
+ {
+ LOGGER_WRITE( "CapUtil::CheckFileType(const TDesC& aFile, const TDesC& aExt) : returned ETrue" );
+ return ETrue;
+ }
+
+ else
+ {
+ LOGGER_WRITE( "CapUtil::CheckFileType(const TDesC& aFile, const TDesC& aExt) : returned EFalse" );
+ return EFalse;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CapUtil::GetLanguageString(TLanguage aId, TDes& aText)
+// Get language string for aId.
+// -----------------------------------------------------------------------------
+//
+void CapUtil::GetLanguageString(TLanguage aId, TDes& aText)
+ {
+ TRACE_FUNC_ENTRY;
+ aText=KNullDesC;
+
+ TInt count=NUMLANGSTRINGS;
+ for (TInt i=0; i<count; i++)
+ {
+ TLangStringStruct t=KLangStrings[i];
+ if (t.id == (TInt)aId)
+ {
+ aText=t.lang;
+ return;
+ }
+ }
+ TRACE_FUNC_EXIT;
+ }
+
+// -----------------------------------------------------------------------------
+// CapUtil::Panic(TInt aReason)
+// Panic.
+// -----------------------------------------------------------------------------
+//
+#ifdef _DEBUG
+void CapUtil::Panic(TInt aReason)
+#else
+void CapUtil::Panic(TInt /*aReason*/)
+#endif
+ {
+ TRACE_FUNC_ENTRY;
+#ifdef _DEBUG
+ _LIT(KPanicCategory,"CapabilitySC");
+
+ User::Panic(KPanicCategory, aReason);
+#endif
+ TRACE_FUNC_EXIT;
+ }
+
+// -----------------------------------------------------------------------------
+// CapUtil::StrCopy(TDes& aTarget, const TDesC& aSource)
+// String copy with lenght check.
+// -----------------------------------------------------------------------------
+//
+void CapUtil::StrCopy(TDes& aTarget, const TDesC& aSource)
+ {
+ TInt len=aTarget.MaxLength();
+ if(len<aSource.Length())
+ {
+ aTarget.Copy(aSource.Left(len));
+ return;
+ }
+ aTarget.Copy(aSource);
+ }
+
+// -----------------------------------------------------------------------------
+// CapUtil::IntToStr(TDes& aText, TInt64 aNum)
+// Function converts ínteger to string.
+// -----------------------------------------------------------------------------
+//
+void CapUtil::IntToStr(TDes& aText, TInt64 aNum)
+ {
+ aText.Num(aNum);
+ }
+
+// -----------------------------------------------------------------------------
+// CapUtil::StrToInt(const TDesC& aText, TInt& aNum)
+// Function converts string to integer. If string cannot be converted,
+// error code is returned.
+// -----------------------------------------------------------------------------
+//
+TInt CapUtil::StrToInt(const TDesC& aText, TInt& aNum)
+ {
+ TLex lex(aText);
+
+ TInt err=lex.Val(aNum);
+ return err;
+ }
+
+// -----------------------------------------------------------------------------
+// CapUtil::SplitL(const TDesC& aText, const TChar aSeparator,
+// RArray<TPtrC>& aArray)
+// Function splits string (eg "name1, name2, name3") into substrings.
+// -----------------------------------------------------------------------------
+//
+void CapUtil::SplitL(const TDesC& aText, const TChar aSeparator,
+ RArray<TPtrC>& aArray)
+ {
+ TRACE_FUNC_ENTRY;
+ TPtrC ptr;
+ ptr.Set(aText);
+
+ for (;;)
+ {
+ TInt pos=ptr.Locate(aSeparator);
+ if (pos==KErrNotFound)
+ {
+ aArray.AppendL(ptr);
+ break;
+ }
+
+ TPtrC subStr=ptr.Left(pos); // get pos characters starting from position 0
+ aArray.AppendL(subStr);
+
+ if (!(ptr.Length()>pos+1))
+ {
+ break;
+ }
+
+ ptr.Set(ptr.Mid(pos+1));// get all characters starting from position pos+1
+ }
+ TRACE_FUNC_EXIT;
+ }
+
+// -----------------------------------------------------------------------------
+// CapUtil::ParseDateL(const TDesC& aText)
+// Function parses date string of the format "dd-mm-yy".
+// -----------------------------------------------------------------------------
+//
+TTime CapUtil::ParseDateL(const TDesC& aText)
+ {
+ TRACE_FUNC_ENTRY;
+ RArray<TPtrC> arr(KDefaultArrayGranularity);
+ CleanupClosePushL( arr );
+
+ CapUtil::SplitL( aText, '-', arr );
+ if ( arr.Count() != 3 )
+ {
+ User::Leave( KErrNotSupported );
+ }
+
+ TInt day;
+ TInt month;
+ TInt year;
+
+ User::LeaveIfError( StrToInt(arr[0], day) );
+ User::LeaveIfError( StrToInt(arr[1], month) );
+ User::LeaveIfError( StrToInt(arr[2], year) );
+
+ TDateTime td;
+ TMonth month2 = Month( month );
+ // if year is defined as two digit, add currect millenium for it
+ const TInt KDefaultMillenium = 2000;
+ if ( year < KDefaultMillenium )
+ {
+ year = year + KDefaultMillenium;
+ }
+
+
+ User::LeaveIfError( td.Set(year, month2, day-1, 0, 0, 0, 0) );
+
+ CleanupStack::PopAndDestroy( &arr );
+
+ TTime t(td);
+ TRACE_FUNC_EXIT;
+ return t;
+}
+
+// -----------------------------------------------------------------------------
+// CapUtil::Month(TInt aNum)
+// Function return TMonth presentation of integer
+// -----------------------------------------------------------------------------
+//
+TMonth CapUtil::Month(TInt aNum)
+ {
+ TRACE_FUNC_ENTRY;
+ __ASSERT_DEBUG(aNum>=1 && aNum<=12, Panic(KErrArgument));
+
+ switch (aNum)
+ {
+ case 1: return EJanuary;
+ case 2: return EFebruary;
+ case 3: return EMarch;
+ case 4: return EApril;
+ case 5: return EMay;
+ case 6: return EJune;
+ case 7: return EJuly;
+ case 8: return EAugust;
+ case 9: return ESeptember;
+ case 10: return EOctober;
+ case 11: return ENovember;
+ case 12: return EDecember;
+ default: return EJanuary;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CapUtil::CapabilityDate(TDes& aText, const TTime aTime)
+// Constructs capability date as string
+// -----------------------------------------------------------------------------
+//
+void CapUtil::CapabilityDate(TDes& aText, const TTime aTime)
+ {
+ TRACE_FUNC_ENTRY;
+ _LIT(KFormat,"%04d%02d%02dT%02d%02d%02dZ");
+
+ TDateTime dt=aTime.DateTime();
+ aText.Format(KFormat, dt.Year(), dt.Month()+1, dt.Day()+1, dt.Hour(),
+ dt.Minute(), dt.Second());
+ TRACE_FUNC_EXIT;
+ }
+
+// -----------------------------------------------------------------------------
+// TIdStack::Pop()
+// Pop id from the stack
+// -----------------------------------------------------------------------------
+//
+TInt TIdStack::Pop()
+ {
+ if (iPos<0)
+ {
+ LOGGER_WRITE( "TIdStack::Pop() returned KErrNotFound" );
+ return KErrNotFound;
+ }
+
+ TInt id=iArray[iPos];
+ iPos--;
+ return id;
+ }
+
+// -----------------------------------------------------------------------------
+// TIdStack::Push( TInt aId )
+// Push id to the stack
+// -----------------------------------------------------------------------------
+//
+void TIdStack::Push( TInt aId )
+ {
+ if ( Size() >= KNestingLimit )
+ {
+ return;
+ }
+
+ iPos++;
+ iArray[iPos] = aId;
+ }
+
+// -----------------------------------------------------------------------------
+// TIdStack::Size() const
+// Size of the stack
+// -----------------------------------------------------------------------------
+//
+TInt TIdStack::Size() const
+ {
+ return iPos+1;
+ }
+
+// -----------------------------------------------------------------------------
+// TIdStack::Reset()
+// Reset the stack.
+// -----------------------------------------------------------------------------
+//
+void TIdStack::Reset()
+ {
+ iArray.Reset();
+ iPos=-1;
+ }
+
+// End of file