summaryrefslogtreecommitdiffstats
path: root/libkcal/versit/readme.txt
diff options
context:
space:
mode:
Diffstat (limited to 'libkcal/versit/readme.txt')
-rw-r--r--libkcal/versit/readme.txt944
1 files changed, 944 insertions, 0 deletions
diff --git a/libkcal/versit/readme.txt b/libkcal/versit/readme.txt
new file mode 100644
index 000000000..5f38fe005
--- /dev/null
+++ b/libkcal/versit/readme.txt
@@ -0,0 +1,944 @@
+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 necessary 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
+