You are viewing a plain text version of this content. The canonical link for it is here.
Posted to rampart-dev@ws.apache.org by sh...@apache.org on 2009/09/21 07:12:59 UTC

svn commit: r817158 - in /webservices/rampart/trunk/c/src/omxmlsec/c14n: c14n.c sorted_list.c

Author: shankar
Date: Mon Sep 21 05:12:58 2009
New Revision: 817158

URL: http://svn.apache.org/viewvc?rev=817158&view=rev
Log:
improving performance

Modified:
    webservices/rampart/trunk/c/src/omxmlsec/c14n/c14n.c
    webservices/rampart/trunk/c/src/omxmlsec/c14n/sorted_list.c

Modified: webservices/rampart/trunk/c/src/omxmlsec/c14n/c14n.c
URL: http://svn.apache.org/viewvc/webservices/rampart/trunk/c/src/omxmlsec/c14n/c14n.c?rev=817158&r1=817157&r2=817158&view=diff
==============================================================================
--- webservices/rampart/trunk/c/src/omxmlsec/c14n/c14n.c (original)
+++ webservices/rampart/trunk/c/src/omxmlsec/c14n/c14n.c Mon Sep 21 05:12:58 2009
@@ -35,7 +35,7 @@
 #define N_C14N_DEBUG
 
 #define DEFAULT_STACK_SIZE 16
-#define INIT_BUFFER_SIZE 256
+#define INIT_BUFFER_SIZE 1024
 
 #define c14n_ns_stack_push(save_stack, ctx) \
         (save_stack)->head = (ctx)->ns_stack->head; \
@@ -69,19 +69,31 @@
     axiom_namespace_t *def_ns; /*default ns in current scope*/
 } c14n_ns_stack_t;
 
+typedef struct c14n_buffer
+{
+    /* Required to manipulate multiple buffers */
+    size_t *buffs_size;         /* Array containing actual sizes of buffers */
+    axis2_char_t **buff;        /* Array of buffers */
+    int cur_buff_index;         /* Current buffer */
+    int cur_buff_pos;           /* Position of the current buffer */
+    unsigned int no_buffers;    /* No of buffers */
+
+    axis2_char_t *cur_buff;     /* current buffer; kept separately for performance */
+    int cur_buff_size;          /* kept separately for performance */
+} c14n_buffer_t;
+
 typedef struct c14n_ctx {
     const axutil_env_t *env;
-    const axiom_document_t *doc;
+    axiom_document_t *doc;
     axis2_bool_t comments;
-    axutil_stream_t *outstream;
+    c14n_buffer_t *outbuffer;
     axis2_bool_t exclusive;
-    const axutil_array_list_t *ns_prefixes;
-    const axiom_node_t *node;
+    axutil_array_list_t *ns_prefixes;
+    axiom_node_t *node;
     c14n_ns_stack_t *ns_stack;
 } c14n_ctx_t;
 
 /*Function prototypes for ns stack*/
-
 static c14n_ns_stack_t*
 c14n_ns_stack_create(
     const c14n_ctx_t *ctx
@@ -94,15 +106,8 @@
 
 static axis2_status_t
 c14n_ns_stack_find(
-    const axiom_namespace_t *ns,
-    const c14n_ctx_t *ctx
-);
-
-static axis2_status_t
-c14n_ns_stack_find_with_prefix_uri(
-    const axis2_char_t *prefix,
-    const axis2_char_t *uri,
-    const c14n_ctx_t *ctx
+    axiom_namespace_t *ns,
+    c14n_ctx_t *ctx
 );
 
 static axis2_status_t
@@ -134,7 +139,8 @@
     return ns_stack;
 }
 
-static axis2_status_t c14n_ns_stack_add(
+static axis2_status_t
+c14n_ns_stack_add(
     axiom_namespace_t *ns,
     const c14n_ctx_t *ctx)
 {
@@ -185,19 +191,20 @@
 }
 
 /*
- * TODO: DONE
- * Find process should be changed ( if the ns has the same prefix but diff uri) 
+ * Find process should  find if the ns has the same prefix but diff uri
  * Eg: <a xmlns:x="a">
  *      <b xmlns:x="b">
  *       <c xmlns:x="a"/>
  *      </b>
  *     </a>
  * */
-static axis2_status_t c14n_ns_stack_find_with_prefix_uri(
-    const axis2_char_t *prefix,
-    const axis2_char_t *uri,
-    const c14n_ctx_t *ctx)
+static axis2_status_t
+c14n_ns_stack_find(
+    axiom_namespace_t *ns,
+    c14n_ctx_t *ctx)
 {
+    axis2_char_t *prefix = axiom_namespace_get_prefix(ns, ctx->env);
+    axis2_char_t *uri = axiom_namespace_get_uri(ns, ctx->env);
     int i;
     c14n_ns_stack_t *ns_stack = ctx->ns_stack;
     if(ns_stack->stack) /*Is this necessary?*/
@@ -212,7 +219,7 @@
                 if(axutil_strcmp(uri_i, uri) == 0)
                     return AXIS2_SUCCESS;
                 else
-                    return AXIS2_FALSE;
+                    return AXIS2_FAILURE;
             }
             else
                 continue;
@@ -222,14 +229,6 @@
     return AXIS2_FAILURE;
 }
 
-static axis2_status_t c14n_ns_stack_find(
-    const axiom_namespace_t *ns,
-    const c14n_ctx_t *ctx)
-{
-    return (c14n_ns_stack_find_with_prefix_uri(axiom_namespace_get_prefix((axiom_namespace_t *) ns,
-        ctx->env), axiom_namespace_get_uri((axiom_namespace_t *) ns, ctx->env), ctx));
-}
-
 static void
 c14n_ns_stack_free(
     c14n_ctx_t *ctx)
@@ -242,6 +241,206 @@
     ctx->ns_stack = NULL;
 }
 
