
/*
 * 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 <tcpmon_util.h>
#include <axiom.h>

#define START_ELEMENT 1
#define CHAR_VALUE 2
#define END_ELEMENT 3
#define EMPTY_ELEMENT 4

typedef struct tcpmon_util_allocator
{
    int allocated;
    int index;
    axis2_char_t *buffer;
}
tcpmon_util_allocator_t;

axis2_char_t *tcpmon_strcat(
    char *dest,
    char *source,
    int *cur_buf_s,
    const axutil_env_t * env);

/*static void add_string(const axutil_env_t* env,
		       tcpmon_util_allocator_t* allocator,
		       axis2_char_t* string);
*/

/*static void add_axis2_char_t(const axutil_env_t* env,
			     tcpmon_util_allocator_t* allocator,
			     axis2_char_t c,
			     int turns);
*/
axis2_char_t *
tcpmon_util_format_as_xml(
    const axutil_env_t * env,
    axis2_char_t * data,
    int format)
{
    if (format)
    {
        int c;
        int tab_pos = 0;
        int has_value = 0;
        int has_space = 0;
        int start_ele = 0;
        int prev_case = 0;
        int buffer_size = 0;

        axis2_char_t *out;

        axiom_xml_reader_t *xml_reader = NULL;

        buffer_size = 2 * strlen(data);
        out = AXIS2_MALLOC(env->allocator, buffer_size * sizeof(axis2_char_t));

        if (data)
        {
            int size = 0;
            size = strlen(data);
            xml_reader =
                axiom_xml_reader_create_for_memory(env, data, size, "utf-8",
                                                   AXIS2_XML_PARSER_TYPE_BUFFER);
            if (!xml_reader)
                return AXIS2_FAILURE;
        }

        axiom_xml_reader_init();

        while ((c = axiom_xml_reader_next(xml_reader, env)) != -1)
        {
            switch (c)
            {
            case AXIOM_XML_READER_START_DOCUMENT:
                {
                    int ix;

                    tcpmon_strcat(out, "<?xml ", &buffer_size, env);

                    ix = axiom_xml_reader_get_attribute_count(xml_reader, env);
                    for (; ix > 0; ix--)
                    {
                        axis2_char_t *attr_prefix;
                        axis2_char_t *attr_name;
                        axis2_char_t *attr_value;

                        attr_prefix =
                            (axis2_char_t *)
                            axiom_xml_reader_get_attribute_prefix_by_number
                            (xml_reader, env, ix);
                        if (attr_prefix)
                        {
                            tcpmon_strcat(out, attr_prefix, &buffer_size, env);
                            tcpmon_strcat(out, ":", &buffer_size, env);
                        }

                        attr_name =
                            (axis2_char_t *)
                            axiom_xml_reader_get_attribute_name_by_number
                            (xml_reader, env, ix);
                        if (attr_name)
                        {
                            tcpmon_strcat(out, attr_name, &buffer_size, env);
                            tcpmon_strcat(out, "=\"", &buffer_size, env);
                        }

                        attr_value =
                            (axis2_char_t *)
                            axiom_xml_reader_get_attribute_value_by_number
                            (xml_reader, env, ix);
                        if (attr_value)
                        {
                            tcpmon_strcat(out, attr_value, &buffer_size, env);
                            tcpmon_strcat(out, "\"", &buffer_size, env);
                        }
                    }

                    printf("?>");
                }
                break;
            case AXIOM_XML_READER_START_ELEMENT:
                {
                    int i,
                     ix,
                     has_prefix = 0;

                    axis2_char_t *ele_name;
                    axis2_char_t *ele_prefix;

                    prev_case = START_ELEMENT;

                    has_value = 0;
                    has_space = 0;

                    if (start_ele != 0)
                        tcpmon_strcat(out, "\n", &buffer_size, env);

                    for (i = 0; i < tab_pos; i++)
                        tcpmon_strcat(out, "\t", &buffer_size, env);

                    tcpmon_strcat(out, "<", &buffer_size, env);

                    ele_prefix =
                        (axis2_char_t *) axiom_xml_reader_get_prefix(xml_reader,
                                                                     env);
                    if (ele_prefix)
                    {
                        tcpmon_strcat(out, ele_prefix, &buffer_size, env);
                        tcpmon_strcat(out, ":", &buffer_size, env);
                    }

                    ele_name =
                        (axis2_char_t *) axiom_xml_reader_get_name(xml_reader,
                                                                   env);
                    if (ele_name)
                    {
                        tcpmon_strcat(out, ele_name, &buffer_size, env);
                    }

                    ix = axiom_xml_reader_get_attribute_count(xml_reader, env);
                    for (; ix > 0; ix--)
                    {
                        axis2_char_t *attr_prefix;
                        axis2_char_t *attr_name;
                        axis2_char_t *attr_value;

                        attr_prefix =
                            (axis2_char_t *)
                            axiom_xml_reader_get_attribute_prefix_by_number
                            (xml_reader, env, ix);
                        if (attr_prefix)
                        {
                            has_prefix = 1;
                            tcpmon_strcat(out, " ", &buffer_size, env);
                            tcpmon_strcat(out, attr_prefix, &buffer_size, env);
                            tcpmon_strcat(out, ":", &buffer_size, env);
                        }

                        attr_name =
                            (axis2_char_t *)
                            axiom_xml_reader_get_attribute_name_by_number
                            (xml_reader, env, ix);
                        if (attr_name)
                        {
                            if (has_prefix)
                            {
                                tcpmon_strcat(out, attr_name, &buffer_size,
                                              env);
                                tcpmon_strcat(out, "=\"", &buffer_size, env);
                            }
                            else
                            {
                                tcpmon_strcat(out, " ", &buffer_size, env);
                                tcpmon_strcat(out, attr_name, &buffer_size,
                                              env);
                                tcpmon_strcat(out, "=\"", &buffer_size, env);
                            }

                            has_prefix = 0;
                        }

                        attr_value =
                            (axis2_char_t *)
                            axiom_xml_reader_get_attribute_value_by_number
                            (xml_reader, env, ix);
                        if (attr_value)
                        {
                            tcpmon_strcat(out, attr_value, &buffer_size, env);
                            tcpmon_strcat(out, "\"", &buffer_size, env);
                        }
                    }

                    tcpmon_strcat(out, ">", &buffer_size, env);

                    tab_pos++;
                    start_ele = 1;
                }
                break;
            case AXIOM_XML_READER_CHARACTER:
                {
                    axis2_char_t *ele_value;

                    prev_case = CHAR_VALUE;

                    ele_value = axiom_xml_reader_get_value(xml_reader, env);
                    if (ele_value)
                        tcpmon_strcat(out, ele_value, &buffer_size, env);

                    has_value = 1;

                }
                break;
            case AXIOM_XML_READER_EMPTY_ELEMENT:
                {
                    int i,
                     ix,
                     has_prefix = 0;

                    axis2_char_t *ele_name;
                    axis2_char_t *ele_prefix;

                    prev_case = EMPTY_ELEMENT;

                    has_value = 0;
                    has_space = 0;

                    if (start_ele != 0)
                        tcpmon_strcat(out, "\n", &buffer_size, env);

                    for (i = 0; i < tab_pos; i++)
                        tcpmon_strcat(out, "\t", &buffer_size, env);

                    tcpmon_strcat(out, "<", &buffer_size, env);

                    ele_prefix =
                        (axis2_char_t *) axiom_xml_reader_get_prefix(xml_reader,
                                                                     env);
                    if (ele_prefix)
                    {
                        tcpmon_strcat(out, ele_prefix, &buffer_size, env);
                        tcpmon_strcat(out, ":", &buffer_size, env);
                    }

                    ele_name =
                        (axis2_char_t *) axiom_xml_reader_get_name(xml_reader,
                                                                   env);
                    if (ele_name)
                        tcpmon_strcat(out, ele_name, &buffer_size, env);

                    ix = axiom_xml_reader_get_attribute_count(xml_reader, env);
                    for (; ix > 0; ix--)
                    {
                        axis2_char_t *attr_prefix;
                        axis2_char_t *attr_name;
                        axis2_char_t *attr_value;

                        attr_prefix =
                            (axis2_char_t *)
                            axiom_xml_reader_get_attribute_prefix_by_number
                            (xml_reader, env, ix);
                        if (attr_prefix)
                        {
                            has_prefix = 1;
                            tcpmon_strcat(out, " ", &buffer_size, env);
                            tcpmon_strcat(out, attr_prefix, &buffer_size, env);
                            tcpmon_strcat(out, ":", &buffer_size, env);
                        }

                        attr_name =
                            (axis2_char_t *)
                            axiom_xml_reader_get_attribute_name_by_number
                            (xml_reader, env, ix);
                        if (attr_name)
                        {
                            if (has_prefix)
                            {
                                tcpmon_strcat(out, attr_name, &buffer_size,
                                              env);
                                tcpmon_strcat(out, "=\"", &buffer_size, env);
                            }
                            else
                            {
                                tcpmon_strcat(out, " ", &buffer_size, env);
                                tcpmon_strcat(out, attr_name, &buffer_size,
                                              env);
                                tcpmon_strcat(out, "=\"", &buffer_size, env);
                            }
                            has_prefix = 0;
                        }

                        attr_value =
                            (axis2_char_t *)
                            axiom_xml_reader_get_attribute_value_by_number
                            (xml_reader, env, ix);
                        if (attr_value)
                        {
                            tcpmon_strcat(out, attr_value, &buffer_size, env);
                            tcpmon_strcat(out, "\"", &buffer_size, env);
                        }
                    }

                    tcpmon_strcat(out, "/>", &buffer_size, env);
                    start_ele = 1;
                }
                break;
            case AXIOM_XML_READER_END_ELEMENT:
                {
                    int i;

                    axis2_char_t *ele_prefix;
                    axis2_char_t *ele_name;

                    tab_pos--;

                    if (has_value == 0 && prev_case != START_ELEMENT)
                    {
                        tcpmon_strcat(out, "\n", &buffer_size, env);
                        for (i = 0; i < tab_pos; i++)
                            tcpmon_strcat(out, "\t", &buffer_size, env);
                    }

                    has_value = 0;

                    tcpmon_strcat(out, "</", &buffer_size, env);

                    ele_prefix =
                        (axis2_char_t *) axiom_xml_reader_get_prefix(xml_reader,
                                                                     env);
                    if (ele_prefix)
                    {
                        tcpmon_strcat(out, ele_prefix, &buffer_size, env);
                        tcpmon_strcat(out, ":", &buffer_size, env);
                    }

                    ele_name =
                        (axis2_char_t *) axiom_xml_reader_get_name(xml_reader,
                                                                   env);
                    if (ele_name)
                    {
                        tcpmon_strcat(out, ele_name, &buffer_size, env);
                        tcpmon_strcat(out, ">", &buffer_size, env);
                    }
                    prev_case = END_ELEMENT;

                }
                break;
            }
        }
        return out;
    }
    return data;
}

