omads/omadsextensions/dsutils/cgiscriptutils/src/nsmlcgiscriptparser.cpp
changeset 19 2691f6aa1921
parent 4 e6e896426eac
child 20 e1de7d03f843
equal deleted inserted replaced
4:e6e896426eac 19:2691f6aa1921
     1 /*
       
     2 * Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  CGI parser and generator
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 // INCLUDE FILES
       
    21 #include <escapeutils.h>
       
    22 
       
    23 #include "nsmlcgiscriptparser.h"
       
    24 #include "nsmlconstants.h" //PtrArrCleanupItem
       
    25 
       
    26 
       
    27 // ============================ MEMBER FUNCTIONS ===============================
       
    28 
       
    29 // -----------------------------------------------------------------------------
       
    30 // TNSmlCGIScriptParser::TNSmlCGIScriptParser
       
    31 // -----------------------------------------------------------------------------
       
    32 //
       
    33 EXPORT_C TNSmlCGIScriptParser::TNSmlCGIScriptParser()
       
    34     {
       
    35     //logical separator table initialization
       
    36     KNSmlCGIScriptLogSep[ENSmlCGIScriptLogicalOperatorAnd] = &KNSmlCGIScriptLogicalSeparatorAndStr;
       
    37     KNSmlCGIScriptLogSep[ENSmlCGIScriptLogicalOperatorOr] = &KNSmlCGIScriptLogicalSeparatorOrStr;
       
    38 
       
    39     //logical operator table initialization
       
    40     KNSmlCGIScriptLogOps[ENSmlCGIScriptComparatorEqualToCaseSensitive] = &KNSmlCGIScriptComparatorEqualToCaseSensitiveStr; 
       
    41     KNSmlCGIScriptLogOps[ENSmlCGIScriptComparatorEqualToCaseInSensitive] = &KNSmlCGIScriptComparatorEqualToCaseInSensitiveStr; 
       
    42     KNSmlCGIScriptLogOps[ENSmlCGIScriptComparatorNotEqualToCaseSensitive] = &KNSmlCGIScriptComparatorNotEqualToCaseSensitiveStr; 
       
    43     KNSmlCGIScriptLogOps[ENSmlCGIScriptComparatorNotEqualToCaseInSensitive] = &KNSmlCGIScriptComparatorNotEqualToCaseInSensitiveStr; 
       
    44     KNSmlCGIScriptLogOps[ENSmlCGIScriptComparatorGreaterThanCaseSensitive] = &KNSmlCGIScriptComparatorGreaterThanCaseSensitiveStr; 
       
    45     KNSmlCGIScriptLogOps[ENSmlCGIScriptComparatorGreaterThanCaseInSensitive] = &KNSmlCGIScriptComparatorGreaterThanCaseInSensitiveStr; 
       
    46     KNSmlCGIScriptLogOps[ENSmlCGIScriptComparatorGreaterThanOrEqualToCaseSensitive] = &KNSmlCGIScriptComparatorGreaterThanOrEqualToCaseSensitiveStr; 
       
    47     KNSmlCGIScriptLogOps[ENSmlCGIScriptComparatorGreaterThanOrEqualToCaseInSensitive] = &KNSmlCGIScriptComparatorGreaterThanOrEqualToCaseInSensitiveStr; 
       
    48     KNSmlCGIScriptLogOps[ENSmlCGIScriptComparatorLessThanCaseSensitive] = &KNSmlCGIScriptComparatorLessThanCaseSensitiveStr; 
       
    49     KNSmlCGIScriptLogOps[ENSmlCGIScriptComparatorLessThanCaseInSensitive] = &KNSmlCGIScriptComparatorLessThanCaseInSensitiveStr; 
       
    50     KNSmlCGIScriptLogOps[ENSmlCGIScriptComparatorLessThanOrEqualCaseSensitive] = &KNSmlCGIScriptComparatorLessThanOrEqualCaseSensitiveStr; 
       
    51     KNSmlCGIScriptLogOps[ENSmlCGIScriptComparatorLessThanOrEqualCaseInSensitive] = &KNSmlCGIScriptComparatorLessThanOrEqualCaseInSensitiveStr; 
       
    52     KNSmlCGIScriptLogOps[ENSmlCGIScriptComparatorContainsValueCaseSensitive] = &KNSmlCGIScriptComparatorContainsValueCaseSensitiveStr; 
       
    53     KNSmlCGIScriptLogOps[ENSmlCGIScriptComparatorContainsValueCaseInSensitive] = &KNSmlCGIScriptComparatorContainsValueCaseInSensitiveStr;
       
    54     KNSmlCGIScriptLogOps[ENSmlCGIScriptComparatorNull] = &KNSmlCGIScriptNullStr;
       
    55 
       
    56     //special usage table initialization
       
    57     KNSmlCGIScriptSpecialUsageStrings[0] = &KNSmlCGIScriptNullValue;
       
    58     KNSmlCGIScriptSpecialUsageStrings[1] = &KNSmlCGIScriptLuidValue;
       
    59     }
       
    60 
       
    61 // -----------------------------------------------------------------------------
       
    62 // TNSmlCGIScriptParser::ParseL
       
    63 // -----------------------------------------------------------------------------
       
    64 //
       
    65 EXPORT_C void TNSmlCGIScriptParser::ParseL(
       
    66     CNSmlCGIScript& aSp, 
       
    67     const CArrayPtr<TNSmlDataTypesForCGIScriptNames>& aDatatypes) const
       
    68     {
       
    69 
       
    70     aSp.Clear();
       
    71 
       
    72     TNSmlCGIScriptParseStateInfo psInfo(aSp.CGIScript(), &aDatatypes);
       
    73     
       
    74     if (psInfo.iCGIScript == NULL)
       
    75         {
       
    76         return;
       
    77         }
       
    78     
       
    79     TNSmlCGIScriptParseData pd;
       
    80 
       
    81     //Main parse loop
       
    82     for ( psInfo.iCurrPos = 0; psInfo.iCurrPos < psInfo.iCGIScript->Length();
       
    83         psInfo.iCurrPos++ )
       
    84         {
       
    85         if ( IsParseSplitPoint(*psInfo.iCGIScript, psInfo.iCurrPos) )
       
    86             {
       
    87             for (psInfo.iState = psInfo.iNextState; ParseStateL(psInfo, pd); 
       
    88                  psInfo.iState = psInfo.iNextState )
       
    89                 {
       
    90                 }
       
    91 
       
    92             if ( pd.iParseDataReady )
       
    93                 {
       
    94                 AddScriptPartL( aSp, pd );
       
    95                 pd.iParseDataReady = EFalse;
       
    96                 }
       
    97             psInfo.iStartPos = psInfo.iCurrPos + 1;
       
    98             }
       
    99         }
       
   100 
       
   101     // parsing script's last value
       
   102     psInfo.iState = psInfo.iNextState;
       
   103     ParseStateL( psInfo, pd );
       
   104     if ( pd.iParseDataReady )
       
   105         {
       
   106         AddScriptPartL( aSp, pd );
       
   107         }
       
   108     else{
       
   109         User::Leave( ENSmlCGIParserErrorParsing );
       
   110         }
       
   111 
       
   112     aSp.SetLogicalOperator( pd.iSeparator );
       
   113     }
       
   114 
       
   115 // -----------------------------------------------------------------------------
       
   116 // TNSmlCGIScriptParser::GenerateL
       
   117 // -----------------------------------------------------------------------------
       
   118 //
       
   119 EXPORT_C void TNSmlCGIScriptParser::GenerateL(CNSmlCGIScript& aSp) const
       
   120     {
       
   121     typedef CArrayPtrFlat<HBufC> CBufParts;
       
   122     CBufParts* bufParts = new (ELeave) CBufParts(aSp.Count());
       
   123     CleanupStack::PushL( PtrArrCleanupItem(HBufC, bufParts) );
       
   124     TInt i;
       
   125 
       
   126     //generates all script parts and appends them to array.
       
   127     for (i = 0;i < aSp.Count();i++)
       
   128         {
       
   129         const TNSmlCGIScriptPart* sp = aSp.Get(i);
       
   130         HBufC* bufTmp = GenerateScriptPartL(*sp);
       
   131 
       
   132         CleanupStack::PushL(bufTmp);
       
   133         bufParts->AppendL(bufTmp);
       
   134         CleanupStack::Pop(bufTmp);
       
   135         }
       
   136 
       
   137     //collects all parts to a single CGI script.
       
   138     SetCGIScriptL(aSp, *bufParts);
       
   139         
       
   140     CleanupStack::PopAndDestroy(bufParts);
       
   141     }
       
   142 
       
   143 // -----------------------------------------------------------------------------
       
   144 // TNSmlCGIScriptParser::IsParseSplitPoint
       
   145 // -----------------------------------------------------------------------------
       
   146 //
       
   147 TBool TNSmlCGIScriptParser::IsParseSplitPoint(const TDesC& aCGIScript, TInt aStartFrom) const
       
   148     {
       
   149     if (aCGIScript[aStartFrom] == '&')
       
   150         {
       
   151         for (TInt i(0); i < KNSmlCGIScriptSpecialUsageStringsCount; i++)
       
   152             {
       
   153             if (Compare(*KNSmlCGIScriptSpecialUsageStrings[i], aCGIScript, aStartFrom))
       
   154                 {
       
   155                 return EFalse;
       
   156                 }
       
   157             }
       
   158         return ETrue;
       
   159         }
       
   160     return EFalse;
       
   161     }
       
   162 
       
   163 // -----------------------------------------------------------------------------
       
   164 // TNSmlCGIScriptParser::ParseStateL
       
   165 // -----------------------------------------------------------------------------
       
   166 //
       
   167 TBool TNSmlCGIScriptParser::ParseStateL(
       
   168     TNSmlCGIScriptParseStateInfo & aPSInfo, 
       
   169     TNSmlCGIScriptParseData & aPD) const
       
   170     {
       
   171     TBool retV(ETrue);
       
   172 
       
   173     switch (aPSInfo.iState)
       
   174         {
       
   175         case ENSmlCGIScriptParseStateKeyWord:
       
   176             aPD.iKeyword.Set(aPSInfo.iCGIScript->Mid(aPSInfo.iStartPos, 
       
   177                 aPSInfo.iCurrPos - aPSInfo.iStartPos));
       
   178             aPD.iDataType = FindDataTypeL(*aPSInfo.iDatatypes, aPD.iKeyword);
       
   179 
       
   180             if (aPD.iDataType == ENSmlCGIScriptDataTypeNoValue)
       
   181                 {
       
   182                 aPSInfo.iNextState = ENSmlCGIScriptParseStateLogSep;
       
   183                 aPD.iValue.Set(TPtrC());
       
   184                 aPD.iComparator = ENSmlCGIScriptComparatorNull;
       
   185                 aPD.iParseDataReady = ETrue;
       
   186                 }
       
   187             else
       
   188                 {
       
   189                 aPSInfo.iNextState = ENSmlCGIScriptParseStateLogOp;
       
   190                 }
       
   191             break;
       
   192         case ENSmlCGIScriptParseStateLogOp:
       
   193             aPD.iComparator = LogOpL(*aPSInfo.iCGIScript,
       
   194                 aPSInfo.iCurrPos + 1);
       
   195             aPSInfo.iCurrPos += LogOpL(aPD.iComparator).Length() - 1;
       
   196             aPSInfo.iNextState = ENSmlCGIScriptParseStateValue;
       
   197             retV = EFalse;
       
   198             break;
       
   199         case ENSmlCGIScriptParseStateValue:
       
   200             {
       
   201             aPD.iValue.Set(aPSInfo.iCGIScript->Mid(aPSInfo.iStartPos, 
       
   202                 aPSInfo.iCurrPos - aPSInfo.iStartPos));
       
   203 
       
   204             aPSInfo.iNextState = ENSmlCGIScriptParseStateLogSep;
       
   205             aPD.iParseDataReady = ETrue;
       
   206             break;
       
   207             }
       
   208         case ENSmlCGIScriptParseStateLogSep:
       
   209             {
       
   210             TNSmlCGIScriptLogicalOperator loTmp(
       
   211                 LogSepL(*aPSInfo.iCGIScript, aPSInfo.iCurrPos + 1) );
       
   212 
       
   213             if ( aPD.iSeparator != ENSmlCGIScriptLogicalOperatorNull && 
       
   214                 (loTmp != aPD.iSeparator) )
       
   215                 {
       
   216                 //Error: query may contain only 1 type of logical separator
       
   217                 User::Leave(ENSmlCGIParserErrorWrongSeparator);
       
   218                 }
       
   219             aPD.iSeparator = loTmp;
       
   220 
       
   221             aPSInfo.iCurrPos += LogSepL( aPD.iSeparator ).Length() - 1;
       
   222             aPSInfo.iNextState = ENSmlCGIScriptParseStateKeyWord;
       
   223             retV = EFalse;
       
   224             }
       
   225             break;
       
   226         default:
       
   227             User::Leave(ENSmlCGIParserErrorParsing);
       
   228             break;
       
   229         }
       
   230     return retV;
       
   231     }
       
   232 
       
   233 // -----------------------------------------------------------------------------
       
   234 // TNSmlCGIScriptParser::AddScriptPartL
       
   235 // -----------------------------------------------------------------------------
       
   236 //
       
   237 TBool TNSmlCGIScriptParser::AddScriptPartL(CNSmlCGIScript& aSp, 
       
   238     TNSmlCGIScriptParseData& aPD)
       
   239     {
       
   240 
       
   241     TNSmlCGIScriptDataType datatype(aPD.iDataType);
       
   242 
       
   243     TNSmlCGIScriptPart* sp = new (ELeave) TNSmlCGIScriptPart;
       
   244     CleanupStack::PushL(sp);
       
   245 
       
   246     sp->iData = NULL;
       
   247     sp->iName = HBufC::NewLC(aPD.iKeyword.Length());
       
   248     *(sp->iName) = aPD.iKeyword;
       
   249 
       
   250     sp->iComparator = aPD.iComparator;
       
   251     sp->iDataType = datatype;
       
   252 
       
   253     TBool retV = ParseScriptPartDataLC(*sp, aPD.iValue);
       
   254 
       
   255     CheckScriptPartValidityL(*sp);
       
   256 
       
   257     if (retV)
       
   258         {
       
   259         aSp.AddL(sp);
       
   260         CleanupStack::Pop(3); //ParseScriptPartDataLC:stä, sp->iName,sp;
       
   261         }
       
   262     else
       
   263         {
       
   264         CleanupStack::PopAndDestroy(2); //sp->iName, sp
       
   265         sp->iName = NULL;
       
   266         sp = NULL;
       
   267         }
       
   268     return retV;
       
   269     }
       
   270 
       
   271 // -----------------------------------------------------------------------------
       
   272 // TNSmlCGIScriptParser::ParseScriptPartDataLC
       
   273 // -----------------------------------------------------------------------------
       
   274 //
       
   275 TBool TNSmlCGIScriptParser::ParseScriptPartDataLC(
       
   276     TNSmlCGIScriptPart& aSp, 
       
   277     const TPtrC& aValue)
       
   278     {
       
   279     TNSmlCGIScriptDataType datatype( (aValue == KNSmlCGIScriptNullValue) 
       
   280         ? ENSmlCGIScriptDataTypeNull : aSp.iDataType );
       
   281 
       
   282     TBool retV(ETrue);
       
   283 
       
   284     // in each case - sentence, either push something to cleanupstack, 
       
   285     // set retV to EFalse or leave
       
   286     switch (datatype)
       
   287         {
       
   288         case ENSmlCGIScriptDataTypeHBufC:
       
   289             {
       
   290             aSp.iData = EscapeUtils::EscapeDecodeL(aValue);
       
   291             CleanupStack::PushL(aSp.iData);
       
   292             }
       
   293             break;
       
   294         case ENSmlCGIScriptDataTypeDateTime:
       
   295         case ENSmlCGIScriptDataTypeDate:
       
   296             {
       
   297             TDateTime* dt = new (ELeave) TDateTime();
       
   298             CleanupStack::PushL(dt);
       
   299             TInt num = ParseDateTimeL(*dt, aValue);
       
   300 
       
   301             switch(num)
       
   302                 {
       
   303                 case KNSmlCGIParserDateTimeLen:
       
   304                     aSp.iDataType = ENSmlCGIScriptDataTypeDateTime;
       
   305                     break;
       
   306                 case KNSmlCGIParserDateLen:
       
   307                     aSp.iDataType = ENSmlCGIScriptDataTypeDate;
       
   308                     break;
       
   309                 default:
       
   310                     User::Leave(ENSmlCGIParserErrorConversion);
       
   311                     break;
       
   312                 }
       
   313             aSp.iData = dt;
       
   314             }
       
   315             break;
       
   316         case ENSmlCGIScriptDataTypeNumber:
       
   317             {
       
   318             TInt* num = new (ELeave) TInt();
       
   319             CleanupStack::PushL(num);
       
   320             *num = ParseIntL(aValue, 0, aValue.Length());
       
   321             aSp.iData = num;
       
   322             }
       
   323             break;
       
   324         case ENSmlCGIScriptDataTypeBoolean:
       
   325             {
       
   326             TBool* bln = new (ELeave) TBool;
       
   327             CleanupStack::PushL(bln);
       
   328             *bln = ParseBoolL(aValue);
       
   329             aSp.iData = bln;
       
   330             }
       
   331             break;
       
   332         case ENSmlCGIScriptDataTypeNoValue:
       
   333         case ENSmlCGIScriptDataTypeNull:
       
   334             aSp.iData = NULL;
       
   335             CleanupStack::PushL(aSp.iData);
       
   336             break;
       
   337         default: // TNSmlCGIScriptDataTypeUnKnown
       
   338             User::Leave(ENSmlCGIParserErrorConversion);
       
   339             break;
       
   340         }
       
   341 
       
   342     return retV;
       
   343     }
       
   344 
       
   345 // -----------------------------------------------------------------------------
       
   346 // TNSmlCGIScriptParser::FindDataTypeL
       
   347 // -----------------------------------------------------------------------------
       
   348 //
       
   349 TNSmlCGIScriptDataType TNSmlCGIScriptParser::FindDataTypeL(
       
   350     const CArrayPtr<TNSmlDataTypesForCGIScriptNames>& aDatatypes, 
       
   351     const TPtrC& aKeyword)
       
   352     {
       
   353     TNSmlCGIScriptDataType dt(FindDataType(aDatatypes, aKeyword));
       
   354     if (dt == ENSmlCGIScriptDataTypeUnKnown)
       
   355         {
       
   356         User::Leave(ENSmlCGIParserErrorDataTypeNotFound);
       
   357         }
       
   358     return dt;
       
   359     }
       
   360 
       
   361 // -----------------------------------------------------------------------------
       
   362 // TNSmlCGIScriptParser::FindDataType
       
   363 // -----------------------------------------------------------------------------
       
   364 //
       
   365 TNSmlCGIScriptDataType TNSmlCGIScriptParser::FindDataType(
       
   366     const CArrayPtr<TNSmlDataTypesForCGIScriptNames>& aDatatypes, 
       
   367     const TPtrC& aKeyword)
       
   368     {
       
   369     TNSmlDataTypesForCGIScriptNames* tmp;
       
   370 
       
   371     for (TInt i = 0; i < aDatatypes.Count(); i++)
       
   372         {
       
   373         tmp = aDatatypes[i];
       
   374         if (*tmp->iKeywordOrProperty == aKeyword)
       
   375             {
       
   376             return tmp->iDataType;
       
   377             }
       
   378         }
       
   379     return ENSmlCGIScriptDataTypeUnKnown;
       
   380     }
       
   381 
       
   382 // -----------------------------------------------------------------------------
       
   383 // TNSmlCGIScriptParser::GenerateScriptPartL
       
   384 // -----------------------------------------------------------------------------
       
   385 //
       
   386 HBufC* TNSmlCGIScriptParser::GenerateScriptPartL(
       
   387     const TNSmlCGIScriptPart& aSp) const
       
   388     {
       
   389 
       
   390     CheckScriptPartValidityL(aSp);
       
   391 
       
   392     TInt len(LogOpL(aSp.iComparator).Length() + aSp.iName->Length());
       
   393     TAny* value = NULL;
       
   394     TBool destroyValue(EFalse);
       
   395     TNSmlCGIScriptDataType dataType(aSp.iDataType);
       
   396 
       
   397     if (aSp.iData == NULL && dataType != ENSmlCGIScriptDataTypeNoValue)
       
   398         {
       
   399         dataType = ENSmlCGIScriptDataTypeNull;
       
   400         }
       
   401 
       
   402     if (dataType == ENSmlCGIScriptDataTypeHBufC)
       
   403         {
       
   404         HBufC* buf = EscapeUtils::EscapeEncodeL( 
       
   405             *reinterpret_cast<HBufC*>(aSp.iData), KNSmlCGIParserReservedChars );
       
   406         CleanupStack::PushL(buf);
       
   407         len += buf->Length();
       
   408         destroyValue = ETrue;
       
   409         value = buf;
       
   410         }
       
   411     else
       
   412         {
       
   413         len += 32;              //enough for datetime, number, boolean etc.
       
   414         value = reinterpret_cast<TAny*>(aSp.iData);
       
   415         }
       
   416 
       
   417     HBufC* bufTmp = HBufC::NewLC(len);
       
   418     TPtr ptr(bufTmp->Des());
       
   419 
       
   420     ptr.Append(*aSp.iName);
       
   421     ptr.Append( LogOpL(aSp.iComparator) );
       
   422     GenerateScriptPartValueL(dataType, value, ptr);
       
   423 
       
   424     CleanupStack::Pop(bufTmp);
       
   425 
       
   426     if (destroyValue)
       
   427         {
       
   428         CleanupStack::PopAndDestroy(value);
       
   429         }
       
   430 
       
   431     return bufTmp;
       
   432 
       
   433     }
       
   434 
       
   435 // -----------------------------------------------------------------------------
       
   436 // TNSmlCGIScriptParser::GenerateScriptPartValueL
       
   437 // -----------------------------------------------------------------------------
       
   438 //
       
   439 void TNSmlCGIScriptParser::GenerateScriptPartValueL(
       
   440     TNSmlCGIScriptDataType aDataType, 
       
   441     const TAny *aValue,
       
   442     TPtr & aPtr)
       
   443     {
       
   444 
       
   445     switch (aDataType)
       
   446         {
       
   447         case ENSmlCGIScriptDataTypeHBufC:
       
   448             {
       
   449             aPtr.Append( *reinterpret_cast<const HBufC*>(aValue) );
       
   450             break;
       
   451             }
       
   452         case ENSmlCGIScriptDataTypeDate:
       
   453             {
       
   454             const TDateTime* dt = reinterpret_cast<const TDateTime*>(aValue);
       
   455             TBuf<KNSmlCGIParserDateLen> des;
       
   456             GenerateDateTimeValue(*dt, des, EFalse);
       
   457             aPtr.Append(des);
       
   458             }
       
   459             break;
       
   460         case ENSmlCGIScriptDataTypeDateTime:
       
   461             {
       
   462             const TDateTime* dt = reinterpret_cast<const TDateTime*>(aValue);
       
   463             TBuf<KNSmlCGIParserDateTimeLen> des;
       
   464             GenerateDateTimeValue(*dt, des, ETrue);
       
   465             aPtr.Append(des);
       
   466             }
       
   467             break;
       
   468         case ENSmlCGIScriptDataTypeNumber:
       
   469             {
       
   470             TBuf<32> des;
       
   471             const TInt* num = reinterpret_cast<const TInt*>(aValue);
       
   472             des.Num(*num);
       
   473             aPtr.Append(des);
       
   474             }
       
   475             break;
       
   476         case ENSmlCGIScriptDataTypeBoolean:
       
   477             {
       
   478             const TBool* bln = reinterpret_cast<const TBool*>(aValue);
       
   479             aPtr.Append(GenerateBoolValue(*bln));
       
   480             }
       
   481             break;
       
   482         case ENSmlCGIScriptDataTypeNull:
       
   483             aPtr.Append(KNSmlCGIScriptNullValue);
       
   484             break;
       
   485         case ENSmlCGIScriptDataTypeNoValue:
       
   486             //empty
       
   487             break;
       
   488         default: //TNSmlCGIScriptDataTypeUnKnown
       
   489             User::Leave(ENSmlCGIParserErrorConversion);
       
   490             break;
       
   491         }
       
   492     }
       
   493 
       
   494 // -----------------------------------------------------------------------------
       
   495 // TNSmlCGIScriptParser::SetCGIScriptL
       
   496 // -----------------------------------------------------------------------------
       
   497 //
       
   498 void TNSmlCGIScriptParser::SetCGIScriptL(
       
   499     CNSmlCGIScript& aSp, 
       
   500     CArrayPtr<HBufC>& aBufParts ) const
       
   501     {
       
   502 
       
   503     TInt bufPartsCount(aBufParts.Count());
       
   504     TInt i(0);
       
   505     TInt scriptLen(0);
       
   506 
       
   507     if (bufPartsCount > 0)
       
   508         {
       
   509 
       
   510         //length of entire script
       
   511         for (i = 0; i < bufPartsCount; i++)
       
   512             {
       
   513             scriptLen += aBufParts.At(i)->Length();
       
   514             }
       
   515 
       
   516         //adds length of separator between two scriptparts
       
   517         if (bufPartsCount > 1)
       
   518             {
       
   519             scriptLen += (bufPartsCount - 1) * 
       
   520                 LogSepL(aSp.LogicalOperator()).Length();
       
   521             }
       
   522 
       
   523         //reserves needed memory
       
   524         HBufC* bufTmp = HBufC::NewLC(scriptLen);
       
   525         TPtr ptr(bufTmp->Des());
       
   526 
       
   527         //appends all parts to a full script.
       
   528         for (i = 0; i < bufPartsCount;i++)
       
   529             {
       
   530             ptr.Append(*aBufParts.At(i));
       
   531             if (i < (bufPartsCount - 1))
       
   532                 {
       
   533                 ptr.Append(LogSepL(aSp.LogicalOperator()));
       
   534                 }
       
   535             }
       
   536 
       
   537         aSp.SetCGIScriptL(*bufTmp);
       
   538         CleanupStack::PopAndDestroy(bufTmp);
       
   539         }
       
   540     }
       
   541 
       
   542 // -----------------------------------------------------------------------------
       
   543 // TNSmlCGIScriptParser::ParseDateTimeL
       
   544 // -----------------------------------------------------------------------------
       
   545 //
       
   546 TInt TNSmlCGIScriptParser::ParseDateTimeL(
       
   547     TDateTime& aDateTime, 
       
   548     const TDesC& aDes, 
       
   549     TInt aStartFrom)
       
   550     {
       
   551 
       
   552     enum TDateParseState{ 
       
   553         EDateParseStateDate, 
       
   554         EDateParseStateTime, 
       
   555         EDateParseStateCheckUTC, 
       
   556         EDateParseStateDone};
       
   557 
       
   558     TDateParseState stateAfterDate(EDateParseStateTime);
       
   559 
       
   560     switch (aDes.Length())
       
   561         {
       
   562         case KNSmlCGIParserDateLen:
       
   563             stateAfterDate = EDateParseStateDone;
       
   564             break;
       
   565         case KNSmlCGIParserDateTimeLen:
       
   566             stateAfterDate = EDateParseStateTime;
       
   567             break;
       
   568         default:
       
   569             User::Leave(ENSmlCGIParserErrorConversion);
       
   570         }
       
   571 
       
   572     TInt ind(aStartFrom);
       
   573     const TInt8 DateItemLengths[] = {4, 2, 2, 2, 2, 2};
       
   574     TInt DateValues[6] = {0, 0, 0, 0, 0, 0};
       
   575 
       
   576     TDateParseState state(EDateParseStateDate);
       
   577     TDateParseState nextState(state);
       
   578 
       
   579     TInt i(0);
       
   580     TInt upto(0);
       
   581 
       
   582     while (state != EDateParseStateDone)
       
   583         {
       
   584         switch (state)
       
   585             {
       
   586             case EDateParseStateDate:
       
   587                 i = 0;
       
   588                 upto = 3;
       
   589                 nextState = stateAfterDate;
       
   590                 break;
       
   591             case EDateParseStateTime:
       
   592                 if (aDes[ind] != 'T')
       
   593                     {
       
   594                     User::Leave(ENSmlCGIParserErrorConversion);
       
   595                     }
       
   596                 ind++;
       
   597                 upto = 6;
       
   598                 nextState = EDateParseStateCheckUTC;
       
   599                 break;
       
   600             case EDateParseStateCheckUTC:
       
   601 
       
   602                 // must be UTC, marked by Z
       
   603                 if (aDes[ind] != 'Z')
       
   604                     {
       
   605                     User::Leave(ENSmlCGIParserErrorConversion);
       
   606                     }
       
   607                 ind++;
       
   608                 state = EDateParseStateDone;
       
   609                 break;
       
   610             default:
       
   611                 User::Leave(KErrGeneral);
       
   612                 break;
       
   613             }
       
   614 
       
   615         if (state != EDateParseStateDone)
       
   616             {
       
   617             for (; i < upto;i++)
       
   618                 {
       
   619                 TInt len(DateItemLengths[i]);
       
   620                 DateValues[i] = ParseIntL(aDes, ind, len);
       
   621                 ind += len;
       
   622                 }
       
   623             state = nextState;
       
   624             }
       
   625         }
       
   626     
       
   627     TInt err(aDateTime.Set(DateValues[0], 
       
   628         static_cast<TMonth>(DateValues[1] - 1), DateValues[2], 
       
   629         DateValues[3], DateValues[4], DateValues[5], 0));
       
   630 
       
   631     User::LeaveIfError(err);
       
   632     return(ind - aStartFrom);
       
   633     }
       
   634 
       
   635 // -----------------------------------------------------------------------------
       
   636 // TNSmlCGIScriptParser::GenerateDateTimeValue
       
   637 // -----------------------------------------------------------------------------
       
   638 //
       
   639 void TNSmlCGIScriptParser::GenerateDateTimeValue(
       
   640     const TDateTime& aDateTime, 
       
   641     TDes& aDes, 
       
   642     TBool aUseTimePart)
       
   643     {
       
   644 
       
   645     if (aUseTimePart)
       
   646         {
       
   647         aDes.Format(KNSmlCGIParserDateTimeFormat, aDateTime.Year(), 
       
   648             aDateTime.Month() + 1, aDateTime.Day(), 
       
   649             aDateTime.Hour(), aDateTime.Minute(), aDateTime.Second());
       
   650         }
       
   651     else
       
   652         {
       
   653         aDes.Format(KNSmlCGIParserDateFormat, aDateTime.Year(),
       
   654             aDateTime.Month() + 1, aDateTime.Day());
       
   655         }
       
   656 }
       
   657 
       
   658 // -----------------------------------------------------------------------------
       
   659 // TNSmlCGIScriptParser::GenerateBoolValue
       
   660 // -----------------------------------------------------------------------------
       
   661 //
       
   662 const TDesC & TNSmlCGIScriptParser::GenerateBoolValue(TBool aBool)
       
   663     {
       
   664 
       
   665     if (aBool)
       
   666         {
       
   667         return KNSmlCGIScriptBoolTrue;
       
   668         }
       
   669     else
       
   670         {
       
   671         return KNSmlCGIScriptBoolFalse;
       
   672         }
       
   673     }
       
   674 
       
   675 // -----------------------------------------------------------------------------
       
   676 // TNSmlCGIScriptParser::ParseIntL
       
   677 // -----------------------------------------------------------------------------
       
   678 //
       
   679 TInt TNSmlCGIScriptParser::ParseIntL(
       
   680     const TDesC& aDes, 
       
   681     TInt aStartFrom, 
       
   682     TInt aLength)
       
   683     {
       
   684 
       
   685     TInt num(0);
       
   686     TPtrC des(aDes.Mid(aStartFrom, aLength));
       
   687     TLex lex(des);    
       
   688     TInt t = lex.Val(num);
       
   689     if (t != KErrNone)
       
   690         {
       
   691         User::Leave(t);
       
   692         }
       
   693     if (!lex.Eos())
       
   694         {
       
   695         User::Leave(ENSmlCGIParserErrorConversion);
       
   696         }
       
   697     return num;
       
   698 
       
   699     }
       
   700 
       
   701 // -----------------------------------------------------------------------------
       
   702 // TNSmlCGIScriptParser::ParseBoolL
       
   703 // -----------------------------------------------------------------------------
       
   704 //
       
   705 TBool TNSmlCGIScriptParser::ParseBoolL(
       
   706     const TDesC& aDes, 
       
   707     TInt aStartFrom)
       
   708     {
       
   709     TBool bln(EFalse);
       
   710     const TDesC* cmp = NULL;
       
   711 
       
   712     if ( Compare(*(cmp = &GenerateBoolValue(ETrue)), aDes, aStartFrom) )
       
   713         {
       
   714         bln = ETrue;
       
   715         }
       
   716     else if ( Compare(*(cmp = &GenerateBoolValue(EFalse)), aDes, aStartFrom) )
       
   717         {
       
   718         bln = EFalse;
       
   719         }
       
   720     else
       
   721         {
       
   722         User::Leave(ENSmlCGIParserErrorConversion);
       
   723         }
       
   724 
       
   725     if ( cmp->Length() != (aDes.Length() - aStartFrom) )
       
   726         {
       
   727         User::Leave(ENSmlCGIParserErrorConversion);
       
   728         }
       
   729     
       
   730     return bln;
       
   731     }
       
   732 
       
   733 // -----------------------------------------------------------------------------
       
   734 // TNSmlCGIScriptParser::LogOpL
       
   735 // -----------------------------------------------------------------------------
       
   736 //
       
   737 const TDesC& TNSmlCGIScriptParser::LogOpL(TNSmlCGIScriptComparator aComp) const
       
   738     {
       
   739     if ( aComp < KNSmlCGIParserLogOpsCount) //range check
       
   740         {
       
   741         return *KNSmlCGIScriptLogOps[aComp];
       
   742         }
       
   743     else
       
   744         {
       
   745         User::Leave(ENSmlCGIParserErrorWrongOperator);
       
   746         }
       
   747     return KNSmlCGIScriptNullStr;
       
   748     }
       
   749 
       
   750 // -----------------------------------------------------------------------------
       
   751 // TNSmlCGIScriptParser::LogOpL
       
   752 // -----------------------------------------------------------------------------
       
   753 //
       
   754 TNSmlCGIScriptComparator TNSmlCGIScriptParser::LogOpL(
       
   755     const TDesC& aDes, 
       
   756     TInt aInd) const
       
   757     {
       
   758 
       
   759      for (TInt i = 0; i < KNSmlCGIParserLogOpsCount; i++)
       
   760         {
       
   761         TNSmlCGIScriptComparator lo(
       
   762             static_cast<TNSmlCGIScriptComparator>(i));
       
   763 
       
   764         if (Compare(LogOpL(lo), aDes, aInd-1))
       
   765             {
       
   766             return lo;
       
   767             }
       
   768         }
       
   769     User::Leave(ENSmlCGIParserErrorWrongOperator);
       
   770 
       
   771     return ENSmlCGIScriptComparatorNull;
       
   772     }
       
   773 
       
   774 // -----------------------------------------------------------------------------
       
   775 // TNSmlCGIScriptParser::LogSepL
       
   776 // -----------------------------------------------------------------------------
       
   777 //
       
   778 const TDesC & TNSmlCGIScriptParser::LogSepL(
       
   779     TNSmlCGIScriptLogicalOperator aLogSep) const
       
   780     {
       
   781     
       
   782     if ( aLogSep < KNSmlCGIScriptLogSepCount) //range check
       
   783         {
       
   784         return *KNSmlCGIScriptLogSep[aLogSep];
       
   785         }
       
   786     else
       
   787         {
       
   788         User::Leave(ENSmlCGIParserErrorWrongSeparator);
       
   789         }
       
   790 
       
   791     return KNSmlCGIScriptNullStr;
       
   792 
       
   793     }
       
   794 
       
   795 // -----------------------------------------------------------------------------
       
   796 // TNSmlCGIScriptParser::LogSepL
       
   797 // -----------------------------------------------------------------------------
       
   798 //
       
   799 TNSmlCGIScriptLogicalOperator TNSmlCGIScriptParser::LogSepL(
       
   800     const TDesC& aDes, 
       
   801     TInt aInd) const
       
   802     {
       
   803 
       
   804     for (TInt i = 0; i < KNSmlCGIScriptLogSepCount; i++)
       
   805         {
       
   806         TNSmlCGIScriptLogicalOperator lo(
       
   807             static_cast<TNSmlCGIScriptLogicalOperator>(i));
       
   808 
       
   809         if (Compare(LogSepL(lo), aDes, aInd-1))
       
   810             {
       
   811             return lo;
       
   812             }
       
   813         }
       
   814     User::Leave(ENSmlCGIParserErrorWrongSeparator);
       
   815     return ENSmlCGIScriptLogicalOperatorNull;
       
   816 
       
   817     }
       
   818 
       
   819 // -----------------------------------------------------------------------------
       
   820 // TNSmlCGIScriptParser::IsEqualityOperator
       
   821 // -----------------------------------------------------------------------------
       
   822 //
       
   823 TBool TNSmlCGIScriptParser::IsEqualityOperator(TNSmlCGIScriptComparator comp)
       
   824     {
       
   825     if (comp >= ENSmlCGIScriptComparatorEqualToCaseSensitive 
       
   826         && comp <= ENSmlCGIScriptComparatorNotEqualToCaseInSensitive)
       
   827         {
       
   828         return ETrue;
       
   829         }
       
   830     return EFalse;
       
   831     }
       
   832 
       
   833 // -----------------------------------------------------------------------------
       
   834 // TNSmlCGIScriptParser::CheckScriptPartValidityL
       
   835 // -----------------------------------------------------------------------------
       
   836 //
       
   837 void TNSmlCGIScriptParser::CheckScriptPartValidityL(const TNSmlCGIScriptPart & aSp)
       
   838     {
       
   839     if (aSp.iData == NULL)
       
   840         {
       
   841         if (aSp.iDataType == ENSmlCGIScriptDataTypeNoValue)
       
   842             {
       
   843             if (aSp.iComparator != ENSmlCGIScriptComparatorNull)
       
   844                 {
       
   845                 User::Leave(ENSmlCGIParserErrorWrongOperator);
       
   846                 }
       
   847             }
       
   848         else if ( !IsEqualityOperator(aSp.iComparator) )
       
   849             {
       
   850             User::Leave(ENSmlCGIParserErrorWrongOperator);
       
   851             }
       
   852         }
       
   853     else
       
   854         {
       
   855         if (aSp.iDataType == ENSmlCGIScriptDataTypeNoValue)
       
   856             {
       
   857             User::Leave(ENSmlCGIParserErrorConversion);
       
   858             }
       
   859         if (aSp.iComparator == ENSmlCGIScriptComparatorNull)
       
   860             {
       
   861             User::Leave(ENSmlCGIParserErrorWrongOperator);
       
   862             }
       
   863         }
       
   864     if (aSp.iName == NULL)
       
   865         {
       
   866         User::Leave(ENSmlCGIParserErrorNoKeyword);
       
   867         }
       
   868     }
       
   869 
       
   870 // -----------------------------------------------------------------------------
       
   871 // TNSmlCGIScriptParser::Compare
       
   872 // -----------------------------------------------------------------------------
       
   873 //
       
   874 TBool TNSmlCGIScriptParser::Compare(
       
   875     const TDesC& aWhat, 
       
   876     const TDesC& aWhere, 
       
   877     TInt aStartFrom)
       
   878     {
       
   879 
       
   880     if((aWhere.Length() - aStartFrom) < aWhat.Length())
       
   881         {
       
   882         return EFalse; //aWhat is longer than what's left in aWhere. No match
       
   883         }
       
   884     TBuf<32> buf( aWhere.Mid(aStartFrom, aWhat.Length()) );
       
   885     return ( buf.Compare(aWhat) == 0 );
       
   886 
       
   887     }
       
   888 
       
   889 //  End of File