+static c14n_buffer_t *
+c14n_buffer_create(
+    const axutil_env_t *env)
+{
+    c14n_buffer_t *buffer = (c14n_buffer_t *)AXIS2_MALLOC(env->allocator, sizeof(c14n_buffer_t));
+    if(!buffer)
+    {
+        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+            "[rampart]Cannot create c14n_buffer structure. Insufficient memory");
+        return NULL;
+    }
+
+    buffer->buffs_size = (size_t *)AXIS2_MALLOC(env->allocator, sizeof(size_t) * DEFAULT_STACK_SIZE);
+    if(!buffer->buffs_size)
+    {
+        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+            "[rampart]Cannot create c14n_buffer size array structure. Insufficient memory");
+        AXIS2_FREE(env->allocator, buffer);
+        return NULL;
+    }
+
+    buffer->buff = (axis2_char_t **)
+        AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t *) * DEFAULT_STACK_SIZE);
+    if(!buffer->buff)
+    {
+        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+            "[rampart]Cannot create c14n_buffer array structure. Insufficient memory");
+        AXIS2_FREE(env->allocator, buffer);
+        AXIS2_FREE(env->allocator, buffer->buffs_size);
+        return NULL;
+    }
+
+    buffer->buff[0] = (axis2_char_t *)
+        AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * INIT_BUFFER_SIZE);
+    if(!buffer->buff[0])
+    {
+        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+            "[rampart]Cannot create c14n buffer. Insufficient memory");
+        AXIS2_FREE(env->allocator, buffer);
+        AXIS2_FREE(env->allocator, buffer->buffs_size);
+        AXIS2_FREE(env->allocator, buffer->buff);
+        return NULL;
+    }
+
+    buffer->cur_buff = buffer->buff[0];
+    buffer->cur_buff_pos = 0;
+    buffer->no_buffers = DEFAULT_STACK_SIZE;
+    buffer->buffs_size[0] = INIT_BUFFER_SIZE;
+    buffer->cur_buff_index = 0;
+    buffer->cur_buff_size = INIT_BUFFER_SIZE;
+
+    return buffer;
+}
+
+static void
+c14n_create_new_buffer(
+    c14n_buffer_t * buffer,
+    const axutil_env_t *env,
+    int length)
+{
+    int curr_buff = buffer->cur_buff_index;
+    int buff_size = buffer->cur_buff_size * 2;
+    while(length > buff_size)
+    {
+        buff_size *= 2;
+    }
+    if(curr_buff == buffer->no_buffers - 1)
+    {
+        axis2_char_t ** temp_buff = NULL;
+        size_t *temp_size = NULL;
+        int i = 0;
+        int buffer_size = buffer->no_buffers * 2;
+
+        temp_buff = (axis2_char_t **)
+            AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t *) * buffer_size);
+        if(!temp_buff)
+        {
+            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "[rampart]Insufficient memory to create buffer");
+            return;
+        }
+
+        temp_size = (size_t *)AXIS2_MALLOC(env->allocator, sizeof(size_t) * buffer_size);
+        if(!temp_size)
+        {
+            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "[rampart]Insufficient memory to create buffer");
+            return;
+        }
+
+        for(i = 0; i <= curr_buff; ++i)
+        {
+            temp_buff[i] = buffer->buff[i];
+            temp_size[i] = buffer->buffs_size[i];
+        }
+
+        AXIS2_FREE(env->allocator, buffer->buff);
+        AXIS2_FREE(env->allocator, buffer->buffs_size);
+        buffer->no_buffers = buffer_size;
+        buffer->buff = temp_buff;
+        buffer->buffs_size = temp_size;
+    }
+
+    buffer->buff[++curr_buff] = (axis2_char_t *)
+        AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * buff_size);
+    if(!buffer->buff[curr_buff])
+    {
+        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "[rampart]Insufficient memory to create buffer");
+        return;
+    }
+
+    ++(buffer->cur_buff_index);
+    buffer->buffs_size[curr_buff] = buff_size;
+    buffer->cur_buff_pos = 0;
+    buffer->cur_buff = buffer->buff[curr_buff];
+    buffer->cur_buff_size = buff_size;
+}
+
+static int
+c14_buffer_get_total_data_size(
+    c14n_buffer_t *buffer,
+    const axutil_env_t *env)
+{
+    int i = 0;
+    int length = 0;
+    int cur_buff = buffer->cur_buff_index;
+    for(i = 0; i < cur_buff; ++i)
+    {
+        length += buffer->buffs_size[i];
+    }
+
+    length += buffer->cur_buff_pos;
+    return length;
+}
+
+static void
+c14n_buffer_copy_data(
+    c14n_buffer_t *buffer,
+    const axutil_env_t *env,
+    axis2_char_t *output)
+{
+    int i = 0;
+    int cur_buff = buffer->cur_buff_index;
+    for(i = 0; i < cur_buff; ++i)
+    {
+        memcpy(output, buffer->buff[i], buffer->buffs_size[i]);
+        output += buffer->buffs_size[i];
+    }
+
+    memcpy(output, buffer->buff[cur_buff], buffer->cur_buff_pos);
+}
+
+static void
+c14n_buffer_free(
+    c14n_buffer_t *buffer,
+    const axutil_env_t *env)
+{
+    int i = 0;
+    int cur_buff = buffer->cur_buff_index;
+    for(i = 0; i <= cur_buff; ++i)
+    {
+        AXIS2_FREE(env->allocator, buffer->buff[i]);
+    }
+    AXIS2_FREE(env->allocator, buffer->buff);
+    AXIS2_FREE(env->allocator, buffer->buffs_size);
+    AXIS2_FREE(env->allocator, buffer);
+}
+
+#define C14N_BUFFER_ADD_CHAR(buffer, env, ch)\
+{\
+    int cur_buff_pos = buffer->cur_buff_pos++;\
+    if(cur_buff_pos == buffer->cur_buff_size)\
+    {\
+        c14n_create_new_buffer(buffer, env, 0);\
+        cur_buff_pos = buffer->cur_buff_pos++;\
+    }\
+\
+    buffer->cur_buff[cur_buff_pos] = ch;\
+}
+
+#define C14N_BUFFER_ADD_STRING_WITH_LENGTH(buffer, env, str, length)\
+{\
+    int diff = buffer->cur_buff_size - buffer->cur_buff_pos;\
+    if(length <= diff)\
+    {\
+        memcpy(buffer->cur_buff + buffer->cur_buff_pos, str, length);\
+        buffer->cur_buff_pos += length;\
+    }\
+    else\
+    {\
+        memcpy(buffer->cur_buff + buffer->cur_buff_pos, str, diff);\
+        c14n_create_new_buffer(buffer, env, length - diff);\
+        memcpy(buffer->cur_buff, str + diff, length-diff);\
+        buffer->cur_buff_pos = length - diff;\
+    }\
+}
+
+#define C14N_BUFFER_ADD_STRING(buffer, env, str)\
+{\
+    C14N_BUFFER_ADD_STRING_WITH_LENGTH(buffer, env, str, axutil_strlen(str));\
+}
+
 /* Function Prototypes */
 
 static axis2_status_t
@@ -251,9 +450,9 @@
 
 static axis2_status_t
 c14n_apply_on_namespace_axis(
-    const axiom_element_t *ele,
-    const axiom_node_t *node,
-    const c14n_ctx_t *ctx);
+    axiom_element_t *ele,
+    axiom_node_t *node,
+    c14n_ctx_t *ctx);
 
 static axis2_status_t
 c14n_apply_on_namespace_axis_exclusive(
@@ -274,12 +473,8 @@
 static void
 c14n_apply_on_comment(
     axiom_node_t *node,
-    c14n_ctx_t *ctx);
-
-static void
-c14n_output(
-    const axis2_char_t *str,
-    const c14n_ctx_t *ctx);
+    c14n_buffer_t *buffer,
+    const axutil_env_t *env);
 
 static int
 attr_compare(
@@ -299,13 +494,13 @@
     const void *ns2,
     const void *context);
 
-static axis2_char_t*
-c14n_normalize_attribute(
+static void
+c14n_add_normalize_attribute(
     axis2_char_t *attval,
-    const c14n_ctx_t *ctx);
+    c14n_ctx_t *ctx);
 
-static axis2_char_t*
-c14n_normalize_text(
+static void
+c14n_add_normalize_text(
     axis2_char_t *text,
     c14n_ctx_t *ctx);
 
@@ -364,12 +559,12 @@
 static c14n_ctx_t*
 c14n_init(
     const axutil_env_t *env,
-    const axiom_document_t *doc,
+    axiom_document_t *doc,
     axis2_bool_t comments,
-    axutil_stream_t *stream,
-    const axis2_bool_t exclusive,
-    const axutil_array_list_t *ns_prefixes,
-    const axiom_node_t *node)
+    c14n_buffer_t *outbuffer,
+    axis2_bool_t exclusive,
+    axutil_array_list_t *ns_prefixes,
+    axiom_node_t *node)
 {
     c14n_ctx_t *ctx = (c14n_ctx_t *) (AXIS2_MALLOC(env->allocator, sizeof(c14n_ctx_t)));
     if(!ctx)
@@ -385,7 +580,7 @@
     ctx->exclusive = exclusive;
     ctx->ns_prefixes = ns_prefixes;
     ctx->node = node;
-    ctx->outstream = stream;
+    ctx->outbuffer = outbuffer;
     ctx->ns_stack = c14n_ns_stack_create(ctx);
     if(!ctx->ns_stack)
     {
@@ -424,7 +619,8 @@
     return (axiom_node_t *) prv_parent;
 }
 
-static c14n_algo_t c14n_get_algorithm(
+static c14n_algo_t
+c14n_get_algorithm(
     const axis2_char_t* algo)
 {
     if(axutil_strcmp(algo, OXS_HREF_XML_C14N) == 0)
@@ -442,80 +638,26 @@
     return 0; /*c14n_algo_t enum starts with 1*/
 }
 
-AXIS2_EXTERN axis2_status_t AXIS2_CALL
-oxs_c14n_apply_stream_algo(
-    const axutil_env_t *env,
-    const axiom_document_t *doc,
-    axutil_stream_t *stream,
-    const axutil_array_list_t *ns_prefixes,
-    const axiom_node_t *node,
-    const axis2_char_t* algo)
-{
-    switch(c14n_get_algorithm(algo))
-    {
-        case C14N_XML_C14N:
-            return oxs_c14n_apply_stream(env, doc, AXIS2_FALSE, stream, AXIS2_FALSE, ns_prefixes,
-                node);
-        case C14N_XML_C14N_WITH_COMMENTS:
-            return oxs_c14n_apply_stream(env, doc, AXIS2_TRUE, stream, AXIS2_FALSE, ns_prefixes,
-                node);
-        case C14N_XML_EXC_C14N:
-            return oxs_c14n_apply_stream(env, doc, AXIS2_FALSE, stream, AXIS2_TRUE, ns_prefixes,
-                node);
-        case C14N_XML_EXC_C14N_WITH_COMMENTS:
-            return oxs_c14n_apply_stream(env, doc, AXIS2_TRUE, stream, AXIS2_TRUE, ns_prefixes,
-                node);
-        default:
-            /*TODO: set the error*/
-            return AXIS2_FAILURE;
-    }
-}
-
-AXIS2_EXTERN axis2_status_t AXIS2_CALL
-oxs_c14n_apply_algo(
-    const axutil_env_t *env,
-    const axiom_document_t *doc,
-    axis2_char_t **outbuf,
-    const axutil_array_list_t *ns_prefixes,
-    const axiom_node_t *node,
-    const axis2_char_t *algo)
-{
-    switch(c14n_get_algorithm(algo))
-    {
-        case C14N_XML_C14N:
-            return oxs_c14n_apply(env, doc, AXIS2_FALSE, outbuf, AXIS2_FALSE, ns_prefixes, node);
-        case C14N_XML_C14N_WITH_COMMENTS:
-            return oxs_c14n_apply(env, doc, AXIS2_TRUE, outbuf, AXIS2_FALSE, ns_prefixes, node);
-        case C14N_XML_EXC_C14N:
-            return oxs_c14n_apply(env, doc, AXIS2_FALSE, outbuf, AXIS2_TRUE, ns_prefixes, node);
-        case C14N_XML_EXC_C14N_WITH_COMMENTS:
-            return oxs_c14n_apply(env, doc, AXIS2_TRUE, outbuf, AXIS2_TRUE, ns_prefixes, node);
-        default:
-            /*TODO:set the error*/
-            return AXIS2_FAILURE;
-    }
-}
-
-AXIS2_EXTERN axis2_status_t AXIS2_CALL
+static axis2_status_t
 oxs_c14n_apply_stream(
     const axutil_env_t *env,
-    const axiom_document_t *doc,
+    axiom_document_t *doc,
     axis2_bool_t comments,
-    axutil_stream_t *stream,
-    const axis2_bool_t exclusive,
-    const axutil_array_list_t *ns_prefixes,
-    const axiom_node_t *node)
+    c14n_buffer_t *outbuffer,
+    axis2_bool_t exclusive,
+    axutil_array_list_t *ns_prefixes,
+    axiom_node_t *node)
 {
     c14n_ctx_t *ctx = NULL;
     axis2_status_t status = AXIS2_SUCCESS;
 
-    if(!stream)
+    if(!outbuffer)
     {
-        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "[rampart]stream is not given to do c14n");
+        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "[rampart]outbuffer is not given to do c14n");
         return AXIS2_FAILURE;
     }
 
