From d3a53b82aa57f5090d95b69e6f567b06eb544df9 Mon Sep 17 00:00:00 2001 From: Nikias Bassen Date: Sun, 10 Feb 2013 20:06:08 +0100 Subject: initial commit of 1.13 sources --- AUTHORS | 7 + COPYING | 503 +++++++++ ChangeLog | 5 + INSTALL | 182 ++++ Makefile.am | 4 + NEWS | 20 + README | 207 ++++ autogen.sh | 15 + common/types.h | 87 ++ config.h.in | 87 ++ configure.ac | 31 + doc/Makefile.am | 16 + src/Makefile.am | 11 + src/vf_access.c | 661 ++++++++++++ src/vf_access_calendar.c | 528 ++++++++++ src/vf_access_wrappers.c | 541 ++++++++++ src/vf_config.h | 85 ++ src/vf_create_object.c | 158 +++ src/vf_delete.c | 327 ++++++ src/vf_internals.h | 223 ++++ src/vf_malloc.c | 270 +++++ src/vf_malloc.h | 166 +++ src/vf_malloc_stdlib.c | 392 +++++++ src/vf_malloc_stdlib.h | 90 ++ src/vf_modified.c | 159 +++ src/vf_modified.h | 84 ++ src/vf_parser.c | 1182 +++++++++++++++++++++ src/vf_reader.c | 277 +++++ src/vf_search.c | 457 ++++++++ src/vf_string_arrays.c | 435 ++++++++ src/vf_string_arrays.h | 177 ++++ src/vf_strings.c | 472 +++++++++ src/vf_strings.h | 230 ++++ src/vf_writer.c | 616 +++++++++++ stamp-h.in | 0 test/Makefile.am | 7 + test/tests/access/access_1.vcf | 17 + test/tests/adhoc/group_1.vcf | 6 + test/tests/adhoc/group_2.vcf | 9 + test/tests/adhoc/group_3.vcf | 13 + test/tests/adhoc/group_4.vcf | 16 + test/tests/adhoc/group_5.vcf | 16 + test/tests/adhoc/group_6.vcf | 23 + test/tests/adhoc/group_7.vcf | 46 + test/tests/adhoc/mail_list_1.vcf | 4 + test/tests/adhoc/mail_list_2.vcf | 4 + test/tests/adhoc/mail_list_3.vcf | 3 + test/tests/adhoc/mail_list_4.vcf | 13 + test/tests/adhoc/mail_list_5.vcf | 19 + test/tests/adhoc/mail_list_6.vcf | 4 + test/tests/adhoc/multiple_objs_1.vcf | 21 + test/tests/adhoc/straight_1.vcf | 2 + test/tests/adhoc/straight_2.vcf | 3 + test/tests/adhoc/straight_3.vcf | 3 + test/tests/adhoc/straight_4.vcf | 3 + test/tests/adhoc/straight_5.vcf | 3 + test/tests/adhoc/straight_6.vcf | 3 + test/tests/adhoc/straight_7.vcf | 3 + test/tests/adhoc/straight_8.vcf | 4 + test/tests/adhoc/straight_9.vcf | 4 + test/tests/adhoc/straight_A.vcf | 7 + test/tests/adhoc/straight_B.vcf | 4 + test/tests/adhoc/straight_C.vcf | 4 + test/tests/adhoc/straight_D.vcf | 4 + test/tests/adhoc/straight_E.vcf | 4 + test/tests/adhoc/straight_F.vcf | 5 + test/tests/adhoc/straight_G.vcf | 8 + test/tests/adhoc/straight_H.vcf | 11 + test/tests/adhoc/straight_I.vcf | 12 + test/tests/adhoc/straight_qp_1.vcf | 3 + test/tests/adhoc/straight_qp_2.vcf | 3 + test/tests/adhoc/straight_qp_3.vcf | 5 + test/tests/adhoc/straight_qp_4.vcf | 5 + test/tests/adhoc/vcal_1.vcs | 20 + test/tests/spec/2_1_1-begin-1.vcf | 3 + test/tests/spec/2_1_1-begin-2.vcf | 23 + test/tests/spec/2_1_2-property.vcf | 7 + test/tests/spec/2_1_3-delimiters.vcf | 7 + test/tests/spec/2_1_4_1-grouping-nested.vcf | 9 + test/tests/spec/2_1_4_1-grouping-sequential.vcf | 9 + test/tests/spec/2_1_4_2-property-grouping.vcf | 4 + test/tests/spec/2_1_6-charset.vcf | 3 + test/tests/spec/2_1_7-language.vcf | 3 + test/tests/spec/2_1_8-valuelocation.vcf | 4 + test/tests/spec/2_2_1-fn.vcf | 3 + test/tests/spec/2_2_2-name.vcf | 4 + test/tests/spec/2_2_3-photo.vcf | 7 + test/tests/spec/2_2_4-birthdate.vcf | 4 + test/tests/spec/2_3_1-address.vcf | 3 + test/tests/spec/2_3_2-label.vcf | 12 + test/tests/spec/2_4_1-tel.vcf | 3 + test/tests/spec/2_4_2-email.vcf | 16 + test/tests/spec/2_4_3-mailer.vcf | 3 + test/tests/spec/2_4_5-tz.vcf | 4 + test/tests/spec/2_4_6-geo.vcf | 3 + test/tests/spec/2_5_1-title.vcf | 3 + test/tests/spec/2_5_2-role.vcf | 3 + test/tests/spec/2_5_3-logo.vcf | 6 + test/tests/spec/2_5_4-agent.vcf | 9 + test/tests/spec/2_5_5-org.vcf | 3 + test/tests/spec/2_6_1-comment.vcf | 6 + test/tests/spec/2_6_2-revision.vcf | 4 + test/tests/spec/2_6_3-sound.vcf | 8 + test/tests/spec/2_6_4-url.vcf | 3 + test/tests/spec/2_6_5-uid.vcf | 3 + test/tests/utf-8/S15cx8.vcf | 352 +++++++ test/tests/utf-8/S15cxu.vcf | 6 + test/testsuppt.c | 409 ++++++++ test/testsuppt.h | 211 ++++ test/vformat.c | 858 +++++++++++++++ vf_iface.h | 35 + vformat/Makefile.am | 2 + vformat/vf_iface.h | 1269 +++++++++++++++++++++++ 113 files changed, 12373 insertions(+) create mode 100644 AUTHORS create mode 100644 COPYING create mode 100644 ChangeLog create mode 100644 INSTALL create mode 100644 Makefile.am create mode 100644 NEWS create mode 100644 README create mode 100755 autogen.sh create mode 100644 common/types.h create mode 100644 config.h.in create mode 100644 configure.ac create mode 100644 doc/Makefile.am create mode 100644 src/Makefile.am create mode 100644 src/vf_access.c create mode 100644 src/vf_access_calendar.c create mode 100644 src/vf_access_wrappers.c create mode 100644 src/vf_config.h create mode 100644 src/vf_create_object.c create mode 100644 src/vf_delete.c create mode 100644 src/vf_internals.h create mode 100644 src/vf_malloc.c create mode 100644 src/vf_malloc.h create mode 100644 src/vf_malloc_stdlib.c create mode 100644 src/vf_malloc_stdlib.h create mode 100644 src/vf_modified.c create mode 100644 src/vf_modified.h create mode 100644 src/vf_parser.c create mode 100644 src/vf_reader.c create mode 100644 src/vf_search.c create mode 100644 src/vf_string_arrays.c create mode 100644 src/vf_string_arrays.h create mode 100644 src/vf_strings.c create mode 100644 src/vf_strings.h create mode 100644 src/vf_writer.c create mode 100644 stamp-h.in create mode 100644 test/Makefile.am create mode 100644 test/tests/access/access_1.vcf create mode 100644 test/tests/adhoc/group_1.vcf create mode 100644 test/tests/adhoc/group_2.vcf create mode 100644 test/tests/adhoc/group_3.vcf create mode 100644 test/tests/adhoc/group_4.vcf create mode 100644 test/tests/adhoc/group_5.vcf create mode 100644 test/tests/adhoc/group_6.vcf create mode 100644 test/tests/adhoc/group_7.vcf create mode 100644 test/tests/adhoc/mail_list_1.vcf create mode 100644 test/tests/adhoc/mail_list_2.vcf create mode 100644 test/tests/adhoc/mail_list_3.vcf create mode 100644 test/tests/adhoc/mail_list_4.vcf create mode 100644 test/tests/adhoc/mail_list_5.vcf create mode 100644 test/tests/adhoc/mail_list_6.vcf create mode 100644 test/tests/adhoc/multiple_objs_1.vcf create mode 100644 test/tests/adhoc/straight_1.vcf create mode 100644 test/tests/adhoc/straight_2.vcf create mode 100644 test/tests/adhoc/straight_3.vcf create mode 100644 test/tests/adhoc/straight_4.vcf create mode 100644 test/tests/adhoc/straight_5.vcf create mode 100644 test/tests/adhoc/straight_6.vcf create mode 100644 test/tests/adhoc/straight_7.vcf create mode 100644 test/tests/adhoc/straight_8.vcf create mode 100644 test/tests/adhoc/straight_9.vcf create mode 100644 test/tests/adhoc/straight_A.vcf create mode 100644 test/tests/adhoc/straight_B.vcf create mode 100644 test/tests/adhoc/straight_C.vcf create mode 100644 test/tests/adhoc/straight_D.vcf create mode 100644 test/tests/adhoc/straight_E.vcf create mode 100644 test/tests/adhoc/straight_F.vcf create mode 100644 test/tests/adhoc/straight_G.vcf create mode 100644 test/tests/adhoc/straight_H.vcf create mode 100644 test/tests/adhoc/straight_I.vcf create mode 100644 test/tests/adhoc/straight_qp_1.vcf create mode 100644 test/tests/adhoc/straight_qp_2.vcf create mode 100644 test/tests/adhoc/straight_qp_3.vcf create mode 100644 test/tests/adhoc/straight_qp_4.vcf create mode 100644 test/tests/adhoc/vcal_1.vcs create mode 100644 test/tests/spec/2_1_1-begin-1.vcf create mode 100644 test/tests/spec/2_1_1-begin-2.vcf create mode 100644 test/tests/spec/2_1_2-property.vcf create mode 100644 test/tests/spec/2_1_3-delimiters.vcf create mode 100644 test/tests/spec/2_1_4_1-grouping-nested.vcf create mode 100644 test/tests/spec/2_1_4_1-grouping-sequential.vcf create mode 100644 test/tests/spec/2_1_4_2-property-grouping.vcf create mode 100644 test/tests/spec/2_1_6-charset.vcf create mode 100644 test/tests/spec/2_1_7-language.vcf create mode 100644 test/tests/spec/2_1_8-valuelocation.vcf create mode 100644 test/tests/spec/2_2_1-fn.vcf create mode 100644 test/tests/spec/2_2_2-name.vcf create mode 100644 test/tests/spec/2_2_3-photo.vcf create mode 100644 test/tests/spec/2_2_4-birthdate.vcf create mode 100644 test/tests/spec/2_3_1-address.vcf create mode 100644 test/tests/spec/2_3_2-label.vcf create mode 100644 test/tests/spec/2_4_1-tel.vcf create mode 100644 test/tests/spec/2_4_2-email.vcf create mode 100644 test/tests/spec/2_4_3-mailer.vcf create mode 100644 test/tests/spec/2_4_5-tz.vcf create mode 100644 test/tests/spec/2_4_6-geo.vcf create mode 100644 test/tests/spec/2_5_1-title.vcf create mode 100644 test/tests/spec/2_5_2-role.vcf create mode 100644 test/tests/spec/2_5_3-logo.vcf create mode 100644 test/tests/spec/2_5_4-agent.vcf create mode 100644 test/tests/spec/2_5_5-org.vcf create mode 100644 test/tests/spec/2_6_1-comment.vcf create mode 100644 test/tests/spec/2_6_2-revision.vcf create mode 100644 test/tests/spec/2_6_3-sound.vcf create mode 100644 test/tests/spec/2_6_4-url.vcf create mode 100644 test/tests/spec/2_6_5-uid.vcf create mode 100644 test/tests/utf-8/S15cx8.vcf create mode 100644 test/tests/utf-8/S15cxu.vcf create mode 100644 test/testsuppt.c create mode 100644 test/testsuppt.h create mode 100644 test/vformat.c create mode 100644 vf_iface.h create mode 100644 vformat/Makefile.am create mode 100644 vformat/vf_iface.h diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..6ee2191 --- /dev/null +++ b/AUTHORS @@ -0,0 +1,7 @@ +Main author of vformat + +Nick + +Porting to Linux + +Mathias Palm \ No newline at end of file diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..1691fad --- /dev/null +++ b/COPYING @@ -0,0 +1,503 @@ + + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations +below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. +^L + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it +becomes a de-facto standard. To achieve this, non-free programs must +be allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. +^L + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control +compilation and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. +^L + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. +^L + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at least + three years, to give the same user the materials specified in + Subsection 6a, above, for a charge no more than the cost of + performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. +^L + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. +^L + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply, and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License +may add an explicit geographical distribution limitation excluding those +countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. +^L + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS +^L + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms +of the ordinary General Public License). + + To apply these terms, attach the following notices to the library. +It is safest to attach them to the start of each source file to most +effectively convey the exclusion of warranty; and each file should +have at least the "copyright" line and a pointer to where the full +notice is found. + + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Main author of vformat + +Nick + +Porting to Linux + +Mathias Palm + + diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..4fe7df9 --- /dev/null +++ b/ChangeLog @@ -0,0 +1,5 @@ +2002-11-22 Mathias Palm + + * manpages are generated from the header file and installed + +see README \ No newline at end of file diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..b42a17a --- /dev/null +++ b/INSTALL @@ -0,0 +1,182 @@ +Basic Installation +================== + + These are generic installation instructions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, a file +`config.cache' that saves the results of its tests to speed up +reconfiguring, and a file `config.log' containing compiler output +(useful mainly for debugging `configure'). + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If at some point `config.cache' +contains results you don't want to keep, you may remove or edit it. + + The file `configure.in' is used to create `configure' by a program +called `autoconf'. You only need `configure.in' if you want to change +it or regenerate `configure' using a newer version of `autoconf'. + +The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. If you're + using `csh' on an old version of System V, you might need to type + `sh ./configure' instead to prevent `csh' from trying to execute + `configure' itself. + + Running `configure' takes awhile. While running, it prints some + messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package. + + 4. Type `make install' to install the programs and any data files and + documentation. + + 5. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the `configure' script does not know about. You can give `configure' +initial values for variables by setting them in the environment. Using +a Bourne-compatible shell, you can do that on the command line like +this: + CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure + +Or on systems that have the `env' program, you can do it like this: + env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure + +Compiling For Multiple Architectures +==================================== + + You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you must use a version of `make' that +supports the `VPATH' variable, such as GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. + + If you have to use a `make' that does not supports the `VPATH' +variable, you have to compile the package for one architecture at a time +in the source code directory. After you have installed the package for +one architecture, use `make distclean' before reconfiguring for another +architecture. + +Installation Names +================== + + By default, `make install' will install the package's files in +`/usr/local/bin', `/usr/local/man', etc. You can specify an +installation prefix other than `/usr/local' by giving `configure' the +option `--prefix=PATH'. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +give `configure' the option `--exec-prefix=PATH', the package will use +PATH as the prefix for installing programs and libraries. +Documentation and other data files will still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=PATH' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + +Optional Features +================= + + Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + +Specifying the System Type +========================== + + There may be some features `configure' can not figure out +automatically, but needs to determine by the type of host the package +will run on. Usually `configure' can figure that out, but if it prints +a message saying it can not guess the host type, give it the +`--host=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name with three fields: + CPU-COMPANY-SYSTEM + +See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the host type. + + If you are building compiler tools for cross-compiling, you can also +use the `--target=TYPE' option to select the type of system they will +produce code for and the `--build=TYPE' option to select the type of +system on which you are compiling the package. + +Sharing Defaults +================ + + If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Operation Controls +================== + + `configure' recognizes the following options to control how it +operates. + +`--cache-file=FILE' + Use and save the results of the tests in FILE instead of + `./config.cache'. Set FILE to `/dev/null' to disable caching, for + debugging `configure'. + +`--help' + Print a summary of the options to `configure', and exit. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`--version' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`configure' also accepts some other, not widely useful, options. diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..9ea4543 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,4 @@ +SUBDIRS = src vformat test doc + +EXTRA_DIST = common/types.h vf_iface.h + diff --git a/NEWS b/NEWS new file mode 100644 index 0000000..c35d277 --- /dev/null +++ b/NEWS @@ -0,0 +1,20 @@ +Posted By: tilda +Date: 2001-12-16 10:19 +Summary:Alpha 5 + +Alpha-5 is here! + +This is mostly a bugfix release over Alpha-4, new functionality will go into Alpha-6, which may be the last Alpha. + +Please note that from Alpha-5 onwards you will need DevIL from SourceForge. + + +Cheers, + +Nick + +Posted By: tilda +Date: 2001-10-24 13:47 +Summary:Alpha-2 + +Well; Alpha-2 is here - this is about as exciting as it gets isn't it... \ No newline at end of file diff --git a/README b/README new file mode 100644 index 0000000..d27d423 --- /dev/null +++ b/README @@ -0,0 +1,207 @@ +/----------------------------------------------------------------------------- +| $Log: README,v $ +| Revision 1.1 2002/10/11 14:08:59 monos +| *** empty log message *** +| +| Revision 1.13 2001/12/28 17:29:29 tilda +| Minor tidy ups after updating to DevIL-1.2.4 +| +| Revision 1.12 2001/12/16 16:01:15 tilda +| Update release notes before Alpha-5 +| +| Revision 1.11 2001/12/10 09:28:35 tilda +| Typo. +| +| Revision 1.10 2001/12/10 09:21:47 tilda +| Describe image librrary build options. +| +| Revision 1.9 2001/12/02 21:20:25 tilda +| Update prior to Alpha-4 +| +| Revision 1.8 2001/11/27 18:32:59 tilda +| Reword LICENCING section in README.txt. Move docs into vformatl.dsp +| +\----------------------------------------------------------------------------- + +Welcome to the vFormat Library! + +LICENCE +======= + +All this software (the library and the demo apps) is distributed under the +GNU Lesser General Public Licence. A copy of this is distributed with the +library - see the file LICENCE.txt in the libraries root directory. + +Please read and understand the comments at the top of vf_iface.h before use. + + +RELEASES +======== +This will be considered "alpha" until all the features I think should be +there are there. It'll be "beta" until I know of no outstanding issues. +Release history: + +Alpha-1 : first cut at a release, known problems with BASE64, no create/modify API + +Alpha-2 : BASE64 encoding fixed, first pass at create/modify functionality + +Alpha-3 : including first usable version of vfedit demo app + +Alpha-4 : Add basic framework support for vCalendar to VFEDIT. Sort out tools menu + and font manager. Fix IIDs 485069, 485071, 488003, 484956, 488006, 488011. + Sort out various bugs in IMGHLP DLLs. + +Alpha-5 : Various bug fixes and move to use of a image library (DevIL from SourceForge) + rather than various dodgy home-grown bits'n'pieces. Fix IIDs 484685, 491475 + 489753, 484684, 488021, 484958, 484844, 484843. vfedit now reasonably usable + (for VCARDs). + + +BUILDING +======== + +Under Windows, the build uses Microsoft's Visual C++ version 6.0 - the +project & workspace files are included in the distribution. The workspace +at .../build/vformat/vformat.dsw references will build and install the +library (ie. the .DLL) and builds the test harness. In detail: + + .../build/vformat/vformat.dsw - workspace including other project files + .../build/vformatl/vformatl.dsp - builds (and installs) DLL version + .../build/tools - various tools & utilities + + .../build/vfdisplay - minimal app enumerating contents of a vobject + .../build/vfedit - demo app supporting VCARDs & VCALENDARs. + +Beware - vformatl.dsp and the other DSPs will install the DLLs in your +windows/system directory using the INSDLL.BAT file in the tools directory +which is invoked as a post-build step (see the post-build tab on the +projects/settings dialog). If you don't like this, delete the post +build step or edit the script to put the DLL somewhere else. + + + +IMAGE LIBRARY +============= +Imaging formats (.JPG etc) are handled in the demo applications using a 3rd party +open source image library. Early releases of VFEDIT used various bits of garbage +I'd collected over the years wrapped up in an .DLL (deliberately hiding the crap). + +As of Alpha-5, VFEDIT includes support for DevIL - the Developer's Image Libray. +Details of this can be found at http://OpenIL.sourceforge.net. + +To enable image support you need to download & install DevIL and change the line +at the top of ImageManager.cpp to #define USE_IMAGE_LIBRARY (rather than #undef). + +Here are the instructions to get a basic version of this going, this is based on +the install instructions included in DevIL & various things about my machine. The +basic version supports .BMP files, I've not (yet) got round to adding .JPG etc to +my build of DevIL. + + - download DevIL-1.2.4.zip from the page in SourceForge. + - unpack the .ZIP file somewhere convenient eg. D:\DevIL + - change your global include paths (eg. Tools->Options->Directories in MSVC6) + to include DevIL's include dirs (eg. D:\DevIL\ImageLib\Include) + - change your global library paths to include DevIL's include dirs + (eg. D:\DevIL\ImageLib\lib and D:\DevIL\ImageLib\lib\debug) + - change the post build steps as appropriate for your system + - uncomment IL_NO_GIF, IL_NO_JPG, IL_NO_MNG, IL_NO_PNG, IL_NO_TIF + - uncomment IL_NO_LCMS and comment out ilApplyProfile from IL.DEF + - comment out ILUT_USE_DIRECTX8 in il/ilut.h (I don't have it installed) + - comment out ilutD3D8LoadSurface ... ilutD3D8VolTexFromResource from ILUT.def + - change the USE_IMAGE_LIBRARY #define in ImageManager.cpp + + + + +REFERENCES +========== +[1] vCard, The Electronic Business Card Version 2.1 from Versit. + + +OUTSTANDING ISSUES +================== + +After Alpha-4, this section transferred to the SourceForge database. + + +THE TEST HARNESS +================ + +Running the test harness will produce a load of output similar to +the following: + +--tests//adhoc//straight_qp_4.vcf------------------------------------------ +Successfully read file 'tests//adhoc//straight_qp_4.vcf' +Successfully wrote file 'vobject.vcf' +Successfully wrote file 'tests//adhoc//straight_qp_4.out-1' + Sizes difference : + tests//adhoc//straight_qp_4.out-1 (139 bytes) Vs. + tests//adhoc//straight_qp_4.vcf (151 bytes) + Warning - differences after 1st read/write +Successfully read file 'tests//adhoc//straight_qp_4.out-1' +Successfully wrote file 'tests//adhoc//straight_qp_4.out-2' + OK - no differences after 2nd read/write + [60 tests, 0 errors, 13 warnings] + +What does it all mean? All the warnings are a result of size differences +between the original file & the result of reading/writing the file back. +The size differences are a result of: + * slightly different conventions for line length + * line ends (eg not ) + * different selection of quoted chars in QP format + * excess whitespace at the end of the file + * characters ignored before the first BEGIN: or between END: and BEGIN: + +Each such difference is clocked up as a warning. The [...] stuff is +a rolling count of tests, errors & warnings. An error is logged if +after the file is "canonicalised" (well; into the format assumed by +this library anyway) we fail to read & write and get the same output. + +The files in tests/spec are named after sections of the (very fine) +vcard 2.1 specification eg. 2_1_4_1-grouping-sequential.vcf will refer +to something like "sequential grouping" in section 2.1.4.1 of the +Versit doc (see http://www.imc.org/pdi/ for the docs). + +(There is no intention to infringe the copyright anyone might consider +they have vested in the text of these examples) + +The files in tests/adhoc are just sample scripts I knocked up +during development. + + +FUTURE PLANS +============ + +1) Convert this document to some decent on-line docs on the project website. + +2) Write a vobjects library .../src/vobjects & .../build/vobjectsl which + provides C++ classes modelling a vformat object with derived classes + for vCard, vNote etc. Functions on the base class provide file handling + and change logs. Functions on the derived classes handle a user's + normal interaction with the relevant objects eg: + + typedef enum + { + Work, + Home, + Cellular, + Mobile = Cellular + } + vf_phone_type_t; + + bool_t vformat::vcard::set_phone_no( + vf_phone_type_t t, /* Type of phone number */ + bool_t is_pref, /* Should this entry be given the PREF flag? */ + const char *phone_no /* The phone number itself */ + ); + +4) Duplicate the MFC app as a GTK app. + + + +CREDITS +======= + +Enjoy! + +Nick diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 0000000..3292973 --- /dev/null +++ b/autogen.sh @@ -0,0 +1,15 @@ +#!/bin/sh +gprefix=`which glibtoolize 2>&1 >/dev/null` +if [ $? -eq 0 ]; then + glibtoolize --force +else + libtoolize --force +fi +aclocal -I m4 +autoheader +automake --add-missing +autoconf + +if [ -z "$NOCONFIGURE" ]; then + ./configure "$@" +fi diff --git a/common/types.h b/common/types.h new file mode 100644 index 0000000..7eed375 --- /dev/null +++ b/common/types.h @@ -0,0 +1,87 @@ +/******************************************************************************* + + (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.5 $ + $Author: tilda $ + +ORIGINAL AUTHOR + Nick Marley + +DESCRIPTION + In the abscence of suitable typedefs provided by whatever environment you're + building under, this defines the minimal set of types required by vformat library. + +MODIFICATION HISTORY + * $Log: types.h,v $ + * Revision 1.5 2002/11/15 09:15:00 tilda + * IID638823 - Various portability issues. + * + * Revision 1.4 2002/10/08 20:23:16 tilda + * Improve comments. Tidy header. + * + * Revision 1.3 2002/10/08 20:20:10 tilda + * Comments (!). Removed unused types. + *******************************************************************************/ + +#ifndef _TYPES_H_ +#define _TYPES_H_ + +#ifndef NORCSID +static const char _types_h_vss_id[] = "$Header: /cvsroot/vformat/src/common/types.h,v 1.5 2002/11/15 09:15:00 tilda Exp $"; +#endif + +/*=============================================================================* + Public Includes + *============================================================================*/ +/* None */ + +/*=============================================================================* + Public Defines + *============================================================================*/ + +#undef NULL +#define NULL 0 + +#undef FALSE +#define FALSE ((bool_t)(0)) + +#undef TRUE +#define TRUE ((bool_t)(1)) + +/*=============================================================================* + Public Types + *============================================================================*/ + +/* + * Basic types. + */ +#if defined(USE_INTTYPES_H) +#include +#else +typedef unsigned char uint8_t; +typedef unsigned short int uint16_t; +typedef unsigned long int uint32_t; +#endif + +/* + * Please avoide 'BOOL' (from Windows) and 'bool' (from C++) - vformat is used + * extensively in pure C embedded applications where neither are relevant. + */ +typedef unsigned char bool_t; + +/*=============================================================================* + Public Functions + *============================================================================*/ +/* None */ + +/*=============================================================================* + End of file + *============================================================================*/ + +#endif /*_TYPES_H_*/ diff --git a/config.h.in b/config.h.in new file mode 100644 index 0000000..54168ab --- /dev/null +++ b/config.h.in @@ -0,0 +1,87 @@ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Define to 1 if you have the `alarm' function. */ +#undef HAVE_ALARM + +/* Define to 1 if you have the `atexit' function. */ +#undef HAVE_ATEXIT + +/* Define to 1 if you have the header file. */ +#undef HAVE_DLFCN_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the `memset' function. */ +#undef HAVE_MEMSET + +/* Define to 1 if `stat' has the bug that it succeeds when given the + zero-length file name argument. */ +#undef HAVE_STAT_EMPTY_STRING_BUG + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the `strstr' function. */ +#undef HAVE_STRSTR + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TIME_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define to 1 if `lstat' dereferences a symlink specified with a trailing + slash. */ +#undef LSTAT_FOLLOWS_SLASHED_SYMLINK + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Define to 1 if you can safely include both and . */ +#undef TIME_WITH_SYS_TIME + +/* Define to 1 if your declares `struct tm'. */ +#undef TM_IN_SYS_TIME + +/* Version number of package */ +#undef VERSION + +/* Define to empty if `const' does not conform to ANSI C. */ +#undef const diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..d1b1041 --- /dev/null +++ b/configure.ac @@ -0,0 +1,31 @@ +# Process this file with autoconf to produce a configure script. +AC_INIT(libvformat, 1.13, Nick ) +AC_CONFIG_SRCDIR([vf_iface.h]) +#AC_CONFIG_HEADER([config.h]) + +AM_INIT_AUTOMAKE(libvformat, 1.13) +AM_CONFIG_HEADER(config.h) + +# Checks for programs. +# AC_PROG_CC + +# Checks for libraries. +AC_PROG_RANLIB +AC_PROG_LIBTOOL + +# Checks for header files. +AC_HEADER_STDC +AC_CHECK_HEADERS([stdlib.h string.h]) + +# Checks for typedefs, structures, and compiler characteristics. +AC_C_CONST +AC_STRUCT_TM + +# Checks for library functions. +AC_FUNC_MKTIME +AC_FUNC_STAT +AC_CHECK_FUNCS([atexit memset strstr]) + +AC_OUTPUT([Makefile src/Makefile vformat/Makefile test/Makefile doc/Makefile]) +AC_CONFIG_FILES([]) + diff --git a/doc/Makefile.am b/doc/Makefile.am new file mode 100644 index 0000000..57591c5 --- /dev/null +++ b/doc/Makefile.am @@ -0,0 +1,16 @@ +# No automatisation found. Write me if any idea. + +install-data-hook: + c2man -P "gcc -E -C -I.." ../vformat/vf_iface.h + + $(mkinstalldirs) $(mandir)/man3 + + for i in *.3; do \ + if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \ + else file=$$i; fi; \ + ext=`echo $$i | sed -e 's/^.*\\.//'`; \ + inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ + inst=`echo $$inst | sed '$(transform)'`.$$ext; \ + echo " $(INSTALL_DATA) $$file $(mandir)/man3/$$inst"; \ + $(INSTALL_DATA) $$file $(mandir)/man3/$$inst; \ + done diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 0000000..19b2d85 --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,11 @@ +lib_LTLIBRARIES = libvformat.la + +libvformat_la_SOURCES = vf_access.c vf_malloc.c vf_strings.c vf_access_wrappers.c \ + vf_parser.c vf_writer.c vf_create_object.c \ + vf_access_calendar.c vf_reader.c vf_delete.c \ + vf_search.c vf_malloc_stdlib.c vf_modified.c vf_string_arrays.c + +EXTRA_DIST = *.h + +libvformat_la_LDFLAGS = -version-info 0 + diff --git a/src/vf_access.c b/src/vf_access.c new file mode 100644 index 0000000..7504150 --- /dev/null +++ b/src/vf_access.c @@ -0,0 +1,661 @@ +/**************************************************************************** + + (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 + $Revision: 1.23 $ + $Author: tilda $ + +ORIGINAL AUTHOR + Nick Marley + +DESCRIPTION + Core access functions for VF_OBJECT_Ts. The library includes other access + functions (see vf_access_wrappers.c) which are often just alternative slightly + higher level versions of what's found below. + + The intention is to provide a basic interface which covers all the required + functionality and also some quick'n'easy functions which can be used but don't + bloat the code (in a static library build anyway). + +REFERENCES + (none) + +MODIFICATION HISTORY + * $Log: vf_access.c,v $ + * Revision 1.23 2002/11/03 18:43:16 tilda + * IID619851 - Update and check headers and function prototypes. + * + * Revision 1.22 2002/11/02 18:29:26 tilda + * IID485157 - UI does character conversion based on CHARSET property. + * + * Revision 1.21 2002/11/02 08:56:17 tilda + * Start of internationalisation changes. + * + * Revision 1.20 2002/10/26 16:09:24 tilda + * IID629125 - Ensure string functions used are portable. + * + * Revision 1.19 2002/10/08 21:45:06 tilda + * IID620473 - reduce c-runtime dependencies. + * + * Revision 1.18 2002/10/08 21:11:36 tilda + * Remove common.h. + * + * Revision 1.17 2002/02/24 17:10:34 tilda + * Add API for "is modified" functionality. + * + * Revision 1.16 2002/01/06 16:18:48 tilda + * Add dialog box for events / todos. + * + * Revision 1.15 2001/11/18 21:45:58 tilda + * Ensure parameters changed to QP are updated correctly. + * + * Revision 1.14 2001/11/17 17:40:29 tilda + * Image / sound dialog box now works. + * + * Revision 1.13 2001/11/05 21:07:20 tilda + * Various changes for initial version of vfedit. + * + * Revision 1.12 2001/10/24 18:36:06 tilda + * BASE64 bugfixes. Split reader/writer code. Start create/modify work. + * + * Revision 1.11 2001/10/24 05:30:39 tilda + * Start work on object create/modify API. + * + * Revision 1.10 2001/10/16 05:50:53 tilda + * Debug support for lists of vobjects from single file (ie. a phonebook). + * + * Revision 1.9 2001/10/14 20:42:37 tilda + * Addition of group searching. + * + * Revision 1.8 2001/10/14 16:40:05 tilda + * Initial testing of access functions. + * + * Revision 1.7 2001/10/13 16:22:08 tilda + * Introduce VBINDATA_T and VOBJDATA_T to tidy up internals. + * + * Revision 1.6 2001/10/13 14:58:56 tilda + * Tidy up version headers, add vf_strings.h where needed. + * + * Revision 1.5 2001/10/13 14:49:30 tilda + * Add string array code to unify handling of names / values. + * + * Revision 1.4 2001/10/12 16:20:03 tilda + * Correctly parse compound quoted printable properties. + * + * Revision 1.3 2001/10/10 20:53:56 tilda + * Various minor tidy ups. + * + * Revision 1.2 2001/10/09 22:01:59 tilda + * Remove older version control comments. + * + *****************************************************************************/ + +#ifndef NORCSID +static const char vf_access_c_vss_id[] = "$Header: /cvsroot/vformat/src/vformat/src/vf_access.c,v 1.23 2002/11/03 18:43:16 tilda Exp $"; +#endif + +/*============================================================================* + ANSI C & System-wide Header Files + *============================================================================*/ + +#include + +/*===========================================================================* + Interface Header Files + *===========================================================================*/ + +#include "vformat/vf_iface.h" + +/*===========================================================================* + Local Header File + *===========================================================================*/ + +#include "vf_config.h" +#include "vf_malloc.h" +#include "vf_internals.h" +#include "vf_strings.h" +#include "vf_string_arrays.h" +#include "vf_modified.h" + +/*===========================================================================* + Public Data + *===========================================================================*/ +/* None */ + +/*===========================================================================* + Private Defines + *===========================================================================*/ + +#define MAXINCREMENT (5) +#define MAXNUMTAGS (10) + +/*===========================================================================* + Private Data Types + *===========================================================================*/ +/* None */ + +/*===========================================================================* + Private Function Prototypes + *===========================================================================*/ + +static bool_t strings_valid_index( + VPROP_T *p_vprop, /* The property */ + uint32_t n_string /* Index required */ + ); + +static bool_t ensure_value_encoding_tag( + VPROP_T *p_vprop, /* The property */ + vf_encoding_t encoding /* Encoding required */ + ); + +static bool_t set_prop_value_string( + VPROP_T *p_vprop, /* The property */ + uint32_t n_string, /* Index required */ + const char *p_string /* String required */ + ); + +static bool_t set_prop_value_base64( + VPROP_T *p_vprop, /* The property */ + const uint8_t *p_data, /* Pointer to the binary data */ + uint32_t length, /* Length of the binary data */ + bool_t copy /* Copy or keep pointer */ + ); + + + + +/*===========================================================================* + Private Data + *===========================================================================*/ +/* None */ + +/*===========================================================================* + Public Function Implementations + *===========================================================================*/ + + +/*---------------------------------------------------------------------------* + * NAME + * vf_get_prop_name() + * + * DESCRIPTION + * Build the property name string in the indicated buffer. + * + * RETURNS + * (none) + *---------------------------------------------------------------------------*/ + +void vf_get_prop_name( + VF_PROP_T *p_prop, /* The property */ + char *p_buffer, /* The buffer */ + uint32_t bufsize /* Size of the buffer */ + ) +{ + VPROP_T *p_vprop = (VPROP_T *)p_prop; + uint32_t i; + + if (p_vprop->p_group) + { + p_strcpy(p_buffer, p_vprop->p_group); + p_strcat(p_buffer, "."); + } + else + { + p_buffer[0] = '\0'; + } + + for (i = 0;i < p_vprop->name.n_strings;i++) + { + if (0 < i) + p_strcat(p_buffer, ";"); + + if (p_vprop->name.pp_strings[i]) + { + p_strcat(p_buffer, p_vprop->name.pp_strings[i]); + } + } +} + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_get_object_type() + * + * DESCRIPTION + * Return the type string identifying the indicated vformat object. + * + * RETURNS + * Ptr to string. + *---------------------------------------------------------------------------*/ + +const char *vf_get_object_type( + VF_OBJECT_T *p_object + ) +{ + const char *p_ret = NULL; + + if (p_object) + { + p_ret = ((VOBJECT_T *)p_object)->p_type; + } + + return p_ret; +} + + + + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_get_prop_value() + * + * DESCRIPTION + * Get hold of raw fields associated with the property. These are of + * various types: + * + * VF_ENC_VOBJECT + * - *pp_value = pointer to contained VF_OBJECT_T which can be + * passed back to any of the object manipulation functions. + * + * VF_ENC_7BIT, VF_ENC_QUOTEDPRINTABLE + * - *pp_value = ptr to array of char*, *p_size = number of elts. + * + * VF_ENC_8BIT, VF_BASE64 + * - *pp_value = ptr to bytes, *p_size = number of bytes + * + * RETURNS + * TRUE <=> encoding is valid, FALSE else. + *---------------------------------------------------------------------------*/ + +bool_t vf_get_prop_value( + VF_PROP_T *p_prop, /* The property */ + void **pp_value, /* Pointer value */ + uint32_t *p_size, /* Integer value */ + vf_encoding_t *p_encoding /* Type of return values */ + ) +{ + VPROP_T *p_vprop = (VPROP_T *)p_prop; + bool_t ret = TRUE; + + switch (p_vprop->value.encoding) + { + case VF_ENC_VOBJECT: + if (pp_value) + { + *pp_value = p_vprop->value.v.o.p_object; + } + break; + + case VF_ENC_7BIT: + case VF_ENC_QUOTEDPRINTABLE: + if (pp_value) + { + *pp_value = p_vprop->value.v.s.pp_strings; + } + if (p_size) + { + *p_size = p_vprop->value.v.s.n_strings; + } + break; + + case VF_ENC_8BIT: + case VF_ENC_BASE64: + if (pp_value) + { + *pp_value = p_vprop->value.v.b.p_buffer; + } + if (p_size) + { + *p_size = p_vprop->value.v.b.n_bufsize; + } + break; + + default: + ret = FALSE; + break; + } + + if (p_encoding) + { + *p_encoding = p_vprop->value.encoding; + } + + return ret; +} + + + + + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_set_prop_value() + * + * DESCRIPTION + * Set values associated with a property. + * + * Passing a value of encoding not the same as the current property + * encoding will cause the property contents to be freed prior to + * setting the indicated value. + * + * RETURNS + * TRUE <=> re-allocation success & encoding correct, FALSE else. + *---------------------------------------------------------------------------*/ + +bool_t vf_set_prop_value( + VF_PROP_T *p_prop, /* The property */ + void *p_value, /* Pointer to the data */ + uint32_t n_param, /* Data size or index */ + vf_encoding_t encoding, /* Encoding in use */ + bool_t copy /* Copy the data? */ + ) +{ + VPROP_T *p_vprop = (VPROP_T *)p_prop; + bool_t ret = TRUE; + + if (!copy) + return FALSE; + + if (encoding == p_vprop->value.encoding) + { + /* Leave it as is */ + } + else + { + delete_prop_contents(p_prop, FALSE); + + ensure_value_encoding_tag(p_vprop, encoding); + } + + switch (p_vprop->value.encoding) + { + case VF_ENC_VOBJECT: + { + if (p_vprop->value.v.o.p_object != p_value) + { + mark_property_modified(p_vprop, TRUE); + } + + p_vprop->value.v.o.p_object = p_value; + } + break; + + case VF_ENC_7BIT: + case VF_ENC_QUOTEDPRINTABLE: + { + ret = set_prop_value_string(p_vprop, n_param, p_value); + } + break; + + case VF_ENC_8BIT: + case VF_ENC_BASE64: + { + ret = set_prop_value_base64(p_vprop, p_value, n_param, copy); + } + break; + + default: + ret = FALSE; + break; + } + + return ret; +} + + + + + + + +/*===========================================================================* + Private Function Implementations + *===========================================================================*/ + + + + +/*---------------------------------------------------------------------------* + * NAME + * set_prop_value_string() + * + * DESCRIPTION + * Set the value of a property. + * + * RETURNS + * TRUE <=> set successfully. + *---------------------------------------------------------------------------*/ + +bool_t set_prop_value_string( + VPROP_T *p_vprop, + uint32_t n_string, + const char *p_string + ) +{ + bool_t ret = FALSE; + + if (strings_valid_index(p_vprop, n_string)) + { + if ((p_vprop->value.v.s.pp_strings[n_string] && !p_string) || + (!p_vprop->value.v.s.pp_strings[n_string] && p_string) || + (p_vprop->value.v.s.pp_strings[n_string] && p_string && + p_stricmp(p_vprop->value.v.s.pp_strings[n_string], p_string))) + { + mark_property_modified(p_vprop, TRUE); + } + + ret = set_string_array_entry(&(p_vprop->value.v.s), p_string, n_string); + } + + return ret; +} + + + + +/*---------------------------------------------------------------------------* + * NAME + * set_prop_value_base64() + * + * DESCRIPTION + * Set the value of a property. + * + * RETURNS + * TRUE <=> set successfully. + *---------------------------------------------------------------------------*/ + +bool_t set_prop_value_base64( + VPROP_T *p_vprop, + const uint8_t *p_data, /* Pointer to the binary data */ + uint32_t length, /* Length of the binary data */ + bool_t copy /* Copy or keep pointer */ + ) +{ + bool_t ret = FALSE; + + if (copy) + { + p_vprop->value.v.b.p_buffer = vf_malloc(length); + + if (p_vprop->value.v.b.p_buffer) + { + p_memcpy(p_vprop->value.v.b.p_buffer, p_data, length); + p_vprop->value.v.b.n_bufsize = length; + + ret = TRUE; + } + } + else + { + /* TBD */ + } + + return ret; +} + + + + + + + +/*---------------------------------------------------------------------------* + * NAME + * strings_valid_index() + * + * DESCRIPTION + * Check request for indicated string. If it's either in the current + * object or represents a reasonable exapansion the request is allowed. + * + * RETURNS + * TRUE <=> object can include indicated string. + *---------------------------------------------------------------------------*/ + +bool_t strings_valid_index( + VPROP_T *p_vprop, + uint32_t n_string + ) +{ + bool_t ret = FALSE; + + if (n_string < p_vprop->value.v.s.n_strings) + { + /* String in current extent of object */ + + ret = TRUE; + } + else + if ((p_vprop->value.v.s.n_strings <= n_string) && (n_string < p_vprop->value.v.s.n_strings + MAXINCREMENT)) + { + /* Set string within reasonable expansion of object */ + + void *p_tmp = vf_realloc(p_vprop->value.v.s.pp_strings, (1 + n_string) * sizeof(char *)); + + if (p_tmp) + { + uint32_t i; + + p_vprop->value.v.s.pp_strings = p_tmp; + + for (i = p_vprop->value.v.s.n_strings;i < (uint32_t)(1 + n_string);i++) + { + p_vprop->value.v.s.pp_strings[i] = NULL; + } + + p_vprop->value.v.s.n_strings = (1 + n_string); + + ret = TRUE; + } + } + else + { + /* Invalid request */ + } + + return ret; +} + + + + + +/*---------------------------------------------------------------------------* + * NAME + * ensure_value_encoding_tag() + * + * DESCRIPTION + * Check/set encoding. + * + * RETURNS + * TRUE <=> encoding was set successfully. + *---------------------------------------------------------------------------*/ + +bool_t ensure_value_encoding_tag( + VPROP_T *p_vprop, + vf_encoding_t encoding + ) +{ + int n; + uint32_t i; + bool_t ret = TRUE; + + /* + * Locate the encoding value. + */ + for (i = 0, n = (-1);n == (-1) && (i < p_vprop->name.n_strings);i++) + { + const char *p_string = p_vprop->name.pp_strings[i]; + + if (p_string) + { + if (p_stristr(p_string, VFP_ENCODING) + || p_stristr(p_string, VFP_QUOTEDPRINTABLE) + || p_stristr(p_string, VFP_BASE64) + || p_stristr(p_string, VFP_8BIT) + || p_stristr(p_string, VFP_7BIT)) + { + n = i; + } + } + } + + /* + * Remove previous encoding + */ + if (0 <= n) + { + ret = set_string_array_entry(&(p_vprop->name), NULL, n); + } + + if (ret) + { + char *p_enc_string; + + switch (encoding) + { + case VF_ENC_QUOTEDPRINTABLE: + p_enc_string = VFP_QUOTEDPRINTABLE; + break; + + case VF_ENC_BASE64: + p_enc_string = VFP_BASE64; + break; + + default: + p_enc_string = NULL; + } + + if (p_enc_string) + { + if ((-1) == n) + { + ret = add_string_to_array(&(p_vprop->name), p_enc_string); + } + else + { + ret = set_string_array_entry(&(p_vprop->name), p_enc_string, n); + } + } + } + + if (ret) + { + p_vprop->value.encoding = encoding; + } + + return ret; +} + + +/*===========================================================================* + End Of File + *===========================================================================*/ diff --git a/src/vf_access_calendar.c b/src/vf_access_calendar.c new file mode 100644 index 0000000..159c432 --- /dev/null +++ b/src/vf_access_calendar.c @@ -0,0 +1,528 @@ +/**************************************************************************** + + (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 + Wrappers on the core access functions & other utility functions. + +REFERENCES + (none) + +MODIFICATION HISTORY + * $Log: vf_access_calendar.c,v $ + * Revision 1.7 2002/11/24 14:26:22 tilda + * IID484686 - More vcard work. + * + * Revision 1.6 2002/11/15 09:15:00 tilda + * IID638823 - Various portability issues. + * + * Revision 1.5 2002/11/03 18:43:16 tilda + * IID619851 - Update and check headers and function prototypes. + * + * Revision 1.4 2002/10/26 16:09:24 tilda + * IID629125 - Ensure string functions used are portable. + * + * Revision 1.3 2002/10/08 21:45:07 tilda + * IID620473 - reduce c-runtime dependencies. + * + * Revision 1.2 2002/10/08 21:11:36 tilda + * Remove common.h. + * + * Revision 1.1 2002/01/06 16:18:48 tilda + * Add dialog box for events / todos. + * + *****************************************************************************/ + +#ifndef NORCSID +static const char vf_access_calendar_c_vss_id[] = "$Header: /cvsroot/vformat/src/vformat/src/vf_access_calendar.c,v 1.7 2002/11/24 14:26:22 tilda Exp $"; +#endif + +/*============================================================================* + ANSI C & System-wide Header Files + *============================================================================*/ + +#include + +#include +#include +#include + +/*===========================================================================* + Interface Header Files + *===========================================================================*/ + +#include "vformat/vf_iface.h" + +/*===========================================================================* + Local Header File + *===========================================================================*/ + +#include "vf_config.h" +#include "vf_malloc.h" +#include "vf_internals.h" +#include "vf_strings.h" +#include "vf_string_arrays.h" + +/*===========================================================================* + Public Data + *===========================================================================*/ +/* None */ + +/*===========================================================================* + Private Defines + *===========================================================================*/ + +#define ISO8061_TOKEN_YEARS 'Y' +#define ISO8061_TOKEN_MONTHS 'M' +#define ISO8061_TOKEN_WEEKS 'W' +#define ISO8061_TOKEN_DAYS 'D' +#define ISO8061_TOKEN_HOURS 'H' +#define ISO8061_TOKEN_MINUTES 'M' +#define ISO8061_TOKEN_SECONDS 'S' + +#define ISO8061_TOKEN_TIME 'T' +#define ISO8061_TOKEN_PERIOD 'P' + +/*===========================================================================* + Private Data Types + *===========================================================================*/ +/* None */ + +/*===========================================================================* + Private Function Prototypes + *===========================================================================*/ + +static void append_iso8061_value(char *p_string, uint32_t value, char symbol); +static void append_iso8061_tag(char *p_string, char symbol); + +/*===========================================================================* + Private Data + *===========================================================================*/ +/* None */ + +/*===========================================================================* + Public Function Implementations + *===========================================================================*/ + + +/*---------------------------------------------------------------------------* + * NAME + * vf_set_prop_value_time() + * + * DESCRIPTION + * Set a time_t value into a VF property. + * + * RETURNS + * TRUE iff property added & set OK. + *---------------------------------------------------------------------------*/ + +bool_t vf_set_prop_value_time( + VF_PROP_T *p_prop, /* The property */ + uint32_t n_string, /* Which string we're encoding to */ + const time_t t_value /* Time value */ + ) +{ + bool_t ret; + struct tm *p_tm; + + p_tm = localtime(&t_value); + + if (p_tm) + { + char value[256]; + + if (p_tm->tm_hour || p_tm->tm_min || p_tm->tm_sec) + { + sprintf(value, "%4d%02d%02dT%02d%02d%02d", + 1900 + p_tm->tm_year, + 1 + p_tm->tm_mon, + p_tm->tm_mday, + p_tm->tm_hour, + p_tm->tm_min, + p_tm->tm_sec); + } + else + { + sprintf(value, "%4d%02d%02d", + 1900 + p_tm->tm_year, + 1 + p_tm->tm_mon, + p_tm->tm_mday); + } + + ret = vf_set_prop_value_string(p_prop, n_string, value); + } + else + { + ret = FALSE; + } + + return ret; +} + + + + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_get_prop_value_time() + * + * DESCRIPTION + * Fetch a time_t value from a VF property. + * + * RETURNS + * TRUE iff foudn & converted OK. + *---------------------------------------------------------------------------*/ + +bool_t vf_get_prop_value_time( + VF_PROP_T *p_prop, /* The property */ + uint32_t n_string, /* Which string we're decoding */ + time_t *p_t_value /* Pointer to output time value */ + ) +{ + bool_t ret; + const char *p_value; + + p_value = vf_get_prop_value_string(p_prop, n_string); + + if (p_value) + { + ret = vf_date_string_to_time(p_t_value, p_value); + } + else + { + ret = FALSE; + } + + return ret; +} + + + + + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_date_string_to_time() + * + * DESCRIPTION + * Convert calendar string to absolute time. The basic formats are + * 19960401, 19960401T073000Z + * + * RETURNS + * TRUE <=> conversion OK, FALSE else. + *---------------------------------------------------------------------------*/ + +bool_t vf_date_string_to_time( + uint32_t *p_time, /* Output time value */ + const char *p_string /* Input string */ + ) +{ + bool_t ret = FALSE; + + if (p_string && p_time) + { + time_t t; + struct tm tm; + + p_memset(&tm, '\0', sizeof(tm)); + + /* + * p_string[8] is either 'T' or '\0' or an error. + */ + + if (ISO8061_TOKEN_TIME == p_string[8]) + { + if (6 == sscanf(p_string, "%4d%2d%2dT%2d%2d%2d", + &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec)) + { + if ((1970 <= tm.tm_year) && + ((1 <= tm.tm_mon) && (tm.tm_mon <= 12)) && + ((1 <= tm.tm_mday) && (tm.tm_mday <= 28)) && + ((0 <= tm.tm_hour) && (tm.tm_hour <= 23)) && + ((0 <= tm.tm_min) && (tm.tm_hour <= 59)) && + ((0 <= tm.tm_sec) && (tm.tm_sec <= 59))) + { + ret = TRUE; + } + } + } + else + if ('\0' == p_string[8]) + { + if (3 == sscanf(p_string, "%4d%2d%2d", + &tm.tm_year, &tm.tm_mon, &tm.tm_mday)) + { + if ((1970 <= tm.tm_year) && + ((1 <= tm.tm_mon) && (tm.tm_mon <= 12)) && + ((1 <= tm.tm_mday) && (tm.tm_mday <= 28))) + { + ret = TRUE; + } + } + } + else + { + /* Nor flesh nor fish nor fowl */ + } + + /* + * Reduce the year value to correct range & convert to time_t. + */ + + if (ret) + { + tm.tm_mon -= 1; + tm.tm_year -= 1900; + tm.tm_isdst = -1; + + t = mktime(&tm); + + if ((-1) == t) + { + ret = FALSE; + } + else + { + *p_time = (uint32_t)t; + } + } + } + + return ret; +} + + + + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_period_string_to_time() + * + * DESCRIPTION + * Convert period definition string to time value. The format is + * P[aaaY][bbbM][cccW][dddD]T[eeeH][fffM][gggS] where 'aaa' is a + * number of years, bbb months etc. + * + * RETURNS + * TRUE <=> conversion OK, FALSE else. + *---------------------------------------------------------------------------*/ + +bool_t vf_period_string_to_time( + VF_ISO8601_PERIOD_T *p_period, /* Output time value */ + const char *p_string /* Input string */ + ) +{ + bool_t ret = TRUE; + bool_t in_time_part = FALSE; + + p_memset(p_period, '\0', sizeof(*p_period)); + + if (p_string && ('P' == p_string[0]) && *(++p_string)) + { + while (ret && *p_string) + { + uint32_t value = 0; + + while (isdigit((int)*p_string)) + { + value = (value * 10) + *(p_string++) - '0'; + } + + switch (*p_string++) + { + case '\0': + { + ret = FALSE; + } + break; + + case ISO8061_TOKEN_YEARS: + { + p_period->years = value; + } + break; + + case ISO8061_TOKEN_MONTHS: + /*case ISO8061_TOKEN_MINUTES:*/ + { + if (in_time_part) + { + p_period->minutes = value; + } + else + { + p_period->months = value; + } + } + break; + + case ISO8061_TOKEN_WEEKS: + { + p_period->weeks = value; + } + break; + + case ISO8061_TOKEN_DAYS: + { + p_period->days = value; + } + break; + + case ISO8061_TOKEN_TIME: + { + if (in_time_part) + { + ret = FALSE; + } + else + { + in_time_part = TRUE; + } + } + break; + + case ISO8061_TOKEN_HOURS: + { + p_period->hours = value; + } + break; + + case ISO8061_TOKEN_SECONDS: + { + p_period->seconds = value; + } + break; + + default: + { + ret = FALSE; + } + break; + } + } + } + else + { + ret = FALSE; + } + + return ret; +} + + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_period_time_to_string() + * + * DESCRIPTION + * Convert a VF_ISO8601_PERIOD_T to a string. + * + * RETURNS + * Number of characters written. + *---------------------------------------------------------------------------*/ + +uint32_t vf_period_time_to_string( + char *p_string, /* Output string */ + const VF_ISO8601_PERIOD_T *p_period /* Input period value */ + ) +{ + uint32_t ret = 0; + + if (p_string && p_period) + { + p_string[0] = '\0'; + + append_iso8061_tag(p_string, ISO8061_TOKEN_PERIOD); + + append_iso8061_value(p_string, p_period->years, ISO8061_TOKEN_YEARS); + append_iso8061_value(p_string, p_period->months, ISO8061_TOKEN_MONTHS); + append_iso8061_value(p_string, p_period->weeks, ISO8061_TOKEN_WEEKS); + append_iso8061_value(p_string, p_period->days, ISO8061_TOKEN_DAYS); + + if (p_period->hours || p_period->minutes || p_period->seconds) + { + append_iso8061_tag(p_string, ISO8061_TOKEN_TIME); + } + + append_iso8061_value(p_string, p_period->hours, ISO8061_TOKEN_HOURS); + append_iso8061_value(p_string, p_period->minutes, ISO8061_TOKEN_MINUTES); + append_iso8061_value(p_string, p_period->seconds, ISO8061_TOKEN_SECONDS); + + ret = p_strlen(p_string); + } + + return ret; +} + + + +/*===========================================================================* + Private Function Implementations + *===========================================================================*/ + + + +/*---------------------------------------------------------------------------* + * NAME + * append_iso8061_value() + * + * DESCRIPTION + * Append xxxY value to the current encoded string. + * + * RETURNS + * (none) + *---------------------------------------------------------------------------*/ + +void append_iso8061_value(char *p_string, uint32_t value, char symbol) +{ + if (value) + { + sprintf(p_string + p_strlen(p_string), "%lu%c", (unsigned long)value, symbol); + } +} + + + + +/*---------------------------------------------------------------------------* + * NAME + * append_iso8061_tag() + * + * DESCRIPTION + * Append indicated character to string. + * + * RETURNS + * (none). + *---------------------------------------------------------------------------*/ + +void append_iso8061_tag(char *p_string, char symbol) +{ + p_string += p_strlen(p_string); + + *p_string++ = symbol; + *p_string++ = '\0'; +} + + +/*===========================================================================* + End Of File + *===========================================================================*/ diff --git a/src/vf_access_wrappers.c b/src/vf_access_wrappers.c new file mode 100644 index 0000000..2eea457 --- /dev/null +++ b/src/vf_access_wrappers.c @@ -0,0 +1,541 @@ +/**************************************************************************** + + (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.16 $ + $Author: tilda $ + +ORIGINAL AUTHOR + Nick Marley + +DESCRIPTION + Wrappers on the core access functions & other utility functions. + +REFERENCES + (none) + +MODIFICATION HISTORY + * $Log: vf_access_wrappers.c,v $ + * Revision 1.16 2002/11/16 13:19:10 tilda + * IID639288 - Implement method for adding subobjects. + * + * Revision 1.15 2002/11/03 18:43:16 tilda + * IID619851 - Update and check headers and function prototypes. + * + * Revision 1.14 2002/11/02 18:29:26 tilda + * IID485157 - UI does character conversion based on CHARSET property. + * + * Revision 1.13 2002/10/26 16:09:24 tilda + * IID629125 - Ensure string functions used are portable. + * + * Revision 1.12 2002/10/08 21:45:07 tilda + * IID620473 - reduce c-runtime dependencies. + * + * Revision 1.11 2002/10/08 21:11:36 tilda + * Remove common.h. + * + * Revision 1.10 2001/11/18 22:07:02 tilda + * Ensure empty BASE64 properties get the encoding set correctly. + * + * Revision 1.9 2001/11/18 21:48:18 tilda + * Remove redundant code. + * + * Revision 1.8 2001/11/17 17:40:29 tilda + * Image / sound dialog box now works. + * + * Revision 1.7 2001/11/16 22:34:50 tilda + * New vf_get_property() allows append as well as find, + * + * Revision 1.6 2001/11/15 08:56:06 tilda + * Fix bug in qualifier location code. + * + * Revision 1.5 2001/11/14 22:36:56 tilda + * Add parameter to vf_find_prop_qual_index() + * + * Revision 1.4 2001/11/14 16:05:06 tilda + * Extend capabilities of vf_find_prop_qual_index(). + * + * Revision 1.3 2001/11/06 22:51:05 tilda + * Supporting access functions for image selection / deletion. + * + * Revision 1.2 2001/10/24 18:56:29 tilda + * Tidy headers after import. Fix include path in release build. + * + * Revision 1.1 2001/10/24 18:34:35 tilda + * Initial Version. + * + *****************************************************************************/ + +#ifndef NORCSID +static const char vf_access_wrappers_c_vss_id[] = "$Header: /cvsroot/vformat/src/vformat/src/vf_access_wrappers.c,v 1.16 2002/11/16 13:19:10 tilda Exp $"; +#endif + +/*============================================================================* + ANSI C & System-wide Header Files + *============================================================================*/ + +#include + +/*===========================================================================* + Interface Header Files + *===========================================================================*/ + +#include "vformat/vf_iface.h" + +/*===========================================================================* + Local Header File + *===========================================================================*/ + +#include "vf_config.h" +#include "vf_malloc.h" +#include "vf_internals.h" +#include "vf_strings.h" +#include "vf_string_arrays.h" + +/*===========================================================================* + Public Data + *===========================================================================*/ +/* None */ + +/*===========================================================================* + Private Defines + *===========================================================================*/ +/* None */ + +/*===========================================================================* + Private Data Types + *===========================================================================*/ +/* None */ + +/*===========================================================================* + Private Function Prototypes + *===========================================================================*/ +/* None */ + +/*===========================================================================* + Private Data + *===========================================================================*/ +/* None */ + +/*===========================================================================* + Public Function Implementations + *===========================================================================*/ + +bool_t vf_prop_belongs_to_object( + VF_PROP_T *p_prop, + VF_OBJECT_T *p_object + ); + + +/*---------------------------------------------------------------------------* + * NAME + * vf_get_prop_value_string() + * + * DESCRIPTION + * Obtain string pointer value from VF_PROP_T. If the array contains + * an entry for the indicated string return it. Return NULL if out of + * range request, ie. n_string=3 for N=0;1;2 + * + * RETURNS + * Pointer to string value if value present, NULL if index too large. + *---------------------------------------------------------------------------*/ + +char *vf_get_prop_value_string( + VF_PROP_T *p_prop, + uint32_t n_string + ) +{ + VPROP_T *p_vprop = (VPROP_T *)p_prop; + char *p_ret = NULL; + + if (p_vprop->value.v.s.pp_strings) + { + if (n_string < p_vprop->value.v.s.n_strings) + { + p_ret = p_vprop->value.v.s.pp_strings[n_string]; + } + } + + return p_ret; +} + + + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_set_prop_value_string() + * + * DESCRIPTION + * Set the value of a property. + * + * RETURNS + * TRUE <=> set successfully. + *---------------------------------------------------------------------------*/ + +bool_t vf_set_prop_value_string( + VF_PROP_T *p_prop, + uint32_t n_string, + const char *p_string + ) +{ + return vf_set_prop_value(p_prop, (char *)p_string, n_string, VF_ENC_7BIT, TRUE); +} + + + + + + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_get_prop_value_base64() + * + * DESCRIPTION + * Obtain data pointer for BASE64 data. + * + * RETURNS + * Pointer to data. + *---------------------------------------------------------------------------*/ + +const uint8_t *vf_get_prop_value_base64( + VF_PROP_T *p_prop, /* Property we're setting a value in */ + uint32_t *p_length /* Length of the binary data */ + ) +{ + const uint8_t *p_return = NULL; + + if (p_prop) + { + VPROP_T *p_vprop = (VPROP_T *)p_prop; + + p_return = p_vprop->value.v.b.p_buffer; + + if (p_length) + { + *p_length = p_vprop->value.v.b.n_bufsize; + } + } + + return p_return; +} + + + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_set_prop_value_base64() + * + * DESCRIPTION + * Set the value of a property. + * + * RETURNS + * TRUE <=> set successfully. + *---------------------------------------------------------------------------*/ + +bool_t vf_set_prop_value_base64( + VF_PROP_T *p_prop, /* Property we're setting a value in */ + const uint8_t *p_data, /* Pointer to the binary data */ + uint32_t length, /* Length of the binary data */ + bool_t copy /* Copy or keep pointer */ + ) +{ + return vf_set_prop_value(p_prop, (char *)p_data, length, VF_ENC_BASE64, copy); +} + + + + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_get_prop_value_object() + * + * DESCRIPTION + * Obtain object pointer value from VF_PROP_T. + * + * RETURNS + * Pointer to vobject value (or NULL if not found). + *---------------------------------------------------------------------------*/ + +VF_OBJECT_T *vf_get_prop_value_object( + VF_PROP_T *p_prop + ) +{ + VPROP_T *p_vprop = (VPROP_T *)p_prop; + + if (VF_ENC_VOBJECT == p_vprop->value.encoding) + { + return (VF_OBJECT_T *)(p_vprop->value.v.o.p_object); + } + + return NULL; +} + + + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_set_prop_value_object() + * + * DESCRIPTION + * Set the value of the indicated property to be a VOBJECT. + * + * RETURNS + * TRUE <=> set successfully. + *---------------------------------------------------------------------------*/ + +bool_t vf_set_prop_value_object( + VF_PROP_T *p_prop, + VF_OBJECT_T *p_object + ) +{ + VPROP_T *p_vprop = (VPROP_T *)p_prop; + bool_t ret = FALSE; + + /* + * Avoid various sillies. + */ + if (p_prop && p_object && !vf_prop_belongs_to_object(p_prop, p_object)) + { + delete_prop_contents(p_prop, FALSE); + + p_vprop->value.v.o.p_object = (VOBJECT_T *)p_object; + p_vprop->value.encoding = VF_ENC_VOBJECT; + } + + return TRUE; +} + + + + + + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_get_prop_name_string() + * + * DESCRIPTION + * Get n'th name string. + * + * RETURNS + * Pointer to string value if value present, NULL if index too large. + *---------------------------------------------------------------------------*/ + +char *vf_get_prop_name_string( + VF_PROP_T *p_prop, + uint32_t n_string + ) +{ + VPROP_T *p_vprop = (VPROP_T *)p_prop; + char *p_ret = NULL; + + if (p_vprop->name.pp_strings) + { + if (n_string < p_vprop->name.n_strings) + { + p_ret = p_vprop->name.pp_strings[n_string]; + } + } + + return p_ret; +} + + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_set_prop_name_string() + * + * DESCRIPTION + * Set n'th name string. + * + * RETURNS + * TRUE iff allocation OK, FALSE else. + *---------------------------------------------------------------------------*/ + +bool_t vf_set_prop_name_string( + VF_PROP_T *p_prop, /* Property we're setting a value in */ + uint32_t n_string, /* Index to string */ + const char *p_string /* Pointer to string */ + ) +{ + VPROP_T *p_vprop; + bool_t ret = FALSE; + + p_vprop = (VPROP_T *)p_prop; + + if (p_vprop) + { + if ((-1) == n_string) + { + ret = add_string_to_array(&p_vprop->name, p_string); + } + else + { + ret = set_string_array_entry(&p_vprop->name, p_string, n_string); + } + } + + return TRUE; +} + + + + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_find_prop_qual_index() + * + * DESCRIPTION + * Locate property qualifier given either an array of possible values + * or a single token that is either present or absent. For example + * if we have a property: + * + * NAME;THIRD;TIME;LUCKY:VALUE1;VALUE2;VALUE3 + * + * Then there are two possible searches. + * + * Firstly we can look for the property qualifier which can take values + * from the array { "FIRST", "SECOND", THIRD" } in which case the array + * is passed as pp_possible_values and the function returns with the + * values *p_found_value_index=2, p_qualifier_index=1 + * + * Secondly we can look for the token with value "TIME" in which case + * p_token is set to "TIME" and the function returns *p_qualifier_index=2. + * + * RETURNS + * TRUE iff found, FALSE else. + *---------------------------------------------------------------------------*/ + +bool_t vf_find_prop_qual_index( + VF_PROP_T *p_prop, /* The property we're querying */ + uint32_t *p_qualifier_index, /* Ptr to output name index */ + uint32_t *p_found_value_index, /* Ptr to output index in array */ + const char **pp_possible_values, /* Array of possible values */ + const char *p_token, /* Token searched for */ + vf_search_flags_t match /* String comparison flags */ + ) +{ + uint32_t n; + bool_t ret; + + VPROP_T *p_vprop = (VPROP_T *)p_prop; + + for (n = 0, ret = FALSE;!ret && (n < p_vprop->name.n_strings);n++) + { + const char *p_string = p_vprop->name.pp_strings[n]; + + if (p_string) + { + if (pp_possible_values) + { + uint32_t i; + + for (i = 0;!ret && pp_possible_values[i];i++) + { + if (0 == p_stricmp(pp_possible_values[i], p_string)) + { + if (p_found_value_index) + *p_found_value_index = i; + if (p_qualifier_index) + *p_qualifier_index = n; + + ret = TRUE; + } + } + } + else + if (p_token) + { + if (0 == p_stricmp(p_token, p_string)) + { + if (p_qualifier_index) + *p_qualifier_index = n; + + ret = TRUE; + } + } + else + { + /*???*/ + } + } + } + + return ret; +} + + + + + + +/*----------------------------------------------------------------------------* + * NAME + * vf_find_charset() + * + * DESCRIPTION + * Locate the charset + * + * RETURNS + * vf_charset_t. + *---------------------------------------------------------------------------*/ + +const char *vf_find_charset( + VF_PROP_T *p_prop + ) +{ + VPROP_T *p_vprop = (VPROP_T *)p_prop; + char *ret; + + if (!string_array_contains_string(&p_vprop->name, &ret, -1, VFP_CHARSET, FALSE)) + { + ret = NULL; + } + else + { + ret += 1 + p_strlen(VFP_CHARSET); + } + + return ret; +} + + + + + +/*===========================================================================* + Private Function Implementations + *===========================================================================*/ + +bool_t vf_prop_belongs_to_object( + VF_PROP_T *p_prop, + VF_OBJECT_T *p_object + ) +{ + return FALSE; +} + +/*===========================================================================* + End Of File + *===========================================================================*/ diff --git a/src/vf_config.h b/src/vf_config.h new file mode 100644 index 0000000..2a4ff8f --- /dev/null +++ b/src/vf_config.h @@ -0,0 +1,85 @@ +/****************************************************************************** + + (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_common.h $ + $Revision: 1.1 $ + $Author: tilda $ + +ORIGINAL AUTHOR + Nick Marley + +DESCRIPTION + Common header file for vformat library. This file is internal to vformat + (ie. changes here don't affect the interface) but contains the definitions + which affect the operation of various components eg. the memory debug. + + This file is #included before all other header files within the library. + +REFERENCES + (none) + +MODIFICATION HISTORY + * $Log: vf_config.h,v $ + * Revision 1.1 2002/10/26 15:57:11 tilda + * Initial Version + * + * + *******************************************************************************/ + +#ifndef _VF_CONFIG_H_ +#define _VF_CONFIG_H_ + +#ifndef NORCSID +static const char vf_config_h_vss_id[] = "$Header: /cvsroot/vformat/src/vformat/src/vf_config.h,v 1.1 2002/10/26 15:57:11 tilda Exp $"; +#endif + +/*=============================================================================* + Public Includes + *============================================================================*/ +/* None */ + +/*=============================================================================* + Public Defines + *============================================================================*/ + +/* + * If building debug version under windows then include the memory debug interface. + */ +#if (defined(WIN) || defined(WIN32)) && defined(_DEBUG) +#if !defined(VFORMAT_MEM_DEBUG) +#define VFORMAT_MEM_DEBUG +#endif +#endif + +/* + * Conditional compiles allowing configuration of various string portability functions. + */ +/* #define HAVE_STRLEN */ +/* #define HAVE_STRCPY */ +/* #define HAVE_STRCMP */ +/* #define HAVE_STRCAT */ +/* #define HAVE_STRSTR */ +/* #define HAVE_STRICMP */ +/* #define HAVE_MEMCPY */ +/* #define HAVE_MEMSET */ + +/*=============================================================================* + Public Types + *============================================================================*/ +/* None */ + +/*=============================================================================* + Public Functions + *============================================================================*/ +/* None */ + +/*=============================================================================* + End of file + *============================================================================*/ + +#endif /*_VF_CONFIG_H_*/ diff --git a/src/vf_create_object.c b/src/vf_create_object.c new file mode 100644 index 0000000..ab540b9 --- /dev/null +++ b/src/vf_create_object.c @@ -0,0 +1,158 @@ +/****************************************************************************** + + (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 + $Revision: 1.8 $ + $Author: tilda $ + +ORIGINAL AUTHOR + Nick Marley. + +DESCRIPTION + The vf_create_object() function. + +REFERENCES + (none) + +MODIFICATION HISTORY + * $Log: vf_create_object.c,v $ + * Revision 1.8 2002/11/16 13:19:10 tilda + * IID639288 - Implement method for adding subobjects. + * + * Revision 1.7 2002/11/03 18:43:16 tilda + * IID619851 - Update and check headers and function prototypes. + * + * Revision 1.6 2002/10/29 07:19:20 tilda + * Tidy headers. + * + * Revision 1.5 2002/10/26 16:09:24 tilda + * IID629125 - Ensure string functions used are portable. + * + * Revision 1.4 2002/10/08 21:45:07 tilda + * IID620473 - reduce c-runtime dependencies. + * + * Revision 1.3 2002/10/08 21:11:36 tilda + * Remove common.h. + * + * Revision 1.2 2002/01/06 13:11:55 tilda + * Update header. + * + * Revision 1.1 2002/01/06 13:08:15 tilda + * Change file name from vf_createobject.c + * + *******************************************************************************/ + +#ifndef NORCSID +static const char vf_create_object_c_vss_id[] = "$Header: /cvsroot/vformat/src/vformat/src/vf_create_object.c,v 1.8 2002/11/16 13:19:10 tilda Exp $"; +#endif + +/*============================================================================* + ANSI C & System-wide Header Files + *===========================================================================*/ + +#include + +/*===========================================================================* + Interface Header Files + *==========================================================================*/ + +#include "vformat/vf_iface.h" + +/*===========================================================================* + Local Header File + *==========================================================================*/ + +#include "vf_config.h" +#include "vf_malloc.h" +#include "vf_internals.h" +#include "vf_strings.h" +#include "vf_string_arrays.h" + +/*===========================================================================* + Public Data + *==========================================================================*/ +/* None */ + +/*===========================================================================* + Private Defines + *==========================================================================*/ +/* None */ + +/*===========================================================================* + Private Data Types + *==========================================================================*/ +/* None */ + +/*===========================================================================* + Private Function Prototypes + *==========================================================================*/ +/* None */ + +/*===========================================================================* + Private Data + *==========================================================================*/ +/* None */ + +/*===========================================================================* + Public Function Implementations + *==========================================================================*/ + + +/*---------------------------------------------------------------------------* + * NAME + * vf_create_object() + * + * DESCRIPTION + * Creates and empty vformat object. + * + * RETURNS + * Ptr to object if created else NULL. + *---------------------------------------------------------------------------*/ + +VF_OBJECT_T *vf_create_object( + const char *p_type, /* Type of object to create */ + VF_OBJECT_T *p_parent /* Parent object if any */ + ) +{ + VOBJECT_T *p_new = NULL; + + if (p_type) + { + p_new = vf_malloc(sizeof(VOBJECT_T)); + + if (p_new) + { + p_memset(p_new, '\0', sizeof(VOBJECT_T)); + + p_new->p_type = vf_malloc(1 + p_strlen(p_type)); + + p_new->p_parent = (VOBJECT_T *)p_parent; + + if (p_new->p_type) + { + p_strcpy(p_new->p_type, p_type); + } + else + { + vf_free(p_new); + p_new = NULL; + } + } + } + + return (VF_OBJECT_T *)p_new; +} + + +/*===========================================================================* + Private Function Implementations + *===========================================================================*/ +/* None */ + +/*===========================================================================* + End Of File + *===========================================================================*/ diff --git a/src/vf_delete.c b/src/vf_delete.c new file mode 100644 index 0000000..d70b8e4 --- /dev/null +++ b/src/vf_delete.c @@ -0,0 +1,327 @@ +/****************************************************************************** + + (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_delete.c $ + $Revision: 1.14 $ + $Author: tilda $ + +ORIGINAL AUTHOR + Nick Marley + +DESCRIPTION + Delete a vformat object. + +REFERENCES + (none) + +MODIFICATION HISTORY + * $Log: vf_delete.c,v $ + * Revision 1.14 2002/11/03 18:43:16 tilda + * IID619851 - Update and check headers and function prototypes. + * + * Revision 1.13 2002/10/26 16:09:24 tilda + * IID629125 - Ensure string functions used are portable. + * + * Revision 1.12 2002/10/08 21:45:07 tilda + * IID620473 - reduce c-runtime dependencies. + * + * Revision 1.11 2002/10/08 21:11:36 tilda + * Remove common.h. + * + * Revision 1.10 2001/11/05 21:07:20 tilda + * Various changes for initial version of vfedit. + * + * Revision 1.9 2001/10/24 18:36:06 tilda + * BASE64 bugfixes. Split reader/writer code. Start create/modify work. + * + * Revision 1.8 2001/10/14 19:53:36 tilda + * Group handling. NO group searching functions. + * + * Revision 1.7 2001/10/13 16:22:08 tilda + * Introduce VBINDATA_T and VOBJDATA_T to tidy up internals. + * + * Revision 1.6 2001/10/13 14:58:56 tilda + * Tidy up version headers, add vf_strings.h where needed. + * + * Revision 1.5 2001/10/13 14:49:30 tilda + * Add string array code to unify handling of names / values. + * + * Revision 1.4 2001/10/12 16:20:03 tilda + * Correctly parse compound quoted printable properties. + * + * Revision 1.3 2001/10/10 20:53:56 tilda + * Various minor tidy ups. + * + * Revision 1.2 2001/10/09 22:01:59 tilda + * Remove older version control comments. + * + *******************************************************************************/ + +#ifndef NORCSID +static const char vf_delete_c_vss_id[] = "$Header: /cvsroot/vformat/src/vformat/src/vf_delete.c,v 1.14 2002/11/03 18:43:16 tilda Exp $"; +#endif + +/*=============================================================================* + ANSI C & System-wide Header Files + *=============================================================================*/ + +#include + +/*============================================================================* + Interface Header Files + *============================================================================*/ + +#include "vformat/vf_iface.h" + +/*============================================================================* + Local Header File + *============================================================================*/ + +#include "vf_config.h" +#include "vf_malloc.h" +#include "vf_internals.h" +#include "vf_string_arrays.h" + +/*============================================================================* + Public Data + *============================================================================*/ +/* None */ + +/*============================================================================* + Private Defines + *============================================================================*/ +/* None */ + +/*============================================================================* + Private Data Types + *============================================================================*/ +/* None */ + +/*============================================================================* + Private Function Prototypes + *============================================================================*/ + +static void free_prop_list( + VPROP_T *p_props /* List of properties to free */ + ); + + + +/*============================================================================* + Private Data + *============================================================================*/ +/* None */ + +/*============================================================================* + Public Function Implementations + *============================================================================*/ + + + +/*----------------------------------------------------------------------------* + * NAME + * vf_delete_object() + * + * DESCRIPTION + * Cleans up the memory used by the indicated vformat object. + * + * RETURNS + * (none) + *----------------------------------------------------------------------------*/ + +void vf_delete_object( + VF_OBJECT_T *p_object, + bool_t all + ) +{ + VOBJECT_T *p_obj = (VOBJECT_T *)p_object; + + if (p_obj) + { + VOBJECT_T *p_next = p_obj->p_next; + + free_prop_list(p_obj->p_props); + + if (p_obj->p_type) + { + vf_free(p_obj->p_type); + } + + vf_free(p_obj); + + if (all ) + { + vf_delete_object((VF_OBJECT_T *)p_next, TRUE); + } + } +} + + + + +/*----------------------------------------------------------------------------* + * NAME + * vf_delete_prop() + * + * DESCRIPTION + * Deletes indicated property from the indicated object. Deletes prop + * contents if dc is set. + * + * RETURNS + * (none) + *----------------------------------------------------------------------------*/ + +void vf_delete_prop( + VF_OBJECT_T *p_object, /* The object we're deleting from */ + VF_PROP_T *p_prop, /* The property we're removing */ + bool_t dc /* Should property contents be deleted? */ + ) +{ + VOBJECT_T *p_obj = (VOBJECT_T *)p_object; + + if (p_obj) + { + VPROP_T **p_vprop = &(p_obj->p_props); + + while (*p_vprop) + { + if ((*p_vprop) == (VPROP_T *)p_prop) + { + *p_vprop = ((VPROP_T *)p_prop)->p_next; + + if (dc) + { + delete_prop_contents(p_prop, TRUE); + } + + vf_free(p_prop); + + break; + } + else + { + p_vprop = &((*p_vprop)->p_next); + } + } + } +} + + + + + +/*----------------------------------------------------------------------------* + * NAME + * delete_prop_contents() + * + * DESCRIPTION + * Cleans up the memory used by the value associated with the property. + * The property is not deleted => can be a statically allocated variable. + * + * RETURNS + * (none) + *----------------------------------------------------------------------------*/ + +void delete_prop_contents( + VF_PROP_T *p_vprop, /* The VF_PROP_T to clean */ + bool_t delname /* Delete the name as well? */ + ) +{ + VPROP_T *p_prop = (VPROP_T *)p_vprop; + + if (delname) + { + free_string_array_contents(&p_prop->name); + + if (p_prop->p_group) + { + vf_free(p_prop->p_group); + p_prop->p_group = NULL; + } + } + + if (p_prop->value.v.b.p_buffer) + { + vf_free(p_prop->value.v.b.p_buffer); + p_prop->value.v.b.p_buffer = NULL; + } + + if (p_prop->value.v.s.pp_strings) + { + uint32_t n; + + for (n = 0;n < p_prop->value.v.s.n_strings;n++) + { + if (p_prop->value.v.s.pp_strings[n]) + { + vf_free(p_prop->value.v.s.pp_strings[n]); + p_prop->value.v.s.pp_strings[n] = NULL; + } + } + + vf_free(p_prop->value.v.s.pp_strings); + p_prop->value.v.s.pp_strings = NULL; + + p_prop->value.v.s.n_strings = 0; + } + + if (p_prop->value.v.o.p_object) + { + vf_delete_object((VF_OBJECT_T *)p_prop->value.v.o.p_object, TRUE); + p_prop->value.v.o.p_object = NULL; + } +} + + + + +/*============================================================================* + Private Function Implementations + *============================================================================*/ + + + +/*----------------------------------------------------------------------------* + * NAME + * free_prop_list() + * + * DESCRIPTION + * Cleans up the memory used by the indicated property list. + * + * RETURNS + * (none) + *----------------------------------------------------------------------------*/ + +void free_prop_list( + VPROP_T *p_props /* List of properties to free */ + ) +{ + VPROP_T *p_tmp; + + for (p_tmp = p_props;p_tmp;) + { + VPROP_T *p_next = p_tmp->p_next; + + delete_prop_contents((VF_PROP_T *)p_tmp, TRUE); + + vf_free(p_tmp); + + p_tmp = p_next; + } +} + + + + + + + + +/*============================================================================* + End Of File + *============================================================================*/ diff --git a/src/vf_internals.h b/src/vf_internals.h new file mode 100644 index 0000000..98ddacc --- /dev/null +++ b/src/vf_internals.h @@ -0,0 +1,223 @@ +/******************************************************************************* + + (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_internals.h $ + $Revision: 1.15 $ + $Author: tilda $ + +ORIGINAL AUTHOR + Nick Marley + +DESCRIPTION + Definition of the internal representation used for VOBJECTs. + +REFERENCES + (none) + +MODIFICATION HISTORY + * $Log: vf_internals.h,v $ + * Revision 1.15 2002/11/02 18:29:26 tilda + * IID485157 - UI does character conversion based on CHARSET property. + * + * Revision 1.14 2002/11/02 08:56:17 tilda + * Start of internationalisation changes. + * + * Revision 1.13 2002/10/26 16:09:24 tilda + * IID629125 - Ensure string functions used are portable. + * + * Revision 1.12 2002/10/08 21:45:07 tilda + * IID620473 - reduce c-runtime dependencies. + * + * Revision 1.11 2002/02/24 17:10:34 tilda + * Add API for "is modified" functionality. + * + * Revision 1.10 2001/10/24 18:36:06 tilda + * BASE64 bugfixes. Split reader/writer code. Start create/modify work. + * + * Revision 1.9 2001/10/14 19:53:36 tilda + * Group handling. NO group searching functions. + * + * Revision 1.8 2001/10/14 16:40:04 tilda + * Initial testing of access functions. + * + * Revision 1.7 2001/10/13 16:22:08 tilda + * Introduce VBINDATA_T and VOBJDATA_T to tidy up internals. + * + * Revision 1.6 2001/10/13 14:58:56 tilda + * Tidy up version headers, add vf_strings.h where needed. + * + * Revision 1.5 2001/10/13 14:49:30 tilda + * Add string array code to unify handling of names / values. + * + * Revision 1.4 2001/10/12 16:20:03 tilda + * Correctly parse compound quoted printable properties. + * + * Revision 1.3 2001/10/10 20:53:56 tilda + * Various minor tidy ups. + * + * Revision 1.2 2001/10/09 22:01:59 tilda + * Remove older version control comments. + * + *******************************************************************************/ + +#ifndef _VF_INTERNALS_H_ +#define _VF_INTERNALS_H_ + +#ifndef NORCSID +static const char vf_internals_h_vss_id[] = "$Header: /cvsroot/vformat/src/vformat/src/vf_internals.h,v 1.15 2002/11/02 18:29:26 tilda Exp $"; +#endif + +/*=============================================================================* + Public Includes + *============================================================================*/ +/* None */ + +/*=============================================================================* + Public Defines + *============================================================================*/ + +#define VFP_BEGIN "BEGIN" +#define VFP_END "END" + +/*=============================================================================* + Public Types + *============================================================================*/ + + +/*----------------------------------------------------------------------------* + * PURPOSE + * VSTRARRAY_T encapsulates an array of strings. + *----------------------------------------------------------------------------*/ + +typedef struct VSTRARRAY_T +{ + uint32_t n_strings; /* Then number of strings */ + char **pp_strings; /* The strings */ +} +VSTRARRAY_T; + + +/*----------------------------------------------------------------------------* + * PURPOSE + * VBINDATA_T encapsulates a chunk of binary data. Yes, you could encode + * any and all vformat attributes in BASE64 but custom is to use BASE64 + * for images etc. + *----------------------------------------------------------------------------*/ + +typedef struct VBINDATA_T +{ + char *p_buffer; /* Binary data */ + uint32_t n_bufsize; +} +VBINDATA_T; + + +/*----------------------------------------------------------------------------* + * PURPOSE + * VOBJDATA_T + *----------------------------------------------------------------------------*/ + +typedef struct VOBJDATA_T +{ + struct VOBJECT_T *p_object; /* Another vformat object */ +} +VOBJDATA_T; + + + +/*----------------------------------------------------------------------------* + * PURPOSE + * VPROPVALUE_T encapsulates the "value" half of a property. + *----------------------------------------------------------------------------*/ + +typedef struct VPROPVALUE_T +{ + vf_encoding_t encoding; + + struct + { + VSTRARRAY_T s; + VBINDATA_T b; + VOBJDATA_T o; + } + v; +} +VPROPVALUE_T; + + + +/*----------------------------------------------------------------------------* + * PURPOSE + * VPROP_T defines a single property. It's an association of a name + * and value pair. A vformat object is simply a list of properties. + * Associated with a property is (possibly) a group name. + *----------------------------------------------------------------------------*/ + +typedef struct VPROP_T +{ + char *p_group; /* Group - we keep the A.B.C format */ + VSTRARRAY_T name; /* Name fields */ + VPROPVALUE_T value; /* Value fields */ + + struct VPROP_T *p_next; /* Next property */ + struct VPROP_T *p_next_srch; /* Next in current search */ + + bool_t modified; /* Property modified? */ + + struct VOBJECT_T *p_parent; /* Owning object (if any) */ +} +VPROP_T; + + +/*----------------------------------------------------------------------------* + * PURPOSE + * VOBJECT_T defines a single vformat object. + *----------------------------------------------------------------------------*/ + +typedef struct VOBJECT_T +{ + char *p_type; /* "VCARD" or "VCALENDAR" etc. */ + VPROP_T *p_props; /* List of properties */ + + bool_t modified; /* Object modified? */ + + struct VOBJECT_T *p_parent; /* Owning object (if any) */ + struct VOBJECT_T *p_next; /* Next object (if any) */ +} +VOBJECT_T; + + +/*=============================================================================* + Public Functions + *============================================================================*/ + + +/*---------------------------------------------------------------------------* + * NAME + * delete_prop_contents() + * + * DESCRIPTION + * Cleans up the memory used by the value associated with the property. + * The property is not deleted => can be a statically allocated variable. + * + * RETURNS + * (none) + *---------------------------------------------------------------------------*/ + +extern void delete_prop_contents( + VF_PROP_T *p_vprop, /* The VF_PROP_T to clean */ + bool_t delname /* Delete the name as well? */ + ); + + +/*=============================================================================* + End of file + *============================================================================*/ + +#endif /*_VF_INTERNALS_H_*/ + diff --git a/src/vf_malloc.c b/src/vf_malloc.c new file mode 100644 index 0000000..ef405d9 --- /dev/null +++ b/src/vf_malloc.c @@ -0,0 +1,270 @@ +/****************************************************************************** + + (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_malloc.c $ + $Revision: 1.7 $ + $Author: tilda $ + +ORIGINAL AUTHOR + Nick Marley + +DESCRIPTION + Implements the memory allocation functions used by the rest of the vformat + library, defaulting to the functions provided by vf_malloc_stdlib.c which + uses malloc() etc. + + Code below knows nothing about the specific allocation scheme in use or it's + debugging facilities and is simply provides the common functions and the + ability to point vformat at an alternative allocation module. + + The only conditional compile option recognised is VFORMAT_MEM_DEBUG which + is described in the accompanying header file. + + Note + ==== + The original code merged the malloc() implementation with the debug facility + and also included a conditional compile VFORMAT_EXT_MALLOC to control the use + of external allocation functions. Given that this tripped up the _author_ on + at least one public test event (UPF-9, where the sync engine was unable to read + VCARDS & extract the X-IRMC stuff) it was considered overcomplicated and has + been considerably simplified ;) - T. + +MODIFICATION HISTORY + * $Log: vf_malloc.c,v $ + * Revision 1.7 2002/10/26 16:09:23 tilda + * IID629125 - Ensure string functions used are portable. + * + * Revision 1.6 2002/10/08 21:45:07 tilda + * IID620473 - reduce c-runtime dependencies. + * + * Revision 1.5 2002/10/08 21:08:43 tilda + * Improve memory debugging 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/10 20:53:56 tilda + * Various minor tidy ups. + * + * Revision 1.2 2001/10/09 22:01:59 tilda + * Remove older version control comments. + * + *******************************************************************************/ + +#ifndef NORCSID +static const char vf_malloc_c_vss_id[] = "$Header: /cvsroot/vformat/src/vformat/src/vf_malloc.c,v 1.7 2002/10/26 16:09:23 tilda Exp $"; +#endif + +/*=============================================================================* + ANSI C & System-wide Header Files + *============================================================================*/ + +#include + +/*============================================================================* + Interface Header Files + *============================================================================*/ + +#include "vformat/vf_iface.h" + +/*============================================================================* + Local Header File + *============================================================================*/ + +#include "vf_config.h" +#include "vf_malloc.h" +#include "vf_internals.h" +#if !defined(VFORMAT_EXCLUDE_MALLOC) +#include "vf_malloc_stdlib.h" +#endif + +/*============================================================================* + Public Data + *============================================================================*/ +/* None */ + +/*============================================================================* + Private Defines + *============================================================================*/ +/* None */ + +/*============================================================================* + Private Data Types + *============================================================================*/ +/* None */ + +/*============================================================================* + Private Function Prototypes + *============================================================================*/ +/* None */ + +/*============================================================================* + Private Data + *============================================================================*/ + +/* + * Pointers to the functions in use - initialised to the default CRT based allocation + * functions unless VFORMAT_EXCLUDE_MALLOC is set in which case they are initialised + * to NULL in the expectation that the user calls vf_set_mem_functions() at some point. + */ + +#if defined(VFORMAT_EXCLUDE_MALLOC) +static vf_malloc_fn_t vf_malloc_fn; +static vf_realloc_fn_t vf_realloc_fn; +static vf_free_fn_t vf_free_fn; +#else +static vf_malloc_fn_t vf_malloc_fn = _vf_stdlib_malloc; +static vf_realloc_fn_t vf_realloc_fn = _vf_stdlib_realloc; +static vf_free_fn_t vf_free_fn = _vf_stdlib_free; +#endif + +/*============================================================================* + Public Function Implementations + *============================================================================*/ + + + +/*----------------------------------------------------------------------------* + * NAME + * vf_set_mem_functions() + * + * DESCRIPTION + * Set the memory allocation functions we're using. + * + * RETURNS + * (none) + *----------------------------------------------------------------------------*/ + +void vf_set_mem_functions( + vf_malloc_fn_t malloc_fn, /* Allocation function */ + vf_realloc_fn_t realloc_fn, /* Reallocation function */ + vf_free_fn_t free_fn /* Free function */ + ) +{ + vf_realloc_fn = realloc_fn; + vf_malloc_fn = malloc_fn; + vf_free_fn = free_fn; +} + + + + + +/*----------------------------------------------------------------------------* + * NAME + * _vf_malloc() + * + * DESCRIPTION + * Allocate chunk of memory. + * + * RETURNS + * Ptr to new block, or NULL if failed. + *----------------------------------------------------------------------------*/ + +void *_vf_malloc( + uint32_t s /* Size required */ +#if defined(VFORMAT_MEM_DEBUG) + , const char *file, /* Filename */ + int line /* Line number */ +#endif + ) +{ + void *p = NULL; + + if (vf_malloc_fn) + { +#if defined(VFORMAT_MEM_DEBUG) + p = vf_malloc_fn(s, file, line); +#else + p = vf_malloc_fn(s); +#endif + } + + return p; +} + + + + + +/*----------------------------------------------------------------------------* + * NAME + * _vf_realloc() + * + * DESCRIPTION + * Re-allocate chunk of memory allocated by _vf_malloc(). + * + * RETURNS + * Ptr to new block, or NULL if failed. + *----------------------------------------------------------------------------*/ + +void *_vf_realloc( + void *p, /* Original pointer */ + uint32_t s /* Size required */ +#if defined(VFORMAT_MEM_DEBUG) + , const char *file, /* filename */ + int line /* line number */ +#endif + ) +{ + void *np = NULL; + + if (vf_realloc_fn) + { +#if defined(VFORMAT_MEM_DEBUG) + np = vf_realloc_fn(p, s, file, line); +#else + np = vf_realloc_fn(p, s); +#endif + } + + return np; +} + + + + + +/*----------------------------------------------------------------------------* + * NAME + * _vf_free() + * + * DESCRIPTION + * De-allocate chunk of memory allocated by _vf_malloc(). + * + * RETURNS + * (none) + *----------------------------------------------------------------------------*/ + +void _vf_free( + void *p /* Pointer */ +#if defined(VFORMAT_MEM_DEBUG) + , const char *file, /* Filename */ + int line /* Line number */ +#endif + ) +{ + if (vf_free_fn) + { +#if defined(VFORMAT_MEM_DEBUG) + vf_free_fn(p, file, line); +#else + vf_free_fn(p); +#endif + } +} + + +/*============================================================================* + Private Function Implementations + *============================================================================*/ +/* None */ + +/*============================================================================* + End Of File + *============================================================================*/ diff --git a/src/vf_malloc.h b/src/vf_malloc.h new file mode 100644 index 0000000..7116d64 --- /dev/null +++ b/src/vf_malloc.h @@ -0,0 +1,166 @@ +/****************************************************************************** + + (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_malloc.h $ + $Revision: 1.6 $ + $Author: tilda $ + +ORIGINAL AUTHOR + Nick Marley + +DESCRIPTION + Memory allocation functions / macros for vformat code. The code always uses + vf_malloc(), vf_realloc() and vf_free() which are replaced by macros with the + names of functions implemented in vf_malloc.c. + + If the conditional compile VFORMAT_MEM_DEBUG is set then in addition to the + caller's allocation parameters, filename and line number information is + provided to the lower layer which may record this for debugging. + + Additionally, a function vf_set_mem_functions() is provided which allows an + application to replace the allocation functions with it's own. This should + be done before vformat allocates any memory ie. during initialisation. + + Unless the library is built with the symbol VFORMAT_EXCLUDE_MALLOC defined + then the library defaults to using malloc() etc. + +MODIFICATION HISTORY + * $Log: vf_malloc.h,v $ + * Revision 1.6 2002/10/26 16:09:23 tilda + * IID629125 - Ensure string functions used are portable. + * + * Revision 1.5 2002/10/08 21:08:43 tilda + * Improve memory debugging 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/10 20:53:56 tilda + * Various minor tidy ups. + * + * Revision 1.2 2001/10/09 22:01:59 tilda + * Remove older version control comments. + * + *******************************************************************************/ + +#ifndef _VF_MALLOC_H_ +#define _VF_MALLOC_H_ + +#ifndef NORCSID +static const char vf_malloc_h_vss_id[] = "$Header: /cvsroot/vformat/src/vformat/src/vf_malloc.h,v 1.6 2002/10/26 16:09:23 tilda Exp $"; +#endif + +/*=============================================================================* + Public Includes + *============================================================================*/ +/* None */ + +/*=============================================================================* + Public Defines + *============================================================================*/ + +/* + * If VFORMAT_MEM_DEBUG is defined, map the vf_xxx() allocation calls to + * the debugging versions found in vf_malloc.c + */ + +#if defined(VFORMAT_MEM_DEBUG) + +#define vf_malloc(x) _vf_malloc(x, __FILE__, __LINE__) +#define vf_realloc(x, y) _vf_realloc(x, y, __FILE__, __LINE__) +#define vf_free(x) _vf_free(x, __FILE__, __LINE__) + +#else /*defined(VFORMAT_MEM_DEBUG)*/ + +#define vf_malloc(x) _vf_malloc(x) +#define vf_realloc(x, y) _vf_realloc(x, y) +#define vf_free(x) _vf_free(x) + +#endif /*defined(VFORMAT_MEM_DEBUG)*/ + +/*=============================================================================* + Public Types + *============================================================================*/ + +#if defined(VFORMAT_MEM_DEBUG) + +typedef void *(*vf_malloc_fn_t)(uint32_t s, const char *file, int line); +typedef void *(*vf_realloc_fn_t)(void *p, uint32_t ns, const char *file, int line); +typedef void (*vf_free_fn_t)(void *p, const char *file, int line); + +#else /*defined(VFORMAT_MEM_DEBUG)*/ + +typedef void *(*vf_malloc_fn_t)(uint32_t s); +typedef void *(*vf_realloc_fn_t)(void *p, uint32_t ns); +typedef void (*vf_free_fn_t)(void *p); + +#endif /*defined(VFORMAT_MEM_DEBUG)*/ + +/*=============================================================================* + Public Functions + *============================================================================*/ +/* None */ + +/*=============================================================================* + End of file + *============================================================================*/ + + +/*----------------------------------------------------------------------------* + * NAME + * _vf_malloc(), _vf_realloc(), _vf_free() + * + * DESCRIPTION + * Memory allocation functions in use. If VFORMAT_MEM_DEBUG is defined + * the line & file are recorded as well. + * + * RETURNS + * (none) + *----------------------------------------------------------------------------*/ + +#if defined(VFORMAT_MEM_DEBUG) + +extern void *_vf_malloc(uint32_t s, const char *file, int line); +extern void *_vf_realloc(void *p, uint32_t ns, const char *file, int line); +extern void _vf_free(void *p, const char *file, int line); + +#else + +extern void *_vf_malloc(uint32_t s); +extern void *_vf_realloc(void *p, uint32_t ns); +extern void _vf_free(void *p); + +#endif + + + +/*----------------------------------------------------------------------------* + * NAME + * vf_set_mem_functions() + * + * DESCRIPTION + * Set the memory allocation functions we're using. + * + * RETURNS + * (none) + *----------------------------------------------------------------------------*/ + +extern VFORMATDECLSPEC void vf_set_mem_functions( + vf_malloc_fn_t malloc_fn, + vf_realloc_fn_t realloc_fn, + vf_free_fn_t free_fn + ); + + + + +/*=============================================================================* + FIN + *============================================================================*/ + +#endif /*_VF_MALLOC_H_*/ diff --git a/src/vf_malloc_stdlib.c b/src/vf_malloc_stdlib.c new file mode 100644 index 0000000..6318fa5 --- /dev/null +++ b/src/vf_malloc_stdlib.c @@ -0,0 +1,392 @@ +/****************************************************************************** + + (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_malloc.c $ + $Revision: 1.2 $ + $Author: tilda $ + +ORIGINAL AUTHOR + Nick Marley + +DESCRIPTION + C standard library based memory allocation functions referenced by default in + the accompanying vf_malloc.c file. These are excluded from the build entirely + if VFORMAT_EXCLUDE_MALLOC is set in the build options. + +MODIFICATION HISTORY + * $Log: vf_malloc_stdlib.c,v $ + * Revision 1.2 2002/11/15 09:15:00 tilda + * IID638823 - Various portability issues. + * + * Revision 1.1 2002/10/26 15:57:11 tilda + * Initial Version + * + *******************************************************************************/ + +#if !defined(VFORMAT_EXCLUDE_MALLOC) + +#ifndef NORCSID +static const char vf_malloc_stdlib_c_vss_id[] = "$Header: /cvsroot/vformat/src/vformat/src/vf_malloc_stdlib.c,v 1.2 2002/11/15 09:15:00 tilda Exp $"; +#endif + +/*=============================================================================* + ANSI C & System-wide Header Files + *============================================================================*/ + +#include + +#include +#include + +/*============================================================================* + Interface Header Files + *============================================================================*/ + +#include "vformat/vf_iface.h" + +/*============================================================================* + Local Header File + *============================================================================*/ + +#include "vf_config.h" +#include "vf_malloc.h" +#include "vf_strings.h" + +/*============================================================================* + Public Data + *============================================================================*/ +/* None */ + +/*============================================================================* + Private Defines + *============================================================================*/ + +#define NUMMEMBLOCKS (1024) + +#if defined(WIN) || defined(WIN32) +#define DEBUGBREAK _asm { int 3 } +#endif + +#ifndef DEBUGBREAK +#define DEBUGBREAK +#endif + +#define ALLOCBREAK (-1) + +/*============================================================================* + Private Data Types + *============================================================================*/ + +typedef struct MEMBLOCK_T +{ + void *p; /* The block */ + uint32_t s; /* The size */ + char *file; /* filename it was allocated in */ + int line; /* line number */ +} +MEMBLOCK_T; + +/*============================================================================* + Private Function Prototypes + *============================================================================*/ + +#if defined(VFORMAT_MEM_DEBUG) +static void init_mem_debug(void); +static void atexit_dump_mem(void); +#endif + +/*============================================================================* + Private Data + *============================================================================*/ + +static MEMBLOCK_T blocks[NUMMEMBLOCKS]; + +/*============================================================================* + Public Function Implementations + *============================================================================*/ + + +/*----------------------------------------------------------------------------* + * NAME + * _vf_stdlib_malloc() + * + * DESCRIPTION + * vformat compatible memory allocator using C standard library functions. + * + * RETURNS + * Ptr to new block, or NULL if failed. + *----------------------------------------------------------------------------*/ + +void *_vf_stdlib_malloc( + uint32_t s /* Size required */ +#if defined(VFORMAT_MEM_DEBUG) + , const char *file, /* filename */ + int line /* line number */ +#endif + ) +{ + void *p = NULL; + +#if defined(VFORMAT_MEM_DEBUG) + + uint32_t i; + + init_mem_debug(); + + for (i = 0;i < NUMMEMBLOCKS;i++) + { + if (blocks[i].p) + { + } + else + { + p = malloc(s); + + if (p) + { + blocks[i].p = p; + blocks[i].s = s; + blocks[i].file = (char *)file; + blocks[i].line = line; + } + + if (i == ALLOCBREAK) + { + DEBUGBREAK; + } + + break; + } + } + +#else /*defined(VFORMAT_MEM_DEBUG)*/ + + p = malloc(s); + +#endif + + return p; +} + + + + + +/*----------------------------------------------------------------------------* + * NAME + * _vf_stdlib_realloc() + * + * DESCRIPTION + * Re-allocate chunk of memory allocated by _vf_malloc(). + * + * RETURNS + * Ptr to new block, or NULL if failed. + *----------------------------------------------------------------------------*/ + +void *_vf_stdlib_realloc( + void *p, /* Original pointer */ + uint32_t s /* Size required */ +#if defined(VFORMAT_MEM_DEBUG) + , const char *file, /* Filename */ + int line /* Line number */ +#endif + ) +{ + void *np = NULL; + +#if defined(VFORMAT_MEM_DEBUG) + + uint32_t i; + + init_mem_debug(); + + if (!p) + return _vf_stdlib_malloc(s, file, line); + + for (i = 0;i < NUMMEMBLOCKS;i++) + { + if (blocks[i].p == p) + { + np = realloc(p, s); + + if (np) + { + blocks[i].p = np; + blocks[i].s = s; + } + + break; + } + } + +#else /*defined(VFORMAT_MEM_DEBUG)*/ + + np = realloc(p, s); + +#endif /*defined(VFORMAT_MEM_DEBUG)*/ + + return np; +} + + + + + +/*----------------------------------------------------------------------------* + * NAME + * _vf_stdlib_free() + * + * DESCRIPTION + * De-allocate chunk of memory allocated by _vf_malloc(). + * + * RETURNS + * (none) + *----------------------------------------------------------------------------*/ + +void _vf_stdlib_free( + void *p /* Pointer */ +#if defined(VFORMAT_MEM_DEBUG) + , const char *file, /* Filename */ + int line /* Line number */ +#endif + ) +{ +#if defined(VFORMAT_MEM_DEBUG) + + uint32_t i; + + init_mem_debug(); + + for (i = 0;i < NUMMEMBLOCKS;i++) + { + if (blocks[i].p == p) + { + blocks[i].p = NULL; + blocks[i].s = 0; + blocks[i].line = 0; + blocks[i].file = NULL; + + free(p); + + break; + } + } + +#else + + free(p); + +#endif +} + + + + + +/*----------------------------------------------------------------------------* + * NAME + * vf_stdlib_dump_alloc_info() + * + * DESCRIPTION + * Display current state of memory allocator. + * + * RETURNS + * TRUE if blocks are currently allocated, FALSE else. + *----------------------------------------------------------------------------*/ + +bool_t vf_stdlib_dump_alloc_info() +{ + unsigned long i; + unsigned long c, s; + + for (i = 0, c = 0, s = 0;i < NUMMEMBLOCKS;i++) + { + if (blocks[i].p) + { + c += 1; + s += blocks[i].s; + + printf("block[%lu] size %lu, file %s, line %d\n", + i, (unsigned long)blocks[i].s, blocks[i].file, blocks[i].line); + } + } + + if (c) + { + printf("... a total of %lu blocks, %lu bytes\n", c, s); + } + + return (0 < c) ? TRUE : FALSE; +} + + + +/*============================================================================* + Private Function Implementations + *============================================================================*/ + +#if defined(VFORMAT_MEM_DEBUG) + +/*----------------------------------------------------------------------------* + * NAME + * init_mem_debug() + * + * DESCRIPTION + * Initialisation function. + * + * RETURNS + * (none) + *----------------------------------------------------------------------------*/ + +static void init_mem_debug() +{ + static bool_t init_yet = FALSE; + + if (init_yet) + { + /* OK */ + } + else + { + p_memset(blocks, '\0', sizeof(blocks)); + + atexit(atexit_dump_mem); + + init_yet = TRUE; + } +} + + + + + +/*----------------------------------------------------------------------------* + * NAME + * atexit_dump_mem() + * + * DESCRIPTION + * atexit() callback function which dumps memory allocated info. + * + * RETURNS + * (none) + *----------------------------------------------------------------------------*/ + +static void atexit_dump_mem(void) +{ + vf_stdlib_dump_alloc_info(); +} + +#endif /*defined(VFORMAT_MEM_DEBUG)*/ + + +#endif /*defined(VFORMAT_EXCLUDE_MALLOC)*/ + + +/*============================================================================* + End Of File + *============================================================================*/ diff --git a/src/vf_malloc_stdlib.h b/src/vf_malloc_stdlib.h new file mode 100644 index 0000000..d765256 --- /dev/null +++ b/src/vf_malloc_stdlib.h @@ -0,0 +1,90 @@ +/****************************************************************************** + + (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_malloc.h $ + $Revision: 1.1 $ + $Author: tilda $ + +ORIGINAL AUTHOR + Nick Marley + +DESCRIPTION + Externs for the malloc() based memory allocator. + +MODIFICATION HISTORY + * $Log: vf_malloc_stdlib.h,v $ + * Revision 1.1 2002/10/26 15:57:11 tilda + * Initial Version + * + * + *******************************************************************************/ + +#ifndef _VF_MALLOC_STDLIB_H_ +#define _VF_MALLOC_STDLIB_H_ + +#ifndef NORCSID +static const char vf_malloc_stdlib_h_vss_id[] = "$Header: /cvsroot/vformat/src/vformat/src/vf_malloc_stdlib.h,v 1.1 2002/10/26 15:57:11 tilda Exp $"; +#endif + +/*=============================================================================* + Public Includes + *============================================================================*/ +/* None */ + +/*=============================================================================* + Public Defines + *============================================================================*/ +/* None */ + +/*=============================================================================* + Public Types + *============================================================================*/ +/* None */ + +/*=============================================================================* + Public Functions + *============================================================================*/ +/* None */ + +/*=============================================================================* + End of file + *============================================================================*/ + + +/*----------------------------------------------------------------------------* + * NAME + * _vf_stdlib_malloc(), _vf_stdlib_realloc(), _vf_stdlib_free() + * + * DESCRIPTION + * Memory allocation functions provided in terms of C runtime library + * malloc() etc. If VFORMAT_MEM_DEBUG is defined the line & file are + * passed through for ebugging purposes. + * + * RETURNS + * (various) + *----------------------------------------------------------------------------*/ + +#if defined(VFORMAT_MEM_DEBUG) + +extern void *_vf_stdlib_malloc(uint32_t s, const char *file, int line); +extern void *_vf_stdlib_realloc(void *p, uint32_t ns, const char *file, int line); +extern void _vf_stdlib_free(void *p, const char *file, int line); + +#else + +extern void *_vf_stdlib_malloc(uint32_t s); +extern void *_vf_stdlib_realloc(void *p, uint32_t ns); +extern void _vf_stdlib_free(void *p); + +#endif + +/*=============================================================================* + FIN + *============================================================================*/ + +#endif /*_VF_MALLOC_STDLIB_H_*/ diff --git a/src/vf_modified.c b/src/vf_modified.c new file mode 100644 index 0000000..427698a --- /dev/null +++ b/src/vf_modified.c @@ -0,0 +1,159 @@ +/****************************************************************************** + + (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_modified.c $ + $Revision: 1.4 $ + $Author: tilda $ + +ORIGINAL AUTHOR + Nick Marley + +DESCRIPTION + Memory allocation system for vformat parser / editor. + +REFERENCES + (none) + +MODIFICATION HISTORY + * $Log: vf_modified.c,v $ + * Revision 1.4 2002/11/02 18:29:26 tilda + * IID485157 - UI does character conversion based on CHARSET property. + * + * Revision 1.3 2002/10/29 07:19:20 tilda + * Tidy headers. + * + * Revision 1.2 2002/10/26 16:09:23 tilda + * IID629125 - Ensure string functions used are portable. + * + * Revision 1.1 2002/10/11 20:29:25 tilda + * Include vf_modified.c + * + *******************************************************************************/ + +#ifndef NORCSID +static const char vf_modified_c_vss_id[] = "$Header: /cvsroot/vformat/src/vformat/src/vf_modified.c,v 1.4 2002/11/02 18:29:26 tilda Exp $"; +#endif + +/*=============================================================================* + ANSI C & System-wide Header Files + *============================================================================*/ + +#include + +/*============================================================================* + Interface Header Files + *============================================================================*/ + +#include "vformat/vf_iface.h" + +/*============================================================================* + Local Header File + *============================================================================*/ + +#include "vf_config.h" +#include "vf_malloc.h" +#include "vf_internals.h" +#include "vf_modified.h" + +/*============================================================================* + Public Data + *============================================================================*/ +/* None */ + +/*============================================================================* + Private Defines + *============================================================================*/ +/* None */ + +/*============================================================================* + Private Data Types + *============================================================================*/ +/* None */ + +/*============================================================================* + Private Function Prototypes + *============================================================================*/ +/* None */ + +/*============================================================================* + Private Data + *============================================================================*/ +/* None */ + +/*============================================================================* + Public Function Implementations + *============================================================================*/ + +/*---------------------------------------------------------------------------* + * NAME + * vf_is_modified() + * + * DESCRIPTION + * Return the status of the modified flag for the indicated object. + * + * RETURNS + * TRUE/FALSE + *---------------------------------------------------------------------------*/ + +bool_t vf_is_modified( + VF_OBJECT_T *p_object + ) +{ + bool_t ret = FALSE; + + if (p_object) + { + ret = ((VOBJECT_T *)p_object)->modified; + } + + return ret; +} + + + + +/*---------------------------------------------------------------------------* + * NAME + * mark_property_modified() + * + * DESCRIPTION + * Mark indicated property and it's owning object as modified. If the + * recurse flag is st, then the owning object's parent object is also + * marked as modified recursively up to the top of the tree. + * + * RETURNS + * (none) + *---------------------------------------------------------------------------*/ + +void mark_property_modified( + VPROP_T *p_prop, /* The property */ + bool_t recurse /* Recurse? */ + ) +{ + p_prop->modified = TRUE; + p_prop->p_parent->modified = TRUE; + + if (recurse) + { + VOBJECT_T *p_parent = p_prop->p_parent->p_parent; + + for (;p_parent;p_parent = p_parent->p_parent) + { + p_parent->modified = TRUE; + } + } +} + + +/*============================================================================* + Private Function Implementations + *============================================================================*/ + + /*============================================================================* + End Of File + *============================================================================*/ diff --git a/src/vf_modified.h b/src/vf_modified.h new file mode 100644 index 0000000..f1616a4 --- /dev/null +++ b/src/vf_modified.h @@ -0,0 +1,84 @@ +/******************************************************************************* + + (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_modified.h $ + $Revision: 1.1 $ + $Author: tilda $ + +ORIGINAL AUTHOR + Nick Marley + +DESCRIPTION + Library internal access to the modification status. + +REFERENCES + (none) + +MODIFICATION HISTORY + * $Log: vf_modified.h,v $ + * Revision 1.1 2002/10/11 20:22:32 tilda + * Added / repaired vf_modified.h + * + * + * 2 9/05/02 3:49p Nm2 + * Adjust memoruy allocation system for use in an embedded build. + * + * 1 7/08/02 7:24a Nm2 + * + *******************************************************************************/ + +#ifndef _VF_MODIFIED_H_ +#define _VF_MODIFIED_H_ + +#ifndef NORCSID +static const char vf_modified_h_vss_id[] = "$Header: /cvsroot/vformat/src/vformat/src/vf_modified.h,v 1.1 2002/10/11 20:22:32 tilda Exp $"; +#endif + +/*=============================================================================* + Public Includes + *============================================================================*/ +/* None */ + +/*=============================================================================* + Public Defines + *============================================================================*/ +/* None */ + +/*=============================================================================* + Public Types + *============================================================================*/ +/* None */ + +/*=============================================================================* + Public Functions + *============================================================================*/ + +/*---------------------------------------------------------------------------* + * NAME + * mark_property_modified() + * + * DESCRIPTION + * Mark indicated property and it's owning object as modified. If the + * recurse flag is st, then the owning object's parent object is also + * marked as modified recursively up to the top of the tree. + * + * RETURNS + * (none) + *---------------------------------------------------------------------------*/ + +extern void mark_property_modified( + VPROP_T *p_prop, /* The property */ + bool_t recurse /* Recurse? */ + ); + + +/*=============================================================================* + End of file + *============================================================================*/ + +#endif /*_VF_MODIFIED_H_*/ diff --git a/src/vf_parser.c b/src/vf_parser.c new file mode 100644 index 0000000..bf7b789 --- /dev/null +++ b/src/vf_parser.c @@ -0,0 +1,1182 @@ +/****************************************************************************** + + (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_parser.c $ + $Revision: 1.22 $ + $Author: tilda $ + +ORIGINAL AUTHOR + Nick Marley + +DESCRIPTION + Parser for text stream in vobject format. + +REFERENCES + (none) + +MODIFICATION HISTORY + * $Log: vf_parser.c,v $ + * Revision 1.22 2002/11/16 13:19:10 tilda + * IID639288 - Implement method for adding subobjects. + * + * Revision 1.21 2002/11/15 09:15:00 tilda + * IID638823 - Various portability issues. + * + * Revision 1.20 2002/11/03 18:43:16 tilda + * IID619851 - Update and check headers and function prototypes. + * + * Revision 1.19 2002/11/02 18:29:26 tilda + * IID485157 - UI does character conversion based on CHARSET property. + * + * Revision 1.18 2002/11/02 08:56:17 tilda + * Start of internationalisation changes. + * + * Revision 1.17 2002/10/26 16:09:23 tilda + * IID629125 - Ensure string functions used are portable. + * + * Revision 1.16 2002/10/08 21:45:07 tilda + * IID620473 - reduce c-runtime dependencies. + * + * Revision 1.15 2002/10/08 21:25:28 tilda + * Assignment of parent property. + * + * Revision 1.14 2002/10/08 21:11:36 tilda + * Remove common.h. + * + * Revision 1.13 2002/02/24 17:10:34 tilda + * Add API for "is modified" functionality. + * + * Revision 1.12 2001/12/13 06:45:35 tilda + * IID488021 - Various bugs with quoted printable format. + * + * Revision 1.11 2001/10/24 18:36:06 tilda + * BASE64 bugfixes. Split reader/writer code. Start create/modify work. + * + * Revision 1.10 2001/10/24 05:32:19 tilda + * BASE64 bugfixes - first part + * + * Revision 1.9 2001/10/14 20:42:37 tilda + * Addition of group searching. + * + * Revision 1.8 2001/10/14 19:53:36 tilda + * Group handling. NO group searching functions. + * + * Revision 1.7 2001/10/13 16:22:08 tilda + * Introduce VBINDATA_T and VOBJDATA_T to tidy up internals. + * + * Revision 1.6 2001/10/13 14:58:56 tilda + * Tidy up version headers, add vf_strings.h where needed. + * + * Revision 1.5 2001/10/13 14:49:30 tilda + * Add string array code to unify handling of names / values. + * + * Revision 1.4 2001/10/12 16:20:03 tilda + * Correctly parse compound quoted printable properties. + * + * Revision 1.3 2001/10/10 20:53:56 tilda + * Various minor tidy ups. + * + * Revision 1.2 2001/10/09 22:01:59 tilda + * Remove older version control comments. + * + *****************************************************************************/ + +#ifndef NORCSID +static const char vf_parser_c_vss_id[] = "$Header: /cvsroot/vformat/src/vformat/src/vf_parser.c,v 1.22 2002/11/16 13:19:10 tilda Exp $"; +#endif + +/*============================================================================* + ANSI C & System-wide Header Files + *===========================================================================*/ + +#include + +/*============================================================================* + Interface Header Files + *===========================================================================*/ + +#include "vformat/vf_iface.h" + +/*============================================================================* + Local Header File + *===========================================================================*/ + +#include "vf_config.h" +#include "vf_malloc.h" +#include "vf_internals.h" +#include "vf_strings.h" +#include "vf_string_arrays.h" + +/*============================================================================* + Public Data + *===========================================================================*/ +/* None */ + +/*============================================================================* + Private Defines + *===========================================================================*/ + +/* + * Significant characters. + */ +#define PERIOD '.' +#define COLON ':' +#define SEMICOLON ';' +#define LINEFEED '\n' +#define CRETURN '\r' +#define TAB '\t' +#define BACKSLASH '\\' +#define SPACE ' ' +#define EQUALS '=' +#define PERIOD '.' + +/* + * dec hex oct char + * 10 0x0A 012 LF NL, line feed, new line, \n + * 13 0x0D 015 CR carriage return, \r + * + * => = 0x0D 0x0A + */ + +/* + * States associated with propname:propvalue parsing. + */ +#define _VF_STATE_PROPNAME (1) /* reading name (including groupings) */ +#define _VF_STATE_PROPNAMEESCAPE (2) /* escaped semicolon in name */ +#define _VF_STATE_RFC822VALUE (3) /* basic */ +#define _VF_STATE_RFC822VALUEFOLD (4) /* waiting for line fold (simple fields) */ +#define _VF_STATE_QPIDLE (5) /* Non escaped position in QP */ +#define _VF_STATE_QPIDLENL (6) /* Non escaped position in QP */ +#define _VF_STATE_QPEQUALSC1 (7) /* After = in QP */ +#define _VF_STATE_QPEQUALSC2 (8) /* After =X in QP */ +#define _VF_STATE_BASE64 (9) /* Reading BASE64 */ + +#define ISCRORNL(c) ((CRETURN == (c)) || (LINEFEED == (c))) + +/*============================================================================* + Private Data Types + *===========================================================================*/ + +/*----------------------------------------------------------------------------* + * PURPOSE + * Maintains state variables etc. for current VOBJECT_T parsing. + *----------------------------------------------------------------------------*/ + +typedef struct +{ + int state; /* Main state variable */ + char qpchar; /* Workspace for QuotedPrintable decoder */ + char *p_b64buf; /* Workspace for BASE64 decoder */ + VOBJECT_T **pp_root_object; /* Pointer to the root */ + VOBJECT_T *p_object; /* Current position in tree */ + VPROP_T prop; /* Current property, copied into tree on completion */ +} +VPARSE_T; + +/*============================================================================* + Private Function Prototypes + *===========================================================================*/ + +static bool_t append_value_to_object( + VPROP_T **pp_prop, /* Pointer to the new property */ + VPARSE_T *p_parse /* The property we're naming */ + ); + +static bool_t handle_base64_chars( + VPARSE_T *p_parse, /* The property value we're adding to */ + const char *p_chars, /* Pointer to characters to add */ + int numchars /* Number of characters */ + ); + +static vf_encoding_t deduce_encoding( + VSTRARRAY_T *p_propname /* Property name */ + ); + +static uint8_t base64_to_char( + char c /* Character to convert */ + ); + +static bool_t is_hex_digit( + char *p_nibble, /* Output nibble value */ + char c /* Character read from file */ + ); + +static bool_t handle_value_complete( + VPARSE_T *p_parse /* Current parse state info */ + ); + +static bool_t alloc_next_object( + VPARSE_T *p_parse, /* Current parse state info */ + char *p_type /* Type of object */ + ); + +static bool_t alloc_sub_object( + VPARSE_T *p_parse, /* Current parse state info */ + char *p_type /* Type of object */ + ); + +static bool_t alloc_object( + VOBJECT_T **pp_new, /* Pointer to output pointer */ + VOBJECT_T *p_parent, /* Parent of new node */ + char *p_type, /* Type of new node */ + VPARSE_T *p_parse /* Current parse info */ + ); + +static bool_t append_group_name( + VPROP_T *p_prop /* Property we're updating */ + ); + + +/*============================================================================* + Private Data + *===========================================================================*/ +/* None */ + +/*============================================================================* + Public Function Implementations + *===========================================================================*/ + + + +/*----------------------------------------------------------------------------* + * NAME + * vf_parse_init() + * + * DESCRIPTION + * Initialise a parsing instance. + * + * RETURNS + * (none) + *---------------------------------------------------------------------------*/ + +bool_t vf_parse_init( + VF_PARSER_T **pp_parser, /* The parser */ + VF_OBJECT_T **pp_object /* The object we're parsing into */ + ) +{ + bool_t ret = FALSE; + + if (pp_parser && pp_object) + { + VPARSE_T *p_parse = (VPARSE_T *)vf_malloc(sizeof(VPARSE_T)); + + if (p_parse) + { + p_memset(p_parse, '\0', sizeof(VPARSE_T)); + + p_parse->state = _VF_STATE_PROPNAME; + p_parse->p_object = NULL; + p_parse->pp_root_object = (VOBJECT_T **)pp_object; + + *pp_parser = (VF_PARSER_T *)p_parse; + + *pp_object = NULL; + + ret = TRUE; + } + } + + return ret; +} + + + + + + +/*----------------------------------------------------------------------------* + * NAME + * vf_parse_text() + * + * DESCRIPTION + * Parse indicated text into the object associated with the VPARSE_T. + * + * RETURNS + * TRUE <=> allocation & syntax OK, FALSE else. + *---------------------------------------------------------------------------*/ + +bool_t vf_parse_text( + VF_PARSER_T *p_parser, /* The parser */ + char *p_chars, /* New characters to parse into object */ + int numchars /* Number of new characters */ + ) +{ + int i; + bool_t ok; + VPARSE_T *p_parse = (VPARSE_T *)p_parser; + + /* + * Check pointer. + */ + if (!p_parse) + { + return FALSE; + } + + /* + * Push each character through the state machine. + */ + for (i = 0, ok = TRUE;ok && (i < numchars);i++) + { + char c = p_chars[i]; + + switch (p_parse->state) + { + case _VF_STATE_RFC822VALUEFOLD: + { + if (ISCRORNL(c)) + { + /* Ignore */ + } + else + if (SPACE == c) + { + ok = append_to_curr_string(&(p_parse->prop.value.v.s), NULL, &c, 1); + + p_parse->state = _VF_STATE_RFC822VALUE; + } + else + { + ok = handle_value_complete(p_parse); + + p_parse->state = _VF_STATE_PROPNAME; + } + } + if (_VF_STATE_PROPNAME == p_parse->state) + { + /* Fall through */ + } + else + { + break; + } + + /* Fall through */ + + + case _VF_STATE_PROPNAME: + { + if (COLON == c) + { + p_parse->prop.value.encoding = deduce_encoding(&p_parse->prop.name); + + switch (p_parse->prop.value.encoding) + { + case VF_ENC_7BIT: + p_parse->state = _VF_STATE_RFC822VALUE; + break; + + case VF_ENC_BASE64: + p_parse->state = _VF_STATE_BASE64; + break; + + case VF_ENC_QUOTEDPRINTABLE: + p_parse->state = _VF_STATE_QPIDLE; + break; + + default: + ok = FALSE; + break; + } + } + else + if (BACKSLASH == c) + { + p_parse->state = _VF_STATE_PROPNAMEESCAPE; + } + else + if (ISCRORNL(c)) + { + /* ignore */ + + free_string_array_contents(&p_parse->prop.name); + } + else + if (SEMICOLON == c) + { + ok = add_string_to_array(&p_parse->prop.name, ""); + } + else + if (PERIOD == c) + { + ok = append_group_name(&p_parse->prop); + } + else + { + ok = append_to_curr_string(&(p_parse->prop.name), NULL, &c, 1); + } + } + break; + + case _VF_STATE_PROPNAMEESCAPE: + { + if (SEMICOLON == c) + { + ok = append_to_curr_string(&(p_parse->prop.name), NULL, &c, 1); + } + else + { + ok = FALSE; + } + } + break; + + case _VF_STATE_RFC822VALUE: + { + if (p_parse->prop.value.v.s.pp_strings) + { + /* Already allocated */ + } + else + { + ok = add_string_to_array(&(p_parse->prop.value.v.s), NULL); + } + + if (ISCRORNL(c)) + { + p_parse->state = _VF_STATE_RFC822VALUEFOLD; + } + else + if (SEMICOLON == c) + { + ok = add_string_to_array(&(p_parse->prop.value.v.s), NULL); + } + else + { + ok = append_to_curr_string(&(p_parse->prop.value.v.s), NULL, &c, 1); + } + } + break; + + case _VF_STATE_QPIDLENL: + { + if (ISCRORNL(c)) + { + break; + } + else + { + p_parse->state = _VF_STATE_QPIDLE; + } + } + + case _VF_STATE_QPIDLE: + { + if (p_parse->prop.value.v.s.pp_strings) + { + /* Already allocated */ + } + else + { + ok = add_string_to_array(&(p_parse->prop.value.v.s), NULL); + } + + if (EQUALS == c) + { + p_parse->qpchar = 0x00; + p_parse->state = _VF_STATE_QPEQUALSC1; + } + else + if (SEMICOLON == c) + { + ok = add_string_to_array(&(p_parse->prop.value.v.s), NULL); + } + else + if (ISCRORNL(c)) + { + ok = handle_value_complete(p_parse); + } + else + { + ok = append_to_curr_string(&(p_parse->prop.value.v.s), NULL, &c, 1); + } + } + break; + + case _VF_STATE_QPEQUALSC1: + { + uint8_t nibble; + + if (ISCRORNL(c)) + { + p_parse->state = _VF_STATE_QPIDLENL; + } + else + if (is_hex_digit(&nibble, c)) + { + (p_parse->qpchar) <<= 4; + (p_parse->qpchar) |= nibble; + + p_parse->state = _VF_STATE_QPEQUALSC2; + } + else + { + ok = FALSE; + } + } + break; + + case _VF_STATE_QPEQUALSC2: + { + uint8_t nibble; + + if (is_hex_digit(&nibble, c)) + { + (p_parse->qpchar) <<= 4; + (p_parse->qpchar) |= nibble; + + ok = append_to_curr_string(&(p_parse->prop.value.v.s), NULL, &(p_parse->qpchar), 1); + + p_parse->state = _VF_STATE_QPIDLE; + } + else + { + ok = FALSE; + } + } + break; + + case _VF_STATE_BASE64: + { + /* + * The cr/nl stuff associated with line ends & termination of BASE64 encoding + * seems to be particularly problematic. Searching and reading vCards from the + * internet shows that all sorts of wierd things are out there in use! In the + * interests of interoperability we look for the next value as an indication of + * the end of the object. We build up each line and if it's still in BASE64 + * format append the decoded data. Otherwise we use the parser recursively to + * decode the buffered text, which is probably something like "NEXT-VALUE:" + */ + + if (ISCRORNL(c)) + { + if (p_parse->p_b64buf) + { + ok = handle_base64_chars(p_parse, p_parse->p_b64buf, p_strlen(p_parse->p_b64buf)); + + vf_free(p_parse->p_b64buf); + p_parse->p_b64buf = NULL; + } + } + else + { + ok = append_to_pointer(&(p_parse->p_b64buf), NULL, &c, 1); + + if ((COLON == c) || (SEMICOLON == c)) + { + ok = handle_value_complete(p_parse); + + ok = vf_parse_text(p_parser, p_parse->p_b64buf, p_strlen(p_parse->p_b64buf)); + + vf_free(p_parse->p_b64buf); + p_parse->p_b64buf = NULL; + } + } + } + break; + } + } + + if (ok) + { + /* no need to panic */ + } + else + { + vf_delete_object((VF_OBJECT_T *)*(p_parse->pp_root_object), TRUE); + *(p_parse->pp_root_object) = NULL; + p_parse->p_object = NULL; + + if (p_parse->p_b64buf) + { + vf_free(p_parse->p_b64buf); + p_parse->p_b64buf = NULL; + } + + delete_prop_contents((VF_PROP_T *)&p_parse->prop, TRUE); + } + + return ok; +} + + + + + + +/*----------------------------------------------------------------------------* + * NAME + * vf_parse_end() + * + * DESCRIPTION + * Ensure parse completion. + * + * RETURNS + * TRUE <=> allocation & syntax OK, FALSE else. + *---------------------------------------------------------------------------*/ + +bool_t vf_parse_end( + VF_PARSER_T *p_parser /* The parser */ + ) +{ + bool_t ret = FALSE; + VPARSE_T *p_parse = (VPARSE_T *)p_parser; + + /* + * Check pointer. + */ + if (p_parse) + { + ret = handle_value_complete(p_parse); + + vf_free(p_parse); + } + + return ret; +} + + + + +/*============================================================================* + Private Functions + *===========================================================================*/ + + +/*----------------------------------------------------------------------------* + * NAME + * append_group_name() + * + * DESCRIPTION + * After reading a ".", we transfer the segment of name we've read (which + * must be the first string ) into the group name. Keep the group name + * in one string of "." tokens for simplicity, so we may end up with a + * group called "X-PHONE-BOOK.ENTRY.1" etc. + * + * RETURNS + * TRUE <=> allocation OK. + *---------------------------------------------------------------------------*/ + +bool_t append_group_name( + VPROP_T *p_prop + ) +{ + bool_t ok = TRUE; + + if (p_prop->p_group) + { + ok &= append_to_pointer(&p_prop->p_group, NULL, ".", 1); + } + + if (ok) + { + const char *p_string = p_prop->name.pp_strings[0]; + + ok &= append_to_pointer(&p_prop->p_group, NULL, p_string, p_strlen(p_string)); + + if (ok) + { + vf_free(p_prop->name.pp_strings[0]); + p_prop->name.pp_strings[0] = NULL; + } + } + + return ok; +} + + + + + +/*----------------------------------------------------------------------------* + * NAME + * handle_value_complete() + * + * DESCRIPTION + * Called when a complete value is parsed. + * + * RETURNS + * (none). + *---------------------------------------------------------------------------*/ + +bool_t handle_value_complete( + VPARSE_T *p_parse /* Current parse state info */ + ) +{ + bool_t ret = TRUE; + VOBJECT_T *p_object; + + /* + * If we've got no object open we ignore values until we read a BEGIN at which point + * we create a vformat object and start to parse properties into it. If we subsequently + * read a BEGIN we add a property & parse the next vobject into that. Each time we read + * an END we pop the pp_object pointer back up to the owner of the object we're parsing + * into. There should be an easier way of doing this ... + */ + + p_object = p_parse->p_object; + + if (p_object) + { + if (string_array_contains_string(&p_parse->prop.name, NULL, 0, VFP_BEGIN, TRUE)) + { + char *p_type; + + p_type = p_parse->prop.value.v.s.pp_strings[0]; + p_parse->prop.value.v.s.pp_strings[0] = NULL; + + delete_prop_contents((VF_PROP_T *)(&(p_parse->prop)), TRUE); + + p_parse->prop.value.encoding = VF_ENC_VOBJECT; + + ret = add_string_to_array(&(p_parse->prop.name), p_type) && + alloc_sub_object(p_parse, p_type); + } + else + if (string_array_contains_string(&p_parse->prop.name, NULL, 0, VFP_END, TRUE)) + { + delete_prop_contents((VF_PROP_T *)(&(p_parse->prop)), TRUE); + + p_parse->p_object = p_parse->p_object->p_parent; + } + else + { + ret = append_value_to_object(NULL, p_parse); + } + } + else + { + if (string_array_contains_string(&p_parse->prop.name, NULL, 0, VFP_BEGIN, TRUE)) + { + char *p_type; + + p_type = p_parse->prop.value.v.s.pp_strings[0]; + p_parse->prop.value.v.s.pp_strings[0] = NULL; + + ret = alloc_next_object(p_parse, p_type); + } + + delete_prop_contents((VF_PROP_T *)(&(p_parse->prop)), TRUE); + } + + p_parse->state = _VF_STATE_PROPNAME; + + return ret; +} + + + + + + +/*----------------------------------------------------------------------------* + * NAME + * alloc_next_object() + * + * DESCRIPTION + * Allocate the "next" object, ie. annother vformat tagged to the p_next + * pointer to the current one. + * + * RETURNS + * TRUE iff memory allocated OK, FALSE else OK. + *---------------------------------------------------------------------------*/ + +bool_t alloc_next_object( + VPARSE_T *p_parse, /* Current parse state info */ + char *p_type /* Type of object */ + ) +{ + bool_t ok = TRUE; + VOBJECT_T *p_parent = p_parse->p_object; + VOBJECT_T *p_new = NULL; + + ok = alloc_object(&p_new, p_parent ? p_parent->p_parent : NULL, p_type, p_parse); + + if (ok) + { + if (*p_parse->pp_root_object) + { + /* root object already set */ + + if (p_new->p_parent) + { + /* Owned by property */ + } + else + { + /* Need to tag to end of top list */ + + VOBJECT_T **pp_tmp = p_parse->pp_root_object; + + while (*pp_tmp) + { + pp_tmp = &((*pp_tmp)->p_next); + } + + *pp_tmp = p_new; + } + } + else + { + *p_parse->pp_root_object = p_new; + } + } + + return ok; +} + + + + + + + +/*----------------------------------------------------------------------------* + * NAME + * alloc_sub_object() + * + * DESCRIPTION + * Allocate "sub" object, ie. annother vformat tagged to the p_object + * pointer of a VPROP_T allocated to contain it. + * + * RETURNS + * TRUE iff memory allocated OK, FALSE else OK. + *---------------------------------------------------------------------------*/ + +bool_t alloc_sub_object( + VPARSE_T *p_parse, /* Current parse state info */ + char *p_type /* Type of object */ + ) +{ + bool_t ok = FALSE; + VOBJECT_T *p_parent = p_parse->p_object; + + if (p_parent) + { + VPROP_T *p_tmp; + + ok = append_value_to_object(&p_tmp, p_parse); + + if (ok && p_tmp) + { + ok = alloc_object(&p_tmp->value.v.o.p_object, p_parent, p_type, p_parse); + } + } + + return ok; +} + + + + + + +/*----------------------------------------------------------------------------* + * NAME + * alloc_object() + * + * DESCRIPTION + * Allocate & initialise a new VOBJECT_T. The new element od made the + * current parse target (ie. new properties will be added to it). + * + * RETURNS + * TRUE <=> allocation went OK, FALSE else. + *---------------------------------------------------------------------------*/ + +bool_t alloc_object( + VOBJECT_T **pp_new, /* Pointer to output pointer */ + VOBJECT_T *p_parent, /* Parent of new node */ + char *p_type, /* Type of new node */ + VPARSE_T *p_parse /* Current parse info */ + ) +{ + bool_t ok = TRUE; + VOBJECT_T *p_new; + + p_new = (VOBJECT_T *)vf_malloc(sizeof(VOBJECT_T)); + + if (p_new) + { + p_memset(p_new, '\0', sizeof(VOBJECT_T)); + + p_new->p_parent = p_parent; + p_new->p_type = p_type; + + p_parse->p_object = p_new; + + *pp_new = p_new; + } + else + { + ok = FALSE; + } + + return ok; +} + + + + + + + +/*----------------------------------------------------------------------------* + * NAME + * handle_base64_chars() + * + * DESCRIPTION + * Handle BASE64 decoding. + * + * RETURNS + * TRUE <=> allocation OK, FALSE else. + *---------------------------------------------------------------------------*/ + +bool_t handle_base64_chars( + VPARSE_T *p_parse, /* The property value we're adding to */ + const char *p_chars, /* Pointer to characters to add */ + int numchars /* Number of characters */ + ) +{ + bool_t ok = TRUE; + + /* + * Skip spaces. + */ + while ((0 < numchars) && (SPACE == p_chars[0])) + { + numchars--; + p_chars++; + } + + /* + * Convert groups of 4 characters to byte triplets & append the bytes + * to the binary data. + */ + if (0 < numchars) + { + int i, j, len, num, left; + const char *p_quad; + + len = numchars; + num = len / 4; + left = len % 4; + + for (i = 0, p_quad = p_chars;(i < num);i++, p_quad += 4) + { + uint32_t b; + char bytes[3]; + uint8_t bits; + + for (j = 0, b = 0, bits = 0;(j < 4);j++) + { + b = (b << 6) | base64_to_char(p_quad[j]); + + if (EQUALS != p_quad[j]) + { + bits += 6; + } + } + + for (j = 0;(j < 3);j++) + { + bytes[2 - j] = (unsigned char)(b & 0xFF); + + b >>= 8; + } + + ok = append_to_pointer(&(p_parse->prop.value.v.b.p_buffer), &(p_parse->prop.value.v.b.n_bufsize), bytes, bits / 8); + } + } + + return ok; +} + + + + + + +/*----------------------------------------------------------------------------* + * NAME + * append_value_to_object() + * + * DESCRIPTION + * Append characters to the name half of a VOBJECT_T. The VOBJECT is + * allocated if not already present. + * + * RETURNS + * TRUE <=> allocation OK, FALSE else. + *---------------------------------------------------------------------------*/ + +bool_t append_value_to_object( + VPROP_T **pp_prop, /* Pointer to the new property */ + VPARSE_T *p_parse /* The property we're naming */ + ) +{ + bool_t ok = FALSE; + + VPROP_T **pp_tmp; + VPROP_T *p_prop; + + pp_tmp = &(p_parse->p_object->p_props); + + while (*pp_tmp) + { + pp_tmp = &((*pp_tmp)->p_next); + } + + *pp_tmp = p_prop = (VPROP_T *)vf_malloc(sizeof(VPROP_T)); + + if (pp_prop) + { + *pp_prop = p_prop; + } + + if (p_prop) + { + p_memset(p_prop, '\0', sizeof(VPROP_T)); + + *p_prop = p_parse->prop; + + p_memset(&(p_parse->prop), '\0', sizeof(VPROP_T)); + + p_prop->p_parent = p_parse->p_object; + + ok = TRUE; + } + + return ok; +} + + + + + + + +/*----------------------------------------------------------------------------* + * NAME + * deduce_encoding() + * + * DESCRIPTION + * Check property name for encoding tags. If none present, return the + * default encoding. + * + * RETURNS + * vf_encoding_t. + *---------------------------------------------------------------------------*/ + +vf_encoding_t deduce_encoding( + VSTRARRAY_T *p_propname /* Property name */ + ) +{ + vf_encoding_t ret = VF_ENC_7BIT; + + if (string_array_contains_string(p_propname, NULL, -1, VFP_QUOTEDPRINTABLE, FALSE)) + { + ret = VF_ENC_QUOTEDPRINTABLE; + } + else + if (string_array_contains_string(p_propname, NULL, -1, VFP_BASE64, FALSE)) + { + ret = VF_ENC_BASE64; + } + else + if (string_array_contains_string(p_propname, NULL, -1, VFP_8BIT, FALSE)) + { + ret = VF_ENC_8BIT; + } + + return ret; +} + + + + + + + +/*----------------------------------------------------------------------------* + * NAME + * is_hex_digit() + * + * DESCRIPTION + * + * + * RETURNS + * TRUE <=> valid HEX digit read. + *---------------------------------------------------------------------------*/ + +bool_t is_hex_digit( + char *p_nibble, /* Output nibble value */ + char c /* Character read from file */ + ) +{ + bool_t ret = TRUE; + + if (('A' <= c) && (c <= 'F')) + { + *p_nibble = c - 'A' + 10; + } + else + if (('a' <= c) && (c <= 'f')) + { + *p_nibble = c - 'a' + 10; + } + else + if (('0' <= c) && (c <= '9')) + { + *p_nibble = c - '0'; + } + else + { + ret = FALSE; + } + + return ret; +} + + + + + +/*----------------------------------------------------------------------------* + * NAME + * base64_to_char() + * + * DESCRIPTION + * Convert base 64 char to byte. + * + * RETURNS + * Number corresponding to char. + *---------------------------------------------------------------------------*/ + +uint8_t base64_to_char(char c) +{ + if (('A' <= c) && (c <= 'Z')) + return c - 'A'; + + if (('a' <= c) && (c <= 'z')) + return c - 'a' + 26; + + if (('0' <= c) && (c <= '9')) + return c - '0' + 52; + + if ('+' == c) + return 62; + + if ('/' == c) + return 63; + + return 0x00; +} + + +/*============================================================================* + End Of File + *===========================================================================*/ diff --git a/src/vf_reader.c b/src/vf_reader.c new file mode 100644 index 0000000..667279f --- /dev/null +++ b/src/vf_reader.c @@ -0,0 +1,277 @@ +/****************************************************************************** + + (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_reader.c $ + $Revision: 1.18 $ + $Author: tilda $ + +ORIGINAL AUTHOR + Nick Marley. + +DESCRIPTION + Code for reading vformat files from disk. Delegates the real responsibility + to vf_parser for actually converting chunks of text into the memory data + structure. + +REFERENCES + (none) + +MODIFICATION HISTORY + * $Log: vf_reader.c,v $ + * Revision 1.18 2002/11/15 09:20:59 tilda + * IID638823 - Don't include unistd.h unless required. + * + * Revision 1.17 2002/11/15 09:15:00 tilda + * IID638823 - Various portability issues. + * + * Revision 1.16 2002/11/03 18:43:16 tilda + * IID619851 - Update and check headers and function prototypes. + * + * Revision 1.15 2002/10/26 16:09:23 tilda + * IID629125 - Ensure string functions used are portable. + * + * Revision 1.14 2002/10/08 21:11:36 tilda + * Remove common.h. + * + * Revision 1.13 2001/12/13 06:45:35 tilda + * IID488021 - Various bugs with quoted printable format. + * + * Revision 1.12 2001/11/05 21:07:19 tilda + * Various changes for initial version of vfedit. + * + * Revision 1.11 2001/10/24 18:36:06 tilda + * BASE64 bugfixes. Split reader/writer code. Start create/modify work. + * + * Revision 1.10 2001/10/24 05:32:19 tilda + * BASE64 bugfixes - first part + * + * Revision 1.9 2001/10/16 05:50:53 tilda + * Debug support for lists of vobjects from single file (ie. a phonebook). + * + * Revision 1.8 2001/10/14 19:53:36 tilda + * Group handling. NO group searching functions. + * + * Revision 1.7 2001/10/13 16:22:08 tilda + * Introduce VBINDATA_T and VOBJDATA_T to tidy up internals. + * + * Revision 1.6 2001/10/13 14:58:56 tilda + * Tidy up version headers, add vf_strings.h where needed. + * + * Revision 1.5 2001/10/13 14:49:30 tilda + * Add string array code to unify handling of names / values. + * + * Revision 1.4 2001/10/12 16:20:02 tilda + * Correctly parse compound quoted printable properties. + * + * Revision 1.3 2001/10/10 20:53:55 tilda + * Various minor tidy ups. + * + * Revision 1.2 2001/10/09 22:01:59 tilda + * Remove older version control comments. + * + *******************************************************************************/ + +#ifndef NORCSID +static const char vf_reader_c_vss_id[] = "$Header: /cvsroot/vformat/src/vformat/src/vf_reader.c,v 1.18 2002/11/15 09:20:59 tilda Exp $"; +#endif + +/*=============================================================================* + ANSI C & System-wide Header Files + *=============================================================================*/ + +#include + +#include +#include + +#if defined(HAS_UNISTD_H) +#include +#endif + +#if defined(WIN) || defined(WIN32) +#include +#endif + + +/*============================================================================* + Interface Header Files + *============================================================================*/ + +#include + +/*============================================================================* + Local Header File + *============================================================================*/ + +#include "vf_config.h" +#include "vf_internals.h" +#include "vf_malloc.h" + +/*============================================================================* + Public Data + *============================================================================*/ +/* None */ + +/*============================================================================* + Private Defines + *============================================================================*/ + +#define PARSEBUFSIZE (1024) + +/*============================================================================* + Private Data Types + *============================================================================*/ +/* None */ + +/*============================================================================* + Private Function Prototypes + *============================================================================*/ +/* None */ + +/*============================================================================* + Private Data + *============================================================================*/ +/* None */ + +/*============================================================================* + Public Function Implementations + *============================================================================*/ + +/*----------------------------------------------------------------------------* + * NAME + * vf_read_file() + * + * DESCRIPTION + * Reads indicated VOBJECT_T file. + * + * RETURNS + * TRUE <=> read OK, FALSE else. + *----------------------------------------------------------------------------*/ + +bool_t vf_read_file( + VF_OBJECT_T **pp_object, + const char *p_name + ) +{ + bool_t ret = FALSE; + + if (pp_object) + { + FILE *fp; + + fp = fopen(p_name, "rb"); + + if (fp) + { + char buffer[PARSEBUFSIZE]; + int charsread; + VF_PARSER_T *p_parser; + + if (vf_parse_init(&p_parser, pp_object)) + { + do + { + charsread = read(fileno(fp), buffer, sizeof(buffer)); + + if (0 < charsread) + { + ret = vf_parse_text(p_parser, buffer, charsread); + } + } + while (ret && (0 < charsread)) + ; + + if (!vf_parse_end(p_parser)) + { + ret = FALSE; + } + } + + if (0 == fclose(fp)) + { + /* OK */ + } + else + { + ret = FALSE; + } + } + } + + return ret; +} + + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_set_property_from_file() + * + * DESCRIPTION + * Loads the indicated file into memory and sets the indicated property. + * + * RETURNS + * (none) + *---------------------------------------------------------------------------*/ + +bool_t vf_set_property_from_file( + VF_PROP_T *p_prop, /* The property */ + vf_encoding_t encoding, /* Encoding to use */ + const char *p_filename /* Source filename */ + ) +{ + bool_t ret = FALSE; + struct stat buf; + + if (0 == stat(p_filename, &buf)) + { + uint8_t *p_data = vf_malloc(buf.st_size); + + if (p_data) + { + FILE *fp = fopen(p_filename, "rb"); + + if (fp) + { + if ((int)buf.st_size == read(fileno(fp), p_data, buf.st_size)) + { + ret = TRUE; + } + + if (0 == fclose(fp)) + { + /* */ + } + else + { + ret = FALSE; + } + + if (ret) + { + ret &= vf_set_prop_value(p_prop, p_data, buf.st_size, encoding, TRUE); + } + } + + vf_free(p_data); + } + } + + return ret; +} + + +/*============================================================================* + Private Function Implementations + *============================================================================*/ +/* None */ + +/*============================================================================* + End Of File + *============================================================================*/ diff --git a/src/vf_search.c b/src/vf_search.c new file mode 100644 index 0000000..71be484 --- /dev/null +++ b/src/vf_search.c @@ -0,0 +1,457 @@ +/**************************************************************************** + + (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.11 $ + $Author: tilda $ + +ORIGINAL AUTHOR + Nick Marley + +DESCRIPTION + Basic searching functions for the vformat library. + +REFERENCES + (none) + +MODIFICATION HISTORY + * $Log: vf_search.c,v $ + * Revision 1.11 2002/11/03 18:43:16 tilda + * IID619851 - Update and check headers and function prototypes. + * + * Revision 1.10 2002/11/02 18:29:26 tilda + * IID485157 - UI does character conversion based on CHARSET property. + * + * Revision 1.9 2002/10/26 16:09:23 tilda + * IID629125 - Ensure string functions used are portable. + * + * Revision 1.8 2002/10/08 21:45:07 tilda + * IID620473 - reduce c-runtime dependencies. + * + * Revision 1.7 2002/10/08 21:11:36 tilda + * Remove common.h. + * + * Revision 1.6 2002/02/24 17:10:34 tilda + * Add API for "is modified" functionality. + * + * Revision 1.5 2001/11/18 21:46:59 tilda + * Remove redundant code. + * + * Revision 1.4 2001/11/16 22:34:50 tilda + * New vf_get_property() allows append as well as find, + * + * Revision 1.3 2001/11/05 21:07:19 tilda + * Various changes for initial version of vfedit. + * + * Revision 1.2 2001/10/24 18:56:29 tilda + * Tidy headers after import. Fix include path in release build. + * + * Revision 1.1 2001/10/24 18:34:35 tilda + * Initial Version. + * + *****************************************************************************/ + +#ifndef NORCSID +static const char vf_search_c_vss_id[] = "$Header: /cvsroot/vformat/src/vformat/src/vf_search.c,v 1.11 2002/11/03 18:43:16 tilda Exp $"; +#endif + +/*============================================================================* + ANSI C & System-wide Header Files + *============================================================================*/ + +#include + +/*===========================================================================* + Interface Header Files + *===========================================================================*/ + +#include "vformat/vf_iface.h" + +/*===========================================================================* + Local Header File + *===========================================================================*/ + +#include "vf_config.h" +#include "vf_malloc.h" +#include "vf_internals.h" +#include "vf_strings.h" +#include "vf_string_arrays.h" + +/*===========================================================================* + Public Data + *===========================================================================*/ +/* None */ + +/*===========================================================================* + Private Defines + *===========================================================================*/ + +/* + * Maximum supported search tags. + */ +#define MAXNUMTAGS (10) + +/*===========================================================================* + Private Data Types + *===========================================================================*/ +/* None */ + +/*===========================================================================* + Private Function Prototypes + *===========================================================================*/ + + +/*===========================================================================* + Private Data + *===========================================================================*/ +/* None */ + +/*===========================================================================* + Public Function Implementations + *===========================================================================*/ + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_get_property() + * + * DESCRIPTION + * Basic searching function locating elements of the VOBJECT by qualified + * name. The function is a varargs function (like sprintf) and the list + * of arguments must be NULL terminated (hence the appearance of the + * p_qualifier argument in the arglist). Valid calls might be: + * + * vf_get_property(&p_out, p_object, FALSE, NULL, "N", NULL); + * vf_get_property(&p_out, p_object, FALSE, NULL, "TEL", "WORK", NULL); + * vf_get_property(&p_out, p_object, FALSE, "ME", "TEL", "WORK", NULL); + * vf_get_property(&p_out, p_object, FALSE, "ME", "*", NULL); + * + * A pointer to the first property matching the search criteria is returned + * the pp_prop argument. The search actually locates all such matches and + * pointer to subsequent entries (if there are >1) may be found by calling + * the vf_get_next_property() function. + * + * Qualifying tags (ie. not the name) may occur in any order + * + * Note that the VF_PROP_T returned vi pp_prop is an opaque type and the + * various accessor functions must be used to get to the data. + * + * RETURNS + * TRUE iff found/added successfully. ptr to prop returned via pp_prop. + *---------------------------------------------------------------------------*/ + +bool_t vf_get_property( + VF_PROP_T **pp_prop, /* Output pointer */ + VF_OBJECT_T *p_object, /* Object to add to */ + vf_get_t ops, /* Search flags */ + const char *p_group, /* Group name if any */ + const char *p_name, /* Name of tag */ + const char *p_qualifier, /* First qualifier if any */ + ... /* Subequent qualifiers */ + ) +{ + bool_t ret = FALSE; + va_list args; + + va_start(args, p_qualifier); + + ret = vf_get_property_ex(pp_prop, p_object, ops, p_group, p_name, p_qualifier, args); + + va_end(args); + + return ret; +} + + + + + + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_get_property_ex() + * + * DESCRIPTION + * The grunt behind vf_get_property(). Manages the search as described + * vf_get_property() but takes the list of arguments as a va_list. + * + * RETURNS + * TRUE iff found / appended OK. + *---------------------------------------------------------------------------*/ + +bool_t vf_get_property_ex( + VF_PROP_T **pp_prop, /* Output pointer */ + VF_OBJECT_T *p_object, /* Object to search */ + vf_get_t ops, /* Search flags */ + const char *p_group, /* Group name if any */ + const char *p_name, /* Name of tag */ + const char *p_qualifier, /* First qualifier if any */ + va_list args /* Argument list */ + ) +{ + bool_t ret = FALSE; + char **pp_tags = NULL; + + if (!p_name || !p_object) + return ret; + + if (pp_prop) + { + *pp_prop = NULL; + } + + pp_tags = (char **)vf_malloc(MAXNUMTAGS * sizeof(char *)); + + if (pp_tags) + { + VOBJECT_T *p_obj = (VOBJECT_T *)p_object; + VPROP_T *p_props = p_obj->p_props; + int i; + + VPROP_T **pp_lastprop = &(p_obj->p_props); + VPROP_T **pp_next_srch = NULL; + + p_memset(pp_tags, '\0', MAXNUMTAGS * sizeof(char *)); + + pp_tags[0] = (char *)p_name; + + /* + * The name is the first tag. We insist on there being at least one qualifier in the + * argument list to make sure callers terminate the list. Subsequent arguments are + * optional, but will be ignored if the (first) qualifier is NULL. + */ + if (p_qualifier) + { + pp_tags[1] = (char *)p_qualifier; + + for (i = 2;i < MAXNUMTAGS;i++) + { + char *p_tag = va_arg(args, char *); + + if (p_tag) + { + pp_tags[i] = p_tag; + } + else + { + break; + } + } + } + + if (ops & VFGP_FIND) + { + /* + * Skip down the list or properties. I'm assuming that we only want to search the + * current object for properties not the current object AND any contained objects. + * Such a search sounds a bit application specific, ie. the caller would be looking + * for a particular structure of things. Each element that is found is stitched + * into the emerging list. + */ + for (;NULL != p_props;p_props = p_props->p_next) + { + bool_t found = TRUE; + + /* + * Check the name & qualifiers. + */ + for (i = 0;found && (i < MAXNUMTAGS) && pp_tags[i];i++) + { + if (0 != p_strcmp(VFP_ANY, pp_tags[i])) + found &= string_array_contains_string(&p_props->name, NULL, -1, pp_tags[i], TRUE); + } + if (p_group && found) + { + found = FALSE; + + if (p_props->p_group) + { + if (0 == p_stricmp(p_props->p_group, p_group)) + { + found = TRUE; + } + } + else + { + /* Search group specified & property doesn't have a group => not required */ + } + } + + if (found) + { + if (pp_prop) + { + if (!*pp_prop) + { + pp_next_srch = &(p_props->p_next_srch); + p_props->p_next_srch = NULL; + + *pp_prop = (VF_PROP_T *)p_props; + } + else + { + *pp_next_srch = p_props; + + pp_next_srch = &(p_props->p_next_srch); + p_props->p_next_srch = NULL; + } + } + + ret = TRUE; + } + + if (p_props->p_next) + { + pp_lastprop = &(p_props->p_next); + } + } + } + + if (!ret && (ops & VFGP_APPEND)) + { + VPROP_T *p_new = (VPROP_T *)vf_malloc(sizeof(VPROP_T)); + + if (p_new) + { + ret = TRUE; + + p_memset(p_new, '\0', sizeof(VPROP_T)); + + p_new->p_parent = p_obj; + + for (i = 0;ret && (i < MAXNUMTAGS) && pp_tags[i];i++) + { + ret = add_string_to_array(&p_new->name, pp_tags[i]); + } + + if (ret) + { + /* All OK */ + + p_new->value.encoding = VF_ENC_7BIT; + } + else + { + free_string_array_contents(&p_new->name); + + vf_free(p_new); + p_new = NULL; + } + } + + if (p_new) + { + if (pp_prop) + { + *pp_prop = (VF_PROP_T *)p_new; + } + + p_new->p_next = *pp_lastprop; + *pp_lastprop = p_new; + + ret = TRUE; + } + } + + vf_free(pp_tags); + } + + return ret; +} + + + + + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_get_next_property() + * + * DESCRIPTION + * Find the next property given the current search critera. + * + * RETURNS + * TRUE iff found, FALSE else. *pp_prop points to the next property. + *---------------------------------------------------------------------------*/ + +bool_t vf_get_next_property( + VF_PROP_T **pp_prop /* Output pointer */ + ) +{ + bool_t ret = FALSE; + + if (pp_prop) + { + VPROP_T **pp_vprop = (VPROP_T **)pp_prop; + + if (*pp_vprop) + { + *pp_prop = (VF_PROP_T *)((*pp_vprop)->p_next_srch); + + if (*pp_prop) + { + ret = TRUE; + } + } + } + + return ret; +} + + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_get_next_object() + * + * DESCRIPTION + * Find "next" vobject. + * + * RETURNS + * TRUE iff found next object. + *---------------------------------------------------------------------------*/ + +bool_t vf_get_next_object( + VF_OBJECT_T **pp_object + ) +{ + bool_t ret = FALSE; + + if (pp_object) + { + if (*pp_object) + { + *pp_object = (VF_OBJECT_T *)(((VOBJECT_T *)(*pp_object))->p_next); + + if (*pp_object) + { + ret = TRUE; + } + } + } + + return ret; +} + + + + +/*===========================================================================* + Private Function Implementations + *===========================================================================*/ +/* None */ + +/*===========================================================================* + End Of File + *===========================================================================*/ diff --git a/src/vf_string_arrays.c b/src/vf_string_arrays.c new file mode 100644 index 0000000..eee27f4 --- /dev/null +++ b/src/vf_string_arrays.c @@ -0,0 +1,435 @@ +/****************************************************************************** + + (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.4 $ + $Author: tilda $ + +ORIGINAL AUTHOR + Nick Marley + +DESCRIPTION + Utility functions handling string arrays - the VSTRARRAY_T type. + +REFERENCES + (none) + +MODIFICATION HISTORY + * $Log: vf_string_arrays.c,v $ + * Revision 1.4 2002/11/03 18:43:16 tilda + * IID619851 - Update and check headers and function prototypes. + * + * Revision 1.3 2002/11/02 18:29:26 tilda + * IID485157 - UI does character conversion based on CHARSET property. + * + * Revision 1.2 2002/10/29 07:19:20 tilda + * Tidy headers. + * + * Revision 1.1 2002/10/26 15:57:11 tilda + * Initial Version + * + *******************************************************************************/ + +#ifndef NORCSID +static const char vf_string_arrays_c_vss_id[] = "$Header: /cvsroot/vformat/src/vformat/src/vf_string_arrays.c,v 1.4 2002/11/03 18:43:16 tilda Exp $"; +#endif + +/*=============================================================================* + ANSI C & System-wide Header Files + *=============================================================================*/ + +#include + +/*============================================================================* + Interface Header Files + *============================================================================*/ + +#include "vformat/vf_iface.h" + +/*============================================================================* + Local Header File + *============================================================================*/ + +#include "vf_config.h" +#include "vf_malloc.h" +#include "vf_internals.h" +#include "vf_strings.h" +#include "vf_string_arrays.h" + +/*============================================================================* + Public Data + *============================================================================*/ +/* None */ + +/*============================================================================* + Private Defines + *============================================================================*/ +/* None */ + +/*============================================================================* + Private Data Types + *============================================================================*/ +/* None */ + +/*============================================================================* + Private Function Prototypes + *============================================================================*/ +/* None */ + +/*============================================================================* + Private Data + *============================================================================*/ +/* None */ + +/*============================================================================* + Public Function Implementations + *============================================================================*/ + + +/*----------------------------------------------------------------------------* + * NAME + * string_array_contains_string() + * + * DESCRIPTION + * Checks the strings in the indicated array to see if it contains a + * particulr value. Can check a particular index or the whole array. + * Can perform an exact match or check wether one of the strings simply + * contains the value. + * + * RETURNS + * TRUE <=> includes indicated value, FALSE else. + *----------------------------------------------------------------------------*/ + +bool_t string_array_contains_string( + VSTRARRAY_T *p_strarray, /* String array */ + char **pp_string_found, /* String found */ + uint32_t index, /* Which entry, (-1) => any */ + const char *p_string, /* The string we're looking for */ + bool_t exact /* Exact or partial match */ + ) +{ + bool_t ret = FALSE; + uint32_t i; + uint32_t s, e; + + if (index == (-1)) + { + s = 0; + e = p_strarray->n_strings; + } + else + { + s = index; + e = index + 1; + } + + for (i = s;!ret && (i < e);i++) + { + if ((i < p_strarray->n_strings) && p_strarray->pp_strings[i]) + { + if (exact) + { + if (0 == p_stricmp(p_strarray->pp_strings[i], p_string)) + ret = TRUE; + } + else + { + if (p_strstr(p_strarray->pp_strings[i], p_string)) + ret = TRUE; + } + } + + if (ret && pp_string_found) + { + *pp_string_found = p_strarray->pp_strings[i]; + } + } + + return ret; +} + + + + + + +/*----------------------------------------------------------------------------* + * NAME + * add_string_to_array() + * + * DESCRIPTION + * Append string to indicated array. + * + * RETURNS + * TRUE <=> allocation OK, FALSE else. + *----------------------------------------------------------------------------*/ + +bool_t add_string_to_array( + VSTRARRAY_T *p_strarray, /* String array */ + const char *p_string /* String to add */ + ) +{ + char **pp_new; + bool_t ret = FALSE; + + pp_new = vf_realloc(p_strarray->pp_strings, sizeof(char *) * (1 + p_strarray->n_strings)); + + if (pp_new) + { + if (p_string) + { + uint32_t l; + char *p_strcopy; + + l = p_strlen(p_string); + + p_strcopy = vf_malloc(1 + l); + + if (p_strcopy) + { + p_strcpy(p_strcopy, p_string); + + pp_new[p_strarray->n_strings] = p_strcopy; + + ret = TRUE; + } + else + { + vf_free(pp_new); + } + } + else + { + pp_new[p_strarray->n_strings] = NULL; + + ret = TRUE; + } + + if (ret) + { + p_strarray->n_strings += 1; + p_strarray->pp_strings = pp_new; + } + } + + return ret; +} + + + + + +/*----------------------------------------------------------------------------* + * NAME + * free_string_array_contents() + * + * DESCRIPTION + * Delete contents of a string array. The structure itself is not free()d. + * + * RETURNS + * (none) + *----------------------------------------------------------------------------*/ + +void free_string_array_contents( + VSTRARRAY_T *p_strarray /* String array */ + ) +{ + if (p_strarray && p_strarray->pp_strings) + { + uint32_t i; + + for (i = 0;i < p_strarray->n_strings;i++) + { + if (p_strarray->pp_strings[i]) + { + vf_free(p_strarray->pp_strings[i]); + p_strarray->pp_strings[i] = NULL; + } + } + + vf_free(p_strarray->pp_strings); + p_strarray->pp_strings = NULL; + + p_strarray->n_strings = 0; + } +} + + + + + + + +/*----------------------------------------------------------------------------* + * NAME + * append_to_curr_string() + * + * DESCRIPTION + * Append characters to the current string in a string array. + * + * RETURNS + * TRUE <=> allocation OK, FALSE else. + *----------------------------------------------------------------------------*/ + +bool_t append_to_curr_string( + VSTRARRAY_T *p_strarray, /* String array */ + uint32_t *p_length, /* Pointer to length, NULL if zero terminated */ + const char *p_chars, /* Characters to append */ + uint32_t numchars /* Number of characters */ + ) +{ + bool_t ret = TRUE; + + if (p_strarray && !p_strarray->pp_strings) + { + ret = add_string_to_array(p_strarray, ""); + } + + if (ret) + { + ret = append_to_pointer(&(p_strarray->pp_strings[p_strarray->n_strings - 1]), p_length, p_chars, numchars); + } + + return ret; +} + + + + + + + +/*----------------------------------------------------------------------------* + * NAME + * append_to_pointer() + * + * DESCRIPTION + * Append characters to indicated pointer. Handles both NULL terminated + * strings (for simple 7-bit values) and buffer/length pairs. Passing + * the p_length field indicates that we're building up binary data. + * + * RETURNS + * TRUE <=> allocation OK, FALSE else. + *----------------------------------------------------------------------------*/ + +bool_t append_to_pointer( + char **pp_string, /* String we're appending to */ + uint32_t *p_length, /* Pointer to length, NULL if ZT */ + const char *p_chars, /* Chars we're appending */ + int numchars /* Number of chars we're appending */ + ) +{ + bool_t ok = FALSE; + + if (pp_string) + { + int newlen, currlen; + char *p_new; + + newlen = numchars; + + if (*pp_string) + { + currlen = p_length ? *p_length : p_strlen(*pp_string); + + newlen += currlen; + } + else + { + currlen = 0; + } + + p_new = vf_realloc(*pp_string, newlen + (p_length ? 0 : 1)); + + if (p_new) + { + p_memcpy(p_new + currlen, p_chars, numchars); + + if (p_length) + { + *p_length = newlen; + } + else + { + p_new[newlen] = '\0'; + } + + *pp_string = p_new; + ok = TRUE; + } + } + + return ok; +} + + + + + + + +/*----------------------------------------------------------------------------* + * NAME + * set_string_array_entry() + * + * DESCRIPTION + * Set indicated entry in a string array. + * + * RETURNS + * TRUE <=> allocation OK, FALSE else. + *----------------------------------------------------------------------------*/ + +bool_t set_string_array_entry( + VSTRARRAY_T *p_strarray, /* String array */ + const char *p_string, /* String to insert */ + uint32_t n_string /* Insertion point */ + ) +{ + bool_t ret = FALSE; + + if (n_string < p_strarray->n_strings) + { + if (p_strarray->pp_strings[n_string]) + { + vf_free(p_strarray->pp_strings[n_string]); + p_strarray->pp_strings[n_string] = NULL; + } + + if (p_string) + { + uint32_t len = p_strlen(p_string); + + p_strarray->pp_strings[n_string] = vf_malloc(1 + len); + + if (p_strarray->pp_strings[n_string]) + { + p_strcpy(p_strarray->pp_strings[n_string], p_string); + + ret = TRUE; + } + } + else + { + /* NULL = "delete" */ + + ret = TRUE; + } + } + + return ret; +} + + +/*============================================================================* + Private Function Implementations + *============================================================================*/ +/* None */ + +/*============================================================================* + End Of File + *============================================================================*/ diff --git a/src/vf_string_arrays.h b/src/vf_string_arrays.h new file mode 100644 index 0000000..252da03 --- /dev/null +++ b/src/vf_string_arrays.h @@ -0,0 +1,177 @@ +/******************************************************************************* + + (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_internals.h $ + $Revision: 1.2 $ + $Author: tilda $ + +ORIGINAL AUTHOR + Nick Marley + +DESCRIPTION + Utility functions handling string arrays - the VSTRARRAY_T type. + +REFERENCES + (none) + +MODIFICATION HISTORY + * $Log: vf_string_arrays.h,v $ + * Revision 1.2 2002/11/02 18:29:26 tilda + * IID485157 - UI does character conversion based on CHARSET property. + * + * Revision 1.1 2002/10/26 15:57:11 tilda + * Initial Version + * + *******************************************************************************/ + +#ifndef _VF_STRING_ARRAYS_H_ +#define _VF_STRING_ARRAYS_H_ + +#ifndef NORCSID +static const char vf_string_arrays_h_vss_id[] = "$Header: /cvsroot/vformat/src/vformat/src/vf_string_arrays.h,v 1.2 2002/11/02 18:29:26 tilda Exp $"; +#endif + +/*=============================================================================* + Public Includes + *============================================================================*/ +/* None */ + +/*=============================================================================* + Public Defines + *============================================================================*/ +/* None */ + +/*=============================================================================* + Public Types + *============================================================================*/ +/* None */ + +/*=============================================================================* + Public Functions + *============================================================================*/ + + +/*----------------------------------------------------------------------------* + * NAME + * string_array_contains_string() + * + * DESCRIPTION + * Checks the strings in the indicated array to see if it contains a + * particulr value. Can check a particular index or the whole array. + * Can perform an exact match or check wether one of the strings simply + * contains the value. + * + * RETURNS + * TRUE <=> includes indicated value, FALSE else. + *----------------------------------------------------------------------------*/ + +extern bool_t string_array_contains_string( + VSTRARRAY_T *p_strarray, /* String array */ + char **pp_string_found, /* String found */ + uint32_t index, /* Which entry, (-1) => any */ + const char *p_string, /* The string we're looking for */ + bool_t exact /* Exact or partial match */ + ); + + +/*----------------------------------------------------------------------------* + * NAME + * add_string_to_array() + * + * DESCRIPTION + * Append string to indicated array. + * + * RETURNS + * TRUE <=> allocation OK, FALSE else. + *----------------------------------------------------------------------------*/ + +extern bool_t add_string_to_array( + VSTRARRAY_T *p_strarray, /* String array */ + const char *p_string /* String to add */ + ); + + +/*----------------------------------------------------------------------------* + * NAME + * free_string_array_contents() + * + * DESCRIPTION + * Delete contents of a string array. The structure itself is not free()d. + * + * RETURNS + * (none) + *----------------------------------------------------------------------------*/ + +extern void free_string_array_contents( + VSTRARRAY_T *p_strarray /* String array */ + ); + + +/*----------------------------------------------------------------------------* + * NAME + * append_to_curr_string() + * + * DESCRIPTION + * Append characters to the current string in a string array. + * + * RETURNS + * TRUE <=> allocation OK, FALSE else. + *----------------------------------------------------------------------------*/ + +extern bool_t append_to_curr_string( + VSTRARRAY_T *p_strarray, /* String array */ + uint32_t *p_length, /* Pointer to length, NULL if zero terminated */ + const char *p_chars, /* Characters to append */ + uint32_t numchars /* Number of characters */ + ); + + +/*----------------------------------------------------------------------------* + * NAME + * append_to_pointer() + * + * DESCRIPTION + * Append characters to indicated pointer. Handles both NULL terminated + * strings (for simple 7-bit values) and buffer/length pairs. Passing + * the p_length field indicates that we're building up binary data. + * + * RETURNS + * TRUE <=> allocation OK, FALSE else. + *----------------------------------------------------------------------------*/ + +extern bool_t append_to_pointer( + char **pp_string, /* String we're appending to */ + uint32_t *p_length, /* Pointer to length, NULL if ZT */ + const char *p_chars, /* Chars we're appending */ + int numchars /* Number of chars we're appending */ + ); + + +/*----------------------------------------------------------------------------* + * NAME + * set_string_array_entry() + * + * DESCRIPTION + * Set indicated entry in a string array. + * + * RETURNS + * TRUE <=> allocation OK, FALSE else. + *----------------------------------------------------------------------------*/ + +extern bool_t set_string_array_entry( + VSTRARRAY_T *p_strarray, /* String array */ + const char *p_string, /* String to insert */ + uint32_t n_string /* Insertion point */ + ); + + +/*=============================================================================* + End of file + *============================================================================*/ + +#endif /*_VF_STRING_ARRAYS_H_*/ diff --git a/src/vf_strings.c b/src/vf_strings.c new file mode 100644 index 0000000..204a188 --- /dev/null +++ b/src/vf_strings.c @@ -0,0 +1,472 @@ +/****************************************************************************** + + (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.9 $ + $Author: tilda $ + +ORIGINAL AUTHOR + Nick Marley + +DESCRIPTION + String handling functions. The library uses the p_ functions (where hopefully + the 'p' stands for 'portable') and they are provided here in terms of C runtime + functions or implemented explicitly. + +REFERENCES + (none) + +MODIFICATION HISTORY + * $Log: vf_strings.c,v $ + * Revision 1.9 2002/11/15 09:15:00 tilda + * IID638823 - Various portability issues. + * + * Revision 1.8 2002/10/26 16:09:23 tilda + * IID629125 - Ensure string functions used are portable. + * + * Revision 1.7 2002/10/08 21:45:07 tilda + * IID620473 - reduce c-runtime dependencies. + * + * Revision 1.6 2002/10/08 21:11:36 tilda + * Remove common.h. + * + * Revision 1.5 2001/11/05 21:07:19 tilda + * Various changes for initial version of vfedit. + * + * Revision 1.4 2001/10/14 20:42:37 tilda + * Addition of group searching. + * + * Revision 1.3 2001/10/13 16:22:08 tilda + * Introduce VBINDATA_T and VOBJDATA_T to tidy up internals. + * + * Revision 1.2 2001/10/13 14:58:56 tilda + * Tidy up version headers, add vf_strings.h where needed. + * + * Revision 1.1 2001/10/13 14:50:33 tilda + * Add string array code to unify handling of names / values. + * + *******************************************************************************/ + +#ifndef NORCSID +static const char vf_strings_c_vss_id[] = "$Header: /cvsroot/vformat/src/vformat/src/vf_strings.c,v 1.9 2002/11/15 09:15:00 tilda Exp $"; +#endif + +/*=============================================================================* + ANSI C & System-wide Header Files + *=============================================================================*/ + +#include + +#include +#include + +/*============================================================================* + Interface Header Files + *============================================================================*/ + +#include "vformat/vf_iface.h" + +/*============================================================================* + Local Header File + *============================================================================*/ + +#include "vf_config.h" +#include "vf_internals.h" +#include "vf_strings.h" + +/*============================================================================* + Public Data + *============================================================================*/ +/* None */ + +/*============================================================================* + Private Defines + *============================================================================*/ + + +/*============================================================================* + Private Data Types + *============================================================================*/ +/* None */ + +/*============================================================================* + Private Function Prototypes + *============================================================================*/ +/* None */ + +/*============================================================================* + Private Data + *============================================================================*/ +/* None */ + +/*============================================================================* + Public Function Implementations + *============================================================================*/ + + +/*----------------------------------------------------------------------------* + * NAME + * p_strlen() + * + * DESCRIPTION + * Find length of string. + * + * RETURNS + * Length of strings. + *----------------------------------------------------------------------------*/ + +int p_strlen( + const char *p_string /* String to measure */ + ) +{ +#if defined(HAVE_STRLEN) + return strlen(p_string); +#else + int len = 0; + + while (*p_string) + { + p_string++; + len++; + } + + return len; +#endif +} + + + + + +/*----------------------------------------------------------------------------* + * NAME + * p_strcpy() + * + * DESCRIPTION + * Copy string to buffer. + * + * RETURNS + * Pointer to buffer. + *----------------------------------------------------------------------------*/ + +char *p_strcpy( + char *p_string1, /* Buffer to copy to */ + const char *p_string2 /* String to copy */ + ) +{ +#if defined(HAVE_STRCPY) + return strcpy(p_string1, p_string2); +#else + char *p_return = p_string1; + + while ((*p_string1++ = *p_string2++)) + ; + + return p_return; +#endif +} + + + + + + +/*----------------------------------------------------------------------------* + * NAME + * p_strcmp() + * + * DESCRIPTION + * Case sensitive string comparison. + * + * RETURNS + * 0<=>strings match, !=0 else. + *----------------------------------------------------------------------------*/ + +int p_strcmp( + const char *p_string1, + const char *p_string2 + ) +{ +#if defined(HAVE_STRCMP) + return strcmp(p_string1, p_string2); +#else + while (*p_string1 && (*p_string1 == *p_string2)) + { + p_string1++; + p_string2++; + } + + return (*(unsigned char *)p_string1) - (*(unsigned char *)p_string2); +#endif +} + + + + + + +/*----------------------------------------------------------------------------* + * NAME + * p_strcat() + * + * DESCRIPTION + * Append one string to another. + * + * RETURNS + * Pointer to resulting string. + *----------------------------------------------------------------------------*/ + +char *p_strcat( + char *p_string1, /* String to append to */ + const char *p_string2 /* String to append */ + ) +{ +#if defined(HAVE_STRCAT) + return strcat(p_string1, p_string2); +#else + char *p_return = p_string1; + + while (*p_string1) + p_string1++; + + while ((*p_string1++ = *p_string2++)) + ; + + return p_return; +#endif +} + + + + + + +/*----------------------------------------------------------------------------* + * NAME + * p_strstr() + * + * DESCRIPTION + * Case sensitive string searching function. + * + * RETURNS + * Pointer to position "looked for" has been located or NULL if !found. + *----------------------------------------------------------------------------*/ + +char *p_strstr( + const char *p_searched, /* Buffer searched */ + const char *p_lookedfor /* String we're looking for */ + ) +{ +#if defined(HAVE_STRSTR) + return strstr(p_searched, p_lookedfor); +#else + if (*p_searched == 0) + { + if (*p_lookedfor) + { + return (char *)NULL; + } + + return (char *)p_searched; + } + + while (*p_searched) + { + uint32_t i; + + for (i = 0;;i++) + { + if (p_lookedfor[i] == 0) + { + return (char *)p_searched; + } + + if (p_lookedfor[i] != p_searched[i]) + { + break; + } + } + + p_searched++; + } + + return (char *)NULL; +#endif +} + + + + + + +/*----------------------------------------------------------------------------* + * NAME + * p_stricmp() + * + * DESCRIPTION + * Case insensitive string comparison function. + * + * RETURNS + * 0<=>strings match, !=0 else. + *----------------------------------------------------------------------------*/ + +int p_stricmp( + const char *p_string1, /* First string */ + const char *p_string2 /* Second string */ + ) +{ +#if defined(HAVE_STRCASECMP) + return strcasecmp(p_string1, p_string2); +#elif defined(HAVE_STRICMP) + return stricmp(p_string1, p_string2); +#else + while (*p_string1 && (tolower(*p_string1) == tolower(*p_string2))) + { + p_string1++; + p_string2++; + } + + return tolower(*(unsigned char *)p_string1) - tolower(*(unsigned char *)p_string2); +#endif +} + + + + + + + +/*----------------------------------------------------------------------------* + * NAME + * p_stristr() + * + * DESCRIPTION + * Case insensitive string searching function. + * + * RETURNS + * Pointer to position "looked for" has been located or NULL if !found. + *----------------------------------------------------------------------------*/ + +char *p_stristr( + const char *p_searched, /* Buffer searched */ + const char *p_lookedfor /* String we're looking for */ + ) +{ +#if defined(HAVE_STRISTR) + return strstr(p_searched, p_lookedfor); +#else + if (*p_searched == 0) + { + if (*p_lookedfor) + { + return (char *)NULL; + } + + return (char *)p_searched; + } + + while (*p_searched) + { + uint32_t i; + + for (i = 0;;i++) + { + if (p_lookedfor[i] == 0) + { + return (char *)p_searched; + } + + if (tolower(p_lookedfor[i]) != tolower(p_searched[i])) + { + break; + } + } + + p_searched++; + } + + return (char *)NULL; +#endif +} + + + + + + +/*----------------------------------------------------------------------------* + * NAME + * p_memcpy() + * + * DESCRIPTION + * Copy characetrs between buffers. No checks on overlap. + * + * RETURNS + * (none) + *----------------------------------------------------------------------------*/ + +void p_memcpy( + void *p_destination, /* Pointer to buffer */ + const void *p_source, /* Source of copy */ + uint32_t length /* Number of characters to copy */ + ) +{ +#if defined(HAVE_MEMCPY) + memcpy(p_destination, p_source, length); +#else + uint8_t *p_dst = (uint8_t *)p_destination; + uint8_t *p_src = (uint8_t *)p_source; + + while (length--) + { + *p_dst++ = *p_src++; + } +#endif +} + + + + + + +/*----------------------------------------------------------------------------* + * NAME + * p_memset() + * + * DESCRIPTION + * Fill buffer with indicated character. + * + * RETURNS + * (none) + *----------------------------------------------------------------------------*/ + +void p_memset( + void *p_destination, /* Pointer to buffer */ + uint8_t v, /* Character to fill with */ + uint32_t length /* Length of buffer to set */ + ) +{ +#if defined(HAVE_MEMSET) + memset(p_destination, v, length); +#else + uint8_t *p_dst = (uint8_t *)p_destination; + + while (length--) + *p_dst++ = v; +#endif +} + + +/*============================================================================* + Private Function Implementations + *============================================================================*/ +/* None */ + +/*============================================================================* + End Of File + *============================================================================*/ diff --git a/src/vf_strings.h b/src/vf_strings.h new file mode 100644 index 0000000..29ccd78 --- /dev/null +++ b/src/vf_strings.h @@ -0,0 +1,230 @@ +/******************************************************************************* + + (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.6 $ + $Author: tilda $ + +ORIGINAL AUTHOR + Nick Marley + +DESCRIPTION + String handling functions. The library uses the p_ functions (where hopefully + the 'p' stands for 'portable') and they are provided here in terms of C runtime + functions or implemented explicitly. + +REFERENCES + (none) + +MODIFICATION HISTORY + * $Log: vf_strings.h,v $ + * Revision 1.6 2002/10/26 16:09:23 tilda + * IID629125 - Ensure string functions used are portable. + * + * Revision 1.5 2002/10/08 21:27:20 tilda + * Correct #endif directive. + * + * Revision 1.4 2001/11/05 21:07:19 tilda + * Various changes for initial version of vfedit. + * + * Revision 1.3 2001/10/14 20:42:37 tilda + * Addition of group searching. + * + * Revision 1.2 2001/10/13 14:58:56 tilda + * Tidy up version headers, add vf_strings.h where needed. + * + * Revision 1.1 2001/10/13 14:50:33 tilda + * Add string array code to unify handling of names / values. + * + *******************************************************************************/ + +#ifndef _VF_STRINGS_H_ +#define _VF_STRINGS_H_ + +#ifndef NORCSID +static const char vf_strings_h_vss_id[] = "$Header: /cvsroot/vformat/src/vformat/src/vf_strings.h,v 1.6 2002/10/26 16:09:23 tilda Exp $"; +#endif + +/*=============================================================================* + Public Includes + *============================================================================*/ +/* None */ + +/*=============================================================================* + Public Defines + *============================================================================*/ +/* None */ + +/*=============================================================================* + Public Types + *============================================================================*/ +/* None */ + +/*=============================================================================* + Public Functions + *============================================================================*/ + + +/*----------------------------------------------------------------------------* + * NAME + * p_strlen() + * + * DESCRIPTION + * Find length of string. + * + * RETURNS + * Length of strings. + *----------------------------------------------------------------------------*/ + +extern int p_strlen( + const char *p_string /* String to measure */ + ); + + +/*----------------------------------------------------------------------------* + * NAME + * p_strcpy() + * + * DESCRIPTION + * Copy string to buffer. + * + * RETURNS + * Pointer to buffer. + *----------------------------------------------------------------------------*/ + +extern char *p_strcpy( + char *p_string1, /* Buffer to copy to */ + const char *p_string2 /* String to copy */ + ); + + +/*----------------------------------------------------------------------------* + * NAME + * p_strcmp() + * + * DESCRIPTION + * Case sensitive string comparison. + * + * RETURNS + * 0<=>strings match, !=0 else. + *----------------------------------------------------------------------------*/ + +extern int p_strcmp( + const char *p_string1, + const char *p_string2 + ); + + +/*----------------------------------------------------------------------------* + * NAME + * p_strcat() + * + * DESCRIPTION + * Append one string to another. + * + * RETURNS + * Pointer to resulting string. + *----------------------------------------------------------------------------*/ + +extern char *p_strcat( + char *p_string1, /* String to append to */ + const char *p_string2 /* String to append */ + ); + + +/*----------------------------------------------------------------------------* + * NAME + * p_strstr() + * + * DESCRIPTION + * Case sensitive string searching function. + * + * RETURNS + * Pointer to position "looked for" has been located or NULL if !found. + *----------------------------------------------------------------------------*/ + +extern char *p_strstr( + const char *p_searched, /* Buffer searched */ + const char *p_lookedfor /* String we're looking for */ + ); + + +/*----------------------------------------------------------------------------* + * NAME + * p_stricmp() + * + * DESCRIPTION + * Case insensitive string comparison function. + * + * RETURNS + * 0<=>strings match, !=0 else. + *----------------------------------------------------------------------------*/ + +extern int p_stricmp( + const char *p_string1, /* First string */ + const char *p_string2 /* Second string */ + ); + + +/*----------------------------------------------------------------------------* + * NAME + * p_stristr() + * + * DESCRIPTION + * Case insensitive string searching function. + * + * RETURNS + * Pointer to position "looked for" has been located or NULL if !found. + *----------------------------------------------------------------------------*/ + +extern char *p_stristr( + const char *p_searched, /* Buffer searched */ + const char *p_lookedfor /* String we're looking for */ + ); + +/*----------------------------------------------------------------------------* + * NAME + * p_memcpy() + * + * DESCRIPTION + * Copy characetrs between buffers. No checks on overlap. + * + * RETURNS + * (none) + *----------------------------------------------------------------------------*/ + +extern void p_memcpy( + void *p_destination, /* Pointer to buffer */ + const void *p_source, /* Source of copy */ + uint32_t length /* Number of characters to copy */ + ); + + +/*----------------------------------------------------------------------------* + * NAME + * p_memset() + * + * DESCRIPTION + * Fill buffer with indicated character. + * + * RETURNS + * (none) + *----------------------------------------------------------------------------*/ + +extern void p_memset( + void *p_destination, /* Pointer to buffer */ + uint8_t v, /* Character to fill with */ + uint32_t length /* Length of buffer to set */ + ); + + +/*=============================================================================* + End of file + *============================================================================*/ + +#endif /*_VF_STRINGS_H_*/ diff --git a/src/vf_writer.c b/src/vf_writer.c new file mode 100644 index 0000000..ef3298a --- /dev/null +++ b/src/vf_writer.c @@ -0,0 +1,616 @@ +/****************************************************************************** + + (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.12 $ + $Author: tilda $ + +ORIGINAL AUTHOR + Nick Marley. + +DESCRIPTION + Code for writing vformat files. This is temporary as it is not based + around a state machine for converting the object to a character stream. + +REFERENCES + (none) + +MODIFICATION HISTORY + * $Log: vf_writer.c,v $ + * Revision 1.12 2002/11/03 18:43:16 tilda + * IID619851 - Update and check headers and function prototypes. + * + * Revision 1.11 2002/11/02 08:56:17 tilda + * Start of internationalisation changes. + * + * Revision 1.10 2002/10/26 16:09:23 tilda + * IID629125 - Ensure string functions used are portable. + * + * Revision 1.9 2002/10/08 21:45:07 tilda + * IID620473 - reduce c-runtime dependencies. + * + * Revision 1.8 2002/10/08 21:11:35 tilda + * Remove common.h. + * + * Revision 1.7 2002/02/24 17:10:34 tilda + * Add API for "is modified" functionality. + * + * Revision 1.6 2001/12/13 06:45:35 tilda + * IID488021 - Various bugs with quoted printable format. + * + * Revision 1.5 2001/11/18 21:45:10 tilda + * Add newline after BASE64 encodings + * + * Revision 1.4 2001/11/14 22:36:55 tilda + * Add parameter to vf_find_prop_qual_index() + * + * Revision 1.3 2001/11/06 22:51:05 tilda + * Supporting access functions for image selection / deletion. + * + * Revision 1.2 2001/10/24 18:56:29 tilda + * Tidy headers after import. Fix include path in release build. + * + * Revision 1.1 2001/10/24 18:34:35 tilda + * Initial Version. + * + *******************************************************************************/ + +#ifndef NORCSID +static const char vf_writer_c_vss_id[] = "$Header: /cvsroot/vformat/src/vformat/src/vf_writer.c,v 1.12 2002/11/03 18:43:16 tilda Exp $"; +#endif + +/*=============================================================================* + ANSI C & System-wide Header Files + *=============================================================================*/ + +#include + +#include +#include + +/*============================================================================* + Interface Header Files + *============================================================================*/ + +#include + +/*============================================================================* + Local Header File + *============================================================================*/ + +#include "vf_config.h" +#include "vf_internals.h" +#include "vf_malloc.h" +#include "vf_strings.h" + +/*============================================================================* + Public Data + *============================================================================*/ +/* None */ + +/*============================================================================* + Private Defines + *============================================================================*/ + +#define QPMAXPERLINE (76) +#define BASE64PERLINE (64) + +/*============================================================================* + Private Data Types + *============================================================================*/ +/* None */ + +/*============================================================================* + Private Function Prototypes + *============================================================================*/ + +static bool_t write_name_fields( + FILE *fp, + uint32_t *p_charsonline, + VPROP_T *p_prop + ); + +static void write_base64_chars( + FILE *fp, /* File we're writing */ + uint8_t *s, /* Pointer to buffer */ + uint32_t len /* buffer length */ + ); + +static bool_t write_quoted_printable( + FILE *fp, /* File we're writing */ + uint8_t *s, /* Pointer to buffer */ + uint32_t *p_charsonline /* Num on line so far */ + ); + +static char char_to_base64( + uint8_t b /* Byte to convert */ + ); + +static bool_t qp_needs_quoting( + uint8_t c /* Char to test */ + ); + +static bool_t write_vobject_to_file( + FILE *fp, + VOBJECT_T *p_object, + bool_t write_all + ); + +/*============================================================================* + Private Data + *============================================================================*/ + +static const char szEndOfLine[3] = { 0x0D, 0x0A, 0x00 }; + +/*============================================================================* + Public Function Implementations + *============================================================================*/ + + + + +/*----------------------------------------------------------------------------* + * NAME + * vf_write_file() + * + * DESCRIPTION + * Write indicated vobject to file. + * + * RETURNS + * TRUE <=> written OK, FALSE else. + *----------------------------------------------------------------------------*/ + +bool_t vf_write_file( + const char *p_name, /* Outpt filename */ + VF_OBJECT_T *p_object, /* The object to write */ + bool_t write_all /* Should write p_next as well? */ + ) +{ + FILE *fp; + bool_t ret = FALSE; + + fp = fopen(p_name, "wb"); + + if (fp) + { + ret = write_vobject_to_file(fp, (VOBJECT_T *)p_object, write_all); + + if (0 == fclose(fp)) + { + /* as is */ + } + else + { + ret = FALSE; + } + } + + return ret; +} + + + + + + +/*============================================================================* + Private Function Implementations + *============================================================================*/ + + +/*----------------------------------------------------------------------------* + * NAME + * write_vobject_to_file() + * + * DESCRIPTION + * Write each field of the indicated vformat object to the indicated FILE* + * invoking write_vobject_to_file() recursively if a field is found which + * contains a vformat object. + * + * RETURNS + * TRUE <=> file acces OK, FALSE else. + *----------------------------------------------------------------------------*/ + +bool_t write_vobject_to_file( + FILE *fp, + VOBJECT_T *p_object, + bool_t write_all + ) +{ + bool_t ret = TRUE; + + VOBJECT_T *p_obj = (VOBJECT_T *)p_object; + VPROP_T *p_props = p_obj->p_props; + + fprintf(fp, "%s:%s", VFP_BEGIN, p_obj->p_type); + + fprintf(fp, szEndOfLine); + + for (;NULL != p_props;p_props = p_props->p_next) + { + uint32_t charsonline; + + switch (p_props->value.encoding) + { + default: + case VF_ENC_7BIT: + { + ret = write_name_fields(fp, &charsonline, p_props); + + if (ret) + { + uint32_t n; + + for (n = 0;ret && (n < p_props->value.v.s.n_strings);n++) + { + if (n) + fprintf(fp, ";"); + + if (p_props->value.v.s.pp_strings[n]) + { + fprintf(fp, "%s", p_props->value.v.s.pp_strings[n]); + } + } + } + } + break; + + case VF_ENC_BASE64: + { + ret = write_name_fields(fp, &charsonline, p_props); + + if (ret) + { + write_base64_chars(fp, p_props->value.v.b.p_buffer, p_props->value.v.b.n_bufsize); + } + } + break; + + case VF_ENC_QUOTEDPRINTABLE: + { + ret = write_name_fields(fp, &charsonline, p_props); + + if (ret) + { + uint32_t n; + + for (n = 0;ret && (n < p_props->value.v.s.n_strings);n++) + { + if (n) + fprintf(fp, ";"); + + if (p_props->value.v.s.pp_strings[n]) + { + ret = write_quoted_printable(fp, p_props->value.v.s.pp_strings[n], &charsonline); + } + } + } + } + break; + + case VF_ENC_VOBJECT: + { + write_vobject_to_file(fp, p_props->value.v.o.p_object, TRUE); + } + break; + } + + if (VF_ENC_VOBJECT != p_props->value.encoding) + fprintf(fp, szEndOfLine); + } + + fprintf(fp, "%s:%s", VFP_END, p_obj->p_type); + + fprintf(fp, szEndOfLine); + + if (ret && p_obj->p_next && write_all) + { + ret = write_vobject_to_file(fp, p_obj->p_next, TRUE); + } + + p_obj->modified = !ret; + + return ret; +} + + + + + + +/*----------------------------------------------------------------------------* + * NAME + * write_base64_chars() + * + * DESCRIPTION + * Write the indicated binary data stream out to FILE* using BASE64 + * encoding. + * + * RETURNS + * (none) + *----------------------------------------------------------------------------*/ + +static void write_base64_chars( + FILE *fp, /* File we're writing */ + uint8_t *p_buffer, /* Pointer to buffer */ + uint32_t n_chars /* buffer length */ + ) +{ + uint32_t posn; + char quad[5]; + uint8_t b; + + quad[4] = 0; + + for (posn = 0;posn < n_chars;) + { + int i; + uint32_t triplet = 0; + uint8_t bits = 0; + + /* Form triplet from data if available */ + + for (i = 0;i < 3;i++, posn++) + { + triplet = triplet << 8; + + if (posn < n_chars) + { + triplet |= *(p_buffer + posn); + + bits += 8; + } + } + + /* Convert the triplet to text */ + + for (i = 0;i < 4;i++) + { + b = (uint8_t)((0xFC0000 & triplet) >> 18); + + triplet = triplet << 6; + + quad[i] = (i <= (bits/6)) ? char_to_base64(b) : '='; + } + + /* Output the text prefixed by newlines if necessary */ + + if (((posn - 3) % (BASE64PERLINE / 4)) == 0) + { + fprintf(fp, szEndOfLine); + fprintf(fp, " "); + } + + fprintf(fp, "%s", quad); + } + + fprintf(fp, szEndOfLine); +} + + + + + +/*----------------------------------------------------------------------------* + * NAME + * write_quoted_printable() + * + * DESCRIPTION + * Write the indicated field back to the file in quoted printable format. + * + * RETURNS + * (none) + *----------------------------------------------------------------------------*/ + +static bool_t write_quoted_printable( + FILE *fp, /* File we're writing */ + uint8_t *s, /* Pointer to buffer */ + uint32_t *p_charsonline /* Num on line so far */ + ) +{ + uint32_t i; + uint32_t charsonline = *p_charsonline; + + for (i = 0;s;i++) + { + uint8_t c = s[i]; + + if ('\0' == c) + { + break; + } + else + { + if (3 + charsonline > QPMAXPERLINE) + { + fprintf(fp, "="); + fprintf(fp, szEndOfLine); + charsonline = 0; + } + + if (qp_needs_quoting(c)) + { + fprintf(fp, "=%02X", c); + charsonline += 3; + + if (0x0D == c) + { + fprintf(fp, "="); + fprintf(fp, szEndOfLine); + charsonline = 0; + } + } + else + { + fprintf(fp, "%c", c); + charsonline += 1; + } + } + } + + *p_charsonline = charsonline; + + return TRUE; +} + + + + +/*----------------------------------------------------------------------------* + * NAME + * char_to_base64() + * + * DESCRIPTION + * Converts byte to BASE64. + * + * RETURNS + * Character encoded. + *----------------------------------------------------------------------------*/ + +static char char_to_base64( + uint8_t b /* Byte to convert */ + ) +{ + char ret; + + if (b < 26) + { + ret = (char)b + 'A'; + } + else + if (b < 52) + { + ret = (char)(b - 26) + 'a'; + } + else + if (b < 62) + { + ret = (char)(b - 52) + '0'; + } + else + if (b == 62) + { + ret = '+'; + } + else + { + ret = '/'; + } + + return ret; +} + + + + +/*----------------------------------------------------------------------------* + * NAME + * qp_needs_quoting() + * + * DESCRIPTION + * Works out of 'c' needs quoting in quoted printable format. + * + * RETURNS + * TRUE <=> need to quote. + *----------------------------------------------------------------------------*/ + +static bool_t qp_needs_quoting( + uint8_t c /* Char to test */ + ) +{ + /* TBD - look in the RFC?! */ + + bool_t needs_quoting = FALSE; + + switch (c) + { + case ' ': + case ',': + case '-': + case '.': + case '!': + case '?': + case '\'': + return FALSE; + + default: + if (isalnum(c)) + needs_quoting = FALSE; + else + needs_quoting = TRUE; + break; + } + + return needs_quoting; +} + + + + + + +/*----------------------------------------------------------------------------* + * NAME + * write_name_fields() + * + * DESCRIPTION + * Write name fields to file. + * + * RETURNS + * TRUE <=> OK so far. + *----------------------------------------------------------------------------*/ + +bool_t write_name_fields( + FILE *fp, + uint32_t *p_charsonline, + VPROP_T *p_prop + ) +{ + VSTRARRAY_T *p_strarray = &(p_prop->name); + bool_t ret = FALSE; + + *p_charsonline = 0; + + if (p_prop->p_group) + { + *p_charsonline += fprintf(fp, "%s.", p_prop->p_group); + } + + if (p_strarray->pp_strings) + { + uint32_t i; + + for (i = 0;i < p_strarray->n_strings;i++) + { + char *p_name_field = p_strarray->pp_strings[i]; + + if (p_name_field && (0 < p_strlen(p_name_field))) + { + if (0 < i) + { + fprintf(fp, ";"); + *p_charsonline += 1; + } + + *p_charsonline += fprintf(fp, "%s", p_name_field); + } + } + + fprintf(fp, ":"); + *p_charsonline += 1; + + ret = TRUE; + } + + return ret; +} + + +/*============================================================================* + End Of File + *============================================================================*/ diff --git a/stamp-h.in b/stamp-h.in new file mode 100644 index 0000000..e69de29 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: +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 +#if defined(HAS_UNISTD_H) +#include +#endif +#include +#include +#include +#include + +#if defined(WIN) || defined(WIN32) +#include +#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 +#else +#include +#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 +#include +#include + +/*============================================================================* + 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); + } +} + diff --git a/vf_iface.h b/vf_iface.h new file mode 100644 index 0000000..6627bf5 --- /dev/null +++ b/vf_iface.h @@ -0,0 +1,35 @@ +/****************************************************************************** + + (C) Mathias Palm, 2002 - + + THIS SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + + IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INCIDENTAL, + INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER + RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF + THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT + OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + + * This file is only an auxiliary for the linux distribution + */ + +#ifndef _VF_IFACE_H_ +#include "iface/vf_iface.h" +#endif diff --git a/vformat/Makefile.am b/vformat/Makefile.am new file mode 100644 index 0000000..325ccb3 --- /dev/null +++ b/vformat/Makefile.am @@ -0,0 +1,2 @@ +include_HEADERS = vf_iface.h + diff --git a/vformat/vf_iface.h b/vformat/vf_iface.h new file mode 100644 index 0000000..8dc1b62 --- /dev/null +++ b/vformat/vf_iface.h @@ -0,0 +1,1269 @@ +/****************************************************************************** + + (C) Nick Marley, 2001 - + + THIS SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + + IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INCIDENTAL, + INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER + RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF + THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT + OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +FILE + $Workfile: vf_iface.h $ + $Revision: 1.30 $ + $Author: monos $ + +ORIGINAL AUTHOR + Tilda@users.sourceforge.net + +DESCRIPTION + Main include file for the vFormat object library. + +REFERENCES + (none) + +MODIFICATION HISTORY + * $Log: vf_iface.h,v $ + * Revision 1.30 2002/12/07 17:25:44 monos + * *** empty log message *** + * + * Revision 1.29 2002/11/24 14:26:22 tilda + * IID484686 - More vcard work. + * + * Revision 1.28 2002/11/17 10:01:02 tilda + * IID484686 - Yet more vCalendar stuff. + * + * Revision 1.27 2002/11/16 13:19:10 tilda + * IID639288 - Implement method for adding subobjects. + * + * Revision 1.26 2002/11/03 18:43:16 tilda + * IID619851 - Update and check headers and function prototypes. + * + * Revision 1.25 2002/11/02 18:29:26 tilda + * IID485157 - UI does character conversion based on CHARSET property. + * + * Revision 1.24 2002/11/02 08:56:17 tilda + * Start of internationalisation changes. + * + * Revision 1.23 2002/10/08 21:45:07 tilda + * IID620473 - reduce c-runtime dependencies. + * + * Revision 1.22 2002/10/08 21:15:56 tilda + * IID619851 - Update comments. + * + * Revision 1.21 2002/02/24 17:10:35 tilda + * Add API for "is modified" functionality. + * + * Revision 1.20 2002/02/16 19:14:36 tilda + * Various mods improving the command line options. + * + * Revision 1.19 2002/01/12 15:55:32 tilda + * Add pragmas for linking. + * + * Revision 1.18 2002/01/06 16:18:48 tilda + * Add dialog box for events / todos. + * + * Revision 1.17 2001/12/28 17:23:50 tilda + * Minor mods to VTODO etc. defines. + * + * Revision 1.16 2001/11/16 22:34:49 tilda + * New vf_get_property() allows append as well as find, + * + * Revision 1.15 2001/11/15 08:55:15 tilda + * Minor reorganisation & add comments where missing. + * + * Revision 1.14 2001/11/14 22:36:56 tilda + * Add parameter to vf_find_prop_qual_index() + * + * Revision 1.13 2001/11/14 16:04:16 tilda + * Add VFP_ names. + * + * Revision 1.12 2001/11/12 20:24:54 tilda + * Add properties. + * + * Revision 1.11 2001/11/06 22:51:05 tilda + * Supporting access functions for image selection / deletion. + * + * Revision 1.10 2001/11/05 21:08:02 tilda + * Various changes for initial version of vfedit. + * + * Revision 1.9 2001/10/24 18:36:45 tilda + * BASE64 bugfixes. Split reader/writer code. Start create/modify work. + * + * Revision 1.8 2001/10/24 05:33:16 tilda + * Start work on object create/modify API. + * + * 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 16:40:35 tilda + * Initial testing of access 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/10 20:54:34 tilda + * Various minor tidy ups. + * + * Revision 1.2 2001/10/09 22:01:59 tilda + * Remove older version control comments. + * + *****************************************************************************/ + +#ifndef _VF_IFACE_H_ +#define _VF_IFACE_H_ + +#ifndef NORCSID +static const char vf_iface_h_vss_id[] = "$Header: /cvsroot/vformat/src/vformat/vf_iface.h,v 1.30 2002/12/07 17:25:44 monos Exp $"; +#endif + +/*============================================================================* + Public Includes + *============================================================================*/ + +#include + +#include + +/* c2man (for producing man pages) can't handle some lines in time.h */ + +#ifndef __C2MAN__ +#include +#else +#define time_t long int +#endif + +/*============================================================================* + Public defines + *============================================================================*/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/* + * Default .DLL build using the symbols maintained by MSDEV. + */ +#if defined(WIN) || defined(WIN32) + #if defined(_USRDLL) + #ifndef VFORMATDECLSPEC + #ifdef VFORMATL_EXPORTS + #define VFORMATDECLSPEC __declspec(dllexport) + #else + #define VFORMATDECLSPEC __declspec(dllimport) + #endif + #endif + #endif +#endif + +#if defined(WIN) || defined(WIN32) + #if !defined(VFORMAT_BUILD) + #if defined(_DEBUG) + #pragma comment(lib, "VFORMATLD.lib") + #else + #pragma comment(lib, "VFORMATL.lib") + #endif + #endif +#endif + + +/* + * Remove VFORMATDECLSPEC if not defined. + */ +#ifndef VFORMATDECLSPEC + #define VFORMATDECLSPEC +#endif + + +/*----------------------------------------------------------------------------* + * PURPOSE + * Definitions of the standard properties. + *----------------------------------------------------------------------------*/ + +#define VFP_AALARM "AALARM" +#define VFP_ADDITIONALNAMES "ADDN" +#define VFP_ADR "ADR" +#define VFP_AGENT "AGENT" +#define VFP_AIFF "AIFF" +#define VFP_AOL "AOL" +#define VFP_APPLELINK "APPLELINK" +#define VFP_ATTACH "ATTACH" +#define VFP_ATTENDEE "ATTENDEE" +#define VFP_ORGANIZER "ORGANIZER" +#define VFP_OWNER "OWNER" +#define VFP_DELEGATE "DELEGATE" +#define VFP_ACCEPTED "ACCEPTED" +#define VFP_NEEDSACTION "NEEDS ACTION" +#define VFP_SENT "SENT" +#define VFP_TENTATIVE "TENTATIVE" +#define VFP_CONFIRMED "CONFIRMED" +#define VFP_DECLINED "DECLINED" +#define VFP_COMPLETED "COMPLETED" +#define VFP_DELEGATED "DELEGATED" +#define VFP_CATERING "CATERING" +#define VFP_COMPUTERPROJECTOR "COMPUTER PROJECTOR" +#define VFP_EASEL "EASEL" +#define VFP_OVERHEADPROJECTOR "OVERHEAD PROJECTOR" +#define VFP_SPEAKERPHONE "SPEAKER PHONE" +#define VFP_TABLE "TABLE" +#define VFP_TV "TV" +#define VFP_VCR "VCR" +#define VFP_VIDEOPHONE "VIDEO PHONE" +#define VFP_VEHICLE "VEHICLE" +#define VFP_ATTMAIL "ATTMAIL" +#define VFP_AUDIOCONTENT "AUDIOCONTENT" +#define VFP_AVI "AVI" +#define VFP_BBS "BBS" +#define VFP_BIRTHDATE "BDAY" +#define VFP_BMP "BMP" +#define VFP_BODY "BODY" +#define VFP_BUSINESSROLE "ROLE" +#define VFP_CAPTION "CAP" +#define VFP_CAR "CAR" +#define VFP_CATEGORIES "CATEGORIES" +#define VFP_CELLULAR "CELL" +#define VFP_CGM "CGM" +#define VFP_CHARSET "CHARSET" +#define VFP_CID "CID" +#define VFP_CIS "CIS" +#define VFP_CITY "L" +#define VFP_CLASS "CLASS" +#define VFP_COMMENT "NOTE" +#define VFP_COMPLETED "COMPLETED" +#define VFP_CONTENTID "CONTENT-ID" +#define VFP_COUNTRYNAME "C" +#define VFP_DALARM "DALARM" +#define VFP_DATASIZE "DATASIZE" +#define VFP_DAYLIGHT "DAYLIGHT" +#define VFP_DCREATED "DCREATED" +#define VFP_DELIVERYLABEL "LABEL" +#define VFP_DESCRIPTION "DESCRIPTION" +#define VFP_DIB "DIB" +#define VFP_DISPLAYSTRING "DISPLAYSTRING" +#define VFP_DOMESTIC "DOM" +#define VFP_DTEND "DTEND" +#define VFP_DTSTART "DTSTART" +#define VFP_DUE "DUE" +#define VFP_EMAILADDRESS "EMAIL" +#define VFP_ENCODING "ENCODING" +#define VFP_EWORLD "EWORLD" +#define VFP_EXNUM "EXNUM" +#define VFP_EXPDATE "EXDATE" +#define VFP_EXPECT "EXPECT" +#define VFP_EXTADDRESS "EXT ADD" +#define VFP_FAMILYNAME "F" +#define VFP_FAX "FAX" +#define VFP_FULLNAME "FN" +#define VFP_GEO "GEO" +#define VFP_GEOLOCATION "GEO" +#define VFP_GIF "GIF" +#define VFP_GIVENNAME "G" +#define VFP_GROUPING "GROUPING" +#define VFP_HOME "HOME" +#define VFP_IBMMAIL "IBMMAIL" +#define VFP_INLINE "INLINE" +#define VFP_INTERNATIONAL "INTL" +#define VFP_INTERNET "INTERNET" +#define VFP_ISDN "ISDN" +#define VFP_JPEG "JPEG" +#define VFP_LANGUAGE "LANG" +#define VFP_LASTMODIFIED "LAST-MODIFIED" +#define VFP_LASTREVISED "REV" +#define VFP_LOCATION "LOCATION" +#define VFP_LOGO "LOGO" +#define VFP_MAILER "MAILER" +#define VFP_MALARM "MALARM" +#define VFP_MCIMAIL "MCIMAIL" +#define VFP_MESSAGE "MSG" +#define VFP_MET "MET" +#define VFP_MODEM "MODEM" +#define VFP_MPEG2 "MPEG2" +#define VFP_MPEG "MPEG" +#define VFP_MSN "MSN" +#define VFP_NAMEPREFIXES "NPRE" +#define VFP_NAME "N" +#define VFP_NAMESUFFIXES "NSUF" +#define VFP_NOTE "NOTE" +#define VFP_ORGNAME "ORGNAME" +#define VFP_ORG "ORG" +#define VFP_ORGUNIT2 "OUN2" +#define VFP_ORGUNIT3 "OUN3" +#define VFP_ORGUNIT4 "OUN4" +#define VFP_ORGUNIT "OUN" +#define VFP_PAGER "PAGER" +#define VFP_PALARM "PALARM" +#define VFP_PARCEL "PARCEL" +#define VFP_PART "PART" +#define VFP_PCM "PCM" +#define VFP_PDF "PDF" +#define VFP_PGP "PGP" +#define VFP_PHOTO "PHOTO" +#define VFP_PROPTYPE "TYPE" +#define VFP_PICT "PICT" +#define VFP_PMB "PMB" +#define VFP_POSTALBOX "BOX" +#define VFP_POSTALCODE "PC" +#define VFP_POSTAL "POSTAL" +#define VFP_POWERSHARE "POWERSHARE" +#define VFP_PREFERRED "PREF" +#define VFP_PRIORITY "PRIORITY" +#define VFP_PROCEDURENAME "PROCEDURENAME" +#define VFP_PRODID "PRODID" +#define VFP_PRODIGY "PRODIGY" +#define VFP_SOUND "SOUND" +#define VFP_PS "PS" +#define VFP_PUBLICKEY "KEY" +#define VFP_QP "QP" +#define VFP_QUICKTIME "QTIME" +#define VFP_RDATE "RDATE" +#define VFP_REGION "R" +#define VFP_RELATEDTO "RELATED-TO" +#define VFP_REPEATCOUNT "REPEATCOUNT" +#define VFP_RESOURCES "RESOURCES" +#define VFP_RNUM "RNUM" +#define VFP_ROLE "ROLE" +#define VFP_RRULE "RRULE" +#define VFP_RSVP "RSVP" +#define VFP_RUNTIME "RUNTIME" +#define VFP_SEQUENCE "SEQUENCE" +#define VFP_SNOOZETIME "SNOOZETIME" +#define VFP_START "START" +#define VFP_STATUS "STATUS" +#define VFP_STREETADDRESS "STREET" +#define VFP_SUBTYPE "SUBTYPE" +#define VFP_SUMMARY "SUMMARY" +#define VFP_TELEPHONE "TEL" +#define VFP_TIFF "TIFF" +#define VFP_TIMEZONE "TZ" +#define VFP_TITLE "TITLE" +#define VFP_TLX "TLX" +#define VFP_TRANSP "TRANSP" +#define VFP_UNIQUESTRING "UID" +#define VFP_URL "URL" +#define VFP_URLVALUE "URLVAL" +#define VFP_VALUE "VALUE" +#define VFP_VERSION "VERSION" +#define VFP_VIDEO "VIDEO" +#define VFP_VOICE "VOICE" +#define VFP_WAVE "WAVE" +#define VFP_WMF "WMF" +#define VFP_WORK "WORK" +#define VFP_X400 "X400" +#define VFP_X509 "X509" +#define VFP_XRULE "XRULE" + +#define VFP_UTF8 "UTF-8" + +#define VFP_PRONUNCIATION VFP_SOUND /* ??? */ + +/* + * Property tokesn indicating encoding. + */ +#define VFP_7BIT "7BIT" +#define VFP_8BIT "8BIT" +#define VFP_BASE64 "BASE64" +#define VFP_QUOTEDPRINTABLE "QUOTED-PRINTABLE" + +/* + * Names for the "begin" token. + */ +#define VF_NAME_VCALENDAR "VCALENDAR" +#define VF_NAME_VCARD "VCARD" +#define VF_NAME_VNOTE "VNOTE" +#define VF_NAME_VEVENT "VEVENT" +#define VF_NAME_VTODO "VTODO" + + +/* + * Special token that matches any when searching. + */ +#define VFP_ANY "*" + +/* + * Indexes for compound name properties (the "N" property). + */ +#define VFP_NAME_FAMILY (0) +#define VFP_NAME_GIVEN (1) +#define VFP_NAME_MIDDLE (2) +#define VFP_NAME_TITLE (3) + +/* + * Indexes for compound address properties (the "ADR" property). + */ +#define VFP_ADR_POBOX (0) +#define VFP_ADR_EXTENDED (1) +#define VFP_ADR_STREET (2) +#define VFP_ADR_CITY (3) +#define VFP_ADR_REGION (4) +#define VFP_ADR_POSTCODE (5) +#define VFP_ADR_COUNTRY (6) + +/* + * Indexes for compound organisation properties (the "ORG" property) + */ +#define VFP_ORG_NAME (0) +#define VFP_ORG_DIVISION (1) + +/* + * Type declaring macro. + */ +#define VF_DECLARE_TYPE(x) typedef struct _vf_##x { uint8_t _; } x; + +/*============================================================================* + Public Types + *============================================================================*/ + +/* + * Type representing "parser" - an object used to parse VOBJECTS. + */ +VF_DECLARE_TYPE(VF_PARSER_T) + +/* + * Type representing an "object" - objects are collections of properties. + */ +VF_DECLARE_TYPE(VF_OBJECT_T) + +/* + * Type representing a "property" - properties associate a name & a value. + */ +VF_DECLARE_TYPE(VF_PROP_T) + + +/*----------------------------------------------------------------------------* + * PURPOSE + * VF_ISO8601_PERIOD_T is used to encapsulate an ISO time 'period'. + *----------------------------------------------------------------------------*/ + +typedef struct VF_ISO8601_PERIOD_T +{ + uint32_t years; + uint32_t months; + uint32_t weeks; + uint32_t days; + uint32_t hours; + uint32_t minutes; + uint32_t seconds; +} +VF_ISO8601_PERIOD_T; + + +/*----------------------------------------------------------------------------* + * PURPOSE + * vf_encoding_t enumerates the supported encodings (formats) of a + * vformat object property. Each "value" has a field of this type. + *----------------------------------------------------------------------------*/ + +typedef uint8_t vf_encoding_t; + +#define VF_ENC_UNKNOWN ((vf_encoding_t)(0)) +#define VF_ENC_7BIT ((vf_encoding_t)(1)) +#define VF_ENC_8BIT ((vf_encoding_t)(2)) +#define VF_ENC_BASE64 ((vf_encoding_t)(3)) +#define VF_ENC_QUOTEDPRINTABLE ((vf_encoding_t)(4)) +#define VF_ENC_VOBJECT ((vf_encoding_t)(5)) + + +/*----------------------------------------------------------------------------* + * PURPOSE + * vf_get_t controls the operation of vf_get_property() (qv). Controls + * how far the search algorithm is prepared to go in order to return a + * property ready for modification. + *----------------------------------------------------------------------------*/ + +typedef uint16_t vf_get_t; + +#define VFGP_FIND ((vf_get_t)(0x0001)) /* Search for property */ +#define VFGP_APPEND ((vf_get_t)(0x0002)) /* Append property, no search */ +#define VFGP_GET ((vf_get_t)(0x0003)) /* Find & append if not present */ + + +/*----------------------------------------------------------------------------* + * PURPOSE + * vf_search_flags_t is used to describe how string matching is performed + * when searching for properties, qualifiers, values etc. + *----------------------------------------------------------------------------*/ + +typedef uint32_t vf_search_flags_t; + +/*============================================================================* + Public Functions + *============================================================================*/ + +/*----------------------------------------------------------------------------* + * NAME + * vf_parse_init() + * + * DESCRIPTION + * Allocate and initialise a parser. To parse a VCARD (or any vObject) + * a user allocates a parser, pushes data through it using vf_parse_text() + * and finally calls vf_parse_end(): + * + * VF_PARSER_T *p_parser; + * + * if (vf_parse_init(&p_parser, pp_object)) + * { + * do + * { + * char buffer[...]; + * int numchars; + * + * numchars = get_chars_from_somewhere(buffer, ...); + * + * ret = vf_parse_text(p_parser, buffer, numchars); + * } + * while (ret && (0 < charsread)) + * ; + * + * if (!vf_parse_end(p_parser)) + * { + * ret = FALSE; + * } + * } + * + * A parser allocated by vf_parse_init(), must be deallocated by calling + * vf_parse_end() whether or not parsing succeeds. Also, parsing may not + * be complete (ie. values may be held buffered and not evaluated fully + * or assigned to a VF_OBJECT_T) untill the final call to vf_parse_end() + * => after a vf_parse_init() you _must_ vf_parse_end(). + * + * RETURNS + * TRUE iff parser allocated successfully. + *----------------------------------------------------------------------------*/ + +extern VFORMATDECLSPEC bool_t vf_parse_init( + VF_PARSER_T **pp_parser, /* Ptr to allocated parser */ + VF_OBJECT_T **pp_object /* The object we're parsing into */ + ); + + + +/*----------------------------------------------------------------------------* + * NAME + * vf_parse_text() + * + * DESCRIPTION + * Parse indicated text into the object associated with the VPARSE_T. + * + * See notes for vf_parse_init(). + * + * RETURNS + * TRUE <=> allocation & syntax OK, FALSE else. + *----------------------------------------------------------------------------*/ + +extern VFORMATDECLSPEC bool_t vf_parse_text( + VF_PARSER_T *p_parse, /* The parser */ + char *p_chars, /* New characters to parse into object */ + int numchars /* Number of new characters */ + ); + + + +/*----------------------------------------------------------------------------* + * NAME + * vf_parse_end() + * + * DESCRIPTION + * Ensure parse completion, release memory associated with the parser. + * + * See notes for vf_parse_init(). + * + * RETURNS + * TRUE <=> parse complete with no error. + *----------------------------------------------------------------------------*/ + +extern VFORMATDECLSPEC bool_t vf_parse_end( + VF_PARSER_T *p_parse /* The parser */ + ); + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_read_file() + * + * DESCRIPTION + * Reads indicated VOBJECT_T file. + * + * RETURNS + * TRUE <=> read OK, FALSE else. + *---------------------------------------------------------------------------*/ + +extern VFORMATDECLSPEC bool_t vf_read_file( + VF_OBJECT_T **pp_object, /* Pointer to output object */ + const char *p_name /* Name of file to read */ + ); + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_write_file() + * + * DESCRIPTION + * Write indicated vobject to file. For lists of objects (eg. read from + * a phonebook) the write_all parameter allows the caller to control if + * the library writes the entire list or just the head item. + * + * RETURNS + * TRUE <=> written OK, FALSE else. + *---------------------------------------------------------------------------*/ + +extern VFORMATDECLSPEC bool_t vf_write_file( + const char *p_name, /* Outpt filename */ + VF_OBJECT_T *p_object, /* The object to write */ + bool_t write_all /* Should write p_next as well? */ + ); + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_get_next_object() + * + * DESCRIPTION + * Find "next" vobject. Typically called after a call to vf_read_file() + * which may well read a list of objects from a file for example: + * + * if (vf_read_file(&p_object, p_filename)) + * { + * do + * { + * ... + * } + * while (vf_get_next_object(&p_object)) + * ; + * } + * + * The value of *pp_object is updated by the call if it returns TRUE. + * + * RETURNS + * TRUE iff found (ie. there is a "next" object). + *---------------------------------------------------------------------------*/ + +extern VFORMATDECLSPEC bool_t vf_get_next_object( + VF_OBJECT_T **pp_object /* Ptr to pointer to current object */ + ); + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_create_object() + * + * DESCRIPTION + * Creates an empty vformat object. + * + * RETURNS + * Ptr to object if created else NULL. + *---------------------------------------------------------------------------*/ + +extern VFORMATDECLSPEC VF_OBJECT_T *vf_create_object( + const char *p_type, /* Type of object to create */ + VF_OBJECT_T *p_parent /* Parent object if any */ + ); + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_get_object_type() + * + * DESCRIPTION + * Return the type string identifying the indicated vformat object, + * the string after the 'BEGIN' mark so 'VCARD' or 'VNOTE' etc. + * + * RETURNS + * Ptr to string. + *---------------------------------------------------------------------------*/ + +extern VFORMATDECLSPEC const char *vf_get_object_type( + VF_OBJECT_T *p_object /* Object to locate type of */ + ); + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_get_property() + * + * DESCRIPTION + * Basic searching function locating elements of the VOBJECT by qualified + * name. The function is a varargs function (like sprintf) and the list + * of arguments must be NULL terminated (hence the appearance of the + * p_qualifier argument in the arglist). Valid calls might be: + * + * vf_get_property(&p_out, p_object, VFGP_FIND, NULL, "N", NULL); + * - find and return "N" properties. If there are none, return FALSE. + * + * vf_get_property(&p_out, p_object, VFGP_FIND, NULL, "TEL", "WORK", NULL); + * - find and return "TEL" entries qualified by the "work" attribute + * (ie. work phone numbers). If there are none, return FALSE. + * + * vf_get_property(&p_out, p_object, VFGP_GET, NULL, "TEL", "WORK", NULL); + * - find and return work phone number. The entry is automatically + * added if not pre-existing. + * + * vf_get_property(&p_out, p_object, VFGP_GET, NULL, "TEL", "WORK", NULL); + * - find and return work phone numbers in the group identifier by the "ME" + * identifier. The entry is automatically added if not pre-existing. + * + * vf_get_property(&p_out, p_object, VFGP_FIND, "ME", "*", NULL); + * - effectively enumerates all entries in the "ME" group. + * + * A pointer to the first property matching the search criteria is returned + * via the pp_prop argument. The search actually locates all such matches + * and pointer to subsequent entries (if there are >1) may be found by + * calling the vf_get_next_property() function. + * + * The tags may occur in any order _except_ that the p_name must be first. + * + * Note that the VF_PROP_T returned by pp_prop is an opaque type and the + * functions vf_get_prop_xxxx() etc. must be used to locate real "values". + * + * Cached search results (the list enumerated by subsequent calls to the + * vf_get_next_property() function) are maintained through the use of a + * a single internal pointer therefore this method is not thread safe. + * + * RETURNS + * TRUE iff found/added successfully. Ptr to prop returned via pp_prop. + *---------------------------------------------------------------------------*/ + +extern VFORMATDECLSPEC bool_t vf_get_property( + VF_PROP_T **pp_prop, /* Output pointer */ + VF_OBJECT_T *p_object, /* Object to add to */ + vf_get_t ops, /* Search flags */ + const char *p_group, /* Group name if any */ + const char *p_name, /* Name of tag */ + const char *p_qualifier, /* First qualifier if any */ + ... /* Subequent qualifiers */ + ); + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_get_property_ex() + * + * DESCRIPTION + * The grunt behind vf_get_property(). Manages the search as described + * vf_get_property() but takes the list of arguments as a va_list. + * This function should be used when writing higher layer functions + * which take varargs (eg. DDX functions). + * + * RETURNS + * TRUE iff found/added successfully. ptr to prop returned via pp_prop. + *---------------------------------------------------------------------------*/ + +extern VFORMATDECLSPEC bool_t vf_get_property_ex( + VF_PROP_T **pp_prop, /* Output pointer */ + VF_OBJECT_T *p_object, /* Object to search */ + vf_get_t ops, /* Search flags */ + const char *p_group, /* Group name if any */ + const char *p_name, /* Name of tag */ + const char *p_qualifier, /* First qualifier if any */ + va_list args /* Argument list */ + ); + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_get_next_property() + * + * DESCRIPTION + * Find the next property given the current search critera. User + * calls vf_get_property() to locate first in a bunch of properties + * and can iterate over the rest by calling vf_get_next_property(). + * + * RETURNS + * TRUE iff found, FALSE else. *pp_prop points to the nex property. + *---------------------------------------------------------------------------*/ + +extern VFORMATDECLSPEC bool_t vf_get_next_property( + VF_PROP_T **pp_prop /* Output pointer */ + ); + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_get_prop_value() + * + * DESCRIPTION + * Get hold of raw fields associated with the property. These are of + * various types: + * + * VF_ENC_VOBJECT + * - *pp_value = pointer to contained VF_OBJECT_T which can be + * passed back to any of the object manipulation functions. + * + * VF_ENC_7BIT, VF_ENC_QUOTEDPRINTABLE + * - *pp_value = ptr to array of char*, *p_size = number of elts. + * + * VF_ENC_8BIT, VF_BASE64 + * - *pp_value = ptr to bytes, *p_size = number of bytes + * + * RETURNS + * TRUE <=> encoding is valid, FALSE else. + *---------------------------------------------------------------------------*/ + +extern VFORMATDECLSPEC bool_t vf_get_prop_value( + VF_PROP_T *p_prop, /* The property */ + void **pp_value, /* Pointer value */ + uint32_t *p_size, /* Integer value */ + vf_encoding_t *p_encoding /* Type of return values */ + ); + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_set_prop_value() + * + * DESCRIPTION + * Set values associated with a property. + * + * Passing a value of encoding not the same as the current property + * encoding will cause the property contents to be freed prior to + * setting the indicated value. + * + * RETURNS + * TRUE <=> re-allocation success & encoding correct, FALSE else. + *---------------------------------------------------------------------------*/ + +extern VFORMATDECLSPEC bool_t vf_set_prop_value( + VF_PROP_T *p_prop, /* The property */ + void *p_value, /* Pointer to the data */ + uint32_t n_param, /* Data size or index */ + vf_encoding_t encoding, /* Encoding in use */ + bool_t copy /* Copy the data? */ + ); + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_get_prop_value_string() + * + * DESCRIPTION + * Obtain string pointer value from VF_PROP_T. For example a property + * may be defined as: + * + * THING;THIS=STUFF;WITH-QUALIFIERS:fred-fred-fred;gogogo;baabaabaa + * + * A call to vf_get_prop_value_string() specifying n_string=1 will + * return a pointer to the gogogo value. + * + * Return NULL if out of range request, ie. n_string=3 for N:0;1;2 + * + * RETURNS + * Pointer to string value if value present, NULL if index too large. + *---------------------------------------------------------------------------*/ + +extern VFORMATDECLSPEC char *vf_get_prop_value_string( + VF_PROP_T *p_prop, /* Property to locate string from */ + uint32_t n_string /* Index to string requred */ + ); + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_get_prop_name_string() + * + * DESCRIPTION + * Get n'th name string. For example a property may be defined as: + * + * THING;THIS=STUFF;WITH-QUALIFIERS:fred-fred-fred;gogogo;baabaabaa + * + * A call to vf_get_prop_name_string() specifying n_string=2 will + * return a pointer to the WITH-QUALIFIERS value. + * + * Return NULL if out of range request, ie. n_string=4 for X;A;B;C:foo + * + * RETURNS + * Pointer to string value if value present, NULL if index too large. + *---------------------------------------------------------------------------*/ + +extern VFORMATDECLSPEC char *vf_get_prop_name_string( + VF_PROP_T *p_prop, /* Property to locate string from */ + uint32_t n_string /* Index to string requred */ + ); + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_set_prop_name_string() + * + * DESCRIPTION + * Set n'th name string. + * + * RETURNS + * TRUE iff allocation OK, FALSE else. + *---------------------------------------------------------------------------*/ + +extern VFORMATDECLSPEC bool_t vf_set_prop_name_string( + VF_PROP_T *p_prop, /* Property we're setting a value in */ + uint32_t n_string, /* Index to string */ + const char *p_string /* Pointer to string */ + ); + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_get_prop_name() + * + * DESCRIPTION + * Build the property name string in the indicated buffer. + * + * RETURNS + * (none) + *---------------------------------------------------------------------------*/ + +extern VFORMATDECLSPEC void vf_get_prop_name( + VF_PROP_T *p_prop, /* The property */ + char *p_buffer, /* The buffer */ + uint32_t bufsize /* Size of the buffer */ + ); + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_get_prop_value_object() + * + * DESCRIPTION + * Obtain object pointer value from VF_PROP_T. + * + * RETURNS + * Pointer to vobject value (or NULL if not found). + *---------------------------------------------------------------------------*/ + +extern VFORMATDECLSPEC VF_OBJECT_T *vf_get_prop_value_object( + VF_PROP_T *p_prop /* Property to locate object from */ + ); + + +/*---------------------------------------------------------------------------* + * NAME + * vf_set_prop_value_object() + * + * DESCRIPTION + * Set the value of the indicated property to be a VOBJECT. + * + * RETURNS + * TRUE <=> set successfully. + *---------------------------------------------------------------------------*/ + +extern VFORMATDECLSPEC bool_t vf_set_prop_value_object( + VF_PROP_T *p_prop, + VF_OBJECT_T *p_object + ); + + +/*---------------------------------------------------------------------------* + * NAME + * vf_set_prop_value_string() + * + * DESCRIPTION + * Set the value of a property. + * + * RETURNS + * TRUE <=> set successfully. + *---------------------------------------------------------------------------*/ + +extern VFORMATDECLSPEC bool_t vf_set_prop_value_string( + VF_PROP_T *p_prop, /* Property we're setting a value in */ + uint32_t n_string, /* Index to string */ + const char *p_string /* Pointer to string */ + ); + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_set_prop_value_base64() + * + * DESCRIPTION + * Set the value of a property. + * + * RETURNS + * TRUE <=> set successfully. + *---------------------------------------------------------------------------*/ + +extern VFORMATDECLSPEC bool_t vf_set_prop_value_base64( + VF_PROP_T *p_prop, /* Property we're setting a value in */ + const uint8_t *p_data, /* Pointer to the binary data */ + uint32_t length, /* Length of the binary data */ + bool_t copy /* Copy or keep pointer */ + ); + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_get_prop_value_base64() + * + * DESCRIPTION + * Get a BASE64 property. Returns ptr, passes length via parameter. + * + * RETURNS + * Ptr to data. + *---------------------------------------------------------------------------*/ + +extern VFORMATDECLSPEC const uint8_t *vf_get_prop_value_base64( + VF_PROP_T *p_prop, /* Property we're setting a value in */ + uint32_t *p_length /* Length of the binary data */ + ); + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_set_property_from_file() + * + * DESCRIPTION + * Loads the indicated file into memory and sets the indicated property. + * + * RETURNS + * TRUE iff succeded, FALSE else. + *---------------------------------------------------------------------------*/ + +extern VFORMATDECLSPEC bool_t vf_set_property_from_file( + VF_PROP_T *p_prop, /* The property */ + vf_encoding_t encoding, /* Encoding to use */ + const char *p_filename /* Source filename */ + ); + + +/*---------------------------------------------------------------------------* + * NAME + * vf_delete_object() + * + * DESCRIPTION + * Cleans up the memory used by the indicated vformat object. + * + * RETURNS + * (none) + *---------------------------------------------------------------------------*/ + +extern VFORMATDECLSPEC void vf_delete_object( + VF_OBJECT_T *p_object, /* The object to delete */ + bool_t all /* Delete all subsequent objects? */ + ); + + +/*----------------------------------------------------------------------------* + * NAME + * vf_delete_prop() + * + * DESCRIPTION + * Deletes indicated property from the indicated object. Deletes prop + * contents if dc is set. + * + * RETURNS + * (none) + *----------------------------------------------------------------------------*/ + +extern VFORMATDECLSPEC void vf_delete_prop( + VF_OBJECT_T *p_object, /* The object we're deleting from */ + VF_PROP_T *p_prop, /* The property we're removing */ + bool_t dc /* Should property contents be deleted? */ + ); + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_find_prop_qual_index() + * + * DESCRIPTION + * Locate property qualifier given either an array of possible values + * or a single token that is either present or absent. For example + * if we have a property: + * + * NAME;THIRD;TIME;LUCKY:VALUE1;VALUE2;VALUE3 + * + * Then there are two possible searches. + * + * Firstly we can look for the property qualifier which can take values + * from the array { "FIRST", "SECOND", THIRD" } in which case the array + * is passed as pp_possible_values and the function returns with the + * values *p_found_value_index=2, p_qualifier_index=1 + * + * Secondly we can look for the token with value "TIME" in which case + * p_token is set to "TIME" and the function returns *p_qualifier_index=2. + * + * RETURNS + * TRUE iff found, FALSE else. + *---------------------------------------------------------------------------*/ + +extern VFORMATDECLSPEC bool_t vf_find_prop_qual_index( + VF_PROP_T *p_prop, /* The property we're querying */ + uint32_t *p_qualifier_index, /* Ptr to output name index */ + uint32_t *p_found_value_index, /* Ptr to output index in array */ + const char **pp_possible_values, /* Array of possible values */ + const char *p_token, /* Token searched for */ + vf_search_flags_t match /* String comparison flags */ + ); + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_is_modified() + * + * DESCRIPTION + * Fetch status of modified flag. + * + * RETURNS + * TRUE iff modified since list read/write. + *---------------------------------------------------------------------------*/ + +extern VFORMATDECLSPEC bool_t vf_is_modified( + VF_OBJECT_T *p_object /* The object */ + ); + + +/*----------------------------------------------------------------------------* + * NAME + * vf_find_charset() + * + * DESCRIPTION + * Locate the CHARSET property which indicates the character encoding + * in use - which indicates how the octet stream encoded in the VCARD + * is to be decoded into characters. + * + * RETURNS + * Pointer to character encoding name eg. "UTF-8". + *---------------------------------------------------------------------------*/ + +extern VFORMATDECLSPEC const char *vf_find_charset( + VF_PROP_T *p_prop /* The property we're querying */ + ); + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_date_string_to_time() + * + * DESCRIPTION + * Convert calendar string to absolute time. The basic formats are + * 19960401, 19960401T073000Z + * + * RETURNS + * TRUE <=> conversion OK, FALSE else. + *---------------------------------------------------------------------------*/ + +extern VFORMATDECLSPEC bool_t vf_date_string_to_time( + uint32_t *p_time, /* Output time value */ + const char *p_string /* Input string */ + ); + + + +/*---------------------------------------------------------------------------* + * NAME + * vf_period_string_to_time() + * + * DESCRIPTION + * Convert period definition string to time value. The format is + * P[aaaY][bbbM][cccW][dddD]T[eeeH][fffM][gggS] where 'aaa' is a + * number of years, bbb months etc. + * + * RETURNS + * TRUE <=> conversion OK, FALSE else. + *---------------------------------------------------------------------------*/ + +extern VFORMATDECLSPEC bool_t vf_period_string_to_time( + VF_ISO8601_PERIOD_T *p_period, /* Output time value */ + const char *p_string /* Input string */ + ); + + +/*---------------------------------------------------------------------------* + * NAME + * vf_period_time_to_string() + * + * DESCRIPTION + * Convert a VF_ISO8601_PERIOD_T to a string. + * + * RETURNS + * Number of characters written. + *---------------------------------------------------------------------------*/ + +extern VFORMATDECLSPEC uint32_t vf_period_time_to_string( + char *p_string, /* Output string */ + const VF_ISO8601_PERIOD_T *p_period /* Input period value */ + ); + + +/*---------------------------------------------------------------------------* + * NAME + * vf_set_prop_value_time() + * + * DESCRIPTION + * Set a time_t value into a VF property. + * + * RETURNS + * TRUE iff property added & set OK. + *---------------------------------------------------------------------------*/ + +extern VFORMATDECLSPEC bool_t vf_set_prop_value_time( + VF_PROP_T *p_prop, /* The property */ + uint32_t n_string, /* Which string we're encoding to */ + const time_t t_value /* Time value */ + ); + + +/*---------------------------------------------------------------------------* + * NAME + * vf_get_prop_value_time() + * + * DESCRIPTION + * Fetch a time_t value from a VF property. + * + * RETURNS + * TRUE iff foudn & converted OK. + *---------------------------------------------------------------------------*/ + +extern VFORMATDECLSPEC bool_t vf_get_prop_value_time( + VF_PROP_T *p_prop, /* The property */ + uint32_t n_string, /* Which string we're decoding */ + time_t *p_t_value /* Pointer to output time value */ + ); + + +#if defined(__cplusplus) +} +#endif + +/*============================================================================* + End of file + *============================================================================*/ + +#endif /*_VF_IFACE_H_*/ -- cgit v1.1-32-gdbae