summaryrefslogtreecommitdiffstats
path: root/guththila/src
diff options
context:
space:
mode:
authorGravatar gmcdonald2010-02-13 01:32:03 +0000
committerGravatar gmcdonald2010-02-13 01:32:03 +0000
commit0425aadc78680e53000fd0108b540d6eca048516 (patch)
tree8ec7ab8e015d454c5ec586dfc91e05a2dce1cfc0 /guththila/src
downloadaxis2c-0425aadc78680e53000fd0108b540d6eca048516.tar.gz
axis2c-0425aadc78680e53000fd0108b540d6eca048516.tar.bz2
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
Diffstat (limited to 'guththila/src')
-rw-r--r--guththila/src/Makefile.am18
-rw-r--r--guththila/src/guththila_attribute.c144
-rw-r--r--guththila/src/guththila_buffer.c134
-rw-r--r--guththila/src/guththila_namespace.c139
-rw-r--r--guththila/src/guththila_reader.c115
-rw-r--r--guththila/src/guththila_stack.c135
-rw-r--r--guththila/src/guththila_token.c221
-rw-r--r--guththila/src/guththila_xml_parser.c1792
-rw-r--r--guththila/src/guththila_xml_writer.c2082
9 files changed, 4780 insertions, 0 deletions
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 <guththila_attribute.h>
+#include <guththila_stack.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <guththila_buffer.h>
+
+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 <guththila_namespace.h>
+#include <guththila_stack.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+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 <stdlib.h>
+#include <string.h>
+#include <guththila_reader.h>
+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 <guththila_stack.h>
+
+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 <guththila_token.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <guththila.h>
+
+#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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <guththila_xml_writer.h>
+
+#define GUTHTHILA_WRITER_SD_DECLARATION "<?xml version=\"1.0\" encoding=\"utf-8\" ?>"
+
+#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, "></", 3u, env);
+ /* Write the contents of the element at the top */
+ elem = (guththila_xml_writer_element_t *)guththila_stack_pop(&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, "</", 2u, env);
+ elem = (guththila_xml_writer_element_t *)guththila_stack_pop(&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, "><!--", 5u, env);
+ guththila_write(wr, buff, strlen(buff), env);
+ 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, "/><!--", 6u, env);
+ guththila_write(wr, buff, strlen(buff), env);
+ guththila_write(wr, "-->", 3u, env);
+ return GUTHTHILA_SUCCESS;
+ }
+ else if(wr->status == BEGINING)
+ {
+ guththila_write(wr, "<!--", 4u, env);
+ guththila_write(wr, buff, strlen(buff), env);
+ 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, "&gt;", 4u, env);
+ break;
+ case '<':
+ guththila_write(wr, "&lt;", 4u, env);
+ break;
+ case '\'':
+ guththila_write(wr, "&apos;", 6u, env);
+ break;
+ case '"':
+ guththila_write(wr, "&quot;", 6u, env);
+ break;
+ case '&':
+ guththila_write(wr, "&amp;", 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;
+}
+