-    ctx = c14n_init(env, doc, comments, stream, exclusive, ns_prefixes, node);
+    ctx = c14n_init(env, doc, comments, outbuffer, exclusive, ns_prefixes, node);
     if(!ctx)
     {
         AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
@@ -533,50 +675,73 @@
         }
     }
 
-    status = c14n_apply_on_node((axiom_node_t *)node, ctx);
+    status = c14n_apply_on_node(node, ctx);
     c14n_ctx_free(ctx);
     return status;
 }
 
-
-AXIS2_EXTERN axis2_status_t AXIS2_CALL
+static axis2_status_t
 oxs_c14n_apply(
     const axutil_env_t *env,
-    const axiom_document_t *doc,
-    const axis2_bool_t comments,
+    axiom_document_t *doc,
+    axis2_bool_t comments,
     axis2_char_t **outbuf,
-    const axis2_bool_t exclusive,
-    const axutil_array_list_t *ns_prefixes,
-    const axiom_node_t *node)
-{
-    axutil_stream_t *stream = axutil_stream_create_basic(env);
-    axis2_status_t ret = oxs_c14n_apply_stream(env, doc, comments, stream, exclusive, ns_prefixes,
-        node);
-
-    *outbuf = NULL;
-
-    if(!ret)
-    {
-        return AXIS2_FAILURE;
-    }
-    else
+    axis2_bool_t exclusive,
+    axutil_array_list_t *ns_prefixes,
+    axiom_node_t *node)
+{
+    c14n_buffer_t *outbuffer = c14n_buffer_create(env);
+    if(oxs_c14n_apply_stream(env, doc, comments, outbuffer, exclusive, ns_prefixes, node)
+        == AXIS2_SUCCESS)
     {
-        int len = axutil_stream_get_len(stream, env) + 1;
+        int len = c14_buffer_get_total_data_size(outbuffer, env);
         if(len > 0)
         {
-            *outbuf = (axis2_char_t *) (AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * len));
-            axutil_stream_read(stream, env, *outbuf, len);
-            axutil_stream_free(stream, env);
-            stream = NULL;
+            *outbuf = (axis2_char_t *)AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * len + 1);
+            c14n_buffer_copy_data(outbuffer, env, *outbuf);
+            (*outbuf)[len] = '\0';
+            c14n_buffer_free(outbuffer, env);
             return AXIS2_SUCCESS;
         }
         else
         {
-            axutil_stream_free(stream, env);
-            stream = NULL;
-            return AXIS2_FAILURE;
+            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "[rampart]invalid c14n output length");
         }
     }
+    else
+    {
+        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "[rampart]applying c14n failed");
+    }
+    c14n_buffer_free(outbuffer, env);
+    return AXIS2_FAILURE;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+oxs_c14n_apply_algo(
+    const axutil_env_t *env,
+    const axiom_document_t *doc,
+    axis2_char_t **outbuf,
+    const axutil_array_list_t *ns_prefixes,
+    const axiom_node_t *node,
+    const axis2_char_t *algo)
+{
+    axiom_document_t *pdoc = (axiom_document_t *)doc;
+    axutil_array_list_t *pns_prefixes = (axutil_array_list_t *)ns_prefixes;
+    axiom_node_t *pnode = (axiom_node_t *)node;
+    switch(c14n_get_algorithm(algo))
+    {
+        case C14N_XML_C14N:
+            return oxs_c14n_apply(env, pdoc, AXIS2_FALSE, outbuf, AXIS2_FALSE, pns_prefixes, pnode);
+        case C14N_XML_C14N_WITH_COMMENTS:
+            return oxs_c14n_apply(env, pdoc, AXIS2_TRUE, outbuf, AXIS2_FALSE, pns_prefixes, pnode);
+        case C14N_XML_EXC_C14N:
+            return oxs_c14n_apply(env, pdoc, AXIS2_FALSE, outbuf, AXIS2_TRUE, pns_prefixes, pnode);
+        case C14N_XML_EXC_C14N_WITH_COMMENTS:
+            return oxs_c14n_apply(env, pdoc, AXIS2_TRUE, outbuf, AXIS2_TRUE, pns_prefixes, pnode);
+        default:
+            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "[rampart]Invalid c14n algorithm [%s]", algo);
+            return AXIS2_FAILURE;
+    }
 }
 
 static axis2_status_t
@@ -584,26 +749,19 @@
     axiom_node_t *node,
     c14n_ctx_t *ctx)
 {
-    axiom_text_t *text = (axiom_text_t *) axiom_node_get_data_element(node, ctx->env);
+    const axutil_env_t *env = ctx->env;
+    axiom_text_t *text = (axiom_text_t *) axiom_node_get_data_element(node, env);
 
     if(text)
     {
-        axis2_char_t *textval = (axis2_char_t*) axiom_text_get_text(text, ctx->env);
-        if(!textval)
-        {
-            AXIS2_LOG_ERROR(ctx->env->log, AXIS2_LOG_SI, "[rampart]cannot get text from node");
-            return AXIS2_FAILURE;
-        }
-
-        textval = c14n_normalize_text(textval, ctx);
+        axis2_char_t *textval = (axis2_char_t*) axiom_text_get_text(text, env);
         if(!textval)
         {
-            AXIS2_LOG_ERROR(ctx->env->log, AXIS2_LOG_SI, "[rampart]cannot normalize text");
+            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "[rampart]cannot get text from node");
             return AXIS2_FAILURE;
         }
 
-        c14n_output(textval, ctx);
-        AXIS2_FREE(ctx->env->allocator, textval);
+        c14n_add_normalize_text(textval, ctx);
     }
 
     return AXIS2_SUCCESS;
@@ -625,7 +783,7 @@
         case AXIOM_COMMENT:
             if(ctx->comments)
             {
-                c14n_apply_on_comment(node, ctx);
+                c14n_apply_on_comment(node, ctx->outbuffer, ctx->env);
                 break;
             }
         case AXIOM_DOCTYPE:
