From 0425aadc78680e53000fd0108b540d6eca048516 Mon Sep 17 00:00:00 2001 From: gmcdonald Date: Sat, 13 Feb 2010 01:32:03 +0000 Subject: Moving axis svn, part of TLP move INFRA-2441 git-svn-id: http://svn.apache.org/repos/asf/axis/axis2/c/core/trunk@909681 13f79535-47bb-0310-9956-ffa450edef68 --- guththila/AUTHORS | 0 guththila/COPYING | 203 +++ guththila/ChangeLog | 0 guththila/INSTALL | 12 + guththila/LICENSE | 203 +++ guththila/Makefile.am | 12 + guththila/NEWS | 0 guththila/README | 41 + guththila/autogen.sh | 51 + guththila/build.sh | 4 + guththila/configure.ac | 81 ++ guththila/include/guththila.h | 353 +++++ guththila/include/guththila_attribute.h | 127 ++ guththila/include/guththila_buffer.h | 152 +++ guththila/include/guththila_defines.h | 73 + guththila/include/guththila_error.h | 96 ++ guththila/include/guththila_namespace.h | 76 ++ guththila/include/guththila_reader.h | 115 ++ guththila/include/guththila_stack.h | 96 ++ guththila/include/guththila_token.h | 174 +++ guththila/include/guththila_xml_writer.h | 507 +++++++ guththila/samples/guththila_main.c | 186 +++ guththila/samples/guththila_writer_main.c | 71 + guththila/src/Makefile.am | 18 + guththila/src/guththila_attribute.c | 144 ++ guththila/src/guththila_buffer.c | 134 ++ guththila/src/guththila_namespace.c | 139 ++ guththila/src/guththila_reader.c | 115 ++ guththila/src/guththila_stack.c | 135 ++ guththila/src/guththila_token.c | 221 +++ guththila/src/guththila_xml_parser.c | 1792 +++++++++++++++++++++++++ guththila/src/guththila_xml_writer.c | 2082 +++++++++++++++++++++++++++++ guththila/tests/resources/om | 1 + guththila/tests/resources/soap | 1 + guththila/tests/s | 13 + guththila/tests/test.c | 200 +++ guththila/tests/test.h | 23 + guththila/tests/test_attribute.c | 84 ++ 38 files changed, 7735 insertions(+) create mode 100644 guththila/AUTHORS create mode 100644 guththila/COPYING create mode 100644 guththila/ChangeLog create mode 100644 guththila/INSTALL create mode 100644 guththila/LICENSE create mode 100644 guththila/Makefile.am create mode 100644 guththila/NEWS create mode 100644 guththila/README create mode 100755 guththila/autogen.sh create mode 100755 guththila/build.sh create mode 100644 guththila/configure.ac create mode 100644 guththila/include/guththila.h create mode 100644 guththila/include/guththila_attribute.h create mode 100644 guththila/include/guththila_buffer.h create mode 100644 guththila/include/guththila_defines.h create mode 100644 guththila/include/guththila_error.h create mode 100644 guththila/include/guththila_namespace.h create mode 100644 guththila/include/guththila_reader.h create mode 100644 guththila/include/guththila_stack.h create mode 100644 guththila/include/guththila_token.h create mode 100644 guththila/include/guththila_xml_writer.h create mode 100644 guththila/samples/guththila_main.c create mode 100644 guththila/samples/guththila_writer_main.c create mode 100644 guththila/src/Makefile.am create mode 100644 guththila/src/guththila_attribute.c create mode 100644 guththila/src/guththila_buffer.c create mode 100644 guththila/src/guththila_namespace.c create mode 100644 guththila/src/guththila_reader.c create mode 100644 guththila/src/guththila_stack.c create mode 100644 guththila/src/guththila_token.c create mode 100644 guththila/src/guththila_xml_parser.c create mode 100644 guththila/src/guththila_xml_writer.c create mode 120000 guththila/tests/resources/om create mode 120000 guththila/tests/resources/soap create mode 100755 guththila/tests/s create mode 100644 guththila/tests/test.c create mode 100644 guththila/tests/test.h create mode 100644 guththila/tests/test_attribute.c (limited to 'guththila') diff --git a/guththila/AUTHORS b/guththila/AUTHORS new file mode 100644 index 0000000..e69de29 diff --git a/guththila/COPYING b/guththila/COPYING new file mode 100644 index 0000000..6b0b127 --- /dev/null +++ b/guththila/COPYING @@ -0,0 +1,203 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/guththila/ChangeLog b/guththila/ChangeLog new file mode 100644 index 0000000..e69de29 diff --git a/guththila/INSTALL b/guththila/INSTALL new file mode 100644 index 0000000..1cdc320 --- /dev/null +++ b/guththila/INSTALL @@ -0,0 +1,12 @@ +Getting Guththila source working on Linux +============================================= +Build the source +This can be done using the following command sequence: + ./configure + make + make install + use './configure --help' for options + +NOTE: If you don't provide a --prefix configure option, it will by default +install into /usr/local/guththila directory. + diff --git a/guththila/LICENSE b/guththila/LICENSE new file mode 100644 index 0000000..6b0b127 --- /dev/null +++ b/guththila/LICENSE @@ -0,0 +1,203 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/guththila/Makefile.am b/guththila/Makefile.am new file mode 100644 index 0000000..b94c0c2 --- /dev/null +++ b/guththila/Makefile.am @@ -0,0 +1,12 @@ +datadir=$(prefix) +SUBDIRS = src +includedir=$(prefix)/include/axis2-1.6.0/ +include_HEADERS=$(top_builddir)/include/*.h +data_DATA= INSTALL README AUTHORS NEWS LICENSE COPYING +#EXTRA_DIST = build.sh autogen.sh CREDITS LICENSE +dist-hook: + rm -rf `find $(distdir)/ -type d -name .svn` + rm -rf `find $(distdir)/ -type d -name .deps` + +EXTRA_DIST=LICENSE + diff --git a/guththila/NEWS b/guththila/NEWS new file mode 100644 index 0000000..e69de29 diff --git a/guththila/README b/guththila/README new file mode 100644 index 0000000..8c40b8b --- /dev/null +++ b/guththila/README @@ -0,0 +1,41 @@ + + Apache Axis2/C Guththila + ======================== + + What Is It? + ----------- + + Guththila is Streaming XML Parser for the Apache Axis2/C. + + The Latest Version + ------------------ + + You can get the latest svn checkout of Apache Axis2/C Guththila module from + + https://svn.apache.org/repos/asf/webservices/axis2/trunk/c/guththila + + Installation + ------------ + + Please see the file called INSTALL. + + Licensing + --------- + + Please see the file called LICENSE. + + Contacts + -------- + + o If you want freely available support for using Apache Axis2/C Guththila please + join the Apache Axis2/C user community by subscribing to users mailing + list, axis-c-user@ws.apache.org' as described at + http://ws.apache.org/axis2/c/mail-lists.html + + o If you have a bug report for Apache Axis2/C Guththila please log-in and create a JIRA issue + at http://issues.apache.org/jira/browse/AXIS2C + + o If you want to participate actively in developing Apache Axis2/C Guththila please + subscribe to the `axis-c-dev@ws.apache.org' mailing list as described at + http://ws.apache.org/axis2/c/mail-lists.html + diff --git a/guththila/autogen.sh b/guththila/autogen.sh new file mode 100755 index 0000000..8ca13d8 --- /dev/null +++ b/guththila/autogen.sh @@ -0,0 +1,51 @@ +#!/bin/bash + +echo -n 'Running libtoolize...' +if [ `uname -s` = Darwin ] +then + LIBTOOLIZE=glibtoolize +else + LIBTOOLIZE=libtoolize +fi + +if $LIBTOOLIZE --force > /dev/null 2>&1; then + + echo 'done.' +else + echo 'failed.' + exit 1 +fi + +echo -n 'Running aclocal...' +if aclocal > /dev/null 2>&1; then + echo 'done.' +else + echo 'failed.' + exit 1 +fi + +echo -n 'Running autoheader...' +if autoheader > /dev/null 2>&1; then + echo 'done.' +else + echo 'failed.' + exit 1 +fi + +echo -n 'Running autoconf...' +if autoconf > /dev/null 2>&1; then + echo 'done.' +else + echo 'failed.' + exit 1 +fi + +echo -n 'Running automake...' +if automake --add-missing > /dev/null 2>&1; then + echo 'done.' +else + echo 'failed.' + exit 1 +fi + +echo 'done' diff --git a/guththila/build.sh b/guththila/build.sh new file mode 100755 index 0000000..48dfd02 --- /dev/null +++ b/guththila/build.sh @@ -0,0 +1,4 @@ +./autogen.sh +./configure --prefix=${AXIS2C_HOME} --with-axis2_util=${AXIS2C_HOME}/include +make +make install diff --git a/guththila/configure.ac b/guththila/configure.ac new file mode 100644 index 0000000..5a6951b --- /dev/null +++ b/guththila/configure.ac @@ -0,0 +1,81 @@ +dnl run autogen.sh to generate the configure script. + +AC_PREREQ(2.59) + +AC_INIT(guththilac-src, 1.6.0) +AC_CANONICAL_SYSTEM +AM_CONFIG_HEADER(config.h) +dnl AM_INIT_AUTOMAKE([tar-ustar]) +AM_INIT_AUTOMAKE +AC_PREFIX_DEFAULT(/usr/local/guththila) + +m4_ifdef([_A][M_PROG_TAR],[_A][M_SET_OPTION([tar-ustar])]) + +dnl Checks for programs. +AC_PROG_CC +AC_PROG_CXX +AC_PROG_CPP +AC_PROG_LIBTOOL +AC_PROG_INSTALL +AC_PROG_LN_S +AC_PROG_MAKE_SET + +dnl check for flavours of varargs macros (test from GLib) +AC_MSG_CHECKING(for ISO C99 varargs macros in C) +AC_TRY_COMPILE([],[ +int a(int p1, int p2, int p3); +#define call_a(...) a(1,__VA_ARGS__) +call_a(2,3); +],axis2c_have_iso_c_varargs=yes,axis2c_have_iso_c_varargs=no) +AC_MSG_RESULT($axis2c_have_iso_c_varargs) + +AC_MSG_CHECKING(for GNUC varargs macros) +AC_TRY_COMPILE([],[ +int a(int p1, int p2, int p3); +#define call_a(params...) a(1,params) +call_a(2,3); +],axis2c_have_gnuc_varargs=yes,axis2c_have_gnuc_varargs=no) +AC_MSG_RESULT($axis2c_have_gnuc_varargs) + +dnl Output varargs tests +if test x$axis2c_have_iso_c_varargs = xyes; then + AC_DEFINE(HAVE_ISO_VARARGS,1,[Have ISO C99 varargs macros]) +fi +if test x$axis2c_have_gnuc_varargs = xyes; then + AC_DEFINE(HAVE_GNUC_VARARGS,1,[Have GNU-style varargs macros]) +fi + +dnl Checks for libraries. +AC_CHECK_LIB(dl, dlopen) + +CFLAGS="$CFLAGS -D_LARGEFILE64_SOURCE -DAXIS2_GUTHTHILA_ENABLED" + +if test "$GCC" = "yes"; then + CFLAGS="$CFLAGS -ansi -ggdb3 -Wall -Wno-implicit-function-declaration " +fi + + +dnl Checks for header files. +AC_HEADER_STDC +AC_CHECK_HEADERS([stdio.h stdlib.h string.h]) + +dnl Checks for typedefs, structures, and compiler characteristics. +AC_C_CONST + +dnl Checks for library functions. +AC_FUNC_MALLOC +AC_FUNC_REALLOC +#AC_CHECK_FUNCS([memmove]) + + +UTILINC=$axis2_utilinc +VERSION_NO="6:0:6" + +AC_SUBST(UTILINC) +AC_SUBST(VERSION_NO) + +AC_CONFIG_FILES([Makefile \ + src/Makefile \ + ]) + +AC_OUTPUT diff --git a/guththila/include/guththila.h b/guththila/include/guththila.h new file mode 100644 index 0000000..663883d --- /dev/null +++ b/guththila/include/guththila.h @@ -0,0 +1,353 @@ + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef GUTHTHILA_H +#define GUTHTHILA_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/* +All the functions in this library does not check weather the given arguments are NULL. +It is the responsblity of the user to check weather the arguments contain NULL values. +*/ +EXTERN_C_START() + +enum guththila_status +{ + S_0 = 0, + S_1, + S_2, + S_3 +}; + +enum guththila_UTF16_endianess +{ + None = 1, + LE, + BE +}; + +typedef enum guththila_type +{ + type_file_name = 0, + type_memory_buffer, + type_reader, + type_io +} guththila_type_t; + +enum guththila_event_types +{ + GUTHTHILA_START_DOCUMENT =0, + GUTHTHILA_END_ELEMENT, + GUTHTHILA_CHARACTER, + GUTHTHILA_ENTITY_REFERANCE, + GUTHTHILA_COMMENT, + GUTHTHILA_SPACE, + GUTHTHILA_START_ELEMENT, + GUTHTHILA_EMPTY_ELEMENT +}; + +typedef struct guththila_s +{ + guththila_tok_list_t tokens; /* Token cache */ + + guththila_buffer_t buffer; /* Holding incoming xml string */ + + guththila_reader_t *reader; /* Reading the data */ + + guththila_token_t *prefix; /* Prefix of the xml element */ + + guththila_token_t *name; /* xml element local name */ + + guththila_token_t *value; /* text of a xml element */ + + guththila_stack_t elem; /* elements are put in a stack */ + + guththila_stack_t attrib; /* Attributes are put in a stack */ + + guththila_stack_t namesp; /* namespaces are put in a stack */ + + int status; + + int guththila_event; /* Current event */ + + size_t next; /* Keep track of the position in the xml string */ + + int last_start; /* Keep track of the starting position of the last token */ + + guththila_token_t *temp_prefix; /* Temporery location for prefixes */ + + guththila_token_t *temp_name; /* Temporery location for names */ + + guththila_token_t *temp_tok; /* We don't know this until we close it */ +} guththila_t; + +/* + * An element will contain one of these things if it has namespaces + * */ +typedef struct guththila_elem_namesp_s +{ + guththila_namespace_t *namesp; /* Array of namespaces */ + int no; /*Number of namespace in the element */ + int size; /* Allocated size */ +} guththila_elem_namesp_t; + +/* + * Element. + */ +typedef struct guththila_element_s +{ + guththila_token_t *name; /* local name */ + + guththila_token_t *prefix; /* prefix */ + + int is_namesp; /* Positive if a namespace is present */ +} guththila_element_t; + +/* Initialize the parser */ +GUTHTHILA_EXPORT int GUTHTHILA_CALL +guththila_init(guththila_t * m, void *reader, + const axutil_env_t * env); + +/* Uninitialize the parser */ +GUTHTHILA_EXPORT int GUTHTHILA_CALL +guththila_un_init(guththila_t * m, const axutil_env_t * env); + +/* Still not used */ +typedef void(GUTHTHILA_CALL * guththila_error_func)(void *arg, + const guththila_char_t *msg, + guththila_error_level level, + void *locator); + +/* + * Parse the xml and return an event. If something went wrong it will return -1. + * The events are of the type guththila_event_types. According to the event + * user can get the required information using the appriate functions. + * @param g pointer to a guththila_t structure + * @param env the environment + */ +GUTHTHILA_EXPORT int GUTHTHILA_CALL +guththila_next(guththila_t * g, const axutil_env_t * env); + +/* + * Return the number of attributes in the current element. + * @param g pointer to a guththila_t structure + * @param env the environment + */ +GUTHTHILA_EXPORT int GUTHTHILA_CALL +guththila_get_attribute_count(guththila_t * g, const axutil_env_t * env); + +/* + * Return the attribute name. + * @param g pointer to a guththila_t structure + * @param att pointer to a attribute + * @param env the environment + */ +GUTHTHILA_EXPORT guththila_char_t * GUTHTHILA_CALL +guththila_get_attribute_name(guththila_t * g, guththila_attr_t * att, + const axutil_env_t * env); + +/* + * Return the attribute value. + * @param g pointer to a guththila_t structure + * @param att pointer to a attribute + * @param env the environment + */ +GUTHTHILA_EXPORT guththila_char_t * GUTHTHILA_CALL +guththila_get_attribute_value(guththila_t * g, + guththila_attr_t * att, + const axutil_env_t * env); + +/* + * Return the attribute prefix. + * @param g pointer to a guththila_t structure + * @param att pointer to a attribute + * @param env the environment + */ +GUTHTHILA_EXPORT guththila_char_t *GUTHTHILA_CALL +guththila_get_attribute_prefix(guththila_t * g, + guththila_attr_t * att, + const axutil_env_t * env); + +/* + * Return the attribute + * @param g pointer to a guththila_t structure + * @param env the environment + */ +GUTHTHILA_EXPORT guththila_attr_t *GUTHTHILA_CALL +guththila_get_attribute(guththila_t * g, const axutil_env_t * env); + +/* + * Return the name of the attribute by the attribute bumber. + * First attribute will be 1. + * @param g pointer to a guththila_t structure + * @param index position of the attribute + * @param env the environment + */ +GUTHTHILA_EXPORT guththila_char_t *GUTHTHILA_CALL +guththila_get_attribute_name_by_number(guththila_t * g, int index, + const axutil_env_t *env); + +/* + * Return the attribute value by number. + * First attribute will be 1. + * @param g pointer to a guththila_t structure + * @param index position of the attribute + * @param env the environment + */ +GUTHTHILA_EXPORT guththila_char_t *GUTHTHILA_CALL +guththila_get_attribute_value_by_number(guththila_t * g, int index, + const axutil_env_t *env); + +/* + * Return the prefix of the attribute. + * First attribute will be 1. + * @param g pointer to a guththila_t structure + * @param index position of the attribute + * @param env the environment + */ +GUTHTHILA_EXPORT guththila_char_t *GUTHTHILA_CALL +guththila_get_attribute_prefix_by_number(guththila_t * g, int index, + const axutil_env_t *env); + +/* + * Return the name of the element. + * @param g pointer to a guththila_t structure + * @param env the environment + */ +GUTHTHILA_EXPORT guththila_char_t *GUTHTHILA_CALL +guththila_get_name(guththila_t * g, const axutil_env_t * env); + +/* + * Return the prefix of the element. + * @param g pointer to a guththila_t structure + * @param env the environment + */ +GUTHTHILA_EXPORT guththila_char_t *GUTHTHILA_CALL +guththila_get_prefix(guththila_t * g, const axutil_env_t * env); + +/* + * Return the text of the element. + * @param g pointer to a guththila_t structure + * @param env the environment + */ +GUTHTHILA_EXPORT guththila_char_t *GUTHTHILA_CALL +guththila_get_value(guththila_t * g, const axutil_env_t * env); + +/* + * Return the namespace of the element. + * @param g pointer to a guththila_t structure + * @param env the environment + */ +GUTHTHILA_EXPORT guththila_namespace_t *GUTHTHILA_CALL +guththila_get_namespace(guththila_t * g, const axutil_env_t * env); + +/* + * Return the number of namespaces in the element. + * @param g pointer to a guththila_t structure + * @param env the environment + */ +GUTHTHILA_EXPORT int GUTHTHILA_CALL +guththila_get_namespace_count(guththila_t * g, const axutil_env_t * env); + +/* + * Return the namespace uri of the given namespace. + * @param g pointer to a guththila_t structure + * @param ns pointer to a namespace + * @param env the environment + */ +GUTHTHILA_EXPORT guththila_char_t * GUTHTHILA_CALL +guththila_get_namespace_uri(guththila_t * g, guththila_namespace_t * ns, + const axutil_env_t * env); + +/* + * Return the prefix of the namespace. + * @param g pointer to a guththila_t structure + * @param ns pointer to a namespace + * @param env the environment + */ +GUTHTHILA_EXPORT guththila_char_t *GUTHTHILA_CALL +guththila_get_namespace_prefix(guththila_t * p, guththila_namespace_t * ns, + const axutil_env_t * env); + +/* + * Return the prefix of the namespace at the given position. + * First namespace will have the value 1. + * @param g pointer to a guththila_t structure + * @param index position of the namespace + * @param env the environment + */ +GUTHTHILA_EXPORT guththila_char_t *GUTHTHILA_CALL +guththila_get_namespace_prefix_by_number(guththila_t * g, int index, + const axutil_env_t *env); + +/* + * Get the uri of the namespace at the given position. + * First namespace will have the value 1. + * @param g pointer to a guththila_t structure + * @param index position of the namespace + * @param env the environment + */ +GUTHTHILA_EXPORT guththila_char_t *GUTHTHILA_CALL +guththila_get_namespace_uri_by_number(guththila_t * g, int index, + const axutil_env_t *env); + +/* + * Get the attribute namespace of the attribute at the given position. + * @param g pointer to a guththila_t structure + * @param index position of the namespace + * @param env the environment + */ +GUTHTHILA_EXPORT guththila_char_t *GUTHTHILA_CALL +guththila_get_attribute_namespace_by_number(guththila_t *g, int index, + const axutil_env_t *env); + +/* + * Get the encoding. at the moment we don't support UNICODE + * @param g pointer to a guththila_t structure + * @param env the environment + */ +GUTHTHILA_EXPORT guththila_char_t *GUTHTHILA_CALL +guththila_get_encoding(guththila_t * p, const axutil_env_t * env); + +/* + * To do. Implement a proper error handling mechanism. + * @param g pointer to a guththila_t structure + * @param env the environment + */ +GUTHTHILA_EXPORT void GUTHTHILA_CALL +guththila_set_error_handler(guththila_t * m, guththila_error_func, + const axutil_env_t * env); + +GUTHTHILA_EXPORT guththila_char_t *GUTHTHILA_CALL +guththila_get_current_buffer( + guththila_t * m, + const axutil_env_t * env); + +EXTERN_C_END() +#endif + diff --git a/guththila/include/guththila_attribute.h b/guththila/include/guththila_attribute.h new file mode 100644 index 0000000..8752283 --- /dev/null +++ b/guththila/include/guththila_attribute.h @@ -0,0 +1,127 @@ + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef GUTHTHILA_ATTRIBUTE_H +#define GUTHTHILA_ATTRIBUTE_H + +#include +#include +#include + +EXTERN_C_START() + +#ifndef GUTHTHILA_ATTR_DEF_SIZE +#define GUTHTHILA_ATTR_DEF_SIZE 16 +#endif + +/* Representation of an attribute */ +typedef struct guththila_attr_s +{ + guththila_token_t *pref; /* Prefix */ + guththila_token_t *name; /* Name */ + guththila_token_t *val; /* Value */ +} guththila_attr_t; + +typedef struct guththila_attr_list_s +{ + guththila_attr_t *list; + guththila_stack_t fr_stack; + int size; + int capacity; +} guththila_attr_list_t; + +/** +* Create function of guththila_attr_list_t type structure +* @param env environment, MUST NOT be NULL. +* return new pointer to structure guththila_attr_list_s with initializing stack +* fr_stack +*/ +guththila_attr_list_t * +GUTHTHILA_CALL guththila_attr_list_create(const axutil_env_t * env); + +/** + * Initializing function of guththila_attr_list_t type structure,same + * thing done by the create method + * @param at_list keeps the list of attributes in this structure using + * a guththila_stack_t variable + * @param env environment, MUST NOT be NULL. + * return status of op AXIS2_SUCCESS on success, + * AXIS2_FAILURE on error + */ +int GUTHTHILA_CALL +guththila_attr_list_init( + guththila_attr_list_t * at_list, + const axutil_env_t * env); + +/** + * @param at_list keeps the list of attributes in this structure using + * a guththila_stack_t variable + * @param env environment, MUST NOT be NULL. + * return the top value of the stack which is inside guththila_attr_list_t + */ +guththila_attr_t * +GUTHTHILA_CALL guththila_attr_list_get(guththila_attr_list_t * at_list, + const axutil_env_t * env); + + +/** + * This method push the given attribute in to the stack which is a + * member of guththila_attr_list_t + * @param at_list keeps the list of attributes in this structure using + * a guththila_stack_t variable + * @param attr contains attribute with attribute name,value,and prefix + * @param env environment, MUST NOT be NULL. + * return status of op AXIS2_SUCCESS on success, + * AXIS2_FAILURE on error + */ +int GUTHTHILA_CALL +guththila_attr_list_release( + guththila_attr_list_t * at_list, + guththila_attr_t * attr, + const axutil_env_t * env); + +/** + * Free method for the stack which is inside guththila_attr_list_s + * structure, free the stack and other members + * @param at_list keeps the list of attributes in this structure using + * a guththila_stack_t variable + * @param env environment, MUST NOT be NULL. + * return status of op AXIS2_SUCCESS on success, + * AXIS2_FAILURE on error + */ +void GUTHTHILA_CALL +msuila_attr_list_free_data( + guththila_attr_list_t * at_list, + const axutil_env_t * env); + +/** + * Free method for guththila_attr_list_s structure,this free at_list too. + * @param at_list keeps the list of attributes in this structure using + * a guththila_stack_t variable + * @param attr contains attribute with attribute name,value,and prefix + * @param env environment, MUST NOT be NULL. + * return status of op AXIS2_SUCCESS on success, + * AXIS2_FAILURE on error + */ +void GUTHTHILA_CALL +guththila_attr_list_free( + guththila_attr_list_t * at_list, + const axutil_env_t * env); + +EXTERN_C_END() +#endif /* */ + diff --git a/guththila/include/guththila_buffer.h b/guththila/include/guththila_buffer.h new file mode 100644 index 0000000..8f94fde --- /dev/null +++ b/guththila/include/guththila_buffer.h @@ -0,0 +1,152 @@ + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef GUTHTHILA_BUFFER_H +#define GUTHTHILA_BUFFER_H + +#include +#include + +EXTERN_C_START() + +typedef enum guththila_buffer_type +{ + GUTHTHILA_SINGLE_BUFFER = 0, /* One buffer */ + GUTHTHILA_MULTIPLE_BUFFER /* Mulitple buffers in a buff array */ +} guththila_buffer_type_t; + +typedef struct guththila_buffer_s +{ + /* Required to manupulate multiple buffers */ + size_t *data_size; /* Array containing filled sizes of buffers */ + size_t *buffs_size; /* Array containing actual sizes of buffers */ + guththila_char_t **buff; /* Array of buffers */ + int cur_buff; /* Current buffer */ + int cur_buff_pos; /* Position of the current buffer */ + size_t pre_tot_data; /* All the data in the previous buffers. Not include cur */ + unsigned int no_buffers; /* No of buffers */ + short type; /* Buffer type */ + guththila_char_t *xml; /* All the buffers serialized together */ +} guththila_buffer_t; + +#define GUTHTHILA_BUFFER_DEF_SIZE 16384 +#define GUTHTHILA_BUFFER_DEF_MIN_SIZE 512 +#define GUTHTHILA_BUFFER_NUMBER_OF_BUFFERS 16 + +#ifndef GUTHTHILA_BUFFER_SIZE +#define GUTHTHILA_BUFFER_SIZE(_buffer) (_buffer.size) +#endif + +#ifndef GUTHTHILA_BUFFER_CURRENT_BUFF +#define GUTHTHILA_BUFFER_CURRENT_BUFF(_buffer) ((_buffer).buff[(_buffer).cur_buff] + (_buffer).data_size[(_buffer).cur_buff]) +#endif + +#ifndef GUTHTHILA_BUFFER_CURRENT_BUFF_SIZE +#define GUTHTHILA_BUFFER_CURRENT_BUFF_SIZE(_buffer) ((_buffer).buffs_size[(_buffer).cur_buff] - (_buffer).data_size[(_buffer).cur_buff]) +#endif + +#ifndef GUTHTHILA_BUFFER_CURRENT_DATA_SIZE +#define GUTHTHILA_BUFFER_CURRENT_DATA_SIZE(_buffer) ((_buffer).data_size[(_buffer).cur_buff]) +#endif + +#ifndef GUTHTHILA_BUFFER_PRE_DATA_SIZE +#define GUTHTHILA_BUFFER_PRE_DATA_SIZE(_buffer) ((_buffer).pre_tot_data) +#endif + +/*We never consider tokens not in the current buffer*/ +#ifndef GUTHTHILA_BUF_POS +#define GUTHTHILA_BUF_POS(_buffer, _pos) ((_buffer).buff[(_buffer).cur_buff] + _pos - (_buffer).pre_tot_data) +#endif + +/** + * This method is the create method of guththila_buffer_s structure + * @param buffer structure which is going to create + * @param size size of the buffer which is going to create + * @param env environment, MUST NOT be NULL. + * return status of op AXIS2_SUCCESS on success, + * AXIS2_FAILURE on error + */ +int GUTHTHILA_CALL +guththila_buffer_init(guththila_buffer_t * buffer, + int size, + const axutil_env_t * env); + +/** + * This is the free method of guththila_buffer_s structure + * @param buffer structure which is going to create + * @param env environment, MUST NOT be NULL. + * return status of op AXIS2_SUCCESS on success, + * AXIS2_FAILURE on error + */ +int GUTHTHILA_CALL +guththila_buffer_un_init(guththila_buffer_t * buffer, + const axutil_env_t * env); + +/** + * This method creates a new buffer and copy the content of given + * data by buffer variable + * @param mu_buff structure which is going to create + * @param buffer data to copy in to new buffer + * @param size size of the buffer to create + * @param env environment, MUST NOT be NULL. + * return status of op AXIS2_SUCCESS on success, + * AXIS2_FAILURE on error + */ +int GUTHTHILA_CALL +guththila_buffer_init_for_buffer(guththila_buffer_t * mu_buff, + guththila_char_t *buffer, + int size, + const axutil_env_t * env); + +void *GUTHTHILA_CALL +guththila_get_position(guththila_buffer_t * buffer, + int pos, + const axutil_env_t * env); + +int GUTHTHILA_CALL +guththila_buffer_next(guththila_buffer_t * buffer, + const axutil_env_t * env); + + +/** + * This method create new xml element which is having the + * size of cur_buff + * data by buffer variable + * @param buffer + * @param env environment, MUST NOT be NULL. + * return xml element of guththila_buffer_s structure + */ +void *GUTHTHILA_CALL +guththila_buffer_get(guththila_buffer_t * buffer, + const axutil_env_t * env); + + +int GUTHTHILA_CALL +guththila_buffer_shift(guththila_buffer_t * buffer, + int no, const axutil_env_t * env); + +int GUTHTHILA_CALL +guththila_buffer_insert_data(guththila_buffer_t * buffer, + void *buff, size_t buff_len, + const axutil_env_t * env); + +EXTERN_C_END() +#endif + + + + diff --git a/guththila/include/guththila_defines.h b/guththila/include/guththila_defines.h new file mode 100644 index 0000000..d297f55 --- /dev/null +++ b/guththila/include/guththila_defines.h @@ -0,0 +1,73 @@ + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef GUTHTHILA_DEFINES_H +#define GUTHTHILA_DEFINES_H + +#if defined(_WIN32) +#define GUTHTHILA_EXPORT __declspec(dllexport) +#else +#define GUTHTHILA_EXPORT +#endif + +#if defined(__GNUC__) +#if defined(__i386) +#define GUTHTHILA_CALL __attribute__((cdecl)) +#else +#define GUTHTHILA_CALL +#endif +#else +#if defined(__unix) +#define GUTHTHILA_CALL +#else +#define GUTHTHILA_CALL __stdcall +#endif +#endif + +#ifndef guththila_char_t +#define guththila_char_t char +#endif + +#ifndef GUTHTHILA_SUCCESS +#define GUTHTHILA_SUCCESS 1 +#endif + +#ifndef GUTHTHILA_FAILURE +#define GUTHTHILA_FAILURE 0 +#endif + +#ifdef __cplusplus +#define EXTERN_C_START() extern "C" { +#define EXTERN_C_END() } +#else +#define EXTERN_C_START() +#define EXTERN_C_END() +#endif + +#ifndef GUTHTHILA_EOF +#define GUTHTHILA_EOF (-1) +#endif + +#ifndef GUTHTHILA_FALSE +#define GUTHTHILA_FALSE 0 +#endif + +#ifndef GUTHTHILA_TRUE +#define GUTHTHILA_TRUE 1 +#endif + +#endif diff --git a/guththila/include/guththila_error.h b/guththila/include/guththila_error.h new file mode 100644 index 0000000..834e954 --- /dev/null +++ b/guththila/include/guththila_error.h @@ -0,0 +1,96 @@ + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include + +#ifndef GUTHTHILA_ERROR_H +#define GUTHTHILA_ERROR_H +EXTERN_C_START() typedef enum guththila_error_l +{ + GUTHTHILA_VALIDITY_ERROR, + GUTHTHILA_VALIDITY_WARNING, + GUTHTHILA_PARSER_ERROR, + GUTHTHILA_PARSER_WARNING +} guththila_error_level; +enum guththila_error_codes +{ + GUTHTHILA_ERROR_NONE = + 0, GUTHTHILA_ERROR_NO_MEMORY, + GUTHTHILA_ERROR_INVALID_NULL_PARAMETER, + GUTHTHILA_ERROR_INVALID_ITERATOR_STATE, + GUTHTHILA_ERROR_INVALID_NODE_TYPE, + GUTHTHILA_STREAM_WRITER_ERROR_NOT_IN_GUTHTHILA_START_ELEMENT, + GUTHTHILA_STREAM_WRITER_ERROR_WRITING_TO_STREAM, + GUTHTHILA_STREAM_WRITER_ERROR_STREAM_STRUCT_NULL, + GUTHTHILA_STREAM_WRITER_ERROR_LOCAL_NAME_NULL, + GUTHTHILA_STREAM_WRITER_ERROR_GUTHTHILA_namespace_t_NULL, + GUTHTHILA_STREAM_WRITER_ERROR_PREFIX_NULL, + GUTHTHILA_STREAM_WRITER_ERROR_GUTHTHILA_namespace_t_NOT_DECLARED, + GUTHTHILA_STREAM_WRITER_ERROR_GUTHTHILA_element_t_GUTHTHILA_stack_t_EMPTY, + GUTHTHILA_STREAM_WRITER_ERROR_ILLEGAL_STATE, + GUTHTHILA_STREAM_WRITER_ERROR_GUTHTHILA_COMMENT_NULL, + GUTHTHILA_STREAM_WRITER_ERROR_ILLEGAL_GUTHTHILA_COMMENT, + GUTHTHILA_STREAM_WRITER_ERROR_PROCESSING_INSTRUCTION_TARGET_NULL, + GUTHTHILA_STREAM_WRITER_ERROR_CDATA_NULL, + GUTHTHILA_STREAM_WRITER_ERROR_ILLEGAL_CDATA, + GUTHTHILA_STREAM_WRITER_ERROR_DTD_NULL, + GUTHTHILA_STREAM_WRITER_ERROR_ENTITY_REF_NULL, + GUTHTHILA_STREAM_WRITER_ERROR_ILLEGAL_XML_VERSION, + GUTHTHILA_STREAM_WRITER_ERROR_TEXT_NULL, + GUTHTHILA_STREAM_WRITER_ERROR_ILLEGAL_PREFIX, + GUTHTHILA_STREAM_WRITER_ERROR_OUT_OF_MEMORY, + GUTHTHILA_STREAM_WRITER_ERROR_FILE_NOT_FOUND, + GUTHTHILA_STREAM_READER_ERROR_OUT_OF_MEMORY, + GUTHTHILA_ERROR_INVALID_ENCODING_DECLARATION, + GUTHTHILA_ERROR_UNEXPECTED_UTF16_EOF, + GUTHTHILA_ERROR_UNEXPECTED_EOF, + GUTHTHILA_ERROR_PROCESS_EQUAL, + GUTHTHILA_ERROR_INCORRECT_VERSION_INFO, + GUTHTHILA_ERROR_INCORRECT_XML_DECLARATION, + GUTHTHILA_ERROR_VERSION_INFO_NOT_FOUND, + GUTHTHILA_ERROR_ENCODING_DECLARATION_ERROR, + GUTHTHILA_ERROR_STANDALONE_ERROR_IN_YES, + GUTHTHILA_ERROR_STANDALONE_ERROR_IN_NO, + GUTHTHILA_ERROR_STANDALONE_ERROR_YES_OR_NO_NOT_AVAILABLE, + GUTHTHILA_ERROR_MISSING_GREATER_SIGN_IN_XML_DECLARATION, + GUTHTHILA_ERROR_INVALID_NAME_STARTING_CHARACTER, + GUTHTHILA_ERROR_QUOTES_NOT_FOUND_BEFORE_ATTRIBUTE_VALUE, + GUTHTHILA_ERROR_EMPTY_ELEMENT_NOT_CLOSED, + GUTHTHILA_ERROR_END_TAG_NOT_CLOSED, + GUTHTHILA_ERROR_MORE_HYPENS_OCCURED_IN_COMMENT, + GUTHTHILA_ERROR_TOKENIZE_ERROR, + GUTHTHILA_ERROR_INVALID_TOKEN_TYPE, + GUTHTHILA_ERROR_NULL_ATTRIBUTE_NAME, + GUTHTHILA_ERROR_NULL_ATTRIBUTE_VALUE, + GUTHTHILA_ERROR_NULL_ATTRIBUTE_PREFIX, + GUTHTHILA_ERROR_REQUESTED_NUMBER_GREATER_THAN_STACK_SIZE, + GUTHTHILA_WRITER_ERROR_EMPTY_ARGUMENTS, + GUTHTHILA_WRITER_ERROR_NON_EXSISTING_PREFIX, + GUTHTHILA_WRITER_ERROR_EMPTY_WRITER, + GUTHTHILA_WRITER_ERROR_NON_MATCHING_ELEMENTS, + GUTHTHILA_WRITER_ERROR_INVALID_BUFFER, + GUTHTHILA_WRITER_ERROR_INVALID_CHAR_IN_NAME, + GUTHTHILA_WRITER_ERROR_XML_STRING_IN_NAME, + GUTHTHILA_WRITER_ERROR_EXCESS_HYPENS_IN_COMMENT, + GUTHTHILA_WRITER_ERROR_INVALID_CHAR_IN_ATTRIBUTE, + GUTHTHILA_WRITER_ERROR_NON_EXSISTING_URI, + GUTHTHILA_WRITER_ERROR_SAME_ATTRIBUTE_REPEAT, + GUTHTHILA_ERROR_ATTRIBUTE_FREE +}; +EXTERN_C_END() +#endif /* */ + diff --git a/guththila/include/guththila_namespace.h b/guththila/include/guththila_namespace.h new file mode 100644 index 0000000..a845665 --- /dev/null +++ b/guththila/include/guththila_namespace.h @@ -0,0 +1,76 @@ + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef GUTHTHILA_NAMESPACE_H +#define GUTHTHILA_NAMESPACE_H + +#include +#include +#include +EXTERN_C_START() + +#ifndef GUTHTHILA_NAMESPACE_DEF_SIZE +#define GUTHTHILA_NAMESPACE_DEF_SIZE 4 +#endif + +typedef struct guththila_namespace_s +{ + guththila_token_t *name; /* Name */ + guththila_token_t *uri; /* URI */ +} guththila_namespace_t; + +typedef struct guththila_namespace_list_s +{ + guththila_namespace_t *list; + guththila_stack_t fr_stack; + int size; + int capacity; +} guththila_namespace_list_t; + +guththila_namespace_list_t *GUTHTHILA_CALL +guththila_namespace_list_create( + const axutil_env_t * env); + +int GUTHTHILA_CALL +guththila_namespace_list_init( + guththila_namespace_list_t * at_list, + const axutil_env_t * env); + +guththila_namespace_t * GUTHTHILA_CALL +guththila_namespace_list_get( + guththila_namespace_list_t *at_list, + const axutil_env_t * env); + +int GUTHTHILA_CALL +guththila_namespace_list_release( + guththila_namespace_list_t * at_list, + guththila_namespace_t * namesp, + const axutil_env_t * env); + +void GUTHTHILA_CALL +msuila_namespace_list_free_data( + guththila_namespace_list_t * at_list, + const axutil_env_t * env); + +void GUTHTHILA_CALL +guththila_namespace_list_free( + guththila_namespace_list_t * at_list, + const axutil_env_t * env); + +EXTERN_C_END() +#endif + diff --git a/guththila/include/guththila_reader.h b/guththila/include/guththila_reader.h new file mode 100644 index 0000000..cad53a1 --- /dev/null +++ b/guththila/include/guththila_reader.h @@ -0,0 +1,115 @@ + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef GUTHTHILA_READER_H +#define GUTHTHILA_READER_H + +#include +#include +#include + +EXTERN_C_START() + +typedef int(GUTHTHILA_CALL * GUTHTHILA_READ_INPUT_CALLBACK)( + guththila_char_t *buffer, + int size, + void *ctx); + +enum guththila_reader_type +{ + GUTHTHILA_FILE_READER = 1, + GUTHTHILA_IO_READER, + GUTHTHILA_MEMORY_READER +}; + +typedef struct guththila_reader_s +{ + int type; /* Type of reader */ + FILE *fp; /* File pointer */ + guththila_char_t *buff; /* Buffer */ + int buff_size; /* Buff size */ + GUTHTHILA_READ_INPUT_CALLBACK input_read_callback; /* Call back */ + void *context; /* Context */ +} guththila_reader_t; + +#ifndef GUTHTHILA_READER_SET_LAST_START +#define GUTHTHILA_READER_SET_LAST_START(_reader, _start) ((_reader)->start = _start) +#endif + +#ifndef GUTHTHILA_READER_STEP_BACK +#define GUTHTHILA_READER_STEP_BACK(_reader) ((_reader->next--)) +#endif + +/* + * Reading a file. + * @param filename name of the file + * @param env environment + */ +GUTHTHILA_EXPORT guththila_reader_t * GUTHTHILA_CALL +guththila_reader_create_for_file(guththila_char_t *filename, + const axutil_env_t * env); + +/* + * Reading from a call back function. + * @param input_read_callback function pointer to read data + * @param ctx context + * @param env environment + */ +GUTHTHILA_EXPORT guththila_reader_t * GUTHTHILA_CALL +guththila_reader_create_for_io(GUTHTHILA_READ_INPUT_CALLBACK + input_read_callback, void *ctx, + const axutil_env_t * env); + +/* + * Reading from memory buffer. + * @param buffer buffer + * @param size size of the buffer + * @param env environment + */ +GUTHTHILA_EXPORT guththila_reader_t * GUTHTHILA_CALL +guththila_reader_create_for_memory(void *buffer, + int size, + const axutil_env_t * env); + +/* + * Read the specified number of character to the given buffer. + * @param r reader + * @param buffer buffer to place the read data + * @param offset position to place the data on the given buffer + * @param length number of bytes to read + * @param env environment + * @return number of bytes put in to the buffer. -1 if end of the read. + */ +GUTHTHILA_EXPORT int GUTHTHILA_CALL guththila_reader_read( + guththila_reader_t * r, + guththila_char_t * buffer, + int offset, + int length, + const axutil_env_t * env); + +/* + * Free the reader. + * @param r reader + * @param env environment + */ +GUTHTHILA_EXPORT void GUTHTHILA_CALL guththila_reader_free( + guththila_reader_t * r, + const axutil_env_t * env); + +EXTERN_C_END() +#endif /* */ + diff --git a/guththila/include/guththila_stack.h b/guththila/include/guththila_stack.h new file mode 100644 index 0000000..3520d73 --- /dev/null +++ b/guththila/include/guththila_stack.h @@ -0,0 +1,96 @@ + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef GUTHTHILA_STACK_H +#define GUTHTHILA_STACK_H + +#include +#include + +#include +#include +#define GUTHTHILA_STACK_DEFAULT 16 + +EXTERN_C_START() + +typedef struct guththila_stack_s +{ + /* Number of Items in the stack */ + int top; + /* Max number of Items that can be hold in data */ + int max; + void ** data; +} guththila_stack_t; + +#ifndef GUTHTHILA_STACK_SIZE +#define GUTHTHILA_STACK_SIZE(_stack) ((_stack).top) +#endif + +#ifndef GUTHTHILA_STACK_TOP_INDEX +#define GUTHTHILA_STACK_TOP_INDEX(_stack) (((_stack).top - 1)) +#endif + +int GUTHTHILA_CALL +guththila_stack_init( + guththila_stack_t * stack, + const axutil_env_t * env); + +void GUTHTHILA_CALL +guththila_stack_free( + guththila_stack_t * stack, + const axutil_env_t * env); + +void GUTHTHILA_CALL +guththila_stack_un_init( + guththila_stack_t * stack, + const axutil_env_t * env); + +void * GUTHTHILA_CALL +guththila_stack_pop( + guththila_stack_t * stack, + const axutil_env_t * env); + +int GUTHTHILA_CALL +guththila_stack_push( + guththila_stack_t * stack, + void *data, + const axutil_env_t * env); + +void * GUTHTHILA_CALL +guththila_stack_peek( + guththila_stack_t * stack, + const axutil_env_t * env); + +void * GUTHTHILA_CALL +guththila_stack_get_by_index( + guththila_stack_t * stack, + int index, + const axutil_env_t * env); + +int GUTHTHILA_CALL +guththila_stack_del_top( + guththila_stack_t * stack, + const axutil_env_t * env); + +int GUTHTHILA_CALL +guththila_stack_is_empty( + guththila_stack_t * stack, + const axutil_env_t * env); + +EXTERN_C_END() +#endif + diff --git a/guththila/include/guththila_token.h b/guththila/include/guththila_token.h new file mode 100644 index 0000000..ae8719c --- /dev/null +++ b/guththila/include/guththila_token.h @@ -0,0 +1,174 @@ + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef GUTHTHILA_TOKEN_H +#define GUTHTHILA_TOKEN_H + +#include +#include + +EXTERN_C_START() + +typedef struct guththila_token_s +{ + short type; + guththila_char_t *start; + int _start; + size_t size; + int last; + int ref; +} guththila_token_t; + +enum guththila_token_type +{ + _Unknown = 1, + _name, + _attribute_name, + _attribute_value, + _prefix, + _char_data, + _text_data +}; + +typedef struct guththila_tok_list_s +{ + guththila_stack_t fr_stack; + guththila_token_t **list; + int no_list; + int cur_list; + int *capacity; +} guththila_tok_list_t; + +#ifndef GUTHTHILA_TOK_DEF_SIZE +#define GUTHTHILA_TOK_DEF_SIZE 16 +#endif + +#ifndef GUTHTHILA_TOK_DEF_LIST_SIZE +#define GUTHTHILA_TOK_DEF_LIST_SIZE 16 +#endif + +#ifndef GUTHTHILA_TOKEN_LEN +#define GUTHTHILA_TOKEN_LEN(tok) (tok->size) +#endif + +#ifndef GUTHTHILA_TOKEN_TO_STRING +#define GUTHTHILA_TOKEN_TO_STRING(tok, string, _env) \ + { \ + string = (guththila_char_t *) AXIS2_MALLOC(_env->allocator, (GUTHTHILA_TOKEN_LEN(tok) + 1) * sizeof(guththila_char_t)); \ + memcpy(string, (tok)->start, GUTHTHILA_TOKEN_LEN(tok)); \ + string[GUTHTHILA_TOKEN_LEN(tok)] = 0; \ + } +#endif + +/* + * Initialize token list. + */ +int GUTHTHILA_CALL +guththila_tok_list_init( + guththila_tok_list_t * tok_list, + const axutil_env_t * env); + +/* + * Free the token list. Allocated tokens are not free. + */ +void GUTHTHILA_CALL +guththila_tok_list_free( + guththila_tok_list_t * tok_list, + const axutil_env_t * env); + +/* + * Get a token from the list. + */ +guththila_token_t * +GUTHTHILA_CALL guththila_tok_list_get_token( + guththila_tok_list_t * tok_list, + const axutil_env_t * env); + +/* + * Release a token to the token list. + */ +int GUTHTHILA_CALL +guththila_tok_list_release_token( + guththila_tok_list_t * tok_list, + guththila_token_t * token, + const axutil_env_t * env); + +/* + * Free the tokens in the token list. + */ +void GUTHTHILA_CALL +guththila_tok_list_free_data( + guththila_tok_list_t * tok_list, + const axutil_env_t * env); + +/* + * Grow the token list. + */ +int GUTHTHILA_CALL +guththila_tok_list_grow( + guththila_tok_list_t * tok_list, + const axutil_env_t * env); + +/* + * Compare a token with a string. + * Return 0 if match. + */ +int GUTHTHILA_CALL +guththila_tok_str_cmp( + guththila_token_t * tok, + guththila_char_t *str, + size_t str_len, + const axutil_env_t * env); + +/* + * Compare two tokens for string equalance + * Return 0 if match. + */ +int GUTHTHILA_CALL +guththila_tok_tok_cmp( + guththila_token_t * tok1, + guththila_token_t * tok2, + const axutil_env_t * env); + +void GUTHTHILA_CALL +guththila_set_token( + guththila_token_t* tok, + guththila_char_t* start, + short type, + int size, + int _start, + int last, + int ref, + const axutil_env_t* env); + +EXTERN_C_END() +#endif + + + + + + + + + + + + + + + diff --git a/guththila/include/guththila_xml_writer.h b/guththila/include/guththila_xml_writer.h new file mode 100644 index 0000000..afc5a26 --- /dev/null +++ b/guththila/include/guththila_xml_writer.h @@ -0,0 +1,507 @@ + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef GUTHTHILA_XML_WRITER_H +#define GUTHTHILA_XML_WRITER_H + +#include +#include +#include +#include +#include + +EXTERN_C_START() +#define GUTHTHILA_XML_WRITER_TOKEN + +/* +Design notes:- +namesp member of guththila_xml_writer_s is populated with malloc created objects. +Providing a list for this seems expensive because most of the times only few +namespaces are present in a XML document. + +element member of guththila_xml_writer_s must be povided the list capablity. This +is particularly important in very deep XML documents. +*/ +typedef enum guththila_writer_type_s +{ + GUTHTHILA_WRITER_FILE = 1, + GUTHTHILA_WRITER_MEMORY +} guththila_writer_type_t; + +typedef struct guththila_writer_s +{ + short type; + FILE *out_stream; + guththila_buffer_t *buffer; + int next; +} +guththila_writer_t; + +typedef enum guththila_writer_status_s +{ + /*Started writing a non empty element */ + START = 1, + /*Started writing a empty element */ + START_EMPTY, + /*We are in a position to begin wrting an element */ + BEGINING +} guththila_writer_status_t; + +/*Main structure which provides the writer capability*/ +typedef struct guththila_xml_writer_s +{ + guththila_stack_t element; + guththila_stack_t namesp; + guththila_writer_t *writer; +#ifdef GUTHTHILA_XML_WRITER_TOKEN + guththila_tok_list_t tok_list; +#endif + /* Type of this writer. Can be file writer or memory writer */ + guththila_writer_type_t type; + + FILE *out_stream; + guththila_buffer_t buffer; + guththila_writer_status_t status; + int next; +} guththila_xml_writer_t; + +/*TODO: we need to came up with common implementation of followng two structures in writer and reader*/ + +/* +This is a private structure for keeping track of the elements. When we start to write an element this structure will be pop +*/ +typedef struct guththila_xml_writer_element_s +{ +#ifdef GUTHTHILA_XML_WRITER_TOKEN + guththila_token_t *prefix; + guththila_token_t *name; +#else + guththila_char_t *prefix; + guththila_char_t *name; +#endif + /* contains the number of the stack which holds the namespaces + for this element. When we close this element all the namespaces + that are below this should also must be closed */ + int name_sp_stack_no; +} +guththila_xml_writer_element_t; + +typedef struct guththila_xml_writer_namesp_s +{ + /* These are double pointers because a single element may contain multple + namespace declarations */ +#ifdef GUTHTHILA_XML_WRITER_TOKEN + guththila_token_t **name; + guththila_token_t **uri; +#else + guththila_char_t **name; + guththila_char_t **uri; +#endif + int no; /*number of namespaces */ + int size; +} +guththila_xml_writer_namesp_t; + +#define GUTHTHILA_XML_WRITER_NAMESP_DEF_SIZE 4 + +/*Writer functions*/ + +/* + * Create a writer which writes to a file. + * @param file_name name of the file + * @param env pointer to the environment + */ +GUTHTHILA_EXPORT guththila_xml_writer_t *GUTHTHILA_CALL +guththila_create_xml_stream_writer( + char *file_name, + const axutil_env_t * env); + +/* + * Create a writer which writes to a memory buffer. + * @param env pointer to the environment + */ +GUTHTHILA_EXPORT guththila_xml_writer_t *GUTHTHILA_CALL +guththila_create_xml_stream_writer_for_memory( + const axutil_env_t * env); + +/* + * Jus write what ever the content in the buffer. If the writer was in + * a start of a element it will close it. + * @param wr pointer to the writer + * @param buff buffer containing the data + * @param size size of the buffer + * @param env pointer to the environment + */ +GUTHTHILA_EXPORT int GUTHTHILA_CALL guththila_write_to_buffer( + guththila_xml_writer_t * wr, + char *buff, + int size, + const axutil_env_t * env); + +/* + * Write the name space with the given prifix and namespace. + * @param wr pointer to the writer + * @param prefix prefix of the namespace + * @param uri uri of the namespace + * @param env pointer to the environment + */ +GUTHTHILA_EXPORT int GUTHTHILA_CALL guththila_write_namespace( + guththila_xml_writer_t * wr, + char *prefix, + char *uri, + const axutil_env_t * env); + +/* + * Write the name space with the given prifix and namespace. + * @param wr pointer to the writer + * @param prefix prefix of the namespace + * @param uri uri of the namespace + * @param local_name name of the attribute + * @param value value of the attribute + * @param env pointer to the environment + */ +GUTHTHILA_EXPORT int GUTHTHILA_CALL +guththila_do_write_attribute_with_prefix_and_namespace( + guththila_xml_writer_t * wr, + char *prefix, + char *uri, + char *local_name, + char *value, + const axutil_env_t * env); + + +/* + * Write the start document element with the xml version and encoding. + * @param wr pointer to the writer + * @param env pointer to the environment + * @param encoding encoding of the XML. + * @param version xml version + */ +GUTHTHILA_EXPORT int GUTHTHILA_CALL guththila_write_start_document( + guththila_xml_writer_t * wr, + const axutil_env_t * env, + char *encoding, + char *version); + +/* + * Write the start element. + * @param wr pointer to the writer + * @param name name of the element + * @param env pointer to the environment + */ +GUTHTHILA_EXPORT int GUTHTHILA_CALL guththila_write_start_element( + guththila_xml_writer_t * wr, + char *name, + const axutil_env_t * env); + +/* + * Write the end element. + * @param wr pointer to the writer + * @param env pointer to the environment + */ +GUTHTHILA_EXPORT int GUTHTHILA_CALL guththila_write_end_element( + guththila_xml_writer_t * wr, + const axutil_env_t * env); + +/* + * Not implemented. + * @param wr pointer to the writer + * @param env pointer to the environment + */ +GUTHTHILA_EXPORT int GUTHTHILA_CALL guththila_close( + guththila_xml_writer_t * wr, + const axutil_env_t * env); + +/* + * Write the text content of a element. + * @param wr pointer to the writer + * @param buff character string + * @param env pointer to the environment + */ +GUTHTHILA_EXPORT int GUTHTHILA_CALL guththila_write_characters( + guththila_xml_writer_t * wr, + char *buff, + const axutil_env_t * env); + +/* + * Write comment with the given text data. + * @param wr pointer to the writer + * @param buff character string + * @param env pointer to the environment + */ +GUTHTHILA_EXPORT int GUTHTHILA_CALL guththila_write_comment( + guththila_xml_writer_t * wr, + char *buff, + const axutil_env_t * env); + +/* + * Write scape character. + * @param wr pointer to the writer + * @param buff character string + * @param env pointer to the environment + */ +GUTHTHILA_EXPORT int GUTHTHILA_CALL guththila_write_escape_character( + guththila_xml_writer_t * wr, + char *buff, + const axutil_env_t * env); + +/* + * Start to write an empty element with the given name. + * @param wr pointer to the writer + * @param name name of the element + * @param env pointer to the environment + */ +GUTHTHILA_EXPORT int GUTHTHILA_CALL guththila_write_empty_element( + guththila_xml_writer_t * wr, + char *name, + const axutil_env_t * env); + +/* + * Write a defualt namespace. + * @param wr pointer to the writer + * @param uri uri of the namespace + * @param env pointer to the environment + */ +GUTHTHILA_EXPORT int GUTHTHILA_CALL guththila_write_default_namespace( + guththila_xml_writer_t * wr, + char *uri, + const axutil_env_t * env); + +/* + * Write a attribute with the given name and value. + * @param wr pointer to the writer + * @param localname name of the attribute + * @param value value of the attribute + * @param env pointer to the environment + */ +GUTHTHILA_EXPORT int GUTHTHILA_CALL guththila_write_attribute( + guththila_xml_writer_t * wr, + char *localname, + char *value, + const axutil_env_t * env); + +/* + * Write a attribute with the given name and value and namespace. + * @param wr pointer to the writer + * @param prefix prefix of the attribute + * @param namespace_uri uri of the namespace + * @param localname name of the attribute + * @param value value of the attribute + * @param env pointer to the environment + */ +GUTHTHILA_EXPORT int GUTHTHILA_CALL +guththila_write_attribute_with_prefix_and_namespace( + guththila_xml_writer_t * wr, + char *prefix, + char *namespace_uri, + char *localname, + char *value, + const axutil_env_t * env); + +/* + * Write a attribute with the given name, value and prefix. If the prefix + * is not defined previously as a namespace this method will fail. + * @param wr pointer to the writer + * @param prefix prefix of the attribute + * @param localname name of the attribute + * @param value value of the attribute + * @param env pointer to the environment + */ +GUTHTHILA_EXPORT int GUTHTHILA_CALL guththila_write_attribute_with_prefix( + guththila_xml_writer_t * wr, + char *prefix, + char *localname, + char *value, + const axutil_env_t * env); + +/* + * Write a attribute with the given name, value and namespace uri. + * If the namespace is not defined previously as a namespace this + * method will fail. The prefix corresponding to the namespace uri + * will be used. + * @param wr pointer to the writer + * @param namesp namespace uri + * @param localname name of the attribute + * @param value value of the attribute + * @param env pointer to the environment + */ +GUTHTHILA_EXPORT int GUTHTHILA_CALL guththila_write_attribute_with_namespace( + guththila_xml_writer_t * wr, + char *namesp, + char *localname, + char *value, + const axutil_env_t * env); + +/* + * Write a start element with prefix and namespace. If the namespace is not + * defined previoully new namespace will be written. + * @param wr pointer to the writer + * @param prefix prefix of the attribute + * @param namespace_uri uri + * @param localname name of the attribute + * @param env pointer to the environment + */ +GUTHTHILA_EXPORT int GUTHTHILA_CALL +guththila_write_start_element_with_prefix_and_namespace( + guththila_xml_writer_t * wr, + char *prefix, + char *namespace_uri, + char *local_name, + const axutil_env_t * env); + +/* + * Write a start element with the namespace. If the namespace is not + * defined previously method will fail. + * @param wr pointer to the writer + * @param namespace_uri uri + * @param localname name of the attribute + * @param env pointer to the environment + */ +GUTHTHILA_EXPORT int GUTHTHILA_CALL +guththila_write_start_element_with_namespace( + guththila_xml_writer_t * wr, + char *namespace_uri, + char *local_name, + const axutil_env_t * env); + +/* + * Write a start element with the prefix. If the prefix is not + * defined previously method will fail. + * @param wr pointer to the writer + * @param namespace_uri uri + * @param localname name of the attribute + * @param env pointer to the environment + */ +GUTHTHILA_EXPORT int GUTHTHILA_CALL +guththila_write_start_element_with_prefix( + guththila_xml_writer_t * wr, + char *prefix, + char *local_name, + const axutil_env_t * env); + +/* + * Write a empty element with prefix and namespace. If the namespace is not + * defined previoully new namespace will be written. + * @param wr pointer to the writer + * @param prefix prefix of the attribute + * @param namespace_uri uri + * @param localname name of the attribute + * @param env pointer to the environment + */ +GUTHTHILA_EXPORT int GUTHTHILA_CALL +guththila_write_empty_element_with_prefix_and_namespace( + guththila_xml_writer_t * wr, + char *prefix, + char *namespace_uri, + char *local_name, + const axutil_env_t * env); + +/* + * Write a empty element with the namespace. If the namespace is not + * defined previously method will fail. + * @param wr pointer to the writer + * @param namespace_uri uri + * @param localname name of the attribute + * @param env pointer to the environment + */ +GUTHTHILA_EXPORT int GUTHTHILA_CALL +guththila_write_empty_element_with_namespace( + guththila_xml_writer_t * wr, + char *namespace_uri, + char *local_name, + const axutil_env_t * env); + +/* + * Write a empty element with the prefix. If the prefix is not + * defined previously method will fail. + * @param wr pointer to the writer + * @param namespace_uri uri + * @param localname name of the attribute + * @param env pointer to the environment + */ +GUTHTHILA_EXPORT int GUTHTHILA_CALL +guththila_write_empty_element_with_prefix( + guththila_xml_writer_t * wr, + char *prefix, + char *local_name, + const axutil_env_t * env); + +/* + * Close all the elements that were started by writing the end elements. + * @param wr pointer to the writer + * @param env pointer to the environment + */ +GUTHTHILA_EXPORT int GUTHTHILA_CALL guththila_write_end_document( + guththila_xml_writer_t * wr, + const axutil_env_t * env); +/* + * Write a new element with the name, then write the characters as text, + * then close the element and write a new line. + * @param wr pointer to the writer + * @element_name name of the element + * @characters text of the new element + * @param env pointer to the environment + */ +GUTHTHILA_EXPORT int GUTHTHILA_CALL guththila_write_line( + guththila_xml_writer_t * wr, + char *element_name, + char *characters, + const axutil_env_t * env); + +/* + * Get the memory buffer that is written. + * @param wr pointer to the writer + * @param env pointer to the environment + * @return memory buffer + */ +GUTHTHILA_EXPORT char *GUTHTHILA_CALL guththila_get_memory_buffer( + guththila_xml_writer_t * wr, + const axutil_env_t * env); + +/* + * Get the size of the memory buffer. + * @param wr pointer to the writer + * @param env pointer to the environment + * @return size of the buffer + */ +GUTHTHILA_EXPORT unsigned int GUTHTHILA_CALL +guththila_get_memory_buffer_size( + guththila_xml_writer_t * wr, + const axutil_env_t * env); + +/* + * Free the writer. + * @param wr pointer to the writer + * @param env pointer to the environment + */ +GUTHTHILA_EXPORT void GUTHTHILA_CALL guththila_xml_writer_free( + guththila_xml_writer_t * wr, + const axutil_env_t * env); +/* + * Get the prefix for the namespace. + * @param wr pointer to the writer + * @namespace namespace uri + * @param env pointer to the environment + * @return prefix for the namspace uri + */ +GUTHTHILA_EXPORT char *GUTHTHILA_CALL guththila_get_prefix_for_namespace( + guththila_xml_writer_t * wr, + char *namespace, + const axutil_env_t * env); + +EXTERN_C_END() +#endif diff --git a/guththila/samples/guththila_main.c b/guththila/samples/guththila_main.c new file mode 100644 index 0000000..687e490 --- /dev/null +++ b/guththila/samples/guththila_main.c @@ -0,0 +1,186 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "guththila.h" +#include "guththila_defines.h" + +int +main( + int argc, + char *argv[]) +{ + int c; + axutil_allocator_t *allocator; + guththila_reader_t *red; + axutil_env_t *environment; + guththila_t *parser; + char *xml_buffer; + allocator = axutil_allocator_init(NULL); + xml_buffer + = "addddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd123"; + environment = axutil_env_create(allocator); + + if(argc > 1) + red = guththila_reader_create_for_file(environment, argv[1]); + else + { + if(xml_buffer) + { + int size = 0; + size = strlen(xml_buffer); + red = guththila_reader_create_for_memory(environment, (void *)xml_buffer, size, NULL); + } + } + + parser = guththila_create(environment, red); + guththila_read(environment, parser); + + while((c = guththila_next(environment, parser)) != -1) + { + switch(c) + { + case GUTHTHILA_START_DOCUMENT: + { + int ix; + printf(" 0; ix--) + { + guththila_attribute_t *a; + char *p; + a = guththila_get_attribute(environment, parser); + p = guththila_get_attribute_name(environment, parser, a); + printf("%s=\"", p); + AXIS2_FREE(allocator, p); + p = guththila_get_attribute_value(environment, parser, a); + printf("%s\" ", p); + AXIS2_FREE(allocator, p); + guththila_attribute_free(environment, a); + } + printf("?>\n"); + } + break; + case GUTHTHILA_START_ELEMENT: + case GUTHTHILA_EMPTY_ELEMENT: + { + int ia; + int d; + char *p; + guththila_depth_t *depth; + + printf("<"); + p = guththila_get_prefix(environment, parser); + if(p) + { + printf("%s:", p); + AXIS2_FREE(allocator, p); + } + p = guththila_get_name(environment, parser); + printf("%s", p); + AXIS2_FREE(allocator, p); + + ia = guththila_get_attribute_count(environment, parser); + for(; ia > 0; ia--) + { + /* p = guththila_get_attribute_prefix_by_number + (parser, ia); */ + p = guththila_get_attribute_prefix_by_number(environment, parser, ia); + if(p) + { + printf(" %s:", p); + AXIS2_FREE(allocator, p); + p = guththila_get_attribute_name_by_number(environment, parser, ia); + printf("%s=\"", p); + AXIS2_FREE(allocator, p); + p = guththila_get_attribute_value_by_number(environment, parser, ia); + printf("%s\"", p); + AXIS2_FREE(allocator, p); + } + else + { + p = guththila_get_attribute_name_by_number(environment, parser, ia); + printf(" %s=\"", p); + AXIS2_FREE(allocator, p); + p = guththila_get_attribute_value_by_number(environment, parser, ia); + printf("%s\"", p); + AXIS2_FREE(allocator, p); + } + } + depth = (guththila_depth_t *)axutil_stack_get(parser->dep, environment); + d = depth->count; + for(; d > 0; d--) + { + p = guththila_get_namespace_prefix_by_number(environment, parser, d); + if(strncmp(p, "xmlns", 5)) + { + printf(" xmlns:"); + printf("%s=\"", p); + } + else + printf(" xmlns=\""); + AXIS2_FREE(allocator, p); + p = guththila_get_namespace_uri_by_number(environment, parser, d); + printf("%s\"", p); + AXIS2_FREE(allocator, p); + } + if(parser->guththila_event == GUTHTHILA_START_ELEMENT) + printf(">"); + else if(parser->guththila_event == GUTHTHILA_EMPTY_ELEMENT) + printf("/>"); + else + printf("error \n"); + + } + break; + case GUTHTHILA_END_ELEMENT: + { + char *p; + printf(""); + } + break; + case GUTHTHILA_CHARACTER: + { + char *p = NULL; + p = guththila_get_value(environment, parser); + /* if (!parser->is_whitespace) */ + /* { */ + /* printf(p); */ + /* } */ + printf("%s", p); + AXIS2_FREE(allocator, p); + } + break; + case GUTHTHILA_COMMENT: + break; + }; + } + guththila_reader_free(environment, red); + guththila_free(environment, parser); + axutil_env_free(environment); + return 0; +} diff --git a/guththila/samples/guththila_writer_main.c b/guththila/samples/guththila_writer_main.c new file mode 100644 index 0000000..9dc1218 --- /dev/null +++ b/guththila/samples/guththila_writer_main.c @@ -0,0 +1,71 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#define MAXA 100000 +int +main( + int argc, + char *argv[]) +{ + char *t; + axutil_allocator_t *allocator; + axutil_env_t *env; + guththila_t *parser; + char *xml = NULL; + FILE *file = NULL; + allocator = axutil_allocator_init(NULL); + env = axutil_env_create(allocator); + parser = guththila_create(env, NULL); + guththila_create_xml_stream_writer_for_memory(env, parser); + guththila_write_start_element(env, parser, "two"); + guththila_write_default_namespace(env, parser, "http://another.host.com"); + guththila_write_start_element_with_prefix_and_namespace(env, parser, "ws", + "http://www.wso2.org", "wso2"); + guththila_write_start_element_with_prefix(env, parser, "ws", "stacks"); + guththila_write_attribute_with_prefix(env, parser, "ws", "stack", "axis2"); + guththila_write_characters(env, parser, + "testadfjaldjf;ajf;lkajdfa;lkjfd;ajdf11111111111122334455"); + guththila_write_end_document(env, parser); + + xml = (char *)AXIS2_MALLOC(env->allocator, MAXA + 1); + memset(xml, 0, MAXA + 1); + if(!argv[1]) + { + file = fopen("/home/dinesh/tmp/mbox_backup/mbox.archived", "r"); + } + else + file = fopen(argv[1], "r"); + + if(file) + fread(xml, 1, MAXA, file); + + guththila_write_to_buffer(env, parser, xml); + t = guththila_writer_get_buffer(env, parser->xsw->writer); + printf("%s \n", t); + free(xml); + fclose(file); + guththila_xml_writer_free(env, parser); + guththila_free(env, parser); + axutil_env_free(env); + return 0; +} diff --git a/guththila/src/Makefile.am b/guththila/src/Makefile.am new file mode 100644 index 0000000..f738e48 --- /dev/null +++ b/guththila/src/Makefile.am @@ -0,0 +1,18 @@ +lib_LTLIBRARIES = libguththila.la + +libguththila_la_LDFLAGS = -version-info $(VERSION_NO) + +libguththila_la_SOURCES = guththila_buffer.c \ + guththila_namespace.c \ + guththila_token.c \ + guththila_reader.c \ + guththila_attribute.c \ + guththila_xml_parser.c \ + guththila_stack.c \ + guththila_xml_writer.c + +libguththila_la_LIBADD = ../../util/src/libaxutil.la + +INCLUDES = -I$(top_builddir)/include \ + -I ../../util/include + diff --git a/guththila/src/guththila_attribute.c b/guththila/src/guththila_attribute.c new file mode 100644 index 0000000..f13ca34 --- /dev/null +++ b/guththila/src/guththila_attribute.c @@ -0,0 +1,144 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include +#include +#include + +int GUTHTHILA_CALL +guththila_attr_list_grow( + guththila_attr_list_t * at_list, + int addition, + const axutil_env_t * env) +{ + int i = 0; + + if(addition > 0 || (addition < 0 && at_list->capacity + addition > 0 && at_list->capacity + + addition >= at_list->size)) + { + at_list->list = (guththila_attr_t *)realloc(at_list->list, sizeof(guththila_attr_t) + * (at_list->capacity + addition)); + + if(at_list->list) + { + for(i = at_list->capacity; i < at_list->capacity + addition; i++) + { + guththila_stack_push(&at_list->fr_stack, at_list->list + i, env); + } + + at_list->capacity += addition; + } + else + { + return GUTHTHILA_FAILURE; + } + } + return 0; +} + +guththila_attr_list_t *GUTHTHILA_CALL +guththila_attr_list_create( + const axutil_env_t * env) +{ + int i = 0; + guththila_attr_list_t * at_list = (guththila_attr_list_t *)AXIS2_MALLOC(env->allocator, + sizeof(guththila_attr_list_t)); + + if(!at_list) + return NULL; + + at_list->list = (guththila_attr_t *)AXIS2_MALLOC(env->allocator, sizeof(guththila_attr_t) + * GUTHTHILA_ATTR_DEF_SIZE); + + if(at_list->list && guththila_stack_init(&at_list->fr_stack, env)) + { + at_list->capacity = GUTHTHILA_ATTR_DEF_SIZE; + at_list->size = 0; + for(i = 0; i < GUTHTHILA_ATTR_DEF_SIZE; i++) + { + guththila_stack_push(&at_list->fr_stack, at_list->list + i, env); + } + return at_list; + } + return NULL; +} + +int GUTHTHILA_CALL +guththila_attr_list_init( + guththila_attr_list_t * at_list, + const axutil_env_t * env) +{ + int i = 0; + at_list->list = (guththila_attr_t *)AXIS2_MALLOC(env->allocator, sizeof(guththila_attr_t) + * GUTHTHILA_ATTR_DEF_SIZE); + + if(at_list->list && guththila_stack_init(&at_list->fr_stack, env)) + { + at_list->capacity = GUTHTHILA_ATTR_DEF_SIZE; + at_list->size = 0; + for(i = 0; i < GUTHTHILA_ATTR_DEF_SIZE; i++) + { + guththila_stack_push(&at_list->fr_stack, at_list->list + i, env); + } + return GUTHTHILA_SUCCESS; + } + return GUTHTHILA_FAILURE; +} + +guththila_attr_t *GUTHTHILA_CALL +guththila_attr_list_get( + guththila_attr_list_t * at_list, + const axutil_env_t * env) +{ + if(at_list->fr_stack.top > 0 || guththila_attr_list_grow(at_list, GUTHTHILA_ATTR_DEF_SIZE, env)) + { + return guththila_stack_pop(&at_list->fr_stack, env); + } + + return NULL; +} + +int GUTHTHILA_CALL +guththila_attr_list_release( + guththila_attr_list_t * at_list, + guththila_attr_t * attr, + const axutil_env_t * env) +{ + + return guththila_stack_push(&at_list->fr_stack, attr, env); + +} + +void GUTHTHILA_CALL +msuila_attr_list_free_data( + guththila_attr_list_t * at_list, + const axutil_env_t * env) +{ + AXIS2_FREE(env->allocator, at_list->list); + guththila_stack_un_init(&at_list->fr_stack, env); +} + +void GUTHTHILA_CALL +guththila_attr_list_free( + guththila_attr_list_t * at_list, + const axutil_env_t * env) +{ + AXIS2_FREE(env->allocator, at_list->list); + guththila_stack_un_init(&at_list->fr_stack, env); + AXIS2_FREE(env->allocator, at_list); +} diff --git a/guththila/src/guththila_buffer.c b/guththila/src/guththila_buffer.c new file mode 100644 index 0000000..77f97f4 --- /dev/null +++ b/guththila/src/guththila_buffer.c @@ -0,0 +1,134 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include +#include + +int GUTHTHILA_CALL +guththila_buffer_init( + guththila_buffer_t * buffer, + int size, + const axutil_env_t * env) +{ + + buffer->type = GUTHTHILA_MULTIPLE_BUFFER; + buffer->data_size = (size_t *)AXIS2_MALLOC(env->allocator, sizeof(size_t) + * GUTHTHILA_BUFFER_NUMBER_OF_BUFFERS); + buffer->buffs_size = (size_t *)AXIS2_MALLOC(env->allocator, sizeof(size_t) + * GUTHTHILA_BUFFER_NUMBER_OF_BUFFERS); + buffer->buff = (guththila_char_t **)AXIS2_MALLOC(env->allocator, sizeof(guththila_char_t *) + * GUTHTHILA_BUFFER_NUMBER_OF_BUFFERS); + buffer->cur_buff = -1; + buffer->pre_tot_data = 0; + buffer->no_buffers = GUTHTHILA_BUFFER_NUMBER_OF_BUFFERS; + buffer->xml = NULL; + if(size > 0) + { + buffer->buff[0] = (guththila_char_t *)AXIS2_MALLOC(env->allocator, sizeof(guththila_char_t) + * size); + buffer->data_size[0] = 0; + buffer->buffs_size[0] = size; + buffer->cur_buff = 0; + } + return GUTHTHILA_SUCCESS; +} + +int GUTHTHILA_CALL +guththila_buffer_un_init( + guththila_buffer_t * buffer, + const axutil_env_t * env) +{ + int i = 0; + + if(buffer->type == GUTHTHILA_SINGLE_BUFFER && buffer->buff && buffer->cur_buff == 0) + { + + if(buffer->buffs_size) + AXIS2_FREE(env->allocator, buffer->buffs_size); + if(buffer->data_size) + AXIS2_FREE(env->allocator, buffer->data_size); + if(buffer->xml) + AXIS2_FREE(env->allocator, buffer->xml); + + AXIS2_FREE(env->allocator, buffer->buff); + + } + else if(buffer->type == GUTHTHILA_MULTIPLE_BUFFER && buffer->buff) + { + for(i = 0; i <= buffer->cur_buff; i++) + { + AXIS2_FREE(env->allocator, buffer->buff[i]); + } + if(buffer->xml) + AXIS2_FREE(env->allocator, buffer->xml); + AXIS2_FREE(env->allocator, buffer->buff); + if(buffer->data_size) + AXIS2_FREE(env->allocator, buffer->data_size); + if(buffer->buffs_size) + AXIS2_FREE(env->allocator, buffer->buffs_size); + } + return GUTHTHILA_SUCCESS; +} + +int GUTHTHILA_CALL +guththila_buffer_init_for_buffer( + guththila_buffer_t * buffer, + char *buff, + int size, + const axutil_env_t * env) +{ + buffer->type = GUTHTHILA_SINGLE_BUFFER; + buffer->buff + = (char **)AXIS2_MALLOC(env->allocator, sizeof(char *) * GUTHTHILA_BUFFER_DEF_SIZE); + buffer->buff[0] = buff; + buffer->cur_buff = 0; + buffer->buffs_size = (size_t *)AXIS2_MALLOC(env->allocator, sizeof(size_t) + * GUTHTHILA_BUFFER_DEF_SIZE); + buffer->buffs_size[0] = size; + buffer->pre_tot_data = 0; + buffer->data_size = (size_t *)AXIS2_MALLOC(env->allocator, sizeof(size_t) + * GUTHTHILA_BUFFER_DEF_SIZE); + buffer->data_size[0] = size; + buffer->no_buffers = 1; + buffer->xml = NULL; + return GUTHTHILA_SUCCESS; +} + +void *GUTHTHILA_CALL +guththila_buffer_get( + guththila_buffer_t * buffer, + const axutil_env_t * env) +{ + size_t size = 0, current_size = 0; + int i = 0; + + for(i = 0; i <= buffer->cur_buff; i++) + { + size += buffer->data_size[i]; + } + buffer->xml = (char *)AXIS2_MALLOC(env->allocator, sizeof(char) * (size + 1)); + for(i = 0; i <= buffer->cur_buff; i++) + { + memcpy(buffer->xml + current_size, buffer->buff[i], buffer->data_size[i]); + current_size += buffer->data_size[i]; + } + + buffer->xml[current_size] = '\0'; + return buffer->xml; +} + diff --git a/guththila/src/guththila_namespace.c b/guththila/src/guththila_namespace.c new file mode 100644 index 0000000..7cd9a50 --- /dev/null +++ b/guththila/src/guththila_namespace.c @@ -0,0 +1,139 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include +#include +#include + +int GUTHTHILA_CALL +guththila_namespace_list_grow( + guththila_namespace_list_t * namesp_list, + int addition, + const axutil_env_t * env) +{ + int i = 0; + if(addition > 0 || (addition < 0 && namesp_list->capacity + addition > 0 + && namesp_list->capacity + addition >= namesp_list->size)) + { + namesp_list->list = (guththila_namespace_t *)realloc(namesp_list->list, + sizeof(guththila_namespace_t) * (namesp_list->capacity + addition)); + if(namesp_list->list) + { + for(i = namesp_list->capacity; i < namesp_list->capacity + addition; i++) + { + guththila_stack_push(&namesp_list->fr_stack, namesp_list->list + i, env); + } + namesp_list->capacity += addition; + } + else + { + return GUTHTHILA_FAILURE; + } + } + return 0; +} + +guththila_namespace_list_t *GUTHTHILA_CALL +guththila_namespace_list_create( + const axutil_env_t * env) +{ + int i = 0; + guththila_namespace_list_t * namesp_list = (guththila_namespace_list_t *)AXIS2_MALLOC( + env->allocator, sizeof(guththila_namespace_list_t)); + + if(!namesp_list) + return NULL; + + namesp_list->list = (guththila_namespace_t *)AXIS2_MALLOC(env->allocator, + sizeof(guththila_namespace_t) * GUTHTHILA_NAMESPACE_DEF_SIZE); + + if(namesp_list->list && guththila_stack_init(&namesp_list->fr_stack, env)) + { + namesp_list->capacity = GUTHTHILA_NAMESPACE_DEF_SIZE; + namesp_list->size = 0; + for(i = 0; i < GUTHTHILA_NAMESPACE_DEF_SIZE; i++) + { + guththila_stack_push(&namesp_list->fr_stack, namesp_list->list + i, env); + } + return namesp_list; + } + return NULL; +} + +int GUTHTHILA_CALL +guththila_namespace_list_init( + guththila_namespace_list_t * namesp_list, + const axutil_env_t * env) +{ + int i = 0; + namesp_list->list = (guththila_namespace_t *)AXIS2_MALLOC(env->allocator, + sizeof(guththila_namespace_t) * GUTHTHILA_NAMESPACE_DEF_SIZE); + if(namesp_list->list && guththila_stack_init(&namesp_list->fr_stack, env)) + { + namesp_list->capacity = GUTHTHILA_NAMESPACE_DEF_SIZE; + namesp_list->size = 0; + for(i = 0; i < GUTHTHILA_NAMESPACE_DEF_SIZE; i++) + { + guththila_stack_push(&namesp_list->fr_stack, namesp_list->list + i, env); + } + return GUTHTHILA_SUCCESS; + } + return GUTHTHILA_FAILURE; +} + +guththila_namespace_t *GUTHTHILA_CALL +guththila_namespace_list_get( + guththila_namespace_list_t *namesp_list, + const axutil_env_t * env) +{ + if(namesp_list->fr_stack.top > 0 || guththila_namespace_list_grow(namesp_list, + GUTHTHILA_NAMESPACE_DEF_SIZE, env)) + { + return guththila_stack_pop(&namesp_list->fr_stack, env); + } + return NULL; +} + +int GUTHTHILA_CALL +guththila_namespace_list_release( + guththila_namespace_list_t * namesp_list, + guththila_namespace_t * namespace, + const axutil_env_t * env) +{ + return guththila_stack_push(&namesp_list->fr_stack, namespace, env); +} + +void GUTHTHILA_CALL +msuila_namespace_list_free_data( + guththila_namespace_list_t * namesp_list, + const axutil_env_t * env) +{ + AXIS2_FREE(env->allocator, namesp_list->list); + guththila_stack_un_init(&namesp_list->fr_stack, env); +} + +void GUTHTHILA_CALL +guththila_namespace_list_free( + guththila_namespace_list_t * namesp_list, + const axutil_env_t * env) +{ + + guththila_stack_un_init(&namesp_list->fr_stack, env); + AXIS2_FREE(env->allocator, namesp_list->list); + AXIS2_FREE(env->allocator, namesp_list); +} diff --git a/guththila/src/guththila_reader.c b/guththila/src/guththila_reader.c new file mode 100644 index 0000000..bcb0efd --- /dev/null +++ b/guththila/src/guththila_reader.c @@ -0,0 +1,115 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include +GUTHTHILA_EXPORT guththila_reader_t * GUTHTHILA_CALL +guththila_reader_create_for_file( + guththila_char_t *file_name, + const axutil_env_t * env) +{ + guththila_reader_t * reader = NULL; + + FILE * f = NULL; + if(!file_name) + return NULL; + reader = (guththila_reader_t *)AXIS2_MALLOC(env->allocator, sizeof(guththila_reader_t)); + if(!reader) + return NULL; + f = fopen(file_name, "r"); + if(!f) + { + AXIS2_FREE(env->allocator, reader); + return NULL; + } + reader->fp = f; + reader->type = GUTHTHILA_FILE_READER; + return reader; +} + +GUTHTHILA_EXPORT guththila_reader_t * GUTHTHILA_CALL +guththila_reader_create_for_memory( + void *buffer, + int size, + const axutil_env_t * env) +{ + guththila_reader_t * reader = (guththila_reader_t *)AXIS2_MALLOC(env->allocator, + sizeof(guththila_reader_t)); + if(reader) + { + reader->type = GUTHTHILA_MEMORY_READER; + reader->buff = buffer; + reader->buff_size = size; + reader->fp = NULL; + return reader; + } + return NULL; +} + +GUTHTHILA_EXPORT guththila_reader_t * GUTHTHILA_CALL +guththila_reader_create_for_io( + GUTHTHILA_READ_INPUT_CALLBACK input_read_callback, + void *ctx, + const axutil_env_t * env) +{ + guththila_reader_t * reader = (guththila_reader_t *)AXIS2_MALLOC(env->allocator, + sizeof(guththila_reader_t)); + if(reader) + { + reader->input_read_callback = input_read_callback; + reader->context = ctx; + reader->type = GUTHTHILA_IO_READER; + return reader; + } + return NULL; +} +GUTHTHILA_EXPORT void GUTHTHILA_CALL +guththila_reader_free( + guththila_reader_t * r, + const axutil_env_t * env) +{ + if(r->type == GUTHTHILA_FILE_READER && r->fp) + { + fclose(r->fp); + } + if(r->type == GUTHTHILA_IO_READER && r->context) + { + AXIS2_FREE(env->allocator, r->context); + } + AXIS2_FREE(env->allocator, r); + +} +GUTHTHILA_EXPORT int GUTHTHILA_CALL +guththila_reader_read( + guththila_reader_t * r, + guththila_char_t * buffer, + int offset, + int length, + const axutil_env_t * env) +{ + int rt = r->type; + switch(rt) + { + case GUTHTHILA_FILE_READER: + return (int)fread(buffer + offset, 1, length, r->fp); + case GUTHTHILA_IO_READER: + return r->input_read_callback((buffer + offset), length, r->context); + default: + return 0; + } +} + diff --git a/guththila/src/guththila_stack.c b/guththila/src/guththila_stack.c new file mode 100644 index 0000000..fd629c1 --- /dev/null +++ b/guththila/src/guththila_stack.c @@ -0,0 +1,135 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include + +int GUTHTHILA_CALL +guththila_stack_init( + guththila_stack_t * stack, + const axutil_env_t * env) +{ + stack->top = 0; + stack->data = (void **)AXIS2_MALLOC(env->allocator, sizeof(void **) * GUTHTHILA_STACK_DEFAULT); + if(!stack->data) + { + return GUTHTHILA_FAILURE; + } + else + { + stack->max = GUTHTHILA_STACK_DEFAULT; + return GUTHTHILA_SUCCESS; + } +} + +void GUTHTHILA_CALL +guththila_stack_free( + guththila_stack_t * stack, + const axutil_env_t * env) +{ + if(stack->data) + AXIS2_FREE(env->allocator, stack->data); + AXIS2_FREE(env->allocator, stack); +} + +void GUTHTHILA_CALL +guththila_stack_un_init( + guththila_stack_t * stack, + const axutil_env_t * env) +{ + if(stack->data) + AXIS2_FREE(env->allocator, stack->data); +} + +void *GUTHTHILA_CALL +guththila_stack_pop( + guththila_stack_t * stack, + const axutil_env_t * env) +{ + if(stack->top > 0) + { + return stack->data[--(stack->top)]; + } + return NULL; +} + +int GUTHTHILA_CALL +guththila_stack_push( + guththila_stack_t * stack, + void *data, + const axutil_env_t * env) +{ + int top = stack->top++; + if(top >= stack->max) + { + void **temp = NULL; + int i = 0; + temp = (void **)AXIS2_MALLOC(env->allocator, sizeof(void **) * (stack->max *= 2)); + for(i = 0; i < top; ++i) + { + temp[i] = stack->data[i]; + } + AXIS2_FREE(env->allocator, stack->data); + stack->data = temp; + } + stack->data[top] = data; + return top; +} + +void *GUTHTHILA_CALL +guththila_stack_peek( + guththila_stack_t * stack, + const axutil_env_t * env) +{ + if(stack->top > 0) + { + return stack->data[stack->top - 1]; + } + else + { + return NULL; + } +} + +int GUTHTHILA_CALL +guththila_stack_del_top( + guththila_stack_t * stack, + const axutil_env_t * env) +{ + if(stack->top > 0) + { + AXIS2_FREE(env->allocator, stack->data[stack->top]); + return GUTHTHILA_SUCCESS; + } + return GUTHTHILA_FAILURE; +} + +int GUTHTHILA_CALL +guththila_stack_is_empty( + guththila_stack_t * stack, + const axutil_env_t * env) +{ + return stack->top == 0 ? 1 : 0; +} + +void *GUTHTHILA_CALL +guththila_stack_get_by_index( + guththila_stack_t * stack, + int index, + const axutil_env_t * env) +{ + return index < stack->top ? stack->data[index] : NULL; +} + diff --git a/guththila/src/guththila_token.c b/guththila/src/guththila_token.c new file mode 100644 index 0000000..6272850 --- /dev/null +++ b/guththila/src/guththila_token.c @@ -0,0 +1,221 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include + +#define TOK_LIST_FREE(tok_list) \ + (if (tok_list) { AXIS2_FREE(tok_list)} ) + +#define TOK_LIST_SIZE(tok_list) (tok_list->size) + +int GUTHTHILA_CALL +guththila_tok_list_grow( + guththila_tok_list_t * tok_list, + const axutil_env_t * env) +{ + int i = 0; + + if(tok_list->cur_list < tok_list->no_list - 1) + { + int cur = ++tok_list->cur_list; + int cur_cap = tok_list->capacity[cur - 1] * 2; + guththila_token_t *list = (guththila_token_t *)AXIS2_MALLOC(env->allocator, + sizeof(guththila_token_t) * cur_cap); + for(i = 0; i < cur_cap; ++i) + { + guththila_stack_push(&tok_list->fr_stack, &list[i], env); + } + tok_list->capacity[cur] = cur_cap; + tok_list->list[cur] = list; + return GUTHTHILA_SUCCESS; + } + else + { + guththila_token_t ** list = NULL; + int *capacity = NULL; + list = (guththila_token_t **)AXIS2_MALLOC(env->allocator, sizeof(guththila_token_t *) + * tok_list->no_list * 2); + capacity = (int *)AXIS2_MALLOC(env->allocator, sizeof(int) * tok_list->no_list * 2); + if(list) + { + int cur_list = tok_list->cur_list; + for(i = 0; i <= cur_list; ++i) + { + list[i] = tok_list->list[i]; + capacity[i] = tok_list->capacity[i]; + } + tok_list->no_list = tok_list->no_list * 2; + AXIS2_FREE(env->allocator, tok_list->list); + tok_list->list = list; + AXIS2_FREE(env->allocator, tok_list->capacity); + tok_list->capacity = capacity; + guththila_tok_list_grow(tok_list, env); + } + } + return GUTHTHILA_FAILURE; +} + +int GUTHTHILA_CALL +guththila_tok_list_init( + guththila_tok_list_t * tok_list, + const axutil_env_t * env) +{ + int i = 0; + tok_list->list = (guththila_token_t **)AXIS2_MALLOC(env->allocator, sizeof(guththila_token_t *) + * GUTHTHILA_TOK_DEF_LIST_SIZE); + if(tok_list->list && guththila_stack_init(&tok_list->fr_stack, env)) + { + tok_list->capacity = (int *)AXIS2_MALLOC(env->allocator, sizeof(int) + * GUTHTHILA_TOK_DEF_LIST_SIZE); + if(tok_list->capacity) + { + tok_list->no_list = GUTHTHILA_TOK_DEF_LIST_SIZE; + tok_list->list[0] = (guththila_token_t *)AXIS2_MALLOC(env->allocator, + sizeof(guththila_token_t) * GUTHTHILA_TOK_DEF_SIZE); + for(i = 0; i < GUTHTHILA_TOK_DEF_SIZE; i++) + { + guththila_stack_push(&tok_list->fr_stack, &tok_list->list[0][i], env); + } + tok_list->capacity[0] = GUTHTHILA_TOK_DEF_SIZE; + tok_list->cur_list = 0; + tok_list->no_list = GUTHTHILA_TOK_DEF_LIST_SIZE; + return GUTHTHILA_SUCCESS; + } + } + return GUTHTHILA_FAILURE; +} + +void GUTHTHILA_CALL +guththila_tok_list_free( + guththila_tok_list_t * tok_list, + const axutil_env_t * env) +{ + int i = 0; + guththila_stack_un_init(&tok_list->fr_stack, env); + for(; i <= tok_list->cur_list; i++) + { + AXIS2_FREE(env->allocator, tok_list->list[i]); + } + AXIS2_FREE(env->allocator, tok_list->list); + AXIS2_FREE(env->allocator, tok_list->capacity); + AXIS2_FREE(env->allocator, tok_list); +} + +void GUTHTHILA_CALL +guththila_tok_list_free_data( + guththila_tok_list_t * tok_list, + const axutil_env_t * env) +{ + int i = 0; + guththila_stack_un_init(&tok_list->fr_stack, env); + for(; i <= tok_list->cur_list; i++) + { + AXIS2_FREE(env->allocator, tok_list->list[i]); + } + AXIS2_FREE(env->allocator, tok_list->capacity); + AXIS2_FREE(env->allocator, tok_list->list); +} + +guththila_token_t *GUTHTHILA_CALL +guththila_tok_list_get_token( + guththila_tok_list_t * tok_list, + const axutil_env_t * env) +{ + if(tok_list->fr_stack.top > 0 || guththila_tok_list_grow(tok_list, env)) + { + return guththila_stack_pop(&tok_list->fr_stack, env); + } + return NULL; +} + +int GUTHTHILA_CALL +guththila_tok_list_release_token( + guththila_tok_list_t * tok_list, + guththila_token_t * token, + const axutil_env_t * env) +{ + return guththila_stack_push(&tok_list->fr_stack, token, env); +} + +int GUTHTHILA_CALL +guththila_tok_str_cmp( + guththila_token_t * tok, + guththila_char_t *str, + size_t str_len, + const axutil_env_t * env) +{ + unsigned int i = 0; + if(tok->size != str_len) + return -1; + for(; i < tok->size; i++) + { + if(tok->start[i] != str[i]) + { + return -1; + } + } + return 0; +} + +int GUTHTHILA_CALL +guththila_tok_tok_cmp( + guththila_token_t * tok1, + guththila_token_t * tok2, + const axutil_env_t * env) +{ + unsigned int i = 0; + + if(tok1 && tok2) + { + if(tok1->size != tok2->size) + return -1; + for(; i < tok1->size; i++) + { + if(tok1->start[i] != tok2->start[i]) + { + return -1; + } + } + return 0; + } + return -1; +} + +void GUTHTHILA_CALL +guththila_set_token( + guththila_token_t* tok, + guththila_char_t* start, + short type, + int size, + int _start, + int last, + int ref, + const axutil_env_t* env) +{ + if(start) + { + tok->start = start; + tok->type = type; + tok->_start = _start; + tok->size = size; + tok->last = last; + tok->ref = ref; + } +} diff --git a/guththila/src/guththila_xml_parser.c b/guththila/src/guththila_xml_parser.c new file mode 100644 index 0000000..7c636a5 --- /dev/null +++ b/guththila/src/guththila_xml_parser.c @@ -0,0 +1,1792 @@ + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include +#include +#include + +#define GUTHTHILA_VALIDATION_PARSER + +/* + * Read the next char from the reader and return it. + */ +static int +guththila_next_char( + guththila_t * m, + const axutil_env_t * env); + +/* part of guththila_next_char method. this was included as macro for performance. 99% of the time + * following will be called, so having it as next_char method is very expensive (method calling + * overhead is higher) so, common case is checked as part of the macro and if not satisfied, method + * is called + */ +#define GUTHTHILA_NEXT_CHAR(m, buffer, data_size, previous_size, env, c)\ +{\ + int result_found = 0;\ + if(!buffer)\ + {\ + if(m->reader->type == GUTHTHILA_MEMORY_READER)\ + {\ + buffer = m->buffer.buff[0];\ + data_size = m->buffer.data_size[0];\ + previous_size = 0;\ + }\ + else\ + {\ + if(m->buffer.cur_buff != -1)\ + {\ + buffer = m->buffer.buff[m->buffer.cur_buff];\ + data_size = GUTHTHILA_BUFFER_CURRENT_DATA_SIZE(m->buffer);\ + previous_size = GUTHTHILA_BUFFER_PRE_DATA_SIZE(m->buffer);\ + }\ + else\ + {\ + c = guththila_next_char(m, env);\ + if(c < 0)\ + return -1;\ + result_found = 1;\ + }\ + }\ + }\ +\ + if(!result_found)\ + {\ + size_t index = m->next++ - previous_size;\ + if(index < data_size)\ + {\ + c = buffer[index];\ + }\ + else\ + {\ + buffer = NULL;\ + data_size = -1;\ + --(m->next);\ + if(m->reader->type == GUTHTHILA_MEMORY_READER)\ + {\ + return -1;\ + }\ + else\ + {\ + c = guththila_next_char(m, env);\ + if(c < 0)\ + return -1;\ + }\ + }\ + }\ +} + +/* + * Read the specified number of characters at once. + */ +static int +guththila_next_no_char( + guththila_t * m, + int eof, + guththila_char_t *bytes, + size_t no, + const axutil_env_t * env); + +/* + * Close a token that is opened previously. + */ +static void +guththila_token_close( + guththila_t * m, + guththila_token_t * tok, + int tok_type, + int referer, + const axutil_env_t * env); + +/* + * Process the XMl declaration part of a XML document. + */ +static int +guththila_process_xml_dec( + guththila_t * m, + const axutil_env_t * env); + +/* + * Return non zero value if the given argument is a space. (c < 0x21) is added to improve the + * performance. common case is printable characters. and if given character is printable, we can + * return false immediately. + */ +#define GUTHTHILA_IS_SPACE(c) ((c < 0x21) && (c == 0x20 || c == 0xD || c == 0xA || c == 0x9)) + +/* + * Read characters until all the white spaces are read. + */ +#define GUTHTHILA_SKIP_SPACES(m, c, buffer, data_size, previous_size, _env)while(GUTHTHILA_IS_SPACE(c)){GUTHTHILA_NEXT_CHAR(m, buffer, data_size, previous_size, _env, c);} + + +#define GUTHTHILA_XML_NAME "xml" + +#define GUTHTHILA_XML_URI "http://www.w3.org/XML/1998/namespace" + +/* + * Open a token. When we open a token we don't know it's type. We only + * set the starting values. + */ +#define GUTHTHILA_TOKEN_OPEN(m, tok, _env) \ + m->temp_tok = guththila_tok_list_get_token(&m->tokens, _env); \ + m->temp_tok->type = _Unknown; \ + m->temp_tok->_start = (int)m->next; \ + m->last_start = (int)m->next - 1; +/* We are sure that the difference lies within the int range */ + +/* + * Read until we met a = character. + */ +#define GUTHTHILA_PROCESS_EQU(m, c, ic, buffer, data_size, previous_size, _env)\ +{\ + GUTHTHILA_SKIP_SPACES(m, c, buffer, data_size, previous_size, _env); \ + if (c == '=')\ + { \ + GUTHTHILA_NEXT_CHAR(m, buffer, data_size, previous_size, _env, ic); \ + GUTHTHILA_SKIP_SPACES(m, ic, buffer, data_size, previous_size, _env); \ + }\ +} + +/* + * Initialize a attribute to the values given. + */ +#define GUTHTHILA_ATTRIBUTE_INITIALIZE(_attr, _pref, _name, _val) \ + (_attr->pref = (_pref)); \ + (_attr->name = (_name)); \ + (_attr->val = (_val)); + +/* + * Initialize namespace to the values given. + */ +#define GUTHTHILA_NAMESPACE_INITIALIZE(_namesp, _name, _uri) \ + (_namesp->name = _name); \ + (_namesp->uri = _uri); + +/* + * Determine weahter a given character is a valid starting char for a xml name. + */ +#define GUTHTHILA_IS_VALID_STARTING_CHAR(c) (isalpha(c) || '_' == c || ':' == c) + +/* + * Initialize the variables in the guththila_t structure. + */ +#define GUTHTHILA_VARIABLE_INITIALZE(m) \ + m->temp_prefix = NULL; \ + m->temp_name = NULL; \ + m->temp_tok = NULL; \ + if (m->value) guththila_tok_list_release_token(&m->tokens, m->value, env); \ + m->name = NULL; \ + m->prefix = NULL; \ + m->value = NULL; + +/* + * Initialize the guththila_t structure with the reader. + * All the values will be set to default values. + */ +GUTHTHILA_EXPORT int GUTHTHILA_CALL +guththila_init( + guththila_t * m, + void *reader, + const axutil_env_t * env) +{ + guththila_token_t* temp_name = NULL; + guththila_token_t* temp_tok = NULL; + guththila_elem_namesp_t* e_namesp = NULL; + + if(!((guththila_reader_t *)reader)) + return GUTHTHILA_FAILURE; + m->reader = (guththila_reader_t *)reader; + if(!guththila_tok_list_init(&m->tokens, env)) + { + return GUTHTHILA_FAILURE; + } + if(m->reader->type == GUTHTHILA_MEMORY_READER) + { + guththila_buffer_init_for_buffer(&m->buffer, m->reader->buff, m->reader->buff_size, env); + } + else if(m->reader->type == GUTHTHILA_FILE_READER || m->reader->type == GUTHTHILA_IO_READER) + { + guththila_buffer_init(&m->buffer, 0, env); + } + guththila_stack_init(&m->elem, env); + guththila_stack_init(&m->attrib, env); + guththila_stack_init(&m->namesp, env); + temp_name = guththila_tok_list_get_token(&m->tokens, env); + temp_tok = guththila_tok_list_get_token(&m->tokens, env); + if(temp_tok && temp_name) + { + guththila_set_token(temp_name, GUTHTHILA_XML_NAME, 0, (int)strlen(GUTHTHILA_XML_NAME), 1, + 0, 0, env); + + guththila_set_token(temp_tok, GUTHTHILA_XML_URI, 0, (int)strlen(GUTHTHILA_XML_URI), 1, 0, + 0, env); + + } + + e_namesp = (guththila_elem_namesp_t *)AXIS2_MALLOC(env->allocator, + sizeof(guththila_elem_namesp_t)); + if(e_namesp && temp_tok && temp_name) + { + e_namesp->namesp = (guththila_namespace_t *)AXIS2_MALLOC(env->allocator, + sizeof(guththila_namespace_t) * GUTHTHILA_NAMESPACE_DEF_SIZE); + } + if(e_namesp->namesp) + { + e_namesp->no = 1; + e_namesp->size = GUTHTHILA_NAMESPACE_DEF_SIZE; + e_namesp->namesp[0].name = temp_name; + e_namesp->namesp[0].uri = temp_tok; + guththila_stack_push(&m->namesp, e_namesp, env); + } + else + { + if(temp_name) + { + AXIS2_FREE(env->allocator, temp_name); + temp_name = NULL; + } + if(temp_tok) + { + AXIS2_FREE(env->allocator, temp_tok); + temp_tok = NULL; + } + if(e_namesp) + { + AXIS2_FREE(env->allocator, e_namesp); + e_namesp = NULL; + } + return GUTHTHILA_FAILURE; + } + m->name = NULL; + m->prefix = NULL; + m->value = NULL; + m->status = S_1; + m->guththila_event = -1; + m->next = 0; + m->last_start = -1; + m->temp_name = NULL; + m->temp_prefix = NULL; + m->temp_tok = NULL; + return GUTHTHILA_SUCCESS; +} + +/* + * Uninitialize a guththila_t structure. This method deallocates all the + * resources that are held in the guththila_t structure. + */ +GUTHTHILA_EXPORT int GUTHTHILA_CALL +guththila_un_init( + guththila_t * m, + const axutil_env_t * env) +{ + int size = 0, i = 0, j = 0; + guththila_attr_t * attr = NULL; + guththila_element_t* elem = NULL; + guththila_elem_namesp_t * e_namesp = NULL; + + if(m->prefix) + { + guththila_tok_list_release_token(&m->tokens, m->prefix, env); + } + if(m->name) + { + guththila_tok_list_release_token(&m->tokens, m->name, env); + } + if(m->value) + { + guththila_tok_list_release_token(&m->tokens, m->value, env); + } + if(m->temp_tok) + { + guththila_tok_list_release_token(&m->tokens, m->temp_tok, env); + } + if(m->temp_name) + { + guththila_tok_list_release_token(&m->tokens, m->temp_name, env); + } + if(m->temp_prefix) + { + guththila_tok_list_release_token(&m->tokens, m->temp_prefix, env); + } + size = GUTHTHILA_STACK_SIZE(m->attrib); + for(i = 0; i < size; i++) + { + attr = (guththila_attr_t *)guththila_stack_pop(&m->attrib, env); + if(attr) + { + if(attr->name) + guththila_tok_list_release_token(&m->tokens, attr->name, env); + if(attr->pref) + guththila_tok_list_release_token(&m->tokens, attr->pref, env); + AXIS2_FREE(env->allocator, attr); + } + } + guththila_stack_un_init(&m->attrib, env); + +#ifndef GUTHTHILA_VALIDATION_PARSER + guththila_namespace_t * namesp = NULL; + + size = GUTHTHILA_STACK_SIZE(m->namesp); + for (i = 0; i < size; i++) + { + namesp = + (guththila_namespace_t *) guththila_stack_pop(&m->namesp, env); + if (namesp) + { + if (namesp->name) + guththila_tok_list_release_token(&m->tokens, namesp->name, env); + if (namesp->uri) + guththila_tok_list_release_token(&m->tokens, namesp->uri, env); + AXIS2_FREE(env->allocator, namesp); + } + } +#else + + size = GUTHTHILA_STACK_SIZE(m->namesp); + for(i = 0; i < size; i++) + { + e_namesp = (guththila_elem_namesp_t *)guththila_stack_pop(&m->namesp, env); + if(e_namesp) + { + for(j = 0; j < e_namesp->no; j++) + { + if(e_namesp->namesp[j].name) + { + guththila_tok_list_release_token(&m->tokens, e_namesp->namesp[j].name, env); + } + if(e_namesp->namesp[j].uri) + { + guththila_tok_list_release_token(&m->tokens, e_namesp->namesp[j].uri, env); + } + } + AXIS2_FREE(env->allocator, e_namesp->namesp); + AXIS2_FREE(env->allocator, e_namesp); + } + } +#endif + + size = GUTHTHILA_STACK_SIZE(m->elem); + for(i = 0; i < size; i++) + { + elem = (guththila_element_t *)guththila_stack_pop(&m->elem, env); + if(elem) + { + if(elem->name) + guththila_tok_list_release_token(&m->tokens, elem->name, env); + if(elem->prefix) + guththila_tok_list_release_token(&m->tokens, elem->prefix, env); + AXIS2_FREE(env->allocator, elem); + } + } + guththila_stack_un_init(&m->elem, env); + guththila_stack_un_init(&m->namesp, env); + guththila_tok_list_free_data(&m->tokens, env); + guththila_buffer_un_init(&m->buffer, env); + AXIS2_FREE(env->allocator, m); + return GUTHTHILA_SUCCESS; +} + +/* + * Replace the references with the corresponding actual values. + */ +static void +guththila_token_evaluate_references( + guththila_token_t * tok) +{ + size_t size = tok->size; + guththila_char_t *start = tok->start; + guththila_char_t *pos = NULL; + size_t i, j; + + pos = (guththila_char_t *)memchr(start, '&', size); + if(pos) + { + i = pos - start; + } + else + { + i = size; + } + /*for(i = 0; (i < size) && (start[i] != '&'); i++) + ;*/ + if(i < size) + { + j = i; + while(i < size) + { + if(((i + 3) < size) && (start[i + 1] == 'g') && (start[i + 2] == 't') && (start[i + 3] + == ';')) + { + /* replace first char of sequence with > */ + start[j++] = '>'; + /* skip remainder of sequence */ + i += 4; + } + else if(((i + 3) < size) && (start[i + 1] == 'l') && (start[i + 2] == 't') && (start[i + + 3] == ';')) + { + /* replace first char of sequence with < */ + start[j++] = '<'; + /* skip remainder of sequence */ + i += 4; + } + else if(((i + 4) < size) && (start[i + 1] == 'a') && (start[i + 2] == 'm') && (start[i + + 3] == 'p') && (start[i + 4] == ';')) + { + /* replace first char of sequence with & */ + start[j++] = '&'; + /* skip remainder of sequence */ + i += 5; + } + else if(((i + 5) < size) && (start[i + 1] == 'a') && (start[i + 2] == 'p') && (start[i + + 3] == 'o') && (start[i + 4] == 's') && (start[i + 5] == ';')) + { + /* replace first char of sequence with ' */ + start[j++] = '\''; + /* skip remainder of sequence */ + i += 6; + } + else if(((i + 5) < size) && (start[i + 1] == 'q') && (start[i + 2] == 'u') && (start[i + + 3] == 'o') && (start[i + 4] == 't') && (start[i + 5] == ';')) + { + /* replace first char of sequence with " */ + start[j++] = '\"'; + /* skip remainder of sequence */ + i += 6; + } + else + { + /* ampersand does not start a sequence; + skip it and continue scanning */ + /* could insert character reference decoding here */ + start[j++] = start[i++]; + } + /* copy characters downward until the next ampersand */ + for(; (i < size) && ('&' != (start[j] = start[i])); i++, j++) + ; + } + tok->size = j; + } +} + +/* + * Close a token. This method accepts the type of the token as a parameter. + */ +static void +guththila_token_close( + guththila_t * m, + guththila_token_t * tok, + int tok_type, + int referer, + const axutil_env_t * env) +{ + guththila_attr_t * attr = NULL; + guththila_element_t * elem = NULL; + guththila_elem_namesp_t * e_namesp = NULL; + guththila_namespace_t * namesp; + int i = 0; + /* We are sure that the difference lies within the short range */ + m->temp_tok->type = (short)tok_type; + m->temp_tok->size = m->next - m->temp_tok->_start; + m->temp_tok->start = GUTHTHILA_BUF_POS(m->buffer, m->next - 1) - m->temp_tok->size; + m->temp_tok->ref = referer; + m->last_start = -1; + switch(tok_type) + { + case _attribute_name: + m->temp_name = m->temp_tok; + m->temp_tok = NULL; + break; + case _char_data: + m->value = m->temp_tok; + m->temp_tok = NULL; + break; + case _text_data: + guththila_token_evaluate_references(m->temp_tok); + m->value = m->temp_tok; + m->temp_tok = NULL; + break; + case _attribute_value: + guththila_token_evaluate_references(m->temp_tok); + /* Chech weather we are at a xml namespace declaration */ + if((m->temp_prefix && (guththila_tok_str_cmp(m->temp_prefix, "xmlns", 5u, env) == 0)) + || (guththila_tok_str_cmp(m->temp_name, "xmlns", 5u, env) == 0)) + /*checks inside the m->temp_name to parse the default namespace*/ + /*checks inside the m->temp_prefix to parse namespace with prefix*/ + { +#ifndef GUTHTHILA_VALIDATION_PARSER + namesp = + (guththila_namespace_t *) + AXIS2_MALLOC(sizeof(guththila_namespace_t)); + GUTHTHILA_NAMESPACE_INITIALIZE(namesp, m->temp_name, m->temp_tok); + guththila_stack_push(&m->namesp, namesp); +#else + elem = (guththila_element_t *)guththila_stack_peek(&m->elem, env); + /* This is the first namespace */ + if(elem && !elem->is_namesp) + { + e_namesp = (guththila_elem_namesp_t *)AXIS2_MALLOC(env->allocator, + sizeof(guththila_elem_namesp_t)); + if(e_namesp) + { + e_namesp->namesp = (guththila_namespace_t *)AXIS2_MALLOC(env->allocator, + sizeof(guththila_namespace_t) * GUTHTHILA_NAMESPACE_DEF_SIZE); + if(e_namesp->namesp) + { + e_namesp->no = 1; + e_namesp->size = GUTHTHILA_NAMESPACE_DEF_SIZE; + e_namesp->namesp[0].name = m->temp_name; + e_namesp->namesp[0].uri = m->temp_tok; + guththila_stack_push(&m->namesp, e_namesp, env); + elem->is_namesp = 1; + } + else + { + AXIS2_FREE(env->allocator, e_namesp); + e_namesp = NULL; + } + } + } + /* Already there is a namespace */ + else if(elem && elem->is_namesp) + { + e_namesp = (guththila_elem_namesp_t *)guththila_stack_peek(&m->namesp, env); + /* if we have enough space allocated */ + if(e_namesp->no < e_namesp->size) + { + e_namesp->namesp[e_namesp->no].name = m->temp_name; + e_namesp->namesp[e_namesp->no].uri = m->temp_tok; + e_namesp->no++; + } + else + { + namesp = (guththila_namespace_t *)AXIS2_MALLOC(env->allocator, + sizeof(guththila_namespace_t) * e_namesp->size * 2); + if(namesp) + { + for(i = 0; i < e_namesp->no; i++) + { + namesp[i].name = e_namesp->namesp[i].name; + namesp[i].uri = e_namesp->namesp[i].uri; + } + AXIS2_FREE(env->allocator, e_namesp->namesp); + e_namesp->namesp = namesp; + e_namesp->size *= 2; + + e_namesp->namesp[e_namesp->no].name = m->temp_name; + e_namesp->namesp[e_namesp->no].uri = m->temp_tok; + e_namesp->no++; + } + } + } +#endif + } + else + { + /* It is just a attribute */ + attr = (guththila_attr_t *)AXIS2_MALLOC(env->allocator, sizeof(guththila_attr_t)); + + GUTHTHILA_ATTRIBUTE_INITIALIZE(attr, + m->temp_prefix, + m->temp_name, + m->temp_tok); + guththila_stack_push(&m->attrib, attr, env); + } + m->temp_prefix = NULL; + m->temp_name = NULL; + m->temp_tok = NULL; + break; + case _prefix: + m->temp_prefix = m->temp_tok; + m->temp_tok = NULL; + break; + default: + m->prefix = m->temp_prefix; + m->name = m->temp_tok; + m->temp_tok = NULL; + m->temp_prefix = NULL; + break; + } +} + +int GUTHTHILA_CALL +guththila_validate_namespaces( + guththila_t *m, + const axutil_env_t *env) +{ + int size = 0, i = 0, nmsp_no = 0, j = 0, k = 0; + int namesp_found = GUTHTHILA_FALSE; + guththila_elem_namesp_t *e_namesp = NULL; + + size = GUTHTHILA_STACK_SIZE(m->attrib); + /* Loop through all the attributes */ + for(i = 0; i < size; i++) + { + guththila_attr_t *attr = (guththila_attr_t *)guththila_stack_get_by_index(&m->attrib, i, + env); + if(attr && attr->pref) + { + /* We have a attribute prefix. Need to validate the prefix */ + nmsp_no = GUTHTHILA_STACK_SIZE(m->namesp); + for(j = nmsp_no - 1; j >= 0; j--) + { + e_namesp = (guththila_elem_namesp_t *)guththila_stack_get_by_index(&m->namesp, j, + env); + for(k = 0; k < e_namesp->no; k++) + { + if(!guththila_tok_tok_cmp(e_namesp->namesp[k].name, attr->pref, env)) + { + namesp_found = GUTHTHILA_TRUE; + j = -1; /* force exit from second for loop */ + break; + } + } + } + if(!namesp_found) + return GUTHTHILA_FAILURE; + } + } + /* If the element has a prefix. Need to validate the prefix*/ + if(m->prefix) + { + namesp_found = AXIS2_FALSE; + nmsp_no = GUTHTHILA_STACK_SIZE(m->namesp); + for(j = nmsp_no - 1; j >= 0; j--) + { + e_namesp = (guththila_elem_namesp_t *)guththila_stack_get_by_index(&m->namesp, j, env); + for(k = 0; k < e_namesp->no; k++) + { + if(!guththila_tok_tok_cmp(e_namesp->namesp[k].name, m->prefix, env)) + { + namesp_found = GUTHTHILA_TRUE; + j = -1; /* force exit from outer loop */ + break; + } + } + } + if(!namesp_found) + return AXIS2_FAILURE; + } + return GUTHTHILA_SUCCESS; +} + +GUTHTHILA_EXPORT int GUTHTHILA_CALL +guththila_next( + guththila_t * m, + const axutil_env_t * env) +{ + guththila_element_t * elem = NULL; + guththila_elem_namesp_t * nmsp = NULL; + guththila_token_t * tok = NULL; + int quote = 0, ref = 0; + int c = -1; + guththila_attr_t * attr = NULL; + int size = 0, i = 0, nmsp_counter, loop = 0, white_space = 0; + size_t data_size = -1; + size_t previous_size = -1; + guththila_char_t *buffer = NULL; + + /* Need to release the resources for attributes */ + size = GUTHTHILA_STACK_SIZE(m->attrib); + for(i = 0; i < size; i++) + { + attr = (guththila_attr_t *)guththila_stack_pop(&m->attrib, env); + if(attr) + { + if(attr->name) + guththila_tok_list_release_token(&m->tokens, attr->name, env); + if(attr->pref) + guththila_tok_list_release_token(&m->tokens, attr->pref, env); + AXIS2_FREE(env->allocator, attr); + } + } + +#ifdef GUTHTHILA_VALIDATION_PARSER + if(m->guththila_event == GUTHTHILA_END_ELEMENT && m->name) + { + guththila_tok_list_release_token(&m->tokens, m->name, env); + if(m->prefix) + { + guththila_tok_list_release_token(&m->tokens, m->prefix, env); + } + } + /* If the previous event was a empty element we need to do some clean up */ + else if(m->guththila_event == GUTHTHILA_EMPTY_ELEMENT) + { + elem = (guththila_element_t *)guththila_stack_pop(&m->elem, env); + if(elem->is_namesp) + { + nmsp = (guththila_elem_namesp_t *)guththila_stack_pop(&m->namesp, env); + for(nmsp_counter = 0; nmsp_counter < nmsp->no; nmsp_counter++) + { + if(nmsp->namesp[nmsp_counter].name) + guththila_tok_list_release_token(&m->tokens, nmsp->namesp[nmsp_counter]. name, + env); + if(nmsp->namesp[nmsp_counter].uri) + guththila_tok_list_release_token(&m->tokens, nmsp->namesp[nmsp_counter]. uri, + env); + } + AXIS2_FREE(env->allocator, nmsp->namesp); + AXIS2_FREE(env->allocator, nmsp); + } + if(elem->name) + guththila_tok_list_release_token(&m->tokens, elem->name, env); + if(elem->prefix) + guththila_tok_list_release_token(&m->tokens, elem->prefix, env); + AXIS2_FREE(env->allocator, elem); + } + GUTHTHILA_VARIABLE_INITIALZE(m); +#endif + /* Actual XML parsing logic */ + do + { + loop = 0; + GUTHTHILA_NEXT_CHAR(m, buffer, data_size, previous_size, env, c); + if(m->status == S_1) + { + while(isspace(c)) + { + GUTHTHILA_NEXT_CHAR(m, buffer, data_size, previous_size, env, c); + } + if('<' == c) + { + m->status = S_2; + } + else + { + return -1; + } + } + if(m->status != S_2) + { + return -1; + } + if(c == '<') + { + GUTHTHILA_NEXT_CHAR(m, buffer, data_size, previous_size, env, c); + if(c != '?' && c != '!' && c != '/') + { + /* We are at the beginning of a xml element */ + if(GUTHTHILA_IS_VALID_STARTING_CHAR(c)) + { + GUTHTHILA_TOKEN_OPEN(m, tok, env); + GUTHTHILA_NEXT_CHAR(m, buffer, data_size, previous_size, env, c); + while(!GUTHTHILA_IS_SPACE(c) && c != '>' && c != '/') + { + if(c != ':') + { + GUTHTHILA_NEXT_CHAR(m, buffer, data_size, previous_size, env, c); + } + else + { + /* We know for sure that this is a prefix */ + guththila_token_close(m, tok, _prefix, 0, env); + GUTHTHILA_NEXT_CHAR(m, buffer, data_size, previous_size, env, c); + GUTHTHILA_TOKEN_OPEN(m, tok, env); + } + } + /* XML element name */ + guththila_token_close(m, tok, _name, 0, env); +#ifdef GUTHTHILA_VALIDATION_PARSER + elem = (guththila_element_t *)AXIS2_MALLOC(env->allocator, + sizeof(guththila_element_t)); + elem->name = m->name; + elem->prefix = m->prefix; + elem->is_namesp = 0; + guththila_stack_push(&m->elem, elem, env); +#endif + } + GUTHTHILA_SKIP_SPACES(m, c, buffer, data_size, previous_size, env); + /* Process the attributes */ + for(;;) + { + /* Empty element */ + if(c == '/') + { + GUTHTHILA_NEXT_CHAR(m, buffer, data_size, previous_size, env, c); + if(c == '>') + { + m->guththila_event = GUTHTHILA_EMPTY_ELEMENT; + if(!guththila_validate_namespaces(m, env)) + return -1; + else + return GUTHTHILA_EMPTY_ELEMENT; + } + else + { + return -1; + } + } + /* Normal element */ + else if(c == '>') + { + m->guththila_event = GUTHTHILA_START_ELEMENT; + if(!guththila_validate_namespaces(m, env)) + return -1; + else + return GUTHTHILA_START_ELEMENT; + } + /* We are in the middle of a element */ + else + { + /* Process the attributes */ + if(GUTHTHILA_IS_VALID_STARTING_CHAR(c)) + { + GUTHTHILA_TOKEN_OPEN(m, tok, env); + + GUTHTHILA_NEXT_CHAR(m, buffer, data_size, previous_size, env, c); + while(!GUTHTHILA_IS_SPACE(c) && c != '=') + { + if(c != ':') + { + GUTHTHILA_NEXT_CHAR(m, buffer, data_size, previous_size, env, c); + } + else if(c == ':') + { + /* Prefix */ + guththila_token_close(m, tok, _prefix, 0, env); + GUTHTHILA_NEXT_CHAR(m, buffer, data_size, previous_size, env, c); + GUTHTHILA_TOKEN_OPEN(m, tok, env); + } + } + /* Attribute name*/ + guththila_token_close(m, tok, _attribute_name, 0, env); + } + else + { + return -1; + } + /* Attribute Value */ + GUTHTHILA_PROCESS_EQU(m, c, quote, buffer, data_size, previous_size, env); + if(quote == '\'' || quote == '\"') + { + GUTHTHILA_NEXT_CHAR(m, buffer, data_size, previous_size, env, c); + GUTHTHILA_TOKEN_OPEN(m, tok, env); + while(c != quote) + { + GUTHTHILA_NEXT_CHAR(m, buffer, data_size, previous_size, env, c); + } + guththila_token_close(m, tok, _attribute_value, 0, env); + GUTHTHILA_NEXT_CHAR(m, buffer, data_size, previous_size, env, c); + GUTHTHILA_SKIP_SPACES(m, c, buffer, data_size, previous_size, env); + } + else + { + return -1; + } + } + } /* for(;;) */ + } + else if(c == '/') + { + /* End Element */ + m->guththila_event = GUTHTHILA_END_ELEMENT; + GUTHTHILA_NEXT_CHAR(m, buffer, data_size, previous_size, env, c); + if(GUTHTHILA_IS_VALID_STARTING_CHAR(c)) + { + GUTHTHILA_TOKEN_OPEN(m, tok, env); + GUTHTHILA_NEXT_CHAR(m, buffer, data_size, previous_size, env, c); + while(!GUTHTHILA_IS_SPACE(c) && c != '>') + { + if(c != ':') + { + GUTHTHILA_NEXT_CHAR(m, buffer, data_size, previous_size, env, c); + } + else + { + /* Prefix */ + guththila_token_close(m, tok, _prefix, 0, env); + GUTHTHILA_NEXT_CHAR(m, buffer, data_size, previous_size, env, c); + GUTHTHILA_TOKEN_OPEN(m, tok, env); + } + } + /* name */ + guththila_token_close(m, tok, _name, 0, env); + +#ifdef GUTHTHILA_VALIDATION_PARSER + elem = (guththila_element_t *)guththila_stack_pop(&m->elem, env); + if(!elem || (!elem->prefix && m->prefix) || (elem->prefix && !m->prefix)) + return -1; + if(guththila_tok_tok_cmp(m->name, elem->name, env)) + { + return -1; + } + if(elem->prefix && m->prefix && guththila_tok_tok_cmp(m->prefix, elem->prefix, + env)) + { + return -1; + } + /* Releasing the namespace related resources */ + if(elem->is_namesp) + { + nmsp = (guththila_elem_namesp_t *)guththila_stack_pop(&m->namesp, env); + for(nmsp_counter = 0; nmsp_counter < nmsp->no; nmsp_counter++) + { + if(nmsp->namesp[nmsp_counter].name) + guththila_tok_list_release_token(&m->tokens, + nmsp-> namesp[nmsp_counter]. name, env); + if(nmsp->namesp[nmsp_counter].uri) + guththila_tok_list_release_token(&m->tokens, + nmsp-> namesp[nmsp_counter]. uri, env); + } + AXIS2_FREE(env->allocator, nmsp->namesp); + AXIS2_FREE(env->allocator, nmsp); + } + /* Release the tokens */ + if(elem->name) + guththila_tok_list_release_token(&m->tokens, elem->name, env); + if(elem->prefix) + guththila_tok_list_release_token(&m->tokens, elem->prefix, env); + AXIS2_FREE(env->allocator, elem); +#endif + GUTHTHILA_SKIP_SPACES(m, c, buffer, data_size, previous_size, env); + if(c != '>') + return -1; + return GUTHTHILA_END_ELEMENT; + } + return -1; + } + else if(c == '!') + { + /* Comment */ + guththila_char_t c_arra[16] = { 0 }; + if(2 == guththila_next_no_char(m, 0, c_arra, 2, env) && '-' == c_arra[0] && '-' + == c_arra[1]) + { + int loop_state = 1; + GUTHTHILA_NEXT_CHAR(m, buffer, data_size, previous_size, env, c); + GUTHTHILA_TOKEN_OPEN(m, tok, env); + while(loop_state) + { + GUTHTHILA_NEXT_CHAR(m, buffer, data_size, previous_size, env, c); + if('-' == c) + { + if(2 == guththila_next_no_char(m, 0, c_arra, 2, env) && '-' + == c_arra[0]) + { + if('>' == c_arra[1]) + { + m->guththila_event = GUTHTHILA_COMMENT; + /* position after first hyphen, as if we just scanned it */ + m->next = m->next - 2; + guththila_token_close(m, tok, _char_data, 0, env); + m->next = m->next + 2; + return GUTHTHILA_COMMENT; + } + else + { + return -1; + } + } + } + } + } + else + { + GUTHTHILA_NEXT_CHAR(m, buffer, data_size, previous_size, env, c); + while('<' != c) + { + GUTHTHILA_NEXT_CHAR(m, buffer, data_size, previous_size, env, c); + } + } + } + else if(c == '?') + { + /* XML declaration */ + c = guththila_process_xml_dec(m, env); + if(c != -1) + return GUTHTHILA_START_DOCUMENT; + else + return -1; + } + } + else + { + /* Text */ + m->guththila_event = GUTHTHILA_CHARACTER; + if(!GUTHTHILA_IS_SPACE(c)) + white_space = 0; + else + white_space = 1; + GUTHTHILA_TOKEN_OPEN(m, tok, env); + + /* code given below is having two do-while loop wrapped by another do-while loop. + * This is done to improve the performance for big messages. Most of the cases, the + * content will be not whitespace, so checking for whitespace even if we already found + * that we have some valid characters is big overhead. Hence better to do the looping + * separately to find white_space = false and normal case + */ + do + { + if(white_space) + { + do + { + GUTHTHILA_NEXT_CHAR(m, buffer, data_size, previous_size, env, c); + if(!GUTHTHILA_IS_SPACE(c) && c != '<') + { + white_space = 0; + break; + } + } + while(c != '<'); + } + else + { + do + { + if(buffer) + { + guththila_char_t *pos = NULL; + size_t index = m->next - previous_size; + pos = (guththila_char_t*)memchr(buffer + index, '<', data_size - index); + if(pos) + { + m->next += pos - (buffer + index); + } + else + { + m->next = previous_size + data_size; + } + + GUTHTHILA_NEXT_CHAR(m, buffer, data_size, previous_size, env, c); + } + else + { + GUTHTHILA_NEXT_CHAR(m, buffer, data_size, previous_size, env, c); + } + }while(c != '<'); + } + } + while(c != '<'); + guththila_token_close(m, tok, _text_data, ref, env); + m->next--; + if(white_space) + { +#ifndef GUTHTHILA_IGNORE_SPACES + m->guththila_event = GUTHTHILA_SPACE; + return GUTHTHILA_SPACE; +#else + loop = 1; + if (m->value) + { + guththila_tok_list_release_token(&m->tokens, m->value, + env); + m->value = NULL; + } +#endif + } + + else + return GUTHTHILA_CHARACTER; + } + } + while(loop); + return c; +} + +/* Process the XML declaration */ +static int +guththila_process_xml_dec( + guththila_t * m, + const axutil_env_t * env) +{ + guththila_token_t * tok = NULL; + guththila_char_t c_arra[16] = { 0 }; + int c = -1; + int quote = -1; + int nc = -1; + size_t data_size = -1; + size_t previous_size = -1; + guththila_char_t *buffer = NULL; + if(3 == guththila_next_no_char(m, GUTHTHILA_EOF, c_arra, 3, env) && 'x' == c_arra[0] && 'm' + == c_arra[1] && 'l' == c_arra[2]) + { + GUTHTHILA_NEXT_CHAR(m, buffer, data_size, previous_size, env, c); + GUTHTHILA_SKIP_SPACES(m, c, buffer, data_size, previous_size, env); + if(c == 'v') + { + GUTHTHILA_TOKEN_OPEN(m, tok, env); + if(6 == guththila_next_no_char(m, 0, c_arra, 6, env) && 'e' == c_arra[0] && 'r' + == c_arra[1] && 's' == c_arra[2] && 'i' == c_arra[3] && 'o' == c_arra[4] && 'n' + == c_arra[5]) + { + GUTHTHILA_NEXT_CHAR(m, buffer, data_size, previous_size, env, c); + guththila_token_close(m, tok, _attribute_name, 0, env); + GUTHTHILA_PROCESS_EQU(m, c, quote, buffer, data_size, previous_size, env); + GUTHTHILA_NEXT_CHAR(m, buffer, data_size, previous_size, env, nc); + GUTHTHILA_TOKEN_OPEN(m, tok, env); + while(nc != quote) + { + GUTHTHILA_NEXT_CHAR(m, buffer, data_size, previous_size, env, nc); + } + guththila_token_close(m, tok, _attribute_value, 0, env); + GUTHTHILA_NEXT_CHAR(m, buffer, data_size, previous_size, env, c); + GUTHTHILA_SKIP_SPACES(m, c, buffer, data_size, previous_size, env); + } + else + { + return -1; + } + } + if(c == 'e') + { + GUTHTHILA_TOKEN_OPEN(m, tok, env); + if(7 == guththila_next_no_char(m, 0, c_arra, 7, env) && 'n' == c_arra[0] && 'c' + == c_arra[1] && 'o' == c_arra[2] && 'd' == c_arra[3] && 'i' == c_arra[4] && 'n' + == c_arra[5] && 'g' == c_arra[6]) + { + GUTHTHILA_NEXT_CHAR(m, buffer, data_size, previous_size, env, c); + guththila_token_close(m, tok, _attribute_name, 0, env); + GUTHTHILA_PROCESS_EQU(m, c, quote, buffer, data_size, previous_size, env); + GUTHTHILA_NEXT_CHAR(m, buffer, data_size, previous_size, env, nc); + GUTHTHILA_TOKEN_OPEN(m, tok, env); + while(nc != quote) + { + GUTHTHILA_NEXT_CHAR(m, buffer, data_size, previous_size, env, nc); + } + guththila_token_close(m, tok, _attribute_value, 0, env); + GUTHTHILA_NEXT_CHAR(m, buffer, data_size, previous_size, env, c); + GUTHTHILA_SKIP_SPACES(m, c, buffer, data_size, previous_size, env); + } + } + if(c == 's') + { + GUTHTHILA_TOKEN_OPEN(m, tok, env); + if(9 == guththila_next_no_char(m, 0, c_arra, 9, env) && 't' == c_arra[0] && 'a' + == c_arra[1] && 'n' == c_arra[2] && 'd' == c_arra[3] && 'a' == c_arra[4] && 'l' + == c_arra[5] && 'o' == c_arra[6] && 'n' == c_arra[7] && 'e' == c_arra[8]) + { + GUTHTHILA_NEXT_CHAR(m, buffer, data_size, previous_size, env, c); + guththila_token_close(m, tok, _attribute_name, 0, env); + GUTHTHILA_PROCESS_EQU(m, c, quote, buffer, data_size, previous_size, env); + GUTHTHILA_NEXT_CHAR(m, buffer, data_size, previous_size, env, nc); + GUTHTHILA_TOKEN_OPEN(m, tok, env); + while(nc != quote) + { + GUTHTHILA_NEXT_CHAR(m, buffer, data_size, previous_size, env, nc); + } + guththila_token_close(m, tok, _attribute_value, 0, env); + GUTHTHILA_NEXT_CHAR(m, buffer, data_size, previous_size, env, c); + GUTHTHILA_SKIP_SPACES(m, c, buffer, data_size, previous_size, env); + } + } + if(c == '?') + { + int nc; + GUTHTHILA_NEXT_CHAR(m, buffer, data_size, previous_size, env, nc); + if('>' == nc) + { + m->guththila_event = GUTHTHILA_START_DOCUMENT; + } + else + { + return -1; + } + } + } + return c; +} + +GUTHTHILA_EXPORT int GUTHTHILA_CALL +guththila_get_attribute_count( + guththila_t * m, + const axutil_env_t * env) +{ + return GUTHTHILA_STACK_SIZE(m->attrib); +} + +GUTHTHILA_EXPORT guththila_char_t *GUTHTHILA_CALL +guththila_get_attribute_name( + guththila_t * m, + guththila_attr_t * att, + const axutil_env_t * env) +{ + guththila_char_t *str = NULL; + if(att->name) + { + GUTHTHILA_TOKEN_TO_STRING(att->name, str, env); + return str; + } + return NULL; +} + +GUTHTHILA_EXPORT guththila_char_t *GUTHTHILA_CALL +guththila_get_attribute_value( + guththila_t * m, + guththila_attr_t * att, + const axutil_env_t * env) +{ + guththila_char_t *str = NULL; + if(att->val) + { + GUTHTHILA_TOKEN_TO_STRING(att->val, str, env); + return str; + } + return NULL; +} + +GUTHTHILA_EXPORT guththila_char_t *GUTHTHILA_CALL +guththila_get_attribute_prefix( + guththila_t * m, + guththila_attr_t * att, + const axutil_env_t * env) +{ + guththila_char_t *str = NULL; + if(att->pref) + { + GUTHTHILA_TOKEN_TO_STRING(att->pref, str, env); + return str; + } + return NULL; +} + +GUTHTHILA_EXPORT guththila_attr_t *GUTHTHILA_CALL +guththila_get_attribute( + guththila_t * m, + const axutil_env_t * env) +{ + return (guththila_attr_t *)guththila_stack_pop(&m->attrib, env); +} + +GUTHTHILA_EXPORT guththila_char_t *GUTHTHILA_CALL +guththila_get_attribute_name_by_number( + guththila_t * m, + int i, + const axutil_env_t *env) +{ + guththila_char_t *str = NULL; + guththila_attr_t * attr = (guththila_attr_t *)guththila_stack_get_by_index(&m->attrib, i - 1, + env); + if(attr->name) + { + GUTHTHILA_TOKEN_TO_STRING(attr->name, str, env); + return str; + } + return NULL; +} + +GUTHTHILA_EXPORT guththila_char_t *GUTHTHILA_CALL +guththila_get_attribute_value_by_number( + guththila_t * m, + int i, + const axutil_env_t *env) +{ + guththila_char_t *str = NULL; + guththila_attr_t * attr = (guththila_attr_t *)guththila_stack_get_by_index(&m->attrib, i - 1, + env); + if(attr->val) + { + GUTHTHILA_TOKEN_TO_STRING(attr->val, str, env); + return str; + } + return NULL; +} + +GUTHTHILA_EXPORT guththila_char_t *GUTHTHILA_CALL +guththila_get_attribute_prefix_by_number( + guththila_t * m, + int i, + const axutil_env_t *env) +{ + guththila_char_t *str = NULL; + guththila_attr_t * attr = (guththila_attr_t *)guththila_stack_get_by_index(&m->attrib, i - 1, + env); + if(attr && attr->pref) + { + GUTHTHILA_TOKEN_TO_STRING(attr->pref, str, env); + return str; + } + return NULL; +} + +GUTHTHILA_EXPORT guththila_char_t *GUTHTHILA_CALL +guththila_get_name( + guththila_t * m, + const axutil_env_t * env) +{ + guththila_char_t *str = NULL; + if(m->name) + { + GUTHTHILA_TOKEN_TO_STRING(m->name, str, env); + return str; + } + return NULL; +} + +GUTHTHILA_EXPORT guththila_char_t *GUTHTHILA_CALL +guththila_get_prefix( + guththila_t * m, + const axutil_env_t * env) +{ + guththila_char_t *str = NULL; + if(m->prefix) + { + GUTHTHILA_TOKEN_TO_STRING(m->prefix, str, env); + return str; + } + return NULL; +} + +GUTHTHILA_EXPORT guththila_char_t * GUTHTHILA_CALL +guththila_get_value( + guththila_t * m, + const axutil_env_t * env) +{ + guththila_char_t *str = NULL; + if(m->value) + { + GUTHTHILA_TOKEN_TO_STRING(m->value, str, env); + return str; + } + return NULL; +} + +GUTHTHILA_EXPORT guththila_namespace_t *GUTHTHILA_CALL +guththila_get_namespace( + guththila_t * m, + const axutil_env_t * env) +{ + +#ifndef GUTHTHILA_VALIDATION_PARSER + return (guththila_namespace_t *) guththila_stack_pop(&m->namesp, env); +#else + return NULL; +#endif +} + +GUTHTHILA_EXPORT int GUTHTHILA_CALL +guththila_get_namespace_count( + guththila_t * m, + const axutil_env_t * env) +{ + +#ifndef GUTHTHILA_VALIDATION_PARSER + return GUTHTHILA_STACK_SIZE(m->namesp); +#else + guththila_elem_namesp_t * nmsp = NULL; + if(((guththila_element_t *)guththila_stack_peek(&m->elem, env))->is_namesp) + { + nmsp = (guththila_elem_namesp_t *)guththila_stack_peek(&m->namesp, env); + return nmsp->no; + } + return 0; + +#endif +} + +GUTHTHILA_EXPORT guththila_char_t *GUTHTHILA_CALL +guththila_get_namespace_uri( + guththila_t * m, + guththila_namespace_t * ns, + const axutil_env_t * env) +{ + guththila_char_t *str = NULL; + if(ns->uri) + { + GUTHTHILA_TOKEN_TO_STRING(ns->uri, str, env); + return str; + } + return NULL; +} + +GUTHTHILA_EXPORT guththila_char_t *GUTHTHILA_CALL +guththila_get_namespace_prefix( + guththila_t * m, + guththila_namespace_t * ns, + const axutil_env_t * env) +{ + guththila_char_t *str = NULL; + if(ns->name) + { + GUTHTHILA_TOKEN_TO_STRING(ns->name, str, env); + return str; + } + return NULL; +} + +GUTHTHILA_EXPORT guththila_char_t *GUTHTHILA_CALL +guththila_get_namespace_prefix_by_number( + guththila_t * m, + int i, + const axutil_env_t *env) +{ + guththila_char_t *str = NULL; + +#ifndef GUTHTHILA_VALIDATION_PARSER + if (GUTHTHILA_STACK_SIZE(m->namesp) >= i) + { + namesp = guththila_stack_get_by_index(&m->namesp, i - 1, env); + if (namesp && namesp->name) + { + GUTHTHILA_TOKEN_TO_STRING(namesp->name, str, env); + return str; + } + } + +#else + guththila_elem_namesp_t * nmsp = NULL; + if(((guththila_element_t *)guththila_stack_peek(&m->elem, env))->is_namesp) + { + nmsp = (guththila_elem_namesp_t *)guththila_stack_peek(&m->namesp, env); + if(nmsp && nmsp->no >= i) + { + GUTHTHILA_TOKEN_TO_STRING(nmsp->namesp[i - 1].name, str, env); + return str; + } + } +#endif /* */ + return NULL; +} + +GUTHTHILA_EXPORT guththila_char_t *GUTHTHILA_CALL +guththila_get_namespace_uri_by_number( + guththila_t * m, + int i, + const axutil_env_t *env) +{ + guththila_char_t *str = NULL; +#ifndef GUTHTHILA_VALIDATION_PARSER + if (GUTHTHILA_STACK_SIZE(m->namesp) >= i) + { + namesp = guththila_stack_get_by_index(&m->namesp, i - 1, env); + if (namesp && namesp->uri) + { + GUTHTHILA_TOKEN_TO_STRING(namesp->uri, str, env); + return str; + } + } +#else + guththila_elem_namesp_t * nmsp = NULL; + if(((guththila_element_t *)guththila_stack_peek(&m->elem, env))->is_namesp) + { + nmsp = (guththila_elem_namesp_t *)guththila_stack_peek(&m->namesp, env); + if(nmsp && nmsp->no >= i) + { + GUTHTHILA_TOKEN_TO_STRING(nmsp->namesp[i - 1].uri, str, env); + return str; + } + } +#endif + return NULL; +} + +GUTHTHILA_EXPORT guththila_char_t *GUTHTHILA_CALL +guththila_get_attribute_namespace_by_number( + guththila_t * m, + int i, + const axutil_env_t *env) +{ + +#ifndef GUTHTHILA_VALIDATION_PARSER + return NULL; + +#else + guththila_attr_t * attr = NULL; + guththila_char_t* str = NULL; + int j = 0, k = 0, count = 0; + guththila_elem_namesp_t * nmsp = NULL; + if(i <= GUTHTHILA_STACK_SIZE(m->attrib)) + { + attr = (guththila_attr_t *)guththila_stack_get_by_index(&m->attrib, i - 1, env); + if(attr && attr->pref) + { + count = GUTHTHILA_STACK_SIZE(m->namesp); + for(j = count - 1; j >= 0; j--) + { + nmsp = (guththila_elem_namesp_t *)guththila_stack_get_by_index(&m->namesp, j, env); + for(k = 0; k < nmsp->no; k++) + { + if(!guththila_tok_tok_cmp(nmsp->namesp[k].name, attr->pref, env)) + { + GUTHTHILA_TOKEN_TO_STRING(nmsp->namesp[k].uri, str, env); + return str; + } + } + } + } + } + return NULL; + +#endif +} + +GUTHTHILA_EXPORT guththila_char_t *GUTHTHILA_CALL +guththila_get_encoding( + guththila_t * m, + const axutil_env_t * env) +{ + return "UTF-8"; +} + +/* Return the next character */ +static int +guththila_next_char( + guththila_t * m, + const axutil_env_t * env) +{ + int c; + size_t data_move, i; + int temp; + guththila_char_t **temp1; + size_t * temp2, *temp3; + + /* we have a buffered reader. Easiest case just fetch the character from + * the buffer. Here we have a single buffer. + * */ + if(m->reader->type == GUTHTHILA_MEMORY_READER) + { + size_t index = m->next++; + if(index < m->buffer.data_size[0]) + { + return m->buffer.buff[0][index]; + } + } + else + { + /* comlex stuff. We have a array of buffers */ + if(m->buffer.cur_buff != -1 && m->next < GUTHTHILA_BUFFER_PRE_DATA_SIZE(m->buffer) + + GUTHTHILA_BUFFER_CURRENT_DATA_SIZE(m->buffer)) + { + /* What we are looking for is already in the buffer */ + c = m->buffer.buff[m->buffer.cur_buff][m->next++ - GUTHTHILA_BUFFER_PRE_DATA_SIZE( + m->buffer)]; + return c; + } + else if(m->buffer.cur_buff != -1 && m->next >= GUTHTHILA_BUFFER_PRE_DATA_SIZE(m->buffer) + + GUTHTHILA_BUFFER_CURRENT_DATA_SIZE(m->buffer)) + { + /* if we have don't have enough space in current buffer, have to create new buffer */ + if(m->buffer.buffs_size[m->buffer.cur_buff] < + GUTHTHILA_BUFFER_CURRENT_DATA_SIZE(m->buffer) + GUTHTHILA_BUFFER_DEF_MIN_SIZE) + { + if(m->buffer.cur_buff == (int)m->buffer.no_buffers - 1) + { + /* we are out of allocated buffers. Need to allocate more buffers */ + temp = m->buffer.no_buffers * 2; + temp1 = (guththila_char_t **)AXIS2_MALLOC(env->allocator, + sizeof(guththila_char_t *) * temp); + temp2 = (size_t *)AXIS2_MALLOC(env->allocator, sizeof(size_t) * temp); + temp3 = (size_t *)AXIS2_MALLOC(env->allocator, sizeof(size_t) * temp); + if(!temp1 || !temp2 || !temp3) + return (-1); + for(i = 0; i < m->buffer.no_buffers; i++) + { + temp1[i] = m->buffer.buff[i]; + temp2[i] = m->buffer.buffs_size[i]; + temp3[i] = m->buffer.data_size[i]; + } + AXIS2_FREE(env->allocator, m->buffer.buff); + AXIS2_FREE(env->allocator, m->buffer.data_size); + AXIS2_FREE(env->allocator, m->buffer.buffs_size); + m->buffer.buff = temp1; + m->buffer.buffs_size = temp2; + m->buffer.data_size = temp3; + m->buffer.no_buffers *= 2; + } + m->buffer.buff[m->buffer.cur_buff + 1] = (guththila_char_t *)AXIS2_MALLOC( + env->allocator, + sizeof(guththila_char_t) * m->buffer.buffs_size[m->buffer.cur_buff] * 2); + if(!m->buffer.buff[m->buffer.cur_buff + 1]) + return -1; + m->buffer.cur_buff++; + m->buffer.buffs_size[m->buffer.cur_buff] = + m->buffer.buffs_size[m->buffer.cur_buff - 1] * 2; + m->buffer.data_size[m->buffer.cur_buff] = 0; + /* We need to have the content for one token in a single buffer. + * So if the space is not sufficient we have to move first part + * of the token to the next buffer */ + if(m->last_start != -1) + { + data_move = m->buffer.data_size[m->buffer.cur_buff - 1] - + (m->last_start - m->buffer.pre_tot_data); + memcpy(m->buffer.buff[m->buffer.cur_buff], m->buffer.buff[m->buffer.cur_buff - 1] + + m->buffer.data_size[m->buffer.cur_buff - 1] - data_move, data_move); + m->buffer.data_size[m->buffer.cur_buff - 1] -= data_move; + m->buffer.data_size[m->buffer.cur_buff] += data_move; + } + m->buffer.pre_tot_data += m->buffer.data_size[m->buffer.cur_buff - 1]; + } + temp = guththila_reader_read(m->reader, GUTHTHILA_BUFFER_CURRENT_BUFF(m->buffer), 0, + (int)GUTHTHILA_BUFFER_CURRENT_BUFF_SIZE(m->buffer), env); + if(temp > 0) + { + m->buffer.data_size[m->buffer.cur_buff] += temp; + } + else + { + return -1; + } + c = m->buffer.buff[m->buffer.cur_buff][m->next++ - GUTHTHILA_BUFFER_PRE_DATA_SIZE( + m->buffer)]; + return c; + } + /* Initial stage. We dont' have the array of buffers allocated*/ + else if(m->buffer.cur_buff == -1) + { + m->buffer.buff[0] = (guththila_char_t *)AXIS2_MALLOC(env->allocator, + sizeof(guththila_char_t) * GUTHTHILA_BUFFER_DEF_SIZE); + m->buffer.buffs_size[0] = GUTHTHILA_BUFFER_DEF_SIZE; + m->buffer.cur_buff = 0; + temp = guththila_reader_read(m->reader, m->buffer.buff[0], 0, + GUTHTHILA_BUFFER_DEF_SIZE, env); + m->buffer.data_size[0] = temp; + c = m->buffer.buff[0][m->next++]; + return c; + } + } + return -1; +} + +/* Same functionality as the guththila_next_char. But insted of reading + * one character this function reads several characters at once + * */ +static int +guththila_next_no_char( + guththila_t * m, + int eof, + guththila_char_t *bytes, + size_t no, + const axutil_env_t * env) +{ + int temp, data_move; + size_t i; + guththila_char_t **temp1; + size_t * temp2, *temp3; + if(m->reader->type == GUTHTHILA_MEMORY_READER && m->next + no - 1 + < GUTHTHILA_BUFFER_CURRENT_DATA_SIZE(m->buffer) && m->buffer.cur_buff != -1) + { + for(i = 0; i < no; i++) + { + bytes[i] = m->buffer.buff[0][m->next++]; + } + return (int)no; + /* We are sure that the difference lies within the int range */ + } + else if(m->reader->type == GUTHTHILA_IO_READER || m->reader->type == GUTHTHILA_FILE_READER) + { + if(m->next < GUTHTHILA_BUFFER_PRE_DATA_SIZE(m->buffer) + + GUTHTHILA_BUFFER_CURRENT_DATA_SIZE(m->buffer) + no && m->buffer.cur_buff != -1) + { + for(i = 0; i < no; i++) + { + bytes[i] = m->buffer.buff[m->buffer.cur_buff][m->next++ + - GUTHTHILA_BUFFER_PRE_DATA_SIZE(m->buffer)]; + } + return (int)no; + /* We are sure that the difference lies within the int range */ + } + else if(m->next >= GUTHTHILA_BUFFER_PRE_DATA_SIZE(m->buffer) + + GUTHTHILA_BUFFER_CURRENT_DATA_SIZE(m->buffer) + no && m->buffer.cur_buff != -1) + { + /* We are sure that the difference lies within the int range */ + if(m->buffer.cur_buff == (int)m->buffer.no_buffers - 1) + { + temp = m->buffer.no_buffers * 2; + temp1 = (guththila_char_t **)AXIS2_MALLOC(env->allocator, + sizeof(guththila_char_t *) * temp); + temp2 = (size_t *)AXIS2_MALLOC(env->allocator, sizeof(size_t) * temp); + temp3 = (size_t *)AXIS2_MALLOC(env->allocator, sizeof(size_t) * temp); + if(!temp1 || !temp2 || !temp3) + return (-1); + for(i = 0; i < m->buffer.no_buffers; i++) + { + temp1[i] = m->buffer.buff[i]; + temp2[i] = m->buffer.buffs_size[i]; + temp3[i] = m->buffer.data_size[i]; + } + AXIS2_FREE(env->allocator, m->buffer.buff); + AXIS2_FREE(env->allocator, m->buffer.data_size); + AXIS2_FREE(env->allocator, m->buffer.buffs_size); + m->buffer.buff = temp1; + m->buffer.buffs_size = temp2; + m->buffer.data_size = temp3; + m->buffer.no_buffers *= 2; + } + m->buffer.buff[m->buffer.cur_buff + 1] = (guththila_char_t *)AXIS2_MALLOC( + env->allocator, sizeof(guththila_char_t) * m->buffer.data_size[m->buffer.cur_buff] + * 2); + if(!m->buffer.buff[m->buffer.cur_buff + 1]) + return -1; + m->buffer.cur_buff++; + m->buffer.buffs_size[m->buffer.cur_buff] = m->buffer.buffs_size[m->buffer.cur_buff - 1] + * 2; + m->buffer.data_size[m->buffer.cur_buff] = 0; + data_move = (int)m->next; + /* We are sure that the difference lies within the int range */ + if((m->last_start != -1) && (m->last_start < data_move)) + data_move = m->last_start; + data_move = (int)m->buffer.data_size[m->buffer.cur_buff - 1] - (data_move + - (int)m->buffer.pre_tot_data); + /* We are sure that the difference lies within the int range */ + if(data_move) + { + memcpy(m->buffer.buff[m->buffer.cur_buff], m->buffer.buff[m->buffer.cur_buff - 1] + + m->buffer.data_size[m->buffer.cur_buff - 1] - data_move, data_move); + m->buffer.data_size[m->buffer.cur_buff - 1] -= data_move; + m->buffer.data_size[m->buffer.cur_buff] += data_move; + } + m->buffer.pre_tot_data += m->buffer.data_size[m->buffer.cur_buff - 1]; + temp = guththila_reader_read(m->reader, GUTHTHILA_BUFFER_CURRENT_BUFF(m->buffer), 0, + (int)GUTHTHILA_BUFFER_CURRENT_BUFF_SIZE(m-> buffer), env); + /* We are sure that the difference lies within the int range */ + if(temp > 0) + { + m->buffer.data_size[m->buffer.cur_buff] += temp; + } + else + { + return -1; + } + for(i = 0; i < no; i++) + { + bytes[i] = m->buffer.buff[m->buffer.cur_buff][m->next++ + - GUTHTHILA_BUFFER_PRE_DATA_SIZE(m->buffer)]; + } + return (int)no; + /* We are sure that the difference lies within the int range */ + } + else if(m->buffer.cur_buff == -1) + { + m->buffer.buff[0] = (guththila_char_t *)AXIS2_MALLOC(env->allocator, + sizeof(guththila_char_t) * GUTHTHILA_BUFFER_DEF_SIZE); + m->buffer.buffs_size[0] = GUTHTHILA_BUFFER_DEF_SIZE; + m->buffer.cur_buff = 0; + temp = guththila_reader_read(m->reader, m->buffer.buff[0], 0, + GUTHTHILA_BUFFER_DEF_SIZE, env); + m->buffer.data_size[0] = temp; + for(i = 0; i < no; i++) + { + bytes[i] = m->buffer.buff[m->buffer.cur_buff][m->next++ + - GUTHTHILA_BUFFER_PRE_DATA_SIZE(m->buffer)]; + } + return (int)no; + /* We are sure that the difference lies within the int range */ + } + } + return -1; +} + +GUTHTHILA_EXPORT guththila_char_t *GUTHTHILA_CALL +guththila_get_current_buffer( + guththila_t * m, + const axutil_env_t * env) +{ + return guththila_buffer_get(&m->buffer, env); +} + diff --git a/guththila/src/guththila_xml_writer.c b/guththila/src/guththila_xml_writer.c new file mode 100644 index 0000000..adc2389 --- /dev/null +++ b/guththila/src/guththila_xml_writer.c @@ -0,0 +1,2082 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include + +#define GUTHTHILA_WRITER_SD_DECLARATION "" + +#ifndef GUTHTHILA_XML_WRITER_TOKEN +#ifndef GUTHTHILA_WRITER_ELEM_FREE +#define GUTHTHILA_WRITER_ELEM_FREE(wr, elem, _env) \ + if ((elem)->prefix) AXIS2_FREE(env->allocator, (elem)->prefix); \ + if ((elem)->name) AXIS2_FREE(env->allocator, (elem)->name); \ + AXIS2_FREE(env->allocator, elem); +#endif +#else +#ifndef GUTHTHILA_WRITER_ELEM_FREE +#define GUTHTHILA_WRITER_ELEM_FREE(wr, elem, _env) \ + if ((elem)->prefix) guththila_tok_list_release_token(&wr->tok_list, (elem)->prefix, _env); \ + if ((elem)->name) guththila_tok_list_release_token(&wr->tok_list, (elem)->name, _env); \ + AXIS2_FREE(env->allocator, elem); +#endif +#endif + +#ifndef GUTHTHILA_XML_WRITER_TOKEN +#ifndef GUTHTHILA_WRITER_CLEAR_NAMESP +#define GUTHTHILA_WRITER_CLEAR_NAMESP(wr, stack_namesp, _no, counter, _namesp, j, _env) \ + for (counter = GUTHTHILA_STACK_TOP_INDEX(*stack_namesp); counter >= _no; counter--) {\ + _namesp = (guththila_xml_writer_namesp_t *) guththila_stack_pop(stack_namesp, _env); \ + if (_namesp) { \ + for (j = 0; j < _namesp->no - 1; j++) { \ + if (_namesp->name[j]) AXIS2_FREE(env->allocator, _namesp->name[j]); \ + if (_namesp->uri[j]) AXIS2_FREE(env->allocator, _namesp->uri[j]); \ + } \ + AXIS2_FREE(env->allocator, _namesp->name); \ + AXIS2_FREE(env->allocator, _namesp->uri); \ + AXIS2_FREE(env->allocator, _namesp); \ + } \ + _namesp = NULL; \ +} +#endif +#else +#ifndef GUTHTHILA_WRITER_CLEAR_NAMESP +#define GUTHTHILA_WRITER_CLEAR_NAMESP(wr, stack_namesp, _no, counter, _namesp, j, _env) \ + for (counter = GUTHTHILA_STACK_TOP_INDEX(*stack_namesp); counter >= _no; counter--) { \ + _namesp = (guththila_xml_writer_namesp_t *) guththila_stack_pop(stack_namesp, _env); \ + if (_namesp) { \ + for (j = 0; j < _namesp->no - 1; j++) { \ + guththila_tok_list_release_token(&wr->tok_list, _namesp->name[j], _env); \ + guththila_tok_list_release_token(&wr->tok_list, _namesp->uri[j], _env); \ + } \ + AXIS2_FREE(env->allocator, _namesp->name); \ + AXIS2_FREE(env->allocator, _namesp->uri); \ + AXIS2_FREE(env->allocator, _namesp); \ + } \ + _namesp = NULL; \ +} +#endif +#endif + +#ifndef GUTHTHILA_WRITER_INIT_ELEMENT +#define GUTHTHILA_WRITER_INIT_ELEMENT_WITH_PREFIX(wr, _elem, _name_start, _name_size, _pref_start, _pref_size) \ + _elem->name = guththila_tok_list_get_token(&wr->tok_list); \ + _elem->prefix = = guththila_tok_list_get_token(&wr->tok_list); \ + _elem->name->start = _name_start; \ + _elem->name->size = _name_size; \ + _elem->prefix->start = _pref_start; \ + _elem->prrefix->size = pref_size; +#endif + +#ifndef GUTHTHILA_WRITER_INIT_ELEMENT +#define GUTHTHILA_WRITER_INIT_ELEMENT_WITHOUT_PREFIX(wr, _elem, _name_start, _name_size) \ + _elem->name = guththila_tok_list_get_token(&(wr)->tok_list); \ + _elem->name->start = _name_start; \ + _elem->name->size = _name_size; \ + _elem->prefix->NULL; +#endif + +/* + #ifndef guththila_write(_wr, _buff, _buff_size) + #define guththila_write(_wr, _buff, _buff_size) \ + if (_wr->type == GUTHTHILA_WRITER_MEMORY){ \ + if (_wr->buffer.size > _wr->buffer.next + _buff_size) {\ + memcpy (_wr->buffer.buff + _wr->buffer.next, _buff, _buff_size);\ + _wr->buffer.next += (int)_buff_size; \ + } else {\ + _wr->buffer.buff = realloc(_wr->buffer.buff, _wr->buffer.size * 2);\ + _wr->buffer.size = _wr->buffer.size * 2; \ + memcpy (_wr->buffer.buff + _wr->buffer.next, _buff, _buff_size);\ + _wr->buffer.next += (int)_buff_size; \ + }\ + } + #endif*/ + +/* + * Write the contents of the buff in to the guththila_xml_writer buffer. + * len indicates the number of items in the buff. + */ +int GUTHTHILA_CALL guththila_write( + guththila_xml_writer_t * wr, + char *buff, + size_t buff_size, + const axutil_env_t * env); + +/* + * Same functionality as the guththila_write only difference is here we are given + * a token to write, not a buffer. + */ +int GUTHTHILA_CALL guththila_write_token( + guththila_xml_writer_t * wr, + guththila_token_t * tok, + const axutil_env_t * env); + +int GUTHTHILA_CALL guththila_write_xtoken( + guththila_xml_writer_t * wr, + char *buff, + size_t buff_len, + const axutil_env_t * env); + +/* + * Private function for free the contents of a empty element. + */ +int GUTHTHILA_CALL guththila_free_empty_element( + guththila_xml_writer_t *wr, + const axutil_env_t *env); + +GUTHTHILA_EXPORT guththila_xml_writer_t * GUTHTHILA_CALL +guththila_create_xml_stream_writer( + guththila_char_t *file_name, + const axutil_env_t * env) +{ + guththila_xml_writer_t * wr = AXIS2_MALLOC(env->allocator, sizeof(guththila_xml_writer_t)); + if(!wr) + return NULL; + wr->out_stream = fopen(file_name, "w"); + if(!wr->out_stream) + { + AXIS2_FREE(env->allocator, wr); + return NULL; + } + if(!guththila_stack_init(&wr->element, env)) + { + fclose(wr->out_stream); + AXIS2_FREE(env->allocator, wr); + return NULL; + } + if(!guththila_stack_init(&wr->namesp, env)) + { + guththila_stack_un_init(&wr->element, env); + fclose(wr->out_stream); + AXIS2_FREE(env->allocator, wr); + return NULL; + } + wr->type = GUTHTHILA_WRITER_FILE; + wr->status = BEGINING; + wr->next = 0; + return wr; +} + +GUTHTHILA_EXPORT guththila_xml_writer_t * GUTHTHILA_CALL +guththila_create_xml_stream_writer_for_memory( + const axutil_env_t * env) +{ + guththila_xml_writer_t * wr = AXIS2_MALLOC(env->allocator, sizeof(guththila_xml_writer_t)); + if(!wr) + return NULL; + if(!guththila_buffer_init(&wr->buffer, GUTHTHILA_BUFFER_DEF_SIZE, env)) + { + AXIS2_FREE(env->allocator, wr); + return NULL; + } + if(!guththila_stack_init(&wr->element, env)) + { + guththila_buffer_un_init(&wr->buffer, env); + AXIS2_FREE(env->allocator, wr); + return NULL; + } + if(!guththila_stack_init(&wr->namesp, env)) + { + guththila_buffer_un_init(&wr->buffer, env); + guththila_stack_un_init(&wr->element, env); + AXIS2_FREE(env->allocator, wr); + return NULL; + } + +#ifdef GUTHTHILA_XML_WRITER_TOKEN + if (!guththila_tok_list_init(&wr->tok_list, env)) + { + guththila_buffer_un_init(&wr->buffer, env); + guththila_stack_un_init(&wr->element, env); + guththila_stack_un_init(&wr->namesp, env); + AXIS2_FREE(env->allocator, wr); + return NULL; + } +#endif + wr->type = GUTHTHILA_WRITER_MEMORY; + wr->status = BEGINING; + wr->next = 0; + return wr; +} + +GUTHTHILA_EXPORT void GUTHTHILA_CALL +guththila_xml_writer_free( + guththila_xml_writer_t * wr, + const axutil_env_t * env) +{ + if(wr->type == GUTHTHILA_WRITER_MEMORY) + { + guththila_buffer_un_init(&wr->buffer, env); + } + else if(wr->type == GUTHTHILA_WRITER_FILE) + { + fclose(wr->out_stream); + } + +#ifdef GUTHTHILA_XML_WRITER_TOKEN + guththila_tok_list_free_data(&wr->tok_list, env); +#endif + guththila_stack_un_init(&wr->element, env); + guththila_stack_un_init(&wr->namesp, env); + AXIS2_FREE(env->allocator, wr); +} + +int GUTHTHILA_CALL +guththila_write( + guththila_xml_writer_t * wr, + guththila_char_t *buff, + size_t buff_len, + const axutil_env_t * env) +{ + size_t remain_len = 0; + size_t temp = 0; + size_t * temp1 = NULL, *temp2 = NULL; + guththila_char_t **temp3 = NULL; + int i = 0; + if(wr->type == GUTHTHILA_WRITER_MEMORY) + { + remain_len = wr->buffer.buffs_size[wr->buffer.cur_buff] + - wr->buffer.data_size[wr->buffer.cur_buff]; + /* We have space */ + if(buff_len < remain_len) + { + memcpy( + wr->buffer.buff[wr->buffer.cur_buff] + wr->buffer.data_size[wr->buffer.cur_buff], + buff, buff_len); + wr->buffer.data_size[wr->buffer.cur_buff] += buff_len; + wr->next += (int)buff_len; + /* We are sure that the difference lies within the int range */ + return (int)buff_len; + } + else + { + if(remain_len != 0) + { + memcpy(wr->buffer.buff[wr->buffer.cur_buff] + + wr->buffer.data_size[wr->buffer.cur_buff], buff, remain_len); + wr->buffer.data_size[wr->buffer.cur_buff] += remain_len; + } + /* We are sure that the difference lies within the int range */ + if(((int)wr->buffer.no_buffers - 1) == wr->buffer.cur_buff) + { + /* Out of allocated array buffers. Need to allocate*/ + wr->buffer.no_buffers = wr->buffer.no_buffers * 2; + temp3 = (guththila_char_t **)AXIS2_MALLOC(env->allocator, + sizeof(guththila_char_t *) * wr->buffer.no_buffers); + temp1 = (size_t *)AXIS2_MALLOC(env->allocator, sizeof(size_t) + * wr->buffer.no_buffers); + temp2 = (size_t *)AXIS2_MALLOC(env->allocator, sizeof(size_t) + * wr->buffer.no_buffers); + for(i = 0; i <= wr->buffer.cur_buff; i++) + { + temp3[i] = wr->buffer.buff[i]; + temp1[i] = wr->buffer.data_size[i]; + temp2[i] = wr->buffer.buffs_size[i]; + } + AXIS2_FREE(env->allocator, wr->buffer.data_size); + AXIS2_FREE(env->allocator, wr->buffer.buffs_size); + AXIS2_FREE(env->allocator, wr->buffer.buff); + wr->buffer.buff = temp3; + wr->buffer.buffs_size = temp2; + wr->buffer.data_size = temp1; + } + wr->buffer.cur_buff++; + temp = wr->buffer.buffs_size[wr->buffer.cur_buff - 1] * 2; + while(temp < (buff_len - remain_len)) + { + temp = temp * 2; + } + /* Create a be buffer */ + wr->buffer.buff[wr->buffer.cur_buff] = (guththila_char_t *)AXIS2_MALLOC(env->allocator, + sizeof(guththila_char_t) * temp); + wr->buffer.buffs_size[wr->buffer.cur_buff] = temp; + memcpy(wr->buffer.buff[wr->buffer.cur_buff], buff + remain_len, buff_len - remain_len); + wr->buffer.data_size[wr->buffer.cur_buff] = buff_len - remain_len; + wr->buffer.pre_tot_data += wr->buffer.data_size[wr->buffer.cur_buff - 1]; + wr->next += (int)buff_len; + /* We are sure that the difference lies within the int range */ + return (int)buff_len; + } + } + else if(wr->type == GUTHTHILA_WRITER_FILE) + { + return (int)fwrite(buff, 1, buff_len, wr->out_stream); + } + return GUTHTHILA_FAILURE; +} + +int GUTHTHILA_CALL +guththila_write_token( + guththila_xml_writer_t * wr, + guththila_token_t * tok, + const axutil_env_t * env) +{ + int i; + size_t remain_len = 0; + size_t temp = 0; + size_t * temp1 = NULL, *temp2 = NULL; + guththila_char_t **temp3 = NULL; + if(wr->type == GUTHTHILA_WRITER_MEMORY) + { + remain_len = wr->buffer.buffs_size[wr->buffer.cur_buff] + - wr->buffer.data_size[wr->buffer.cur_buff]; + if(tok->size < remain_len) + { + memcpy( + wr->buffer.buff[wr->buffer.cur_buff] + wr->buffer.data_size[wr->buffer.cur_buff], + tok->start, tok->size); + + wr->buffer.data_size[wr->buffer.cur_buff] += tok->size; + wr->next += (int)tok->size; + /* We are sure that the difference lies within the int range */ + return (int)tok->size; + } + else + { + if(remain_len != 0) + { + memcpy(wr->buffer.buff[wr->buffer.cur_buff] + + wr->buffer.data_size[wr->buffer.cur_buff], tok->start, remain_len); + + wr->buffer.data_size[wr->buffer.cur_buff] += remain_len; + } + /* We are sure that the difference lies within the int range */ + if(((int)wr->buffer.no_buffers - 1) == wr->buffer.cur_buff) + { + wr->buffer.no_buffers = wr->buffer.no_buffers * 2; + temp3 = (guththila_char_t **)AXIS2_MALLOC(env->allocator, + sizeof(guththila_char_t *) * wr->buffer.no_buffers); + temp1 = (size_t *)AXIS2_MALLOC(env->allocator, sizeof(size_t) + * wr->buffer.no_buffers); + temp2 = (size_t *)AXIS2_MALLOC(env->allocator, sizeof(size_t) + * wr->buffer.no_buffers); + for(i = 0; i <= wr->buffer.cur_buff; i++) + { + temp3[i] = wr->buffer.buff[i]; + temp1[i] = wr->buffer.data_size[i]; + temp2[i] = wr->buffer.buffs_size[i]; + } + AXIS2_FREE(env->allocator, wr->buffer.data_size); + AXIS2_FREE(env->allocator, wr->buffer.buffs_size); + AXIS2_FREE(env->allocator, wr->buffer.buff); + wr->buffer.buff = temp3; + wr->buffer.buffs_size = temp2; + wr->buffer.data_size = temp1; + } + wr->buffer.cur_buff++; + temp = wr->buffer.buffs_size[wr->buffer.cur_buff - 1] * 2; + while(temp < (tok->size - remain_len)) + { + temp = temp * 2; + } + wr->buffer.buff[wr->buffer.cur_buff] = (guththila_char_t *)AXIS2_MALLOC(env->allocator, + sizeof(guththila_char_t) * temp); + + wr->buffer.buffs_size[wr->buffer.cur_buff] = temp; + memcpy(wr->buffer.buff[wr->buffer.cur_buff], tok->start + remain_len, tok->size + - remain_len); + wr->buffer.data_size[wr->buffer.cur_buff] = tok->size - remain_len; + wr->buffer.pre_tot_data += wr->buffer.data_size[wr->buffer.cur_buff - 1]; + wr->next += (int)tok->size; + /* We are sure that the difference lies within the int range */ + return (int)tok->size; + } + } + else if(wr->type == GUTHTHILA_WRITER_FILE) + { + return (int)fwrite(tok->start, 1, tok->size, wr->out_stream); + } + return GUTHTHILA_FAILURE; +} + +int GUTHTHILA_CALL +guththila_write_xtoken( + guththila_xml_writer_t * wr, + guththila_char_t *buff, + size_t buff_len, + const axutil_env_t * env) +{ + int i; + size_t temp = 0; + size_t remain_len = 0; + size_t * temp1 = NULL, *temp2 = NULL; + guththila_char_t **temp3 = NULL; + if(wr->type == GUTHTHILA_WRITER_MEMORY) + { + remain_len = wr->buffer.buffs_size[wr->buffer.cur_buff] + - wr->buffer.data_size[wr->buffer.cur_buff]; + if(buff_len < remain_len) + { + memcpy( + wr->buffer.buff[wr->buffer.cur_buff] + wr->buffer.data_size[wr->buffer.cur_buff], + buff, buff_len); + wr->buffer.data_size[wr->buffer.cur_buff] += buff_len; + wr->next += (int)buff_len; + /* We are sure that the difference lies within the int range */ + return (int)buff_len; + } + else + { + /* We are sure that the difference lies within the int range */ + if(((int)wr->buffer.no_buffers - 1) == wr->buffer.cur_buff) + { + wr->buffer.no_buffers = wr->buffer.no_buffers * 2; + temp3 = (guththila_char_t **)AXIS2_MALLOC(env->allocator, + sizeof(guththila_char_t *) * wr->buffer.no_buffers); + temp1 = (size_t *)AXIS2_MALLOC(env->allocator, sizeof(size_t) + * wr->buffer.no_buffers); + temp2 = (size_t *)AXIS2_MALLOC(env->allocator, sizeof(size_t) + * wr->buffer.no_buffers); + for(i = 0; i <= wr->buffer.cur_buff; i++) + { + temp3[i] = wr->buffer.buff[i]; + temp1[i] = wr->buffer.data_size[i]; + temp2[i] = wr->buffer.buffs_size[i]; + } + AXIS2_FREE(env->allocator, wr->buffer.data_size); + AXIS2_FREE(env->allocator, wr->buffer.buffs_size); + AXIS2_FREE(env->allocator, wr->buffer.buff); + wr->buffer.buff = temp3; + wr->buffer.buffs_size = temp2; + wr->buffer.data_size = temp1; + } + temp = wr->buffer.buffs_size[wr->buffer.cur_buff] * 2; + while(temp < (buff_len)) + { + temp = temp * 2; + } + wr->buffer.cur_buff++; + wr->buffer.buff[wr->buffer.cur_buff] = (guththila_char_t *)AXIS2_MALLOC(env->allocator, + sizeof(guththila_char_t) * temp); + + wr->buffer.buffs_size[wr->buffer.cur_buff] = temp; + memcpy(wr->buffer.buff[wr->buffer.cur_buff], buff, buff_len); + wr->buffer.data_size[wr->buffer.cur_buff] = buff_len; + wr->buffer.pre_tot_data += wr->buffer.data_size[wr->buffer.cur_buff - 1]; + wr->next += (int)buff_len; + /* We are sure that the difference lies within the int range */ + return (int)buff_len; + } + } + else if(wr->type == GUTHTHILA_WRITER_FILE) + { + return (int)fwrite(buff, 1, buff_len, wr->out_stream); + } + return GUTHTHILA_FAILURE; +} + +int GUTHTHILA_CALL +guththila_free_empty_element( + guththila_xml_writer_t *wr, + const axutil_env_t *env) +{ + guththila_xml_writer_element_t * elem = NULL; + guththila_xml_writer_namesp_t * namesp = NULL; + int i = 0, j = 0; + elem = (guththila_xml_writer_element_t *)guththila_stack_pop(&wr->element, env); + if(elem) + { + wr->status = BEGINING; + if(elem->name_sp_stack_no != -1) + { + GUTHTHILA_WRITER_CLEAR_NAMESP(wr, &wr->namesp, + elem->name_sp_stack_no, i, + namesp, j, env); + } + GUTHTHILA_WRITER_ELEM_FREE(wr, elem, env); + return GUTHTHILA_SUCCESS; + } + else + { + return GUTHTHILA_FAILURE; + } +} + +GUTHTHILA_EXPORT int GUTHTHILA_CALL +guththila_write_start_document( + guththila_xml_writer_t * wr, + const axutil_env_t * env, + char *encoding, + char *version) +{ + char *tmp1 = NULL; + char *tmp2 = GUTHTHILA_WRITER_SD_DECLARATION; + + tmp1 = strchr(tmp2, '\"'); + tmp1++; + guththila_write(wr, tmp2, (int)(tmp1 - tmp2), env); + tmp2 = strchr(tmp1, '\"'); + if(version) + { + guththila_write(wr, version, (int)strlen(version), env); + } + else + { + guththila_write(wr, tmp1, (int)(tmp2 - tmp1), env); + } + tmp2++; + tmp1 = strchr(tmp2, '\"'); + tmp2--; + tmp1++; + guththila_write(wr, tmp2, (int)(tmp1 - tmp2), env); + tmp2 = strchr(tmp1, '\"'); + if(encoding) + { + guththila_write(wr, encoding, (int)strlen(encoding), env); + } + else + { + guththila_write(wr, tmp1, (int)(tmp2 - tmp1), env); + } + guththila_write(wr, tmp2, (int)strlen(tmp2), env); + + return GUTHTHILA_SUCCESS; +} + +GUTHTHILA_EXPORT int GUTHTHILA_CALL +guththila_write_start_element( + guththila_xml_writer_t * wr, + guththila_char_t *start_element, + const axutil_env_t * env) +{ + int cur_pos = 0; + size_t len = 0; + guththila_xml_writer_element_t * element = (guththila_xml_writer_element_t *)AXIS2_MALLOC( + env->allocator, sizeof(guththila_xml_writer_element_t)); + len = strlen(start_element); + if(wr->status == START) + { + /* If we are in a start we need to close and start */ + guththila_write(wr, "><", 2u, env); + cur_pos = wr->next; + guththila_write_xtoken(wr, start_element, len, env); + } + else if(wr->status == START_EMPTY) + { + /* We need to close and start */ + guththila_free_empty_element(wr, env); + guththila_write(wr, "/><", 3u, env); + cur_pos = wr->next; + guththila_write_xtoken(wr, start_element, len, env); + } + else if(wr->status == BEGINING) + { + /* We can start rightaway*/ + guththila_write(wr, "<", 1u, env); + cur_pos = wr->next; + guththila_write_xtoken(wr, start_element, len, env); + } + else + { + return GUTHTHILA_FAILURE; + } + wr->status = START; + +#ifndef GUTHTHILA_XML_WRITER_TOKEN + element->name = strdup(start_element); + element->prefix = NULL; +#else + element->name = guththila_tok_list_get_token(&wr->tok_list, env); + element->name->start = GUTHTHILA_BUF_POS(wr->buffer, cur_pos); + element->name->size = len; + element->prefix = NULL; + +#endif + element->name_sp_stack_no = -1; + return guththila_stack_push(&wr->element, element, env); +} + +GUTHTHILA_EXPORT int GUTHTHILA_CALL +guththila_write_end_element( + guththila_xml_writer_t * wr, + const axutil_env_t * env) +{ + guththila_xml_writer_element_t * elem = NULL; + guththila_xml_writer_namesp_t * namesp = NULL; + int i = 0, j = 0; + if(wr->status == START) + { + guththila_write(wr, ">element, env); + if(elem) + { + if(elem->prefix) + { + +#ifndef GUTHTHILA_XML_WRITER_TOKEN + guththila_write(wr, elem->prefix, strlen(elem->prefix), env); +#else + guththila_write_token(wr, elem->prefix, env); +#endif + guththila_write(wr, ":", 1u, env); + } + +#ifndef GUTHTHILA_XML_WRITER_TOKEN + guththila_write(wr, elem->name, strlen(elem->name), env); +#else + guththila_write_token(wr, elem->name, env); +#endif + guththila_write(wr, ">", 1u, env); + wr->status = BEGINING; + if(elem->name_sp_stack_no != -1) + { + GUTHTHILA_WRITER_CLEAR_NAMESP(wr, &wr->namesp, + elem->name_sp_stack_no, i, + namesp, j, env); + } + GUTHTHILA_WRITER_ELEM_FREE(wr, elem, env); + return GUTHTHILA_SUCCESS; + } + else + { + return GUTHTHILA_FAILURE; + } + } + else if(wr->status == START_EMPTY) + { + guththila_write(wr, "/>", 2u, env); + elem = (guththila_xml_writer_element_t *)guththila_stack_pop(&wr->element, env); + if(elem) + { + wr->status = BEGINING; + if(elem->name_sp_stack_no != -1) + { + GUTHTHILA_WRITER_CLEAR_NAMESP(wr, &wr->namesp, + elem->name_sp_stack_no, i, + namesp, j, env); + } + GUTHTHILA_WRITER_ELEM_FREE(wr, elem, env); + return GUTHTHILA_SUCCESS; + } + else + { + return GUTHTHILA_FAILURE; + } + } + else if(wr->status == BEGINING) + { + guththila_write(wr, "element, env); + if(elem) + { + if(elem->prefix) + { + +#ifndef GUTHTHILA_XML_WRITER_TOKEN + guththila_write(wr, elem->prefix, strlen(elem->prefix), env); +#else + guththila_write_token(wr, elem->prefix, env); +#endif + guththila_write(wr, ":", 1u, env); + } + +#ifndef GUTHTHILA_XML_WRITER_TOKEN + guththila_write(wr, elem->name, strlen(elem->name), env); +#else + guththila_write_token(wr, elem->name, env); +#endif + guththila_write(wr, ">", 1u, env); + wr->status = BEGINING; + if(elem->name_sp_stack_no != -1) + { + GUTHTHILA_WRITER_CLEAR_NAMESP(wr, &wr->namesp, + elem->name_sp_stack_no, i, + namesp, j, env); + } + GUTHTHILA_WRITER_ELEM_FREE(wr, elem, env); + return GUTHTHILA_SUCCESS; + } + else + { + return GUTHTHILA_FAILURE; + } + } + return GUTHTHILA_FAILURE; +} + +GUTHTHILA_EXPORT int GUTHTHILA_CALL +guththila_close( + guththila_xml_writer_t * wr, + const axutil_env_t * env) +{ + return GUTHTHILA_FAILURE; +} + +GUTHTHILA_EXPORT int GUTHTHILA_CALL +guththila_write_characters( + guththila_xml_writer_t * wr, + guththila_char_t *buff, + const axutil_env_t * env) +{ + size_t len = strlen(buff); + if(wr->status == START) + { + wr->status = BEGINING; + guththila_write(wr, ">", 1u, env); + } + else if(wr->status == START_EMPTY) + { + guththila_free_empty_element(wr, env); + wr->status = BEGINING; + guththila_write(wr, "/>", 2u, env); + } + else if(wr->status != BEGINING) + { + return GUTHTHILA_FAILURE; + } + while(len > 0) + { + size_t i = 0; + /* scan buffer until the next special character (&, <, >, ', ") these need to be escaped, + * otherwise XML will not be valid*/ + guththila_char_t *pos = (guththila_char_t*)strpbrk(buff, "&<>'\""); + if(pos) + { + i = pos - buff; + } + else + { + i = len; + } + + /* write everything until the special character */ + if(i > 0) + { + guththila_write(wr, buff, i, env); + buff += i; + len -= i; + } + /* replace the character with the appropriate sequence */ + if(len > 0) + { + if(AXIS2_SUCCESS != guththila_write_escape_character(wr, buff, env)) + return GUTHTHILA_FAILURE; + /* skip the character */ + buff++; + len--; + } + } + return GUTHTHILA_SUCCESS; +} + +GUTHTHILA_EXPORT int GUTHTHILA_CALL +guththila_write_comment( + guththila_xml_writer_t * wr, + guththila_char_t *buff, + const axutil_env_t * env) +{ + if(wr->status == START) + { + wr->status = BEGINING; + guththila_write(wr, ">", 3u, env); + return GUTHTHILA_SUCCESS; + } + else if(wr->status == START_EMPTY) + { + guththila_free_empty_element(wr, env); + wr->status = BEGINING; + guththila_write(wr, "/>", 3u, env); + return GUTHTHILA_SUCCESS; + } + else if(wr->status == BEGINING) + { + guththila_write(wr, "", 3u, env); + return GUTHTHILA_SUCCESS; + } + return GUTHTHILA_FAILURE; +} + +GUTHTHILA_EXPORT int GUTHTHILA_CALL +guththila_write_escape_character( + guththila_xml_writer_t * wr, + guththila_char_t *buff, + const axutil_env_t * env) +{ + if(buff) + { + switch(buff[0]) + { + case '>': + guththila_write(wr, ">", 4u, env); + break; + case '<': + guththila_write(wr, "<", 4u, env); + break; + case '\'': + guththila_write(wr, "'", 6u, env); + break; + case '"': + guththila_write(wr, """, 6u, env); + break; + case '&': + guththila_write(wr, "&", 5u, env); + break; + default: + return GUTHTHILA_FAILURE; + }; + } + return GUTHTHILA_SUCCESS; +} + +GUTHTHILA_EXPORT int GUTHTHILA_CALL +guththila_write_empty_element( + guththila_xml_writer_t * wr, + guththila_char_t *start_element, + const axutil_env_t * env) +{ + int cur_pos = 0; + size_t len = 0; + guththila_xml_writer_element_t * element = (guththila_xml_writer_element_t *)AXIS2_MALLOC( + env->allocator, sizeof(guththila_xml_writer_element_t)); + len = strlen(start_element); + if(wr->status == START) + { + guththila_write(wr, "><", 2u, env); + cur_pos = wr->next; + guththila_write_xtoken(wr, start_element, len, env); + } + else if(wr->status == START_EMPTY) + { + guththila_free_empty_element(wr, env); + wr->status = BEGINING; + guththila_write(wr, "/><", 3u, env); + cur_pos = wr->next; + guththila_write_xtoken(wr, start_element, len, env); + } + else if(wr->status == BEGINING) + { + guththila_write(wr, "<", 1u, env); + cur_pos = wr->next; + guththila_write_xtoken(wr, start_element, len, env); + } + else + { + return GUTHTHILA_FAILURE; + } + wr->status = START_EMPTY; + +#ifndef GUTHTHILA_XML_WRITER_TOKEN + element->name = strdup(start_element); + element->prefix = NULL; +#else + element->name = guththila_tok_list_get_token(&wr->tok_list, env); + element->name->start = GUTHTHILA_BUF_POS(wr->buffer, cur_pos); + element->name->size = len; + element->prefix = NULL; + +#endif + element->name_sp_stack_no = -1; + return guththila_stack_push(&wr->element, element, env); +} + +GUTHTHILA_EXPORT int GUTHTHILA_CALL +guththila_write_default_namespace( + guththila_xml_writer_t * wr, + guththila_char_t *namespace_uri, + const axutil_env_t * env) +{ + if(wr->status == START || wr->status == START_EMPTY) + { + guththila_write(wr, " xmlns=\"", 8u, env); + guththila_write(wr, namespace_uri, strlen(namespace_uri), env); + guththila_write(wr, "\"", 1u, env); + return GUTHTHILA_SUCCESS; + } + return GUTHTHILA_FAILURE; +} + +GUTHTHILA_EXPORT int GUTHTHILA_CALL +guththila_write_namespace( + guththila_xml_writer_t * wr, + guththila_char_t *prefix, + guththila_char_t *uri, + const axutil_env_t * env) +{ + int i, j, temp, nmsp_found = GUTHTHILA_FALSE, stack_size; + guththila_xml_writer_namesp_t * namesp = NULL; + guththila_xml_writer_element_t * elem = NULL; + int pref_start = 0, uri_start = 0; + guththila_char_t *pref_start_p = NULL, *uri_start_p = NULL; + guththila_xml_writer_namesp_t * writer_namesp = NULL; + guththila_token_t ** tok_name = NULL, **tok_uri = NULL; + size_t pref_len = strlen(prefix), uri_len = strlen(uri); + stack_size = GUTHTHILA_STACK_SIZE(wr->namesp); + /* Check weather we have met the namespace before */ + for(i = stack_size - 1; i >= 0; i--) + { + writer_namesp = (guththila_xml_writer_namesp_t *)guththila_stack_get_by_index(&wr->namesp, + i, env); + temp = writer_namesp->no; + for(j = 0; j < temp; j++) + { + +#ifndef GUTHTHILA_XML_WRITER_TOKEN + if(!strcmp(prefix, writer_namesp->name[j])) + { + +#else + if (!guththila_tok_str_cmp(writer_namesp->name[j], prefix, pref_len, env)) + { +#endif + nmsp_found = GUTHTHILA_TRUE; + } + } + } + /* Proceed if we didn't find the namespace */ + if(!nmsp_found && (wr->status == START || wr->status == START_EMPTY)) + { + guththila_write(wr, " xmlns:", 7u, env); + pref_start = wr->next; + guththila_write_xtoken(wr, prefix, pref_len, env); + pref_start_p = GUTHTHILA_BUF_POS(wr->buffer, pref_start); + guththila_write(wr, "=\"", 2u, env); + uri_start = wr->next; + guththila_write_xtoken(wr, uri, uri_len, env); + uri_start_p = GUTHTHILA_BUF_POS(wr->buffer, uri_start); + guththila_write(wr, "\"", 1u, env); + elem = guththila_stack_peek(&wr->element, env); + if(elem && elem->name_sp_stack_no == -1) + { + namesp = (guththila_xml_writer_namesp_t *)AXIS2_MALLOC(env->allocator, + sizeof(guththila_xml_writer_namesp_t)); + if(namesp) + { + +#ifndef GUTHTHILA_XML_WRITER_TOKEN + namesp->name = (guththila_char_t **)AXIS2_MALLOC(env->allocator, + sizeof(guththila_char_t *) * GUTHTHILA_XML_WRITER_NAMESP_DEF_SIZE); + namesp->uri = (guththila_char_t **)AXIS2_MALLOC(env->allocator, + sizeof(guththila_char_t *) * GUTHTHILA_XML_WRITER_NAMESP_DEF_SIZE); + namesp->name[0] = strdup(prefix); + namesp->uri[0] = strdup(uri); + +#else + namesp->name = + (guththila_token_t **) AXIS2_MALLOC(env->allocator, + sizeof(guththila_token_t + *) * + GUTHTHILA_XML_WRITER_NAMESP_DEF_SIZE); + namesp->uri = + (guththila_token_t **) AXIS2_MALLOC(env->allocator, + sizeof(guththila_token_t + *) * + GUTHTHILA_XML_WRITER_NAMESP_DEF_SIZE); + namesp->name[0] = guththila_tok_list_get_token(&wr->tok_list, env); + namesp->name[0]->start = pref_start_p ; + namesp->name[0]->size = pref_len; + namesp->uri[0] = guththila_tok_list_get_token(&wr->tok_list, env); + namesp->uri[0]->start = uri_start_p ; + namesp->uri[0]->size = uri_len; + +#endif + namesp->no = 1; + namesp->size = GUTHTHILA_XML_WRITER_NAMESP_DEF_SIZE; + guththila_stack_push(&wr->namesp, namesp, env); + elem->name_sp_stack_no = GUTHTHILA_STACK_TOP_INDEX(wr->namesp); + } + else + { + return GUTHTHILA_FAILURE; + } + } + else if(elem) + { + namesp = guththila_stack_peek(&wr->namesp, env); + if(namesp->no < namesp->size) + { + +#ifndef GUTHTHILA_XML_WRITER_TOKEN + namesp->name[++(namesp->no) - 1] = strdup(prefix); + namesp->uri[namesp->no - 1] = strdup(uri); + +#else + namesp->name[++(namesp->no) - 1] = guththila_tok_list_get_token(&wr->tok_list, env); + namesp->uri[namesp->no - 1] = guththila_tok_list_get_token(&wr->tok_list, env); + namesp->name[namesp->no - 1]->start = pref_start_p; + namesp->name[namesp->no - 1]->size = pref_len; + namesp->uri[namesp->no - 1]->start = uri_start_p; + namesp->uri[namesp->no - 1]->size = uri_len; + +#endif + } + else + { + +#ifndef GUTHTHILA_XML_WRITER_TOKEN + namesp->name = (guththila_char_t **)realloc(namesp->name, + sizeof(guththila_char_t *) * (GUTHTHILA_XML_WRITER_NAMESP_DEF_SIZE + + namesp->size)); + namesp->uri = (guththila_char_t **)realloc(namesp->name, sizeof(guththila_char_t *) + * (GUTHTHILA_XML_WRITER_NAMESP_DEF_SIZE + namesp->size)); + namesp->size = GUTHTHILA_XML_WRITER_NAMESP_DEF_SIZE + namesp->size; + namesp->name[++(namesp->no) - 1] = strdup(prefix); + namesp->uri[namesp->no - 1] = strdup(uri); + +#else + tok_name = + (guththila_token_t **) AXIS2_MALLOC(env->allocator, + sizeof(guththila_token_t *) * + (GUTHTHILA_XML_WRITER_NAMESP_DEF_SIZE + + namesp->size)); + tok_uri = + (guththila_token_t **) AXIS2_MALLOC(env->allocator, + sizeof(guththila_token_t *) * + (GUTHTHILA_XML_WRITER_NAMESP_DEF_SIZE + + namesp->size)); + for (i = 0; i < namesp->no; i++) + { + tok_name[i] = namesp->name[i]; + tok_uri[i] = namesp->uri[i]; + } + AXIS2_FREE(env->allocator, namesp->name); + AXIS2_FREE(env->allocator, namesp->uri); + namesp->name = tok_name; + namesp->uri = tok_uri; + namesp->size = GUTHTHILA_XML_WRITER_NAMESP_DEF_SIZE + namesp->size; + + namesp->name[namesp->no] = guththila_tok_list_get_token(&wr->tok_list, env); + namesp->uri[namesp->no] = guththila_tok_list_get_token(&wr->tok_list, env); + + namesp->name[namesp->no ]->start = pref_start_p; + namesp->name[namesp->no ]->size = pref_len; + namesp->uri[namesp->no ]->start = uri_start_p; + namesp->uri[namesp->no ]->size = uri_len; + namesp->no ++; +#endif + } + } + return GUTHTHILA_SUCCESS; + } + if(nmsp_found) + return GUTHTHILA_SUCCESS; + return GUTHTHILA_FAILURE; +} + +GUTHTHILA_EXPORT int GUTHTHILA_CALL +guththila_write_attribute( + guththila_xml_writer_t * wr, + guththila_char_t *localname, + guththila_char_t *value, + const axutil_env_t * env) +{ + if(wr->status == START || wr->status == START_EMPTY) + { + guththila_write(wr, " ", 1u, env); + guththila_write(wr, localname, strlen(localname), env); + guththila_write(wr, "=\"", 2u, env); + guththila_write(wr, value, strlen(value), env); + guththila_write(wr, "\"", 1u, env); + return GUTHTHILA_SUCCESS; + } + return GUTHTHILA_FAILURE; +} + +GUTHTHILA_EXPORT int GUTHTHILA_CALL +guththila_write_attribute_with_prefix_and_namespace( + guththila_xml_writer_t * wr, + guththila_char_t *prefix, + guththila_char_t *namespace_uri, + guththila_char_t *localname, + guththila_char_t *value, + const axutil_env_t * env) +{ + return guththila_write_namespace(wr, prefix, namespace_uri, env) + && guththila_write_attribute_with_prefix(wr, prefix, localname, value, env); +} + +GUTHTHILA_EXPORT int GUTHTHILA_CALL +guththila_write_attribute_with_prefix( + guththila_xml_writer_t * wr, + guththila_char_t *prefix, + guththila_char_t *localname, + guththila_char_t *value, + const axutil_env_t * env) +{ + int i, j; + int stack_size = GUTHTHILA_STACK_SIZE(wr->namesp); + int temp; + size_t pref_len = strlen(prefix); + guththila_xml_writer_namesp_t * writer_namesp = NULL; + if(wr->status == START || wr->status == START_EMPTY) + { + /* We need to make sure that there is a namespace defined with the + * given prefix as the name */ + for(i = stack_size - 1; i >= 0; i--) + { + writer_namesp = (guththila_xml_writer_namesp_t *)guththila_stack_get_by_index( + &wr->namesp, i, env); + temp = writer_namesp->no; + for(j = 0; j < temp; j++) + { + +#ifndef GUTHTHILA_XML_WRITER_TOKEN + if(!strcmp(prefix, writer_namesp->name[j])) + { + +#else + if (!guththila_tok_str_cmp + (writer_namesp->name[j], prefix, pref_len, env)) + { + +#endif + guththila_write(wr, " ", 1u, env); + guththila_write(wr, prefix, pref_len, env); + guththila_write(wr, ":", 1u, env); + guththila_write(wr, localname, strlen(localname), env); + guththila_write(wr, "=\"", 2u, env); + guththila_write(wr, value, strlen(value), env); + guththila_write(wr, "\"", 1u, env); + return GUTHTHILA_SUCCESS; + } + } + } + } + return GUTHTHILA_FAILURE; +} + +GUTHTHILA_EXPORT int GUTHTHILA_CALL +guththila_write_attribute_with_namespace( + guththila_xml_writer_t * wr, + guththila_char_t *namesp, + guththila_char_t *loc_name, + guththila_char_t *value, + const axutil_env_t * env) +{ + int i, j; + int stack_size = GUTHTHILA_STACK_SIZE(wr->namesp); + int temp; + guththila_xml_writer_namesp_t * writer_namesp = NULL; + if(wr->status == START || wr->status == START_EMPTY) + { + /* We need to make sure that the namespace is previously declared */ + for(i = stack_size - 1; i >= 0; i--) + { + writer_namesp = (guththila_xml_writer_namesp_t *)guththila_stack_get_by_index( + &wr->namesp, i, env); + temp = writer_namesp->no; + for(j = 0; j < temp; j++) + { +#ifndef GUTHTHILA_XML_WRITER_TOKEN + if(!strcmp(namesp, writer_namesp->uri[j])) + { + guththila_write(wr, " ", 1, env); + guththila_write(wr, writer_namesp->name[j], strlen(writer_namesp->name[j]), env); +#else + if (!guththila_tok_str_cmp + (writer_namesp->uri[j], namesp, strlen(namesp), env)) + { + guththila_write(wr, " ", 1u, env); + guththila_write_token(wr, writer_namesp->name[j], env); +#endif + guththila_write(wr, ":", 1u, env); + guththila_write(wr, loc_name, strlen(loc_name), env); + guththila_write(wr, "=\"", 2u, env); + guththila_write(wr, value, strlen(value), env); + guththila_write(wr, "\"", 1u, env); + return GUTHTHILA_SUCCESS; + } + } + } + } + return GUTHTHILA_FAILURE; +} + +GUTHTHILA_EXPORT int GUTHTHILA_CALL +guththila_write_start_element_with_prefix_and_namespace( + guththila_xml_writer_t * wr, + guththila_char_t *prefix, + guththila_char_t *namespace_uri, + guththila_char_t *local_name, + const axutil_env_t * env) +{ + int i, j, temp, stack_size, nmsp_found = GUTHTHILA_FALSE; + guththila_xml_writer_namesp_t * namesp = NULL; + guththila_xml_writer_element_t * elem = NULL; + int uri_start = 0, pref_start = 0, elem_start = 0, elem_pref_start = 0; + guththila_char_t *uri_start_p = NULL, *pref_start_p = NULL; + guththila_char_t *elem_start_p = NULL, *elem_pref_start_p = NULL ; + size_t uri_len = 0; + size_t pref_len = 0; + size_t elem_len = 0; + guththila_xml_writer_namesp_t * writer_namesp = NULL; + + elem = (guththila_xml_writer_element_t *)AXIS2_MALLOC(env->allocator, + sizeof(guththila_xml_writer_element_t)); + uri_len = strlen(namespace_uri); + pref_len = strlen(prefix); + elem_len = strlen(local_name); + stack_size = GUTHTHILA_STACK_SIZE(wr->namesp); + /* We have to determine weather we have seen the namespace before */ + for(i = stack_size - 1; i >= 0; i--) + { + writer_namesp = (guththila_xml_writer_namesp_t *)guththila_stack_get_by_index(&wr->namesp, + i, env); + temp = writer_namesp->no; + for(j = 0; j < temp; j++) + { +#ifndef GUTHTHILA_XML_WRITER_TOKEN + if(!strcmp(uri, writer_namesp->uri[j])) + { + +#else + if (!guththila_tok_str_cmp + (writer_namesp->name[j], prefix, pref_len, env)) + { + +#endif + nmsp_found = GUTHTHILA_TRUE; + } + } + } + if(elem) + { + elem->name_sp_stack_no = -1; + if(wr->status == START) + { + guththila_write(wr, "><", 2u, env); + elem_pref_start = wr->next; + guththila_write_xtoken(wr, prefix, pref_len, env); + elem_pref_start_p = GUTHTHILA_BUF_POS(wr->buffer, elem_pref_start); + guththila_write(wr, ":", 1u, env); + elem_start = wr->next; + guththila_write_xtoken(wr, local_name, elem_len, env); + elem_start_p = GUTHTHILA_BUF_POS(wr->buffer, elem_start); + if(!nmsp_found) + { + guththila_write(wr, " ", 1u, env); + guththila_write(wr, "xmlns:", 6u, env); + pref_start = wr->next; + guththila_write_xtoken(wr, prefix, pref_len, env); + pref_start_p = GUTHTHILA_BUF_POS(wr->buffer, pref_start); + guththila_write(wr, "=\"", 2u, env); + uri_start = wr->next; + guththila_write_xtoken(wr, namespace_uri, uri_len, env); + uri_start_p = GUTHTHILA_BUF_POS(wr->buffer, uri_start); + guththila_write(wr, "\"", 1u, env); + } + } + else if(wr->status == START_EMPTY) + { + guththila_free_empty_element(wr, env); + guththila_write(wr, "/><", 2u, env); + elem_pref_start = wr->next; + guththila_write_xtoken(wr, prefix, pref_len, env); + elem_pref_start_p = GUTHTHILA_BUF_POS(wr->buffer, elem_pref_start); + guththila_write(wr, ":", 1u, env); + elem_start = wr->next; + guththila_write_xtoken(wr, local_name, elem_len, env); + elem_start_p = GUTHTHILA_BUF_POS(wr->buffer, elem_start); + if(!nmsp_found) + { + guththila_write(wr, " ", 1u, env); + guththila_write(wr, "xmlns:", 6u, env); + pref_start = wr->next; + guththila_write_xtoken(wr, prefix, pref_len, env); + pref_start_p = GUTHTHILA_BUF_POS(wr->buffer, pref_start); + guththila_write(wr, "=\"", 2u, env); + uri_start = wr->next; + guththila_write_xtoken(wr, namespace_uri, uri_len, env); + uri_start_p = GUTHTHILA_BUF_POS(wr->buffer, uri_start); + guththila_write(wr, "\"", 1u, env); + } + wr->status = START; + } + else if(wr->status == BEGINING) + { + guththila_write(wr, "<", 1u, env); + elem_pref_start = wr->next; + guththila_write_xtoken(wr, prefix, pref_len, env); + elem_pref_start_p = GUTHTHILA_BUF_POS(wr->buffer, elem_pref_start); + guththila_write(wr, ":", 1u, env); + elem_start = wr->next; + guththila_write_xtoken(wr, local_name, elem_len, env); + elem_start_p = GUTHTHILA_BUF_POS(wr->buffer, elem_start); + if(!nmsp_found) + { + guththila_write(wr, " ", 1u, env); + guththila_write(wr, "xmlns:", 6u, env); + pref_start = wr->next; + guththila_write_xtoken(wr, prefix, pref_len, env); + pref_start_p = GUTHTHILA_BUF_POS(wr->buffer, pref_start); + guththila_write(wr, "=\"", 2u, env); + uri_start = wr->next; + guththila_write_xtoken(wr, namespace_uri, uri_len, env); + uri_start_p = GUTHTHILA_BUF_POS(wr->buffer, uri_start); + guththila_write(wr, "\"", 1u, env); + } + wr->status = START; + } + else + { + return GUTHTHILA_FAILURE; + } + if(!nmsp_found) + { + /* If this namespace not defined previously we need to add it */ + namesp = (guththila_xml_writer_namesp_t *)AXIS2_MALLOC(env->allocator, + sizeof(guththila_xml_writer_namesp_t)); + +#ifndef GUTHTHILA_XML_WRITER_TOKEN + namesp->name = (guththila_char_t **)AXIS2_MALLOC(env->allocator, + sizeof(guththila_char_t *) * GUTHTHILA_XML_WRITER_NAMESP_DEF_SIZE); + namesp->uri = (guththila_char_t **)AXIS2_MALLOC(env->allocator, + sizeof(guththila_char_t *) * GUTHTHILA_XML_WRITER_NAMESP_DEF_SIZE); + namesp->name[0] = strdup(prefix); + namesp->uri[0] = strdup(namespace_uri); + +#else + namesp->name = + (guththila_token_t **) AXIS2_MALLOC(env->allocator, + sizeof(guththila_token_t *) + * + GUTHTHILA_XML_WRITER_NAMESP_DEF_SIZE); + namesp->uri = + (guththila_token_t **) AXIS2_MALLOC(env->allocator, + sizeof(guththila_token_t *) + * + GUTHTHILA_XML_WRITER_NAMESP_DEF_SIZE); + namesp->name[0] = guththila_tok_list_get_token(&wr->tok_list, env); + namesp->name[0]->start = pref_start_p; + namesp->name[0]->size = pref_len; + namesp->uri[0] = guththila_tok_list_get_token(&wr->tok_list, env); + namesp->uri[0]->start = uri_start_p; + namesp->uri[0]->size = uri_len; +#endif + namesp->no = 1; + namesp->size = GUTHTHILA_XML_WRITER_NAMESP_DEF_SIZE; + guththila_stack_push(&wr->namesp, namesp, env); + elem->name_sp_stack_no = GUTHTHILA_STACK_TOP_INDEX(wr->namesp); + } + +#ifndef GUTHTHILA_XML_WRITER_TOKEN + elem->name = strdup(local_name); + elem->prefix = strdup(prefix); +#else + elem->name = guththila_tok_list_get_token(&wr->tok_list, env); + elem->prefix = guththila_tok_list_get_token(&wr->tok_list, env); + elem->name->start = elem_start_p; + elem->name->size = elem_len; + elem->prefix->start = elem_pref_start_p; + elem->prefix->size = pref_len; +#endif + guththila_stack_push(&wr->element, elem, env); + } + else + { + return GUTHTHILA_FAILURE; + } + return GUTHTHILA_SUCCESS; +} + +GUTHTHILA_EXPORT int GUTHTHILA_CALL +guththila_write_start_element_with_namespace( + guththila_xml_writer_t * wr, + guththila_char_t *namespace_uri, + guththila_char_t *local_name, + const axutil_env_t * env) +{ + int i = 0, j = 0; + int stack_size = GUTHTHILA_STACK_SIZE(wr->namesp); + int temp = 0; + int elem_start = 0; + guththila_char_t *elem_start_p = NULL; + size_t elem_len = 0; + guththila_xml_writer_namesp_t * writer_namesp = NULL; + guththila_xml_writer_element_t * element; + + elem_len = strlen(local_name); + element = (guththila_xml_writer_element_t *)AXIS2_MALLOC(env->allocator, + sizeof(guththila_xml_writer_element_t)); + if(!element) + return GUTHTHILA_FAILURE; + + for(i = stack_size - 1; i >= 0; i--) + { + writer_namesp = (guththila_xml_writer_namesp_t *)guththila_stack_get_by_index(&wr->namesp, + i, env); + temp = writer_namesp->no; + for(j = 0; j < temp; j++) + { +#ifndef GUTHTHILA_XML_WRITER_TOKEN + if(!strcmp(namespace_uri, writer_namesp->uri[j])) +#else + if (!guththila_tok_str_cmp + (writer_namesp->uri[j], namespace_uri, + strlen(namespace_uri), env)) +#endif + { + i = 0; /* force exit from outer loop as well */ + break; + } + } + } + + /* Close off any preceding element and start a new element */ + if(wr->status == START) + { + guththila_write(wr, "><", 2u, env); + } + else if(wr->status == START_EMPTY) + { + guththila_free_empty_element(wr, env); + guththila_write(wr, "/><", 2u, env); + } + else if(wr->status == BEGINING) + { + guththila_write(wr, "<", 1u, env); + } + else + { + return GUTHTHILA_FAILURE; + } + /* If there is a prefix, include it. */ + if(writer_namesp && (j < writer_namesp->no)) + { +#ifndef GUTHTHILA_XML_WRITER_TOKEN + guththila_write(wr, writer_namesp->name[j], strlen(writer_namesp->name[j]), env); +#else + guththila_write_token(wr, writer_namesp->name[j], env); +#endif + guththila_write(wr, ":", 1u, env); + } + elem_start = wr->next; + guththila_write_xtoken(wr, local_name, elem_len, env); + elem_start_p = GUTHTHILA_BUF_POS(wr->buffer, elem_start); + + /* Remember this element's name and prefix, so the closing tag can be written later. */ +#ifndef GUTHTHILA_XML_WRITER_TOKEN + element->name = strdup(local_name); + if(writer_namesp && (j < writer_namesp->no)) + { + element->prefix = strdup(writer_namesp->name[j]); + } + else + { + element->prefix = NULL; + } + +#else + element->name = + guththila_tok_list_get_token(&wr->tok_list, env); + element->name->size = elem_len; + element->name->start = elem_start_p; + if (writer_namesp && (j < writer_namesp->no)) + { + element->prefix = + guththila_tok_list_get_token(&wr->tok_list, env); + element->prefix->size = writer_namesp->name[j]->size; + element->prefix->start = writer_namesp->name[j]->start; + } + else + { + element->prefix = NULL; + } +#endif + + element->name_sp_stack_no = -1; + wr->status = START; + return guththila_stack_push(&wr->element, element, env); +} + +GUTHTHILA_EXPORT int GUTHTHILA_CALL +guththila_write_start_element_with_prefix( + guththila_xml_writer_t * wr, + guththila_char_t *prefix, + guththila_char_t *local_name, + const axutil_env_t * env) +{ + int i, j; + int stack_size = GUTHTHILA_STACK_SIZE(wr->namesp); + int temp; + int elem_start = 0; + guththila_char_t *elem_start_p = NULL; + size_t elem_len = 0, pref_len = 0; + guththila_xml_writer_namesp_t * writer_namesp = NULL; + elem_len = strlen(local_name); + pref_len = strlen(prefix); + for(i = stack_size - 1; i >= 0; i--) + { + writer_namesp = (guththila_xml_writer_namesp_t *)guththila_stack_get_by_index(&wr-> namesp, + i, env); + temp = writer_namesp->no; + for(j = 0; j < temp; j++) + { + /* if we found a namespace with the given prefix we can proceed */ +#ifndef GUTHTHILA_XML_WRITER_TOKEN + if(!strcmp(prefix, writer_namesp->name[j])) + { +#else + if (!guththila_tok_str_cmp(writer_namesp->name[j], + prefix, pref_len, env)) + { +#endif + guththila_xml_writer_element_t * element = + (guththila_xml_writer_element_t *)AXIS2_MALLOC(env-> allocator, + sizeof(guththila_xml_writer_element_t)); + if(wr->status == START) + { + guththila_write(wr, "><", 2u, env); + guththila_write_xtoken(wr, prefix, pref_len, env); + guththila_write(wr, ":", 1u, env); + elem_start = wr->next; + guththila_write_xtoken(wr, local_name, strlen(local_name), env); + elem_start_p = GUTHTHILA_BUF_POS(wr->buffer, elem_start); + } + else if(wr->status == START_EMPTY) + { + guththila_free_empty_element(wr, env); + guththila_write(wr, "/><", 3u, env); + guththila_write_xtoken(wr, prefix, pref_len, env); + guththila_write(wr, ":", 1u, env); + elem_start = wr->next; + guththila_write_xtoken(wr, local_name, strlen(local_name), env); + elem_start_p = GUTHTHILA_BUF_POS(wr->buffer, elem_start); + } + else if(wr->status == BEGINING) + { + guththila_write(wr, "<", 1u, env); + guththila_write_xtoken(wr, prefix, pref_len, env); + guththila_write(wr, ":", 1u, env); + elem_start = wr->next; + guththila_write_xtoken(wr, local_name, strlen(local_name), env); + elem_start_p = GUTHTHILA_BUF_POS(wr->buffer, elem_start); + } + else + { + return GUTHTHILA_FAILURE; + } + +#ifndef GUTHTHILA_XML_WRITER_TOKEN + element->name = strdup(local_name); + element->prefix = strdup(prefix); +#else + element->name = + guththila_tok_list_get_token(&wr->tok_list, env); + element->name->size = elem_len; + element->name->start = elem_start_p; + element->prefix = guththila_tok_list_get_token(&wr->tok_list, env); + element->prefix->size = writer_namesp->name[j]->size; + element->prefix->start = writer_namesp->name[j]->start; +#endif + wr->status = START; + element->name_sp_stack_no = -1; + return guththila_stack_push(&wr->element, element, env); + } + } + } + return GUTHTHILA_FAILURE; +} + +GUTHTHILA_EXPORT int GUTHTHILA_CALL +guththila_write_empty_element_with_prefix_and_namespace( + guththila_xml_writer_t * wr, + guththila_char_t *prefix, + guththila_char_t *namespace_uri, + guththila_char_t *local_name, + const axutil_env_t * env) +{ + int i, j, temp, stack_size, nmsp_found = GUTHTHILA_FALSE; + guththila_xml_writer_namesp_t * namesp = NULL; + guththila_xml_writer_element_t * elem = NULL; + int uri_start = 0, pref_start = 0, elem_start = 0, elem_pref_start = 0; + guththila_char_t *uri_start_p = NULL, *pref_start_p = NULL; + guththila_char_t *elem_start_p = NULL, *elem_pref_start_p = NULL ; + size_t uri_len = 0; + size_t pref_len = 0; + size_t elem_len = 0; + guththila_xml_writer_namesp_t * writer_namesp = NULL; + + namesp = (guththila_xml_writer_namesp_t *)AXIS2_MALLOC(env->allocator, + sizeof(guththila_xml_writer_namesp_t)); + elem = (guththila_xml_writer_element_t *)AXIS2_MALLOC(env->allocator, + sizeof(guththila_xml_writer_element_t)); + uri_len = strlen(namespace_uri); + pref_len = strlen(prefix); + elem_len = strlen(local_name); + stack_size = GUTHTHILA_STACK_SIZE(wr->namesp); + /* Chech weather we have defined this namespace before */ + for(i = stack_size - 1; i >= 0; i--) + { + writer_namesp = (guththila_xml_writer_namesp_t *)guththila_stack_get_by_index(&wr->namesp, + i, env); + temp = writer_namesp->no; + for(j = 0; j < temp; j++) + { +#ifndef GUTHTHILA_XML_WRITER_TOKEN + if(!strcmp(uri, writer_namesp->uri[j])) + { + +#else + if (!guththila_tok_str_cmp + (writer_namesp->name[j], prefix, pref_len, env)) + { + +#endif + nmsp_found = GUTHTHILA_TRUE; + } + } + } + if(namesp && elem) + { + elem->name_sp_stack_no = -1; + if(wr->status == START) + { + guththila_write(wr, "><", 2u, env); + elem_pref_start = wr->next; + guththila_write_xtoken(wr, prefix, pref_len, env); + elem_pref_start_p = GUTHTHILA_BUF_POS(wr->buffer, elem_pref_start); + guththila_write(wr, ":", 1u, env); + elem_start = wr->next; + guththila_write_xtoken(wr, local_name, elem_len, env); + elem_start_p = GUTHTHILA_BUF_POS(wr->buffer, elem_start); + if(!nmsp_found) + { + guththila_write(wr, " ", 1u, env); + guththila_write(wr, "xmlns:", 6u, env); + pref_start = wr->next; + guththila_write_xtoken(wr, prefix, pref_len, env); + pref_start_p = GUTHTHILA_BUF_POS(wr->buffer, pref_start); + guththila_write(wr, "=\"", 2u, env); + uri_start = wr->next; + guththila_write_xtoken(wr, namespace_uri, uri_len, env); + uri_start_p = GUTHTHILA_BUF_POS(wr->buffer, uri_start); + guththila_write(wr, "\"", 1u, env); + } + wr->status = START_EMPTY; + } + else if(wr->status == START_EMPTY) + { + guththila_free_empty_element(wr, env); + guththila_write(wr, "/><", 2u, env); + elem_pref_start = wr->next; + guththila_write_xtoken(wr, prefix, pref_len, env); + elem_pref_start_p = GUTHTHILA_BUF_POS(wr->buffer, elem_pref_start); + guththila_write(wr, ":", 1u, env); + elem_start = wr->next; + guththila_write_xtoken(wr, local_name, elem_len, env); + elem_start_p = GUTHTHILA_BUF_POS(wr->buffer, elem_start); + if(!nmsp_found) + { + guththila_write(wr, " ", 1u, env); + guththila_write(wr, "xmlns:", 6u, env); + pref_start = wr->next; + guththila_write_xtoken(wr, prefix, pref_len, env); + pref_start_p = GUTHTHILA_BUF_POS(wr->buffer, pref_start); + guththila_write(wr, "=\"", 2u, env); + uri_start = wr->next; + guththila_write_xtoken(wr, namespace_uri, uri_len, env); + uri_start_p = GUTHTHILA_BUF_POS(wr->buffer, uri_start); + guththila_write(wr, "\"", 1u, env); + } + } + else if(wr->status == BEGINING) + { + guththila_write(wr, "<", 1u, env); + elem_pref_start = wr->next; + guththila_write_xtoken(wr, prefix, pref_len, env); + elem_pref_start_p = GUTHTHILA_BUF_POS(wr->buffer, elem_pref_start); + guththila_write(wr, ":", 1u, env); + elem_start = wr->next; + guththila_write_xtoken(wr, local_name, elem_len, env); + elem_start_p = GUTHTHILA_BUF_POS(wr->buffer, elem_start); + if(!nmsp_found) + { + guththila_write(wr, " ", 1u, env); + guththila_write(wr, "xmlns:", 6u, env); + pref_start = wr->next; + guththila_write_xtoken(wr, prefix, pref_len, env); + pref_start_p = GUTHTHILA_BUF_POS(wr->buffer, pref_start); + guththila_write(wr, "=\"", 2u, env); + uri_start = wr->next; + guththila_write_xtoken(wr, namespace_uri, uri_len, env); + uri_start_p = GUTHTHILA_BUF_POS(wr->buffer, uri_start); + guththila_write(wr, "\"", 1u, env); + } + wr->status = START_EMPTY; + } + else + { + return GUTHTHILA_FAILURE; + } + if(!nmsp_found) + { + /* If the namespace is not defined we need to remember it for later*/ +#ifndef GUTHTHILA_XML_WRITER_TOKEN + namesp->name = (guththila_char_t **)AXIS2_MALLOC(env->allocator, + sizeof(guththila_char_t *) * GUTHTHILA_XML_WRITER_NAMESP_DEF_SIZE); + namesp->uri = (guththila_char_t **)AXIS2_MALLOC(env->allocator, + sizeof(guththila_char_t *) * GUTHTHILA_XML_WRITER_NAMESP_DEF_SIZE); + namesp->name[0] = strdup(prefix); + namesp->uri[0] = strdup(namespace_uri); + +#else + namesp->name = + (guththila_token_t **) AXIS2_MALLOC(env->allocator, + sizeof(guththila_token_t *) + * + GUTHTHILA_XML_WRITER_NAMESP_DEF_SIZE); + namesp->uri = + (guththila_token_t **) AXIS2_MALLOC(env->allocator, + sizeof(guththila_token_t *) + * + GUTHTHILA_XML_WRITER_NAMESP_DEF_SIZE); + namesp->name[0] = guththila_tok_list_get_token(&wr->tok_list, env); + namesp->name[0]->start = pref_start_p; + namesp->name[0]->size = pref_len; + namesp->uri[0] = guththila_tok_list_get_token(&wr->tok_list, env); + namesp->uri[0]->start = uri_start_p; + namesp->uri[0]->size = uri_len; +#endif + namesp->no = 1; + namesp->size = GUTHTHILA_XML_WRITER_NAMESP_DEF_SIZE; + guththila_stack_push(&wr->namesp, namesp, env); + elem->name_sp_stack_no = GUTHTHILA_STACK_TOP_INDEX(wr->namesp); + } + +#ifndef GUTHTHILA_XML_WRITER_TOKEN + elem->name = strdup(local_name); + elem->prefix = strdup(prefix); +#else + elem->name = guththila_tok_list_get_token(&wr->tok_list, env); + elem->prefix = guththila_tok_list_get_token(&wr->tok_list, env); + elem->name->start = elem_start_p; + elem->name->size = elem_len; + elem->prefix->start = elem_pref_start_p; + elem->prefix->size = pref_len; +#endif + guththila_stack_push(&wr->element, elem, env); + } + return GUTHTHILA_SUCCESS; +} + +GUTHTHILA_EXPORT int GUTHTHILA_CALL +guththila_write_empty_element_with_namespace( + guththila_xml_writer_t * wr, + guththila_char_t *namespace_uri, + guththila_char_t *local_name, + const axutil_env_t * env) +{ + int i = 0, j = 0; + int stack_size = GUTHTHILA_STACK_SIZE(wr->namesp); + int temp = 0; + int elem_start = 0; + guththila_char_t *elem_start_p = NULL; + size_t elem_len = 0; + guththila_xml_writer_namesp_t * writer_namesp = NULL; + guththila_xml_writer_element_t * element; + + elem_len = strlen(local_name); + element = (guththila_xml_writer_element_t *)AXIS2_MALLOC(env->allocator, + sizeof(guththila_xml_writer_element_t)); + if(!element) + return GUTHTHILA_FAILURE; + + for(i = stack_size - 1; i >= 0; i--) + { + writer_namesp = (guththila_xml_writer_namesp_t *)guththila_stack_get_by_index(&wr->namesp, + i, env); + temp = writer_namesp->no; + for(j = 0; j < temp; j++) + { +#ifndef GUTHTHILA_XML_WRITER_TOKEN + if(!strcmp(namespace_uri, writer_namesp->uri[j])) +#else + if (!guththila_tok_str_cmp + (writer_namesp->uri[j], namespace_uri, + strlen(namespace_uri), env)) +#endif + { + i = 0; /* force exit from outer loop as well */ + break; + } + } + } + + /* Close off any preceding element and start a new element */ + if(wr->status == START) + { + guththila_write(wr, "><", 2u, env); + } + else if(wr->status == START_EMPTY) + { + guththila_free_empty_element(wr, env); + guththila_write(wr, "/><", 2u, env); + } + else if(wr->status == BEGINING) + { + guththila_write(wr, "<", 1u, env); + } + else + { + return GUTHTHILA_FAILURE; + } + /* If there is a prefix, include it. */ + if(writer_namesp && (j < writer_namesp->no)) + { +#ifndef GUTHTHILA_XML_WRITER_TOKEN + guththila_write(wr, writer_namesp->name[j], strlen(writer_namesp->name[j]), env); +#else + guththila_write_token(wr, writer_namesp->name[j], env); +#endif + guththila_write(wr, ":", 1u, env); + } + elem_start = wr->next; + guththila_write_xtoken(wr, local_name, elem_len, env); + elem_start_p = GUTHTHILA_BUF_POS(wr->buffer, elem_start); + + /* Remember this element's name and prefix, so the closing tag can be written later. */ +#ifndef GUTHTHILA_XML_WRITER_TOKEN + element->name = strdup(local_name); + if(writer_namesp && (j < writer_namesp->no)) + { + element->prefix = strdup(writer_namesp->name[j]); + } + else + { + element->prefix = NULL; + } + +#else + element->name = + guththila_tok_list_get_token(&wr->tok_list, env); + element->name->size = elem_len; + element->name->start = elem_start_p; + if (writer_namesp && (j < writer_namesp->no)) + { + element->prefix = + guththila_tok_list_get_token(&wr->tok_list, env); + element->prefix->size = writer_namesp->name[j]->size; + element->prefix->start = writer_namesp->name[j]->start; + } + else + { + element->prefix = NULL; + } +#endif + + element->name_sp_stack_no = -1; + wr->status = START_EMPTY; + return guththila_stack_push(&wr->element, element, env); +} + +GUTHTHILA_EXPORT int GUTHTHILA_CALL +guththila_write_empty_element_with_prefix( + guththila_xml_writer_t * wr, + guththila_char_t *prefix, + guththila_char_t *local_name, + const axutil_env_t * env) +{ + int i, j; + int stack_size = GUTHTHILA_STACK_SIZE(wr->namesp); + int temp; + int elem_start = 0; + guththila_char_t *elem_start_p = NULL ; + size_t elem_len = 0, pref_len = 0; + guththila_xml_writer_namesp_t * writer_namesp = NULL; + elem_len = strlen(local_name); + pref_len = strlen(prefix); + for(i = stack_size - 1; i >= 0; i--) + { + writer_namesp = (guththila_xml_writer_namesp_t *)guththila_stack_get_by_index(&wr-> namesp, + i, env); + temp = writer_namesp->no; + for(j = 0; j < temp; j++) + { + /* Proceed if we found the namespace */ +#ifndef GUTHTHILA_XML_WRITER_TOKEN + if(!strcmp(prefix, writer_namesp->name[j])) + { +#else + if (!guththila_tok_str_cmp(writer_namesp->name[j], + prefix, pref_len, env)) + { +#endif + guththila_xml_writer_element_t * element = + (guththila_xml_writer_element_t *)AXIS2_MALLOC(env-> allocator, + sizeof(guththila_xml_writer_element_t)); + if(wr->status == START) + { + guththila_write(wr, "><", 2u, env); + guththila_write_xtoken(wr, prefix, pref_len, env); + guththila_write(wr, ":", 1u, env); + elem_start = wr->next; + guththila_write_xtoken(wr, local_name, strlen(local_name), env); + elem_start_p = GUTHTHILA_BUF_POS(wr->buffer, elem_start); + } + else if(wr->status == START_EMPTY) + { + guththila_free_empty_element(wr, env); + guththila_write(wr, "/><", 3u, env); + guththila_write_xtoken(wr, prefix, pref_len, env); + guththila_write(wr, ":", 1u, env); + elem_start = wr->next; + guththila_write_xtoken(wr, local_name, strlen(local_name), env); + elem_start_p = GUTHTHILA_BUF_POS(wr->buffer, elem_start); + } + else if(wr->status == BEGINING) + { + guththila_write(wr, "<", 1u, env); + guththila_write_xtoken(wr, prefix, pref_len, env); + guththila_write(wr, ":", 1u, env); + elem_start = wr->next; + guththila_write_xtoken(wr, local_name, strlen(local_name), env); + elem_start_p = GUTHTHILA_BUF_POS(wr->buffer, elem_start); + } + else + { + return GUTHTHILA_FAILURE; + } + +#ifndef GUTHTHILA_XML_WRITER_TOKEN + element->name = strdup(local_name); + element->prefix = strdup(prefix); +#else + element->name = + guththila_tok_list_get_token(&wr->tok_list, env); + element->name->size = elem_len; + element->name->start = elem_start_p; + element->prefix = + guththila_tok_list_get_token(&wr->tok_list, env); + element->prefix->size = writer_namesp->name[j]->size; + element->prefix->start = writer_namesp->name[j]->start; +#endif + wr->status = START_EMPTY; + element->name_sp_stack_no = -1; + /* remember the element */ + return guththila_stack_push(&wr->element, element, env); + } + } + } + return GUTHTHILA_FAILURE; +} + +GUTHTHILA_EXPORT int GUTHTHILA_CALL +guththila_write_end_document( + guththila_xml_writer_t * wr, + const axutil_env_t * env) +{ + int i = 0; + int size = GUTHTHILA_STACK_SIZE(wr->element); + if(wr->status == START_EMPTY) + guththila_write_end_element(wr, env); + /* For all the open elements in the element stack close them */ + for(i = 0; i < size; i++) + { + if(!guththila_write_end_element(wr, env)) + { + return GUTHTHILA_FAILURE; + } + } + return GUTHTHILA_SUCCESS; +} + +GUTHTHILA_EXPORT int GUTHTHILA_CALL +guththila_write_line( + guththila_xml_writer_t * wr, + guththila_char_t *element_name, + guththila_char_t *characters, + const axutil_env_t * env) +{ + guththila_write_start_element(wr, element_name, env); + guththila_write_characters(wr, characters, env); + guththila_write_end_element(wr, env); + guththila_write_characters(wr, "\n", env); + return GUTHTHILA_FAILURE; +} + +GUTHTHILA_EXPORT guththila_char_t *GUTHTHILA_CALL +guththila_get_memory_buffer( + guththila_xml_writer_t * wr, + const axutil_env_t * env) +{ + if(wr->type == GUTHTHILA_WRITER_MEMORY) + { + return (guththila_char_t *)guththila_buffer_get(&wr->buffer, env); + } + return NULL; +} + +GUTHTHILA_EXPORT unsigned int GUTHTHILA_CALL +guththila_get_memory_buffer_size( + guththila_xml_writer_t * wr, + const axutil_env_t * env) +{ + if(wr->type == GUTHTHILA_WRITER_MEMORY) + { + return (unsigned int)(wr->buffer.pre_tot_data + wr->buffer.data_size[wr->buffer.cur_buff]); + } + return 0; +} + +GUTHTHILA_EXPORT guththila_char_t *GUTHTHILA_CALL +guththila_get_prefix_for_namespace( + guththila_xml_writer_t * wr, + guththila_char_t *nmsp, + const axutil_env_t * env) +{ + int i, j; + int stack_size = GUTHTHILA_STACK_SIZE(wr->namesp); + int temp; + guththila_char_t *str = NULL; + guththila_xml_writer_namesp_t * writer_namesp = NULL; + for(i = stack_size - 1; i >= 0; i--) + { + writer_namesp = (guththila_xml_writer_namesp_t *)guththila_stack_get_by_index(&wr-> namesp, + i, env); + temp = writer_namesp->no; + for(j = 0; j < temp; j++) + { + if(!guththila_tok_str_cmp(writer_namesp->uri[j], nmsp, strlen(nmsp), env)) + { + GUTHTHILA_TOKEN_TO_STRING(writer_namesp->uri[j], str, env); + return str; + } + } + } + return NULL; +} + +GUTHTHILA_EXPORT int GUTHTHILA_CALL +guththila_write_to_buffer( + guththila_xml_writer_t * wr, + guththila_char_t *buff, + int size, + const axutil_env_t * env) +{ + /* Just write what ever given. But need to close things before */ + if(wr->status == START) + { + guththila_write(wr, ">", 1u, env); + } + if(wr->status == START_EMPTY) + { + guththila_write(wr, "/>", 2u, env); + } + guththila_write(wr, buff, size, env); + wr->status = BEGINING; + return GUTHTHILA_SUCCESS; +} + diff --git a/guththila/tests/resources/om b/guththila/tests/resources/om new file mode 120000 index 0000000..3bd0c61 --- /dev/null +++ b/guththila/tests/resources/om @@ -0,0 +1 @@ +../../../axiom/test/resources/xml/om/ \ No newline at end of file diff --git a/guththila/tests/resources/soap b/guththila/tests/resources/soap new file mode 120000 index 0000000..9674db5 --- /dev/null +++ b/guththila/tests/resources/soap @@ -0,0 +1 @@ +../../../axiom/test/resources/xml/soap \ No newline at end of file diff --git a/guththila/tests/s b/guththila/tests/s new file mode 100755 index 0000000..7e9f4f8 --- /dev/null +++ b/guththila/tests/s @@ -0,0 +1,13 @@ +#!/usr/bin/perl -w +use strict; + +if ($ARGV[0] == 1) +{ + print "compiling writer\n"; + system "gcc -Wall -g3 -O0 -o writer guththila_writer_main.c -L\$AXIS2C_HOME/lib -I\$AXIS2C_HOME/include -lguththila -laxis2_util"; +} +else +{ + print "compiling reader tests \n"; + system "gcc -Wall -g3 -O0 -o reader *.c \-L\$AXIS2C_HOME/lib \-I\$AXIS2C_HOME/include -lcheck -lguththila \-laxis2_util"; +} diff --git a/guththila/tests/test.c b/guththila/tests/test.c new file mode 100644 index 0000000..cebbe02 --- /dev/null +++ b/guththila/tests/test.c @@ -0,0 +1,200 @@ +#include +#include +#include "guththila_defines.h" +#include "test.h" + +void +setup( + void) +{ + allocator = axutil_allocator_init(NULL); + env = axutil_env_create(allocator); +} + +void +teardown( + void) +{ + guththila_reader_free(env, red); + guththila_free(env, parser); + axutil_env_free(env); +} + +START_TEST(test_guththila) +{ + red = guththila_reader_create_for_file(env, "resources/om/axis.xml"); + parser = guththila_create(env, red); + fail_if(red == NULL, "guththila reader failed"); + fail_if(parser == NULL, "guththila parser failed"); +} + +END_TEST +START_TEST( + test_guththila_start_element) +{ + int c = 0; + char *p; + red = guththila_reader_create_for_file(env, "resources/om/axis.xml"); + parser = guththila_create(env, red); + guththila_read(env, parser); + c = guththila_next(env, parser); + + while((c != GUTHTHILA_START_ELEMENT)) + c = guththila_next(env, parser); + p = guththila_get_name(env, parser); + fail_unless((c == GUTHTHILA_START_ELEMENT), "no start element found"); + fail_if((p == NULL), "no name found"); + fail_unless(!strcmp(p, "root"), "root element differed"); + c = 0; + + while((c != GUTHTHILA_START_ELEMENT)) + c = guththila_next(env, parser); + p = guththila_get_name(env, parser); + fail_unless((c == GUTHTHILA_START_ELEMENT), "no start element found"); + fail_if((p == NULL), "no name found"); + fail_unless(!strcmp(p, "a"), "a element differed"); + + c = 0; + while((c != GUTHTHILA_START_ELEMENT)) + c = guththila_next(env, parser); + p = guththila_get_name(env, parser); + fail_unless(!strcmp(p, "b"), "b element differed"); +} + +END_TEST +START_TEST( + test_guththila_empty_element) +{ + int c = 0; + char *p; + red = guththila_reader_create_for_file(env, "resources/om/axis.xml"); + parser = guththila_create(env, red); + guththila_read(env, parser); + c = guththila_next(env, parser); + + while((c != GUTHTHILA_EMPTY_ELEMENT)) + c = guththila_next(env, parser); + p = guththila_get_name(env, parser); + fail_unless((c == GUTHTHILA_EMPTY_ELEMENT), "no empty element found"); + fail_if((p == NULL), "no name found"); + fail_unless(!strcmp(p, "a.1"), "a.1 element differed"); + + c = 0; + + while((c != GUTHTHILA_EMPTY_ELEMENT)) + c = guththila_next(env, parser); + p = guththila_get_name(env, parser); + fail_unless((c == GUTHTHILA_EMPTY_ELEMENT), "no empty element found"); + fail_if((p == NULL), "no name found"); + fail_unless(!strcmp(p, "a.2"), "a.2 element differed"); + + c = 0; + while((c != GUTHTHILA_START_ELEMENT)) + c = guththila_next(env, parser); + + c = 0; + while((c != GUTHTHILA_EMPTY_ELEMENT)) + c = guththila_next(env, parser); + p = guththila_get_name(env, parser); + fail_unless((c == GUTHTHILA_EMPTY_ELEMENT), "no empty element found"); + fail_if((p == NULL), "no name found"); + fail_unless(!strcmp(p, "b.1"), "b.1 element differed"); +} + +END_TEST +START_TEST( + test_guththila_end_element) +{ + int c = 0; + char *p; + red = guththila_reader_create_for_file(env, "resources/om/axis.xml"); + parser = guththila_create(env, red); + guththila_read(env, parser); + c = guththila_next(env, parser); + + while((c != GUTHTHILA_END_ELEMENT)) + c = guththila_next(env, parser); + p = guththila_get_name(env, parser); + fail_unless((c == GUTHTHILA_END_ELEMENT), "no end element found"); + fail_if((p == NULL), "no name found"); + fail_unless(!strcmp(p, "a"), "a element differed"); + + c = 0; + while((c != GUTHTHILA_END_ELEMENT)) + c = guththila_next(env, parser); + p = guththila_get_name(env, parser); + fail_unless((c == GUTHTHILA_END_ELEMENT), "no endelement found"); + fail_if((p == NULL), "no name found"); + fail_unless(!strcmp(p, "b"), "b element differed"); + + c = 0; + while((c != GUTHTHILA_END_ELEMENT)) + c = guththila_next(env, parser); + p = guththila_get_name(env, parser); + fail_unless((c == GUTHTHILA_END_ELEMENT), "no empty element found"); + fail_if((p == NULL), "no name found"); + fail_unless(!strcmp(p, "root"), "root element differed"); +} + +END_TEST +START_TEST( + test_guththila_character) +{ + int c = 0; + int i = 0; + char *p; + red = guththila_reader_create_for_file(env, "resources/om/numbers.xml"); + parser = guththila_create(env, red); + guththila_read(env, parser); + c = guththila_next(env, parser); + while(i < 3) + { + if(c == GUTHTHILA_START_ELEMENT) + i++; + c = guththila_next(env, parser); + } + + if(c == GUTHTHILA_CHARACTER) + p = guththila_get_value(env, parser); + fail_unless(!strcmp(p, "3"), "3 not found"); + + c = 0; + while((c != GUTHTHILA_CHARACTER) || (parser->is_whitespace)) + c = guththila_next(env, parser); + p = guththila_get_value(env, parser); + fail_unless(!strcmp(p, "24"), "24 not found"); + +} +END_TEST Suite * +guththila_suite( + void) +{ + Suite *s = suite_create("Guththila"); + + /* Core test case */ + TCase *tc_core = tcase_create("Core"); + tcase_add_checked_fixture(tc_core, setup, teardown); + tcase_add_test(tc_core, test_guththila); + tcase_add_test(tc_core, test_guththila_start_element); + tcase_add_test(tc_core, test_guththila_empty_element); + tcase_add_test(tc_core, test_guththila_end_element); + tcase_add_test(tc_core, test_guththila_character); + suite_add_tcase(s, tc_core); + return s; +} + +int +main( + void) +{ + int number_failed; + Suite *s = guththila_suite(); + Suite *att = guththila_attribute_suite(); + SRunner *sr = srunner_create(s); + srunner_add_suite(sr, att); + srunner_set_log(sr, "guththila.log"); + srunner_run_all(sr, CK_NORMAL); + number_failed = srunner_ntests_failed(sr); + srunner_free(sr); + return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; +} diff --git a/guththila/tests/test.h b/guththila/tests/test.h new file mode 100644 index 0000000..93bebff --- /dev/null +++ b/guththila/tests/test.h @@ -0,0 +1,23 @@ +#ifndef _GUTHTHILA_TESTS_ +#define _GUTHTHILA_TESTS_ +#include +#include +#include "guththila_defines.h" + +axutil_allocator_t *allocator; +guththila_reader_t *red; +axutil_env_t *env; +guththila_t *parser; + +void setup( + void); +void teardown( + void); + +Suite *guththila_suite( + void); + +Suite *guththila_attribute_suite( + void); + +#endif diff --git a/guththila/tests/test_attribute.c b/guththila/tests/test_attribute.c new file mode 100644 index 0000000..bd6c4b5 --- /dev/null +++ b/guththila/tests/test_attribute.c @@ -0,0 +1,84 @@ +#include +#include +#include "test.h" + +START_TEST(test_attribute) +{ + int count = 0;; + int c = 0; + guththila_attribute_t *att; + red = guththila_reader_create_for_file(env, "resources/om/evaluate.xml"); + parser = guththila_create(env, red); + guththila_read(env, parser); + c = guththila_next(env, parser); + while (!count) + { + c = guththila_next(env, parser); + count = guththila_get_attribute_count(env, parser); + if (count) + att = guththila_get_attribute(env, parser); + } + fail_if(count == 0, "guththila attribute count failed"); + fail_unless(!strcmp + (guththila_get_attribute_name(env, parser, att), "color"), + "guththila attribute name failed"); + fail_unless(!strcmp + (guththila_get_attribute_value(env, parser, att), "brown"), + "guththila attribute value failed"); +} + +END_TEST +START_TEST( + test_attribute_prefix) +{ + int count = 0; + ; + int c = 0; + guththila_attribute_t *att; + red = guththila_reader_create_for_file(env, "resources/soap/soapmessage.xml"); + parser = guththila_create(env, red); + guththila_read(env, parser); + c = guththila_next(env, parser); + while(!count) + { + c = guththila_next(env, parser); + count = guththila_get_attribute_count(env, parser); + if(count) + att = guththila_get_attribute(env, parser); + } + fail_if(count == 0, "guththila attribute count failed"); + fail_unless(!strcmp(guththila_get_attribute_prefix(env, parser, att), "soapenv"), + "guththila attribute count failed"); + fail_unless(!strcmp(guththila_get_attribute_name(env, parser, att), "mustUnderstand"), + "guththila attribute count failed"); + fail_unless(!strcmp(guththila_get_attribute_value(env, parser, att), "0"), + "guththila attribute count failed"); + count = 0; + while(!count) + { + c = guththila_next(env, parser); + count = guththila_get_attribute_count(env, parser); + if(count) + att = guththila_get_attribute(env, parser); + } + fail_unless(!strcmp(guththila_get_attribute_prefix(env, parser, att), "soapenv"), + "guththila attribute count failed"); + fail_unless(!strcmp(guththila_get_attribute_name(env, parser, att), "mustUnderstand"), + "guththila attribute count failed"); + fail_if(!strcmp(guththila_get_attribute_value(env, parser, att), "1"), + "guththila attribute count failed"); +} +END_TEST Suite * +guththila_attribute_suite( + void) +{ + Suite *s = suite_create("Guththila_attribute"); + + /* Core test case */ + TCase *tc_core = tcase_create("attribute"); + tcase_add_checked_fixture(tc_core, setup, teardown); + tcase_add_test(tc_core, test_attribute); + tcase_add_test(tc_core, test_attribute_prefix); + suite_add_tcase(s, tc_core); + return s; +} -- cgit v1.1-32-gdbae