summaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/Makefile.am7
-rw-r--r--test/tests/access/access_1.vcf17
-rw-r--r--test/tests/adhoc/group_1.vcf6
-rw-r--r--test/tests/adhoc/group_2.vcf9
-rw-r--r--test/tests/adhoc/group_3.vcf13
-rw-r--r--test/tests/adhoc/group_4.vcf16
-rw-r--r--test/tests/adhoc/group_5.vcf16
-rw-r--r--test/tests/adhoc/group_6.vcf23
-rw-r--r--test/tests/adhoc/group_7.vcf46
-rw-r--r--test/tests/adhoc/mail_list_1.vcf4
-rw-r--r--test/tests/adhoc/mail_list_2.vcf4
-rw-r--r--test/tests/adhoc/mail_list_3.vcf3
-rw-r--r--test/tests/adhoc/mail_list_4.vcf13
-rw-r--r--test/tests/adhoc/mail_list_5.vcf19
-rw-r--r--test/tests/adhoc/mail_list_6.vcf4
-rw-r--r--test/tests/adhoc/multiple_objs_1.vcf21
-rw-r--r--test/tests/adhoc/straight_1.vcf2
-rw-r--r--test/tests/adhoc/straight_2.vcf3
-rw-r--r--test/tests/adhoc/straight_3.vcf3
-rw-r--r--test/tests/adhoc/straight_4.vcf3
-rw-r--r--test/tests/adhoc/straight_5.vcf3
-rw-r--r--test/tests/adhoc/straight_6.vcf3
-rw-r--r--test/tests/adhoc/straight_7.vcf3
-rw-r--r--test/tests/adhoc/straight_8.vcf4
-rw-r--r--test/tests/adhoc/straight_9.vcf4
-rw-r--r--test/tests/adhoc/straight_A.vcf7
-rw-r--r--test/tests/adhoc/straight_B.vcf4
-rw-r--r--test/tests/adhoc/straight_C.vcf4
-rw-r--r--test/tests/adhoc/straight_D.vcf4
-rw-r--r--test/tests/adhoc/straight_E.vcf4
-rw-r--r--test/tests/adhoc/straight_F.vcf5
-rw-r--r--test/tests/adhoc/straight_G.vcf8
-rw-r--r--test/tests/adhoc/straight_H.vcf11
-rw-r--r--test/tests/adhoc/straight_I.vcf12
-rw-r--r--test/tests/adhoc/straight_qp_1.vcf3
-rw-r--r--test/tests/adhoc/straight_qp_2.vcf3
-rw-r--r--test/tests/adhoc/straight_qp_3.vcf5
-rw-r--r--test/tests/adhoc/straight_qp_4.vcf5
-rw-r--r--test/tests/adhoc/vcal_1.vcs20
-rw-r--r--test/tests/spec/2_1_1-begin-1.vcf3
-rw-r--r--test/tests/spec/2_1_1-begin-2.vcf23
-rw-r--r--test/tests/spec/2_1_2-property.vcf7
-rw-r--r--test/tests/spec/2_1_3-delimiters.vcf7
-rw-r--r--test/tests/spec/2_1_4_1-grouping-nested.vcf9
-rw-r--r--test/tests/spec/2_1_4_1-grouping-sequential.vcf9
-rw-r--r--test/tests/spec/2_1_4_2-property-grouping.vcf4
-rw-r--r--test/tests/spec/2_1_6-charset.vcf3
-rw-r--r--test/tests/spec/2_1_7-language.vcf3
-rw-r--r--test/tests/spec/2_1_8-valuelocation.vcf4
-rw-r--r--test/tests/spec/2_2_1-fn.vcf3
-rw-r--r--test/tests/spec/2_2_2-name.vcf4
-rw-r--r--test/tests/spec/2_2_3-photo.vcf7
-rw-r--r--test/tests/spec/2_2_4-birthdate.vcf4
-rw-r--r--test/tests/spec/2_3_1-address.vcf3
-rw-r--r--test/tests/spec/2_3_2-label.vcf12
-rw-r--r--test/tests/spec/2_4_1-tel.vcf3
-rw-r--r--test/tests/spec/2_4_2-email.vcf16
-rw-r--r--test/tests/spec/2_4_3-mailer.vcf3
-rw-r--r--test/tests/spec/2_4_5-tz.vcf4
-rw-r--r--test/tests/spec/2_4_6-geo.vcf3
-rw-r--r--test/tests/spec/2_5_1-title.vcf3
-rw-r--r--test/tests/spec/2_5_2-role.vcf3
-rw-r--r--test/tests/spec/2_5_3-logo.vcf6
-rw-r--r--test/tests/spec/2_5_4-agent.vcf9
-rw-r--r--test/tests/spec/2_5_5-org.vcf3
-rw-r--r--test/tests/spec/2_6_1-comment.vcf6
-rw-r--r--test/tests/spec/2_6_2-revision.vcf4
-rw-r--r--test/tests/spec/2_6_3-sound.vcf8
-rw-r--r--test/tests/spec/2_6_4-url.vcf3
-rw-r--r--test/tests/spec/2_6_5-uid.vcf3
-rw-r--r--test/tests/utf-8/S15cx8.vcf352
-rw-r--r--test/tests/utf-8/S15cxu.vcf6
-rw-r--r--test/testsuppt.c409
-rw-r--r--test/testsuppt.h211
-rw-r--r--test/vformat.c858
75 files changed, 2362 insertions, 0 deletions
diff --git a/test/Makefile.am b/test/Makefile.am
new file mode 100644
index 0000000..883a1a7
--- /dev/null
+++ b/test/Makefile.am
@@ -0,0 +1,7 @@
+bin_PROGRAMS = vformat
+
+vformat_SOURCE = testsuppt.c vformat.c
+vformat_LDADD = ../src/.libs/libvformat.a testsuppt.o
+
+EXTRA_DIST = testsuppt.c testsuppt.h tests/access/*.vcf tests/adhoc/*.vc* tests/spec/*.vcf tests/utf-8/*.vcf
+TESTS = vformat \ No newline at end of file
diff --git a/test/tests/access/access_1.vcf b/test/tests/access/access_1.vcf
new file mode 100644
index 0000000..ecb8636
--- /dev/null
+++ b/test/tests/access/access_1.vcf
@@ -0,0 +1,17 @@
+BEGIN:VCARD
+N:frfrfr;frfrfr
+TEL;HOME;PREF:123456789
+FN:Fr. Frfrfr (fr the frfrfr)
+TEL;WORK;PREF:ABCDEFGHI
+ORG:fr;fr;fr;fr
+TEL;CELLULAR;PREF:JKLMNOP
+SOUND;WAVE;BASE64:
+ UklGRhAsAABXQVZFZm10IBAAAAABAAEAESsAABErAAABAAgAZGF0YesrAACAg4eC
+ eXR4e3uAhoiIiYmKjIiDfnx5eX6CgoKEhYWDenV5fH6BhISGiIiDfHZ2eXt/hIiK
+ jY2IhH12d3Vyc3uDiIiFf3l7fn18eXl+houFf319fnyAgHl5eoCIiISChIeAfnt2
+TEL;WORK:XXYYZZ!!
+SOUND;WAVE;BASE64:
+ UklGRhAsAABXQVZFZm10IBAAAAABAAEAESsAABErAAABAAgAZGF0YesrAACAg4eC
+ eXR4e3uAhoiIiYmKjIiDfnx5eX6CgoKEhYWDenV5fH6BhISGiIiDfHZ2eXt/hIiK
+ jY2IhH12d3Vyc3uDiIiFf3l7fn18eXl+houFf319fnyAgHl5eoCIiISChIeAfnt2
+END:VCARD
diff --git a/test/tests/adhoc/group_1.vcf b/test/tests/adhoc/group_1.vcf
new file mode 100644
index 0000000..c0ab6ef
--- /dev/null
+++ b/test/tests/adhoc/group_1.vcf
@@ -0,0 +1,6 @@
+BEGIN:VCARD
+N:aaa;bbb;ccc
+A.N:ddd;eee;fff
+B.N:ggg;hhh;iii
+C.N:jjj;kkk;lll
+END:VCARD
diff --git a/test/tests/adhoc/group_2.vcf b/test/tests/adhoc/group_2.vcf
new file mode 100644
index 0000000..bd5dad8
--- /dev/null
+++ b/test/tests/adhoc/group_2.vcf
@@ -0,0 +1,9 @@
+BEGIN:VCARD
+N:aaa;bbb;ccc
+X-1-FILLER:1;2;3;4;5;6;7;8
+A.N:ddd;eee;fff
+X-2-FILLER:1;2;3;4;5;6;7;8
+B.N:ggg;hhh;iii
+X-3-FILLER:1;2;3;4;5;6;7;8
+C.N:jjj;kkk;lll
+END:VCARD
diff --git a/test/tests/adhoc/group_3.vcf b/test/tests/adhoc/group_3.vcf
new file mode 100644
index 0000000..7f278ad
--- /dev/null
+++ b/test/tests/adhoc/group_3.vcf
@@ -0,0 +1,13 @@
+BEGIN:VCARD
+N:aaa;bbb;ccc
+FN:111;222;333
+X-1-FILLER:1;2;3;4;5;6;7;8
+A.N:ddd;eee;fff
+A.FN:111ddd;222eee;222fff
+X-2-FILLER:1;2;3;4;5;6;7;8
+B.N:ggg;hhh;iii
+B.FN:111ggg;222hhh;333iii
+X-3-FILLER:1;2;3;4;5;6;7;8
+C.N:jjj;kkk;lll
+C.FN:111jjj;222kkk;333lll
+END:VCARD
diff --git a/test/tests/adhoc/group_4.vcf b/test/tests/adhoc/group_4.vcf
new file mode 100644
index 0000000..23f9f06
--- /dev/null
+++ b/test/tests/adhoc/group_4.vcf
@@ -0,0 +1,16 @@
+BEGIN:VCARD
+N:aaa;bbb;ccc
+FN:111;222;333
+END:VCARD
+BEGIN:VCARD
+A.N:ddd;eee;fff
+A.FN:111ddd;222eee;222fff
+END:VCARD
+BEGIN:VCARD
+B.N:ggg;hhh;iii
+B.FN:111ggg;222hhh;333iii
+END:VCARD
+BEGIN:VCARD
+C.N:jjj;kkk;lll
+C.FN:111jjj;222kkk;333lll
+END:VCARD
diff --git a/test/tests/adhoc/group_5.vcf b/test/tests/adhoc/group_5.vcf
new file mode 100644
index 0000000..460777b
--- /dev/null
+++ b/test/tests/adhoc/group_5.vcf
@@ -0,0 +1,16 @@
+BEGIN:VCARD
+N:aaa;bbb;ccc
+FN:111;222;333
+BEGIN:VCARD
+A.N:ddd;eee;fff
+A.FN:111ddd;222eee;222fff
+BEGIN:VCARD
+B.N:ggg;hhh;iii
+B.FN:111ggg;222hhh;333iii
+BEGIN:VCARD
+C.N:jjj;kkk;lll
+C.FN:111jjj;222kkk;333lll
+END:VCARD
+END:VCARD
+END:VCARD
+END:VCARD
diff --git a/test/tests/adhoc/group_6.vcf b/test/tests/adhoc/group_6.vcf
new file mode 100644
index 0000000..4e5bffe
--- /dev/null
+++ b/test/tests/adhoc/group_6.vcf
@@ -0,0 +1,23 @@
+BEGIN:VCARD
+X-DUMMY-1:123
+X-DUMMY-2:456
+X-DUMMY-3:789
+ALPHA.LOGO;ENCODING=BASE64;TYPE=GIF:
+ R0lGODdhfgA4AOYAAAAAAK+vr62trVIxa6WlpZ+fnzEpCEpzlAha/0Kc74+PjyGM
+ SuecKRhrtX9/fzExORBSjCEYCGtra2NjYyF7nDGE50JrhAg51qWtOTl7vee1MWu1
+ 50o5e3PO/3sxcwAx/4R7GBgQOcDAwFoAQt61hJyMGHuUSpRKIf8A/wAY54yMjHt=
+ABC.X-DUMMY-1:123
+ABC.X-DUMMY-2:456
+ABC.X-DUMMY-3:789
+ALPHA.ABC.LOGO;ENCODING=BASE64;TYPE=GIF:
+ R0lGODdhfgA4AOYAAAAAAK+vr62trVIxa6WlpZ+fnzEpCEpzlAha/0Kc74+PjyGM
+ SuecKRhrtX9/fzExORBSjCEYCGtra2NjYyF7nDGE50JrhAg51qWtOTl7vee1MWu1
+ 50o5e3PO/3sxcwAx/4R7GBgQOcDAwFoAQt61hJyMGHuUSpRKIf8A/wAY54yMjHt=
+DEF.X-DUMMY-1:123
+DEF.X-DUMMY-2:456
+DEF.X-DUMMY-3:789
+ALPHA.DEF.LOGO;ENCODING=BASE64;TYPE=GIF:
+ R0lGODdhfgA4AOYAAAAAAK+vr62trVIxa6WlpZ+fnzEpCEpzlAha/0Kc74+PjyGM
+ SuecKRhrtX9/fzExORBSjCEYCGtra2NjYyF7nDGE50JrhAg51qWtOTl7vee1MWu1
+ 50o5e3PO/3sxcwAx/4R7GBgQOcDAwFoAQt61hJyMGHuUSpRKIf8A/wAY54yMjHt=
+END:VCARD
diff --git a/test/tests/adhoc/group_7.vcf b/test/tests/adhoc/group_7.vcf
new file mode 100644
index 0000000..9dcb356
--- /dev/null
+++ b/test/tests/adhoc/group_7.vcf
@@ -0,0 +1,46 @@
+BEGIN:VCARD
+X-DUMMY-1:123
+DEF.X-DUMMY-1:123
+ALPHA.LOGO;ENCODING=BASE64;TYPE=GIF:
+ R0lGODdhfgA4AOYAAAAAAK+vr62trVIxa6WlpZ+fnzEpCEpzlAha/0Kc74+PjyGM
+ SuecKRhrtX9/fzExORBSjCEYCGtra2NjYyF7nDGE50JrhAg51qWtOTl7vee1MWu1
+ 50o5e3PO/3sxcwAx/4R7GBgQOcDAwFoAQt61hJyMGHuUSpRKIf8A/wAY54yMjHt=
+ABC.X-DUMMY-1:123
+DEF.X-DUMMY-2:456
+X-DUMMY-2:456
+ABC.X-DUMMY-2:456
+ALPHA.ABC.LOGO;ENCODING=BASE64;TYPE=GIF:
+ R0lGODdhfgA4AOYAAAAAAK+vr62trVIxa6WlpZ+fnzEpCEpzlAha/0Kc74+PjyGM
+ SuecKRhrtX9/fzExORBSjCEYCGtra2NjYyF7nDGE50JrhAg51qWtOTl7vee1MWu1
+ 50o5e3PO/3sxcwAx/4R7GBgQOcDAwFoAQt61hJyMGHuUSpRKIf8A/wAY54yMjHt=
+DEF.X-DUMMY-3:789
+X-DUMMY-3:789
+ABC.X-DUMMY-3:789
+ALPHA.DEF.LOGO;ENCODING=BASE64;TYPE=GIF:
+ R0lGODdhfgA4AOYAAAAAAK+vr62trVIxa6WlpZ+fnzEpCEpzlAha/0Kc74+PjyGM
+ SuecKRhrtX9/fzExORBSjCEYCGtra2NjYyF7nDGE50JrhAg51qWtOTl7vee1MWu1
+ 50o5e3PO/3sxcwAx/4R7GBgQOcDAwFoAQt61hJyMGHuUSpRKIf8A/wAY54yMjHt=
+BEGIN:VCARD
+PPP.X-DUMMY-1:123
+PPP.DEF.X-DUMMY-1:123
+PPP.ALPHA.LOGO;ENCODING=BASE64;TYPE=GIF:
+ R0lGODdhfgA4AOYAAAAAAK+vr62trVIxa6WlpZ+fnzEpCEpzlAha/0Kc74+PjyGM
+ SuecKRhrtX9/fzExORBSjCEYCGtra2NjYyF7nDGE50JrhAg51qWtOTl7vee1MWu1
+ 50o5e3PO/3sxcwAx/4R7GBgQOcDAwFoAQt61hJyMGHuUSpRKIf8A/wAY54yMjHt=
+PPP.ABC.X-DUMMY-1:123
+PPP.DEF.X-DUMMY-2:456
+PPP.X-DUMMY-2:456
+PPP.ABC.X-DUMMY-2:456
+PPP.ALPHA.ABC.LOGO;ENCODING=BASE64;TYPE=GIF:
+ R0lGODdhfgA4AOYAAAAAAK+vr62trVIxa6WlpZ+fnzEpCEpzlAha/0Kc74+PjyGM
+ SuecKRhrtX9/fzExORBSjCEYCGtra2NjYyF7nDGE50JrhAg51qWtOTl7vee1MWu1
+ 50o5e3PO/3sxcwAx/4R7GBgQOcDAwFoAQt61hJyMGHuUSpRKIf8A/wAY54yMjHt=
+PPP.DEF.X-DUMMY-3:789
+PPP.X-DUMMY-3:789
+PPP.ABC.X-DUMMY-3:789
+PPP.ALPHA.DEF.LOGO;ENCODING=BASE64;TYPE=GIF:
+ R0lGODdhfgA4AOYAAAAAAK+vr62trVIxa6WlpZ+fnzEpCEpzlAha/0Kc74+PjyGM
+ SuecKRhrtX9/fzExORBSjCEYCGtra2NjYyF7nDGE50JrhAg51qWtOTl7vee1MWu1
+ 50o5e3PO/3sxcwAx/4R7GBgQOcDAwFoAQt61hJyMGHuUSpRKIf8A/wAY54yMjHt=
+END:VCARD
+END:VCARD
diff --git a/test/tests/adhoc/mail_list_1.vcf b/test/tests/adhoc/mail_list_1.vcf
new file mode 100644
index 0000000..b211638
--- /dev/null
+++ b/test/tests/adhoc/mail_list_1.vcf
@@ -0,0 +1,4 @@
+BEGIN:VCARD
+TEL;CAR:
+TEL;HOME;VOICE:123
+END:VCARD
diff --git a/test/tests/adhoc/mail_list_2.vcf b/test/tests/adhoc/mail_list_2.vcf
new file mode 100644
index 0000000..eacbd72
--- /dev/null
+++ b/test/tests/adhoc/mail_list_2.vcf
@@ -0,0 +1,4 @@
+BEGIN:VCARD
+ADR;WORK;ENCODING=QUOTED-PRINTABLE:;;HSBC Building=0A=0D=
+30 Metcalfe Street, 3rd Floor;Ottawa;ON;K1P 5L4;Canada
+END:VCARD
diff --git a/test/tests/adhoc/mail_list_3.vcf b/test/tests/adhoc/mail_list_3.vcf
new file mode 100644
index 0000000..5012c8b
--- /dev/null
+++ b/test/tests/adhoc/mail_list_3.vcf
@@ -0,0 +1,3 @@
+BEGIN:VCARD
+N;ENCODING=QUOTED-PRINTABLE;CHARSET=ISO-8859-1:Familyame=E4;Surname
+END:VCARD
diff --git a/test/tests/adhoc/mail_list_4.vcf b/test/tests/adhoc/mail_list_4.vcf
new file mode 100644
index 0000000..dea6393
--- /dev/null
+++ b/test/tests/adhoc/mail_list_4.vcf
@@ -0,0 +1,13 @@
+BEGIN:VCARD
+VERSION:2.1
+BEGIN:VCARD
+UID:1
+N:Jerry Ramond
+TEL:1-221-222-1123
+END:VCARD
+BEGIN:VCARD
+UID:2
+N:Lacy Ramond
+TEL:1-212-222-1223
+END:VCARD
+END:VCARD
diff --git a/test/tests/adhoc/mail_list_5.vcf b/test/tests/adhoc/mail_list_5.vcf
new file mode 100644
index 0000000..19ed460
--- /dev/null
+++ b/test/tests/adhoc/mail_list_5.vcf
@@ -0,0 +1,19 @@
+BEGIN:VCARD
+VERSION:2.1
+X-DL;Design Work Group:List Item 1;List Item 2;List Item 3
+BEGIN:VCARD
+UID:List Item 1
+N:John Smith
+TEL:+1-213-555-1111
+END:VCARD
+BEGIN:VCARD
+UID:List Item 2
+N:I. M. Big
+TEL:+1-213-555-9999
+END:VCARD
+BEGIN:VCARD
+UID:List Item 3
+N:Jane Doe
+TEL:+1-213-555-5555
+END:VCARD
+END:VCARD
diff --git a/test/tests/adhoc/mail_list_6.vcf b/test/tests/adhoc/mail_list_6.vcf
new file mode 100644
index 0000000..987350d
--- /dev/null
+++ b/test/tests/adhoc/mail_list_6.vcf
@@ -0,0 +1,4 @@
+BEGIN:VCARD
+N;ENCODING=QUOTED-PRINTABLE:Last;First;Middle
+N:Last;First;Middle
+END:VCARD
diff --git a/test/tests/adhoc/multiple_objs_1.vcf b/test/tests/adhoc/multiple_objs_1.vcf
new file mode 100644
index 0000000..f6d69ef
--- /dev/null
+++ b/test/tests/adhoc/multiple_objs_1.vcf
@@ -0,0 +1,21 @@
+BEGIN:VCARD
+STUF;QUOTED-PRINTABLE:Come And Get It!
+END:VCARD
+
+BEGIN:VCARD
+MORE-STUF;QUOTED-PRINTABLE:Come And Get It!
+END:VCARD
+
+BEGIN:VCARD
+YET-MORE-STUF;QUOTED-PRINTABLE:Come And Get It!
+END:VCARD
+
+BEGIN:VCARD
+AND-YET-SOME-MORE-STUF;QUOTED-PRINTABLE:Come And Get It!
+
+BEGIN:VCARD
+YET-MORE-STUF;QUOTED-PRINTABLE:Come And Get It!
+END:VCARD
+
+END:VCARD
+
diff --git a/test/tests/adhoc/straight_1.vcf b/test/tests/adhoc/straight_1.vcf
new file mode 100644
index 0000000..d4413f3
--- /dev/null
+++ b/test/tests/adhoc/straight_1.vcf
@@ -0,0 +1,2 @@
+BEGIN:VCARD
+END:VCARD
diff --git a/test/tests/adhoc/straight_2.vcf b/test/tests/adhoc/straight_2.vcf
new file mode 100644
index 0000000..50ac599
--- /dev/null
+++ b/test/tests/adhoc/straight_2.vcf
@@ -0,0 +1,3 @@
+BEGIN:VCARD
+N:aaaa
+END:VCARD
diff --git a/test/tests/adhoc/straight_3.vcf b/test/tests/adhoc/straight_3.vcf
new file mode 100644
index 0000000..bed344f
--- /dev/null
+++ b/test/tests/adhoc/straight_3.vcf
@@ -0,0 +1,3 @@
+BEGIN:VCARD
+N:aaaa;bbbb
+END:VCARD
diff --git a/test/tests/adhoc/straight_4.vcf b/test/tests/adhoc/straight_4.vcf
new file mode 100644
index 0000000..ce8b613
--- /dev/null
+++ b/test/tests/adhoc/straight_4.vcf
@@ -0,0 +1,3 @@
+BEGIN:VCARD
+N:aaaa;bbbb;cccc
+END:VCARD
diff --git a/test/tests/adhoc/straight_5.vcf b/test/tests/adhoc/straight_5.vcf
new file mode 100644
index 0000000..b45a355
--- /dev/null
+++ b/test/tests/adhoc/straight_5.vcf
@@ -0,0 +1,3 @@
+BEGIN:VCARD
+N:;bbbb;cccc
+END:VCARD
diff --git a/test/tests/adhoc/straight_6.vcf b/test/tests/adhoc/straight_6.vcf
new file mode 100644
index 0000000..84438f3
--- /dev/null
+++ b/test/tests/adhoc/straight_6.vcf
@@ -0,0 +1,3 @@
+BEGIN:VCARD
+N:;;cccc
+END:VCARD
diff --git a/test/tests/adhoc/straight_7.vcf b/test/tests/adhoc/straight_7.vcf
new file mode 100644
index 0000000..2907949
--- /dev/null
+++ b/test/tests/adhoc/straight_7.vcf
@@ -0,0 +1,3 @@
+BEGIN:VCARD
+N:;bbbb;
+END:VCARD
diff --git a/test/tests/adhoc/straight_8.vcf b/test/tests/adhoc/straight_8.vcf
new file mode 100644
index 0000000..165f956
--- /dev/null
+++ b/test/tests/adhoc/straight_8.vcf
@@ -0,0 +1,4 @@
+BEGIN:VCARD
+FN:12. 345678 987654321
+N:;bbbb;
+END:VCARD
diff --git a/test/tests/adhoc/straight_9.vcf b/test/tests/adhoc/straight_9.vcf
new file mode 100644
index 0000000..d16729d
--- /dev/null
+++ b/test/tests/adhoc/straight_9.vcf
@@ -0,0 +1,4 @@
+BEGIN:VCARD
+N:;bbbb;
+FN:12. 345678 987654321
+END:VCARD
diff --git a/test/tests/adhoc/straight_A.vcf b/test/tests/adhoc/straight_A.vcf
new file mode 100644
index 0000000..2f6a4f5
--- /dev/null
+++ b/test/tests/adhoc/straight_A.vcf
@@ -0,0 +1,7 @@
+BEGIN:VCARD
+X-DUMMY-1:123
+X-DUMMY-2:456
+X-DUMMY-3:789
+N:;bbbb;
+FN:12. 345678 987654321
+END:VCARD
diff --git a/test/tests/adhoc/straight_B.vcf b/test/tests/adhoc/straight_B.vcf
new file mode 100644
index 0000000..49f79a3
--- /dev/null
+++ b/test/tests/adhoc/straight_B.vcf
@@ -0,0 +1,4 @@
+BEGIN:VCARD
+N;qqq:;bbbb;
+FN:12. 345678 987654321
+END:VCARD
diff --git a/test/tests/adhoc/straight_C.vcf b/test/tests/adhoc/straight_C.vcf
new file mode 100644
index 0000000..51ae8ff
--- /dev/null
+++ b/test/tests/adhoc/straight_C.vcf
@@ -0,0 +1,4 @@
+BEGIN:VCARD
+N;qqq;rrr;sss:;bbbb;
+FN:12. 345678 987654321
+END:VCARD
diff --git a/test/tests/adhoc/straight_D.vcf b/test/tests/adhoc/straight_D.vcf
new file mode 100644
index 0000000..ae90513
--- /dev/null
+++ b/test/tests/adhoc/straight_D.vcf
@@ -0,0 +1,4 @@
+BEGIN:VCARD
+N;qqq;rrr;sss:aaa;bbbb;ccc
+FN:12. 345678 987654321
+END:VCARD
diff --git a/test/tests/adhoc/straight_E.vcf b/test/tests/adhoc/straight_E.vcf
new file mode 100644
index 0000000..71e53c9
--- /dev/null
+++ b/test/tests/adhoc/straight_E.vcf
@@ -0,0 +1,4 @@
+BEGIN:VCARD
+FN:12. 345678 987654321
+N;qqq;rrr;sss:;;ccc
+END:VCARD
diff --git a/test/tests/adhoc/straight_F.vcf b/test/tests/adhoc/straight_F.vcf
new file mode 100644
index 0000000..530ff82
--- /dev/null
+++ b/test/tests/adhoc/straight_F.vcf
@@ -0,0 +1,5 @@
+BEGIN:VCARD
+FN:12. 345678 987654321
+X;Y;Z:123123123
+N;qqq;rrr;sss:;;ccc
+END:VCARD
diff --git a/test/tests/adhoc/straight_G.vcf b/test/tests/adhoc/straight_G.vcf
new file mode 100644
index 0000000..1cc3d18
--- /dev/null
+++ b/test/tests/adhoc/straight_G.vcf
@@ -0,0 +1,8 @@
+BEGIN:VCARD
+A:
+B:
+C;D:
+E:;
+F;G:;
+H;I;J:;K;L;M
+END:VCARD
diff --git a/test/tests/adhoc/straight_H.vcf b/test/tests/adhoc/straight_H.vcf
new file mode 100644
index 0000000..d507d3f
--- /dev/null
+++ b/test/tests/adhoc/straight_H.vcf
@@ -0,0 +1,11 @@
+BEGIN:VCARD
+A:
+B:
+C;D:
+E:;
+F;G:;
+H;I;J:;K;L;M
+N;;:
+O;;;:;;P
+Q;;;:;;R;;;S
+END:VCARD
diff --git a/test/tests/adhoc/straight_I.vcf b/test/tests/adhoc/straight_I.vcf
new file mode 100644
index 0000000..298e613
--- /dev/null
+++ b/test/tests/adhoc/straight_I.vcf
@@ -0,0 +1,12 @@
+BEGIN:VCARD
+A;QUOTED-PRINTABLE:
+B;QUOTED-PRINTABLE:
+C;QUOTED-PRINTABLE;D:
+E;;;QUOTED-PRINTABLE:;
+F;;;;;QUOTED-PRINTABLE;;;G:;
+H;I;J;QUOTED-PRINTABLE:;K;L;M
+N;QUOTED-PRINTABLE;;:
+O;QUOTED-PRINTABLE;;;:;;P
+Q;QUOTED-PRINTABLE;;;:;;R;;;S
+T;QUOTED-PRINTABLE:;;UUU;VVV=12=12=12
+END:VCARD
diff --git a/test/tests/adhoc/straight_qp_1.vcf b/test/tests/adhoc/straight_qp_1.vcf
new file mode 100644
index 0000000..04fac0a
--- /dev/null
+++ b/test/tests/adhoc/straight_qp_1.vcf
@@ -0,0 +1,3 @@
+BEGIN:VCARD
+ORG;QUOTED-PRINTABLE:ah-ah-ah-ah-ah-ah-ah-ah
+END:VCARD
diff --git a/test/tests/adhoc/straight_qp_2.vcf b/test/tests/adhoc/straight_qp_2.vcf
new file mode 100644
index 0000000..dcdbe3c
--- /dev/null
+++ b/test/tests/adhoc/straight_qp_2.vcf
@@ -0,0 +1,3 @@
+BEGIN:VCARD
+ORG;QUOTED-PRINTABLE:ah-ah-ah-ah-ah-ah-ah-ah-=41=48
+END:VCARD
diff --git a/test/tests/adhoc/straight_qp_3.vcf b/test/tests/adhoc/straight_qp_3.vcf
new file mode 100644
index 0000000..4b858ff
--- /dev/null
+++ b/test/tests/adhoc/straight_qp_3.vcf
@@ -0,0 +1,5 @@
+BEGIN:VCARD
+ORG;QUOTED-PRINTABLE:ah-ah-ah-ah-ah-ah-ah-ah-=41=48=
+-ah-ah-ah-ah-ah-ah-ah-ah-=41=48=0D=0A=
+-ah-ah-ah-ah-ah-ah-ah-ah-=41=48
+END:VCARD
diff --git a/test/tests/adhoc/straight_qp_4.vcf b/test/tests/adhoc/straight_qp_4.vcf
new file mode 100644
index 0000000..4b858ff
--- /dev/null
+++ b/test/tests/adhoc/straight_qp_4.vcf
@@ -0,0 +1,5 @@
+BEGIN:VCARD
+ORG;QUOTED-PRINTABLE:ah-ah-ah-ah-ah-ah-ah-ah-=41=48=
+-ah-ah-ah-ah-ah-ah-ah-ah-=41=48=0D=0A=
+-ah-ah-ah-ah-ah-ah-ah-ah-=41=48
+END:VCARD
diff --git a/test/tests/adhoc/vcal_1.vcs b/test/tests/adhoc/vcal_1.vcs
new file mode 100644
index 0000000..aba139a
--- /dev/null
+++ b/test/tests/adhoc/vcal_1.vcs
@@ -0,0 +1,20 @@
+BEGIN:VCALENDAR
+VERSION:1.0
+
+BEGIN:VEVENT
+CATEGORIES:MEETING
+STATUS:NEEDS ACTION
+DTSTART:19960401T073000Z
+DTEND:19960401T083000Z
+SUMMARY:Steve's Proposal Review
+DESCRIPTION:Steve and John to review newest proposal material
+CLASS:PRIVATE
+END:VEVENT
+
+BEGIN:VTODO
+SUMMARY:John to pay for lunch
+DUE:19960401T083000Z
+STATUS:NEEDS ACTION
+END:VTODO
+
+END:VCALENDAR
diff --git a/test/tests/spec/2_1_1-begin-1.vcf b/test/tests/spec/2_1_1-begin-1.vcf
new file mode 100644
index 0000000..36123a5
--- /dev/null
+++ b/test/tests/spec/2_1_1-begin-1.vcf
@@ -0,0 +1,3 @@
+BEGIN:VCARD
+X-HERE-IT-IS:fred
+END:VCARD
diff --git a/test/tests/spec/2_1_1-begin-2.vcf b/test/tests/spec/2_1_1-begin-2.vcf
new file mode 100644
index 0000000..497bd3d
--- /dev/null
+++ b/test/tests/spec/2_1_1-begin-2.vcf
@@ -0,0 +1,23 @@
+yv vuyg duvy gvuysdfgvdvgosdf gvouyvg uyv ouvgsd ovuydgs vudov dvuyg
+vdovd vuhdpvduh vpdhv pdiv
+sd vdosv dsvuh dvuh vdvpdu ivhd
+sdvoidusvodsvdvdovd
+
+BEGIN:VCARD
+X-HERE-IT-IS:fred
+END:VCARD
+
+vdvdpfkvo
+vkof
+dfk
+dfkvfd
+vokdf
+vdfkvdf
+ovkdf
+vokdf
+vodk
+ko
+
+BEGIN:VCARD
+X-HERE-IT-IS:bloggs
+END:VCARD
diff --git a/test/tests/spec/2_1_2-property.vcf b/test/tests/spec/2_1_2-property.vcf
new file mode 100644
index 0000000..934b2b9
--- /dev/null
+++ b/test/tests/spec/2_1_2-property.vcf
@@ -0,0 +1,7 @@
+BEGIN:VCARD
+TEL;HOME:+1-919-555-1234
+NOTE;ENCODING=QUOTED-PRINTABLE:Don't remember to order Girl=
+ Scout cookies from Stacey today!
+NOTE;QUOTED-PRINTABLE:Don't remember to order Girl=
+ Scout cookies from Stacey today!
+END:VCARD
diff --git a/test/tests/spec/2_1_3-delimiters.vcf b/test/tests/spec/2_1_3-delimiters.vcf
new file mode 100644
index 0000000..cacec9e
--- /dev/null
+++ b/test/tests/spec/2_1_3-delimiters.vcf
@@ -0,0 +1,7 @@
+BEGIN:VCARD
+NOTE_1:This is a very long description that exists on a long line.
+NOTE_2:This is a very long description
+ that exists on a long line.
+NOTE_2:This is a very long description
+ that exists on a long line.
+END:VCARD
diff --git a/test/tests/spec/2_1_4_1-grouping-nested.vcf b/test/tests/spec/2_1_4_1-grouping-nested.vcf
new file mode 100644
index 0000000..15d0aae
--- /dev/null
+++ b/test/tests/spec/2_1_4_1-grouping-nested.vcf
@@ -0,0 +1,9 @@
+BEGIN:VCARD
+N:abc;def;ghi
+BEGIN:VCARD
+N:jkl;mno;pqr
+BEGIN:VCARD
+N:stu;vwx;yz
+END:VCARD
+END:VCARD
+END:VCARD
diff --git a/test/tests/spec/2_1_4_1-grouping-sequential.vcf b/test/tests/spec/2_1_4_1-grouping-sequential.vcf
new file mode 100644
index 0000000..72bfb23
--- /dev/null
+++ b/test/tests/spec/2_1_4_1-grouping-sequential.vcf
@@ -0,0 +1,9 @@
+BEGIN:VCARD
+N:abc;def;ghi
+END:VCARD
+BEGIN:VCARD
+N:jkl;mno;pqr
+END:VCARD
+BEGIN:VCARD
+N:stu;vwx;yz
+END:VCARD
diff --git a/test/tests/spec/2_1_4_2-property-grouping.vcf b/test/tests/spec/2_1_4_2-property-grouping.vcf
new file mode 100644
index 0000000..7abd856
--- /dev/null
+++ b/test/tests/spec/2_1_4_2-property-grouping.vcf
@@ -0,0 +1,4 @@
+BEGIN:VCARD
+A.TEL;HOME:+1-213-555-1234
+A.NOTE:This is my vacation home.
+END:VCARD
diff --git a/test/tests/spec/2_1_6-charset.vcf b/test/tests/spec/2_1_6-charset.vcf
new file mode 100644
index 0000000..4be0ecf
--- /dev/null
+++ b/test/tests/spec/2_1_6-charset.vcf
@@ -0,0 +1,3 @@
+BEGIN:VCARD
+ADR;CHARSET=ISO-8859-8:...
+END:VCARD
diff --git a/test/tests/spec/2_1_7-language.vcf b/test/tests/spec/2_1_7-language.vcf
new file mode 100644
index 0000000..d561fb2
--- /dev/null
+++ b/test/tests/spec/2_1_7-language.vcf
@@ -0,0 +1,3 @@
+BEGIN:VCARD
+ADR;LANGUAGE=fr-CA:...
+END:VCARD
diff --git a/test/tests/spec/2_1_8-valuelocation.vcf b/test/tests/spec/2_1_8-valuelocation.vcf
new file mode 100644
index 0000000..1ca41b6
--- /dev/null
+++ b/test/tests/spec/2_1_8-valuelocation.vcf
@@ -0,0 +1,4 @@
+BEGIN:VCARD
+PHOTO;VALUE=URL;TYPE=GIF:http://www.abc.com/dir_photos/my_photo.gif
+SOUND;VALUE=CONTENT-ID:<jsmith.part3.960817T083000.xyzMail@host1.com>
+END:VCARD
diff --git a/test/tests/spec/2_2_1-fn.vcf b/test/tests/spec/2_2_1-fn.vcf
new file mode 100644
index 0000000..fa6df57
--- /dev/null
+++ b/test/tests/spec/2_2_1-fn.vcf
@@ -0,0 +1,3 @@
+BEGIN:VCARD
+FN:Mr. John Q. Public, Esq.
+END:VCARD
diff --git a/test/tests/spec/2_2_2-name.vcf b/test/tests/spec/2_2_2-name.vcf
new file mode 100644
index 0000000..deb7774
--- /dev/null
+++ b/test/tests/spec/2_2_2-name.vcf
@@ -0,0 +1,4 @@
+BEGIN:VCARD
+N:Public;John;Quinlan;Mr.;Esq.
+N:Veni, Vidi, Vici;The Restaurant.
+END:VCARD
diff --git a/test/tests/spec/2_2_3-photo.vcf b/test/tests/spec/2_2_3-photo.vcf
new file mode 100644
index 0000000..cb77196
--- /dev/null
+++ b/test/tests/spec/2_2_3-photo.vcf
@@ -0,0 +1,7 @@
+BEGIN:VCARD
+PHOTO;VALUE=URL:file:///jqpublic.gif
+PHOTO;ENCODING=BASE64;TYPE=GIF:
+ R0lGODdhfgA4AOYAAAAAAK+vr62trVIxa6WlpZ+fnzEpCEpzlAha/0Kc74+PjyGM
+ SuecKRhrtX9/fzExORBSjCEYCGtra2NjYyF7nDGE50JrhAg51qWtOTl7vee1MWu1
+ 50o5e3PO/3sxcwAx/4R7GBgQOcDAwFoAQt61hJyMGHuUSpRKIf8A/wAY54yMjHtz
+END:VCARD
diff --git a/test/tests/spec/2_2_4-birthdate.vcf b/test/tests/spec/2_2_4-birthdate.vcf
new file mode 100644
index 0000000..996a303
--- /dev/null
+++ b/test/tests/spec/2_2_4-birthdate.vcf
@@ -0,0 +1,4 @@
+BEGIN:VCARD
+BDAY:19950415
+BDAY:1995-04-15
+END:VCARD
diff --git a/test/tests/spec/2_3_1-address.vcf b/test/tests/spec/2_3_1-address.vcf
new file mode 100644
index 0000000..c7fb5f0
--- /dev/null
+++ b/test/tests/spec/2_3_1-address.vcf
@@ -0,0 +1,3 @@
+BEGIN:VCARD
+ADR;DOM;WORK;HOME;POSTAL:P.O. Box 101;;;Any Town;CA;91921-1234;
+END:VCARD
diff --git a/test/tests/spec/2_3_2-label.vcf b/test/tests/spec/2_3_2-label.vcf
new file mode 100644
index 0000000..0c5330d
--- /dev/null
+++ b/test/tests/spec/2_3_2-label.vcf
@@ -0,0 +1,12 @@
+BEGIN:VCARD
+LABEL;DOM;POSTAL;ENCODING=QUOTED-PRINTABLE:P. O. Box 456=0D=0A=
+123 Main Street=0D=0A=
+Any Town, CA 91921-1234
+LABEL;INTL;PARCEL,ENCODING=QUOTED-PRINTABLE:Suite 101=0D=0A=
+123 Main Street=0D=0A=
+Any Town, CA 91921-1234=0D=0A=
+U.S.A.
+LABEL;DOM;HOME,ENCODING=QUOTED-PRINTABLE:Suite 101=0D=0A=
+123 Main Street=0D=0A=
+Any Town, CA 91921-1234
+END:VCARD
diff --git a/test/tests/spec/2_4_1-tel.vcf b/test/tests/spec/2_4_1-tel.vcf
new file mode 100644
index 0000000..ef68044
--- /dev/null
+++ b/test/tests/spec/2_4_1-tel.vcf
@@ -0,0 +1,3 @@
+BEGIN:VCARD
+TEL;WORK;HOME;VOICE;FAX:+1-800-555-1234
+END:VCARD
diff --git a/test/tests/spec/2_4_2-email.vcf b/test/tests/spec/2_4_2-email.vcf
new file mode 100644
index 0000000..020e419
--- /dev/null
+++ b/test/tests/spec/2_4_2-email.vcf
@@ -0,0 +1,16 @@
+BEGIN:VCARD
+EMAIL;INTERNET:john.public@abc.com
+EMAIL;TYPE=INTERNET:john.public@abc.com
+EMAIL;TYPE=AppleLink:john.public@abc.com
+EMAIL;TYPE=ATTMail:john.public@abc.com
+EMAIL;TYPE=CIS:john.public@abc.com
+EMAIL;TYPE=eWorld:john.public@abc.com
+EMAIL;TYPE=INTERNET:john.public@abc.com
+EMAIL;TYPE=IBMMail:john.public@abc.com
+EMAIL;TYPE=MCIMail:john.public@abc.com
+EMAIL;TYPE=POWERSHARE:john.public@abc.com
+EMAIL;TYPE=PRODIGY:john.public@abc.com
+EMAIL;TYPE=TLX:john.public@abc.com
+EMAIL;TYPE=X400:john.public@abc.com
+END:VCARD
+
diff --git a/test/tests/spec/2_4_3-mailer.vcf b/test/tests/spec/2_4_3-mailer.vcf
new file mode 100644
index 0000000..bdec58f
--- /dev/null
+++ b/test/tests/spec/2_4_3-mailer.vcf
@@ -0,0 +1,3 @@
+BEGIN:VCARD
+MAILER:ccMail 2.2
+END:VCARD
diff --git a/test/tests/spec/2_4_5-tz.vcf b/test/tests/spec/2_4_5-tz.vcf
new file mode 100644
index 0000000..6ceb500
--- /dev/null
+++ b/test/tests/spec/2_4_5-tz.vcf
@@ -0,0 +1,4 @@
+BEGIN:VCARD
+TZ:-0500
+TZ:-08:00
+END:VCARD
diff --git a/test/tests/spec/2_4_6-geo.vcf b/test/tests/spec/2_4_6-geo.vcf
new file mode 100644
index 0000000..8fdcde9
--- /dev/null
+++ b/test/tests/spec/2_4_6-geo.vcf
@@ -0,0 +1,3 @@
+BEGIN:VCARD
+GEO:37.24,-17.87
+END:VCARD
diff --git a/test/tests/spec/2_5_1-title.vcf b/test/tests/spec/2_5_1-title.vcf
new file mode 100644
index 0000000..12a6d70
--- /dev/null
+++ b/test/tests/spec/2_5_1-title.vcf
@@ -0,0 +1,3 @@
+BEGIN:VCARD
+TITLE:V.P., Research and Development
+END:VCARD
diff --git a/test/tests/spec/2_5_2-role.vcf b/test/tests/spec/2_5_2-role.vcf
new file mode 100644
index 0000000..9aeb431
--- /dev/null
+++ b/test/tests/spec/2_5_2-role.vcf
@@ -0,0 +1,3 @@
+BEGIN:VCARD
+ROLE:Executive
+END:VCARD
diff --git a/test/tests/spec/2_5_3-logo.vcf b/test/tests/spec/2_5_3-logo.vcf
new file mode 100644
index 0000000..d740429
--- /dev/null
+++ b/test/tests/spec/2_5_3-logo.vcf
@@ -0,0 +1,6 @@
+BEGIN:VCARD
+LOGO;ENCODING=BASE64;TYPE=GIF:
+ R0lGODdhfgA4AOYAAAAAAK+vr62trVIxa6WlpZ+fnzEpCEpzlAha/0Kc74+PjyGM
+ SuecKRhrtX9/fzExORBSjCEYCGtra2NjYyF7nDGE50JrhAg51qWtOTl7vee1MWu1
+ 50o5e3PO/3sxcwAx/4R7GBgQOcDAwFoAQt61hJyMGHuUSpRKIf8A/wAY54yMjHtz
+END:VCARD
diff --git a/test/tests/spec/2_5_4-agent.vcf b/test/tests/spec/2_5_4-agent.vcf
new file mode 100644
index 0000000..af79284
--- /dev/null
+++ b/test/tests/spec/2_5_4-agent.vcf
@@ -0,0 +1,9 @@
+BEGIN:VCARD
+AGENT:
+BEGIN:VCARD
+VERSION:2.1
+N:Friday;Fred
+TEL;WORK;VOICE:+1-213-555-1234
+TEL;WORK;FAX:+1-213-555-5678
+END:VCARD
+END:VCARD
diff --git a/test/tests/spec/2_5_5-org.vcf b/test/tests/spec/2_5_5-org.vcf
new file mode 100644
index 0000000..49ed921
--- /dev/null
+++ b/test/tests/spec/2_5_5-org.vcf
@@ -0,0 +1,3 @@
+BEGIN:VCARD
+ORG:ABC, Inc.;North American Division;Marketing
+END:VCARD
diff --git a/test/tests/spec/2_6_1-comment.vcf b/test/tests/spec/2_6_1-comment.vcf
new file mode 100644
index 0000000..0573597
--- /dev/null
+++ b/test/tests/spec/2_6_1-comment.vcf
@@ -0,0 +1,6 @@
+BEGIN:VCARD
+NOTE;ENCODING=QUOTED-PRINTABLE:This facsimile machine if operational=
+ 0830 to 1715 hours=0D=0A=
+Monday through Friday. Call +1-213-555-1234 if you have problems=0D=0A=
+with access to the machine.
+END:VCARD
diff --git a/test/tests/spec/2_6_2-revision.vcf b/test/tests/spec/2_6_2-revision.vcf
new file mode 100644
index 0000000..f61aff7
--- /dev/null
+++ b/test/tests/spec/2_6_2-revision.vcf
@@ -0,0 +1,4 @@
+BEGIN:VCARD
+REV:19951031T222710
+REV:1995-10-31T22:27:10Z
+END:VCARD
diff --git a/test/tests/spec/2_6_3-sound.vcf b/test/tests/spec/2_6_3-sound.vcf
new file mode 100644
index 0000000..fd4cffe
--- /dev/null
+++ b/test/tests/spec/2_6_3-sound.vcf
@@ -0,0 +1,8 @@
+BEGIN:VCARD
+SOUND:JON Q PUBLIK
+SOUND;VALUE=URL:file///multimed/audio/jqpublic.wav
+SOUND;WAVE;BASE64:
+ UklGRhAsAABXQVZFZm10IBAAAAABAAEAESsAABErAAABAAgAZGF0YesrAACAg4eC
+ eXR4e3uAhoiIiYmKjIiDfnx5eX6CgoKEhYWDenV5fH6BhISGiIiDfHZ2eXt/hIiK
+ jY2IhH12d3Vyc3uDiIiFf3l7fn18eXl+houFf319fnyAgHl5eoCIiISChIeAfnt2
+END:VCARD
diff --git a/test/tests/spec/2_6_4-url.vcf b/test/tests/spec/2_6_4-url.vcf
new file mode 100644
index 0000000..6b0e080
--- /dev/null
+++ b/test/tests/spec/2_6_4-url.vcf
@@ -0,0 +1,3 @@
+BEGIN:VCARD
+URL:http://abc.com/pub/directory/northam/jpublic.ecd
+END:VCARD
diff --git a/test/tests/spec/2_6_5-uid.vcf b/test/tests/spec/2_6_5-uid.vcf
new file mode 100644
index 0000000..ae32da3
--- /dev/null
+++ b/test/tests/spec/2_6_5-uid.vcf
@@ -0,0 +1,3 @@
+BEGIN:VCARD
+UID:19950401-080045-40000F192713-0052
+END:VCARD
diff --git a/test/tests/utf-8/S15cx8.vcf b/test/tests/utf-8/S15cx8.vcf
new file mode 100644
index 0000000..b4b796f
--- /dev/null
+++ b/test/tests/utf-8/S15cx8.vcf
@@ -0,0 +1,352 @@
+BEGIN:VCARD
+LOGO;GIF;BASE64;INLINE:
+ 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
+ LNOjPNE8LbMpPT0c3dOyHNTpKNRGHccJAAA7
+
+SOUND;URL:http://www.sounds.com
+LABEL;DOM;QUOTED-PRINTABLE:=C3=91=C3=AC=C2=A2=C3=91=C3=AC=C2=A2=C3=91=C3=AC=
+=C2=A2
+SOUND:
+VERSION:2.1
+X-ESI-CATEGORIES:Keine Gruppe
+NAME;CHARSET=UTF-8;ENCODING=QUOTED-PRINTABLE:Anon;H=C3=A4p
+ADR;CHARSET=UTF-8:;;£;¥;;;
+ORG;CHARSET=UTF-8:Näbert€€;
+X-VFORMAT-POSNS:ORG@0x0;LABEL@0x-503;FN@14200x-503;LOGO@250x-6853
+FN:
+N:;;
+TITLE:
+LABEL;QUOTED-PRINTABLE:=C3=91=C3=AC=C2=A2=C3=91=C3=AC=C2=A2=C3=91=C3=AC=C2=
+=A2
+END:VCARD
diff --git a/test/tests/utf-8/S15cxu.vcf b/test/tests/utf-8/S15cxu.vcf
new file mode 100644
index 0000000..a80c39e
--- /dev/null
+++ b/test/tests/utf-8/S15cxu.vcf
@@ -0,0 +1,6 @@
+BEGIN:VCARD
+VERSION:2.1
+X-ESI-CATEGORIES:Keine Gruppe
+N;CHARSET=UTF-8;ENCODING=QUOTED-PRINTABLE:B=C3=BCro
+TEL;HOME:+12345678
+END:VCARD
diff --git a/test/testsuppt.c b/test/testsuppt.c
new file mode 100644
index 0000000..1a678d5
--- /dev/null
+++ b/test/testsuppt.c
@@ -0,0 +1,409 @@
+/******************************************************************************
+
+ (C) Nick Marley, 2001 -
+
+ This software is distributed under the GNU Lesser General Public Licence.
+ Please read and understand the comments at the top of vf_iface.h before use!
+
+FILE
+ $Workfile: vf_access.c $
+ $Revision: 1.7 $
+ $Author: tilda $
+
+ORIGINAL AUTHOR
+ Nick Marley
+
+DESCRIPTION
+ See accompanying header file.
+
+REFERENCES
+ (none)
+
+MODIFICATION HISTORY
+ $Log: testsuppt.c,v $
+ Revision 1.7 2002/11/15 09:20:58 tilda
+ IID638823 - Don't include unistd.h unless required.
+
+ Revision 1.6 2002/11/15 09:14:59 tilda
+ IID638823 - Various portability issues.
+
+ Revision 1.5 2002/11/14 20:14:24 tilda
+ Minot tidy ups to WIN32 versions.
+
+ Revision 1.4 2002/11/11 17:23:07 monos
+ run testing harness on linux systems
+
+ Revision 1.3 2001/10/24 18:40:25 tilda
+ FindClose() not CloseHandle(). Nit.
+
+ Revision 1.2 2001/10/14 19:53:36 tilda
+ Group handling. NO group searching functions.
+
+ Revision 1.1 2001/10/12 19:02:15 tilda
+ Moved generic test functions to new file
+ *
+ *******************************************************************************/
+
+#ifndef NORCSID
+static const char vf_access_c_vss_id[] = "$Header: /cvsroot/vformat/build/vformat/testsuppt.c,v 1.7 2002/11/15 09:20:58 tilda Exp $";
+#endif
+
+/*============================================================================*
+ ANSI C & System-wide Header Files
+ *============================================================================*/
+
+#include <stdlib.h>
+#if defined(HAS_UNISTD_H)
+#include <unistd.h>
+#endif
+#include <stdio.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <string.h>
+
+#if defined(WIN) || defined(WIN32)
+#include <io.h>
+#endif
+
+/*============================================================================*
+ Interface Header Files
+ *============================================================================*/
+
+#include "vformat/vf_iface.h"
+
+/*============================================================================*
+ Local Header File
+ *============================================================================*/
+
+#include "testsuppt.h"
+
+/*============================================================================*
+ Private Defines
+ *============================================================================*/
+/* None */
+
+/*============================================================================*
+ Private Data Types
+ *============================================================================*/
+/* None */
+
+/*============================================================================*
+ Private Function Prototypes
+ *============================================================================*/
+/* None */
+
+/*============================================================================*
+ Private Data
+ *============================================================================*/
+
+static int ts_nextfile;
+
+/*============================================================================*
+ Public Function Implementations
+ *============================================================================*/
+
+
+
+/*----------------------------------------------------------------------------*
+ * NAME
+ * find_first_file()
+ *
+ * DESCRIPTION
+ * Locate (initialise search for) first file of indicated pattern in
+ * directory. See also find_next_file().
+ *
+ * RETURNS
+ * TRUE <=> first file found, FALSE else.
+ *----------------------------------------------------------------------------*/
+
+bool_t find_first_file(
+ char *p_name, /* Name of file found (output) */
+ file_enum_t *p_enum, /* Pointer to enumerator */
+ const char *p_dirname, /* Directory we're searching in */
+ const char *p_pattern /* Pattern we're searching for */
+ )
+{
+ bool_t ret = FALSE;
+ char pattern[_MAX_PATH];
+
+ sprintf(pattern, "%s//%s", p_dirname, p_pattern);
+
+ if (p_enum)
+ {
+ memset(p_enum, '\0', sizeof(*p_enum));
+
+#if defined(WIN) || defined(WIN32)
+
+ p_enum->h = INVALID_HANDLE_VALUE;
+
+ if (INVALID_HANDLE_VALUE == (p_enum->h = FindFirstFile(pattern, &p_enum->fd)))
+ {
+ /* No files */
+ }
+ else
+ {
+ p_enum->p_dirname = strdup(p_dirname);
+
+ if (p_enum->p_dirname)
+ {
+ sprintf(p_name, "%s//%s", p_enum->p_dirname, p_enum->fd.cFileName);
+
+ ret = TRUE;
+ }
+ else
+ {
+ close_file_find(p_enum);
+ }
+ }
+#else
+ if (0 == glob(pattern, GLOB_ERR, NULL, &p_enum->h))
+ {
+ /* Return first found pathname and increment counter */
+ sprintf(p_name, "%s", p_enum->h.gl_pathv[0]);
+ ts_nextfile = 1;
+
+ ret = TRUE;
+ }
+ else
+ {
+ /* Failed to open directory or to find files */
+ }
+#endif
+ }
+
+ return ret;
+}
+
+
+
+
+/*----------------------------------------------------------------------------*
+ * NAME
+ * find_next_file()
+ *
+ * DESCRIPTION
+ * Locate (initialise search for) first file of indicated pattern in
+ * directory. See also find_first_file().
+ *
+ * RETURNS
+ * TRUE <=> next file found, FALSE else.
+ *----------------------------------------------------------------------------*/
+
+bool_t find_next_file(
+ char *p_name, /* Name of file found (output) */
+ file_enum_t *p_enum /* Pointer to enumerator */
+ )
+{
+ bool_t ret = FALSE;
+
+ if (p_enum)
+ {
+#if defined(WIN) || defined(WIN32)
+ if (INVALID_HANDLE_VALUE == p_enum->h)
+ {
+ /* No files */
+ }
+ else
+ {
+ if (FindNextFile(p_enum->h, &p_enum->fd))
+ {
+ sprintf(p_name, "%s//%s", p_enum->p_dirname, p_enum->fd.cFileName);
+
+ ret = TRUE;
+ }
+ }
+#else
+ if (ts_nextfile < p_enum->h.gl_pathc)
+ {
+ sprintf(p_name, "%s", p_enum->h.gl_pathv[ts_nextfile++]);
+ ret = TRUE;
+ }
+#endif
+ }
+
+ return ret;
+}
+
+
+
+
+
+/*----------------------------------------------------------------------------*
+ * NAME
+ * close_file_find()
+ *
+ * DESCRIPTION
+ * Close the file search. Free memory, close handles etc. The enumerator
+ * is ready for another call to find_first_file().
+ *
+ * RETURNS
+ * (none)
+ *----------------------------------------------------------------------------*/
+
+void close_file_find(
+ file_enum_t *p_enum /* Pointer to enumerator */
+ )
+{
+ if (p_enum)
+ {
+#if defined(WIN) || defined(WIN32)
+ if (INVALID_HANDLE_VALUE == p_enum->h)
+ {
+ /* Not an open handle */
+ }
+ else
+ {
+ FindClose(p_enum->h);
+ p_enum->h = INVALID_HANDLE_VALUE;
+ }
+
+ if (p_enum->p_dirname)
+ {
+ free(p_enum->p_dirname);
+ p_enum->p_dirname = NULL;
+ }
+#else
+ globfree(&p_enum->h);
+#endif
+ }
+}
+
+
+
+/*----------------------------------------------------------------------------*
+ * NAME
+ * filecomp()
+ *
+ * DESCRIPTION
+ * Compare files.
+ *
+ * RETURNS
+ * 0 <=> fies are th same, != 0 else.
+ *----------------------------------------------------------------------------*/
+
+int filecomp(
+ const char *p_file1, /* Name of first file */
+ const char *p_file2 /* Name of second file */
+ )
+{
+ int ret = (-1);
+ file_image_t f1, f2;
+
+ if (get_file_image(&f1, p_file1))
+ {
+ if (get_file_image(&f2, p_file2))
+ {
+ if (f1.size == f2.size)
+ {
+ ret = memcmp(f1.p_data, f2.p_data, f1.size);
+ }
+ else
+ {
+ printf(" Sizes difference :\n %s (%lu bytes) Vs.\n %s (%lu bytes)\n",
+ p_file1, (unsigned long)f1.size, p_file2, (unsigned long)f2.size);
+ }
+
+ free_file_image(&f2);
+ }
+
+ free_file_image(&f1);
+ }
+
+ return ret;
+}
+
+
+
+
+
+
+/*----------------------------------------------------------------------------*
+ * NAME
+ * get_file_image()
+ *
+ * DESCRIPTION
+ * Load file into memory.
+ *
+ * RETURNS
+ * TRUE <=> file i/o successful, FALSE else.
+ *----------------------------------------------------------------------------*/
+
+bool_t get_file_image(
+ file_image_t *p, /* Info on file (output) */
+ const char *p_name /* Name of file */
+ )
+{
+ bool_t ret = FALSE;
+
+ if (p)
+ {
+ struct stat buf;
+
+ memset(p, '\0', sizeof(*p));
+
+ if (0 == stat(p_name, &buf))
+ {
+ p->size = buf.st_size;
+ p->p_data = malloc(p->size);
+
+ if (p->p_data)
+ {
+ FILE *fp;
+
+ fp = fopen(p_name, "rb");
+
+ if (fp)
+ {
+ if (p->size == (size_t)read(fileno(fp), p->p_data, p->size))
+ {
+ ret = TRUE;
+ }
+
+ fclose(fp);
+ }
+ }
+ }
+ }
+
+ return ret;
+}
+
+
+
+
+/*----------------------------------------------------------------------------*
+ * NAME
+ * free_file_image()
+ *
+ * DESCRIPTION
+ * Free up resources allocated to a file image.
+ *
+ * RETURNS
+ * (none)
+ *----------------------------------------------------------------------------*/
+
+void free_file_image(
+ file_image_t *p /* Info on file (output) */
+ )
+{
+ if (p)
+ {
+ if (p->p_data)
+ {
+ free(p->p_data);
+ p->p_data = NULL;
+ }
+
+ p->size = 0l;
+ }
+}
+
+
+/*============================================================================*
+ Private Function Implementations
+ *============================================================================*/
+/* None */
+
+/*============================================================================*
+ FIN
+ *============================================================================*/
diff --git a/test/testsuppt.h b/test/testsuppt.h
new file mode 100644
index 0000000..142a676
--- /dev/null
+++ b/test/testsuppt.h
@@ -0,0 +1,211 @@
+/******************************************************************************
+
+ (C) Nick Marley, 2001 -
+
+ This software is distributed under the GNU Lesser General Public Licence.
+ Please read and understand the comments at the top of vf_iface.h before use!
+
+FILE
+ $Workfile$
+ $Revision: 1.3 $
+ $Author: tilda $
+
+ORIGINAL AUTHOR
+ Nick Marley
+
+DESCRIPTION
+ Platform dependant functions supporting vformat library test harness.
+
+ A typical usage for the file find functions is as follows:
+
+ if (find_first_file(...))
+ {
+ do
+ {
+ something_worthwhile();
+ }
+ while (find_next_file(...))
+ ;
+
+ close_file_find(...);
+ }
+
+ The only reason this exists is 'cos I like to keep the core test harness
+ code platform independant.
+
+REFERENCES
+ (none)
+
+MODIFICATION HISTORY
+ $Log: testsuppt.h,v $
+ Revision 1.3 2002/11/14 20:14:25 tilda
+ Minot tidy ups to WIN32 versions.
+
+ Revision 1.2 2002/11/11 17:23:08 monos
+ run testing harness on linux systems
+
+ Revision 1.1 2001/10/12 19:02:15 tilda
+ Moved generic test functions to new file
+ *
+ *******************************************************************************/
+
+#ifndef NORCSID
+static const char testsuppt_h_vss_id[] = "$Header: /cvsroot/vformat/build/vformat/testsuppt.h,v 1.3 2002/11/14 20:14:25 tilda Exp $";
+#endif
+
+/*=============================================================================*
+ Public Includes
+ *=============================================================================*/
+
+#if defined(WIN) || defined(WIN32)
+#include <Windows.h>
+#else
+#include <glob.h>
+#endif
+
+/*============================================================================*
+ Public Defines
+ *============================================================================*/
+
+#ifndef _MAX_PATH
+#define _MAX_PATH (256)
+#endif
+
+/*============================================================================*
+ Private Data Types
+ *============================================================================*/
+
+typedef struct
+{
+#if defined(WIN) || defined(WIN32)
+ WIN32_FIND_DATA fd;
+ HANDLE h;
+ char *p_dirname;
+#else
+ glob_t h;
+#endif
+}
+file_enum_t;
+
+typedef struct
+{
+ size_t size;
+ char *p_data;
+}
+file_image_t;
+
+/*============================================================================*
+ Public Functions
+ *============================================================================*/
+
+
+/*----------------------------------------------------------------------------*
+ * NAME
+ * find_first_file()
+ *
+ * DESCRIPTION
+ * Locate (initialise search for) first file of indicated pattern in
+ * directory. If find_first_file() returns TRUE, users should call
+ * do whatever they wer going to do with the file that's located and
+ * then continue their search using find_next_file().
+ *
+ * RETURNS
+ * TRUE <=> first file found, FALSE else.
+ *----------------------------------------------------------------------------*/
+
+extern bool_t find_first_file(
+ char *p_name, /* Name of file found (output) */
+ file_enum_t *p_enum, /* Pointer to enumerator */
+ const char *p_dirname, /* Directory we're searching in */
+ const char *p_pattern /* Pattern we're searching for */
+ );
+
+
+
+/*----------------------------------------------------------------------------*
+ * NAME
+ * find_next_file()
+ *
+ * DESCRIPTION
+ * Continues a search initialised by find_first_file(). Users should
+ * call find_next_file() until it returns FALSE, then close_file_find().
+ *
+ * RETURNS
+ * TRUE <=> next file found, FALSE else.
+ *----------------------------------------------------------------------------*/
+
+extern bool_t find_next_file(
+ char *p_name, /* Name of file found (output) */
+ file_enum_t *p_enum /* Pointer to enumerator */
+ );
+
+
+
+/*----------------------------------------------------------------------------*
+ * NAME
+ * close_file_find()
+ *
+ * DESCRIPTION
+ * Close the file search. Free memory, close handles etc. The enumerator
+ * is ready for another call to find_first_file(). User should always
+ * call close_file_find() if find_first_file() returns TRUE or resources
+ * may be leaked.
+ *
+ * RETURNS
+ * (none)
+ *----------------------------------------------------------------------------*/
+
+extern void close_file_find(
+ file_enum_t *p_enum /* Pointer to enumerator */
+ );
+
+
+
+/*----------------------------------------------------------------------------*
+ * NAME
+ * filecomp()
+ *
+ * DESCRIPTION
+ * Compare files.
+ *
+ * RETURNS
+ * 0 <=> contents of files is the same, != 0 else.
+ *----------------------------------------------------------------------------*/
+
+extern int filecomp(
+ const char *p_file1, /* Name of first file */
+ const char *p_file2 /* Name of second file */
+ );
+
+
+/*----------------------------------------------------------------------------*
+ * NAME
+ * get_file_image()
+ *
+ * DESCRIPTION
+ * Load file into memory.
+ *
+ * RETURNS
+ * TRUE <=> file i/o successful, FALSE else.
+ *----------------------------------------------------------------------------*/
+
+extern bool_t get_file_image(
+ file_image_t *p, /* Info on file (output) */
+ const char *p_name /* Name of file */
+ );
+
+
+/*----------------------------------------------------------------------------*
+ * NAME
+ * free_file_image()
+ *
+ * DESCRIPTION
+ * Free up resources allocated to a file image.
+ *
+ * RETURNS
+ * (none)
+ *----------------------------------------------------------------------------*/
+
+extern void free_file_image(
+ file_image_t *p /* Info on file (output) */
+ );
diff --git a/test/vformat.c b/test/vformat.c
new file mode 100644
index 0000000..b4a753d
--- /dev/null
+++ b/test/vformat.c
@@ -0,0 +1,858 @@
+/******************************************************************************
+
+ (C) Nick Marley, 2001 -
+
+ This software is distributed under the GNU Lesser General Public Licence.
+ Please read and understand the comments at the top of vf_iface.h before use!
+
+FILE
+ $Workfile$
+ $Revision: 1.18 $
+ $Author: tilda $
+
+ORIGINAL AUTHOR
+ Nick Marley
+
+DESCRIPTION
+ Platform independant test harness for the vformat library functions. This
+ code runs various tests on the library, results are written to stdout.
+
+REFERENCES
+ (none)
+
+MODIFICATION HISTORY
+ * $Log: vformat.c,v $
+ * Revision 1.18 2002/11/16 13:33:18 tilda
+ * IID639288 - Implement method for adding subobjects.
+ *
+ * Revision 1.17 2002/11/15 09:14:59 tilda
+ * IID638823 - Various portability issues.
+ *
+ * Revision 1.16 2002/11/14 20:14:25 tilda
+ * Minot tidy ups to WIN32 versions.
+ *
+ * Revision 1.15 2002/11/11 17:23:08 monos
+ * run testing harness on linux systems
+ *
+ * Revision 1.14 2002/11/03 18:56:45 tilda
+ * Add test functions for VCAL encoding functions.
+ *
+ * Revision 1.13 2002/11/02 18:29:26 tilda
+ * IID485157 - UI does character conversion based on CHARSET property.
+ *
+ * Revision 1.12 2002/11/02 09:03:45 tilda
+ * Start of internationalisation changes.
+ *
+ * Revision 1.11 2001/11/18 22:05:57 tilda
+ * Correct args for vf_get_property().
+ *
+ * Revision 1.10 2001/10/24 20:20:27 tilda
+ * uit printing when we're done.
+ *
+ * Revision 1.9 2001/10/24 18:40:40 tilda
+ * BASE64 bugfixes. Split reader/writer code. Start create/modify work.
+ *
+ * Revision 1.8 2001/10/24 05:33:59 tilda
+ * Test harness / file list mods
+ *
+ * Revision 1.7 2001/10/16 05:50:53 tilda
+ * Debug support for lists of vobjects from single file (ie. a phonebook).
+ *
+ * Revision 1.6 2001/10/14 20:42:37 tilda
+ * Addition of group searching.
+ *
+ * Revision 1.5 2001/10/14 19:53:36 tilda
+ * Group handling. NO group searching functions.
+ *
+ * Revision 1.4 2001/10/13 14:58:56 tilda
+ * Tidy up version headers, add vf_strings.h where needed.
+ *
+ * Revision 1.3 2001/10/12 19:02:15 tilda
+ * Moved generic test functions to new file
+ *
+ ******************************************************************************/
+
+#ifndef NORCSID
+static const char vformat_c_vss_id[] = "$Header: /cvsroot/vformat/build/vformat/vformat.c,v 1.18 2002/11/16 13:33:18 tilda Exp $";
+#endif
+
+/*============================================================================*
+ ANSI C & System-wide Header Files
+ *============================================================================*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+/*============================================================================*
+ Interface Header Files
+ *============================================================================*/
+
+#include "vformat/vf_iface.h"
+
+/*============================================================================*
+ Local Header File
+ *============================================================================*/
+
+#include "testsuppt.h"
+
+/*============================================================================*
+ Private Defines
+ *============================================================================*/
+
+#define LINELENGTH (76)
+
+#define MAXBASE64ENC (1000)
+
+/*============================================================================*
+ Private Data Types
+ *============================================================================*/
+/* None */
+
+/*============================================================================*
+ Private Function Prototypes
+ *============================================================================*/
+
+static void read_cards_from_dir(const char *dirname, const char *p_pattern);
+static void test_read_vcard(const char *filename);
+static bool_t read_show_status(VF_OBJECT_T **pp_object, const char *p_name);
+static bool_t write_show_status(const char *p_name, VF_OBJECT_T *p_object);
+static void update_results(bool_t pass, bool_t warning);
+static void do_title_line(const char *filename);
+static void print_search_results(VF_PROP_T *p_tmp);
+static void check_extract_fields(const char *filename, const char *p_array[3]);
+static void check_extract_groups(const char *filename, const char *p_group);
+static void check_base64_enc(bool_t rdata);
+static bool_t encode_decode_check(const char *p_data, uint32_t length);
+static void check_vcal_functions(void);
+static void get_random_date(VF_ISO8601_PERIOD_T *p_period);
+static void get_out_file(char *, const char *, const char *);
+
+/*============================================================================*
+ Private Data
+ *============================================================================*/
+
+static int tot_tests = 0;
+static int tot_errors = 0;
+static int tot_warnings = 0;
+
+static const char *pp_tel_fields[3] =
+{
+ VFP_TELEPHONE,
+ VFP_WORK,
+ VFP_PREFERRED
+};
+
+
+/*============================================================================*
+ Public Function Implementations
+ *============================================================================*/
+
+
+/*----------------------------------------------------------------------------*
+ * NAME
+ * main()
+ *
+ * DESCRIPTION
+ * Entry point.
+ *
+ * RETURNS
+ * Hopefully.
+ *----------------------------------------------------------------------------*/
+
+int main(int argc, char **argv)
+{
+ /*
+ * simple reading / writing tests.
+ */
+ read_cards_from_dir("tests//spec", "*.vcf");
+ read_cards_from_dir("tests//adhoc", "*.vcf");
+ read_cards_from_dir("tests//utf-8", "*.vcf");
+
+ /*
+ * list access functions.
+ */
+ check_extract_fields("tests//access//access_1.vcf", pp_tel_fields);
+ check_extract_groups("tests//adhoc//group_7.vcf", "ALPHA");
+
+ /*
+ * data format tests.
+ */
+ check_base64_enc(TRUE);
+
+ /*
+ * VCAL access functions
+ */
+ check_vcal_functions();
+
+ /* split_phonebook("C:\\Windows\\Desktop\\Whole Phonebook.vcf", "C:\\Temp"); */
+
+
+ /* for automatic testing */
+ if (tot_errors) exit (1);
+ exit (0);
+}
+
+
+
+/*============================================================================*
+ Private Function Implementations
+ *============================================================================*/
+
+
+/*----------------------------------------------------------------------------*
+ * NAME
+ * main()
+ *
+ * DESCRIPTION
+ * Entry point.
+ *
+ * RETURNS
+ * Hopefully.
+ *----------------------------------------------------------------------------*/
+
+void read_cards_from_dir(
+ const char *p_dirname,
+ const char *p_pattern
+ )
+{
+ file_enum_t f;
+ char filename[_MAX_PATH];
+
+ if (find_first_file(filename, &f, p_dirname, p_pattern))
+ {
+ do
+ {
+ test_read_vcard(filename);
+ }
+ while (find_next_file(filename, &f))
+ ;
+
+ close_file_find(&f);
+ }
+}
+
+
+
+
+
+
+/*----------------------------------------------------------------------------*
+ * NAME
+ * test_read_vcard()
+ *
+ * DESCRIPTION
+ * Attempt to read the indicated card. If the read succeeds, then write
+ * the card out to a new file. Compare the original file with the new
+ * files - they will be the same if the file was in exactly the format
+ * produced by this library (line lengths & ends may differ of course as
+ * well as choice of characters escaped in quoted printable format).
+ *
+ * We then read in "our" version of the test file and write it out. This
+ * time, the output should be the same as the input. Well - for the
+ * purposes of this test I consider it an error if they differ!
+ *
+ * RETURNS
+ * (none)
+ *----------------------------------------------------------------------------*/
+
+static void test_read_vcard(
+ const char *filename
+ )
+{
+ VF_OBJECT_T *p_object = NULL;
+ bool_t warning = FALSE, pass = FALSE;
+
+ do_title_line(filename);
+
+ if (read_show_status(&p_object, filename))
+ {
+ VF_OBJECT_T *p_object_1 = NULL;
+ char outfile_1[_MAX_PATH];
+ char outfile_2[_MAX_PATH];
+
+ get_out_file(outfile_1, ".out-1", filename);
+ get_out_file(outfile_2, ".out-2", filename);
+
+ write_show_status("vobject.vcf", p_object);
+
+ write_show_status(outfile_1, p_object);
+
+ if (0 == filecomp(outfile_1, filename))
+ {
+ printf(" OK - no differences after 1st read/write\n");
+ }
+ else
+ {
+ printf(" Warning - differences after 1st read/write\n");
+
+ warning = TRUE;
+ }
+
+ if (read_show_status(&p_object_1, outfile_1))
+ {
+ write_show_status(outfile_2, p_object_1);
+ }
+
+ if (0 == filecomp(outfile_2, outfile_1))
+ {
+ printf(" OK - no differences after 2nd read/write\n");
+
+ pass = TRUE;
+ }
+ else
+ {
+ printf(" Error - differences after 2nd read/write\n");
+ }
+
+ vf_delete_object(p_object, TRUE);
+ vf_delete_object(p_object_1, TRUE);
+ }
+
+ update_results(pass, warning);
+}
+
+
+
+
+
+/*----------------------------------------------------------------------------*
+ * NAME
+ * do_title_line()
+ *
+ * DESCRIPTION
+ * Print a title line.
+ *
+ * RETURNS
+ * (none)
+ *----------------------------------------------------------------------------*/
+
+static void do_title_line(const char *filename)
+{
+ char title[LINELENGTH];
+
+ memset(title, '-', sizeof(title));
+ title[sizeof(title) - 1] = '\0';
+ memcpy(title + 2, filename, strlen(filename));
+ printf("\n%s\n", title);
+}
+
+
+
+
+
+
+
+/*----------------------------------------------------------------------------*
+ * NAME
+ * read_show_status()
+ *
+ * DESCRIPTION
+ * Wrapper on vf_read_file() which displays status after the read.
+ *
+ * RETURNS
+ * Same as wrapped vf_read_file().
+ *----------------------------------------------------------------------------*/
+
+static bool_t read_show_status(
+ VF_OBJECT_T **pp_object,
+ const char *p_name
+ )
+{
+ bool_t ret;
+
+ ret = vf_read_file(pp_object, p_name);
+
+ if (ret)
+ {
+ printf("Successfully read file '%s'\n", p_name);
+ }
+ else
+ {
+ printf("Failed to read file '%s'\n", p_name);
+ }
+
+ return ret;
+}
+
+
+
+
+/*----------------------------------------------------------------------------*
+ * NAME
+ * write_show_status()
+ *
+ * DESCRIPTION
+ * Wrapper on vf_write_file() which displays status after the read.
+ *
+ * RETURNS
+ * Same as wrapped vf_read_file().
+ *----------------------------------------------------------------------------*/
+
+static bool_t write_show_status(
+ const char *p_name,
+ VF_OBJECT_T *p_object
+ )
+{
+ bool_t ret;
+
+ ret = vf_write_file(p_name, p_object, TRUE);
+
+ if (ret)
+ {
+ printf("Successfully wrote file '%s'\n", p_name);
+ }
+ else
+ {
+ printf("Failed to wrote file '%s'\n", p_name);
+ }
+
+ return ret;
+}
+
+
+
+/*----------------------------------------------------------------------------*
+ * NAME
+ * write_show_status()
+ *
+ * DESCRIPTION
+ * Wrapper on vf_write_file() which displays status after the read.
+ *
+ * RETURNS
+ * Same as wrapped vf_read_file().
+ *----------------------------------------------------------------------------*/
+
+static void update_results(
+ bool_t pass,
+ bool_t warning
+ )
+{
+ char buffer[80];
+
+ tot_tests += 1;
+
+ if (pass)
+ {
+ /* OK */
+ }
+ else
+ {
+ tot_errors += 1;
+ }
+
+ if (warning)
+ {
+ tot_warnings += 1;
+ }
+
+ sprintf(buffer, "[%d tests, %d errors, %d warnings]",
+ tot_tests, tot_errors, tot_warnings);
+
+ printf("%*s\n", LINELENGTH-1, buffer);
+}
+
+
+
+
+
+
+/*----------------------------------------------------------------------------*
+ * NAME
+ * check_extract_fields()
+ *
+ * DESCRIPTION
+ * Exract fields.
+ *
+ * RETURNS
+ * (none)
+ *----------------------------------------------------------------------------*/
+
+static void check_extract_fields(
+ const char *filename,
+ const char *p_array[3]
+ )
+{
+ VF_OBJECT_T *p_object = NULL;
+ bool_t warning = FALSE, pass = FALSE;
+
+ do_title_line(filename);
+
+ if (read_show_status(&p_object, filename))
+ {
+ VF_PROP_T *p_tmp;
+
+ printf(" Looking for {%s}...\n", p_array[0]);
+ if (vf_get_property(&p_tmp, p_object, VFGP_FIND, NULL, p_array[0], NULL))
+ {
+ print_search_results(p_tmp);
+ }
+
+ printf(" Looking for {%s, %s}...\n", p_array[0], p_array[1]);
+ if (vf_get_property(&p_tmp, p_object, VFGP_FIND, NULL, p_array[0], p_array[1], NULL))
+ {
+ print_search_results(p_tmp);
+ }
+
+ printf(" Looking for {%s, %s}...\n", p_array[0], p_array[2]);
+ if (vf_get_property(&p_tmp, p_object, VFGP_FIND, NULL, p_array[0], p_array[2], NULL))
+ {
+ print_search_results(p_tmp);
+ }
+
+ printf(" Looking for {%s, %s, %s}...\n", p_array[0], p_array[1], p_array[2]);
+ if (vf_get_property(&p_tmp, p_object, VFGP_FIND, NULL, p_array[0], p_array[1], p_array[2], NULL))
+ {
+ print_search_results(p_tmp);
+ }
+
+ vf_delete_object(p_object, TRUE);
+
+ pass = TRUE;
+ }
+
+ update_results(pass, warning);
+}
+
+
+
+
+
+
+
+/*----------------------------------------------------------------------------*
+ * NAME
+ * extract_groups()
+ *
+ * DESCRIPTION
+ *
+ *
+ * RETURNS
+ * (none)
+ *----------------------------------------------------------------------------*/
+
+static void check_extract_groups(
+ const char *filename,
+ const char *p_group
+ )
+{
+ VF_OBJECT_T *p_object = NULL;
+ bool_t warning = FALSE, pass = FALSE;
+
+ do_title_line(filename);
+
+ if (read_show_status(&p_object, filename))
+ {
+ VF_PROP_T *p_tmp;
+
+ if (vf_get_property(&p_tmp, p_object, VFGP_FIND, p_group, "LOGO", NULL))
+ {
+ print_search_results(p_tmp);
+ }
+
+ vf_delete_object(p_object, TRUE);
+
+ pass = TRUE;
+ }
+
+ update_results(pass, warning);
+}
+
+
+
+
+
+
+
+
+/*----------------------------------------------------------------------------*
+ * NAME
+ * print_search_results()
+ *
+ * DESCRIPTION
+ * List the values in each of the current search results.
+ *
+ * RETURNS
+ * (none)
+ *----------------------------------------------------------------------------*/
+
+static void print_search_results(
+ VF_PROP_T *p_tmp /* Pointer to current property */
+ )
+{
+ do
+ {
+ void *ptr;
+ uint32_t size;
+ vf_encoding_t enc;
+
+ if (vf_get_prop_value(p_tmp, &ptr, &size, &enc))
+ {
+ switch (enc)
+ {
+ case VF_ENC_BASE64:
+ {
+ printf(" prop = \"%s\"\n", vf_get_prop_name_string(p_tmp, 0));
+ }
+ break;
+
+ case VF_ENC_7BIT:
+ case VF_ENC_QUOTEDPRINTABLE:
+ {
+ uint16_t i;
+
+ for (i = 0;;i++)
+ {
+ const char *p_value = vf_get_prop_value_string(p_tmp, i);
+
+ if (p_value)
+ {
+ printf(" field[%d] = \"%s\"\n", i, p_value);
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+ break;
+ }
+ }
+ }
+ while (vf_get_next_property(&p_tmp))
+ ;
+}
+
+
+
+
+
+
+/*----------------------------------------------------------------------------*
+ * NAME
+ * check_base64_enc()
+ *
+ * DESCRIPTION
+ * Check BASE64 encoding.
+ *
+ * RETURNS
+ * (none)
+ *----------------------------------------------------------------------------*/
+
+static void check_base64_enc(bool_t rdata)
+{
+ char buffer[MAXBASE64ENC+1];
+ int i, s;
+ bool_t pass;
+
+ do_title_line("BASE64 encoding");
+
+ for (s = 1, pass = TRUE;pass && (s < sizeof(buffer));s++)
+ {
+ for (i = 0;i < s;i++)
+ {
+ buffer[i] = (rdata ? rand() : (i + 1)) % 256;
+ }
+
+ pass &= encode_decode_check(buffer, s);
+
+ if (pass)
+ {
+ printf("encode_decode_check() : OK @ %d bytes\r", s);
+ }
+ }
+
+ printf("\n");
+
+ update_results(pass, 0);
+}
+
+
+
+/*----------------------------------------------------------------------------*
+ * NAME
+ * encode_decode_check()
+ *
+ * DESCRIPTION
+ * Encode & decode chunk of data. Check data consistency.
+ *
+ * RETURNS
+ * TRUE iff encoded / decoded successfully.
+ *----------------------------------------------------------------------------*/
+
+static bool_t encode_decode_check(
+ const char *p_data, /* Pointer to data */
+ uint32_t length /* Length */
+ )
+{
+ VF_OBJECT_T *p_object;
+ const char *testfile = "bindata.vcf";
+ const char *testprop = "X-BINARY-DATA";
+
+ bool_t pass = FALSE;
+
+ p_object = vf_create_object("TEST", NULL);
+
+ if (p_object)
+ {
+ VF_PROP_T *p_prop;
+
+ if (vf_get_property(&p_prop, p_object, VFGP_GET, NULL, testprop, NULL))
+ {
+ vf_set_prop_value_base64(p_prop, p_data, length, TRUE);
+ }
+
+ vf_write_file(testfile, p_object, TRUE);
+
+ vf_delete_object(p_object, TRUE);
+ }
+
+ if (vf_read_file(&p_object, testfile))
+ {
+ VF_PROP_T *p_prop;
+
+ if (vf_get_property(&p_prop, p_object, VFGP_FIND, NULL, testprop, NULL))
+ {
+ const char *p_new_data;
+ uint32_t new_length;
+
+ p_new_data = vf_get_prop_value_base64(p_prop, &new_length);
+
+ if (p_new_data)
+ {
+ if (length == new_length)
+ {
+ if (0 == memcmp(p_data, p_new_data, length))
+ {
+ pass = TRUE;
+ }
+ else
+ {
+ printf("encode_decode_check() : data NOT OK\n");
+ }
+ }
+ else
+ {
+ printf("encode_decode_check() : Length error\n");
+ }
+ }
+ else
+ {
+ printf("encode_decode_check() : No data\n");
+ }
+ }
+
+ vf_delete_object(p_object, TRUE);
+ }
+
+ return pass;
+}
+
+
+
+
+
+/*----------------------------------------------------------------------------*
+ * NAME
+ * check_vcal_functions()
+ *
+ * DESCRIPTION
+ * Check the date encoding functions. This is a non systematic random
+ * test ehich generates random values, encodes them, decodes them and
+ * compares the result with the initial value.
+ *
+ * RETURNS
+ * (none)
+ *----------------------------------------------------------------------------*/
+
+static void check_vcal_functions(void)
+{
+ VF_ISO8601_PERIOD_T test_in, test_out;
+ int i;
+ bool_t pass;
+
+ do_title_line("VCAL encoding functions");
+
+ for (i = 0, pass = TRUE;pass && (i < 1000);i++)
+ {
+ char sz[256];
+
+ get_random_date(&test_in);
+
+ vf_period_time_to_string(sz, &test_in);
+ vf_period_string_to_time(&test_out, sz);
+
+ if (memcmp(&test_in, &test_out, sizeof(VF_ISO8601_PERIOD_T)))
+ {
+ pass = FALSE;
+ }
+ else
+ {
+ printf("check_vcal_functions() : %s \r", sz);
+ }
+ }
+
+ printf("\n");
+
+ update_results(pass, 0);
+}
+
+
+
+
+/*----------------------------------------------------------------------------*
+ * NAME
+ * get_random_date()
+ *
+ * DESCRIPTION
+ * Initialise a random VF_ISO8601_PERIOD_T value.
+ *
+ * RETURNS
+ * (none)
+ *----------------------------------------------------------------------------*/
+
+void get_random_date(VF_ISO8601_PERIOD_T *p_period)
+{
+ p_period->days = rand() % 100;
+ p_period->hours = rand() % 24;
+ p_period->minutes = rand() % 60;
+ p_period->months = rand() % 12;
+ p_period->seconds = rand() % 60;
+ p_period->weeks = rand() % 9;
+ p_period->years = rand() % 20;
+}
+
+
+
+/*----------------------------------------------------------------------------*
+ * NAME
+ * get_out_file()
+ *
+ * DESCRIPTION
+ * Obtain the name of a test output file from a teset input file. The
+ * outout filename is the input name with the subscript replaced.
+ *
+ * RETURNS
+ * (none)
+ *----------------------------------------------------------------------------*/
+
+void get_out_file(
+ char *p_outfile, /* Buffer to receive filename */
+ const char *p_subscript, /* New subscript */
+ const char *p_infile /* Name of source file we're mimicing */
+ )
+{
+ char *p_found_subscript;
+
+ strcpy(p_outfile, p_infile);
+
+ if (NULL == (p_found_subscript = strstr(p_outfile, ".")))
+ {
+ printf("get_out_file() : invalid name (%s) in test files\n", p_outfile);
+ }
+ else
+ {
+ strcpy(p_found_subscript, p_subscript);
+ }
+}
+