@@ -640,13 +798,17 @@
 static void
 c14n_apply_on_comment(
     axiom_node_t *node,
-    c14n_ctx_t *ctx)
+    c14n_buffer_t *buffer,
+    const axutil_env_t *env)
 {
-    /*TODO: HACK*/
-    c14n_output("<!--", ctx);
-    c14n_output(axiom_comment_get_value((axiom_comment_t*) axiom_node_get_data_element(
-        node, ctx->env), ctx->env), ctx);
-    c14n_output("-->", ctx);
+    axis2_char_t *comment = axiom_comment_get_value((axiom_comment_t*) axiom_node_get_data_element(
+        node, env), env);
+    if(comment)
+    {
+        C14N_BUFFER_ADD_STRING_WITH_LENGTH(buffer, env, "<!--", 4);
+        C14N_BUFFER_ADD_STRING(buffer, env, comment);
+        C14N_BUFFER_ADD_STRING_WITH_LENGTH(buffer, env, "-->", 3);
+    }
 }
 
 static axis2_status_t
@@ -659,31 +821,40 @@
     axiom_namespace_t *ns = NULL;
     c14n_ns_stack_t *save_stack = NULL;
     axiom_node_t *child_node = NULL;
+    const axutil_env_t *env = ctx->env;
+    c14n_buffer_t *buffer = ctx->outbuffer;
+
+    axis2_char_t *prefix = NULL;
+    axis2_ssize_t prefix_len = 0;
+    axis2_char_t *localname = NULL;
+    axis2_ssize_t localname_len = 0;
 
-    ele = (axiom_element_t *) axiom_node_get_data_element(node, ctx->env);
+    ele = (axiom_element_t *) axiom_node_get_data_element(node, env);
     if(!ele)
     {
-        AXIS2_LOG_ERROR(ctx->env->log, AXIS2_LOG_SI,
-            "[rampart] cannot find valid element to apply c14n");
+        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "[rampart] cannot find valid element to apply c14n");
         return AXIS2_FAILURE;
     }
 
-    ns = axiom_element_get_namespace(ele, ctx->env, node);
+    ns = axiom_element_get_namespace(ele, env, node);
     save_stack = c14n_ns_stack_create(ctx);
     c14n_ns_stack_push(save_stack, ctx); /*save current ns stack*/
 
     /*print start tag*/
-    c14n_output("<", ctx);
+    C14N_BUFFER_ADD_CHAR(buffer, env, '<');
     if(ns)
     {
-        axis2_char_t *prefix = axiom_namespace_get_prefix(ns, ctx->env);
-        if(axutil_strlen(prefix) > 0)
+        prefix = axiom_namespace_get_prefix(ns, env);
+        prefix_len = axutil_strlen(prefix);
+        if(prefix_len > 0)
         {
-            c14n_output(prefix, ctx);
-            c14n_output(":", ctx);
+            C14N_BUFFER_ADD_STRING_WITH_LENGTH(buffer, env, prefix, prefix_len);
+            C14N_BUFFER_ADD_CHAR(buffer, env, ':');
         }
     }
-    c14n_output(axiom_element_get_localname(ele, ctx->env), ctx);
+    localname = axiom_element_get_localname(ele, env);
+    localname_len = axutil_strlen(localname);
+    C14N_BUFFER_ADD_STRING_WITH_LENGTH(buffer, env, localname, localname_len);
 
     if(ctx->exclusive)
         res = c14n_apply_on_namespace_axis_exclusive(ele, node, ctx);
@@ -702,42 +873,39 @@
 
     if(!res)
         return res;
-
-    c14n_output(">", ctx);
-
+    C14N_BUFFER_ADD_CHAR(buffer, env, '>');
 
     /*process child elements*/
-    child_node = axiom_node_get_first_child((axiom_node_t *) node, ctx->env);
+    child_node = axiom_node_get_first_child(node, env);
     while(child_node)
     {
         c14n_apply_on_node(child_node, ctx);
-        child_node = axiom_node_get_next_sibling(child_node, ctx->env);
+        child_node = axiom_node_get_next_sibling(child_node, env);
     }
 
     /*print end tag*/
-    c14n_output("</", ctx);
+    C14N_BUFFER_ADD_STRING_WITH_LENGTH(buffer, env,"</", 2);
     if(ns)
     {
-        axis2_char_t *prefix = axiom_namespace_get_prefix(ns, ctx->env);
-
-        if(axutil_strlen(prefix) > 0)
+        if(prefix_len > 0)
         {
-            c14n_output(prefix, ctx);
-            c14n_output(":", ctx);
+            C14N_BUFFER_ADD_STRING_WITH_LENGTH(buffer, env, prefix, prefix_len);
+            C14N_BUFFER_ADD_CHAR(buffer, env, ':');
         }
     }
-    c14n_output(axiom_element_get_localname(ele, ctx->env), ctx);
-    c14n_output(">", ctx);
+    C14N_BUFFER_ADD_STRING_WITH_LENGTH(buffer, env, localname, localname_len);
+    C14N_BUFFER_ADD_CHAR(buffer, env, '>');
 
     c14n_ns_stack_pop(save_stack, ctx); /*restore to previous ns stack */
 
     /*since save_stack is used just to memorize the head of the stack,
      * we don't have to worry about freeing its members*/
-    AXIS2_FREE(ctx->env->allocator, save_stack);
+    AXIS2_FREE(env->allocator, save_stack);
     return res;
 }
 
-static int ns_uri_compare(
+static int
+ns_uri_compare(
     const void *ns1,
     const void *ns2,
     const void *context)
@@ -756,7 +924,8 @@
         ctx->env)));
 }
 
-static int ns_prefix_compare(
+static int
+ns_prefix_compare(
     const void *ns1,
     const void *ns2,
     const void *context)
@@ -775,7 +944,8 @@
         (axiom_namespace_t *) ns2, ctx->env)));
 }
 
-static int attr_compare(
+static int
+attr_compare(
     const void *a1,
     const void *a2,
     const void *context)
@@ -826,38 +996,30 @@
     const void *attribute,
     const void *context)
 {
-    c14n_ctx_t *ctx = (c14n_ctx_t *) context;
+    const axutil_env_t *env = ((c14n_ctx_t *)context)->env;
+    c14n_buffer_t *buffer = ((c14n_ctx_t *)context)->outbuffer;
     axiom_attribute_t *attr = (axiom_attribute_t *) attribute;
-    axiom_namespace_t *ns = axiom_attribute_get_namespace(attr, ctx->env);
+    axiom_namespace_t *ns = axiom_attribute_get_namespace(attr, env);
     axis2_char_t *attvalue = NULL;
 
-    c14n_output(" ", ctx);
+    C14N_BUFFER_ADD_CHAR(buffer, env, ' ');
     if(ns)
     {
-        axis2_char_t *prefix = axiom_namespace_get_prefix(ns, ctx->env);
+        axis2_char_t *prefix = axiom_namespace_get_prefix(ns, env);
 
         if(axutil_strlen(prefix) > 0)
         {
-            c14n_output(prefix, ctx);
-            c14n_output(":", ctx);
+            C14N_BUFFER_ADD_STRING(buffer, env, prefix);
+            C14N_BUFFER_ADD_CHAR(buffer, env, ':');
         }
     }
-    c14n_output(axiom_attribute_get_localname(attr, ctx->env), ctx);
-    c14n_output("=\"", ctx);
-
-    /* TODO:DONE Normalize the text before output */
-    attvalue = axiom_attribute_get_value(attr, ctx->env);
-    attvalue = c14n_normalize_attribute(attvalue, (c14n_ctx_t const *) context);
-
-    c14n_output(attvalue, ctx);
-
-    c14n_output("\"", ctx);
+    C14N_BUFFER_ADD_STRING(buffer, env, axiom_attribute_get_localname(attr, env));
+    C14N_BUFFER_ADD_STRING_WITH_LENGTH(buffer, env, "=\"", 2);
 
-    if(attvalue)
-    {
-        AXIS2_FREE(ctx->env->allocator, attvalue);
-        attvalue = NULL;
-    }
+    /* Normalize the text before output */
+    attvalue = axiom_attribute_get_value(attr, env);
+    c14n_add_normalize_attribute(attvalue, (c14n_ctx_t *)context);
+    C14N_BUFFER_ADD_CHAR(buffer, env, '\"');
 }
 
 static axis2_status_t
