meetingrequest/mrversit2/src/cesmricalvalue.cpp
changeset 0 8466d47a6819
equal deleted inserted replaced
-1:000000000000 0:8466d47a6819
       
     1 /*
       
     2 * Copyright (c) 2002-2009 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: This file implements class CESMRICalValue.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // Class include.
       
    20 #include "emailtrace.h"
       
    21 #include "cesmricalvalue.h" // CESMRICalValue
       
    22 
       
    23 //debug
       
    24 
       
    25 // User includes.
       
    26 #include "esmricalkeywords.h"       // Literals
       
    27 #include "cesmricalrulesegment.h"   // CESMRICalRuleSegment
       
    28 
       
    29 // Constants.
       
    30 
       
    31 namespace{
       
    32 // Maximum number of characters to use for storing TInt.
       
    33 // (The maximum number of characters for storing a decimal representation of
       
    34 // KMaxTInt, KMinTInt or even KMaxTUint is 10 on current implementations.
       
    35 // The maximum number of characters for storing a decimal representation of
       
    36 // KMaxTUint64 is 20, so using this for future proofing.)
       
    37 const TInt KICalTIntWidth = 20;
       
    38 
       
    39 // Width of "HHMMSS"
       
    40 const TInt KICalTimeWidth = 6;
       
    41 
       
    42 // Width of "YYYYMMDD"
       
    43 const TInt KICalDateWidth = 8;
       
    44 
       
    45 // Width of "YYYYMMDDTHHMMSS" (note the 'T' in the middle)
       
    46 const TInt KICalDateTimeWidth = KICalDateWidth + KICalTimeWidth + 1;
       
    47 
       
    48 // Width of a duration.
       
    49 const TInt KICalDurationWidth = 25;
       
    50 
       
    51 // Width of a short format UTC offset.
       
    52 const TInt KShortFormatUtcOffsetWidth = 5;  // The width of (e.g.) +1000.
       
    53 
       
    54 // Width of a long format UTC offset.
       
    55 const TInt KLongFormatUtcOffsetWidth = 7;   // The width of (e.g.) -013045.
       
    56 
       
    57 // Time constants.
       
    58 const TInt KICalSecondsPerMinute =     60;
       
    59 const TInt KICalSecondsPerHour   =   3600; // That is:      60*60;
       
    60 const TInt KICalSecondsPerDay    =  86400; // That is:   24*60*60;
       
    61 const TInt KICalSecondsPerWeek   = 604800; // That is: 7*24*60*60;
       
    62 
       
    63 // Time characters
       
    64 const TUint KICalUtcChar('Z');      // UTC time.
       
    65 const TUint KICalTimeChar('T');     // Date/time separator.
       
    66 const TUint KICalPeriodChar('/');   // Period separator.
       
    67 const TUint KICalMicroChar('.');    // Second/microsecond separator.
       
    68 const TUint KICalDurationChar('P'); // Duration.
       
    69 const TUint KICalWeekChar('W');     // Week.
       
    70 const TUint KICalDayChar('D');      // Day.
       
    71 const TUint KICalHourChar('H');     // Hour.
       
    72 const TUint KICalMinuteChar('M');   // Minute.
       
    73 const TUint KICalSecondChar('S');   // Second.
       
    74 const TUint KICalPositiveChar('+'); // Positive values.
       
    75 const TUint KICalNegativeChar('-'); // Negative values.
       
    76 
       
    77 // Date format.
       
    78 _LIT(KICalDateFormat, "%F%Y%M%D");
       
    79 }//namespace
       
    80 
       
    81 // ======== MEMBER FUNCTIONS ========
       
    82 
       
    83 // ---------------------------------------------------------------------------
       
    84 // CESMRICalValue::NewL
       
    85 // ---------------------------------------------------------------------------
       
    86 //
       
    87 EXPORT_C CESMRICalValue* CESMRICalValue::NewL()
       
    88     {
       
    89     FUNC_LOG;
       
    90 
       
    91     CESMRICalValue* self  = CESMRICalValue::NewLC();
       
    92     CleanupStack::Pop(self);
       
    93 
       
    94     return self;
       
    95     }
       
    96 
       
    97 // ---------------------------------------------------------------------------
       
    98 // CESMRICalValue::NewLC
       
    99 // ---------------------------------------------------------------------------
       
   100 //
       
   101 EXPORT_C CESMRICalValue* CESMRICalValue::NewLC()
       
   102     {
       
   103     FUNC_LOG;
       
   104 
       
   105     CESMRICalValue* self  = new (ELeave) CESMRICalValue;
       
   106     CleanupStack::PushL(self);
       
   107     self->ConstructL();
       
   108 
       
   109     return self;
       
   110     }
       
   111 
       
   112 // ---------------------------------------------------------------------------
       
   113 // CESMRICalValue::~CESMRICalValue
       
   114 // ---------------------------------------------------------------------------
       
   115 //
       
   116 CESMRICalValue::~CESMRICalValue()
       
   117     {
       
   118     FUNC_LOG;
       
   119     delete iValue;
       
   120     }
       
   121 
       
   122 // ---------------------------------------------------------------------------
       
   123 // CESMRICalValue::BinaryLC
       
   124 // ---------------------------------------------------------------------------
       
   125 //
       
   126 EXPORT_C HBufC8* CESMRICalValue::BinaryLC() const
       
   127     {
       
   128     FUNC_LOG;
       
   129 
       
   130     CheckNullValueL();
       
   131     HBufC8* buf = HBufC8::NewLC(iValue->Length());
       
   132     buf->Des().Copy(*iValue);
       
   133 
       
   134     return buf;
       
   135     }
       
   136 
       
   137 // ---------------------------------------------------------------------------
       
   138 // CESMRICalValue::SetBinaryL
       
   139 // ---------------------------------------------------------------------------
       
   140 //
       
   141 EXPORT_C void CESMRICalValue::SetBinaryL(const TDesC8& aBuffer)
       
   142     {
       
   143     FUNC_LOG;
       
   144 
       
   145     PrepareValuePointer();
       
   146     iValue = HBufC::NewL(aBuffer.Length());
       
   147     iValue->Des().Copy(aBuffer);
       
   148     }
       
   149 
       
   150 // ---------------------------------------------------------------------------
       
   151 // CESMRICalValue::BooleanL
       
   152 // ---------------------------------------------------------------------------
       
   153 //
       
   154 EXPORT_C TBool CESMRICalValue::BooleanL() const
       
   155     {
       
   156     FUNC_LOG;
       
   157 
       
   158     CheckNullValueL();
       
   159 
       
   160     if (iValue->Des() == KICalTrue)
       
   161         {
       
   162         return ETrue;
       
   163         }
       
   164     else if (iValue->Des() == KICalFalse)
       
   165         {
       
   166         return EFalse;
       
   167         }
       
   168 
       
   169     // Else...
       
   170     User::Leave(KErrCorrupt);
       
   171 
       
   172     return EFalse;  // Never reached.
       
   173     }
       
   174 
       
   175 // ---------------------------------------------------------------------------
       
   176 // CESMRICalValue::SetBooleanL
       
   177 // ---------------------------------------------------------------------------
       
   178 //
       
   179 EXPORT_C void CESMRICalValue::SetBooleanL(TBool aBool)
       
   180     {
       
   181     FUNC_LOG;
       
   182 
       
   183     PrepareValuePointer();
       
   184 
       
   185     if (aBool) // ETrue
       
   186         {
       
   187         iValue = KICalTrue().AllocL();
       
   188         }
       
   189     else    // EFalse
       
   190         {
       
   191         iValue = KICalFalse().AllocL();
       
   192         }
       
   193 
       
   194     }
       
   195 
       
   196 // ---------------------------------------------------------------------------
       
   197 // CESMRICalValue::GetDateL
       
   198 // ---------------------------------------------------------------------------
       
   199 //
       
   200 EXPORT_C void CESMRICalValue::GetDateL(TTime& aDate) const
       
   201     {
       
   202     FUNC_LOG;
       
   203 
       
   204     CheckNullValueL();
       
   205     GetDateFromValueL(aDate);
       
   206 
       
   207     }
       
   208 
       
   209 // ---------------------------------------------------------------------------
       
   210 // CESMRICalValue::SetDateL
       
   211 // ---------------------------------------------------------------------------
       
   212 //
       
   213 EXPORT_C void CESMRICalValue::SetDateL(const TTime& aDate)
       
   214     {
       
   215     FUNC_LOG;
       
   216 
       
   217     PrepareValuePointer();
       
   218     iValue = HBufC::NewL(KICalDateWidth);
       
   219     AppendDateToValueL(aDate);
       
   220 
       
   221     }
       
   222 
       
   223 // ---------------------------------------------------------------------------
       
   224 // CESMRICalValue::GetTimeL
       
   225 // ---------------------------------------------------------------------------
       
   226 //
       
   227 EXPORT_C void CESMRICalValue::GetTimeL(TTime& aTime, TTimeZoneType& aTzType) const
       
   228     {
       
   229     FUNC_LOG;
       
   230 
       
   231     CheckNullValueL();
       
   232     GetTimeFromValueL(aTime, aTzType);
       
   233 
       
   234     }
       
   235 
       
   236 // ---------------------------------------------------------------------------
       
   237 // CESMRICalValue::SetTimeL
       
   238 // ---------------------------------------------------------------------------
       
   239 //
       
   240 EXPORT_C void CESMRICalValue::SetTimeL(const TTime& aTime, TTimeZoneType aTzType)
       
   241     {
       
   242     FUNC_LOG;
       
   243 
       
   244     PrepareValuePointer();
       
   245 
       
   246     if (aTzType == EUtcTime)
       
   247         {
       
   248         iValue = HBufC::NewL(KICalTimeWidth + 1);
       
   249         AppendTimeToValueL(aTime);
       
   250         iValue->Des().Append(KICalUtcChar); // Append a 'Z' to signify UTC.
       
   251         }
       
   252     else if (aTzType == ESpecifiedTimeZone || aTzType == EFloatingTime)
       
   253         {
       
   254         iValue = HBufC::NewL(KICalTimeWidth);
       
   255         AppendTimeToValueL(aTime);
       
   256         }
       
   257 
       
   258     }
       
   259 
       
   260 // ---------------------------------------------------------------------------
       
   261 // CESMRICalValue::GetDateTimeL
       
   262 // ---------------------------------------------------------------------------
       
   263 //
       
   264 EXPORT_C void CESMRICalValue::GetDateTimeL(TTime& aDateTime, TTimeZoneType& aTzType, TInt aFirstCharacterNum) const
       
   265     {
       
   266     FUNC_LOG;
       
   267 
       
   268     CheckNullValueL();
       
   269 
       
   270     // The GetTimeFromValueL() function explicitly sets the TTime passed
       
   271     // in, so create a new TTime for the date and merge with the time later.
       
   272     TTime theDate;
       
   273     GetDateFromValueL(theDate, aFirstCharacterNum);
       
   274 
       
   275     // Only start looking for the time at character position KICalDateWidth
       
   276     // plus one for the 'T' separator.
       
   277     if (iValue->Length() > aFirstCharacterNum + KICalDateWidth + 1)
       
   278         {
       
   279         TTime theTime;
       
   280         if ((*iValue)[aFirstCharacterNum + KICalDateWidth] != KICalDateTimeSeparator)
       
   281             {
       
   282             User::Leave(KErrCorrupt);
       
   283             }
       
   284 
       
   285         GetTimeFromValueL(theTime, aTzType, aFirstCharacterNum + KICalDateWidth + 1);
       
   286 
       
   287         // Set the time component.
       
   288         TDateTime dateValues(theDate.DateTime());
       
   289         TDateTime combinedValues(theTime.DateTime());
       
   290 
       
   291         // Set the date component.
       
   292         combinedValues.SetYear(dateValues.Year());
       
   293         combinedValues.SetMonth(dateValues.Month());
       
   294         combinedValues.SetDay(dateValues.Day());
       
   295 
       
   296         // Set the value to return.
       
   297         aDateTime = TTime(combinedValues);
       
   298         }
       
   299     else
       
   300         {
       
   301         // There is no time component specified.  For compatibility with MS Outlook,
       
   302         // which can export RECURRENCE-ID fields with no time component, we use
       
   303         // a default time of '00:00'
       
   304         aDateTime = theDate;
       
   305         }
       
   306 
       
   307     }
       
   308 
       
   309 // ---------------------------------------------------------------------------
       
   310 // CESMRICalValue::SetDateTimeL
       
   311 // ---------------------------------------------------------------------------
       
   312 //
       
   313 EXPORT_C void CESMRICalValue::SetDateTimeL(const TTime& aDateTime, TTimeZoneType aTzType)
       
   314     {
       
   315     FUNC_LOG;
       
   316 
       
   317     PrepareValuePointer();
       
   318 
       
   319     if (aTzType == EUtcTime)
       
   320         {
       
   321         iValue = HBufC::NewL(KICalDateTimeWidth + 1);
       
   322         AppendDateToValueL(aDateTime);
       
   323 
       
   324         iValue->Des().Append(KICalTimeChar);
       
   325         AppendTimeToValueL(aDateTime);
       
   326 
       
   327         iValue->Des().Append(KICalUtcChar); // For UTC Time.
       
   328         }
       
   329     else if (aTzType == ESpecifiedTimeZone || aTzType == EFloatingTime)
       
   330         {
       
   331         iValue = HBufC::NewL(KICalDateTimeWidth);
       
   332         AppendDateToValueL(aDateTime);
       
   333 
       
   334         iValue->Des().Append(KICalTimeChar);
       
   335         AppendTimeToValueL(aDateTime);
       
   336         }
       
   337 
       
   338     }
       
   339 
       
   340 // ---------------------------------------------------------------------------
       
   341 // CESMRICalValue::DurationL
       
   342 // ---------------------------------------------------------------------------
       
   343 //
       
   344 EXPORT_C TTimeIntervalSeconds CESMRICalValue::DurationL() const
       
   345     {
       
   346     FUNC_LOG;
       
   347 
       
   348     CheckNullValueL();
       
   349     TTimeIntervalSeconds theTis;
       
   350     GetTimeIntervalFromValueL(theTis);
       
   351 
       
   352     return theTis;
       
   353     }
       
   354 
       
   355 // ---------------------------------------------------------------------------
       
   356 // CESMRICalValue::SetDurationL
       
   357 // ---------------------------------------------------------------------------
       
   358 //
       
   359 EXPORT_C void CESMRICalValue::SetDurationL(TTimeIntervalSeconds aDuration)
       
   360     {
       
   361     FUNC_LOG;
       
   362 
       
   363     // e.g. P15DT5H0M20S
       
   364     PrepareValuePointer();
       
   365 
       
   366     iValue = HBufC::NewL(KICalDurationWidth);
       
   367     TInt durInt(aDuration.Int());
       
   368 
       
   369     if (durInt < 0)
       
   370         {
       
   371         // First character is a '-' for negative values
       
   372         iValue->Des().Append(KICalNegativeChar);
       
   373 
       
   374         // Now we've set the sign, change the durInt to +ve
       
   375         durInt =- durInt;
       
   376         }
       
   377 
       
   378     iValue->Des().Append(KICalDurationChar);
       
   379 
       
   380     // Add day portion.
       
   381     TInt numDays(durInt / KICalSecondsPerDay);
       
   382     durInt -= (numDays * KICalSecondsPerDay);
       
   383     iValue->Des().AppendNum(numDays);
       
   384     iValue->Des().Append(KICalDayChar);
       
   385     iValue->Des().Append(KICalTimeChar);
       
   386 
       
   387     // Add hour portion.
       
   388     TInt numHours(durInt / KICalSecondsPerHour);
       
   389     durInt -= (numHours * KICalSecondsPerHour);
       
   390     iValue->Des().AppendNum(numHours);
       
   391     iValue->Des().Append(KICalHourChar);
       
   392 
       
   393     // Add minute portion.
       
   394     TInt numMinutes(durInt / KICalSecondsPerMinute);
       
   395     durInt -= (numMinutes * KICalSecondsPerMinute);
       
   396     iValue->Des().AppendNum(numMinutes);
       
   397     iValue->Des().Append(KICalMinuteChar);
       
   398 
       
   399     // Add second portion.
       
   400     TInt numSeconds(durInt);
       
   401     iValue->Des().AppendNum(numSeconds);
       
   402     iValue->Des().Append(KICalSecondChar);
       
   403 
       
   404     }
       
   405 
       
   406 // ---------------------------------------------------------------------------
       
   407 // CESMRICalValue::GetFloatL
       
   408 // ---------------------------------------------------------------------------
       
   409 //
       
   410 EXPORT_C void CESMRICalValue::GetFloatL(TReal& aFloat) const
       
   411     {
       
   412     FUNC_LOG;
       
   413 
       
   414     CheckNullValueL();
       
   415     TLex stringLex(iValue->Des());
       
   416     User::LeaveIfError(stringLex.Val(aFloat));
       
   417 
       
   418     }
       
   419 
       
   420 // ---------------------------------------------------------------------------
       
   421 // CESMRICalValue::SetFloatL
       
   422 // ---------------------------------------------------------------------------
       
   423 //
       
   424 EXPORT_C void CESMRICalValue::SetFloatL(const TReal& aFloat)
       
   425     {
       
   426     FUNC_LOG;
       
   427 
       
   428     PrepareValuePointer();
       
   429 
       
   430     iValue = HBufC::NewL(KDefaultRealWidth);
       
   431     TRealFormat format;
       
   432     iValue->Des().Num(aFloat, format);
       
   433 
       
   434     }
       
   435 
       
   436 // ---------------------------------------------------------------------------
       
   437 // CESMRICalValue::IntegerL
       
   438 // ---------------------------------------------------------------------------
       
   439 //
       
   440 EXPORT_C TInt CESMRICalValue::IntegerL() const
       
   441     {
       
   442     FUNC_LOG;
       
   443 
       
   444     CheckNullValueL();
       
   445 
       
   446     return ReadIntL(iValue->Des());
       
   447     }
       
   448 
       
   449 // ---------------------------------------------------------------------------
       
   450 // CESMRICalValue::SetIntegerL
       
   451 // ---------------------------------------------------------------------------
       
   452 //
       
   453 EXPORT_C void CESMRICalValue::SetIntegerL(TInt aInt)
       
   454     {
       
   455     FUNC_LOG;
       
   456 
       
   457     PrepareValuePointer();
       
   458     iValue = HBufC::NewL(KICalTIntWidth);
       
   459     iValue->Des().Num(aInt);
       
   460 
       
   461     }
       
   462 
       
   463 // ---------------------------------------------------------------------------
       
   464 // CESMRICalValue::GetPeriodL
       
   465 // ---------------------------------------------------------------------------
       
   466 //
       
   467 EXPORT_C void CESMRICalValue::GetPeriodL(
       
   468     TTime& aStartTime,
       
   469     TTimeZoneType& aStartTzType,
       
   470     TTime& aEndTime,
       
   471     TTimeZoneType& aEndTzType) const
       
   472     {
       
   473     FUNC_LOG;
       
   474 
       
   475     // Example :   19970101T180000Z/19970102T070000Z
       
   476     // that is : yyyymmddThhmmss[Z]/yyyymmddThhmmss[Z]
       
   477 
       
   478     // Example2:   19970101T180000Z/PT5H30M
       
   479     // that is2: yyyymmddThhmmss[Z]/[+/-]P[lots of stuff]
       
   480 
       
   481     // As the first part is always a date-time, get this out to start off with
       
   482     GetDateTimeL(aStartTime, aStartTzType, 0);
       
   483 
       
   484     // Next we need to get the position of the separator.
       
   485     TInt charNumber(iValue->Des().Locate(KICalPeriodChar));
       
   486     User::LeaveIfError(charNumber);
       
   487 
       
   488     // If the character after the separator is a 'P', '+' or '-' the second part is a duration.
       
   489     ++charNumber;
       
   490     if (charNumber >= iValue->Length())
       
   491         {
       
   492         User::Leave(KErrCorrupt);
       
   493         }
       
   494 
       
   495     TChar theChar(iValue->Des()[charNumber]);
       
   496 
       
   497     if ((theChar == KICalDurationChar) ||
       
   498         (theChar == KICalPositiveChar) ||
       
   499         (theChar == KICalNegativeChar))
       
   500         {
       
   501         // Call a function to change the duration into a TTime (date + time)
       
   502         TTimeIntervalSeconds interval;
       
   503         GetTimeIntervalFromValueL(interval, charNumber);
       
   504 
       
   505         // Convert from this TimeInterval to a TTime
       
   506         aEndTime = aStartTime;
       
   507         aEndTime += interval;
       
   508 
       
   509         // The timezone will be the same as the first.
       
   510         aEndTzType = aStartTzType;
       
   511         }
       
   512     else // Presume it's a date-time
       
   513         {
       
   514         GetDateTimeL(aEndTime, aEndTzType, charNumber);
       
   515         }
       
   516 
       
   517     }
       
   518 
       
   519 // ---------------------------------------------------------------------------
       
   520 // CESMRICalValue::SetPeriodL
       
   521 // ---------------------------------------------------------------------------
       
   522 //
       
   523 EXPORT_C void CESMRICalValue::SetPeriodL(
       
   524     const TTime& aStartTime,
       
   525     TTimeZoneType aStartTzType,
       
   526     const TTime& aEndTime,
       
   527     TTimeZoneType aEndTzType)
       
   528     {
       
   529     FUNC_LOG;
       
   530 
       
   531     // Example:   19970101T180000Z/19970102T070000Z
       
   532     // that is: yyyymmddThhmmss[Z]/yyyymmddThhmmss[Z]
       
   533 
       
   534     PrepareValuePointer();
       
   535 
       
   536     SetDateTimeL(aStartTime, aStartTzType);
       
   537 
       
   538     if (aEndTzType == EUtcTime)
       
   539         {
       
   540         iValue->ReAllocL(iValue->Length() + 2 + KICalDateTimeWidth);
       
   541         iValue->Des().Append(KICalPeriodChar);
       
   542 
       
   543         AppendDateToValueL(aEndTime);
       
   544         iValue->Des().Append(KICalTimeChar);
       
   545 
       
   546         AppendTimeToValueL(aEndTime);
       
   547         iValue->Des().Append(KICalUtcChar);
       
   548         }
       
   549     else if (aEndTzType == ESpecifiedTimeZone || aEndTzType == EFloatingTime)
       
   550         {
       
   551         iValue->ReAllocL(iValue->Length() + 1 + KICalDateTimeWidth);
       
   552 
       
   553         iValue->Des().Append(KICalPeriodChar);
       
   554         AppendDateToValueL(aEndTime);
       
   555 
       
   556         iValue->Des().Append(KICalTimeChar);
       
   557         AppendTimeToValueL(aEndTime);
       
   558         }
       
   559 
       
   560     }
       
   561 
       
   562 // ---------------------------------------------------------------------------
       
   563 // CESMRICalValue::GetDayL
       
   564 // ---------------------------------------------------------------------------
       
   565 //
       
   566 EXPORT_C void CESMRICalValue::GetDayL(TDay& aDay, TInt& aPos) const
       
   567     {
       
   568     FUNC_LOG;
       
   569 
       
   570     CheckNullValueL();
       
   571 
       
   572     // Find the end of the numeric part.
       
   573     _LIT(KICalDayNumeric, "-+0123456789");
       
   574     TInt endNumeric(0);
       
   575 
       
   576     while (endNumeric < iValue->Length())
       
   577         {
       
   578         if (KICalDayNumeric().Locate((*iValue)[endNumeric]) == KErrNotFound)
       
   579             {
       
   580             break;
       
   581             }
       
   582 
       
   583         ++endNumeric;
       
   584         }
       
   585 
       
   586     // Set the numeric part.
       
   587     if (endNumeric != 0)
       
   588         {
       
   589         aPos = ReadIntL(iValue->Left(endNumeric));
       
   590         }
       
   591     else
       
   592         {
       
   593         aPos = 0;
       
   594         }
       
   595 
       
   596     // Set the day part.
       
   597     HBufC* dayStrBuf = iValue->Mid(endNumeric).AllocLC();
       
   598     TPtr dayStr( dayStrBuf->Des() );
       
   599     dayStr.TrimLeft();
       
   600 
       
   601     if (dayStr.CompareF(KICalMonday) == 0)
       
   602         {
       
   603         aDay = EMonday;
       
   604         }
       
   605     else if (dayStr.CompareF(KICalTuesday) == 0)
       
   606         {
       
   607         aDay = ETuesday;
       
   608         }
       
   609     else if (dayStr.CompareF(KICalWednesday) == 0)
       
   610         {
       
   611         aDay = EWednesday;
       
   612         }
       
   613     else if (dayStr.CompareF(KICalThursday) == 0)
       
   614         {
       
   615         aDay = EThursday;
       
   616         }
       
   617     else if (dayStr.CompareF(KICalFriday) == 0)
       
   618         {
       
   619         aDay = EFriday;
       
   620         }
       
   621     else if (dayStr.CompareF(KICalSaturday) == 0)
       
   622         {
       
   623         aDay = ESaturday;
       
   624         }
       
   625     else if (dayStr.CompareF(KICalSunday) == 0)
       
   626         {
       
   627         aDay = ESunday;
       
   628         }
       
   629     else
       
   630         {
       
   631         User::Leave(KErrCorrupt);   // Invalid day.
       
   632         }
       
   633 
       
   634     CleanupStack::PopAndDestroy( dayStrBuf );
       
   635     dayStrBuf = NULL;
       
   636 
       
   637     }
       
   638 
       
   639 // ---------------------------------------------------------------------------
       
   640 // CESMRICalValue::SetDayL
       
   641 // ---------------------------------------------------------------------------
       
   642 //
       
   643 EXPORT_C void CESMRICalValue::SetDayL(TDay aDay, TInt aPos)
       
   644     {
       
   645     FUNC_LOG;
       
   646 
       
   647     PrepareValuePointer();
       
   648 
       
   649     // Get the day as a descriptor.
       
   650     TPtrC dayName;
       
   651 
       
   652     switch (aDay)
       
   653         {
       
   654         case EMonday:
       
   655             dayName.Set(KICalMonday());
       
   656             break;
       
   657         case ETuesday:
       
   658             dayName.Set(KICalTuesday());
       
   659             break;
       
   660         case EWednesday:
       
   661             dayName.Set(KICalWednesday());
       
   662             break;
       
   663         case EThursday:
       
   664             dayName.Set(KICalThursday());
       
   665             break;
       
   666         case EFriday:
       
   667             dayName.Set(KICalFriday());
       
   668             break;
       
   669         case ESaturday:
       
   670             dayName.Set(KICalSaturday());
       
   671             break;
       
   672         case ESunday:
       
   673             dayName.Set(KICalSunday());
       
   674             break;
       
   675         default:
       
   676             User::Leave(KErrUnknown);
       
   677             break;
       
   678         }
       
   679 
       
   680     // We need space for a number and a day name.
       
   681     iValue = HBufC::NewL(KICalTIntWidth + dayName.Length());
       
   682     iValue->Des().AppendNum(aPos);
       
   683     iValue->Des().Append(dayName);
       
   684 
       
   685     }
       
   686 
       
   687 // ---------------------------------------------------------------------------
       
   688 // CESMRICalValue::MonthL
       
   689 // ---------------------------------------------------------------------------
       
   690 //
       
   691 EXPORT_C TMonth CESMRICalValue::MonthL() const
       
   692     {
       
   693     FUNC_LOG;
       
   694 
       
   695     CheckNullValueL();
       
   696 
       
   697     TInt num(IntegerL());
       
   698 
       
   699     if ((num < 1) || (num > 12))
       
   700         {
       
   701         User::Leave(KErrCorrupt);
       
   702         }
       
   703 
       
   704     return static_cast<TMonth>(num - 1);
       
   705     }
       
   706 
       
   707 // ---------------------------------------------------------------------------
       
   708 // CESMRICalValue::SetMonthL
       
   709 // ---------------------------------------------------------------------------
       
   710 //
       
   711 EXPORT_C void CESMRICalValue::SetMonthL(TMonth aMonth)
       
   712     {
       
   713     FUNC_LOG;
       
   714 
       
   715     PrepareValuePointer();
       
   716     SetIntegerL(aMonth + 1);
       
   717 
       
   718     }
       
   719 
       
   720 // ---------------------------------------------------------------------------
       
   721 // CESMRICalValue::GetRecurrenceRuleL
       
   722 // ---------------------------------------------------------------------------
       
   723 //
       
   724 EXPORT_C void CESMRICalValue::GetRecurrenceRuleL(RPointerArray<CESMRICalRuleSegment>& aRuleSegmentArray) const
       
   725     {
       
   726     FUNC_LOG;
       
   727 
       
   728     CheckNullValueL();
       
   729 
       
   730     // Find the first semicolon:
       
   731     TInt nextSemiColon(iValue->Locate(KICalSemiColonChar));
       
   732 
       
   733     if (nextSemiColon == KErrNotFound)
       
   734         {
       
   735         // This means there is only one segment, pretend the semicolon exists at the end of the buffer
       
   736         nextSemiColon = iValue->Length();
       
   737         }
       
   738 
       
   739     TUint charNum(0);
       
   740 
       
   741     do
       
   742         {
       
   743         // Create a rule segment from characters charNum to nextSemiColon
       
   744         CESMRICalRuleSegment* theRule = CESMRICalRuleSegment::NewLC(iValue->Mid(charNum, nextSemiColon - charNum));
       
   745         User::LeaveIfError(aRuleSegmentArray.Append(theRule));  // Takes ownership.
       
   746         CleanupStack::Pop(theRule);
       
   747 
       
   748         // Put the character marker past the current semicolon
       
   749         charNum = nextSemiColon + 1;
       
   750 
       
   751         // We only want to check for any more semicolons in the area to the right of charNum.
       
   752         // First check if there are ANY characters to the right of charNum
       
   753         if (charNum < iValue->Length())
       
   754             {
       
   755             // Find the location of the next semi colon in this area.
       
   756             nextSemiColon = iValue->Right(iValue->Length() - charNum).Locate(KICalSemiColonChar);
       
   757 
       
   758             if (nextSemiColon != KErrNotFound)
       
   759                 {
       
   760                 // Set the semicolon to be in it's correct position, shifted to take into account the fact
       
   761                 // that we were only looking in the right part of the original descriptor.
       
   762                 nextSemiColon += charNum;
       
   763                 }
       
   764             else
       
   765                 {
       
   766                 // There are no more semicolons, read in the last value and then exit the loop
       
   767                 nextSemiColon = iValue->Length();
       
   768                 }
       
   769             }
       
   770         }
       
   771     while (charNum < iValue->Length());
       
   772 
       
   773     }
       
   774 
       
   775 // ---------------------------------------------------------------------------
       
   776 // CESMRICalValue::SetRecurrenceRuleL
       
   777 // ---------------------------------------------------------------------------
       
   778 //
       
   779 EXPORT_C void CESMRICalValue::SetRecurrenceRuleL(const TDesC& aRuleValue)
       
   780     {
       
   781     FUNC_LOG;
       
   782 
       
   783     PrepareValuePointer();
       
   784     iValue = aRuleValue.AllocL();
       
   785 
       
   786     }
       
   787 
       
   788 // ---------------------------------------------------------------------------
       
   789 // CESMRICalValue::TextL
       
   790 // ---------------------------------------------------------------------------
       
   791 //
       
   792 EXPORT_C const TDesC& CESMRICalValue::TextL() const
       
   793     {
       
   794     FUNC_LOG;
       
   795 
       
   796     CheckNullValueL();
       
   797 
       
   798     return *iValue;
       
   799     }
       
   800 
       
   801 // ---------------------------------------------------------------------------
       
   802 // CESMRICalValue::SetTextL
       
   803 // ---------------------------------------------------------------------------
       
   804 //
       
   805 EXPORT_C void CESMRICalValue::SetTextL(const TDesC& aText)
       
   806     {
       
   807     FUNC_LOG;
       
   808 
       
   809     PrepareValuePointer();
       
   810     iValue = aText.AllocL();
       
   811 
       
   812     }
       
   813 
       
   814 // ---------------------------------------------------------------------------
       
   815 // CESMRICalValue::UtcOffsetL
       
   816 // ---------------------------------------------------------------------------
       
   817 //
       
   818 EXPORT_C TTimeIntervalSeconds CESMRICalValue::UtcOffsetL() const
       
   819     {
       
   820     FUNC_LOG;
       
   821 
       
   822     // Format is (e.g.) +1000 (10 hours ahead) or -013045 (1.5 hours and 45 seconds behind).
       
   823     CheckNullValueL();
       
   824 
       
   825     const TInt length = iValue->Length();
       
   826 
       
   827     if ((length != KLongFormatUtcOffsetWidth) && (length != KShortFormatUtcOffsetWidth))
       
   828         {
       
   829         // Invalid UTC Offset - we can't really test more than this, so the output may be garbage
       
   830         User::Leave(KErrCorrupt);
       
   831         }
       
   832 
       
   833     // Get the value of the hour component.
       
   834     TInt hours(ReadIntL(iValue->Des().Left(3)));    // '+' or '-' plus the hours component.
       
   835 
       
   836     // Get the value of the minute component.
       
   837     TInt minutes(ReadIntL(iValue->Des().Mid(3, 2)));    // The minutes component.
       
   838 
       
   839     // Get the value of the (optional) second component.
       
   840     TInt seconds(0);
       
   841 
       
   842     if (length == KLongFormatUtcOffsetWidth)    // Long format.
       
   843         {
       
   844         seconds = ReadIntL(iValue->Des().Mid(5, 2));    // The second component.
       
   845         }
       
   846 
       
   847     // Convert to TTimeIntervalSeconds.
       
   848     return TTimeIntervalSeconds((hours * KICalSecondsPerHour) + (minutes * KICalSecondsPerMinute) + seconds);
       
   849     }
       
   850 
       
   851 // ---------------------------------------------------------------------------
       
   852 // CESMRICalValue::SetUtcOffsetL
       
   853 // ---------------------------------------------------------------------------
       
   854 //
       
   855 EXPORT_C void CESMRICalValue::SetUtcOffsetL(TTimeIntervalSeconds aOffset)
       
   856     {
       
   857     FUNC_LOG;
       
   858 
       
   859     // Format is (e.g.) +1000 (10 hours ahead) or -013045 (1.5 hours and 45 seconds behind).
       
   860     PrepareValuePointer();
       
   861 
       
   862     // Create a buffer long enough to hold the widest format.
       
   863     iValue = HBufC::NewL(KLongFormatUtcOffsetWidth);
       
   864 
       
   865     // Get the offset as an integer.
       
   866     TInt offset(aOffset.Int());
       
   867 
       
   868     // Set the sign.
       
   869     if (offset < 0)
       
   870         {
       
   871         iValue->Des().Append(KICalNegativeChar);
       
   872 
       
   873         // Set offset to positive for calculations.
       
   874         offset =- offset;
       
   875         }
       
   876     else
       
   877         {
       
   878         iValue->Des().Append(KICalPositiveChar);
       
   879         }
       
   880 
       
   881     // Add hour portion.
       
   882     TInt numHours(offset / KICalSecondsPerHour);
       
   883     offset -= (numHours * KICalSecondsPerHour);
       
   884     iValue->Des().AppendNumFixedWidth(numHours, EDecimal, 2);
       
   885 
       
   886     // Add minute portion.
       
   887     TInt numMinutes(offset / KICalSecondsPerMinute);
       
   888     offset -= (numMinutes * KICalSecondsPerMinute);
       
   889     iValue->Des().AppendNumFixedWidth(numMinutes, EDecimal, 2);
       
   890 
       
   891     // Add second portion if necessary.
       
   892     if (offset > 0)
       
   893         {
       
   894         iValue->Des().AppendNumFixedWidth(offset, EDecimal, 2);
       
   895         }
       
   896 
       
   897     }
       
   898 
       
   899 // ---------------------------------------------------------------------------
       
   900 // CESMRICalValue::CESMRICalValue
       
   901 // ---------------------------------------------------------------------------
       
   902 //
       
   903 CESMRICalValue::CESMRICalValue()
       
   904     {
       
   905     FUNC_LOG;
       
   906     }
       
   907 
       
   908 // ---------------------------------------------------------------------------
       
   909 // CESMRICalValue::ConstructL
       
   910 // ---------------------------------------------------------------------------
       
   911 //
       
   912 void CESMRICalValue::ConstructL()
       
   913     {
       
   914     FUNC_LOG;
       
   915     }
       
   916 
       
   917 // ---------------------------------------------------------------------------
       
   918 // CESMRICalValue::CheckNullValueL
       
   919 // ---------------------------------------------------------------------------
       
   920 //
       
   921 /**
       
   922 Checks for a NULL value. Should be called before accessing iValue.
       
   923 @leave Leaves with KErrCorrupt if the value is NULL.
       
   924 @internalTechnology
       
   925 */
       
   926 void CESMRICalValue::CheckNullValueL() const
       
   927     {
       
   928     FUNC_LOG;
       
   929 
       
   930     if (!iValue)
       
   931         {
       
   932         User::Leave(KErrCorrupt);
       
   933         }
       
   934 
       
   935     }
       
   936 
       
   937 // ---------------------------------------------------------------------------
       
   938 // CESMRICalValue::PrepareValuePointer
       
   939 // ---------------------------------------------------------------------------
       
   940 //
       
   941 /**
       
   942 Prepares iValue pointer for writing. Deletes existing pointer if it exists.
       
   943 @internalTechnology
       
   944 */
       
   945 void CESMRICalValue::PrepareValuePointer()
       
   946     {
       
   947     FUNC_LOG;
       
   948 
       
   949     if (iValue)
       
   950         {
       
   951         delete iValue;
       
   952         iValue = NULL;
       
   953         }
       
   954 
       
   955     }
       
   956 
       
   957 // ---------------------------------------------------------------------------
       
   958 // CESMRICalValue::ReadIntL
       
   959 // ---------------------------------------------------------------------------
       
   960 //
       
   961 /**
       
   962 Reads a TInt from the given descriptor.
       
   963 @param aDes The descriptor to convert
       
   964 @return The integer conversion.
       
   965 @leave Leaves if there is an error reading an integer.
       
   966 @internalTechnology
       
   967 */
       
   968 TInt CESMRICalValue::ReadIntL(const TDesC& aDes) const
       
   969     {
       
   970     FUNC_LOG;
       
   971 
       
   972     TLex stringLex(aDes);
       
   973     TInt returnValue(0);
       
   974     User::LeaveIfError(stringLex.Val(returnValue));
       
   975 
       
   976     return returnValue;
       
   977     }
       
   978 
       
   979 // ---------------------------------------------------------------------------
       
   980 // CESMRICalValue::AppendDateToValueL
       
   981 // ---------------------------------------------------------------------------
       
   982 //
       
   983 /**
       
   984 Appends the date to iValue. Member iValue must be initialised before calling.
       
   985 @param aDate TTime to append to the value.
       
   986 @internalTechnology
       
   987 */
       
   988 void CESMRICalValue::AppendDateToValueL(const TTime& aDate)
       
   989     {
       
   990     FUNC_LOG;
       
   991 
       
   992     TBuf<KICalDateWidth> formattedDate;
       
   993     aDate.FormatL(formattedDate, KICalDateFormat);
       
   994     iValue->Des().Append(formattedDate);
       
   995 
       
   996     }
       
   997 
       
   998 // ---------------------------------------------------------------------------
       
   999 // CESMRICalValue::GetDateFromValueL
       
  1000 // ---------------------------------------------------------------------------
       
  1001 //
       
  1002 /**
       
  1003 Gets the date from iValue descriptor. Should be in the format YYYYMMDD
       
  1004 @param aDate A modifiable reference returning a date.
       
  1005 @param aFirstCharacterNum Skip this many characters at the start of the value.
       
  1006 @leave Leaves with KErrCorrupt if the format of the value is not a valid date.
       
  1007 @internalTechnology
       
  1008 */
       
  1009 void CESMRICalValue::GetDateFromValueL(TTime& aDate, TInt aFirstCharacterNum) const
       
  1010     {
       
  1011     FUNC_LOG;
       
  1012 
       
  1013     if (aFirstCharacterNum + KICalDateWidth > iValue->Length())
       
  1014         {
       
  1015         User::Leave(KErrCorrupt);
       
  1016         }
       
  1017 
       
  1018     // Get the year as an int.
       
  1019     TInt year(ReadIntL(iValue->Des().Mid(aFirstCharacterNum, 4)));  // YYYYmmdd
       
  1020 
       
  1021     if (year < 0)   // All positive years are valid
       
  1022         {
       
  1023         User::Leave(KErrCorrupt);
       
  1024         }
       
  1025 
       
  1026     // Get the month as an int.
       
  1027     TInt month(ReadIntL(iValue->Mid(aFirstCharacterNum + 4, 2)));   // yyyMMdd
       
  1028 
       
  1029     if ((month < 1) || (month > 12))
       
  1030         {
       
  1031         User::Leave(KErrCorrupt);
       
  1032         }
       
  1033 
       
  1034     // Get the day as an int.
       
  1035     TInt day(ReadIntL(iValue->Mid(aFirstCharacterNum + 6, 2))); // yyyymmDD
       
  1036 
       
  1037     if ((day < 1) || (day > Time::DaysInMonth(year, static_cast<TMonth>(month - 1))))   // Zero-offset month.
       
  1038         {
       
  1039         User::Leave(KErrCorrupt);
       
  1040         }
       
  1041 
       
  1042     // Set the date from its component parts.
       
  1043     aDate = 0;
       
  1044     aDate += TTimeIntervalYears(year);
       
  1045     aDate += TTimeIntervalMonths(month - 1);    // Zero-offset.
       
  1046     aDate += TTimeIntervalDays(day - 1);        // Zero-offset.
       
  1047 
       
  1048     }
       
  1049 
       
  1050 // ---------------------------------------------------------------------------
       
  1051 // CESMRICalValue::AppendTimeToValueL
       
  1052 // ---------------------------------------------------------------------------
       
  1053 //
       
  1054 /**
       
  1055 Appends the time to iValue. Member iValue must be initialised before calling.
       
  1056 @param aTime TTime to append to the value.
       
  1057 @internalTechnology
       
  1058 */
       
  1059 void CESMRICalValue::AppendTimeToValueL(const TTime& aTime)
       
  1060     {
       
  1061     FUNC_LOG;
       
  1062 
       
  1063     // Format is HHMMSS followed optionally by a Z for UTC time.
       
  1064     // Note that the 'Z' is not appended here.
       
  1065     TDateTime fullTime(aTime.DateTime());
       
  1066 
       
  1067     iValue->Des().AppendNumFixedWidth(fullTime.Hour(), EDecimal, 2);
       
  1068     iValue->Des().AppendNumFixedWidth(fullTime.Minute(), EDecimal, 2);
       
  1069     iValue->Des().AppendNumFixedWidth(fullTime.Second(), EDecimal, 2);
       
  1070 
       
  1071     }
       
  1072 
       
  1073 // ---------------------------------------------------------------------------
       
  1074 // CESMRICalValue::GetTimeFromValueL
       
  1075 // ---------------------------------------------------------------------------
       
  1076 //
       
  1077 /**
       
  1078 Gets the time from iValue descriptor, starting from a pre-determined point.
       
  1079 Should be in the format HHMMSS[Z]
       
  1080 @param aTime TTime to store result of read in
       
  1081 @param aTzType Enumeration showing whether the time represents local time (not
       
  1082 supported), UTC or a custom time zone.
       
  1083 @param aFirstCharacterNum The character number to start searching from.
       
  1084 @leave Leaves with KErrCorrupt if the value does not hold a valid time.
       
  1085 @internalTechnology
       
  1086 */
       
  1087 void CESMRICalValue::GetTimeFromValueL(TTime& aTime, TTimeZoneType& aTzType, TInt aFirstCharacterNum) const
       
  1088     {
       
  1089     FUNC_LOG;
       
  1090 
       
  1091     if (aFirstCharacterNum + KICalTimeWidth > iValue->Length())
       
  1092         {
       
  1093         User::Leave(KErrCorrupt);
       
  1094         }
       
  1095 
       
  1096     // Create a new descriptor containing just the first KICalTimeWidth characters of iValue
       
  1097     // It's size is one larger as we will need to add a full stop (see below)
       
  1098     HBufC* formattedTime = HBufC::NewLC(iValue->Des().Mid(aFirstCharacterNum, KICalTimeWidth).Length() + 1);
       
  1099     *formattedTime = iValue->Des().Mid(aFirstCharacterNum, KICalTimeWidth);
       
  1100 
       
  1101     // The only formatting needed is to append a full stop
       
  1102     formattedTime->Des().Append(KICalMicroChar);
       
  1103 
       
  1104     if (aTime.Set(*formattedTime))
       
  1105         {
       
  1106         User::Leave(KErrCorrupt);
       
  1107         }
       
  1108 
       
  1109     if ((iValue->Length() > (KICalTimeWidth + aFirstCharacterNum)) &&
       
  1110         (iValue->Des()[KICalTimeWidth + aFirstCharacterNum] == KICalUtcChar))
       
  1111         {
       
  1112         aTzType = EUtcTime;
       
  1113         }
       
  1114     else
       
  1115         {//DAVIDTODO:
       
  1116         // If there is no 'Z' character then assume that there
       
  1117         // is a specified time zone - EFloatingTime is not used.
       
  1118         aTzType = ESpecifiedTimeZone;
       
  1119         }
       
  1120 
       
  1121     CleanupStack::PopAndDestroy(formattedTime);
       
  1122 
       
  1123     }
       
  1124 
       
  1125 // ---------------------------------------------------------------------------
       
  1126 // CESMRICalValue::GetTimeIntervalFromValueL
       
  1127 // ---------------------------------------------------------------------------
       
  1128 //
       
  1129 /**
       
  1130 Retrieves a time interval stored as a duration as per the RFC 2445
       
  1131 specification.
       
  1132 @param aTimeInterval TTimeIntervalSeconds to store the result in.
       
  1133 @param aFirstCharacterNum The position in the value containing the first
       
  1134 character of the duration.
       
  1135 @leave Leaves with KErrCorrupt if the value does not hold a valid interval.
       
  1136 @internalTechnology
       
  1137 */
       
  1138 void CESMRICalValue::GetTimeIntervalFromValueL(TTimeIntervalSeconds& aTimeInterval, TInt aFirstCharacterNum) const
       
  1139     {
       
  1140     FUNC_LOG;
       
  1141 
       
  1142     //     dur-value  = (["+"] / "-") "P" (dur-date / dur-time / dur-week)
       
  1143     //     dur-date   = dur-day [dur-time]
       
  1144     //     dur-time   = "T" (dur-hour / dur-minute / dur-second)
       
  1145     //     dur-week   = 1*DIGIT "W"
       
  1146     //     dur-hour   = 1*DIGIT "H" [dur-minute]
       
  1147     //     dur-minute = 1*DIGIT "M" [dur-second]
       
  1148     //     dur-second = 1*DIGIT "S"
       
  1149     //     dur-day    = 1*DIGIT "D"
       
  1150 
       
  1151     // Example: A duration of 15 days, 5 hours and 20 seconds would be:
       
  1152     //     P15DT5H0M20S
       
  1153     // A duration of 7 weeks would be:
       
  1154     //     P7W
       
  1155 
       
  1156     TInt intervalMultiplier(1); // This variable sets the interval to be positive or negative.
       
  1157 
       
  1158     // Length should be at least two.
       
  1159     if ((aFirstCharacterNum >= iValue->Length()) || (iValue->Length() < 2 + aFirstCharacterNum))
       
  1160         {
       
  1161         User::Leave(KErrCorrupt);
       
  1162         }
       
  1163 
       
  1164     // Check that the first character is a 'P', '+' or '-' and adjust the interval accordingly.
       
  1165     TChar firstCharacter(iValue->Des()[aFirstCharacterNum]);
       
  1166 
       
  1167     if (firstCharacter == KICalDurationChar)
       
  1168         {
       
  1169         intervalMultiplier = 1;
       
  1170         aFirstCharacterNum += 1; // Skip the "P"
       
  1171         }
       
  1172     else if (firstCharacter == KICalPositiveChar)
       
  1173         {
       
  1174         intervalMultiplier = 1;
       
  1175         aFirstCharacterNum += 2; // Skip the "+P"
       
  1176         }
       
  1177     else if (firstCharacter == KICalNegativeChar)
       
  1178         {
       
  1179         intervalMultiplier = -1;
       
  1180         aFirstCharacterNum += 2; // Skip the "-P"
       
  1181         }
       
  1182     else
       
  1183         {
       
  1184         User::Leave(KErrCorrupt);
       
  1185         }
       
  1186 
       
  1187     // It can only contain a dur-date, or a dur-time, or a dur-week
       
  1188     TInt theInterval(0);
       
  1189     if (!GetDurDateL(theInterval, aFirstCharacterNum))
       
  1190         {
       
  1191         if (!GetDurTimeL(theInterval, aFirstCharacterNum))
       
  1192             {
       
  1193             if (!GetDurWeekL(theInterval, aFirstCharacterNum))
       
  1194                 {
       
  1195                 User::Leave(KErrCorrupt);
       
  1196                 }
       
  1197             }
       
  1198         }
       
  1199 
       
  1200     theInterval *= intervalMultiplier;
       
  1201 
       
  1202     // Now we've done the multiply we can convert it into a TTimeIntervalSeconds
       
  1203     aTimeInterval = theInterval;
       
  1204     }
       
  1205 
       
  1206 // ---------------------------------------------------------------------------
       
  1207 // CESMRICalValue::GetDurDateL
       
  1208 // ---------------------------------------------------------------------------
       
  1209 //
       
  1210 /**
       
  1211 Reads in and converts a dur-day into a number of seconds
       
  1212 @param aIntervalSecs Function adds number of seconds to this variable.
       
  1213 @param aCurrentCharNumber Character number to start looking in the value.
       
  1214 @return ETrue if the value could be interpreted as a dur-date, EFalse otherwise.
       
  1215 @internalTechnology
       
  1216 */
       
  1217 TBool CESMRICalValue::GetDurDateL(TInt& aIntervalSecs, TInt& aCurrentCharNumber) const
       
  1218     {
       
  1219     FUNC_LOG;
       
  1220 
       
  1221     //  dur-date   = dur-day [dur-time]
       
  1222     //  dur-day    = 1*DIGIT "D"
       
  1223 
       
  1224     if (aCurrentCharNumber >= iValue->Length())
       
  1225         {
       
  1226         return EFalse;
       
  1227         }
       
  1228 
       
  1229     // Create a new TPtrC containing the data from iValue which we need.
       
  1230     TPtrC data(iValue->Mid(aCurrentCharNumber));
       
  1231 
       
  1232     // Find the next 'D' in the descriptor.
       
  1233     TInt nextDPos(data.Locate(KICalDayChar));
       
  1234 
       
  1235     // Check it exists
       
  1236     if (nextDPos != KErrNotFound)
       
  1237         {
       
  1238         // If character found, construct a number from currentCharNumber to nextDPos
       
  1239         TInt theNum(ReadIntL(data.Left(nextDPos)));
       
  1240 
       
  1241         // Convert this time from days to seconds
       
  1242         theNum *= KICalSecondsPerDay;
       
  1243         aIntervalSecs += theNum;
       
  1244         aCurrentCharNumber += nextDPos + 1; // Extra increment to get past the 'D'
       
  1245 
       
  1246         // Check if a dur-time follows. It's optional
       
  1247         // so we can ignore it's return value.
       
  1248         GetDurTimeL(aIntervalSecs, aCurrentCharNumber);
       
  1249         return ETrue;
       
  1250         }
       
  1251 
       
  1252     // If no character found, return EFalse
       
  1253     return EFalse;
       
  1254     }
       
  1255 
       
  1256 // ---------------------------------------------------------------------------
       
  1257 // CESMRICalValue::GetDurTimeL
       
  1258 // ---------------------------------------------------------------------------
       
  1259 //
       
  1260 /**
       
  1261 Reads in and converts a dur-time into a number of seconds
       
  1262 @param aIntervalSecs Function adds number of seconds to this variable.
       
  1263 @param aCurrentCharNumber Character number to start looking in the value.
       
  1264 @return ETrue if the value could be interpreted as a dur-time, EFalse otherwise.
       
  1265 @leave Leaves with KErrCorrupt if the value does not hold a valid time.
       
  1266 @internalTechnology
       
  1267 */
       
  1268 TBool CESMRICalValue::GetDurTimeL(TInt& aIntervalSecs, TInt& aCurrentCharNumber) const
       
  1269     {
       
  1270     FUNC_LOG;
       
  1271 
       
  1272     //  dur-time   = "T" (dur-hour / dur-minute / dur-second) e.g. T5H0M20S
       
  1273 
       
  1274     if (aCurrentCharNumber >= iValue->Length())
       
  1275         {
       
  1276         return EFalse;
       
  1277         }
       
  1278 
       
  1279     if (iValue->Des()[aCurrentCharNumber] == KICalTimeChar)
       
  1280         {
       
  1281         ++aCurrentCharNumber; // Increment to get past 'T'
       
  1282 
       
  1283         if (!GetDurHourL(aIntervalSecs, aCurrentCharNumber))
       
  1284             {
       
  1285             if (!GetDurMinuteL(aIntervalSecs, aCurrentCharNumber))
       
  1286                 {
       
  1287                 if (!GetDurSecondL(aIntervalSecs, aCurrentCharNumber))
       
  1288                     {
       
  1289                     // We should not have read a 'T' and failed to match hour/minute/second
       
  1290                     User::Leave(KErrCorrupt);
       
  1291                     }
       
  1292                 }
       
  1293             }
       
  1294         }
       
  1295     else
       
  1296         {
       
  1297         // First character is not a 'T', therefore value is not a dur-time
       
  1298         return EFalse;
       
  1299         }
       
  1300 
       
  1301     return ETrue;
       
  1302     }
       
  1303 
       
  1304 // ---------------------------------------------------------------------------
       
  1305 // CESMRICalValue::GetDurHourL
       
  1306 // ---------------------------------------------------------------------------
       
  1307 //
       
  1308 /**
       
  1309 Reads in and converts a dur-hour into a number of seconds. There is no range
       
  1310 check on the number of hours.
       
  1311 @param aIntervalSecs Function adds number of seconds to this variable.
       
  1312 @param aCurrentCharNumber Character number to start looking in the value.
       
  1313 @return ETrue if the value could be interpreted as a dur-hour, EFalse otherwise.
       
  1314 @internalTechnology
       
  1315 */
       
  1316 TBool CESMRICalValue::GetDurHourL(TInt& aIntervalSecs, TInt& aCurrentCharNumber) const
       
  1317     {
       
  1318     FUNC_LOG;
       
  1319 
       
  1320     //  dur-hour   = 1*DIGIT "H" [dur-minute]
       
  1321 
       
  1322     if (aCurrentCharNumber >= iValue->Length())
       
  1323         {
       
  1324         return EFalse;
       
  1325         }
       
  1326 
       
  1327     // Create a new TPtrC containing the data from iValue which we need
       
  1328     TPtrC data(iValue->Mid(aCurrentCharNumber));
       
  1329 
       
  1330     // Find the next 'H' in the descriptor
       
  1331     TInt nextHPos(data.Locate(KICalHourChar));
       
  1332 
       
  1333     // Check it exists
       
  1334     if (nextHPos != KErrNotFound)
       
  1335         {
       
  1336         // If character found, construct a number from currentCharNumber to nextHPos
       
  1337         TInt theNum(ReadIntL(data.Left(nextHPos)));
       
  1338 
       
  1339         // Convert this time from hours to seconds
       
  1340         theNum *= KICalSecondsPerHour;
       
  1341 
       
  1342         aIntervalSecs += theNum;
       
  1343         aCurrentCharNumber += nextHPos + 1; // Extra increment to get past 'H'
       
  1344 
       
  1345         // Check if a dur-minute follows. It's optional
       
  1346         // so we can ignore it's return value.
       
  1347         GetDurMinuteL(aIntervalSecs,aCurrentCharNumber);
       
  1348         return ETrue;
       
  1349         }
       
  1350 
       
  1351     // If no character found, return EFalse
       
  1352     return EFalse;
       
  1353     }
       
  1354 
       
  1355 // ---------------------------------------------------------------------------
       
  1356 // CESMRICalValue::GetDurMinuteL
       
  1357 // ---------------------------------------------------------------------------
       
  1358 //
       
  1359 /**
       
  1360 Reads in and converts a dur-minute into a number of seconds. There is no range
       
  1361 check on the number of minutes.
       
  1362 @param aIntervalSecs Function adds number of seconds to this variable.
       
  1363 @param aCurrentCharNumber Character number to start looking in the value.
       
  1364 @return ETrue if the value could be interpreted as a dur-minute, EFalse
       
  1365 otherwise.
       
  1366 @internalTechnology
       
  1367 */
       
  1368 TBool CESMRICalValue::GetDurMinuteL(TInt& aIntervalSecs, TInt& aCurrentCharNumber) const
       
  1369     {
       
  1370     FUNC_LOG;
       
  1371 
       
  1372     //  dur-minute = 1*DIGIT "M" [dur-second]
       
  1373 
       
  1374     if (aCurrentCharNumber >= iValue->Length())
       
  1375         {
       
  1376         return EFalse;
       
  1377         }
       
  1378 
       
  1379     // Create a new TPtrC containing the data from iValue which we need
       
  1380     TPtrC data(iValue->Mid(aCurrentCharNumber));
       
  1381 
       
  1382     // Find the next 'M' in the descriptor
       
  1383     TInt nextMPos(data.Locate(KICalMinuteChar));
       
  1384 
       
  1385     // Check it exists
       
  1386     if (nextMPos != KErrNotFound)
       
  1387         {
       
  1388         // If character found, construct a number from currentCharNumber to nextMPos
       
  1389         TInt theNum(ReadIntL(data.Left(nextMPos)));
       
  1390 
       
  1391         // Convert this time from minutes to seconds
       
  1392         theNum *= KICalSecondsPerMinute;
       
  1393 
       
  1394         aIntervalSecs += theNum;
       
  1395         aCurrentCharNumber += nextMPos + 1; // Extra increment to get past 'M'
       
  1396 
       
  1397         // Check if a dur-second follows. It's optional
       
  1398         // so we can ignore it's return value.
       
  1399         GetDurSecondL(aIntervalSecs,aCurrentCharNumber);
       
  1400         return ETrue;
       
  1401         }
       
  1402 
       
  1403     // If no character found, return EFalse
       
  1404     return EFalse;
       
  1405     }
       
  1406 
       
  1407 // ---------------------------------------------------------------------------
       
  1408 // CESMRICalValue::GetDurSecondL
       
  1409 // ---------------------------------------------------------------------------
       
  1410 //
       
  1411 /**
       
  1412 Reads in and converts a dur-second into a number of seconds. There is no range
       
  1413 check on the number of seconds.
       
  1414 @param aIntervalSecs Function adds number of seconds to this variable.
       
  1415 @param aCurrentCharNumber Character number to start looking in the value.
       
  1416 @return ETrue if the value could be interpreted as a dur-second, EFalse
       
  1417 otherwise.
       
  1418 @internalTechnology
       
  1419 */
       
  1420 TBool CESMRICalValue::GetDurSecondL(TInt& aIntervalSecs, TInt& aCurrentCharNumber) const
       
  1421     {
       
  1422     FUNC_LOG;
       
  1423 
       
  1424     //  dur-second = 1*DIGIT "S"
       
  1425 
       
  1426     if (aCurrentCharNumber >= iValue->Length())
       
  1427         {
       
  1428         return EFalse;
       
  1429         }
       
  1430 
       
  1431     // Create a new TPtrC containing the data from iValue which we need
       
  1432     TPtrC data(iValue->Mid(aCurrentCharNumber));
       
  1433 
       
  1434     // Find the next 'S' in the descriptor
       
  1435     TInt nextSPos(data.Locate(KICalSecondChar));
       
  1436 
       
  1437     // Check it exists
       
  1438     if (nextSPos != KErrNotFound)
       
  1439         {
       
  1440         // If character found, construct a number from currentCharNumber to nextSPos
       
  1441         TInt theNum(ReadIntL(data.Left(nextSPos)));
       
  1442 
       
  1443         aIntervalSecs += theNum;
       
  1444         aCurrentCharNumber += nextSPos;
       
  1445 
       
  1446         return ETrue;
       
  1447         }
       
  1448 
       
  1449     // If no character found, return EFalse
       
  1450     return EFalse;
       
  1451     }
       
  1452 
       
  1453 // ---------------------------------------------------------------------------
       
  1454 // CESMRICalValue::GetDurWeekL
       
  1455 // ---------------------------------------------------------------------------
       
  1456 //
       
  1457 /**
       
  1458 Reads in and converts a dur-week into a number of seconds
       
  1459 @param aIntervalSecs Function adds number of seconds to this variable
       
  1460 @param aCurrentCharNumber Character number to start looking in the value.
       
  1461 @return ETrue if the value could be interpreted as a dur-week, EFalse
       
  1462 otherwise.
       
  1463 @internalTechnology
       
  1464 */
       
  1465 TBool CESMRICalValue::GetDurWeekL(TInt& aIntervalSecs, TInt& aCurrentCharNumber) const
       
  1466     {
       
  1467     FUNC_LOG;
       
  1468 
       
  1469     //  dur-week   = 1*DIGIT "W"
       
  1470 
       
  1471     if (aCurrentCharNumber >= iValue->Length())
       
  1472         {
       
  1473         return EFalse;
       
  1474         }
       
  1475 
       
  1476     // Create a new TPtrC containing the data from iValue which we need
       
  1477     TPtrC data(iValue->Mid(aCurrentCharNumber));
       
  1478 
       
  1479     // Find the next 'W' in the descriptor
       
  1480     TInt nextWPos(data.Locate(KICalWeekChar));
       
  1481 
       
  1482     // Check it exists
       
  1483     if (nextWPos != KErrNotFound)
       
  1484         {
       
  1485         // If character found, construct a number from currentCharNumber to nextWPos
       
  1486         TInt theNum(ReadIntL(data.Left(nextWPos)));
       
  1487 
       
  1488         // Convert this time from weeks to seconds
       
  1489         theNum *= KICalSecondsPerWeek;
       
  1490 
       
  1491         aIntervalSecs += theNum;
       
  1492         aCurrentCharNumber += nextWPos;
       
  1493 
       
  1494         return ETrue;
       
  1495         }
       
  1496 
       
  1497     // If no character found, return EFalse
       
  1498     return EFalse;
       
  1499     }
       
  1500 
       
  1501 
       
  1502 // End of File
       
  1503 
       
  1504 
       
  1505