3 * Copyright 2012, Raphaƫl Droz <raphael.droz+floss@gmail.com>
5 * abook's wrapper for libvformat:
6 * fits a vcard parsed by libvformat into a usable abook item list
9 * libvformat's vf_iface.h
10 * http://www.imc.org/pdi/vcard-21.txt
23 int vcard_parse_file_libvformat(char *filename) {
25 if (!vf_read_file(&vfobj, filename)) {
26 fprintf(stderr, "Could not read VCF file %s\n", filename);
30 // a libvformat property
32 // property number (used for multivalued properties)
36 char multival[MAX_FIELD_LEN] = { 0 };
37 size_t available = MAX_FIELD_LEN;
40 list_item item = item_create();
42 // fullname [ or struct-name [ or name ] ]
43 if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "FN", NULL))
44 if ((propval = vf_get_prop_value_string(prop, 0)))
45 item_fput(item, NAME, xstrdup(propval));
47 if (!propval && vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "N", "*", NULL)) {
48 // TODO: GIVENNAME , FAMILYNAME
49 propval = vf_get_prop_value_string(prop, 0);
51 item_fput(item, NAME, xstrdup(propval));
54 if (!propval && vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "NAME", NULL)) {
55 propval = vf_get_prop_value_string(prop, 0);
57 item_fput(item, NAME, xstrdup(propval));
61 // TODO: use our strconcat() ?
62 if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "EMAIL", NULL)) {
64 available = MAX_FIELD_LEN;
65 while (available > 0 && props < 5) {
66 propval = vf_get_prop_value_string(prop, props++);
67 if(!propval) continue;
68 if (available > 0 && *multival != 0)
69 strncat(multival, ",", available--);
70 strncat(multival, propval, available);
71 available -= strlen(propval);
73 if (available < MAX_FIELD_LEN)
74 item_fput(item, EMAIL, xstrdup(multival));
78 // PO Box, Extended Addr, Street, Locality, Region, Postal Code, Country
79 if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "ADR", NULL)) {
81 // PO Box: abook ignores
82 vf_get_prop_value_string(prop, props++);
85 propval = vf_get_prop_value_string(prop, props++);
86 if(propval) item_fput(item, ADDRESS2, xstrdup(propval));
88 propval = vf_get_prop_value_string(prop, props++);
89 if(propval) item_fput(item, ADDRESS, xstrdup(propval));
91 propval = vf_get_prop_value_string(prop, props++);
92 if(propval) item_fput(item, CITY, xstrdup(propval));
94 propval = vf_get_prop_value_string(prop, props++);
95 if(propval) item_fput(item, STATE, xstrdup(propval));
97 propval = vf_get_prop_value_string(prop, props++);
98 if(propval) item_fput(item, ZIP, xstrdup(propval));
100 propval = vf_get_prop_value_string(prop, props++);
101 if(propval) item_fput(item, COUNTRY, xstrdup(propval));
106 // city: not in libvformat
107 if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "ADR", "CITY", NULL)) {
108 propval = vf_get_prop_value_string(prop, 0);
109 item_fput(item, CITY, xstrdup(propval));
114 if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "C", NULL)) {
115 propval = vf_get_prop_value_string(prop, 0);
116 item_fput(item, COUNTRY, xstrdup(propval));
122 if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "TEL", "HOME")) {
123 propval = vf_get_prop_value_string(prop, 0);
124 item_fput(item, PHONE, xstrdup(propval));
126 // or grab a more generic one otherwise
127 else if(vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "TEL", NULL)) {
128 propval = vf_get_prop_value_string(prop, 0);
129 item_fput(item, PHONE, xstrdup(propval));
133 if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "TEL", "WORK", NULL)) {
134 propval = vf_get_prop_value_string(prop, 0);
135 item_fput(item, WORKPHONE, xstrdup(propval));
139 if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "TEL", "FAX", NULL)) {
140 propval = vf_get_prop_value_string(prop, 0);
141 item_fput(item, FAX, xstrdup(propval));
145 if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "TEL", "CELL", NULL)) {
146 propval = vf_get_prop_value_string(prop, 0);
147 item_fput(item, MOBILEPHONE, xstrdup(propval));
151 if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "NICKNAME", NULL)) {
152 propval = vf_get_prop_value_string(prop, 0);
153 item_fput(item, NICK, xstrdup(propval));
157 if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "URL", NULL)) {
158 propval = vf_get_prop_value_string(prop, 0);
159 item_fput(item, URL, xstrdup(propval));
163 if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "NOTE", NULL)) {
164 propval = vf_get_prop_value_string(prop, 0);
165 item_fput(item, NOTES, xstrdup(propval));
169 if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "BDAY", NULL)) {
170 propval = vf_get_prop_value_string(prop, 0);
171 item_fput(item, ANNIVERSARY, xstrdup(propval));
175 if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "CATEGORIES", NULL)) {
177 available = MAX_FIELD_LEN;
179 while (available > 0 && props < 5) {
180 propval = vf_get_prop_value_string(prop, props++);
181 if(!propval) continue;
182 if (available > 0 && *multival != 0)
183 strncat(multival, ",", available--);
184 strncat(multival, propval, available);
185 available -= strlen(propval);
187 if (available < MAX_FIELD_LEN)
188 item_fput(item, GROUPS, xstrdup(multival));
191 add_item2database(item);
193 } while (vf_get_next_object(&vfobj));