diff -r 000000000000 -r 08ec8eefde2f persistentstorage/dbms/security/SC_TextIn.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/persistentstorage/dbms/security/SC_TextIn.cpp Fri Jan 22 11:06:30 2010 +0200 @@ -0,0 +1,840 @@ +// Copyright (c) 2004-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: +// CPDTextLoader class +// +// + +#define __INCLUDE_CAPABILITY_NAMES__ +#define __REFERENCE_CAPABILITY_NAMES__ +#include "e32capability.h" + +#include "SC_Strings.h" +#include "SC_TextIn.h" + +namespace DBSC +{ + +/** +Max capability count, when SID or VID used. +@internalComponent +*/ +const TInt KMaxCapabilityCount1 = 3; + +/** +Max capability count, when no SID and no VID are used. +@internalComponent +*/ +const TInt KMaxCapabilityCount2 = 7; + +static TInt CompareCapabilities(const TCapability& aLeft, const TCapability& aRight) + { + return aRight - aLeft; + } + +/** +TStmtProps describes an object representing text file statement type and value +(the right side of "=" expression) +@internalComponent +*/ +struct TStmtProps + { + inline TStmtProps() : + iType(EStmtTEof), + iValue(NULL, 0) + { + } + TStmtType iType; + TPtrC iValue; + }; + +/** +StmtType2Class() function returns the statement class of the supplied statement type parameter. +@param aType Statement type. +@return Statement class. +@internalComponent +*/ +static TStmtClass StmtType2Class(TStmtType aType) + { + switch(aType) + { + case EStmtTComment: + case EStmtTBlank: + return EStmtCNoData; + case EStmtTDatabase: + case EStmtTTable: + return EStmtCPolicyObj; + case EStmtTRead: + case EStmtTWrite: + case EStmtTSchema: + return EStmtCPolicyType; + case EStmtTCapability: + case EStmtTSID: + case EStmtTVID: + return EStmtCPolicyItem; + case EStmtTBackup: + return EStmtCBackup; + default: + break; + } + return EStmtCInvalid; + } + +/** +Capabilities count. +@internalComponent +*/ + +const TInt KCapabilityCount = sizeof(CapabilityNames) / sizeof(CapabilityNames[0]); + +/** +CapabilityName2Id() function searches and returns the related capability ID having +the capability name as an input parameter. +@param aName Capability name +@return Related to aName capability ID +@internalComponent +*/ +static TCapability CapabilityName2Id(const TDesC& aName) + { + const TInt KMaxCapabilityStringLen = 20; + + TBufC8 cap; + TPtr8 capPtr (cap.Des()); + + capPtr.Copy(aName); + + for(TInt i=0;i((TText8*)CapabilityNames[i]))) + return (TCapability)i; + } + return (TCapability) -1; // Return 'None' if no other capabilities are found + } + +/** +Statement keywords, which format is: + +KStmtKeywordT1 array is in 1:1 relation with KStmtT1 array, except the last KStmtT1 +member - EStmtTInvalid - it does not have a match in KStmtKeywordT1 array. +@internalComponent +*/ +const TDesC* const KStmtKeywordT1[] = + { + &KDbStr(), &KTblStr(), &KReadStr(), &KWriteStr(), &KSchemaStr(), &KBackupStr() + }; + +/** +Statements count, which format is: + +@internalComponent +*/ +const TInt KStmtT1Count = sizeof(KStmtKeywordT1) / sizeof(KStmtKeywordT1[0]); + +/** +Statement IDs, which format is: + +KStmtKeywordT1 array is in 1:1 relation with KStmtT1 array, except the last KStmtT1 +member - EStmtTInvalid - it does not have a match in KStmtKeywordT1 array. +"EStmtTInvalid" always has to be the last array element. +@internalComponent +*/ +const TStmtType KStmtT1[KStmtT1Count + 1] = + { + EStmtTDatabase, EStmtTTable, EStmtTRead, EStmtTWrite, EStmtTSchema, EStmtTBackup, EStmtTInvalid + }; + +/** +StmtKeywordT1ToId() function searches and returns the related statement ID having +the statement keyword as an input parameter. +@param aKeyword Statement keyword +@return Related to aKeyword statement ID +@internalComponent +*/ +static TStmtType StmtKeywordT1ToId(const TDesC& aKeyword) + { + TInt i; + for(i=0;i= +KStmtKeywordT2 array is in 1:1 relation with KStmtT2 array, except the last KStmtT2 +member - EStmtTInvalid - it does not have a match in KStmtKeywordT2 array. +@internalComponent +*/ +const TDesC* const KStmtKeywordT2[] = + { + &KNameStr(), &KCapabilityStr(), &KSIDStr(), &KVIDStr() + }; + +/** +Statements count, which format is: += +@internalComponent +*/ +const TInt KStmtT2Count = sizeof(KStmtKeywordT2) / sizeof(KStmtKeywordT2[0]); + +/** +Statement IDs, which format is: += +KStmtKeywordT2 array is in 1:1 relation with KStmtT2 array, except the last KStmtT2 +member - EStmtTInvalid - it does not have a match in KStmtKeywordT2 array. +EStmtTInvalid always has to be the last element in KStmtT2 array. +@internalComponent +*/ +const TStmtType KStmtT2[KStmtT2Count + 1] = + { + EStmtTName, EStmtTCapability, EStmtTSID, EStmtTVID, EStmtTInvalid + }; + +/** +StmtKeywordT2ToId() function searches and returns the related statement ID having +the statement keyword as an input parameter. +@param aKeyword Statement keyword +@return Related to aKeyword statement ID +@internalComponent +*/ +static TStmtType StmtKeywordT2ToId(const TDesC& aKeyword) + { + TInt i; + for(i=0;i 0) + { + aDes.Trim(); + } + } + +/** +StmtType2PolicyType() function returns the related to aStmtType value - policy type. +@param aStmtType Statement type +@return The related policy type - R/W/S +@internalComponent +*/ +static TPolicyType StmtType2PolicyType(TStmtType aStmtType) + { + switch(aStmtType) + { + case EStmtTRead: + return EPTRead; + case EStmtTWrite: + return EPTWrite; + case EStmtTSchema: + return EPTSchema; + default: + break; + } + return EPTNone; + } + +/** +Creates TSecurityPolicy instance of type 1: SID and a set of up to 3 capabilities. +@param aSid Security ID +@param aCapabilities Capabilities array. +@param aSecurityPolicy Output. Created security policy. +@internalComponent +*/ +static void CreateSecurityPolicyT1(TSecureId aSid, const RArray& aCapabilities, + TSecurityPolicy& aSecurityPolicy) + { + TInt count = aCapabilities.Count(); + if(count == 0) + { + aSecurityPolicy = TSecurityPolicy(aSid); + } + else if(count == 1) + { + aSecurityPolicy = TSecurityPolicy(aSid, aCapabilities[0]); + } + else if(count == 2) + { + aSecurityPolicy = TSecurityPolicy(aSid, aCapabilities[0], aCapabilities[1]); + } + else if(count == 3) + { + aSecurityPolicy = TSecurityPolicy(aSid, aCapabilities[0], aCapabilities[1], aCapabilities[2]); + } + else + { + User::Invariant(); + } + } + +/** +Creates TSecurityPolicy instance of type 2: VID and a set of up to 3 capabilities. +@param aVid Vendor ID +@param aCapabilities Capabilities array. +@param aSecurityPolicy Output. Created security policy. +@internalComponent +*/ +static void CreateSecurityPolicyT2(TVendorId aVid, const RArray& aCapabilities, + TSecurityPolicy& aSecurityPolicy) + { + TInt count = aCapabilities.Count(); + if(count == 0) + { + aSecurityPolicy = TSecurityPolicy(aVid); + } + else if(count == 1) + { + aSecurityPolicy = TSecurityPolicy(aVid, aCapabilities[0]); + } + else if(count == 2) + { + aSecurityPolicy = TSecurityPolicy(aVid, aCapabilities[0], aCapabilities[1]); + } + else if(count == 3) + { + aSecurityPolicy = TSecurityPolicy(aVid, aCapabilities[0], aCapabilities[1], aCapabilities[2]); + } + else + { + User::Invariant(); + } + } + +/** +Creates TSecurityPolicy instance of type 3: A set of up to 7 capabilities. +@param aCapabilities Capabilities array. +@param aSecurityPolicy Output. Created security policy. +@internalComponent +*/ +static void CreateSecurityPolicyT3(const RArray& aCapabilities, TSecurityPolicy& aSecurityPolicy) + { + TInt count = aCapabilities.Count(); + if(count == 1) + { + aSecurityPolicy = TSecurityPolicy(aCapabilities[0]); + } + else if(count == 2) + { + aSecurityPolicy = TSecurityPolicy(aCapabilities[0], aCapabilities[1]); + } + else if(count == 3) + { + aSecurityPolicy = TSecurityPolicy(aCapabilities[0], aCapabilities[1], aCapabilities[2]); + } + else if(count == 4) + { + aSecurityPolicy = TSecurityPolicy(aCapabilities[0], aCapabilities[1], aCapabilities[2], aCapabilities[3]); + } + else if(count == 5) + { + aSecurityPolicy = TSecurityPolicy(aCapabilities[0], aCapabilities[1], aCapabilities[2], aCapabilities[3], aCapabilities[4]); + } + else if(count == 6) + { + aSecurityPolicy = TSecurityPolicy(aCapabilities[0], aCapabilities[1], aCapabilities[2], aCapabilities[3], aCapabilities[4], aCapabilities[5]); + } + else if(count == 7) + { + aSecurityPolicy = TSecurityPolicy(aCapabilities[0], aCapabilities[1], aCapabilities[2], aCapabilities[3], aCapabilities[4], aCapabilities[5], aCapabilities[6]); + } + else + { + User::Invariant(); + } + } + +/** +Creates TSecurityPolicy instance (initializing aSecurityPolicy parameter). +@param aSid Security ID +@param aVid Vendor ID +@param aCapabilities Capabilities array. +@leave KErrCorrupt Bad set of SID/VID/Capabilities +@internalComponent +*/ +static void CreateSecurityPolicyL(TSecureId aSid, TVendorId aVid, + const RArray& aCapabilities, + TSecurityPolicy& aSecurityPolicy) + { + TInt cababilityCount = aCapabilities.Count(); + if(aSid != 0 && aVid != 0) + { + __LEAVE(KErrCorrupt); + } + if(aSid != 0 || aVid != 0) + { + if(cababilityCount > KMaxCapabilityCount1) + { + __LEAVE(KErrCorrupt); + } + if(aSid != 0) + { + DBSC::CreateSecurityPolicyT1(aSid, aCapabilities, aSecurityPolicy); + } + else + { + DBSC::CreateSecurityPolicyT2(aVid, aCapabilities, aSecurityPolicy); + } + } + else if(cababilityCount > KMaxCapabilityCount2 || cababilityCount == 0) + { + __LEAVE(KErrCorrupt); + } + else + { + DBSC::CreateSecurityPolicyT3(aCapabilities, aSecurityPolicy); + } + } + +/** +*/ +inline CPDTextLoader::CPDTextLoader() + { + } + +/** +Standard phase-one factory method for CPDTextLoader instance. +CPDTextLoader instance will be used for loading a set of security policies information +from a text file, creating the related security policy objects and adding them to +a CPolicyDomain collection. +@param aFs File server session +@param aTextFileName Full text file path, which will be used as an input. +@return A pointer to just created CPDTextLoader instance. +@leave System-wide error codes, including KErrNoMemory. +*/ +CPDTextLoader* CPDTextLoader::NewLC(RFs& aFs, const TDesC& aTextFileName) + { + CPDTextLoader* self = new (ELeave) CPDTextLoader; + CleanupStack::PushL(self); + self->ConstructL(aFs, aTextFileName); + return self; + } + +/** +*/ +CPDTextLoader::~CPDTextLoader() + { + iRdStream.Close(); + } + +/** +Standard phase-two construction method for CPDTextLoader instance. +@param aFs File server session +@param aTextFileName Full text file path, which will be used as an input. +*/ +void CPDTextLoader::ConstructL(RFs& aFs, const TDesC& aTextFileName) + { + __LEAVE_IF_ERROR(iRdStream.Open(aFs, aTextFileName, EFileRead | EFileStreamText)); + } + +/** +MPolicyDomainLoader::RunL() implementation, which is used to load security policies +from a text file, create the related security policy objects and add them +to CPolicyDomain instance, controlled by aPolicyDomainBuilder object. +It is not called directly, but will be called back. +@param aPolicyDomainBuilder TPolicyDomainBuilder instance, which will be used to add + created security policy objects to the controlled by it collection. +@leave System-wide error codes +*/ +void CPDTextLoader::RunL(TPolicyDomainBuilder& aPolicyDomainBuilder) + { + TStmtProps stmtProps; + const CDbPolicy* dbPolicy = LoadDbPolicyL(aPolicyDomainBuilder, stmtProps); + __ASSERT(dbPolicy); + LoadTblPoliciesL(aPolicyDomainBuilder, stmtProps, dbPolicy); + LoadBackupSIDL(aPolicyDomainBuilder, stmtProps); + } + +/** +The method returns ETrue if this is the end of file. +@return ETrue - EOF, EFalse otherwise +*/ +TBool CPDTextLoader::IsEofL() + { + return iRdStream.Source()->TellL(MStreamBuf::ERead) >= iRdStream.Source()->SizeL(); + } + +/** +The method parses a line from the text file, detects its type and gets the right side +of "=" as a text line data descriptor. The information will be stored in aStmtProps +parameter. If the text line is not recognizable, the method leaves with KErrCorrupt. +Recognizable text line formats are: +<[keyword]> + += +<;>[comments] + +@param aStmt Current text line +@param aStmtProps The collected information will be stored there. Output parameter. +@leave KErrCorrupt - the text line has unknown format +*/ +void CPDTextLoader::GetStmtPropsL(const TDesC& aStmt, TStmtProps& aStmtProps) const + { + aStmtProps.iValue.Set(aStmt); + if(aStmt.Length() == 0) + { + aStmtProps.iType = EStmtTBlank; + return; + } + else if(aStmt[0] == ';') + { + aStmtProps.iType = EStmtTComment; + return; + } + TBool res = TryGetStmt1Props(aStmt, aStmtProps); + if(!res) + { + res = TryGetStmt2Props(aStmt, aStmtProps); + } + if(!res) + { + __LEAVE(KErrCorrupt); + } + } + +/** +Tries to process a text line as a: + +or +<[keyword]> +@param aStmt Current text line +@param aStmtProps Output parameter +@return ETrue, if it is recognizable text line. Then the method will set the text line type + in aStmtProps.iType data member. + EFalse This is not recognizable text line with or <[keyword]> format. +*/ +TBool CPDTextLoader::TryGetStmt1Props(const TDesC& aStmt, TStmtProps& aStmtProps) const + { + aStmtProps.iType = DBSC::StmtKeywordT1ToId(aStmt); + return aStmtProps.iType != EStmtTInvalid; + } + +/** +Tries to process a text line as a: += +@param aStmt Current text line +@param aStmtProps Output parameter +@return ETrue, if it is recognizable text line. Then the method will set the text line type + in aStmtProps.iType data member and the line value in aStmtProps.iValue + data member. The text will be converted to a upper case. + EFalse This is not recognizable text line with = format. +*/ +TBool CPDTextLoader::TryGetStmt2Props(const TDesC& aStmt, TStmtProps& aStmtProps) const + { + TInt eqPos = aStmt.Find(KEqStr); + if(eqPos != KErrNotFound && eqPos < (aStmt.Length() - 1)) + { + TPtr stmtKeyword(const_cast (aStmt.Left(eqPos).Ptr()), eqPos, eqPos); + DBSC::Trim(stmtKeyword); + aStmtProps.iType = DBSC::StmtKeywordT2ToId(stmtKeyword); + if(aStmtProps.iType != EStmtTInvalid) + { + TInt valPos = eqPos + 1; + TInt valLen = aStmt.Length() - valPos; + TPtr value(const_cast (aStmt.Mid(valPos).Ptr()), valLen, valLen); + DBSC::Trim(value); + aStmtProps.iValue.Set(value); + return ETrue; + } + } + return EFalse; + } + +/** +The method loads a single text line from the file in the place, pointed by aStmt parameter. +@param aStmt The place, where the text line data will be stored +@return ETrue This not the end of file, the information in aStmt is valid. + EFalse End of file. +@leave System-wide error codes, including KErrCorrupt - unknown file format. + */ +TBool CPDTextLoader::LoadStmtL(TPtr& aStmt) + { + if(IsEofL()) + { + return EFalse; + } + TChar char_LF('\n'); + iStmt8.Zero(); + iRdStream.ReadL(iStmt8, char_LF); + aStmt.Copy(iStmt8); + const TInt len = aStmt.Length(); + if(len < 2) + {//Unknown text file format. The text line should have at the end CR-LF pair. + __LEAVE(KErrCorrupt); + } + if(TChar(aStmt[len - 1]) != char_LF) + {//Too long line + __LEAVE(KErrCorrupt); + } + aStmt.SetLength(len - 1); + //The last character is (CR). Check for (LF). + TChar char_CR('\r'); + if(TChar(aStmt[len - 2]) == char_CR) + { + aStmt.SetLength(len - 2); + } + DBSC::Trim(aStmt); + return ETrue; + } + +/** +The method loads a single text line from the file in the place, pointed by iStmt data member +skipping lines with comments and blank lines. +@param aStmtProps Output parameter. It will be initialized after the call. +@return Statement class. +@leave System-wide error codes, including KErrCorrupt - unknown file format. +*/ +TStmtClass CPDTextLoader::LoadNextStmtL(TStmtProps& aStmtProps) + { + TPtr stmt(const_cast (iStmt.Ptr()), 0, iStmt.MaxLength()); + TStmtClass stmtClass = EStmtCInvalid; + do + { + if(!LoadStmtL(stmt)) + { + aStmtProps.iType = EStmtTEof; + break; + } + GetStmtPropsL(stmt, aStmtProps); + } + while((stmtClass = DBSC::StmtType2Class(aStmtProps.iType)) == EStmtCNoData); + return stmtClass; + } + +/** +The method loads a single text line from the file in the place, pointed by iStmt data member +skipping lines with comments and blank lines. The loaded text line type is expected to be +aStmtType. +@param aStmtProps Output parameter. It will be initialized after the call. +@param aStmtType Expected type of the loaded text line. +@leave System-wide error codes, including KErrCorrupt - unknown file format or the loaded line type is + not the expected type. +*/ +void CPDTextLoader::LoadNextStmtOfTypeL(TStmtProps& aStmtProps, TStmtType aStmtType) + { + (void)LoadNextStmtL(aStmtProps); + if(aStmtProps.iType != aStmtType) + { + __LEAVE(KErrCorrupt); + } + } + +/** +The method loads all database policy related data from the text file. +@param aPolicyDomainBuilder TPolicyDomainBuilder instance, which will be used to add + created database security policy object to the controlled by it policy collection. +@param aStmtProps The information about the last loaded text line. +@return A const pointer to just created database policy object from loaded text data. +@leave System-wide error codes. +*/ +const CDbPolicy* CPDTextLoader::LoadDbPolicyL(TPolicyDomainBuilder& aPolicyDomainBuilder, + TStmtProps& aStmtProps) + { + LoadNextStmtOfTypeL(aStmtProps, EStmtTDatabase); + + CPolicyBase::RPolicyCollection policyColl; + CleanupClosePushL(policyColl); + + LoadSecurityPoliciesL(policyColl, aStmtProps); + + CDbPolicy* dbPolicy = CDbPolicy::NewLC(policyColl); + aPolicyDomainBuilder.SetDbPolicyL(dbPolicy); + CleanupStack::Pop(dbPolicy); + + CleanupStack::PopAndDestroy(&policyColl); + return dbPolicy; + } + +/** +The method loads all table policy related data from the text file. +@param aPolicyDomainBuilder TPolicyDomainBuilder instance, which will be used to add + created table security policy objects to the controlled by it policy collection. +@param aStmtProps The information about the last loaded text line. +@param aDbPolicy A const pointer to the database policy object, created previously from loaded text data. +@leave System-wide error codes. +*/ +void CPDTextLoader::LoadTblPoliciesL(TPolicyDomainBuilder& aPolicyDomainBuilder, + TStmtProps& aStmtProps, const CDbPolicy* aDbPolicy) + { + __ASSERT(aDbPolicy); + CPolicyBase::RPolicyCollection policyColl; + CleanupClosePushL(policyColl); + while(aStmtProps.iType == EStmtTTable) + { + LoadNextStmtOfTypeL(aStmtProps, EStmtTName); + TBufC tableName; + tableName = aStmtProps.iValue; + + LoadSecurityPoliciesL(policyColl, aStmtProps); + + CTblPolicy* tblPolicy = CTblPolicy::NewLC(tableName, policyColl, aDbPolicy); + aPolicyDomainBuilder.AddTblPolicyL(tblPolicy); + CleanupStack::Pop(tblPolicy); + } + CleanupStack::PopAndDestroy(&policyColl); + } + +/** +The method loads the backup & restore SID, if it is in the file. +@param aPolicyDomainBuilder TPolicyDomainBuilder instance, which will be used to store + loaded backup & restore SID. +@param aStmtProps The information about the last loaded text line. +@leave System-wide error codes. +*/ +void CPDTextLoader::LoadBackupSIDL(TPolicyDomainBuilder& aPolicyDomainBuilder, + TStmtProps& aStmtProps) + { + TSecureId backupSID((TUint32)ECapability_None);//ECapability_None is used in TSecurityPolicy constructors too. + if(aStmtProps.iType == EStmtTBackup) + { + LoadNextStmtOfTypeL(aStmtProps, EStmtTSID); + backupSID = GetIdL(aStmtProps.iValue); + } + else if(aStmtProps.iType != EStmtTEof) + { + __LEAVE(KErrCorrupt); + } + aPolicyDomainBuilder.SetBackupSID(backupSID); + } + +/** +The method loads all database/table related security policy information from the text file. +@param aPolicyColl Output parameter - an array, which elements type is CPolicyBase::RPolicyCollection. + The collected from the text file security policy information wil be stored there. +@param aStmtProps The information about the last loaded text line. +@leave System-wide error codes. +*/ +void CPDTextLoader::LoadSecurityPoliciesL(CPolicyBase::RPolicyCollection& aPolicyColl, + TStmtProps& aStmtProps) + { + aPolicyColl.Reset(); + (void)LoadNextStmtL(aStmtProps); + while(DBSC::StmtType2Class(aStmtProps.iType) == EStmtCPolicyType) + { + CPolicyBase::TPolicy policy; + policy.iType = DBSC::StmtType2PolicyType(aStmtProps.iType); + __ASSERT(policy.iType != EPTNone); + LoadSecurityPolicyL(policy.iData, aStmtProps); + __LEAVE_IF_ERROR(aPolicyColl.Append(policy)); + } + if(aPolicyColl.Count() == 0) + { + __LEAVE(KErrCorrupt); + } + } + +/** +The method loads a single security policy from the text file. +@param aSecurityPolicy Output parameter - the information from the file will be stored there. + The collected from the text file security policy information wil be stored there. +@param aStmtProps The information about the last loaded text line. +@leave System-wide error codes. +*/ +void CPDTextLoader::LoadSecurityPolicyL(TSecurityPolicy& aSecurityPolicy, + TStmtProps& aStmtProps) + { + TSecureId sid(0); + TVendorId vid(0); + RArray capabilities; + CleanupClosePushL(capabilities); + while(LoadNextStmtL(aStmtProps) == EStmtCPolicyItem) + { + if(aStmtProps.iType == EStmtTCapability) + { + GetCapabilitiesL(aStmtProps.iValue, capabilities); + } + else if(aStmtProps.iType == EStmtTSID) + { + if(sid != 0) + {//duplicated SID text line + __LEAVE(KErrCorrupt); + } + sid = GetIdL(aStmtProps.iValue); + } + else if(aStmtProps.iType == EStmtTVID) + { + if(vid != 0) + {//duplicated VID text line + __LEAVE(KErrCorrupt); + } + vid = GetIdL(aStmtProps.iValue); + } + else + { + __ASSERT(0); + } + } + if(capabilities.Count() == 0 && sid == 0 && vid == 0) + {//invalid security policy data + __LEAVE(KErrCorrupt); + } + DBSC::CreateSecurityPolicyL(sid, vid, capabilities, aSecurityPolicy); + CleanupStack::PopAndDestroy(&capabilities); + } + +/** +The method parses a string with capabilities information and puts found capabilities in aCapability +output parameter. +@param aCapabilityStr Capabilities string. +@param aCapabilities The collected capabilities will be stored there. +@leave System-wide error codes. KErrCorrupt, if aCapability is not 0, which means there are + 2 or more capability strings for the same policy. +*/ +void CPDTextLoader::GetCapabilitiesL(const TDesC& aCapabilityStr, + RArray& aCapabilities) const + { + if(aCapabilities.Count() > 0) + {//No more than one "capability" statement in the text file! + __LEAVE(KErrCorrupt); + } + TLinearOrder linearOrder(&DBSC::CompareCapabilities); + TLex lex(aCapabilityStr); + for(TPtrC token=lex.NextToken();token.Length()!=0;token.Set(lex.NextToken())) + { + TCapability cap = DBSC::CapabilityName2Id(token); + if(cap != ECapability_Limit) + {//InsertInOrder() - to warn the user in case of duplicates + __LEAVE_IF_ERROR(aCapabilities.InsertInOrder(cap, linearOrder)); + } + else + { + __LEAVE(KErrGeneral);//Unknown capability + } + } + } + +/** +@param aStr A string with SID or VID. +@return The UID, extracted from the string +@leave System-wide error codes. +*/ +TUint CPDTextLoader::GetIdL(const TDesC& aStr) const + { + TLex lex(aStr); + TUint id; + __LEAVE_IF_ERROR(lex.Val(id, EHex)); + if(id == 0) + { + __LEAVE(KErrCorrupt); + } + return id; + } + +} //end of - namespace DBSC