@@ -867,12 +1029,12 @@
 {
     axutil_hash_t *attr_ht = NULL;
     axutil_hash_index_t *hi = NULL;
-    c14n_sorted_list_t *attr_list = c14n_sorted_list_create(ctx->env);
 
     attr_ht = axiom_element_get_all_attributes((axiom_element_t *) ele, ctx->env);
 
     if(attr_ht)
     {
+        c14n_sorted_list_t *attr_list = c14n_sorted_list_create(ctx->env);
         for(hi = axutil_hash_first(attr_ht, ctx->env); hi; hi = axutil_hash_next(ctx->env, hi))
         {
             void *v = NULL;
@@ -885,11 +1047,9 @@
         }
 
         C14N_SORTED_LIST_ITERATE(attr_list, ctx, c14n_apply_on_attribute, ctx->env);
+        C14N_SORTED_LIST_FREE_CONTAINER(attr_list, ctx->env);
     }
 
-    /*TODO:DONE C14N_SORTED_LIST_FREE();*/
-    C14N_SORTED_LIST_FREE_CONTAINER(attr_list, ctx->env);
-
     return AXIS2_SUCCESS;
 
     /* TODO: Still need to add the "xml" attrs of the parents in case of doc subsets
@@ -897,127 +1057,19 @@
      * */
 }
 
