From 5f62166de5ccdc039aa285c59b9d9839d9196330 Mon Sep 17 00:00:00 2001 From: Sebastian Rittau Date: Wed, 13 Feb 2002 19:50:48 +0000 Subject: Change id of gnomecal chapter grom gcal to gnomecal, since that's what * gncal/doc/C/gnomecal.sgml: Change id of gnomecal chapter grom gcal to gnomecal, since that's what topic.dat expects and what is nicer anyways. * libversit/README.TXT: * libversit/vobject.h: * libversit/vcaltmp.c: * libversit/vcaltmp.h: * libversit/vcaltest.c: * libversit/vctest.c: * libversit/vcc.h: Removed DOS-style line endings. (Bugzilla #16741) * gncal/gncal-todo.c: (make_todo_style), (insert_in_clist): * gncal/main.c: (parse_an_arg): Added break's to empty case blocks. (Bugzilla #16741) svn path=/trunk/; revision=15712 --- libversit/README.TXT | 1902 +++++++++++++++++++++++++------------------------- 1 file changed, 951 insertions(+), 951 deletions(-) diff --git a/libversit/README.TXT b/libversit/README.TXT index c8ce8b0979..ae810806c8 100644 --- a/libversit/README.TXT +++ b/libversit/README.TXT @@ -1,951 +1,951 @@ -NOTE: If you used the earlier APIs released by Versit -then you will want to look at the document "migrate.doc" -included with this package. It contains a discussion of -the differences between the old API and this one. - ----------------------------------------------------------------- - -The vCard/vCalendar C interface is implemented in the set -of files as follows: - -vcc.y, yacc source, and vcc.c, the yacc output you will use -implements the core parser - -vobject.c implements an API that insulates the caller from -the parser and changes in the vCard/vCalendar BNF - -port.h defines compilation environment dependent stuff - -vcc.h and vobject.h are header files for their .c counterparts - -vcaltmp.h and vcaltmp.c implement vCalendar "macro" functions -which you may find useful. - -test.c is a standalone test driver that exercises some of -the features of the APIs provided. Invoke test.exe on a -VCARD/VCALENDAR input text file and you will see the pretty -print output of the internal representation (this pretty print -output should give you a good idea of how the internal -representation looks like -- there is one such output in the -following too). Also, a file with the .out suffix is generated -to show that the internal representation can be written back -in the original text format. - ------------------------------------------------------------------ - - - VObject for VCard/VCalendar - -Table of Contents -================= -1. VObject -2. Internal Representations of VCard/VCalendar -3. Iterating Through VObject's Properties or Values -4. Pretty Printing a VObject Tree -5. Building A VObject Representation of A VCard/VCalendar -6. Converting A VObject Representation Into Its Textual Representation -7. Miscellaneous Notes On VObject APIs usages -8. Brief descriptions of each APIs -9. Additional Programming Notes. - -This document is mainly about the VObject and its APIs. The main -use of a VObject is to represent a VCard or a VCalendar inside -a program. However, its use is not limited to aforemention as it -can represent an arbitrary information that makes up of a tree or -forest of properties/values. - -1. VObject - ======= -A VObject can have a name (id) and a list of associated properties and -a value. Each property is itself a VObject. - -2. Internal Representations of VCard/VCalendar - =========================================== -A list of VCard or a VCalendar is represented by a list of VObjects. -The name (id) of the VObjects in the list is either VCCardProp or -VCCalProp. Each of these VObjects can have a list of properties. -Since a property is represented as a VObject, each of these properties -can have a name, a list of properties, and a value. - -For example, the input file "vobject.vcf": - -BEGIN:VCARD -N:Alden;Roland -FN:Roland H. Alden -ORG:AT&T;Versit Project Office -TITLE:Consultant -EMAIL;WORK;PREF;INTERNET:sf!rincon!ralden@alden.attmail.com -EMAIL;INTERNET:ralden@sfgate.com -EMAIL;MCIMail:242-2200 -LABEL;DOM;POSTAL;PARCEL;HOME;WORK;QUOTED-PRINTABLE:Roland H. Alden=0A= -Suite 2208=0A= -One Pine Street=0A= -San Francisco, CA 94111 -LABEL;POSTAL;PARCEL;HOME;WORK;QUOTED-PRINTABLE:Roland H. Alden=0A= -Suite 2208=0A= -One Pine Street=0A= -San Francisco, CA 94111=0A= -U.S.A. -TEL;WORK;PREF;MSG:+1 415 296 9106 -TEL;WORK;FAX:+1 415 296 9016 -TEL;MSG;CELL:+1 415 608 5981 -ADR:;Suite 2208;One Pine Street;San Francisco;CA;94111;U.S.A. -SOUND:ROW-LAND H ALL-DIN -LOGO;GIF;BASE64: - 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 - -BEGIN:VCALENDAR -DCREATED:19960523T100522 -PRODID:-//Alden Roland/Hand Crafted In North Carolina//NONSGML Made By Hand//EN -VERSION:0.3 -BEGIN:VEVENT -START:19960523T120000 -END:19960523T130000 -SUBTYPE:PHONE CALL -SUMMARY:VERSIT PDI PR Teleconference/Interview -DESCRIPTION:VERSIT PDI PR Teleconference/Interview With Tom Streeter and Alden Roland -END:VEVENT -BEGIN:VEVENT -START:19960523T113000 -END:19960523T115500 -SUBTYPE:LUNCH -SUMMARY:Eat in the cafeteria today -END:VEVENT -END:VCALENDAR - -END:VCARD - - -will conceptually be be represented as - vcard - VCNameProp - VCFamilyNameProp=Alden - VCGivenNameProp=Roland - VCFullNameProp=Roland H.Alden - .... - -note that - EMAIL;WORK;PREF;INTERNET:sf!rincon!ralden@alden.attmail.com -will be represented as: - VCEmailAddress=sf!rincon!ralden@alden.attmail.com - VCWork - VCPreferred - VCInternet -where the lower level properties are properties of the property -VCEmailAddress. - -Groupings are flattened out in the VObject representation such -that: - a.b:blah - a.c:blahblah -are represented as: - b=blah - VCGrouping=a - c=blahblah - VCGrouping=a -i.e. one can read the above as: - the property "b" has value "blah" and property "VCGrouping" - with the value "a". - the property "c" has value "blahblah" and property "VCGrouping" - with the value "a". -likewise, multi-level groupings are flatten similarly. e.g. - a.b.c:blah - a.b.e:blahblah ---> - c=blah - VCGrouping=b - VCGrouping=a - e=blahblah - VCGrouping=b - VCGrouping=a -which read: - the property "c" has value "blah" and property "VCGrouping" - with the value "b" which has property "VCGrouping" - with value "a". - the property "e" has value "blahblah" and property "VCGrouping" - with the value "b" which has property "VCGrouping" - with value "a". - -3. Iterating Through VObject's Properties or Values - ================================================ -The following is a skeletal form of iterating through -all properties of a vobject, o: - - // assume the object of interest, o, is of type VObject - VObjectIterator i; - initPropIterator(&i,o); - while (moreIteration(&i)) { - VObject *each = nextVObject(&i); - // ... do something with "each" property - } - -Use the API vObjectName() to access a VObject's name. -Use the API vObjectValueType() to determine if a VObject has - a value. For VCard/VCalendar application, you - should not need this function as practically - all values are either of type VCVT_USTRINGZ or - VCVT_RAW (i.e set by setVObjectUStringZValue and - setVObjectAnyValue APIs respectively), and the - value returned by calls to vObjectUStringZValue - and vObjectAnyValue are 0 if a VObject has no - value. (There is a minor exception where VObject with - VCDataSizeProp has value that is set by - setVObjectLongValue). -Use the APIs vObject???Value() to access a VObject's value. - where ??? is the expected type. -Use the APIs setvObject???Value() to set or modify a VObject's value. - where ??? is the expected type. -Use the API isAPropertyOf() to query if a name match the name of - a property of a VObject. Since isAPropertyOf() return - the matching property, we can use that to retrieve - a property and subsequently the value of the property. - -4. Pretty Printing a VObject Tree - ============================== -VObject tree can be pretty printed with the printVObject() function. -The output of pretty printing a VObject representation of the input -test file "vobject.vcf" is shown below. Note that the indentation -indicates the tree hirerarchy where the immediate children nodes -of a parent node is all at the same indentation level and the -immediate children nodes are the immediate properties of the -associated parent nodes. In the following, {N,FN,ORG,TITLE,...} -are immediate properties of VCARD. {F and G} are properties of N -with value {"Alden" and "Roland"} respectively; FN has no property -but has the value "Roland H. Alden"; EMAIL has value and -the properties WORK, PREF, and INTERNET. - - -VCARD - N - F="Alden" - G="Roland" - FN="Roland H. Alden" - ORG - ORGNAME="AT&T" - OUN="Versit Project Office" - TITLE="Consultant" - EMAIL="sf!rincon!ralden@alden.attmail.com" - WORK - PREF - INTERNET - EMAIL="ralden@sfgate.com" - INTERNET - EMAIL="242-2200" - MCIMail - LABEL="Roland H. Alden - Suite 2208 - One Pine Street - San Francisco, CA 94111" - DOM - POSTAL - PARCEL - HOME - WORK - QP - LABEL="Roland H. Alden - Suite 2208 - One Pine Street - San Francisco, CA 94111 - U.S.A." - POSTAL - PARCEL - HOME - WORK - QP - TEL="+1 415 296 9106" - WORK - PREF - MSG - TEL="+1 415 296 9016" - WORK - FAX - TEL="+1 415 608 5981" - MSG - CELL - ADR - EXT ADD="Suite 2208" - STREET="One Pine Street" - L="San Francisco" - R="CA" - PC="94111" - C="U.S.A." - SOUND="ROW-LAND H ALL-DIN" - LOGO=[raw data] - GIF - BASE64 - DataSize=1482 -VCALENDAR - DCREATED="19960523T100522" - PRODID="-//Alden Roland/Hand Crafted In North Carolina//NONSGML Made By Hand//EN" - VERSION="0.3" - VEVENT - START="19960523T120000" - END="19960523T130000" - SUBTYPE="PHONE CALL" - SUMMARY="VERSIT PDI PR Teleconference/Interview" - DESCRIPTION="VERSIT PDI PR Teleconference/Interview With Tom Streeter and Alden Roland" - VEVENT - START="19960523T113000" - END="19960523T115500" - SUBTYPE="LUNCH" - SUMMARY="Eat in the cafeteria today" - -5. Building A VObject Representation of A VCard/VCalendar - ====================================================== -The parser in vcc.y converts an input file with one or more -VCard/VCalendar that is in their textual representation -into their corresponding VObject representation. - -VObject representation of a VCard/VCalendar can also be built -directly with calls to the VObject building APIs. e.g. - - VObject *prop; - VObject *vcard = newVObject(VCCardProp); - prop = addProp(vcard,VCNameProp); - addPropValue(prop,VCFamilyNameProp,"Alden"); - addPropValue(prop,VCGivenNameProp,"Roland"); - addPropValue(vcard,VCFullNameProp,"Roland H. Alden"); - .... - -6. Converting A VObject Representation Into Its Textual Representation - =================================================================== -The VObject representation can be converted back to its textual -representation via the call to writeVObject() or writeMemVObject() -API. e.g. - a. to write to a file: - // assume vcard is of type VObject - FILE *fp = fopen("alden.vcf","w"); - writeVObject(fp,vcard); - a. to write to memory, and let the API allocate the required memory. - char* clipboard = writeVObject(0,0,vcard); - ... do something to clipboard - free(clipboard); - b. to write to a user allocated buffer: - char clipboard[16384]; - int len = 16384; - char *buf = writeVObject(clipboard,&len,vcard); - ... buf will be equal to clipboard if the write - is successful otherwise 0. - -In the case of writing to memory, the memory buffer can be either -allocated by the API or the user. If the user allocate the -memory for the buffer, then the length of the buffer needs to be -communicated to the API via a variable. The variable passed as -the length argument will be overwritten with the actual size -of the text output. A 0 return value from writeMemVObject() -indicates an error which could be caused by overflowing the -size of the buffer or lack of heap memory. - -7. Miscellaneous Notes On VObject APIs usages - ========================================== -a. vcc.h -- contains basic interfaces to the parser: - VObject* Parse_MIME(const char *input, unsigned long len); - VObject* Parse_MIME_FromFile(FILE *file); - -- both of this return a null-terminated list of - VObject that is either a VCARD or VCALENDAR. - To iterate through this list, do - VObject *t, *v; - v = Parse_Mime_FromFile(fp); - while (v) { - // ... do something to v. - t = v; - v = nextVObjectInList(v); - cleanVObject(t); - } - note that call to cleanVObject will release - resource used to represent the VObject. - -b. vobject.h -- contains basic interfaces to the VObject APIs. - see the header for more details. - The structure of VObject is purposely (hiddened) not exposed - to the user. Every access has to be done via - the APIs. This way, if we need to change the - structure or implementation, the client need not - recompile as long as the interfaces remain the - same. - -c. values of a property is determined by the property definition - itself. The vobject APIs does not attempt to enforce - any of such definition. It is the consumer responsibility - to know what value is expected from a property. e.g - most properties have unicode string value, so to access - the value of these type of properties, you will use - the vObjectUStringZValue() to read the value and - setVObjectUStringZValue() to set or modify the value. - Refer to the VCard and VCalendar specifications for - the definition of each property. - -d. properties name (id) are case incensitive. - -8. Brief descriptions of each APIs - =============================== - * the predefined properties' names (id) are listed under vobject.h - each is of the form VC*Prop. e.g. - #define VC7bitProp "7BIT" - #define VCAAlarmProp "AALARM" - .... - - * consumer of a VObject can only define pointers to VObject. - - * a variable of type VObjectIterator, say "i", can be used to iterate - through a VObject's properties, say "o". The APIs related to - VObjectIterator are: - void initPropIterator(VObjectIterator *i, VObject *o); - -- e.g. usage - initPropIterator(&i,o); - int moreIteration(VObjectIterator *i); - -- e.g. usage - while (moreIteration(&i)) { ... } - VObject* nextVObject(VObjectIterator *i); - -- e.g. usage - while (moreIteration(&i)) { - VObject *each = nextVObject(&i); - } - - * VObject can be chained together to form a list. e.g. of such - use is in the parser where the return value of the parser is - a link list of VObject. A link list of VObject can be - built by: - void addList(VObject **o, VObject *p); - and iterated by - VObject* nextVObjectInList(VObject *o); - -- next VObjectInList return 0 if the list - is exhausted. - - * the following APIs are mainly used to construct a VObject tree: - VObject* newVObject(const char *id); - -- used extensively internally by VObject APIs but when - used externally, its use is mainly limited to the - construction of top level object (e.g. an object - with VCCardProp or VCCalendarProp id). - - void deleteVObject(VObject *p); - -- to deallocate single VObject, for most user, use - cleanVObject(VObject *o) instead for freeing all - resources associated with the VObject. - - char* dupStr(const char *s, unsigned int size); - -- duplicate a string s. If size is 0, the string is - assume to be a null-terminated. - - void deleteStr(const char *p); - -- used to deallocate a string allocated by dupStr(); - - void setVObjectName(VObject *o, const char* id); - -- set the id of VObject o. This function is not - normally used by the user. The setting of id - is normally done as part of other APIs (e.g. - addProp()). - - void setVObjectStringZValue(VObject *o, const char *s); - -- set a string value of a VObject. - - void setVObjectUStringZValue(VObject *o, const wchar_t *s); - -- set a Unicode string value of a VObject. - - void setVObjectIntegerValue(VObject *o, unsigned int i); - -- set an integer value of a VObject. - - void setVObjectLongValue(VObject *o, unsigned long l); - -- set an long integer value of a VObject. - - void setVObjectAnyValue(VObject *o, void *t); - -- set any value of a VObject. The value type is - unspecified. - - VObject* setValueWithSize(VObject *prop, void *val, unsigned int size); - -- set a raw data (stream of bytes) value of a VObject - whose size is size. The internal VObject representation - is - this object = val - VCDataSizeProp=size - i.e. the value val will be attached to the VObject prop - and a property of VCDataSize whose value is size - is also added to the object. - - void setVObjectVObjectValue(VObject *o, VObject *p); - -- set a VObject as the value of another VObject. - - const char* vObjectName(VObject *o); - -- retrieve the VObject's Name (i.e. id). - - const char* vObjectStringZValue(VObject *o); - -- retrieve the VObject's value interpreted as - null-terminated string. - - const wchar_t* vObjectUStringZValue(VObject *o); - -- retrieve the VObject's value interpreted as - null-terminated unicode string. - - unsigned int vObjectIntegerValue(VObject *o); - -- retrieve the VObject's value interpreted as - integer. - - unsigned long vObjectLongValue(VObject *o); - -- retrieve the VObject's value interpreted as - long integer. - - void* vObjectAnyValue(VObject *o); - -- retrieve the VObject's value interpreted as - any value. - - VObject* vObjectVObjectValue(VObject *o); - -- retrieve the VObject's value interpreted as - a VObject. - - VObject* addVObjectProp(VObject *o, VObject *p); - -- add a VObject p as a property of VObject o. - (not normally used externally for building a - VObject). - - VObject* addProp(VObject *o, const char *id); - -- add a property whose name is id to VObject o. - - VObject* addPropValue(VObject *o, const char *id, const char *v); - -- add a property whose name is id and whose value - is a null-terminated string to VObject o. - - VObject* addPropSizedValue(VObject *o, const char *id, - const char *v, unsigned int size); - -- add a property whose name is id and whose value - is a stream of bytes of size size, to VObject o. - - VObject* addGroup(VObject *o, const char *g); - -- add a group g to VObject o. - e.g. if g is a.b.c, you will have - o - c - VCGroupingProp=b - VCGroupingProp=a - and the object c is returned. - - VObject* isAPropertyOf(VObject *o, const char *id); - -- query if a property by the name id is in o and - return the VObject that represent that property. - - void printVObject(VObject *o); - -- pretty print VObject o to stdout (for debugging use). - - void writeVObject(FILE *fp, VObject *o); - -- convert VObject o to its textual representation and - write it to file. - - char* writeMemVObject(char *s, int *len, VObject *o); - -- convert VObject o to its textual representation and - write it to memory. If s is 0, then memory required - to hold the textual representation will be allocated - by this API. If a variable len is passed, len will - be overwriten with the byte size of the textual - representation. If s is non-zero, then s has to - be a user allocated buffer whose size has be passed - in len as a variable. Memory allocated by the API - has to be freed with call to free. The return value - of this API is either the user supplied buffer, - the memory allocated by the API, or 0 (in case of - failure). - - void cleanStrTbl(); - -- this function has to be called when all - VObject has been destroyed. - - void cleanVObject(VObject *o); - -- release all resources used by VObject o. - - wchar_t* fakeUnicode(const char *ps, int *bytes); - -- convert char* to wchar_t*. - - extern int uStrLen(const wchar_t *u); - -- length of unicode u. - - char *fakeCString(const wchar_t *u); - -- convert wchar_t to CString (blindly assumes that - this could be done). - -9. Additional Programming Notes - ============================ -In the following notes, please refers to the listing -of Example.vcf and its VObject Representation -(shown at the end of this section). - -* Handling the Return Value of the VCard/VCalendar Parser - The example input text file contains two root VObjects - (a VCalendar and a VCard). The output of the VCard/VCalendar - parser is a null-terminated list of VObjects. For this - particular input file, the list will have two VObjects. - The following shows a template for iterating through the - output of the Parser: - - VObject *t, *v; - v = Parse_Mime_fromFileName("example.vcf"); - while (v) { - // currently, v will either be a VCard or a VCalendar - // do whatever your application need to do to - // v here ... - t = v; - v = nextVObjectInList(v); - cleanVObject(t); - } - -* Iterating Through a VCard/VCalendar VObject - From the VObject APIs point of view, a VCard VObject - is the same as a VCalendar VObject. However, the application - needs to know what are in a VCard or a VCalendar. - For example, A VCalendar VObject can have VCDCreatedProp, - a VCGEOLocationProp, etc, and one or more VCEventProp and - or VCTodoProp. The VCEventProp and VCTodoProp can have - many properties of their own, which in turn could have - more properties (e.g. VCDAlarmProp can be a VCEventProp - VObject's property, and VCRunTimeProp can be a - VCDAlarmProp VObject's property. Because a VObject tree - can be arbitrarily complex, in general, to process all - properties and values of a VObject tree, a recursive walk - is desirable. An example recursive VObject tree walk - can be found in the vobject.c source lines for printVObject* - and writeVObject* APIs. Depending on what the application need - to do with a VCard or a VCalendar, a recursive walk - of the VObject tree may or may not be desirable. An example - template of a non-recursive walk is shown below: - - void processVCardVCalendar(char *inputFile) - { - VObject *t, *v; - v = Parse_Mime_fromFileName(inputFile); - while (v) { - char *n = vObjectName(v); - if (strcmp(n,VCCardProp) == 0) { - do_VCard(v); - } - else if (strcmp(n,VCCalendarProp) == 0) { - do_VCalendar(v); - } - else { - // don't know how to handle anything else! - } - t = v; - v = nextVObjectInList(v); - cleanVObject(t); - } - } - - void do_VCard(VObject *vcard) - { - VObjectIterator t; - initPropIterator(&t,vcard); - while (moreIteration(&t)) { - VObject *eachProp = nextVObject(&t); - // The primarly purpose of this example is to - // show how to iterate through a VCard VObject, - // it is not meant to be efficient at all. - char *n = vObjectName(eachProp); - if (strcmp(n,VCNameProp)==0) { - do_name(eachProp); - } - else if (strcmp(n,VCEmailProp)==0) { - do_email(eachProp); - } - else if (strcmp(n,VCLabelProp)==0) { - do_label(eachProp); - } - else if .... - } - } - - void do_VCalendar(VObject *vcal) - { - VObjectIterator t; - initPropIterator(&t,vcard); - while (moreIteration(&t)) { - VObject *eachProp = nextVObject(&t); - // The primarly purpose of this example is to - // show how to iterate through a VCalendar VObject, - // it is not meant to be efficient at all. - char *n = vObjectName(eachProp); - if (strcmp(n,VCDCreatedProp)==0) { - do_DCreated(eachProp); - } - else if (strcmp(n,VCVersionProp)==0) { - do_Version(eachProp); - } - else if (strcmp(n,VCTodoProp)==0) { - do_Todo(eachProp); - } - else if (strcmp(n,VCEventProp)==0) { - do_Event(eachProp); - } - else if .... - } - } - - void do_Todo(VObject *vtodo) { ... } - - void do_Event(VObject *vevent) { ... } - - ... - -* Property's Values and Properties - The VObject APIs do not attempt to check for the - correctness of the values of a property. Nor do they - will prevent the user from attaching a non-VCard/VCalendar - standard property to a VCard/VCalendar property. Take - the example of line [11] of the example, "O.K" is not - a valid value of VCStatusProp. It is up to the application - to accept or reject the value of a property. - -* Output of printVObject - PrintVObject pretty prints a VObject tree in human - readable form. See the listing at the end of the file - for an example output of printVObject on the example - input file "Example.vcf". - - Note that binary data are not shown in the output of - printVObject. Instead, a note is made ([raw data]) to - indicate that there exists such a binary data. - -* Note on Binary Data - When the value of a property is a binary data, it is only - useful to know the size of the binary data. - - In the case of the VCard/VCalendar parser, it chooses - to represent the size information as a separate property - called VCDataSizeProp whose value is the size of the binary - data. The APIs sequence to construct the VObject subtree - of line [44] of Example.vcf is - - // VObject *vcard; - VObject *p1 = addProp(vcard,VCLogoProp); - (void) addProp(p1,VCGIFProp); - (void) addProp(p1,VCBASE64Prop); - VObject *p2 = addProp(p1,VCDataSizeProp); - (void) setVObjectLongValue(p2,1482); - setVObjectAnyValue(vcard,...pointer to binary data); - - Note the presence of VCBase64Prop will cause the - writeVObject API to output the binary data as BASE64 text. - For VCard/VCalendar application, having the VCBase64Prop - property is pratically always neccessary for property with - binary data as its value. - -* Note on Quoted-Printable String - String value with embedded newline are written out as - quoted-prinatable string. It is therefore important - to mark a property with a string value that has - one or more embedded newlines, with the VCQutedPrintableProp - property. e.g. - - // VObject *root; - char *msg="To be\nor\nnot to be"; - VObject *p = addPropValue(root,VCDescriptionProp,msg); - // the following is how you mark a property with - // a property. In this case, the marker is - // VCQuotedPrintableProp - addProp(p,VCQuotedPrintableProp); - -* Note on Unicode - Although, the current parser takes ASCII text file only, - string values are all stored as Unicode in the VObject tree. - For now, when using the VObject APIs to construct a - VObject tree, one should always convert ASCII string value - to a Unicode string value: - - // VObject *root; - VObject *p = addProp(root,VCSomeProp); - setVObjectUStringZValue(p,fakeUnicode(someASCIIStringZvalue)); - - An API is provided to simplify the above process: - - addPropValue(root,VCSomeProp,someASCIIStringZValue); - - Note that someASCIISTringZValue is automatically converted to - Unicode by addPropValue API, where as, the former code - sequence do an explicit call to fakeUnicode. - - To read back the value, one should use the vObjectUStringZValue - API not vObjectStringZValue API. The value returned by the - vObjectUStringZValue API is a Unicode string. If the application - do not know how to handle Unicode string, it can use the - fakeCString API to convert it back to ASCII string (as long - as the conversion is meaningful). - - Note that fakeCString return a heap allocated memory. It is - important to call deleteStr on fakeCString return value if - it is not longer required (or there will be memory leak). - - NOTE: Unfortunately, at the point when this document is written, - there is still no consensus on how Unicode is to be handled - in the textual representation of VCard/VCalendar. So, there - is no version of writeVObject and the parser to output and - input Unicode textual representation of VCard/VCalendar. - - -Example.vcf ------------ -line -number Input Text (example.vcf) ------- ---------- -1 BEGIN:VCALENDAR -2 DCREATED:19961102T100522 -3 GEO:0,0 -4 VERSION:1.0 -5 BEGIN:VEVENT -6 DTSTART:19961103T000000 -7 DTEND:20000101T000000 -8 DESCRIPTION;QUOTED-PRINTABLE:To be =0A= -9 or =0A= -10 not to be -11 STATUS:O.K. -12 X-ACTION:No action required -13 DALARM:19961103T114500;5;3;Enjoy -14 MALARM:19970101T120000;;;johny@nowhere.com;Call Mom. -15 END:VEVENT -16 -17 BEGIN:VTODO -18 DUE:19960614T0173000 -19 DESCRIPTION:Relex. -20 END:VTODO -21 -22 END:VCALENDAR -23 -24 BEGIN:VCARD -25 N:Alden;Roland -26 FN:Roland H. Alden -27 ORG:AT&T;Versit Project Office -28 TITLE:Consultant -29 EMAIL;WORK;PREF;INTERNET:ralden@ralden.com -30 LABEL;DOM;POSTAL;PARCEL;HOME;WORK;QUOTED-PRINTABLE:Roland H. Alden=0A= -31 Suite 2208=0A= -32 One Pine Street=0A= -33 San Francisco, CA 94111 -34 LABEL;POSTAL;PARCEL;HOME;WORK;QUOTED-PRINTABLE:Roland H. Alden=0A= -35 Suite 2208=0A= -36 One Pine Street=0A= -37 San Francisco, CA 94111=0A= -38 U.S.A. -39 TEL;WORK;PREF;MSG:+1 415 296 9106 -40 TEL;WORK;FAX:+1 415 296 9016 -41 TEL;MSG;CELL:+1 415 608 5981 -42 ADR:;Suite 2208;One Pine Street;San Francisco;CA;94111;U.S.A. -43 SOUND:ROW-LAND H ALL-DIN -44 LOGO;GIF;BASE64: -45 R0lGODdhpgBOAMQAAP///+/v797e3s7Ozr29va2trZycnIyMjHt7e2NjY1JSUkJC - ... 30 lines of BASE64 data not shown here. -76 END:VCARD - - -VObject Representation of Example.vcf: -------------------------------------- -line -in -text -file VObject Tree as Printed by printVObject API ----- ------------------------------------------- -1 VCALENDAR -2 DCREATED="19961102T100522" -3 GEO="0,0" -4 VERSION="1.0" -5 VEVENT -6 DTSTART="19961103T000000" -7 DTEND="20000101T000000" -8 DESCRIPTION="To be -9 or -10 not to be" -8 QUOTED-PRINTABLE -11 STATUS="O.K." -12 X-ACTION="No action required" -13 DALARM -13 RUNTIME="19961103T114500" -13 SNOOZETIME="5" -13 REPEATCOUNT="3" -13 DISPLAYSTRING="Enjoy" -14 MALARM -14 RUNTIME="19970101T120000" -14 EMAIL="johny@nowhere.com" -14 NOTE="Call Mom" -17 VTODO -18 DUE="19960614T0173000" -19 DESCRIPTION="Relex." -24 VCARD -25 N -25 F="Alden" -25 G="Roland" -26 FN="Roland H. Alden" -27 ORG -27 ORGNAME="AT&T" -27 OUN="Versit Project Office" -28 TITLE="Consultant" -29 EMAIL="ralden@alden.com" -29 WORK -29 PREF -29 INTERNET -30 LABEL="Roland H. Alden -31 Suite 2208 -32 One Pine Street -33 San Francisco, CA 94111" -30 DOM -30 POSTAL -30 PARCEL -30 HOME -30 WORK -30 QUOTED-PRINTABLE -34 LABEL="Roland H. Alden -35 Suite 2208 -36 One Pine Street -37 San Francisco, CA 94111 -38 U.S.A." -34 POSTAL -34 PARCEL -34 HOME -34 WORK -34 QUOTED-PRINTABLE -39 TEL="+1 415 296 9106" -39 WORK -39 PREF -39 MSG -40 TEL="+1 415 296 9016" -40 WORK -40 FAX -41 TEL="+1 415 608 5981" -41 MSG -41 CELL -42 ADR -42 EXT ADD="Suite 2208" -42 STREET="One Pine Street" -42 L="San Francisco" -42 R="CA" -42 PC="94111" -42 C="U.S.A." -43 SOUND="ROW-LAND H ALL-DIN" -44 LOGO=[raw data] -44 GIF -44 BASE64 -44 DATASIZE=1482 - +NOTE: If you used the earlier APIs released by Versit +then you will want to look at the document "migrate.doc" +included with this package. It contains a discussion of +the differences between the old API and this one. + +---------------------------------------------------------------- + +The vCard/vCalendar C interface is implemented in the set +of files as follows: + +vcc.y, yacc source, and vcc.c, the yacc output you will use +implements the core parser + +vobject.c implements an API that insulates the caller from +the parser and changes in the vCard/vCalendar BNF + +port.h defines compilation environment dependent stuff + +vcc.h and vobject.h are header files for their .c counterparts + +vcaltmp.h and vcaltmp.c implement vCalendar "macro" functions +which you may find useful. + +test.c is a standalone test driver that exercises some of +the features of the APIs provided. Invoke test.exe on a +VCARD/VCALENDAR input text file and you will see the pretty +print output of the internal representation (this pretty print +output should give you a good idea of how the internal +representation looks like -- there is one such output in the +following too). Also, a file with the .out suffix is generated +to show that the internal representation can be written back +in the original text format. + +----------------------------------------------------------------- + + + VObject for VCard/VCalendar + +Table of Contents +================= +1. VObject +2. Internal Representations of VCard/VCalendar +3. Iterating Through VObject's Properties or Values +4. Pretty Printing a VObject Tree +5. Building A VObject Representation of A VCard/VCalendar +6. Converting A VObject Representation Into Its Textual Representation +7. Miscellaneous Notes On VObject APIs usages +8. Brief descriptions of each APIs +9. Additional Programming Notes. + +This document is mainly about the VObject and its APIs. The main +use of a VObject is to represent a VCard or a VCalendar inside +a program. However, its use is not limited to aforemention as it +can represent an arbitrary information that makes up of a tree or +forest of properties/values. + +1. VObject + ======= +A VObject can have a name (id) and a list of associated properties and +a value. Each property is itself a VObject. + +2. Internal Representations of VCard/VCalendar + =========================================== +A list of VCard or a VCalendar is represented by a list of VObjects. +The name (id) of the VObjects in the list is either VCCardProp or +VCCalProp. Each of these VObjects can have a list of properties. +Since a property is represented as a VObject, each of these properties +can have a name, a list of properties, and a value. + +For example, the input file "vobject.vcf": + +BEGIN:VCARD +N:Alden;Roland +FN:Roland H. Alden +ORG:AT&T;Versit Project Office +TITLE:Consultant +EMAIL;WORK;PREF;INTERNET:sf!rincon!ralden@alden.attmail.com +EMAIL;INTERNET:ralden@sfgate.com +EMAIL;MCIMail:242-2200 +LABEL;DOM;POSTAL;PARCEL;HOME;WORK;QUOTED-PRINTABLE:Roland H. Alden=0A= +Suite 2208=0A= +One Pine Street=0A= +San Francisco, CA 94111 +LABEL;POSTAL;PARCEL;HOME;WORK;QUOTED-PRINTABLE:Roland H. Alden=0A= +Suite 2208=0A= +One Pine Street=0A= +San Francisco, CA 94111=0A= +U.S.A. +TEL;WORK;PREF;MSG:+1 415 296 9106 +TEL;WORK;FAX:+1 415 296 9016 +TEL;MSG;CELL:+1 415 608 5981 +ADR:;Suite 2208;One Pine Street;San Francisco;CA;94111;U.S.A. +SOUND:ROW-LAND H ALL-DIN +LOGO;GIF;BASE64: + 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 + +BEGIN:VCALENDAR +DCREATED:19960523T100522 +PRODID:-//Alden Roland/Hand Crafted In North Carolina//NONSGML Made By Hand//EN +VERSION:0.3 +BEGIN:VEVENT +START:19960523T120000 +END:19960523T130000 +SUBTYPE:PHONE CALL +SUMMARY:VERSIT PDI PR Teleconference/Interview +DESCRIPTION:VERSIT PDI PR Teleconference/Interview With Tom Streeter and Alden Roland +END:VEVENT +BEGIN:VEVENT +START:19960523T113000 +END:19960523T115500 +SUBTYPE:LUNCH +SUMMARY:Eat in the cafeteria today +END:VEVENT +END:VCALENDAR + +END:VCARD + + +will conceptually be be represented as + vcard + VCNameProp + VCFamilyNameProp=Alden + VCGivenNameProp=Roland + VCFullNameProp=Roland H.Alden + .... + +note that + EMAIL;WORK;PREF;INTERNET:sf!rincon!ralden@alden.attmail.com +will be represented as: + VCEmailAddress=sf!rincon!ralden@alden.attmail.com + VCWork + VCPreferred + VCInternet +where the lower level properties are properties of the property +VCEmailAddress. + +Groupings are flattened out in the VObject representation such +that: + a.b:blah + a.c:blahblah +are represented as: + b=blah + VCGrouping=a + c=blahblah + VCGrouping=a +i.e. one can read the above as: + the property "b" has value "blah" and property "VCGrouping" + with the value "a". + the property "c" has value "blahblah" and property "VCGrouping" + with the value "a". +likewise, multi-level groupings are flatten similarly. e.g. + a.b.c:blah + a.b.e:blahblah +--> + c=blah + VCGrouping=b + VCGrouping=a + e=blahblah + VCGrouping=b + VCGrouping=a +which read: + the property "c" has value "blah" and property "VCGrouping" + with the value "b" which has property "VCGrouping" + with value "a". + the property "e" has value "blahblah" and property "VCGrouping" + with the value "b" which has property "VCGrouping" + with value "a". + +3. Iterating Through VObject's Properties or Values + ================================================ +The following is a skeletal form of iterating through +all properties of a vobject, o: + + // assume the object of interest, o, is of type VObject + VObjectIterator i; + initPropIterator(&i,o); + while (moreIteration(&i)) { + VObject *each = nextVObject(&i); + // ... do something with "each" property + } + +Use the API vObjectName() to access a VObject's name. +Use the API vObjectValueType() to determine if a VObject has + a value. For VCard/VCalendar application, you + should not need this function as practically + all values are either of type VCVT_USTRINGZ or + VCVT_RAW (i.e set by setVObjectUStringZValue and + setVObjectAnyValue APIs respectively), and the + value returned by calls to vObjectUStringZValue + and vObjectAnyValue are 0 if a VObject has no + value. (There is a minor exception where VObject with + VCDataSizeProp has value that is set by + setVObjectLongValue). +Use the APIs vObject???Value() to access a VObject's value. + where ??? is the expected type. +Use the APIs setvObject???Value() to set or modify a VObject's value. + where ??? is the expected type. +Use the API isAPropertyOf() to query if a name match the name of + a property of a VObject. Since isAPropertyOf() return + the matching property, we can use that to retrieve + a property and subsequently the value of the property. + +4. Pretty Printing a VObject Tree + ============================== +VObject tree can be pretty printed with the printVObject() function. +The output of pretty printing a VObject representation of the input +test file "vobject.vcf" is shown below. Note that the indentation +indicates the tree hirerarchy where the immediate children nodes +of a parent node is all at the same indentation level and the +immediate children nodes are the immediate properties of the +associated parent nodes. In the following, {N,FN,ORG,TITLE,...} +are immediate properties of VCARD. {F and G} are properties of N +with value {"Alden" and "Roland"} respectively; FN has no property +but has the value "Roland H. Alden"; EMAIL has value and +the properties WORK, PREF, and INTERNET. + + +VCARD + N + F="Alden" + G="Roland" + FN="Roland H. Alden" + ORG + ORGNAME="AT&T" + OUN="Versit Project Office" + TITLE="Consultant" + EMAIL="sf!rincon!ralden@alden.attmail.com" + WORK + PREF + INTERNET + EMAIL="ralden@sfgate.com" + INTERNET + EMAIL="242-2200" + MCIMail + LABEL="Roland H. Alden + Suite 2208 + One Pine Street + San Francisco, CA 94111" + DOM + POSTAL + PARCEL + HOME + WORK + QP + LABEL="Roland H. Alden + Suite 2208 + One Pine Street + San Francisco, CA 94111 + U.S.A." + POSTAL + PARCEL + HOME + WORK + QP + TEL="+1 415 296 9106" + WORK + PREF + MSG + TEL="+1 415 296 9016" + WORK + FAX + TEL="+1 415 608 5981" + MSG + CELL + ADR + EXT ADD="Suite 2208" + STREET="One Pine Street" + L="San Francisco" + R="CA" + PC="94111" + C="U.S.A." + SOUND="ROW-LAND H ALL-DIN" + LOGO=[raw data] + GIF + BASE64 + DataSize=1482 +VCALENDAR + DCREATED="19960523T100522" + PRODID="-//Alden Roland/Hand Crafted In North Carolina//NONSGML Made By Hand//EN" + VERSION="0.3" + VEVENT + START="19960523T120000" + END="19960523T130000" + SUBTYPE="PHONE CALL" + SUMMARY="VERSIT PDI PR Teleconference/Interview" + DESCRIPTION="VERSIT PDI PR Teleconference/Interview With Tom Streeter and Alden Roland" + VEVENT + START="19960523T113000" + END="19960523T115500" + SUBTYPE="LUNCH" + SUMMARY="Eat in the cafeteria today" + +5. Building A VObject Representation of A VCard/VCalendar + ====================================================== +The parser in vcc.y converts an input file with one or more +VCard/VCalendar that is in their textual representation +into their corresponding VObject representation. + +VObject representation of a VCard/VCalendar can also be built +directly with calls to the VObject building APIs. e.g. + + VObject *prop; + VObject *vcard = newVObject(VCCardProp); + prop = addProp(vcard,VCNameProp); + addPropValue(prop,VCFamilyNameProp,"Alden"); + addPropValue(prop,VCGivenNameProp,"Roland"); + addPropValue(vcard,VCFullNameProp,"Roland H. Alden"); + .... + +6. Converting A VObject Representation Into Its Textual Representation + =================================================================== +The VObject representation can be converted back to its textual +representation via the call to writeVObject() or writeMemVObject() +API. e.g. + a. to write to a file: + // assume vcard is of type VObject + FILE *fp = fopen("alden.vcf","w"); + writeVObject(fp,vcard); + a. to write to memory, and let the API allocate the required memory. + char* clipboard = writeVObject(0,0,vcard); + ... do something to clipboard + free(clipboard); + b. to write to a user allocated buffer: + char clipboard[16384]; + int len = 16384; + char *buf = writeVObject(clipboard,&len,vcard); + ... buf will be equal to clipboard if the write + is successful otherwise 0. + +In the case of writing to memory, the memory buffer can be either +allocated by the API or the user. If the user allocate the +memory for the buffer, then the length of the buffer needs to be +communicated to the API via a variable. The variable passed as +the length argument will be overwritten with the actual size +of the text output. A 0 return value from writeMemVObject() +indicates an error which could be caused by overflowing the +size of the buffer or lack of heap memory. + +7. Miscellaneous Notes On VObject APIs usages + ========================================== +a. vcc.h -- contains basic interfaces to the parser: + VObject* Parse_MIME(const char *input, unsigned long len); + VObject* Parse_MIME_FromFile(FILE *file); + -- both of this return a null-terminated list of + VObject that is either a VCARD or VCALENDAR. + To iterate through this list, do + VObject *t, *v; + v = Parse_Mime_FromFile(fp); + while (v) { + // ... do something to v. + t = v; + v = nextVObjectInList(v); + cleanVObject(t); + } + note that call to cleanVObject will release + resource used to represent the VObject. + +b. vobject.h -- contains basic interfaces to the VObject APIs. + see the header for more details. + The structure of VObject is purposely (hiddened) not exposed + to the user. Every access has to be done via + the APIs. This way, if we need to change the + structure or implementation, the client need not + recompile as long as the interfaces remain the + same. + +c. values of a property is determined by the property definition + itself. The vobject APIs does not attempt to enforce + any of such definition. It is the consumer responsibility + to know what value is expected from a property. e.g + most properties have unicode string value, so to access + the value of these type of properties, you will use + the vObjectUStringZValue() to read the value and + setVObjectUStringZValue() to set or modify the value. + Refer to the VCard and VCalendar specifications for + the definition of each property. + +d. properties name (id) are case incensitive. + +8. Brief descriptions of each APIs + =============================== + * the predefined properties' names (id) are listed under vobject.h + each is of the form VC*Prop. e.g. + #define VC7bitProp "7BIT" + #define VCAAlarmProp "AALARM" + .... + + * consumer of a VObject can only define pointers to VObject. + + * a variable of type VObjectIterator, say "i", can be used to iterate + through a VObject's properties, say "o". The APIs related to + VObjectIterator are: + void initPropIterator(VObjectIterator *i, VObject *o); + -- e.g. usage + initPropIterator(&i,o); + int moreIteration(VObjectIterator *i); + -- e.g. usage + while (moreIteration(&i)) { ... } + VObject* nextVObject(VObjectIterator *i); + -- e.g. usage + while (moreIteration(&i)) { + VObject *each = nextVObject(&i); + } + + * VObject can be chained together to form a list. e.g. of such + use is in the parser where the return value of the parser is + a link list of VObject. A link list of VObject can be + built by: + void addList(VObject **o, VObject *p); + and iterated by + VObject* nextVObjectInList(VObject *o); + -- next VObjectInList return 0 if the list + is exhausted. + + * the following APIs are mainly used to construct a VObject tree: + VObject* newVObject(const char *id); + -- used extensively internally by VObject APIs but when + used externally, its use is mainly limited to the + construction of top level object (e.g. an object + with VCCardProp or VCCalendarProp id). + + void deleteVObject(VObject *p); + -- to deallocate single VObject, for most user, use + cleanVObject(VObject *o) instead for freeing all + resources associated with the VObject. + + char* dupStr(const char *s, unsigned int size); + -- duplicate a string s. If size is 0, the string is + assume to be a null-terminated. + + void deleteStr(const char *p); + -- used to deallocate a string allocated by dupStr(); + + void setVObjectName(VObject *o, const char* id); + -- set the id of VObject o. This function is not + normally used by the user. The setting of id + is normally done as part of other APIs (e.g. + addProp()). + + void setVObjectStringZValue(VObject *o, const char *s); + -- set a string value of a VObject. + + void setVObjectUStringZValue(VObject *o, const wchar_t *s); + -- set a Unicode string value of a VObject. + + void setVObjectIntegerValue(VObject *o, unsigned int i); + -- set an integer value of a VObject. + + void setVObjectLongValue(VObject *o, unsigned long l); + -- set an long integer value of a VObject. + + void setVObjectAnyValue(VObject *o, void *t); + -- set any value of a VObject. The value type is + unspecified. + + VObject* setValueWithSize(VObject *prop, void *val, unsigned int size); + -- set a raw data (stream of bytes) value of a VObject + whose size is size. The internal VObject representation + is + this object = val + VCDataSizeProp=size + i.e. the value val will be attached to the VObject prop + and a property of VCDataSize whose value is size + is also added to the object. + + void setVObjectVObjectValue(VObject *o, VObject *p); + -- set a VObject as the value of another VObject. + + const char* vObjectName(VObject *o); + -- retrieve the VObject's Name (i.e. id). + + const char* vObjectStringZValue(VObject *o); + -- retrieve the VObject's value interpreted as + null-terminated string. + + const wchar_t* vObjectUStringZValue(VObject *o); + -- retrieve the VObject's value interpreted as + null-terminated unicode string. + + unsigned int vObjectIntegerValue(VObject *o); + -- retrieve the VObject's value interpreted as + integer. + + unsigned long vObjectLongValue(VObject *o); + -- retrieve the VObject's value interpreted as + long integer. + + void* vObjectAnyValue(VObject *o); + -- retrieve the VObject's value interpreted as + any value. + + VObject* vObjectVObjectValue(VObject *o); + -- retrieve the VObject's value interpreted as + a VObject. + + VObject* addVObjectProp(VObject *o, VObject *p); + -- add a VObject p as a property of VObject o. + (not normally used externally for building a + VObject). + + VObject* addProp(VObject *o, const char *id); + -- add a property whose name is id to VObject o. + + VObject* addPropValue(VObject *o, const char *id, const char *v); + -- add a property whose name is id and whose value + is a null-terminated string to VObject o. + + VObject* addPropSizedValue(VObject *o, const char *id, + const char *v, unsigned int size); + -- add a property whose name is id and whose value + is a stream of bytes of size size, to VObject o. + + VObject* addGroup(VObject *o, const char *g); + -- add a group g to VObject o. + e.g. if g is a.b.c, you will have + o + c + VCGroupingProp=b + VCGroupingProp=a + and the object c is returned. + + VObject* isAPropertyOf(VObject *o, const char *id); + -- query if a property by the name id is in o and + return the VObject that represent that property. + + void printVObject(VObject *o); + -- pretty print VObject o to stdout (for debugging use). + + void writeVObject(FILE *fp, VObject *o); + -- convert VObject o to its textual representation and + write it to file. + + char* writeMemVObject(char *s, int *len, VObject *o); + -- convert VObject o to its textual representation and + write it to memory. If s is 0, then memory required + to hold the textual representation will be allocated + by this API. If a variable len is passed, len will + be overwriten with the byte size of the textual + representation. If s is non-zero, then s has to + be a user allocated buffer whose size has be passed + in len as a variable. Memory allocated by the API + has to be freed with call to free. The return value + of this API is either the user supplied buffer, + the memory allocated by the API, or 0 (in case of + failure). + + void cleanStrTbl(); + -- this function has to be called when all + VObject has been destroyed. + + void cleanVObject(VObject *o); + -- release all resources used by VObject o. + + wchar_t* fakeUnicode(const char *ps, int *bytes); + -- convert char* to wchar_t*. + + extern int uStrLen(const wchar_t *u); + -- length of unicode u. + + char *fakeCString(const wchar_t *u); + -- convert wchar_t to CString (blindly assumes that + this could be done). + +9. Additional Programming Notes + ============================ +In the following notes, please refers to the listing +of Example.vcf and its VObject Representation +(shown at the end of this section). + +* Handling the Return Value of the VCard/VCalendar Parser + The example input text file contains two root VObjects + (a VCalendar and a VCard). The output of the VCard/VCalendar + parser is a null-terminated list of VObjects. For this + particular input file, the list will have two VObjects. + The following shows a template for iterating through the + output of the Parser: + + VObject *t, *v; + v = Parse_Mime_fromFileName("example.vcf"); + while (v) { + // currently, v will either be a VCard or a VCalendar + // do whatever your application need to do to + // v here ... + t = v; + v = nextVObjectInList(v); + cleanVObject(t); + } + +* Iterating Through a VCard/VCalendar VObject + From the VObject APIs point of view, a VCard VObject + is the same as a VCalendar VObject. However, the application + needs to know what are in a VCard or a VCalendar. + For example, A VCalendar VObject can have VCDCreatedProp, + a VCGEOLocationProp, etc, and one or more VCEventProp and + or VCTodoProp. The VCEventProp and VCTodoProp can have + many properties of their own, which in turn could have + more properties (e.g. VCDAlarmProp can be a VCEventProp + VObject's property, and VCRunTimeProp can be a + VCDAlarmProp VObject's property. Because a VObject tree + can be arbitrarily complex, in general, to process all + properties and values of a VObject tree, a recursive walk + is desirable. An example recursive VObject tree walk + can be found in the vobject.c source lines for printVObject* + and writeVObject* APIs. Depending on what the application need + to do with a VCard or a VCalendar, a recursive walk + of the VObject tree may or may not be desirable. An example + template of a non-recursive walk is shown below: + + void processVCardVCalendar(char *inputFile) + { + VObject *t, *v; + v = Parse_Mime_fromFileName(inputFile); + while (v) { + char *n = vObjectName(v); + if (strcmp(n,VCCardProp) == 0) { + do_VCard(v); + } + else if (strcmp(n,VCCalendarProp) == 0) { + do_VCalendar(v); + } + else { + // don't know how to handle anything else! + } + t = v; + v = nextVObjectInList(v); + cleanVObject(t); + } + } + + void do_VCard(VObject *vcard) + { + VObjectIterator t; + initPropIterator(&t,vcard); + while (moreIteration(&t)) { + VObject *eachProp = nextVObject(&t); + // The primarly purpose of this example is to + // show how to iterate through a VCard VObject, + // it is not meant to be efficient at all. + char *n = vObjectName(eachProp); + if (strcmp(n,VCNameProp)==0) { + do_name(eachProp); + } + else if (strcmp(n,VCEmailProp)==0) { + do_email(eachProp); + } + else if (strcmp(n,VCLabelProp)==0) { + do_label(eachProp); + } + else if .... + } + } + + void do_VCalendar(VObject *vcal) + { + VObjectIterator t; + initPropIterator(&t,vcard); + while (moreIteration(&t)) { + VObject *eachProp = nextVObject(&t); + // The primarly purpose of this example is to + // show how to iterate through a VCalendar VObject, + // it is not meant to be efficient at all. + char *n = vObjectName(eachProp); + if (strcmp(n,VCDCreatedProp)==0) { + do_DCreated(eachProp); + } + else if (strcmp(n,VCVersionProp)==0) { + do_Version(eachProp); + } + else if (strcmp(n,VCTodoProp)==0) { + do_Todo(eachProp); + } + else if (strcmp(n,VCEventProp)==0) { + do_Event(eachProp); + } + else if .... + } + } + + void do_Todo(VObject *vtodo) { ... } + + void do_Event(VObject *vevent) { ... } + + ... + +* Property's Values and Properties + The VObject APIs do not attempt to check for the + correctness of the values of a property. Nor do they + will prevent the user from attaching a non-VCard/VCalendar + standard property to a VCard/VCalendar property. Take + the example of line [11] of the example, "O.K" is not + a valid value of VCStatusProp. It is up to the application + to accept or reject the value of a property. + +* Output of printVObject + PrintVObject pretty prints a VObject tree in human + readable form. See the listing at the end of the file + for an example output of printVObject on the example + input file "Example.vcf". + + Note that binary data are not shown in the output of + printVObject. Instead, a note is made ([raw data]) to + indicate that there exists such a binary data. + +* Note on Binary Data + When the value of a property is a binary data, it is only + useful to know the size of the binary data. + + In the case of the VCard/VCalendar parser, it chooses + to represent the size information as a separate property + called VCDataSizeProp whose value is the size of the binary + data. The APIs sequence to construct the VObject subtree + of line [44] of Example.vcf is + + // VObject *vcard; + VObject *p1 = addProp(vcard,VCLogoProp); + (void) addProp(p1,VCGIFProp); + (void) addProp(p1,VCBASE64Prop); + VObject *p2 = addProp(p1,VCDataSizeProp); + (void) setVObjectLongValue(p2,1482); + setVObjectAnyValue(vcard,...pointer to binary data); + + Note the presence of VCBase64Prop will cause the + writeVObject API to output the binary data as BASE64 text. + For VCard/VCalendar application, having the VCBase64Prop + property is pratically always neccessary for property with + binary data as its value. + +* Note on Quoted-Printable String + String value with embedded newline are written out as + quoted-prinatable string. It is therefore important + to mark a property with a string value that has + one or more embedded newlines, with the VCQutedPrintableProp + property. e.g. + + // VObject *root; + char *msg="To be\nor\nnot to be"; + VObject *p = addPropValue(root,VCDescriptionProp,msg); + // the following is how you mark a property with + // a property. In this case, the marker is + // VCQuotedPrintableProp + addProp(p,VCQuotedPrintableProp); + +* Note on Unicode + Although, the current parser takes ASCII text file only, + string values are all stored as Unicode in the VObject tree. + For now, when using the VObject APIs to construct a + VObject tree, one should always convert ASCII string value + to a Unicode string value: + + // VObject *root; + VObject *p = addProp(root,VCSomeProp); + setVObjectUStringZValue(p,fakeUnicode(someASCIIStringZvalue)); + + An API is provided to simplify the above process: + + addPropValue(root,VCSomeProp,someASCIIStringZValue); + + Note that someASCIISTringZValue is automatically converted to + Unicode by addPropValue API, where as, the former code + sequence do an explicit call to fakeUnicode. + + To read back the value, one should use the vObjectUStringZValue + API not vObjectStringZValue API. The value returned by the + vObjectUStringZValue API is a Unicode string. If the application + do not know how to handle Unicode string, it can use the + fakeCString API to convert it back to ASCII string (as long + as the conversion is meaningful). + + Note that fakeCString return a heap allocated memory. It is + important to call deleteStr on fakeCString return value if + it is not longer required (or there will be memory leak). + + NOTE: Unfortunately, at the point when this document is written, + there is still no consensus on how Unicode is to be handled + in the textual representation of VCard/VCalendar. So, there + is no version of writeVObject and the parser to output and + input Unicode textual representation of VCard/VCalendar. + + +Example.vcf +----------- +line +number Input Text (example.vcf) +------ ---------- +1 BEGIN:VCALENDAR +2 DCREATED:19961102T100522 +3 GEO:0,0 +4 VERSION:1.0 +5 BEGIN:VEVENT +6 DTSTART:19961103T000000 +7 DTEND:20000101T000000 +8 DESCRIPTION;QUOTED-PRINTABLE:To be =0A= +9 or =0A= +10 not to be +11 STATUS:O.K. +12 X-ACTION:No action required +13 DALARM:19961103T114500;5;3;Enjoy +14 MALARM:19970101T120000;;;johny@nowhere.com;Call Mom. +15 END:VEVENT +16 +17 BEGIN:VTODO +18 DUE:19960614T0173000 +19 DESCRIPTION:Relex. +20 END:VTODO +21 +22 END:VCALENDAR +23 +24 BEGIN:VCARD +25 N:Alden;Roland +26 FN:Roland H. Alden +27 ORG:AT&T;Versit Project Office +28 TITLE:Consultant +29 EMAIL;WORK;PREF;INTERNET:ralden@ralden.com +30 LABEL;DOM;POSTAL;PARCEL;HOME;WORK;QUOTED-PRINTABLE:Roland H. Alden=0A= +31 Suite 2208=0A= +32 One Pine Street=0A= +33 San Francisco, CA 94111 +34 LABEL;POSTAL;PARCEL;HOME;WORK;QUOTED-PRINTABLE:Roland H. Alden=0A= +35 Suite 2208=0A= +36 One Pine Street=0A= +37 San Francisco, CA 94111=0A= +38 U.S.A. +39 TEL;WORK;PREF;MSG:+1 415 296 9106 +40 TEL;WORK;FAX:+1 415 296 9016 +41 TEL;MSG;CELL:+1 415 608 5981 +42 ADR:;Suite 2208;One Pine Street;San Francisco;CA;94111;U.S.A. +43 SOUND:ROW-LAND H ALL-DIN +44 LOGO;GIF;BASE64: +45 R0lGODdhpgBOAMQAAP///+/v797e3s7Ozr29va2trZycnIyMjHt7e2NjY1JSUkJC + ... 30 lines of BASE64 data not shown here. +76 END:VCARD + + +VObject Representation of Example.vcf: +------------------------------------- +line +in +text +file VObject Tree as Printed by printVObject API +---- ------------------------------------------- +1 VCALENDAR +2 DCREATED="19961102T100522" +3 GEO="0,0" +4 VERSION="1.0" +5 VEVENT +6 DTSTART="19961103T000000" +7 DTEND="20000101T000000" +8 DESCRIPTION="To be +9 or +10 not to be" +8 QUOTED-PRINTABLE +11 STATUS="O.K." +12 X-ACTION="No action required" +13 DALARM +13 RUNTIME="19961103T114500" +13 SNOOZETIME="5" +13 REPEATCOUNT="3" +13 DISPLAYSTRING="Enjoy" +14 MALARM +14 RUNTIME="19970101T120000" +14 EMAIL="johny@nowhere.com" +14 NOTE="Call Mom" +17 VTODO +18 DUE="19960614T0173000" +19 DESCRIPTION="Relex." +24 VCARD +25 N +25 F="Alden" +25 G="Roland" +26 FN="Roland H. Alden" +27 ORG +27 ORGNAME="AT&T" +27 OUN="Versit Project Office" +28 TITLE="Consultant" +29 EMAIL="ralden@alden.com" +29 WORK +29 PREF +29 INTERNET +30 LABEL="Roland H. Alden +31 Suite 2208 +32 One Pine Street +33 San Francisco, CA 94111" +30 DOM +30 POSTAL +30 PARCEL +30 HOME +30 WORK +30 QUOTED-PRINTABLE +34 LABEL="Roland H. Alden +35 Suite 2208 +36 One Pine Street +37 San Francisco, CA 94111 +38 U.S.A." +34 POSTAL +34 PARCEL +34 HOME +34 WORK +34 QUOTED-PRINTABLE +39 TEL="+1 415 296 9106" +39 WORK +39 PREF +39 MSG +40 TEL="+1 415 296 9016" +40 WORK +40 FAX +41 TEL="+1 415 608 5981" +41 MSG +41 CELL +42 ADR +42 EXT ADD="Suite 2208" +42 STREET="One Pine Street" +42 L="San Francisco" +42 R="CA" +42 PC="94111" +42 C="U.S.A." +43 SOUND="ROW-LAND H ALL-DIN" +44 LOGO=[raw data] +44 GIF +44 BASE64 +44 DATASIZE=1482 + -- cgit v1.2.3