| /* |
| * 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) |
| { |
| |
| 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; |
| } |
| return guththila_write_escaped_buffer(wr,buff,env); |
| } |
| |
| 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, ">", 4u, env); |
| break; |
| case '<': |
| guththila_write(wr, "<", 4u, env); |
| break; |
| case '\'': |
| guththila_write(wr, "'", 6u, env); |
| break; |
| case '"': |
| guththila_write(wr, """, 6u, env); |
| break; |
| case '&': |
| guththila_write(wr, "&", 5u, env); |
| break; |
| default: |
| return GUTHTHILA_FAILURE; |
| }; |
| } |
| return GUTHTHILA_SUCCESS; |
| } |
| |
| GUTHTHILA_EXPORT int GUTHTHILA_CALL |
| guththila_write_escaped_buffer( |
| guththila_xml_writer_t * wr, |
| char *buff, |
| const axutil_env_t * env) |
| { |
| size_t len = strlen(buff); |
| |
| 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_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); |
| if(guththila_write_escaped_buffer(wr, value, env)!=GUTHTHILA_SUCCESS) |
| return GUTHTHILA_FAILURE; |
| 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); |
| if(guththila_write_escaped_buffer(wr, value, env)!=GUTHTHILA_SUCCESS) |
| return GUTHTHILA_FAILURE; |
| 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); |
| if(guththila_write_escaped_buffer(wr, value, env)!=GUTHTHILA_SUCCESS) |
| return GUTHTHILA_FAILURE; |
| 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); |
| } |
| else |
| { |
| AXIS2_FREE(env->allocator, namesp); |
| namesp = NULL; |
| } |
| |
| #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; |
| } |
| |