/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #define GUTHTHILA_WRITER_SD_DECLARATION "" #ifndef GUTHTHILA_XML_WRITER_TOKEN #ifndef GUTHTHILA_WRITER_ELEM_FREE #define GUTHTHILA_WRITER_ELEM_FREE(wr, elem, _env) \ if ((elem)->prefix) AXIS2_FREE(env->allocator, (elem)->prefix); \ if ((elem)->name) AXIS2_FREE(env->allocator, (elem)->name); \ AXIS2_FREE(env->allocator, elem); #endif #else #ifndef GUTHTHILA_WRITER_ELEM_FREE #define GUTHTHILA_WRITER_ELEM_FREE(wr, elem, _env) \ if ((elem)->prefix) guththila_tok_list_release_token(&wr->tok_list, (elem)->prefix, _env); \ if ((elem)->name) guththila_tok_list_release_token(&wr->tok_list, (elem)->name, _env); \ AXIS2_FREE(env->allocator, elem); #endif #endif #ifndef GUTHTHILA_XML_WRITER_TOKEN #ifndef GUTHTHILA_WRITER_CLEAR_NAMESP #define GUTHTHILA_WRITER_CLEAR_NAMESP(wr, stack_namesp, _no, counter, _namesp, j, _env) \ for (counter = GUTHTHILA_STACK_TOP_INDEX(*stack_namesp); counter >= _no; counter--) {\ _namesp = (guththila_xml_writer_namesp_t *) guththila_stack_pop(stack_namesp, _env); \ if (_namesp) { \ for (j = 0; j < _namesp->no - 1; j++) { \ if (_namesp->name[j]) AXIS2_FREE(env->allocator, _namesp->name[j]); \ if (_namesp->uri[j]) AXIS2_FREE(env->allocator, _namesp->uri[j]); \ } \ AXIS2_FREE(env->allocator, _namesp->name); \ AXIS2_FREE(env->allocator, _namesp->uri); \ AXIS2_FREE(env->allocator, _namesp); \ } \ _namesp = NULL; \ } #endif #else #ifndef GUTHTHILA_WRITER_CLEAR_NAMESP #define GUTHTHILA_WRITER_CLEAR_NAMESP(wr, stack_namesp, _no, counter, _namesp, j, _env) \ for (counter = GUTHTHILA_STACK_TOP_INDEX(*stack_namesp); counter >= _no; counter--) { \ _namesp = (guththila_xml_writer_namesp_t *) guththila_stack_pop(stack_namesp, _env); \ if (_namesp) { \ for (j = 0; j < _namesp->no - 1; j++) { \ guththila_tok_list_release_token(&wr->tok_list, _namesp->name[j], _env); \ guththila_tok_list_release_token(&wr->tok_list, _namesp->uri[j], _env); \ } \ AXIS2_FREE(env->allocator, _namesp->name); \ AXIS2_FREE(env->allocator, _namesp->uri); \ AXIS2_FREE(env->allocator, _namesp); \ } \ _namesp = NULL; \ } #endif #endif #ifndef GUTHTHILA_WRITER_INIT_ELEMENT #define GUTHTHILA_WRITER_INIT_ELEMENT_WITH_PREFIX(wr, _elem, _name_start, _name_size, _pref_start, _pref_size) \ _elem->name = guththila_tok_list_get_token(&wr->tok_list); \ _elem->prefix = = guththila_tok_list_get_token(&wr->tok_list); \ _elem->name->start = _name_start; \ _elem->name->size = _name_size; \ _elem->prefix->start = _pref_start; \ _elem->prrefix->size = pref_size; #endif #ifndef GUTHTHILA_WRITER_INIT_ELEMENT #define GUTHTHILA_WRITER_INIT_ELEMENT_WITHOUT_PREFIX(wr, _elem, _name_start, _name_size) \ _elem->name = guththila_tok_list_get_token(&(wr)->tok_list); \ _elem->name->start = _name_start; \ _elem->name->size = _name_size; \ _elem->prefix->NULL; #endif /* #ifndef guththila_write(_wr, _buff, _buff_size) #define guththila_write(_wr, _buff, _buff_size) \ if (_wr->type == GUTHTHILA_WRITER_MEMORY){ \ if (_wr->buffer.size > _wr->buffer.next + _buff_size) {\ memcpy (_wr->buffer.buff + _wr->buffer.next, _buff, _buff_size);\ _wr->buffer.next += (int)_buff_size; \ } else {\ _wr->buffer.buff = realloc(_wr->buffer.buff, _wr->buffer.size * 2);\ _wr->buffer.size = _wr->buffer.size * 2; \ memcpy (_wr->buffer.buff + _wr->buffer.next, _buff, _buff_size);\ _wr->buffer.next += (int)_buff_size; \ }\ } #endif*/ /* * Write the contents of the buff in to the guththila_xml_writer buffer. * len indicates the number of items in the buff. */ int GUTHTHILA_CALL guththila_write( guththila_xml_writer_t * wr, char *buff, size_t buff_size, const axutil_env_t * env); /* * Same functionality as the guththila_write only difference is here we are given * a token to write, not a buffer. */ int GUTHTHILA_CALL guththila_write_token( guththila_xml_writer_t * wr, guththila_token_t * tok, const axutil_env_t * env); int GUTHTHILA_CALL guththila_write_xtoken( guththila_xml_writer_t * wr, char *buff, size_t buff_len, const axutil_env_t * env); /* * Private function for free the contents of a empty element. */ int GUTHTHILA_CALL guththila_free_empty_element( guththila_xml_writer_t *wr, const axutil_env_t *env); GUTHTHILA_EXPORT guththila_xml_writer_t * GUTHTHILA_CALL guththila_create_xml_stream_writer( guththila_char_t *file_name, const axutil_env_t * env) { guththila_xml_writer_t * wr = AXIS2_MALLOC(env->allocator, sizeof(guththila_xml_writer_t)); if(!wr) return NULL; wr->out_stream = fopen(file_name, "w"); if(!wr->out_stream) { AXIS2_FREE(env->allocator, wr); return NULL; } if(!guththila_stack_init(&wr->element, env)) { fclose(wr->out_stream); AXIS2_FREE(env->allocator, wr); return NULL; } if(!guththila_stack_init(&wr->namesp, env)) { guththila_stack_un_init(&wr->element, env); fclose(wr->out_stream); AXIS2_FREE(env->allocator, wr); return NULL; } wr->type = GUTHTHILA_WRITER_FILE; wr->status = BEGINING; wr->next = 0; return wr; } GUTHTHILA_EXPORT guththila_xml_writer_t * GUTHTHILA_CALL guththila_create_xml_stream_writer_for_memory( const axutil_env_t * env) { guththila_xml_writer_t * wr = AXIS2_MALLOC(env->allocator, sizeof(guththila_xml_writer_t)); if(!wr) return NULL; if(!guththila_buffer_init(&wr->buffer, GUTHTHILA_BUFFER_DEF_SIZE, env)) { AXIS2_FREE(env->allocator, wr); return NULL; } if(!guththila_stack_init(&wr->element, env)) { guththila_buffer_un_init(&wr->buffer, env); AXIS2_FREE(env->allocator, wr); return NULL; } if(!guththila_stack_init(&wr->namesp, env)) { guththila_buffer_un_init(&wr->buffer, env); guththila_stack_un_init(&wr->element, env); AXIS2_FREE(env->allocator, wr); return NULL; } #ifdef GUTHTHILA_XML_WRITER_TOKEN if (!guththila_tok_list_init(&wr->tok_list, env)) { guththila_buffer_un_init(&wr->buffer, env); guththila_stack_un_init(&wr->element, env); guththila_stack_un_init(&wr->namesp, env); AXIS2_FREE(env->allocator, wr); return NULL; } #endif wr->type = GUTHTHILA_WRITER_MEMORY; wr->status = BEGINING; wr->next = 0; return wr; } GUTHTHILA_EXPORT void GUTHTHILA_CALL guththila_xml_writer_free( guththila_xml_writer_t * wr, const axutil_env_t * env) { if(wr->type == GUTHTHILA_WRITER_MEMORY) { guththila_buffer_un_init(&wr->buffer, env); } else if(wr->type == GUTHTHILA_WRITER_FILE) { fclose(wr->out_stream); } #ifdef GUTHTHILA_XML_WRITER_TOKEN guththila_tok_list_free_data(&wr->tok_list, env); #endif guththila_stack_un_init(&wr->element, env); guththila_stack_un_init(&wr->namesp, env); AXIS2_FREE(env->allocator, wr); } int GUTHTHILA_CALL guththila_write( guththila_xml_writer_t * wr, guththila_char_t *buff, size_t buff_len, const axutil_env_t * env) { size_t remain_len = 0; size_t temp = 0; size_t * temp1 = NULL, *temp2 = NULL; guththila_char_t **temp3 = NULL; int i = 0; if(wr->type == GUTHTHILA_WRITER_MEMORY) { remain_len = wr->buffer.buffs_size[wr->buffer.cur_buff] - wr->buffer.data_size[wr->buffer.cur_buff]; /* We have space */ if(buff_len < remain_len) { memcpy( wr->buffer.buff[wr->buffer.cur_buff] + wr->buffer.data_size[wr->buffer.cur_buff], buff, buff_len); wr->buffer.data_size[wr->buffer.cur_buff] += buff_len; wr->next += (int)buff_len; /* We are sure that the difference lies within the int range */ return (int)buff_len; } else { if(remain_len != 0) { memcpy(wr->buffer.buff[wr->buffer.cur_buff] + wr->buffer.data_size[wr->buffer.cur_buff], buff, remain_len); wr->buffer.data_size[wr->buffer.cur_buff] += remain_len; } /* We are sure that the difference lies within the int range */ if(((int)wr->buffer.no_buffers - 1) == wr->buffer.cur_buff) { /* Out of allocated array buffers. Need to allocate*/ wr->buffer.no_buffers = wr->buffer.no_buffers * 2; temp3 = (guththila_char_t **)AXIS2_MALLOC(env->allocator, sizeof(guththila_char_t *) * wr->buffer.no_buffers); temp1 = (size_t *)AXIS2_MALLOC(env->allocator, sizeof(size_t) * wr->buffer.no_buffers); temp2 = (size_t *)AXIS2_MALLOC(env->allocator, sizeof(size_t) * wr->buffer.no_buffers); for(i = 0; i <= wr->buffer.cur_buff; i++) { temp3[i] = wr->buffer.buff[i]; temp1[i] = wr->buffer.data_size[i]; temp2[i] = wr->buffer.buffs_size[i]; } AXIS2_FREE(env->allocator, wr->buffer.data_size); AXIS2_FREE(env->allocator, wr->buffer.buffs_size); AXIS2_FREE(env->allocator, wr->buffer.buff); wr->buffer.buff = temp3; wr->buffer.buffs_size = temp2; wr->buffer.data_size = temp1; } wr->buffer.cur_buff++; temp = wr->buffer.buffs_size[wr->buffer.cur_buff - 1] * 2; while(temp < (buff_len - remain_len)) { temp = temp * 2; } /* Create a be buffer */ wr->buffer.buff[wr->buffer.cur_buff] = (guththila_char_t *)AXIS2_MALLOC(env->allocator, sizeof(guththila_char_t) * temp); wr->buffer.buffs_size[wr->buffer.cur_buff] = temp; memcpy(wr->buffer.buff[wr->buffer.cur_buff], buff + remain_len, buff_len - remain_len); wr->buffer.data_size[wr->buffer.cur_buff] = buff_len - remain_len; wr->buffer.pre_tot_data += wr->buffer.data_size[wr->buffer.cur_buff - 1]; wr->next += (int)buff_len; /* We are sure that the difference lies within the int range */ return (int)buff_len; } } else if(wr->type == GUTHTHILA_WRITER_FILE) { return (int)fwrite(buff, 1, buff_len, wr->out_stream); } return GUTHTHILA_FAILURE; } int GUTHTHILA_CALL guththila_write_token( guththila_xml_writer_t * wr, guththila_token_t * tok, const axutil_env_t * env) { int i; size_t remain_len = 0; size_t temp = 0; size_t * temp1 = NULL, *temp2 = NULL; guththila_char_t **temp3 = NULL; if(wr->type == GUTHTHILA_WRITER_MEMORY) { remain_len = wr->buffer.buffs_size[wr->buffer.cur_buff] - wr->buffer.data_size[wr->buffer.cur_buff]; if(tok->size < remain_len) { memcpy( wr->buffer.buff[wr->buffer.cur_buff] + wr->buffer.data_size[wr->buffer.cur_buff], tok->start, tok->size); wr->buffer.data_size[wr->buffer.cur_buff] += tok->size; wr->next += (int)tok->size; /* We are sure that the difference lies within the int range */ return (int)tok->size; } else { if(remain_len != 0) { memcpy(wr->buffer.buff[wr->buffer.cur_buff] + wr->buffer.data_size[wr->buffer.cur_buff], tok->start, remain_len); wr->buffer.data_size[wr->buffer.cur_buff] += remain_len; } /* We are sure that the difference lies within the int range */ if(((int)wr->buffer.no_buffers - 1) == wr->buffer.cur_buff) { wr->buffer.no_buffers = wr->buffer.no_buffers * 2; temp3 = (guththila_char_t **)AXIS2_MALLOC(env->allocator, sizeof(guththila_char_t *) * wr->buffer.no_buffers); temp1 = (size_t *)AXIS2_MALLOC(env->allocator, sizeof(size_t) * wr->buffer.no_buffers); temp2 = (size_t *)AXIS2_MALLOC(env->allocator, sizeof(size_t) * wr->buffer.no_buffers); for(i = 0; i <= wr->buffer.cur_buff; i++) { temp3[i] = wr->buffer.buff[i]; temp1[i] = wr->buffer.data_size[i]; temp2[i] = wr->buffer.buffs_size[i]; } AXIS2_FREE(env->allocator, wr->buffer.data_size); AXIS2_FREE(env->allocator, wr->buffer.buffs_size); AXIS2_FREE(env->allocator, wr->buffer.buff); wr->buffer.buff = temp3; wr->buffer.buffs_size = temp2; wr->buffer.data_size = temp1; } wr->buffer.cur_buff++; temp = wr->buffer.buffs_size[wr->buffer.cur_buff - 1] * 2; while(temp < (tok->size - remain_len)) { temp = temp * 2; } wr->buffer.buff[wr->buffer.cur_buff] = (guththila_char_t *)AXIS2_MALLOC(env->allocator, sizeof(guththila_char_t) * temp); wr->buffer.buffs_size[wr->buffer.cur_buff] = temp; memcpy(wr->buffer.buff[wr->buffer.cur_buff], tok->start + remain_len, tok->size - remain_len); wr->buffer.data_size[wr->buffer.cur_buff] = tok->size - remain_len; wr->buffer.pre_tot_data += wr->buffer.data_size[wr->buffer.cur_buff - 1]; wr->next += (int)tok->size; /* We are sure that the difference lies within the int range */ return (int)tok->size; } } else if(wr->type == GUTHTHILA_WRITER_FILE) { return (int)fwrite(tok->start, 1, tok->size, wr->out_stream); } return GUTHTHILA_FAILURE; } int GUTHTHILA_CALL guththila_write_xtoken( guththila_xml_writer_t * wr, guththila_char_t *buff, size_t buff_len, const axutil_env_t * env) { int i; size_t temp = 0; size_t remain_len = 0; size_t * temp1 = NULL, *temp2 = NULL; guththila_char_t **temp3 = NULL; if(wr->type == GUTHTHILA_WRITER_MEMORY) { remain_len = wr->buffer.buffs_size[wr->buffer.cur_buff] - wr->buffer.data_size[wr->buffer.cur_buff]; if(buff_len < remain_len) { memcpy( wr->buffer.buff[wr->buffer.cur_buff] + wr->buffer.data_size[wr->buffer.cur_buff], buff, buff_len); wr->buffer.data_size[wr->buffer.cur_buff] += buff_len; wr->next += (int)buff_len; /* We are sure that the difference lies within the int range */ return (int)buff_len; } else { /* We are sure that the difference lies within the int range */ if(((int)wr->buffer.no_buffers - 1) == wr->buffer.cur_buff) { wr->buffer.no_buffers = wr->buffer.no_buffers * 2; temp3 = (guththila_char_t **)AXIS2_MALLOC(env->allocator, sizeof(guththila_char_t *) * wr->buffer.no_buffers); temp1 = (size_t *)AXIS2_MALLOC(env->allocator, sizeof(size_t) * wr->buffer.no_buffers); temp2 = (size_t *)AXIS2_MALLOC(env->allocator, sizeof(size_t) * wr->buffer.no_buffers); for(i = 0; i <= wr->buffer.cur_buff; i++) { temp3[i] = wr->buffer.buff[i]; temp1[i] = wr->buffer.data_size[i]; temp2[i] = wr->buffer.buffs_size[i]; } AXIS2_FREE(env->allocator, wr->buffer.data_size); AXIS2_FREE(env->allocator, wr->buffer.buffs_size); AXIS2_FREE(env->allocator, wr->buffer.buff); wr->buffer.buff = temp3; wr->buffer.buffs_size = temp2; wr->buffer.data_size = temp1; } temp = wr->buffer.buffs_size[wr->buffer.cur_buff] * 2; while(temp < (buff_len)) { temp = temp * 2; } wr->buffer.cur_buff++; wr->buffer.buff[wr->buffer.cur_buff] = (guththila_char_t *)AXIS2_MALLOC(env->allocator, sizeof(guththila_char_t) * temp); wr->buffer.buffs_size[wr->buffer.cur_buff] = temp; memcpy(wr->buffer.buff[wr->buffer.cur_buff], buff, buff_len); wr->buffer.data_size[wr->buffer.cur_buff] = buff_len; wr->buffer.pre_tot_data += wr->buffer.data_size[wr->buffer.cur_buff - 1]; wr->next += (int)buff_len; /* We are sure that the difference lies within the int range */ return (int)buff_len; } } else if(wr->type == GUTHTHILA_WRITER_FILE) { return (int)fwrite(buff, 1, buff_len, wr->out_stream); } return GUTHTHILA_FAILURE; } int GUTHTHILA_CALL guththila_free_empty_element( guththila_xml_writer_t *wr, const axutil_env_t *env) { guththila_xml_writer_element_t * elem = NULL; guththila_xml_writer_namesp_t * namesp = NULL; int i = 0, j = 0; elem = (guththila_xml_writer_element_t *)guththila_stack_pop(&wr->element, env); if(elem) { wr->status = BEGINING; if(elem->name_sp_stack_no != -1) { GUTHTHILA_WRITER_CLEAR_NAMESP(wr, &wr->namesp, elem->name_sp_stack_no, i, namesp, j, env); } GUTHTHILA_WRITER_ELEM_FREE(wr, elem, env); return GUTHTHILA_SUCCESS; } else { return GUTHTHILA_FAILURE; } } GUTHTHILA_EXPORT int GUTHTHILA_CALL guththila_write_start_document( guththila_xml_writer_t * wr, const axutil_env_t * env, char *encoding, char *version) { char *tmp1 = NULL; char *tmp2 = GUTHTHILA_WRITER_SD_DECLARATION; tmp1 = strchr(tmp2, '\"'); tmp1++; guththila_write(wr, tmp2, (int)(tmp1 - tmp2), env); tmp2 = strchr(tmp1, '\"'); if(version) { guththila_write(wr, version, (int)strlen(version), env); } else { guththila_write(wr, tmp1, (int)(tmp2 - tmp1), env); } tmp2++; tmp1 = strchr(tmp2, '\"'); tmp2--; tmp1++; guththila_write(wr, tmp2, (int)(tmp1 - tmp2), env); tmp2 = strchr(tmp1, '\"'); if(encoding) { guththila_write(wr, encoding, (int)strlen(encoding), env); } else { guththila_write(wr, tmp1, (int)(tmp2 - tmp1), env); } guththila_write(wr, tmp2, (int)strlen(tmp2), env); return GUTHTHILA_SUCCESS; } GUTHTHILA_EXPORT int GUTHTHILA_CALL guththila_write_start_element( guththila_xml_writer_t * wr, guththila_char_t *start_element, const axutil_env_t * env) { int cur_pos = 0; size_t len = 0; guththila_xml_writer_element_t * element = (guththila_xml_writer_element_t *)AXIS2_MALLOC( env->allocator, sizeof(guththila_xml_writer_element_t)); len = strlen(start_element); if(wr->status == START) { /* If we are in a start we need to close and start */ guththila_write(wr, "><", 2u, env); cur_pos = wr->next; guththila_write_xtoken(wr, start_element, len, env); } else if(wr->status == START_EMPTY) { /* We need to close and start */ guththila_free_empty_element(wr, env); guththila_write(wr, "/><", 3u, env); cur_pos = wr->next; guththila_write_xtoken(wr, start_element, len, env); } else if(wr->status == BEGINING) { /* We can start rightaway*/ guththila_write(wr, "<", 1u, env); cur_pos = wr->next; guththila_write_xtoken(wr, start_element, len, env); } else { return GUTHTHILA_FAILURE; } wr->status = START; #ifndef GUTHTHILA_XML_WRITER_TOKEN element->name = strdup(start_element); element->prefix = NULL; #else element->name = guththila_tok_list_get_token(&wr->tok_list, env); element->name->start = GUTHTHILA_BUF_POS(wr->buffer, cur_pos); element->name->size = len; element->prefix = NULL; #endif element->name_sp_stack_no = -1; return guththila_stack_push(&wr->element, element, env); } GUTHTHILA_EXPORT int GUTHTHILA_CALL guththila_write_end_element( guththila_xml_writer_t * wr, const axutil_env_t * env) { guththila_xml_writer_element_t * elem = NULL; guththila_xml_writer_namesp_t * namesp = NULL; int i = 0, j = 0; if(wr->status == START) { guththila_write(wr, ">element, env); if(elem) { if(elem->prefix) { #ifndef GUTHTHILA_XML_WRITER_TOKEN guththila_write(wr, elem->prefix, strlen(elem->prefix), env); #else guththila_write_token(wr, elem->prefix, env); #endif guththila_write(wr, ":", 1u, env); } #ifndef GUTHTHILA_XML_WRITER_TOKEN guththila_write(wr, elem->name, strlen(elem->name), env); #else guththila_write_token(wr, elem->name, env); #endif guththila_write(wr, ">", 1u, env); wr->status = BEGINING; if(elem->name_sp_stack_no != -1) { GUTHTHILA_WRITER_CLEAR_NAMESP(wr, &wr->namesp, elem->name_sp_stack_no, i, namesp, j, env); } GUTHTHILA_WRITER_ELEM_FREE(wr, elem, env); return GUTHTHILA_SUCCESS; } else { return GUTHTHILA_FAILURE; } } else if(wr->status == START_EMPTY) { guththila_write(wr, "/>", 2u, env); elem = (guththila_xml_writer_element_t *)guththila_stack_pop(&wr->element, env); if(elem) { wr->status = BEGINING; if(elem->name_sp_stack_no != -1) { GUTHTHILA_WRITER_CLEAR_NAMESP(wr, &wr->namesp, elem->name_sp_stack_no, i, namesp, j, env); } GUTHTHILA_WRITER_ELEM_FREE(wr, elem, env); return GUTHTHILA_SUCCESS; } else { return GUTHTHILA_FAILURE; } } else if(wr->status == BEGINING) { guththila_write(wr, "element, env); if(elem) { if(elem->prefix) { #ifndef GUTHTHILA_XML_WRITER_TOKEN guththila_write(wr, elem->prefix, strlen(elem->prefix), env); #else guththila_write_token(wr, elem->prefix, env); #endif guththila_write(wr, ":", 1u, env); } #ifndef GUTHTHILA_XML_WRITER_TOKEN guththila_write(wr, elem->name, strlen(elem->name), env); #else guththila_write_token(wr, elem->name, env); #endif guththila_write(wr, ">", 1u, env); wr->status = BEGINING; if(elem->name_sp_stack_no != -1) { GUTHTHILA_WRITER_CLEAR_NAMESP(wr, &wr->namesp, elem->name_sp_stack_no, i, namesp, j, env); } GUTHTHILA_WRITER_ELEM_FREE(wr, elem, env); return GUTHTHILA_SUCCESS; } else { return GUTHTHILA_FAILURE; } } return GUTHTHILA_FAILURE; } GUTHTHILA_EXPORT int GUTHTHILA_CALL guththila_close( guththila_xml_writer_t * wr, const axutil_env_t * env) { return GUTHTHILA_FAILURE; } GUTHTHILA_EXPORT int GUTHTHILA_CALL guththila_write_characters( guththila_xml_writer_t * wr, guththila_char_t *buff, const axutil_env_t * env) { size_t len = strlen(buff); if(wr->status == START) { wr->status = BEGINING; guththila_write(wr, ">", 1u, env); } else if(wr->status == START_EMPTY) { guththila_free_empty_element(wr, env); wr->status = BEGINING; guththila_write(wr, "/>", 2u, env); } else if(wr->status != BEGINING) { return GUTHTHILA_FAILURE; } while(len > 0) { size_t i = 0; /* scan buffer until the next special character (&, <, >, ', ") these need to be escaped, * otherwise XML will not be valid*/ guththila_char_t *pos = (guththila_char_t*)strpbrk(buff, "&<>'\""); if(pos) { i = pos - buff; } else { i = len; } /* write everything until the special character */ if(i > 0) { guththila_write(wr, buff, i, env); buff += i; len -= i; } /* replace the character with the appropriate sequence */ if(len > 0) { if(AXIS2_SUCCESS != guththila_write_escape_character(wr, buff, env)) return GUTHTHILA_FAILURE; /* skip the character */ buff++; len--; } } return GUTHTHILA_SUCCESS; } GUTHTHILA_EXPORT int GUTHTHILA_CALL guththila_write_comment( guththila_xml_writer_t * wr, guththila_char_t *buff, const axutil_env_t * env) { if(wr->status == START) { wr->status = BEGINING; guththila_write(wr, ">", 3u, env); return GUTHTHILA_SUCCESS; } else if(wr->status == START_EMPTY) { guththila_free_empty_element(wr, env); wr->status = BEGINING; guththila_write(wr, "/>", 3u, env); return GUTHTHILA_SUCCESS; } else if(wr->status == BEGINING) { guththila_write(wr, "", 3u, env); return GUTHTHILA_SUCCESS; } return GUTHTHILA_FAILURE; } GUTHTHILA_EXPORT int GUTHTHILA_CALL guththila_write_escape_character( guththila_xml_writer_t * wr, guththila_char_t *buff, const axutil_env_t * env) { if(buff) { switch(buff[0]) { case '>': guththila_write(wr, ">", 4u, env); break; case '<': guththila_write(wr, "<", 4u, env); break; case '\'': guththila_write(wr, "'", 6u, env); break; case '"': guththila_write(wr, """, 6u, env); break; case '&': guththila_write(wr, "&", 5u, env); break; default: return GUTHTHILA_FAILURE; }; } return GUTHTHILA_SUCCESS; } GUTHTHILA_EXPORT int GUTHTHILA_CALL guththila_write_empty_element( guththila_xml_writer_t * wr, guththila_char_t *start_element, const axutil_env_t * env) { int cur_pos = 0; size_t len = 0; guththila_xml_writer_element_t * element = (guththila_xml_writer_element_t *)AXIS2_MALLOC( env->allocator, sizeof(guththila_xml_writer_element_t)); len = strlen(start_element); if(wr->status == START) { guththila_write(wr, "><", 2u, env); cur_pos = wr->next; guththila_write_xtoken(wr, start_element, len, env); } else if(wr->status == START_EMPTY) { guththila_free_empty_element(wr, env); wr->status = BEGINING; guththila_write(wr, "/><", 3u, env); cur_pos = wr->next; guththila_write_xtoken(wr, start_element, len, env); } else if(wr->status == BEGINING) { guththila_write(wr, "<", 1u, env); cur_pos = wr->next; guththila_write_xtoken(wr, start_element, len, env); } else { return GUTHTHILA_FAILURE; } wr->status = START_EMPTY; #ifndef GUTHTHILA_XML_WRITER_TOKEN element->name = strdup(start_element); element->prefix = NULL; #else element->name = guththila_tok_list_get_token(&wr->tok_list, env); element->name->start = GUTHTHILA_BUF_POS(wr->buffer, cur_pos); element->name->size = len; element->prefix = NULL; #endif element->name_sp_stack_no = -1; return guththila_stack_push(&wr->element, element, env); } GUTHTHILA_EXPORT int GUTHTHILA_CALL guththila_write_default_namespace( guththila_xml_writer_t * wr, guththila_char_t *namespace_uri, const axutil_env_t * env) { if(wr->status == START || wr->status == START_EMPTY) { guththila_write(wr, " xmlns=\"", 8u, env); guththila_write(wr, namespace_uri, strlen(namespace_uri), env); guththila_write(wr, "\"", 1u, env); return GUTHTHILA_SUCCESS; } return GUTHTHILA_FAILURE; } GUTHTHILA_EXPORT int GUTHTHILA_CALL guththila_write_namespace( guththila_xml_writer_t * wr, guththila_char_t *prefix, guththila_char_t *uri, const axutil_env_t * env) { int i, j, temp, nmsp_found = GUTHTHILA_FALSE, stack_size; guththila_xml_writer_namesp_t * namesp = NULL; guththila_xml_writer_element_t * elem = NULL; int pref_start = 0, uri_start = 0; guththila_char_t *pref_start_p = NULL, *uri_start_p = NULL; guththila_xml_writer_namesp_t * writer_namesp = NULL; guththila_token_t ** tok_name = NULL, **tok_uri = NULL; size_t pref_len = strlen(prefix), uri_len = strlen(uri); stack_size = GUTHTHILA_STACK_SIZE(wr->namesp); /* Check weather we have met the namespace before */ for(i = stack_size - 1; i >= 0; i--) { writer_namesp = (guththila_xml_writer_namesp_t *)guththila_stack_get_by_index(&wr->namesp, i, env); temp = writer_namesp->no; for(j = 0; j < temp; j++) { #ifndef GUTHTHILA_XML_WRITER_TOKEN if(!strcmp(prefix, writer_namesp->name[j])) { #else if (!guththila_tok_str_cmp(writer_namesp->name[j], prefix, pref_len, env)) { #endif nmsp_found = GUTHTHILA_TRUE; } } } /* Proceed if we didn't find the namespace */ if(!nmsp_found && (wr->status == START || wr->status == START_EMPTY)) { guththila_write(wr, " xmlns:", 7u, env); pref_start = wr->next; guththila_write_xtoken(wr, prefix, pref_len, env); pref_start_p = GUTHTHILA_BUF_POS(wr->buffer, pref_start); guththila_write(wr, "=\"", 2u, env); uri_start = wr->next; guththila_write_xtoken(wr, uri, uri_len, env); uri_start_p = GUTHTHILA_BUF_POS(wr->buffer, uri_start); guththila_write(wr, "\"", 1u, env); elem = guththila_stack_peek(&wr->element, env); if(elem && elem->name_sp_stack_no == -1) { namesp = (guththila_xml_writer_namesp_t *)AXIS2_MALLOC(env->allocator, sizeof(guththila_xml_writer_namesp_t)); if(namesp) { #ifndef GUTHTHILA_XML_WRITER_TOKEN namesp->name = (guththila_char_t **)AXIS2_MALLOC(env->allocator, sizeof(guththila_char_t *) * GUTHTHILA_XML_WRITER_NAMESP_DEF_SIZE); namesp->uri = (guththila_char_t **)AXIS2_MALLOC(env->allocator, sizeof(guththila_char_t *) * GUTHTHILA_XML_WRITER_NAMESP_DEF_SIZE); namesp->name[0] = strdup(prefix); namesp->uri[0] = strdup(uri); #else namesp->name = (guththila_token_t **) AXIS2_MALLOC(env->allocator, sizeof(guththila_token_t *) * GUTHTHILA_XML_WRITER_NAMESP_DEF_SIZE); namesp->uri = (guththila_token_t **) AXIS2_MALLOC(env->allocator, sizeof(guththila_token_t *) * GUTHTHILA_XML_WRITER_NAMESP_DEF_SIZE); namesp->name[0] = guththila_tok_list_get_token(&wr->tok_list, env); namesp->name[0]->start = pref_start_p ; namesp->name[0]->size = pref_len; namesp->uri[0] = guththila_tok_list_get_token(&wr->tok_list, env); namesp->uri[0]->start = uri_start_p ; namesp->uri[0]->size = uri_len; #endif namesp->no = 1; namesp->size = GUTHTHILA_XML_WRITER_NAMESP_DEF_SIZE; guththila_stack_push(&wr->namesp, namesp, env); elem->name_sp_stack_no = GUTHTHILA_STACK_TOP_INDEX(wr->namesp); } else { return GUTHTHILA_FAILURE; } } else if(elem) { namesp = guththila_stack_peek(&wr->namesp, env); if(namesp->no < namesp->size) { #ifndef GUTHTHILA_XML_WRITER_TOKEN namesp->name[++(namesp->no) - 1] = strdup(prefix); namesp->uri[namesp->no - 1] = strdup(uri); #else namesp->name[++(namesp->no) - 1] = guththila_tok_list_get_token(&wr->tok_list, env); namesp->uri[namesp->no - 1] = guththila_tok_list_get_token(&wr->tok_list, env); namesp->name[namesp->no - 1]->start = pref_start_p; namesp->name[namesp->no - 1]->size = pref_len; namesp->uri[namesp->no - 1]->start = uri_start_p; namesp->uri[namesp->no - 1]->size = uri_len; #endif } else { #ifndef GUTHTHILA_XML_WRITER_TOKEN namesp->name = (guththila_char_t **)realloc(namesp->name, sizeof(guththila_char_t *) * (GUTHTHILA_XML_WRITER_NAMESP_DEF_SIZE + namesp->size)); namesp->uri = (guththila_char_t **)realloc(namesp->name, sizeof(guththila_char_t *) * (GUTHTHILA_XML_WRITER_NAMESP_DEF_SIZE + namesp->size)); namesp->size = GUTHTHILA_XML_WRITER_NAMESP_DEF_SIZE + namesp->size; namesp->name[++(namesp->no) - 1] = strdup(prefix); namesp->uri[namesp->no - 1] = strdup(uri); #else tok_name = (guththila_token_t **) AXIS2_MALLOC(env->allocator, sizeof(guththila_token_t *) * (GUTHTHILA_XML_WRITER_NAMESP_DEF_SIZE + namesp->size)); tok_uri = (guththila_token_t **) AXIS2_MALLOC(env->allocator, sizeof(guththila_token_t *) * (GUTHTHILA_XML_WRITER_NAMESP_DEF_SIZE + namesp->size)); for (i = 0; i < namesp->no; i++) { tok_name[i] = namesp->name[i]; tok_uri[i] = namesp->uri[i]; } AXIS2_FREE(env->allocator, namesp->name); AXIS2_FREE(env->allocator, namesp->uri); namesp->name = tok_name; namesp->uri = tok_uri; namesp->size = GUTHTHILA_XML_WRITER_NAMESP_DEF_SIZE + namesp->size; namesp->name[namesp->no] = guththila_tok_list_get_token(&wr->tok_list, env); namesp->uri[namesp->no] = guththila_tok_list_get_token(&wr->tok_list, env); namesp->name[namesp->no ]->start = pref_start_p; namesp->name[namesp->no ]->size = pref_len; namesp->uri[namesp->no ]->start = uri_start_p; namesp->uri[namesp->no ]->size = uri_len; namesp->no ++; #endif } } return GUTHTHILA_SUCCESS; } if(nmsp_found) return GUTHTHILA_SUCCESS; return GUTHTHILA_FAILURE; } GUTHTHILA_EXPORT int GUTHTHILA_CALL guththila_write_attribute( guththila_xml_writer_t * wr, guththila_char_t *localname, guththila_char_t *value, const axutil_env_t * env) { if(wr->status == START || wr->status == START_EMPTY) { guththila_write(wr, " ", 1u, env); guththila_write(wr, localname, strlen(localname), env); guththila_write(wr, "=\"", 2u, env); guththila_write(wr, value, strlen(value), env); guththila_write(wr, "\"", 1u, env); return GUTHTHILA_SUCCESS; } return GUTHTHILA_FAILURE; } GUTHTHILA_EXPORT int GUTHTHILA_CALL guththila_write_attribute_with_prefix_and_namespace( guththila_xml_writer_t * wr, guththila_char_t *prefix, guththila_char_t *namespace_uri, guththila_char_t *localname, guththila_char_t *value, const axutil_env_t * env) { return guththila_write_namespace(wr, prefix, namespace_uri, env) && guththila_write_attribute_with_prefix(wr, prefix, localname, value, env); } GUTHTHILA_EXPORT int GUTHTHILA_CALL guththila_write_attribute_with_prefix( guththila_xml_writer_t * wr, guththila_char_t *prefix, guththila_char_t *localname, guththila_char_t *value, const axutil_env_t * env) { int i, j; int stack_size = GUTHTHILA_STACK_SIZE(wr->namesp); int temp; size_t pref_len = strlen(prefix); guththila_xml_writer_namesp_t * writer_namesp = NULL; if(wr->status == START || wr->status == START_EMPTY) { /* We need to make sure that there is a namespace defined with the * given prefix as the name */ for(i = stack_size - 1; i >= 0; i--) { writer_namesp = (guththila_xml_writer_namesp_t *)guththila_stack_get_by_index( &wr->namesp, i, env); temp = writer_namesp->no; for(j = 0; j < temp; j++) { #ifndef GUTHTHILA_XML_WRITER_TOKEN if(!strcmp(prefix, writer_namesp->name[j])) { #else if (!guththila_tok_str_cmp (writer_namesp->name[j], prefix, pref_len, env)) { #endif guththila_write(wr, " ", 1u, env); guththila_write(wr, prefix, pref_len, env); guththila_write(wr, ":", 1u, env); guththila_write(wr, localname, strlen(localname), env); guththila_write(wr, "=\"", 2u, env); guththila_write(wr, value, strlen(value), env); guththila_write(wr, "\"", 1u, env); return GUTHTHILA_SUCCESS; } } } } return GUTHTHILA_FAILURE; } GUTHTHILA_EXPORT int GUTHTHILA_CALL guththila_write_attribute_with_namespace( guththila_xml_writer_t * wr, guththila_char_t *namesp, guththila_char_t *loc_name, guththila_char_t *value, const axutil_env_t * env) { int i, j; int stack_size = GUTHTHILA_STACK_SIZE(wr->namesp); int temp; guththila_xml_writer_namesp_t * writer_namesp = NULL; if(wr->status == START || wr->status == START_EMPTY) { /* We need to make sure that the namespace is previously declared */ for(i = stack_size - 1; i >= 0; i--) { writer_namesp = (guththila_xml_writer_namesp_t *)guththila_stack_get_by_index( &wr->namesp, i, env); temp = writer_namesp->no; for(j = 0; j < temp; j++) { #ifndef GUTHTHILA_XML_WRITER_TOKEN if(!strcmp(namesp, writer_namesp->uri[j])) { guththila_write(wr, " ", 1, env); guththila_write(wr, writer_namesp->name[j], strlen(writer_namesp->name[j]), env); #else if (!guththila_tok_str_cmp (writer_namesp->uri[j], namesp, strlen(namesp), env)) { guththila_write(wr, " ", 1u, env); guththila_write_token(wr, writer_namesp->name[j], env); #endif guththila_write(wr, ":", 1u, env); guththila_write(wr, loc_name, strlen(loc_name), env); guththila_write(wr, "=\"", 2u, env); guththila_write(wr, value, strlen(value), env); guththila_write(wr, "\"", 1u, env); return GUTHTHILA_SUCCESS; } } } } return GUTHTHILA_FAILURE; } GUTHTHILA_EXPORT int GUTHTHILA_CALL guththila_write_start_element_with_prefix_and_namespace( guththila_xml_writer_t * wr, guththila_char_t *prefix, guththila_char_t *namespace_uri, guththila_char_t *local_name, const axutil_env_t * env) { int i, j, temp, stack_size, nmsp_found = GUTHTHILA_FALSE; guththila_xml_writer_namesp_t * namesp = NULL; guththila_xml_writer_element_t * elem = NULL; int uri_start = 0, pref_start = 0, elem_start = 0, elem_pref_start = 0; guththila_char_t *uri_start_p = NULL, *pref_start_p = NULL; guththila_char_t *elem_start_p = NULL, *elem_pref_start_p = NULL ; size_t uri_len = 0; size_t pref_len = 0; size_t elem_len = 0; guththila_xml_writer_namesp_t * writer_namesp = NULL; elem = (guththila_xml_writer_element_t *)AXIS2_MALLOC(env->allocator, sizeof(guththila_xml_writer_element_t)); uri_len = strlen(namespace_uri); pref_len = strlen(prefix); elem_len = strlen(local_name); stack_size = GUTHTHILA_STACK_SIZE(wr->namesp); /* We have to determine weather we have seen the namespace before */ for(i = stack_size - 1; i >= 0; i--) { writer_namesp = (guththila_xml_writer_namesp_t *)guththila_stack_get_by_index(&wr->namesp, i, env); temp = writer_namesp->no; for(j = 0; j < temp; j++) { #ifndef GUTHTHILA_XML_WRITER_TOKEN if(!strcmp(uri, writer_namesp->uri[j])) { #else if (!guththila_tok_str_cmp (writer_namesp->name[j], prefix, pref_len, env)) { #endif nmsp_found = GUTHTHILA_TRUE; } } } if(elem) { elem->name_sp_stack_no = -1; if(wr->status == START) { guththila_write(wr, "><", 2u, env); elem_pref_start = wr->next; guththila_write_xtoken(wr, prefix, pref_len, env); elem_pref_start_p = GUTHTHILA_BUF_POS(wr->buffer, elem_pref_start); guththila_write(wr, ":", 1u, env); elem_start = wr->next; guththila_write_xtoken(wr, local_name, elem_len, env); elem_start_p = GUTHTHILA_BUF_POS(wr->buffer, elem_start); if(!nmsp_found) { guththila_write(wr, " ", 1u, env); guththila_write(wr, "xmlns:", 6u, env); pref_start = wr->next; guththila_write_xtoken(wr, prefix, pref_len, env); pref_start_p = GUTHTHILA_BUF_POS(wr->buffer, pref_start); guththila_write(wr, "=\"", 2u, env); uri_start = wr->next; guththila_write_xtoken(wr, namespace_uri, uri_len, env); uri_start_p = GUTHTHILA_BUF_POS(wr->buffer, uri_start); guththila_write(wr, "\"", 1u, env); } } else if(wr->status == START_EMPTY) { guththila_free_empty_element(wr, env); guththila_write(wr, "/><", 2u, env); elem_pref_start = wr->next; guththila_write_xtoken(wr, prefix, pref_len, env); elem_pref_start_p = GUTHTHILA_BUF_POS(wr->buffer, elem_pref_start); guththila_write(wr, ":", 1u, env); elem_start = wr->next; guththila_write_xtoken(wr, local_name, elem_len, env); elem_start_p = GUTHTHILA_BUF_POS(wr->buffer, elem_start); if(!nmsp_found) { guththila_write(wr, " ", 1u, env); guththila_write(wr, "xmlns:", 6u, env); pref_start = wr->next; guththila_write_xtoken(wr, prefix, pref_len, env); pref_start_p = GUTHTHILA_BUF_POS(wr->buffer, pref_start); guththila_write(wr, "=\"", 2u, env); uri_start = wr->next; guththila_write_xtoken(wr, namespace_uri, uri_len, env); uri_start_p = GUTHTHILA_BUF_POS(wr->buffer, uri_start); guththila_write(wr, "\"", 1u, env); } wr->status = START; } else if(wr->status == BEGINING) { guththila_write(wr, "<", 1u, env); elem_pref_start = wr->next; guththila_write_xtoken(wr, prefix, pref_len, env); elem_pref_start_p = GUTHTHILA_BUF_POS(wr->buffer, elem_pref_start); guththila_write(wr, ":", 1u, env); elem_start = wr->next; guththila_write_xtoken(wr, local_name, elem_len, env); elem_start_p = GUTHTHILA_BUF_POS(wr->buffer, elem_start); if(!nmsp_found) { guththila_write(wr, " ", 1u, env); guththila_write(wr, "xmlns:", 6u, env); pref_start = wr->next; guththila_write_xtoken(wr, prefix, pref_len, env); pref_start_p = GUTHTHILA_BUF_POS(wr->buffer, pref_start); guththila_write(wr, "=\"", 2u, env); uri_start = wr->next; guththila_write_xtoken(wr, namespace_uri, uri_len, env); uri_start_p = GUTHTHILA_BUF_POS(wr->buffer, uri_start); guththila_write(wr, "\"", 1u, env); } wr->status = START; } else { return GUTHTHILA_FAILURE; } if(!nmsp_found) { /* If this namespace not defined previously we need to add it */ namesp = (guththila_xml_writer_namesp_t *)AXIS2_MALLOC(env->allocator, sizeof(guththila_xml_writer_namesp_t)); #ifndef GUTHTHILA_XML_WRITER_TOKEN namesp->name = (guththila_char_t **)AXIS2_MALLOC(env->allocator, sizeof(guththila_char_t *) * GUTHTHILA_XML_WRITER_NAMESP_DEF_SIZE); namesp->uri = (guththila_char_t **)AXIS2_MALLOC(env->allocator, sizeof(guththila_char_t *) * GUTHTHILA_XML_WRITER_NAMESP_DEF_SIZE); namesp->name[0] = strdup(prefix); namesp->uri[0] = strdup(namespace_uri); #else namesp->name = (guththila_token_t **) AXIS2_MALLOC(env->allocator, sizeof(guththila_token_t *) * GUTHTHILA_XML_WRITER_NAMESP_DEF_SIZE); namesp->uri = (guththila_token_t **) AXIS2_MALLOC(env->allocator, sizeof(guththila_token_t *) * GUTHTHILA_XML_WRITER_NAMESP_DEF_SIZE); namesp->name[0] = guththila_tok_list_get_token(&wr->tok_list, env); namesp->name[0]->start = pref_start_p; namesp->name[0]->size = pref_len; namesp->uri[0] = guththila_tok_list_get_token(&wr->tok_list, env); namesp->uri[0]->start = uri_start_p; namesp->uri[0]->size = uri_len; #endif namesp->no = 1; namesp->size = GUTHTHILA_XML_WRITER_NAMESP_DEF_SIZE; guththila_stack_push(&wr->namesp, namesp, env); elem->name_sp_stack_no = GUTHTHILA_STACK_TOP_INDEX(wr->namesp); } #ifndef GUTHTHILA_XML_WRITER_TOKEN elem->name = strdup(local_name); elem->prefix = strdup(prefix); #else elem->name = guththila_tok_list_get_token(&wr->tok_list, env); elem->prefix = guththila_tok_list_get_token(&wr->tok_list, env); elem->name->start = elem_start_p; elem->name->size = elem_len; elem->prefix->start = elem_pref_start_p; elem->prefix->size = pref_len; #endif guththila_stack_push(&wr->element, elem, env); } else { return GUTHTHILA_FAILURE; } return GUTHTHILA_SUCCESS; } GUTHTHILA_EXPORT int GUTHTHILA_CALL guththila_write_start_element_with_namespace( guththila_xml_writer_t * wr, guththila_char_t *namespace_uri, guththila_char_t *local_name, const axutil_env_t * env) { int i = 0, j = 0; int stack_size = GUTHTHILA_STACK_SIZE(wr->namesp); int temp = 0; int elem_start = 0; guththila_char_t *elem_start_p = NULL; size_t elem_len = 0; guththila_xml_writer_namesp_t * writer_namesp = NULL; guththila_xml_writer_element_t * element; elem_len = strlen(local_name); element = (guththila_xml_writer_element_t *)AXIS2_MALLOC(env->allocator, sizeof(guththila_xml_writer_element_t)); if(!element) return GUTHTHILA_FAILURE; for(i = stack_size - 1; i >= 0; i--) { writer_namesp = (guththila_xml_writer_namesp_t *)guththila_stack_get_by_index(&wr->namesp, i, env); temp = writer_namesp->no; for(j = 0; j < temp; j++) { #ifndef GUTHTHILA_XML_WRITER_TOKEN if(!strcmp(namespace_uri, writer_namesp->uri[j])) #else if (!guththila_tok_str_cmp (writer_namesp->uri[j], namespace_uri, strlen(namespace_uri), env)) #endif { i = 0; /* force exit from outer loop as well */ break; } } } /* Close off any preceding element and start a new element */ if(wr->status == START) { guththila_write(wr, "><", 2u, env); } else if(wr->status == START_EMPTY) { guththila_free_empty_element(wr, env); guththila_write(wr, "/><", 2u, env); } else if(wr->status == BEGINING) { guththila_write(wr, "<", 1u, env); } else { return GUTHTHILA_FAILURE; } /* If there is a prefix, include it. */ if(writer_namesp && (j < writer_namesp->no)) { #ifndef GUTHTHILA_XML_WRITER_TOKEN guththila_write(wr, writer_namesp->name[j], strlen(writer_namesp->name[j]), env); #else guththila_write_token(wr, writer_namesp->name[j], env); #endif guththila_write(wr, ":", 1u, env); } elem_start = wr->next; guththila_write_xtoken(wr, local_name, elem_len, env); elem_start_p = GUTHTHILA_BUF_POS(wr->buffer, elem_start); /* Remember this element's name and prefix, so the closing tag can be written later. */ #ifndef GUTHTHILA_XML_WRITER_TOKEN element->name = strdup(local_name); if(writer_namesp && (j < writer_namesp->no)) { element->prefix = strdup(writer_namesp->name[j]); } else { element->prefix = NULL; } #else element->name = guththila_tok_list_get_token(&wr->tok_list, env); element->name->size = elem_len; element->name->start = elem_start_p; if (writer_namesp && (j < writer_namesp->no)) { element->prefix = guththila_tok_list_get_token(&wr->tok_list, env); element->prefix->size = writer_namesp->name[j]->size; element->prefix->start = writer_namesp->name[j]->start; } else { element->prefix = NULL; } #endif element->name_sp_stack_no = -1; wr->status = START; return guththila_stack_push(&wr->element, element, env); } GUTHTHILA_EXPORT int GUTHTHILA_CALL guththila_write_start_element_with_prefix( guththila_xml_writer_t * wr, guththila_char_t *prefix, guththila_char_t *local_name, const axutil_env_t * env) { int i, j; int stack_size = GUTHTHILA_STACK_SIZE(wr->namesp); int temp; int elem_start = 0; guththila_char_t *elem_start_p = NULL; size_t elem_len = 0, pref_len = 0; guththila_xml_writer_namesp_t * writer_namesp = NULL; elem_len = strlen(local_name); pref_len = strlen(prefix); for(i = stack_size - 1; i >= 0; i--) { writer_namesp = (guththila_xml_writer_namesp_t *)guththila_stack_get_by_index(&wr-> namesp, i, env); temp = writer_namesp->no; for(j = 0; j < temp; j++) { /* if we found a namespace with the given prefix we can proceed */ #ifndef GUTHTHILA_XML_WRITER_TOKEN if(!strcmp(prefix, writer_namesp->name[j])) { #else if (!guththila_tok_str_cmp(writer_namesp->name[j], prefix, pref_len, env)) { #endif guththila_xml_writer_element_t * element = (guththila_xml_writer_element_t *)AXIS2_MALLOC(env-> allocator, sizeof(guththila_xml_writer_element_t)); if(wr->status == START) { guththila_write(wr, "><", 2u, env); guththila_write_xtoken(wr, prefix, pref_len, env); guththila_write(wr, ":", 1u, env); elem_start = wr->next; guththila_write_xtoken(wr, local_name, strlen(local_name), env); elem_start_p = GUTHTHILA_BUF_POS(wr->buffer, elem_start); } else if(wr->status == START_EMPTY) { guththila_free_empty_element(wr, env); guththila_write(wr, "/><", 3u, env); guththila_write_xtoken(wr, prefix, pref_len, env); guththila_write(wr, ":", 1u, env); elem_start = wr->next; guththila_write_xtoken(wr, local_name, strlen(local_name), env); elem_start_p = GUTHTHILA_BUF_POS(wr->buffer, elem_start); } else if(wr->status == BEGINING) { guththila_write(wr, "<", 1u, env); guththila_write_xtoken(wr, prefix, pref_len, env); guththila_write(wr, ":", 1u, env); elem_start = wr->next; guththila_write_xtoken(wr, local_name, strlen(local_name), env); elem_start_p = GUTHTHILA_BUF_POS(wr->buffer, elem_start); } else { return GUTHTHILA_FAILURE; } #ifndef GUTHTHILA_XML_WRITER_TOKEN element->name = strdup(local_name); element->prefix = strdup(prefix); #else element->name = guththila_tok_list_get_token(&wr->tok_list, env); element->name->size = elem_len; element->name->start = elem_start_p; element->prefix = guththila_tok_list_get_token(&wr->tok_list, env); element->prefix->size = writer_namesp->name[j]->size; element->prefix->start = writer_namesp->name[j]->start; #endif wr->status = START; element->name_sp_stack_no = -1; return guththila_stack_push(&wr->element, element, env); } } } return GUTHTHILA_FAILURE; } GUTHTHILA_EXPORT int GUTHTHILA_CALL guththila_write_empty_element_with_prefix_and_namespace( guththila_xml_writer_t * wr, guththila_char_t *prefix, guththila_char_t *namespace_uri, guththila_char_t *local_name, const axutil_env_t * env) { int i, j, temp, stack_size, nmsp_found = GUTHTHILA_FALSE; guththila_xml_writer_namesp_t * namesp = NULL; guththila_xml_writer_element_t * elem = NULL; int uri_start = 0, pref_start = 0, elem_start = 0, elem_pref_start = 0; guththila_char_t *uri_start_p = NULL, *pref_start_p = NULL; guththila_char_t *elem_start_p = NULL, *elem_pref_start_p = NULL ; size_t uri_len = 0; size_t pref_len = 0; size_t elem_len = 0; guththila_xml_writer_namesp_t * writer_namesp = NULL; namesp = (guththila_xml_writer_namesp_t *)AXIS2_MALLOC(env->allocator, sizeof(guththila_xml_writer_namesp_t)); elem = (guththila_xml_writer_element_t *)AXIS2_MALLOC(env->allocator, sizeof(guththila_xml_writer_element_t)); uri_len = strlen(namespace_uri); pref_len = strlen(prefix); elem_len = strlen(local_name); stack_size = GUTHTHILA_STACK_SIZE(wr->namesp); /* Chech weather we have defined this namespace before */ for(i = stack_size - 1; i >= 0; i--) { writer_namesp = (guththila_xml_writer_namesp_t *)guththila_stack_get_by_index(&wr->namesp, i, env); temp = writer_namesp->no; for(j = 0; j < temp; j++) { #ifndef GUTHTHILA_XML_WRITER_TOKEN if(!strcmp(uri, writer_namesp->uri[j])) { #else if (!guththila_tok_str_cmp (writer_namesp->name[j], prefix, pref_len, env)) { #endif nmsp_found = GUTHTHILA_TRUE; } } } if(namesp && elem) { elem->name_sp_stack_no = -1; if(wr->status == START) { guththila_write(wr, "><", 2u, env); elem_pref_start = wr->next; guththila_write_xtoken(wr, prefix, pref_len, env); elem_pref_start_p = GUTHTHILA_BUF_POS(wr->buffer, elem_pref_start); guththila_write(wr, ":", 1u, env); elem_start = wr->next; guththila_write_xtoken(wr, local_name, elem_len, env); elem_start_p = GUTHTHILA_BUF_POS(wr->buffer, elem_start); if(!nmsp_found) { guththila_write(wr, " ", 1u, env); guththila_write(wr, "xmlns:", 6u, env); pref_start = wr->next; guththila_write_xtoken(wr, prefix, pref_len, env); pref_start_p = GUTHTHILA_BUF_POS(wr->buffer, pref_start); guththila_write(wr, "=\"", 2u, env); uri_start = wr->next; guththila_write_xtoken(wr, namespace_uri, uri_len, env); uri_start_p = GUTHTHILA_BUF_POS(wr->buffer, uri_start); guththila_write(wr, "\"", 1u, env); } wr->status = START_EMPTY; } else if(wr->status == START_EMPTY) { guththila_free_empty_element(wr, env); guththila_write(wr, "/><", 2u, env); elem_pref_start = wr->next; guththila_write_xtoken(wr, prefix, pref_len, env); elem_pref_start_p = GUTHTHILA_BUF_POS(wr->buffer, elem_pref_start); guththila_write(wr, ":", 1u, env); elem_start = wr->next; guththila_write_xtoken(wr, local_name, elem_len, env); elem_start_p = GUTHTHILA_BUF_POS(wr->buffer, elem_start); if(!nmsp_found) { guththila_write(wr, " ", 1u, env); guththila_write(wr, "xmlns:", 6u, env); pref_start = wr->next; guththila_write_xtoken(wr, prefix, pref_len, env); pref_start_p = GUTHTHILA_BUF_POS(wr->buffer, pref_start); guththila_write(wr, "=\"", 2u, env); uri_start = wr->next; guththila_write_xtoken(wr, namespace_uri, uri_len, env); uri_start_p = GUTHTHILA_BUF_POS(wr->buffer, uri_start); guththila_write(wr, "\"", 1u, env); } } else if(wr->status == BEGINING) { guththila_write(wr, "<", 1u, env); elem_pref_start = wr->next; guththila_write_xtoken(wr, prefix, pref_len, env); elem_pref_start_p = GUTHTHILA_BUF_POS(wr->buffer, elem_pref_start); guththila_write(wr, ":", 1u, env); elem_start = wr->next; guththila_write_xtoken(wr, local_name, elem_len, env); elem_start_p = GUTHTHILA_BUF_POS(wr->buffer, elem_start); if(!nmsp_found) { guththila_write(wr, " ", 1u, env); guththila_write(wr, "xmlns:", 6u, env); pref_start = wr->next; guththila_write_xtoken(wr, prefix, pref_len, env); pref_start_p = GUTHTHILA_BUF_POS(wr->buffer, pref_start); guththila_write(wr, "=\"", 2u, env); uri_start = wr->next; guththila_write_xtoken(wr, namespace_uri, uri_len, env); uri_start_p = GUTHTHILA_BUF_POS(wr->buffer, uri_start); guththila_write(wr, "\"", 1u, env); } wr->status = START_EMPTY; } else { return GUTHTHILA_FAILURE; } if(!nmsp_found) { /* If the namespace is not defined we need to remember it for later*/ #ifndef GUTHTHILA_XML_WRITER_TOKEN namesp->name = (guththila_char_t **)AXIS2_MALLOC(env->allocator, sizeof(guththila_char_t *) * GUTHTHILA_XML_WRITER_NAMESP_DEF_SIZE); namesp->uri = (guththila_char_t **)AXIS2_MALLOC(env->allocator, sizeof(guththila_char_t *) * GUTHTHILA_XML_WRITER_NAMESP_DEF_SIZE); namesp->name[0] = strdup(prefix); namesp->uri[0] = strdup(namespace_uri); #else namesp->name = (guththila_token_t **) AXIS2_MALLOC(env->allocator, sizeof(guththila_token_t *) * GUTHTHILA_XML_WRITER_NAMESP_DEF_SIZE); namesp->uri = (guththila_token_t **) AXIS2_MALLOC(env->allocator, sizeof(guththila_token_t *) * GUTHTHILA_XML_WRITER_NAMESP_DEF_SIZE); namesp->name[0] = guththila_tok_list_get_token(&wr->tok_list, env); namesp->name[0]->start = pref_start_p; namesp->name[0]->size = pref_len; namesp->uri[0] = guththila_tok_list_get_token(&wr->tok_list, env); namesp->uri[0]->start = uri_start_p; namesp->uri[0]->size = uri_len; #endif namesp->no = 1; namesp->size = GUTHTHILA_XML_WRITER_NAMESP_DEF_SIZE; guththila_stack_push(&wr->namesp, namesp, env); elem->name_sp_stack_no = GUTHTHILA_STACK_TOP_INDEX(wr->namesp); } 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; }