-#if 0
-static axis2_char_t*
-c14n_normalize_text(
+static void
+c14n_add_normalize_text(
     axis2_char_t *text,
-    const c14n_ctx_t *ctx
-)
+    c14n_ctx_t *ctx)
 {
-    axis2_char_t *buf = NULL;
-    axis2_char_t *endpivot = NULL;
-    axis2_char_t *p = NULL;
-    axis2_char_t *old = NULL;
-    int bufsz = INIT_BUFFER_SIZE;
+    int original_size = axutil_strlen(text);
+    c14n_buffer_t *buffer = ctx->outbuffer;
+    const axutil_env_t *env = ctx->env;
 
-    /* TODO:DONE a better buffer implementation */
-    buf = (axis2_char_t *)(AXIS2_MALLOC(ctx->env->allocator,
-            (sizeof(axis2_char_t) * bufsz) + 10));
-    if (!buf)
+    while(original_size > 0)
     {
-        AXIS2_ERROR_SET(ctx->env->error, AXIS2_ERROR_NO_MEMORY,
-            AXIS2_FAILURE);
-        return buf;
-    }
+        size_t i = 0;
 
-    p = buf;
-    endpivot = p + bufsz;
-
-    old = text;
-
-    while (*old !='\0')
-    {
-        if (p > endpivot)
-        {
-            int size = bufsz * 2;
-            axis2_char_t *temp_buf = (axis2_char_t *)(AXIS2_MALLOC(
-                    ctx->env->allocator, sizeof(axis2_char_t) * size + 10));
-
-            if (!temp_buf)
-            {
-                AXIS2_ERROR_SET(ctx->env->error, AXIS2_ERROR_NO_MEMORY,
-                    AXIS2_FAILURE);
-                return buf;
-            }
-
-            memcpy(temp_buf, buf, sizeof(axis2_char_t) * bufsz + 10);
-
-            p = temp_buf + (p - buf);
-
-            AXIS2_FREE(ctx->env->allocator, buf);
-            buf = temp_buf;
-            bufsz = size;
-            endpivot = buf + bufsz;
-        }
-
-        switch (*old)
-        {
-            case '&':
-            *p++ = '&';
-            *p++ = 'a';
-            *p++ = 'm';
-            *p++ = 'p';
-            *p++ = ';';
-            break;
-            case '>':
-            *p++ = '&';
-            *p++ = 'g';
-            *p++ = 't';
-            *p++ = ';';
-            break;
-            case '<':
-            *p++ = '&';
-            *p++ = 'l';
-            *p++ = 't';
-            *p++ = ';';
-            break;
-            case '\x0D':
-            *p++ = '&';
-            *p++ = '#';
-            *p++ = 'x';
-            *p++ = 'D';
-            *p++ = ';';
-            break;
-            default:
-            *p++ = *old;
-        }
-        old ++;
-    }
-    *p++ = '\0';
-    return buf;
-}
-#endif
-
-static axis2_char_t*
-c14n_normalize_text(
-    axis2_char_t *text,
-    c14n_ctx_t *ctx)
-{
-    axis2_char_t *buf = NULL;
-    int index = 0;
-    int bufsz = INIT_BUFFER_SIZE;
-    int original_size = axutil_strlen(text);
-
-    /* TODO:DONE a better buffer implementation */
-
-    /* we need atleast the size of original text. worst case is, each character is replaced with
-     * 5 other characters (all the texts are special character). But these special characters are
-     * rare and will occur less than 10% of the time. Hence we can create a buffer with length
-     * max(INIT_BUFFER_SIZE, strlen(text)*1.5).. This will reduce the number of memcpy needed
-     */
-    if(bufsz < original_size * 1.5)
-        bufsz = original_size * 1.5;
-
-    buf = (axis2_char_t *) AXIS2_MALLOC(ctx->env->allocator, (sizeof(axis2_char_t) * bufsz));
-    if(!buf)
-    {
-        AXIS2_ERROR_SET(ctx->env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
-        return NULL;
-    }
-
-    while(original_size > 0)
-    {
-        size_t i = 0;
         /* scan buffer until the next special character (&, <, >, \x0D) these need to be escaped,
          * otherwise XML will not be valid*/
         axis2_char_t *pos = (axis2_char_t*) strpbrk(text, "&<>\x0D");
@@ -1033,29 +1085,8 @@
         /* copy everything until the special character */
         if(i > 0)
         {
-            if(index + i + 6 > bufsz)
-            {
-                /* not enough space to write remaining characters + (5 character resulting
-                 * from special character + 1 NULL character). So, have to create a new buffer
-                 * and populate */
-                axis2_char_t *temp_buf = NULL;
-
-                bufsz *= 2;
-                temp_buf = (axis2_char_t *) AXIS2_MALLOC(ctx->env->allocator, sizeof(axis2_char_t)
-                    * bufsz);
-                if(!temp_buf)
-                {
-                    AXIS2_ERROR_SET(ctx->env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
-                    return buf;
-                }
-                memcpy(temp_buf, buf, index);
-                AXIS2_FREE(ctx->env->allocator, buf);
-                buf = temp_buf;
-            }
-
-            memcpy(buf + index, text, i);
+            C14N_BUFFER_ADD_STRING_WITH_LENGTH(buffer, env,text, i);
             text += i;
-            index += i;
             original_size -= i;
         }
 
@@ -1065,30 +1096,16 @@
             switch(text[0])
             {
                 case '&':
-                    buf[index++] = '&';
-                    buf[index++] = 'a';
-                    buf[index++] = 'm';
-                    buf[index++] = 'p';
-                    buf[index++] = ';';
+                    C14N_BUFFER_ADD_STRING_WITH_LENGTH(buffer, env,"&amp;", 5);
                     break;
                 case '>':
-                    buf[index++] = '&';
-                    buf[index++] = 'g';
-                    buf[index++] = 't';
-                    buf[index++] = ';';
+                    C14N_BUFFER_ADD_STRING_WITH_LENGTH(buffer, env,"&gt;", 4);
                     break;
                 case '<':
-                    buf[index++] = '&';
-                    buf[index++] = 'l';
-                    buf[index++] = 't';
-                    buf[index++] = ';';
+                    C14N_BUFFER_ADD_STRING_WITH_LENGTH(buffer, env,"&lt;", 4);
                     break;
                 case '\x0D':
-                    buf[index++] = '&';
-                    buf[index++] = '#';
-                    buf[index++] = 'x';
-                    buf[index++] = 'D';
-                    buf[index++] = ';';
+                    C14N_BUFFER_ADD_STRING_WITH_LENGTH(buffer, env,"&#xD;", 5);
                     break;
                 default:
                     ;
@@ -1098,153 +1115,110 @@
             --original_size;
         }
     }
-
-    buf[index] = '\0';
-    /*printf("buffer [%s]\n", buf);*/
-    return buf;
 }
 
-static axis2_char_t*
-c14n_normalize_attribute(
+static void
+c14n_add_normalize_attribute(
     axis2_char_t *attval,
-    const c14n_ctx_t *ctx)
+    c14n_ctx_t *ctx)
 {
-    axis2_char_t *buf = NULL;
-    axis2_char_t *endpivot = NULL;
-    axis2_char_t *p = NULL;
-    axis2_char_t *old = NULL;
-    int bufsz = INIT_BUFFER_SIZE;
+    int original_size = axutil_strlen(attval);
+    c14n_buffer_t *buffer = ctx->outbuffer;
+    const axutil_env_t *env = ctx->env;
 
-    /* TODO:DONE a better buffer implementation */
-    buf = (axis2_char_t *) (AXIS2_MALLOC(ctx->env->allocator, sizeof(axis2_char_t)
-        * INIT_BUFFER_SIZE + 10));
-    if(!buf)
+    while(original_size > 0)
     {
-        AXIS2_ERROR_SET(ctx->env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
-        return buf;
-    }
-
-    p = buf;
-    endpivot = buf + bufsz;
+        size_t i = 0;
 
-    old = attval;
+        /* scan buffer until the next special character (&, <, ", \x09, \x0A, \x0D)
+         * these need to be escaped, otherwise XML will not be valid*/
+        axis2_char_t *pos = (axis2_char_t*) strpbrk(attval, "&<\"\x09\x0A\x0D");
+        if(pos)
+        {
+            i = pos - attval;
+        }
+        else
+        {
+            i = original_size;
+        }
 
-    while(*old != '\0')
-    {
-        if(p > endpivot)
+        /* copy everything until the special character */
+        if(i > 0)
         {
-            int size = bufsz * 2;
-            axis2_char_t *temp_buf = (axis2_char_t *) (AXIS2_MALLOC(ctx->env->allocator,
-                sizeof(axis2_char_t) * size + 10));
+            C14N_BUFFER_ADD_STRING_WITH_LENGTH(buffer, env,attval, i);
+            attval += i;
+            original_size -= i;
+        }
 
-            if(!temp_buf)
+        /* replace the character with the appropriate sequence */
+        if(original_size > 0)
+        {
+            switch(attval[0])
             {
-                AXIS2_ERROR_SET(ctx->env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
-                return buf;
+                case '&':
+                    C14N_BUFFER_ADD_STRING_WITH_LENGTH(buffer, env,"&amp;", 5);
+                    break;
+                case '<':
+                    C14N_BUFFER_ADD_STRING_WITH_LENGTH(buffer, env,"&lt;", 4);
+                    break;
+                case '"':
+                    C14N_BUFFER_ADD_STRING_WITH_LENGTH(buffer, env,"&quot;", 6);
+                    break;
+                case '\x09':
+                    C14N_BUFFER_ADD_STRING_WITH_LENGTH(buffer, env,"&#x9;", 5);
+                    break;
+                case '\x0A':
+                    C14N_BUFFER_ADD_STRING_WITH_LENGTH(buffer, env,"&#xA;", 5);
+                    break;
+                case '\x0D':
+                    C14N_BUFFER_ADD_STRING_WITH_LENGTH(buffer, env,"&#xD;", 5);
+                    break;
+                default:
+                    ;
             }
 
-            memcpy(temp_buf, buf, sizeof(axis2_char_t) * bufsz + 10);
-
-            p = temp_buf + (p - buf);
-
-            AXIS2_FREE(ctx->env->allocator, buf);
-            buf = temp_buf;
-            bufsz = size;
-            endpivot = buf + bufsz;
-        }
-
-        switch(*old)
-        {
-            case '&':
-                *p++ = '&';
-                *p++ = 'a';
-                *p++ = 'm';
-                *p++ = 'p';
-                *p++ = ';';
-                break;
-            case '<':
-                *p++ = '&';
-                *p++ = 'l';
-                *p++ = 't';
-                *p++ = ';';
-                break;
-            case '"':
-                *p++ = '&';
-                *p++ = 'q';
-                *p++ = 'u';
-                *p++ = 'o';
-                *p++ = 't';
-                *p++ = ';';
-                break;
-            case '\x09':
-                *p++ = '&';
-                *p++ = '#';
-                *p++ = 'x';
-                *p++ = '9';
-                *p++ = ';';
-                break;
-            case '\x0A':
-                *p++ = '&';
-                *p++ = '#';
-                *p++ = 'x';
-                *p++ = 'A';
-                *p++ = ';';
-                break;
-            case '\x0D':
-                *p++ = '&';
-                *p++ = '#';
-                *p++ = 'x';
-                *p++ = 'D';
-                *p++ = ';';
-                break;
-            default:
-                *p++ = *old;
+            ++attval;
+            --original_size;
         }
-        old++;
     }
-    *p++ = '\0';
-    return buf;
 }
 
-static axis2_status_t c14n_apply_on_namespace_axis(
-    const axiom_element_t *ele,
-    const axiom_node_t *node,
-    const c14n_ctx_t *ctx)
+static axis2_status_t
+c14n_apply_on_namespace_axis(
+    axiom_element_t *ele,
+    axiom_node_t *node,
+    c14n_ctx_t *ctx)
 {
     axutil_hash_t *ns_ht = NULL;
     axutil_hash_index_t *hi = NULL;
+    const axutil_env_t *env = ctx->env;
 
-    c14n_sorted_list_t *out_list = c14n_sorted_list_create(ctx->env);
+    c14n_sorted_list_t *out_list = c14n_sorted_list_create(env);
 
-    ns_ht = axiom_element_get_namespaces((axiom_element_t *) ele, ctx->env);
+    ns_ht = axiom_element_get_namespaces(ele, env);
 
     if(ns_ht)
     {
-        for(hi = axutil_hash_first(ns_ht, ctx->env); hi; hi = axutil_hash_next(ctx->env, hi))
+        for(hi = axutil_hash_first(ns_ht, env); hi; hi = axutil_hash_next(env, hi))
         {
             void *v = NULL;
             axutil_hash_this(hi, NULL, NULL, &v);
-
             if(v)
             {
                 axiom_namespace_t *ns = (axiom_namespace_t *) v;
-
-                axis2_char_t *pfx = axiom_namespace_get_prefix(ns, ctx->env);
-                axis2_char_t *uri = axiom_namespace_get_uri(ns, ctx->env);
+                axis2_char_t *pfx = axiom_namespace_get_prefix(ns, env);
+                axis2_char_t *uri = axiom_namespace_get_uri(ns, env);
 
                 if(axutil_strlen(pfx) == 0)
                 {
                     /*process for default namespace*/
-                    /*int nsc = ns_prefix_compare(c14n_ns_stack_get_default(ctx), ns, ctx);
-                     int len = axutil_strlen(uri);*/
-
                     if(axutil_strlen(uri) == 0)
                     {
                         if(c14n_ns_stack_get_default(ctx) != NULL)
                         {
                             c14n_ns_stack_set_default(ns, ctx);
                             C14N_SORTED_LIST_INSERT(&out_list, (void *) ns, ctx, ns_prefix_compare,
-                                ctx->env);
+                                env);
                         }
 
                     }
@@ -1252,15 +1226,14 @@
                     {
                         axiom_namespace_t *prev_def = c14n_ns_stack_get_default(ctx);
 
-                        axis2_char_t *prev_def_uri = ((prev_def) ? axiom_namespace_get_uri(
-                            prev_def, ctx->env)
-                            : NULL);
+                        axis2_char_t *prev_def_uri = ((prev_def) ?
+                            axiom_namespace_get_uri(prev_def, env) : NULL);
 
                         if(!prev_def_uri || axutil_strcmp(prev_def_uri, uri) != 0)
                         {
                             c14n_ns_stack_set_default(ns, ctx);
                             C14N_SORTED_LIST_INSERT(&out_list, (void *) ns, ctx, ns_prefix_compare,
-                                ctx->env);
+                                env);
                         }
                     }
                 }
@@ -1269,17 +1242,15 @@
                     /*non-default namespace*/
                     c14n_ns_stack_add(ns, ctx);
                     C14N_SORTED_LIST_INSERT(&out_list, (void *) ns, ctx, ns_prefix_compare,
-                        ctx->env);
+                        env);
                 }
             }
         }
     }
 
-    C14N_SORTED_LIST_ITERATE(out_list, ctx, c14n_apply_on_namespace, ctx->env);
-
-    C14N_SORTED_LIST_FREE_CONTAINER(out_list, ctx->env);
+    C14N_SORTED_LIST_ITERATE(out_list, ctx, c14n_apply_on_namespace, env);
+    C14N_SORTED_LIST_FREE_CONTAINER(out_list, env);
 
-    /*TODO:DONE C14N_SORTED_LIST_FREE();*/
     return AXIS2_SUCCESS;
 }
 