/*void add_string(const axutil_env_t* env,
		tcpmon_util_allocator_t* allocator,
		axis2_char_t* string)
{
  int additional_len = 0;
  void* dest = NULL;
  void* src = NULL;
  int count = 0;

  additional_len = axutil_strlen(string) + 1;
  if (allocator-> index + additional_len  >= allocator-> allocated)
    {
      if (allocator-> allocated == 0)
        {
	  allocator-> buffer =
	    AXIS2_MALLOC(env-> allocator, additional_len);
        }
      else
        {
	  allocator-> buffer =
	    AXIS2_REALLOC(env-> allocator, allocator-> buffer,
			  allocator-> allocated + additional_len);
        }
      allocator-> allocated += additional_len;
    }

  dest = allocator-> buffer + allocator-> index;
  src = string;
  count = additional_len; 
  memcpy(dest, src, count);

  allocator-> index += count - 1;
}
*/

/*void add_axis2_char_t(const axutil_env_t* env,
		      tcpmon_util_allocator_t* allocator,
		      axis2_char_t c,
		      int turns)
{
  int additional_len = 0;

  additional_len = turns + 1;
  if (allocator-> index + additional_len  >= allocator-> allocated)
    {
      if (allocator-> allocated == 0)
        {
	  allocator-> buffer =
	    AXIS2_MALLOC(env-> allocator, additional_len);
        }
      else
        {
	  allocator-> buffer =
	    AXIS2_REALLOC(env-> allocator, allocator-> buffer,
			  allocator-> allocated + additional_len);
        }
      allocator-> allocated += additional_len;
    }

  memset(allocator-> buffer + allocator-> index, c, turns);

  allocator-> index += turns;

} */

axis2_char_t *
tcpmon_strcat(
    axis2_char_t * dest,
    axis2_char_t * source,
    int *buff_size,
    const axutil_env_t * env)
{
    int cur_len = 0;
    int source_len = 0;

    axis2_char_t *tmp;
    cur_len = strlen(dest);
    source_len = strlen(source);

    if ((*buff_size - cur_len) < source_len)
    {
        *buff_size = *buff_size + (*buff_size * 2);
        tmp =
            (axis2_char_t *) AXIS2_REALLOC(env->allocator, dest,
                                           *buff_size * sizeof(axis2_char_t));
        dest = tmp;
        strcat((char *) dest, (char *) source);
    }
    else
    {
        strcat((char *) dest, (char *) source);
    }

    return dest;
}
