1 // Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
28 #include <versittls.h>
32 class TVersitDateTime;
33 class MVersitObserver;
36 #ifndef SYMBIAN_ENABLE_SPLIT_HEADERS
38 /** Versit panic numbers. The Versit panic numbers have a category of "Versit-Parser".
42 enum TVersitParserPanic
44 ECurrentTokenNotFound, //Unused
45 EUnicodeUtilsNotFound, //Unused
46 ENoPropertyValue, //Unused
47 /** A CWeekDayArray contains an invalid value (not between EMonday
48 and ESunday inclusive). */
50 /** The number of a week within a month is invalid. */
52 /** The repeat type for a recurrence rule property value is not one of the values
53 specified in CVersitRecurrence::TType. */
54 ENoRecognizedRepeatType,
55 EVersitPanicEscapedTextAlreadyExists, //Unused
56 /** 8-bit encoding is proposed as the default for a parser but may not be appropriate. */
57 EVersitPanicCannotSetEightBitEncoding,
58 /** 8-bit encoding is encountered or proposed where it is not expected. */
59 EVersitPanicUnexpectedEightBitEncoding,
60 /** A parser was not specified when externalising a property. */
61 EVersitPanicNeedToSpecifyParser,
62 /** The additional storage slot for the given property has already been used */
63 EVersitPanicAdditionalStorageSlotAlreadyInUse,
64 /** Attempting to assign a NULL value to an additional storage slot */
65 EVersitPanicNullValueAssignedToAdditionalStorageSlot,
71 Used as key into additional storage within tls object, for CVersitTLSContainer
72 Value should not conflict with genuine compiler generated pointer values
76 const static TInt* const KTLSVars = reinterpret_cast<TInt*>(1);
81 GLREF_C void DestroyHBufC(TAny* aHBufC);
82 /** Versit parser panic
86 IMPORT_C void Panic(TVersitParserPanic aPanic);
87 #endif //SYMBIAN_ENABLE_SPLIT_HEADERS
91 #ifndef SYMBIAN_ENABLE_SPLIT_HEADERS
92 /** Extension mechanism for CLineReader
93 This is an internal class and is only for use by CLineReader
97 NONSHARABLE_CLASS(CLineReaderExtension) : public CBase
99 friend class CLineReader;
101 CLineReaderExtension();
102 ~CLineReaderExtension();
104 static CLineReaderExtension* NewL();
106 void DeleteBase64ValueBuffer();
107 HBufC8* CreateBase64ValueBufferL();
108 HBufC8* Base64ValueBuffer();
114 // Hold the line buffer temporarily.
115 // It is only used when the client wants
116 // the base64 extended behaviour defined
117 // in MVersitPlugInExtensionBase64Ending
118 HBufC8* iLineBase64Value;
121 //Forward declare class
122 class CLineReaderExtension;
123 #endif //SYMBIAN_ENABLE_SPLIT_HEADERS
125 class CLineReader : public CBase
126 /** Line reader for a vCalendar or vCard parser.
128 Reads in a line at a time for the parser.
130 Also allows the first character of the next line to be checked to see if it
131 is a space, which can indicate that the line is wrapped. This enables the
132 reading of multi-line property values.
134 Used by CVersitParser to internalise streams.
140 /** Defines the initial line size of, and the size of expansions to, the buffer
141 which stores the line being read. */
144 /** The initial size of the buffer (pointed to by iBuf). */
146 /** The size by which the buffer (pointed to by iBuf)
147 is expanded when it has run out of room. */
150 /** Defines values which describe the content of a line that has been read.
152 This is the return value from the function ReadLine(). */
155 /** The line has content (not white space). */
157 /** The line has white space only. */
158 ELineIsWhiteSpace=1, //Doesn't include next case
159 /** The line has no content, and so is just a carriage return and line
162 /** The line has a colon
163 This is only used internally. When the line has a colon, ReadLineL will
164 return ELineHasContent for the sake of backwards compatibility.
169 IMPORT_C static CLineReader* NewL(RReadStream& aStream);
170 IMPORT_C ~CLineReader();
171 IMPORT_C virtual TInt ReadLineL(TInt aPos,TInt& aErr);
172 IMPORT_C TBool AppendLineIfSpaceNextL();
173 IMPORT_C TBool IsSpaceNextL();
174 IMPORT_C TInt AppendSpaceL();
175 inline void SetPlugIn(MVersitPlugIn* aPlugIn);
176 inline void SetSkipWhiteSpaceAtStart(TBool aDoSkip);
179 void ReadBase64ValueL(TInt aPopValueStart);
182 inline CLineReader(RReadStream& aStream) :iReadStream(&aStream), iBufPtr(NULL,0), iFirstCharNextLine(-1) {}
183 IMPORT_C void ConstructL();
184 IMPORT_C void ExpandBufferL(TInt aCurrentSize);
185 IMPORT_C TUint8 ReadChar(TInt& aErr);
188 IMPORT_C virtual void Reserved();
191 TInt ReadLineL(HBufC8*& aHBuf, TInt aPos,TInt& aErr);
194 /** A pointer to an RReadStream object, the ReadUint8L() function of which is used
195 to read single characters from the stream.
197 This is passed into the NewL() function upon construction. */
198 RReadStream* iReadStream;
199 /** A pointer to a buffer which stores data read from the stream.
201 Its size on construction is EInitialLineSize, and it is expanded by EExpandSize
204 A copy of this value should not be stored, since the buffer location may change
205 if the buffer is expanded.
207 Data in the buffer is not lost when the buffer is expanded, but is copied
208 to the new location. */
212 TInt iFirstCharNextLine;
214 MVersitPlugIn* iPlugIn;
215 TBool iSkipWhiteSpaceAtStart;
216 CLineReaderExtension* iExtension;
219 class CVersitParser : public CBase
220 /** A generic Versit parser.
222 Provides generic functions which implement behaviour common to both vCalendar
223 and vCard parsers. For instance:
225 - InternalizeL() and ExternalizeL() functions, for writing and reading
226 data from a stream or file.
228 - adding/retrieving properties and sub-entities to/from an existing entity.
230 - encoding and character set conversion capabilities.
232 Although this is not an abstract class, in practice you would create and use
233 objects of a derived class instead (CParserVCal or CParserVCard), as these
234 provide additional functionality needed for parsing vCalendars and vCards.
236 Note: a flag used in the class constructor indicates whether the entity needs
237 a version property. The version property will be inserted at the start of
238 the array of properties for the entity, and specifies the version of the vCard/vCalendar
239 specification used by the data of this particular vCard/vCalendar. The versions
240 that are currently supported are vCard v2.1 and vCalendar v1.0.
242 A typical vCard looks like this:
250 Note: if you are sequentially creating and destroying multiple
251 parsers, a major performance improvement may be achieved
252 by using thread local storage to store an instance of CVersitUnicodeUtils
253 which persists and can be used by all of the parsers.
255 See CVersitTlsData for more details.
260 friend class CParserProperty;
262 IMPORT_C CVersitParser(TUint aFlags);
263 IMPORT_C void ConstructL();
264 IMPORT_C ~CVersitParser();
265 IMPORT_C void InternalizeL(RFile& aInputFile,TInt& aBytesThroughFile);
266 IMPORT_C virtual void InternalizeL(RReadStream& aStream);
267 IMPORT_C virtual void InternalizeL(HBufC* aEntityName,CLineReader* aLineReader);
268 IMPORT_C void ExternalizeL(RFile& aOutputFile);
269 IMPORT_C virtual void ExternalizeL(RWriteStream& aStream);
270 IMPORT_C void AddEntityL(CVersitParser* aEntity);
271 IMPORT_C void AddPropertyL(CParserProperty* aProperty,TBool aInternalizing=EFalse);
272 IMPORT_C CArrayPtr<CVersitParser>* EntityL(const TDesC& aEntityName,TBool aTakeOwnership=ETrue);
273 IMPORT_C CArrayPtr<CVersitParser>* ArrayOfEntities(TBool aTakeOwnership=ETrue);
274 IMPORT_C CArrayPtr<CParserProperty>* PropertyL(const TDesC8& aPropertyName,const TUid& aPropertyUid,TBool aTakeOwnership=ETrue) const;
275 IMPORT_C CArrayPtr<CParserProperty>* ArrayOfProperties(TBool aTakeOwnership=ETrue);
276 IMPORT_C virtual void ConvertAllPropertyDateTimesToMachineLocalL(const TTimeIntervalSeconds& aIncrement,const CVersitDaylight* aDaylight);
277 IMPORT_C void AdjustAllPropertyDateTimesToMachineLocalL();
278 IMPORT_C static TBool IsValidParameterValue(TInt& aPos,const TDesC& aParamValue);
279 IMPORT_C void SetEntityNameL(const TDesC& aEntityName);
280 IMPORT_C TPtrC EntityName() const;
281 IMPORT_C static TBool IsValidLabel(const TDesC& aLabel, TInt& aPos);
282 IMPORT_C static TInt Val(const TDesC& aString, TInt& aNumber);
283 IMPORT_C void SetCharacterConverter(Versit::TEncodingAndCharset& encodingAndCharset);
286 // Set/Get the default settings for the [en|de]coding process
288 IMPORT_C Versit::TVersitEncoding DefaultEncoding() const;
289 IMPORT_C void SetDefaultEncoding(const Versit::TVersitEncoding aEncoding);
290 IMPORT_C Versit::TVersitCharSet DefaultCharSet() const;
291 IMPORT_C TUint DefaultCharSetId() const;
292 IMPORT_C void SetDefaultCharSet(const Versit::TVersitCharSet aCharSet);
293 IMPORT_C void SetDefaultCharSetId(TUint aCharSetId);
294 IMPORT_C void SetAutoDetect(TBool aOn,const CArrayFix<CCnvCharacterSetConverter::SCharacterSet>* aAutoDetectCharSets=NULL);
297 // Set/Get Observers and PlugIn's
299 inline void SetObserver(MVersitObserver* aObserver);
300 inline MVersitObserver* Observer();
301 inline void SetPlugIn(MVersitPlugIn* aPlugIn);
302 inline MVersitPlugIn* PlugIn();
306 IMPORT_C TInt LoadBinaryValuesFromFilesL();
307 IMPORT_C TInt LoadBinaryValuesFromFilesL(RFs& aFileSession);
308 IMPORT_C TInt SaveBinaryValuesToFilesL(TInt aSizeThreshold,const TDesC& aPath);
309 IMPORT_C TInt SaveBinaryValuesToFilesL(TInt aSizeThreshold,const TDesC& aPath,RFs& aFileSession);
311 /** White space character codes: used while analysing the syntax of the received
312 data and while externalising data.
325 ECarriageReturn = 13,
329 /** Flags that can be specified on construction.
333 enum TVersitParserFlags
335 /** This entity does not need a version property. */
336 ENoVersionProperty = 0,
337 /** This entity should have a version property. */
338 ESupportsVersion = 0x01,
339 //Gaps since other flags have been used in past
340 EImportSyncML = 0x1000, //Importing from a SyncML server
341 /** Indicates whether the parser should use auto-detection of character sets when
342 one has not been explicitly specified. */
343 EUseAutoDetection = 0x4000,
344 //versit Internal use only
345 /** The current property has specified a character set. */
346 ECharSetIdentified = 0x8000,
347 /** If the charset is not explicitly specified, the default charset will be used instead of US-ASCII as required
348 by the Versit specification . */
349 EUseDefaultCharSetForAllProperties = 0x2000
353 // Unicode support conversion functions
355 IMPORT_C static TInt ConvertFromUnicodeToISOL(TDes8& aIso, const TDesC16& aUnicode, CCnvCharacterSetConverter* aConverter);
356 IMPORT_C TVersitDateTime* DecodeDateTimeL(TDes& aToken) const;
359 IMPORT_C TInt ConvertToUnicodeFromISOL(TDes16& aUnicode, const TDesC8& aIso, TUint aCharacterSet);
362 // Parsing high level functions
364 IMPORT_C void ParsePropertiesL();
365 IMPORT_C void ParseBeginL();
366 IMPORT_C void ParseEndL();
367 void ParseEndL(HBufC16& aEntityName);
368 IMPORT_C TBool ParseEntityL();
369 IMPORT_C virtual void ParsePropertyL();
370 IMPORT_C CArrayPtr<CParserParam>* ReadLineAndDecodeParamsLC(TInt& aValueStart,TInt& aNameLen);
371 IMPORT_C void MakePropertyL(TPtr8& aPropName,TInt aValueStart);
372 IMPORT_C CArrayPtr<CParserParam>* GetPropertyParamsLC(TPtr8 aParams);
373 IMPORT_C void ParseParamL(CArrayPtr<CParserParam>* aArray,TPtr8 aParam);
374 IMPORT_C void AnalysesEncodingCharset(CArrayPtr<CParserParam>* aArrayOfParams);
375 IMPORT_C void ReadMultiLineValueL(TPtr8& aValue,TInt aValueStart,TBool aBinaryData);
376 inline TPtr8& BufPtr();
379 // Append standard versit tokens to streams
381 IMPORT_C void AppendBeginL();
382 IMPORT_C void AppendEndL();
383 void AppendEntityNameL();
384 IMPORT_C void DoAddPropertyL(CParserProperty* aProperty);
387 // Dispatcher functions to create entities/properties based upon a Versit identifying Uid
389 IMPORT_C virtual CVersitParser* MakeEntityL(TInt aEntityUid,HBufC* aEntityName);
390 CParserPropertyValueHBufC* MakeDefaultPropertyValueL(HBufC16*& aValue);
391 IMPORT_C virtual CParserPropertyValue* MakePropertyValueL(const TUid& aPropertyUid,HBufC16*& aValue);
392 IMPORT_C HBufC* DecodePropertyValueL(const TDesC8& aValue);
393 IMPORT_C void DecodePropertyValueL(const TDesC8& aValue,const TUid& aEncodingUid);
394 HBufC* ConvertToUnicodeL(const TDesC8& aValue);
395 IMPORT_C CDesCArray* MakePropertyValueCDesCArrayL(TPtr16 aStringValue);
396 IMPORT_C CArrayPtr<TVersitDateTime>* MakePropertyValueMultiDateTimeL(TPtr16 aDateTimeGroup);
397 IMPORT_C CVersitDaylight* MakePropertyValueDaylightL(TPtr16 aDaylightValue);
398 IMPORT_C TBool FindFirstField(TPtr16& aField,TPtr16& aRemaining, TBool aTrimSpace=ETrue);
399 IMPORT_C void FindRemainingField(TPtr16& aField,TPtr16& aRemaining);
402 // Helper methods to decode versit dates, times, and time periods
404 IMPORT_C TTimeIntervalSeconds DecodeTimeZoneL(const TDesC& aToken) const;
405 IMPORT_C TTime* DecodeTimePeriodL(const TDesC& aToken) const;
406 IMPORT_C TInt GetNumberL(const TDesC& aToken,TInt& aNumChars) const;
409 IMPORT_C virtual TUid RecognizeToken(const TDesC8& aToken) const;
410 IMPORT_C virtual TInt RecognizeEntityName() const;
412 // Cleanup support methods
414 IMPORT_C static void ResetAndDestroyArrayOfParams(TAny* aObject);
415 IMPORT_C static void ResetAndDestroyArrayOfProperties(TAny* aObject);
416 IMPORT_C static void ResetAndDestroyArrayOfEntities(TAny* aObject);
417 IMPORT_C static void ResetAndDestroyArrayOfDateTimes(TAny* aObject);
419 inline void SetFlags(TUint aFlags);
427 static TBool IsPunctuationToken(TUint aChar);
428 inline TBool SupportsVersion() const;
429 inline void SetSupportsVersion();
430 inline void ClearSupportsVersion();
433 // Set the settings for the [en|de]coding of the current property
435 IMPORT_C void RestoreLineCodingDetailsToDefault();
436 IMPORT_C void SetLineEncoding(Versit::TVersitEncoding aLineEncoding);
437 IMPORT_C void SetLineEncoding(TUint aVersitEncodingUid);
438 IMPORT_C void SetLineCharacterSet(Versit::TVersitCharSet aLineCharSet);
439 IMPORT_C void SetLineCharacterSetId(TUint aLineCharSetId);
440 IMPORT_C void SetLineCoding(Versit::TVersitCharSet aLineCharSet, Versit::TVersitEncoding aLineEncoding);
443 // Return the settings for the current property
445 IMPORT_C Versit::TVersitEncoding LineEncoding() const;
446 IMPORT_C Versit::TVersitCharSet LineCharSet() const;
447 IMPORT_C TUint LineEncodingId() const;
448 IMPORT_C TUint LineCharSetId() const;
450 inline CVersitUnicodeUtils& UnicodeUtils();
454 // Static utility functions to aid with the Unicode conversion process
456 static TUint MapVersitCharsetToCharConvCharset(Versit::TVersitCharSet aVersitSet);
457 static TUint MapVersitEncodingToConArcUid(Versit::TVersitEncoding aVersitEncoding);
460 void SetLineCharsetDetailsToDefault();
461 void SetLineEncodingDetailsToDefault();
463 private: //To fix TimeZone SyncML bug
464 void ConvertAllUTCDateTimesToMachineLocalL(const TTimeIntervalSeconds& aIncrement,const CVersitDaylight* aDaylight);
465 void ConvertUTCDateTimeToMachineLocal(TVersitDateTime* aDateTime,const TTimeIntervalSeconds& aIncrement,const CVersitDaylight* aDaylight);
466 //void AddTimeZonePropertyL();
469 struct TParserCodingDetails
471 Versit::TVersitEncoding iEncoding;
473 Versit::TVersitCharSet iCharSet;
478 // Default settings & internal flags
480 TParserCodingDetails iDefaultCodingDetails;
481 TParserCodingDetails iCurrentPropertyCodingDetails;
482 TBuf<KVersitMaxVersionLength> iDefaultVersion;
483 const CArrayFix<CCnvCharacterSetConverter::SCharacterSet>* iAutoDetectCharSets;
485 // Member data relating to the current item being parsed
487 CArrayPtr<CVersitParser>* iArrayOfEntities;
488 CArrayPtr<CParserProperty>* iArrayOfProperties;
489 CParserProperty* iCurrentProperty;
490 CLineReader* iOwnedLineReader;
491 CLineReader* iLineReader;
492 HBufC8* iDecodedValue;
493 CBufSeg* iLargeDataBuf;
496 RWriteStream* iWriteStream;
498 // General utility class
499 CVersitTlsData* iStaticUtils;
502 MVersitObserver* iObserver;
503 MVersitPlugIn* iPlugIn;
506 void DoInternalizeL();
507 IMPORT_C virtual void Reserved1();
508 IMPORT_C virtual void Reserved2();
514 #ifndef SYMBIAN_ENABLE_SPLIT_HEADERS
515 NONSHARABLE_CLASS( CVersitTLSContainer ): public CBase
517 Wrapper class for static variables to be stored in TLS
523 static CVersitTLSContainer *NewLC(const TInt aSize);
524 ~CVersitTLSContainer();
526 HBufC * iShiftJisEscape;//Store shift-jis escape charcter, as generated by relevant charconv plugin
528 #endif //SYMBIAN_ENABLE_SPLIT_HEADERS
529 #include <versit.inl>