@@ -1294,29 +1265,28 @@
     axiom_node_t *pnode = NULL;
     axiom_element_t *pele = NULL;
     axiom_namespace_t *ns = NULL;
+    const axutil_env_t *env = ctx->env;
 
-    c14n_sorted_list_t *out_list = c14n_sorted_list_create(ctx->env);
+    c14n_sorted_list_t *out_list = c14n_sorted_list_create(env);
 
     pele = ele;
     pnode = node;
 
     /*treat the default namespace specially*/
 
-    ns = axiom_element_get_namespace(pele, ctx->env, pnode);
+    ns = axiom_element_get_namespace(pele, env, pnode);
 
     if(ns)
     {
-        if(axutil_strlen(axiom_namespace_get_prefix((axiom_namespace_t *) ns, ctx->env)) == 0)
+        if(axutil_strlen(axiom_namespace_get_prefix(ns, env)) == 0)
         {
             axiom_namespace_t *def_ns = c14n_ns_stack_get_default(ctx);
-            if(def_ns || axutil_strlen(axiom_namespace_get_uri((axiom_namespace_t *) ns, ctx->env))
-                != 0)
+            if(def_ns || axutil_strlen(axiom_namespace_get_uri(ns, env)) != 0)
             {
                 if(ns_uri_compare(ns, def_ns, ctx) != 0)
                 {
                     c14n_ns_stack_set_default(ns, ctx);
-                    C14N_SORTED_LIST_INSERT(&out_list, (void *) ns, ctx, ns_prefix_compare,
-                        ctx->env);
+                    C14N_SORTED_LIST_INSERT(&out_list, (void *) ns, ctx, ns_prefix_compare, env);
                 }
             }
         }
@@ -1324,12 +1294,12 @@
 
     while(pnode)
     {
-        pele = axiom_node_get_data_element(pnode, ctx->env);
-        ns_ht = axiom_element_get_namespaces(pele, ctx->env);
+        pele = axiom_node_get_data_element(pnode, env);
+        ns_ht = axiom_element_get_namespaces(pele, env);
 
         if(ns_ht)
         {
-            for(hi = axutil_hash_first(ns_ht, ctx->env); hi; hi = axutil_hash_next(ctx->env, hi))
+            for(hi = axutil_hash_first(ns_ht, env); hi; hi = axutil_hash_next(env, hi))
             {
                 void *v = NULL;
                 axutil_hash_this(hi, NULL, NULL, &v);
@@ -1339,8 +1309,7 @@
                     axis2_char_t *pfx = NULL;
                     ns = (axiom_namespace_t *) v;
 
-                    pfx = axiom_namespace_get_prefix(ns, ctx->env);
-                    /*axis2_char_t *uri = axiom_namespace_get_uri(ns, ctx->env);*/
+                    pfx = axiom_namespace_get_prefix(ns, env);
 
                     if(axutil_strlen(pfx) == 0)
                     {
@@ -1356,60 +1325,56 @@
                         {
                             c14n_ns_stack_add(ns, ctx);
                             C14N_SORTED_LIST_INSERT(&out_list, (void *) ns, ctx, ns_prefix_compare,
-                                ctx->env);
+                                env);
                         }
                     }
                 }
             }
         }
-        pnode = axiom_node_get_parent(pnode, ctx->env);
+        pnode = axiom_node_get_parent(pnode, env);
     } /*while*/
-    C14N_SORTED_LIST_ITERATE(out_list, ctx, c14n_apply_on_namespace, ctx->env);
-
-    C14N_SORTED_LIST_FREE_CONTAINER(out_list, ctx->env);
+    C14N_SORTED_LIST_ITERATE(out_list, ctx, c14n_apply_on_namespace, env);
+    C14N_SORTED_LIST_FREE_CONTAINER(out_list, env);
 
-    /*TODO:DONE C14N_SORTED_LIST_FREE();*/
     return AXIS2_SUCCESS;
 }
 
-static void c14n_apply_on_namespace(
+static void
+c14n_apply_on_namespace(
     const void *namespace,
     const void *context)
 {
     axiom_namespace_t *ns = (axiom_namespace_t *) namespace;
     c14n_ctx_t *ctx = (c14n_ctx_t *) context;
+    c14n_buffer_t *buffer = ctx->outbuffer;
+    const axutil_env_t *env = ctx->env;
 
-    axis2_char_t *pfx = axiom_namespace_get_prefix(ns, ctx->env);
-    axis2_char_t *uri = axiom_namespace_get_uri(ns, ctx->env);
-
-    /*c14n_output(" *", ctx);
-     c14n_output(axiom_namespace_to_string(ns, ctx->env), ctx);
-     c14n_output("*", ctx);*/
+    axis2_char_t *pfx = axiom_namespace_get_prefix(ns, env);
+    axis2_char_t *uri = axiom_namespace_get_uri(ns, env);
+    int length = 0;
 
-    if(axutil_strlen(pfx) > 0)
+    if((length = axutil_strlen(pfx)) > 0)
     {
-        c14n_output(" xmlns:", ctx);
-        c14n_output(pfx, ctx);
+        C14N_BUFFER_ADD_STRING_WITH_LENGTH(buffer, env, " xmlns:", 7);
+        C14N_BUFFER_ADD_STRING_WITH_LENGTH(buffer, env, pfx, length);
     }
     else
-        c14n_output(" xmlns", ctx);
-
-    c14n_output("=\"", ctx);
+    {
+        C14N_BUFFER_ADD_STRING_WITH_LENGTH(buffer, env, " xmlns", 6);
+    }
 
-    if(axutil_strlen(uri) > 0)
-        c14n_output(uri, ctx);
-    c14n_output("\"", ctx);
+    C14N_BUFFER_ADD_STRING_WITH_LENGTH(buffer, env, "=\"", 2);
 
-}
+    if((length = axutil_strlen(uri)) > 0)
+    {
+        C14N_BUFFER_ADD_STRING_WITH_LENGTH(buffer, env, uri, length);
+    }
 
-static void c14n_output(
-    const axis2_char_t *str,
-    const c14n_ctx_t *ctx)
-{
-    axutil_stream_write(ctx->outstream, ctx->env, str, axutil_strlen(str) * sizeof(axis2_char_t));
+    C14N_BUFFER_ADD_CHAR(buffer, env, '\"');
 }
 
-static axis2_bool_t c14n_need_to_declare_ns(
+static axis2_bool_t
+c14n_need_to_declare_ns(
     const axiom_element_t *ele,
     const axiom_node_t *node,
     const axiom_namespace_t *ns,
@@ -1417,15 +1382,16 @@
 {
     axis2_bool_t vu = c14n_ns_visibly_utilized(ele, node, ns, ctx);
 
-    if(vu || (ctx->ns_prefixes && axutil_array_list_contains(
-        (axutil_array_list_t*) (ctx->ns_prefixes), ctx->env, (void*) (axiom_namespace_get_prefix(
-            (axiom_namespace_t*) ns, ctx->env)))))
+    if(vu || (ctx->ns_prefixes &&
+        axutil_array_list_contains(ctx->ns_prefixes, ctx->env,
+        (void*) (axiom_namespace_get_prefix((axiom_namespace_t*) ns, ctx->env)))))
         return c14n_no_output_ancestor_uses_prefix(ele, node, ns, ctx);
 
     return AXIS2_FALSE;
 }
 
-static axis2_bool_t c14n_ns_visibly_utilized(
+static axis2_bool_t
+c14n_ns_visibly_utilized(
     const axiom_element_t *ele,
     const axiom_node_t *node,
     const axiom_namespace_t *ns,
@@ -1486,7 +1452,8 @@
     return vu;
 }
 
-static axis2_bool_t in_nodeset(
+static axis2_bool_t
+in_nodeset(
     const axiom_node_t *node,
     const c14n_ctx_t *ctx)
 {
@@ -1503,7 +1470,8 @@
     return AXIS2_FALSE;
 }
 
-static axis2_bool_t c14n_no_output_ancestor_uses_prefix(
+static axis2_bool_t
+c14n_no_output_ancestor_uses_prefix(
     const axiom_element_t *ele,
     const axiom_node_t *node,
     const axiom_namespace_t *ns,
@@ -1584,3 +1552,226 @@
 
     return AXIS2_TRUE;
 }
+
+#if 0
+static axis2_status_t
+oxs_c14n_apply_stream_algo(
+    const axutil_env_t *env,
+    const axiom_document_t *doc,
+    axutil_stream_t *stream,
+    const axutil_array_list_t *ns_prefixes,
+    const axiom_node_t *node,
+    const axis2_char_t* algo)
+{
+    switch(c14n_get_algorithm(algo))
+    {
+        case C14N_XML_C14N:
+            return oxs_c14n_apply_stream(env, doc, AXIS2_FALSE, stream, AXIS2_FALSE, ns_prefixes,
+                node);
+        case C14N_XML_C14N_WITH_COMMENTS:
+            return oxs_c14n_apply_stream(env, doc, AXIS2_TRUE, stream, AXIS2_FALSE, ns_prefixes,
+                node);
+        case C14N_XML_EXC_C14N:
+            return oxs_c14n_apply_stream(env, doc, AXIS2_FALSE, stream, AXIS2_TRUE, ns_prefixes,
+                node);
+        case C14N_XML_EXC_C14N_WITH_COMMENTS:
+            return oxs_c14n_apply_stream(env, doc, AXIS2_TRUE, stream, AXIS2_TRUE, ns_prefixes,
+                node);
+        default:
+            /*TODO: set the error*/
+            return AXIS2_FAILURE;
+    }
+}
+
+static axis2_char_t*
+c14n_normalize_text(
+    axis2_char_t *text,
+    const c14n_ctx_t *ctx
+)
+{
+    axis2_char_t *buf = NULL;
+    axis2_char_t *endpivot = NULL;
+    axis2_char_t *p = NULL;
+    axis2_char_t *old = NULL;
+    int bufsz = INIT_BUFFER_SIZE;
+
+    /* TODO:DONE a better buffer implementation */
+    buf = (axis2_char_t *)(AXIS2_MALLOC(ctx->env->allocator,
+            (sizeof(axis2_char_t) * bufsz) + 10));
+    if (!buf)
+    {
+        AXIS2_ERROR_SET(ctx->env->error, AXIS2_ERROR_NO_MEMORY,
+            AXIS2_FAILURE);
+        return buf;
+    }
+
+    p = buf;
+    endpivot = p + bufsz;
+
+    old = text;
+
+    while (*old !='\0')
+    {
+        if (p > endpivot)
+        {
+            int size = bufsz * 2;
+            axis2_char_t *temp_buf = (axis2_char_t *)(AXIS2_MALLOC(
+                    ctx->env->allocator, sizeof(axis2_char_t) * size + 10));
+
+            if (!temp_buf)
+            {
+                AXIS2_ERROR_SET(ctx->env->error, AXIS2_ERROR_NO_MEMORY,
+                    AXIS2_FAILURE);
+                return buf;
+            }
+
+            memcpy(temp_buf, buf, sizeof(axis2_char_t) * bufsz + 10);
+
+            p = temp_buf + (p - buf);
+
+            AXIS2_FREE(ctx->env->allocator, buf);
+            buf = temp_buf;
+            bufsz = size;
+            endpivot = buf + bufsz;
+        }
+
+        switch (*old)
+        {
+            case '&':
+            *p++ = '&';
+            *p++ = 'a';
+            *p++ = 'm';
+            *p++ = 'p';
+            *p++ = ';';
+            break;
+            case '>':
+            *p++ = '&';
+            *p++ = 'g';
+            *p++ = 't';
+            *p++ = ';';
+            break;
+            case '<':
+            *p++ = '&';
+            *p++ = 'l';
+            *p++ = 't';
+            *p++ = ';';
+            break;
+            case '\x0D':
+            *p++ = '&';
+            *p++ = '#';
+            *p++ = 'x';
+            *p++ = 'D';
+            *p++ = ';';
+            break;
+            default:
+            *p++ = *old;
+        }
+        old ++;
+    }
+    *p++ = '\0';
+    return buf;
+}
+
+static axis2_char_t*
+c14n_normalize_attribute(
+    axis2_char_t *attval,
+    const c14n_ctx_t *ctx)
+{
+    axis2_char_t *buf = NULL;
+    axis2_char_t *endpivot = NULL;
+    axis2_char_t *p = NULL;
+    axis2_char_t *old = NULL;
+    int bufsz = INIT_BUFFER_SIZE;
+
+    /* TODO:DONE a better buffer implementation */
+    buf = (axis2_char_t *) (AXIS2_MALLOC(ctx->env->allocator, sizeof(axis2_char_t)
+        * INIT_BUFFER_SIZE + 10));
+    if(!buf)
+    {
+        AXIS2_ERROR_SET(ctx->env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+        return buf;
+    }
+
+    p = buf;
+    endpivot = buf + bufsz;
+
+    old = attval;
+
+    while(*old != '\0')
+    {
+        if(p > endpivot)
+        {
+            int size = bufsz * 2;
+            axis2_char_t *temp_buf = (axis2_char_t *) (AXIS2_MALLOC(ctx->env->allocator,
+                sizeof(axis2_char_t) * size + 10));
+
+            if(!temp_buf)
+            {
+                AXIS2_ERROR_SET(ctx->env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+                return buf;
+            }
+
+            memcpy(temp_buf, buf, sizeof(axis2_char_t) * bufsz + 10);
+
+            p = temp_buf + (p - buf);
+
+            AXIS2_FREE(ctx->env->allocator, buf);
+            buf = temp_buf;
+            bufsz = size;
+            endpivot = buf + bufsz;
+        }
+
+        switch(*old)
+        {
+            case '&':
+                *p++ = '&';
+                *p++ = 'a';
+                *p++ = 'm';
+                *p++ = 'p';
+                *p++ = ';';
+                break;
+            case '<':
+                *p++ = '&';
+                *p++ = 'l';
+                *p++ = 't';
+                *p++ = ';';
+                break;
+            case '"':
+                *p++ = '&';
+                *p++ = 'q';
+                *p++ = 'u';
+                *p++ = 'o';
+                *p++ = 't';
+                *p++ = ';';
+                break;
+            case '\x09':
+                *p++ = '&';
+                *p++ = '#';
+                *p++ = 'x';
+                *p++ = '9';
+                *p++ = ';';
+                break;
+            case '\x0A':
+                *p++ = '&';
+                *p++ = '#';
+                *p++ = 'x';
+                *p++ = 'A';
+                *p++ = ';';
+                break;
+            case '\x0D':
+                *p++ = '&';
+                *p++ = '#';
+                *p++ = 'x';
+                *p++ = 'D';
+                *p++ = ';';
+                break;
+            default:
+                *p++ = *old;
+        }
+        old++;
+    }
+    *p++ = '\0';
+    return buf;
+}
+
+#endif

Modified: webservices/rampart/trunk/c/src/omxmlsec/c14n/sorted_list.c
URL: http://svn.apache.org/viewvc/webservices/rampart/trunk/c/src/omxmlsec/c14n/sorted_list.c?rev=817158&r1=817157&r2=817158&view=diff
==============================================================================
--- webservices/rampart/trunk/c/src/omxmlsec/c14n/sorted_list.c (original)
+++ webservices/rampart/trunk/c/src/omxmlsec/c14n/sorted_list.c Mon Sep 21 05:12:58 2009
@@ -49,21 +49,25 @@
     void *val,
     const void *ctx,
     int(*compar)(const void *, const void *, const void *),
-    const axutil_env_t *env
-)
+    const axutil_env_t *env)
 {
-    if(!(*node)) {
+
+    if(!(*node))
+    {
         *node = (c14n_sorted_list_t *) AXIS2_MALLOC(env->allocator, (sizeof(**node)));
         (*node)->left = (*node)->right = NULL;
         (*node)->val = val;
         return;
     }
-
-    if(compar(val, (*node)->val, ctx)<0)
-        sorted_list_insert(&(*node)->left, val, ctx, compar, env);
-    else if(compar(val, (*node)->val, ctx)>0)
-        sorted_list_insert(&(*node)->right, val, ctx, compar, env);
-    else; /*neglect if the same ns*/
+    else
+    {
+        int result = compar(val, (*node)->val, ctx);
+        if(result < 0)
+            sorted_list_insert(&(*node)->left, val, ctx, compar, env);
+        else if(result > 0)
+            sorted_list_insert(&(*node)->right, val, ctx, compar, env);
+        else; /*neglect if the same ns*/
+    }
 }
 
 void