You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-dev@axis.apache.org by ma...@apache.org on 2008/07/22 10:43:42 UTC

svn commit: r678680 [2/4] - in /webservices/axis2/trunk/c: ./ axiom/include/ axiom/src/attachments/ axiom/src/om/ include/ samples/ samples/client/mtom/ samples/client/mtom/resources/ samples/server/ samples/server/mtom/ src/core/context/ src/core/desc...

Modified: webservices/axis2/trunk/c/axiom/src/attachments/mime_parser.c
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/c/axiom/src/attachments/mime_parser.c?rev=678680&r1=678679&r2=678680&view=diff
==============================================================================
--- webservices/axis2/trunk/c/axiom/src/attachments/mime_parser.c (original)
+++ webservices/axis2/trunk/c/axiom/src/attachments/mime_parser.c Tue Jul 22 01:43:36 2008
@@ -1,3 +1,4 @@
+
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
@@ -19,48 +20,201 @@
 #include <axutil_string.h>
 #include <axiom_data_handler.h>
 #include <stdio.h>
+#include <ctype.h>    
 #include <axutil_http_chunked_stream.h>
-#include <ctype.h>
 
 struct axiom_mime_parser
 {
+    /* This will keep the attachment and its info*/
     axutil_hash_t *mime_parts_map;
+
+    /* This is the actual SOAP part len */
     int soap_body_len;
+
+    /* The SOAP part of the message */
     axis2_char_t *soap_body_str;
-    int chunk_buffer_size;
-    int max_chunk_buffers;
+
+    /* The size of the buffer we give to the callback to
+     * read data */
+    int buffer_size;
+
+    /* The number of buffers */
+    int max_buffers;
+
+    /* The attachment dir name, in the case of caching */
+    axis2_char_t *attachment_dir;
+};
+
+struct axiom_search_info
+{
+    /*String need to be searched*/
+    const axis2_char_t *search_str;
+
+    /*The buffers and the lengths need to be searched*/
+    axis2_char_t *buffer1;
+    int len1;
+    axis2_char_t *buffer2;
+    int len2;
+
+    /*Flag to keep what type of search is this buffer has done*/
+    axis2_bool_t primary_search;
+
+    /*The offset where we found the pattern entirely in one buffer*/
+    int match_len1;
+
+    /*when pattern contains in two buffers the length of partial pattern
+    in buffer2 */
+    int match_len2;
+
+    /*Whether we need caching or not*/
+    axis2_bool_t cached;
+
+    /*A pointer to a user provided storage to which we cache the attachment*/
+    void *handler;
+
+    /* Size of the binary when writing to the buffer*/
+    int binary_size;
 };
 
+typedef struct axiom_search_info axiom_search_info_t;
+
+
+#define AXIOM_MIME_PARSER_CONTENT_ID "content-id"
+#define AXIOM_MIME_PARSER_CONTENT_TYPE "content-type"
+
+#define AXIOM_MIME_PARSER_END_OF_MIME_MAX_COUNT 100
+
+static axis2_char_t *axiom_mime_parser_search_for_soap(
+    const axutil_env_t * env,
+    AXIS2_READ_INPUT_CALLBACK callback,
+    void *callback_ctx,
+    int *buf_num,
+    int *len_array,
+    axis2_char_t **buf_array,
+    axiom_search_info_t *search_info,
+    int size,
+    axis2_char_t *mime_boundary,
+    axiom_mime_parser_t *mime_parser);
+
+
+static axis2_char_t *axiom_mime_parser_search_for_crlf(
+    const axutil_env_t * env,
+    AXIS2_READ_INPUT_CALLBACK callback,
+    void *callback_ctx,
+    int *buf_num,
+    int *len_array,
+    axis2_char_t **buf_array,
+    axiom_search_info_t *search_info,
+    int size,
+    axiom_mime_parser_t *mime_parser);
+
+static int axiom_mime_parser_calculate_part_len(
+    const axutil_env_t *env,
+    int buf_num,
+    int *len_list,
+    int maker,
+    axis2_char_t *pos,
+    axis2_char_t *buf
+);
+
+static axis2_char_t * axiom_mime_parser_create_part (
+    const axutil_env_t *env,
+    int part_len,
+    int buf_num,
+    int *len_list,
+    int marker,
+    axis2_char_t *pos,
+    axis2_char_t **buf_list,
+    axiom_mime_parser_t *mime_parser);
+
+static axis2_char_t *axiom_mime_parser_search_string(
+    axiom_search_info_t *search_info,
+    const axutil_env_t *env);
+
+static axis2_char_t *axiom_mime_parser_search_for_attachment(
+    axiom_mime_parser_t *mime_parser,
+    const axutil_env_t * env,
+    AXIS2_READ_INPUT_CALLBACK callback,
+    void *callback_ctx,
+    int *buf_num,
+    int *len_array,
+    axis2_char_t **buf_array,
+    axiom_search_info_t *search_info,
+    int size,
+    axis2_char_t *mime_boundary,
+    axis2_char_t *mime_id);
+
+static axis2_status_t axiom_mime_parser_store_attachment(
+    const axutil_env_t *env,
+    axiom_mime_parser_t *mime_parser,
+    axis2_char_t *mime_id,
+    axis2_char_t *mime_type,
+    axis2_char_t *mime_binary,
+    int mime_binary_len,
+    axis2_bool_t cached);
+
+static void axiom_mime_parser_clear_buffers(
+    const axutil_env_t *env,
+    axis2_char_t **buf_list,
+    int free_from,
+    int free_to);
+
+static axis2_status_t axiom_mime_parser_cache_to_buffer(
+    const axutil_env_t *env,
+    axis2_char_t *buf,
+    int buf_len,
+    axiom_search_info_t *search_info,
+    axiom_mime_parser_t *mime_parser);
+
+
+static axis2_bool_t axiom_mime_parser_is_more_data(
+    axiom_mime_parser_t *mime_parser,
+    const axutil_env_t *env,
+    axis2_callback_info_t *callback_info);
+
+static axis2_char_t *
+    axiom_mime_parser_process_mime_headers(
+    const axutil_env_t *env,
+    axiom_mime_parser_t *mime_parser,
+    axis2_char_t **mime_id,
+    axis2_char_t *mime_headers);
+
+static axis2_status_t 
+axiom_mime_parser_cache_to_file(
+    const axutil_env_t* env,
+    axis2_char_t *buf,
+    int buf_len,
+    void *handler);
+
+
 AXIS2_EXTERN axiom_mime_parser_t *AXIS2_CALL
 axiom_mime_parser_create(
-    const axutil_env_t *env)
+    const axutil_env_t * env)
 {
     axiom_mime_parser_t *mime_parser = NULL;
 
     AXIS2_ENV_CHECK(env, NULL);
-    mime_parser = (axiom_mime_parser_t *)
-        AXIS2_MALLOC(env->allocator, sizeof(axiom_mime_parser_t));
+    mime_parser = (axiom_mime_parser_t *) AXIS2_MALLOC(env->allocator,
+                                                       sizeof
+                                                       (axiom_mime_parser_t));
 
     if (!mime_parser)
     {
         AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
-        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
-            "No memory. Cannot create MIME parser");
         return NULL;
     }
 
     mime_parser->mime_parts_map = NULL;
     mime_parser->soap_body_len = 0;
-    mime_parser->soap_body_str = NULL;
-    mime_parser->chunk_buffer_size = 1;
-    mime_parser->max_chunk_buffers = AXIOM_MIME_PARSER_MAX_CHUNK_BUFFERS;
+    mime_parser->soap_body_str = NULL;  /* shallow copy */
+    mime_parser->buffer_size = 1;
+    mime_parser->max_buffers = AXIOM_MIME_PARSER_MAX_BUFFERS;
+    mime_parser->attachment_dir = NULL;
 
     mime_parser->mime_parts_map = axutil_hash_make(env);
     if (!(mime_parser->mime_parts_map))
     {
         axiom_mime_parser_free(mime_parser, env);
-        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
-            "Failed in creating MIME parts map. Cannot create MIME parser");
         return NULL;
     }
 
@@ -69,16 +223,13 @@
 
 AXIS2_EXTERN void AXIS2_CALL
 axiom_mime_parser_free(
-    axiom_mime_parser_t *mime_parser,
-    const axutil_env_t *env)
+    axiom_mime_parser_t * mime_parser,
+    const axutil_env_t * env)
 {
-    /* This map is passed on to SOAP builder, and SOAP builder take over the
-     * ownership of the map
-     */
-    mime_parser->mime_parts_map = NULL;
+    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
 
-    /* The MIME parser doesn't own the SOAP Body string */
-    mime_parser->soap_body_str = NULL;
+    /* The map is passed on to SOAP builder, and SOAP builder take over the
+       ownership of the map */
 
     if (mime_parser)
     {
@@ -90,365 +241,709 @@
 
 AXIS2_EXTERN axutil_hash_t *AXIS2_CALL
 axiom_mime_parser_parse(
-    axiom_mime_parser_t *mime_parser,
-    const axutil_env_t *env,
+    axiom_mime_parser_t * mime_parser,
+    const axutil_env_t * env,
     AXIS2_READ_INPUT_CALLBACK callback,
     void *callback_ctx,
-    axis2_char_t *mime_boundary)
+    axis2_char_t * mime_boundary)
 {
-    axis2_char_t *buffer = NULL;
-    int size = AXIOM_MIME_PARSER_BUFFER_SIZE;
-    int len = 0;
-    axis2_char_t *root_mime = NULL;
-    axis2_char_t *soap_body_str = NULL;
-    int soap_body_len = 0;
-    axis2_char_t *body_mime = NULL;
-    axis2_char_t *mime_binary = NULL;
-    int mime_binary_len = 0;
-    axis2_char_t *pos = NULL;
-    axis2_bool_t end_of_mime = AXIS2_FALSE;
-    int count = 0;
-    int read = 0;
-    int buf_num = 0;    
-    int buf_len = 0;
-    axis2_callback_info_t *cb_ctx = NULL;
+    int size = 0;
+    axis2_char_t *soap_str = NULL;
+    int soap_len = 0;
+    axis2_char_t *mime_headers = NULL;
+    int mime_headers_len = 0;
+    int temp_mime_boundary_size = 0;
+    axis2_char_t *temp_mime_boundary = NULL;
     axis2_char_t **buf_array = NULL;
     int *len_array = NULL;
+    int buf_num = 0;
+    axis2_char_t *pos = NULL;
+    axiom_search_info_t *search_info = NULL;
+    int part_start = 0;
+    axis2_bool_t end_of_mime = AXIS2_FALSE;
+    int count = 0; 
+    int mime_binary_len = 0;
+    axis2_char_t *mime_binary = NULL;
+    int len = 0;
+    axis2_status_t status = AXIS2_FAILURE; 
+    axis2_char_t *buffer = NULL;
+    int malloc_len = 0;
+    axis2_callback_info_t *callback_info = NULL;
+
+    callback_info = (axis2_callback_info_t *)callback_ctx;
 
-    cb_ctx = (axis2_callback_info_t *) callback_ctx;
+    /* The user will specify the mime_parser->buffer_size */
 
-    if (cb_ctx->chunked_stream)
+    size = AXIOM_MIME_PARSER_BUFFER_SIZE * (mime_parser->buffer_size); 
+
+    /*An array to keep the set of buffers*/
+
+    buf_array = AXIS2_MALLOC(env->allocator,
+        sizeof(axis2_char_t *) * (mime_parser->max_buffers));
+
+    if (!buf_array)
     {
-        buf_array = AXIS2_MALLOC(env->allocator,
-            sizeof(axis2_char_t *) * (mime_parser->max_chunk_buffers));
+        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+            "No memory. Failed in creating buffer array");
+        return NULL;
+    }
 
-        if (!buf_array)
-        {
-            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
-                "No memory. Failed in creating buffer array");
-            return NULL;
-        }
+    /*Keeps the corresponding lengths of buffers in buf_array*/
 
-        len_array = AXIS2_MALLOC(env->allocator, 
-            sizeof(int) * (mime_parser->max_chunk_buffers));
- 
-        if (!len_array)
+    len_array = AXIS2_MALLOC(env->allocator,
+        sizeof(int) * (mime_parser->max_buffers));
+
+
+    if (!len_array)
+    {
+        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+            "No memory. Failed in creating length array");
+        return NULL;
+    }
+
+    temp_mime_boundary = axutil_stracat(env, "--", mime_boundary);
+    temp_mime_boundary_size = strlen(mime_boundary) + 2;
+
+    /*This struct keeps the pre-post search informations*/
+    search_info = AXIS2_MALLOC(env->allocator,
+        sizeof(axiom_search_info_t));
+
+    /* The first buffer is created */
+    buf_array[buf_num] = AXIS2_MALLOC(env->allocator, 
+            sizeof(axis2_char_t) * (size + 1));
+
+    /* The buffer is filled from the callback */
+
+    if(buf_array[buf_num])
+    {
+        len = callback(buf_array[buf_num], size, (void *) callback_ctx);
+    }
+    if(len > 0)
+    {
+        len_array[buf_num] = len;
+    }
+    else
+    {
+        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+            "Error reading from the stream");
+        return NULL;
+    }
+
+    /*starting buffer for the current search*/
+    part_start = buf_num;
+
+    /*We are passing the address of the buf_num , beacause that value 
+    is changing inside the method.*/
+
+    /* Following call to the method will search first \r\n\r\n */
+
+    pos = axiom_mime_parser_search_for_crlf(env, callback, callback_ctx, &buf_num,
+            len_array, buf_array, search_info, size, mime_parser);
+
+    if(!pos)
+    {
+        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+            "Error in the message.");
+        return NULL;
+    }   
+
+    /* The patteren contains in one buffer */
+
+    if((search_info->match_len2 == 0))
+    {
+        /*Readjusting the buffers for the next search and discarding the prevoius 
+        buffers*/
+
+        /* We need the remaining part in the buffer after the \r\n\r\n*/
+
+        malloc_len = buf_array[buf_num] + len_array[buf_num] - pos - 4;
+        if(malloc_len < 0)
         {
             AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
-                "No memory. Failed in creating length array");
+            "Error in parsing.");
             return NULL;
         }
+        else    
+        {
+            /* Here we will create a new buffer of predefined size fill the 
+             * first portion from the remaining part after previous search
+             * and then fill the remaining from the callback */
 
-        size = (mime_parser->chunk_buffer_size) * AXIOM_MIME_PARSER_BUFFER_SIZE;
+            buffer = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * (
+                size + 1));
 
-        while (!axutil_http_chunked_stream_get_end_of_chunks(
-            cb_ctx->chunked_stream, env))
-        {
-            read = 0;
-            
-            if (buf_num > (mime_parser->max_chunk_buffers - 1))
+            if(malloc_len > 0)
             {
-                AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
-                    "Attachment size exceeds "
-                    "the system MTOM configuration parameters");
-                return NULL;
+                memcpy(buffer, pos + 4, malloc_len);
             }
 
-            buf_array[buf_num] = AXIS2_MALLOC(env->allocator,
-                sizeof(axis2_char_t) * (size + 1));
-            if (!buf_array[buf_num])
+            /* Here we need to check for more data, because if the message is too small
+             * comapred to the reading size there may be no data in the stream , instead
+             * all the remaining data may be in the buffer */            
+
+            if(axiom_mime_parser_is_more_data(mime_parser, env, callback_info))
             {
-                AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
-                    "No memory. Failed in creating buffer");
-                return NULL;
+                /* There is more data so fill the remaining from the  stream*/
+
+                len = callback(buffer + malloc_len, size - malloc_len, (void *) callback_ctx);           
             }
-            do
+            
+            /* We do not need the data in the previous buffers once we found a particular
+             * string and after worked with those buffers */
+    
+            axiom_mime_parser_clear_buffers(env, buf_array, part_start, buf_num);
+
+            /* Adding the new buffer to the buffer list */
+
+            if(len >= 0)
             {
-                read += len;
-                len = callback(buf_array[buf_num] + read, size - read,
-                    (void *) callback_ctx);
+                buf_array[buf_num] = buffer;
+                len_array[buf_num] = malloc_len + len;                    
             }
-            while ((read < (size-1)) && (len > 0));
-
-            *(buf_array[buf_num] + read) = '\0';
-            len_array[buf_num] = read;
-            buf_num++;
         }
-        /* If we have only one buffer */
-        if (buf_num == 1)
+    }
+
+    /*The pattern divides among two buffers*/
+        
+    else if(search_info->match_len2 > 0)
+    {
+        malloc_len = len_array[buf_num] - search_info->match_len2;      
+        if(malloc_len < 0)
         {
-            buffer = buf_array[buf_num - 1];
-        }
+            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+            "Error in parsing.");
+            return NULL;
+        } 
         else
         {
-            int i = 0;
-            int temp = 0;
-            buf_len = 0;
+            buffer = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * (
+                size + 1));
 
-            for (i = 0; i < buf_num; i++)
+            /* Here the buf_num is the second buffer. We will copy the remaining data
+             * after the partial string in the second buffer */
+
+            if(malloc_len > 0)
             {
-                if (buf_array[i])
-                {
-                    buf_len += len_array[i];    
-                }
+                memcpy(buffer, buf_array[buf_num] + search_info->match_len2, malloc_len);        
             }
-            buffer = AXIS2_MALLOC(env->allocator, sizeof(char) * (buf_len + 1));
-
-            if (!buffer)
+            if(axiom_mime_parser_is_more_data(mime_parser, env, callback_info))
             {
-                AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
-                    "No memory. Failed in creating buffer");
-                return NULL;
+                len = callback(buffer + malloc_len, size - malloc_len, (void *) callback_ctx);
             }
-
-            for (i = 0; i < buf_num; i++)
+            axiom_mime_parser_clear_buffers(env, buf_array, part_start, buf_num);
+            if(len >= 0)
             {
-                if (buf_array[i])
-                {
-                    memcpy(buffer + temp, buf_array[i], len_array[i]);
-                    temp += len_array[i];
-                    AXIS2_FREE(env->allocator, buf_array[i]);
-                    buf_array[i] = NULL;
-                }
+                buf_array[buf_num] = buffer;
+                len_array[buf_num] = malloc_len + len; 
             }
-            *(buffer + temp) = '\0';
         }
     }
     else
     {
-        size = cb_ctx->content_length + 100;
-        buffer = AXIS2_MALLOC(env->allocator,
-            sizeof(axis2_char_t) * (size + 1));
-        if (!buffer)
-        {
-            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
-                "No memory. Failed in creating buffer");
-            return NULL;
-        }
-        do
+        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+            "Error in parsing.");
+        return NULL;
+    }
+
+    /*Resetting the previous search data and getting ready 
+      for the next search */
+
+    part_start = buf_num;
+    pos = NULL;
+    malloc_len = 0;
+ 
+    search_info->match_len1 = 0;
+    search_info->match_len2 = 0;
+
+    /*In order to extract the soap envelope we need to search for the first
+      --MIMEBOUNDARY  */
+
+    pos = axiom_mime_parser_search_for_soap(env, callback, callback_ctx, &buf_num,
+          len_array, buf_array, search_info, size, temp_mime_boundary, mime_parser);
+
+    if(!pos)
+    {
+        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+            "Error while searching for the SOAP part ");
+        return NULL;
+    }
+    
+    if(search_info->match_len2 == 0)
+    {
+        /*Calculating the length of the SOAP str*/
+
+        soap_len = axiom_mime_parser_calculate_part_len (
+            env, buf_num, len_array, part_start, pos, buf_array[buf_num]);
+        if(soap_len > 0)
         {
-            read += len;
-            len = callback(buffer + read, size - read, (void *) callback_ctx);
-        }
-        while ((read < size) && (len > 0));
+            /* Get the SOAP string from the starting and end buffers containing 
+             * the SOAP  part */
+
+            soap_str = axiom_mime_parser_create_part(
+            env, soap_len, buf_num, len_array, part_start, pos, buf_array, mime_parser);
+            if(!soap_str)
+            {
+                AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+                    "Error while creating the SOAP part from the message ");
+                return NULL;
+            }
+
+            malloc_len = len_array[buf_num] - search_info->match_len1 - temp_mime_boundary_size;
+            if(malloc_len < 0)
+            {
+                AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+                    "Error in parsing for mime.");
+                return NULL;
+            }    
+            else
+            {
+                /* This will fill the new buffer with remaining data after the
+                 * SOAP */
+
+                buffer = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * (
+                    size + 1));
 
-        buffer[read+1] = '\0';
-        buf_len = read;
+                memset(buffer, 0, size + 1);
+                if(malloc_len > 0)
+                {
+                    memcpy(buffer, pos + temp_mime_boundary_size, malloc_len);
+                }
+                if(axiom_mime_parser_is_more_data(mime_parser, env, callback_info))
+                {
+                    len = callback(buffer + malloc_len, size - malloc_len, (void *) callback_ctx);
+                }
 
-        if (buf_len < cb_ctx->content_length)
+                axiom_mime_parser_clear_buffers(env, buf_array, part_start, buf_num);
+                if(len >= 0)
+                {
+                    buf_array[buf_num] = buffer;
+                    len_array[buf_num] = malloc_len + len;
+                }
+            }
+        }     
+        else
         {
-            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
-                "Some data in the message was not recieved");
             return NULL;
         }
-    }
+    }    
 
-    if (buffer)
+    /* This is the condition where the --MIMEBOUNDARY is devided among two
+     * buffers */
+
+    else if(search_info->match_len2 > 0)
     {
-        pos = axutil_strstr(buffer, AXIS2_CRLF AXIS2_CRLF);
-        if (pos)
+        soap_len = axiom_mime_parser_calculate_part_len (
+            env, buf_num - 1, len_array, part_start, pos, buf_array[buf_num - 1]);
+
+        if(soap_len > 0)
         {
-            root_mime = pos + 4;
-            pos = NULL;
-        }
-    }
+            /* Here we pass buf_num-1 becasue buf_num does not have any thing we want to
+             * for this particular part. It begins with the latter part of the search string */
 
-    if (root_mime)
-    {
-        pos = axutil_strstr(root_mime, mime_boundary);
-    }
+            soap_str = axiom_mime_parser_create_part(
+            env, soap_len, buf_num - 1, len_array, part_start, pos, buf_array, mime_parser);
+            if(!soap_str)
+            {
+                return NULL;
+            }
 
-    if (pos)
-    {
-        pos -= 2;
-        soap_body_len = pos - root_mime;
-        soap_body_str = AXIS2_MALLOC(env->allocator,
-            sizeof(char) * (soap_body_len + 1));
-        if (!soap_body_str)
+            malloc_len = len_array[buf_num] - search_info->match_len2;
+            if(malloc_len < 0)
+            {
+                return NULL;
+            }    
+            else
+            {
+                buffer = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * (
+                    size + 1));
+
+                if(malloc_len > 0)
+                {
+                    memcpy(buffer, buf_array[buf_num] + search_info->match_len2, malloc_len);
+                }
+
+                if(axiom_mime_parser_is_more_data(mime_parser, env, callback_info))
+                {
+                    len = callback(buffer + malloc_len, size - malloc_len, (void *) callback_ctx);
+                }
+                axiom_mime_parser_clear_buffers(env, buf_array, part_start, buf_num);
+                if(len >= 0)
+                {
+                    buf_array[buf_num] = buffer;
+                    len_array[buf_num] = malloc_len + len;
+                }
+            }
+        }     
+        else
         {
-            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
-                "No memory. Failed in SOAP body string");
             return NULL;
         }
-        memcpy(soap_body_str, root_mime, soap_body_len);
-        soap_body_str[soap_body_len] = '\0';
-        body_mime = pos;
-        mime_parser->soap_body_len = soap_body_len;
-        mime_parser->soap_body_str = soap_body_str;
     }
+
+    mime_parser->soap_body_str = soap_str;
+    mime_parser->soap_body_len = soap_len;
+
+    /*<SOAP></SOAP>--MIMEBOUNDARY
+      mime_headr1:.......
+      mime_headr2:....
+
+      Binarstart.................
+      ...............--MIMEBOUNDARY      
+ */
     
+    /* This loop will extract all the attachments in the message. The condition
+     * with the count is needed because if the sender not marked the end of the 
+     * attachment wiht -- then this loop may run infinitely. To prevent that
+     * this additional condition has been put */
+
+
     while (!end_of_mime && count < AXIOM_MIME_PARSER_END_OF_MIME_MAX_COUNT)
     {
-        axis2_char_t *temp_body_mime = NULL;
-        axis2_char_t *temp_mime_binary = NULL;
-        axis2_char_t *temp_pos = NULL;
-
+        /*First we will search for \r\n\r\n*/
+        axis2_char_t *mime_id = NULL;
+        axis2_char_t *mime_type = NULL; 
+        search_info->match_len1 = 0;
+        search_info->match_len2 = 0;
         pos = NULL;
+        part_start = buf_num;
+
+        malloc_len = 0;
 
-        /* Keep track of the count to ensure that we do not go in an infinite 
-         * loop. It is possible that we could fall into an infinite loop if 
-         * there are problems in sender's message format
-         */
-        count++;
+        count++;       
+ 
+        pos = axiom_mime_parser_search_for_crlf(env, callback, callback_ctx, &buf_num,
+            len_array, buf_array, search_info, size, mime_parser);
 
-        if (body_mime)
+        if(!pos)
         {
-            pos = axutil_strstr(body_mime, AXIS2_CRLF AXIS2_CRLF);
+            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+                    "Error in parsing for mime.");
+            return NULL;
         }
-
-        if (pos)
+        
+        /*The pattern contains in one buffer*/
+        if(search_info->match_len2 == 0)
         {
-            axis2_char_t *old_pos = NULL;
+            /*We found it . so lets seperates the details of this binary into 
+              mime headers.*/
 
-            temp_mime_binary = pos + 4;
-            old_pos = temp_mime_binary;    
-            do
+            mime_headers_len = axiom_mime_parser_calculate_part_len (
+                env, buf_num, len_array, part_start, pos, buf_array[buf_num]);
+            if(mime_headers_len > 0)
             {
-                pos = NULL;
-            
-                if (old_pos) 
+                mime_headers = axiom_mime_parser_create_part(
+                    env, mime_headers_len, buf_num, len_array, part_start, pos, buf_array, mime_parser);
+                if(!mime_headers)
                 {
-                    pos = memchr(old_pos, AXIOM_MIME_BOUNDARY_BYTE,
-                        buffer + buf_len - old_pos); 
+                    AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+                    "Error in parsing for mime headers.");
+                    return NULL;
                 }
+                malloc_len = buf_array[buf_num] + len_array[buf_num] - pos - 4;
 
-                if (pos)
+                /*This should be > 0 , > 0 means there is some part to copy = 0 means
+                there is nothing to copy*/
+                if(malloc_len < 0)
                 {
-                    old_pos = pos + 1;
-                    temp_pos = axutil_strstr(pos + 1, mime_boundary);
+                    AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+                    "Error in parsing for mime headers");
+                    return NULL;
                 }
-            }
-            while (pos && (*(pos + 1) != AXIOM_MIME_BOUNDARY_BYTE ||
-                temp_pos != pos + 2));
-        }
-                
-        if (pos && (*(pos + 1) == AXIOM_MIME_BOUNDARY_BYTE) && 
-            (temp_pos == pos + 2))
-        {
-            mime_binary_len = (int)(pos - temp_mime_binary);
-            temp_pos = pos + 2 + axutil_strlen(mime_boundary);
 
-            end_of_mime = (AXIOM_MIME_BOUNDARY_BYTE == *(temp_pos)) &&
-                (AXIOM_MIME_BOUNDARY_BYTE == *(temp_pos + 1));
+                else
+                {
+                    buffer = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * (
+                        size + 1));
+
+                    if(malloc_len > 0)
+                    {
+                        memcpy(buffer, pos + 4, malloc_len);
+                    }
+                    
+                    if(axiom_mime_parser_is_more_data(mime_parser, env, callback_info))
+                    {
+                        len = callback(buffer + malloc_len, size - malloc_len, (void *) callback_ctx);
+                    }
 
-            temp_body_mime = pos;
-            mime_binary = AXIS2_MALLOC(env->allocator,
-                sizeof(char) * (mime_binary_len + 1));
-            if (!mime_binary)
+                    axiom_mime_parser_clear_buffers(env, buf_array, part_start, buf_num);
+                    if(len >= 0)
+                    {
+                        buf_array[buf_num] = buffer;
+                        len_array[buf_num] = malloc_len + len;
+                    }
+                }
+            }     
+            else
             {
                 AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
-                    "No memory. Failed in creating binary stream");
+                    "Error in parsing for mime headers.");
                 return NULL;
             }
-            memcpy(mime_binary, temp_mime_binary, mime_binary_len);
-            mime_binary[mime_binary_len] = '\0';
-        }
+        }    
 
-        if (mime_parser->mime_parts_map)
+        else if(search_info->match_len2 > 0)
         {
-            axis2_char_t *id = NULL;
-            axis2_char_t *type = NULL;
+            /*Now we extract the mime headers */
 
-            /* Get the MIME ID */
-            if (body_mime)
+            mime_headers_len = axiom_mime_parser_calculate_part_len (
+                env, buf_num - 1, len_array, part_start, pos, buf_array[buf_num - 1]);
+
+            if(mime_headers_len > 0)
             {
-                id = axutil_strcasestr(body_mime, AXIOM_MIME_HEADER_CONTENT_ID);
-                type = axutil_strcasestr(body_mime,
-                    AXIOM_MIME_HEADER_CONTENT_TYPE);
-                if (type)
+                mime_headers = axiom_mime_parser_create_part(
+                    env, soap_len, buf_num - 1, len_array, part_start, pos, buf_array, mime_parser);
+                if(!mime_headers)
                 {
-                    axis2_char_t *end = NULL;
-                    axis2_char_t *temp_type = NULL;
-                    type += axutil_strlen(AXIOM_MIME_HEADER_CONTENT_TYPE);
-                    while (type && *type && *type != ':')
-                    {
-                        type++;
-                    }
-                    type++;
-                    while (type && *type && *type == ' ')
-                    {
-                        type++;
-                    }
-                    end = type;
-                    while (end && *end && !isspace(*end))
-                    {
-                        end++;
+                    return NULL;
+                }
+
+                malloc_len = len_array[buf_num] - search_info->match_len2;
+                if(malloc_len < 0)
+                {
+                    return NULL;
+                }
+                else
+                {
+                    buffer = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * (
+                        size + 1));
+
+                    if(malloc_len > 0)
+                    {
+                        memcpy(buffer, buf_array[buf_num] + search_info->match_len2, malloc_len);
+                    }
+                    if(axiom_mime_parser_is_more_data(mime_parser, env, callback_info))
+                    {
+                        len = callback(buffer + malloc_len, size - malloc_len, (void *) callback_ctx);
+                    }
+                    axiom_mime_parser_clear_buffers(env, buf_array, part_start, buf_num);
+                    if(len >= 0)
+                    {
+                        buf_array[buf_num] = buffer;
+                        len_array[buf_num] = malloc_len + len;
+                    }
+                }
+            }     
+            else
+            {
+                return NULL;
+            }
+        }
+        else
+        {
+            return NULL;
+        }
+
+        pos = NULL;
+
+        search_info->match_len1 = 0;
+        search_info->match_len2 = 0;
+
+        part_start = buf_num;
+        malloc_len = 0;
+
+        mime_type = axiom_mime_parser_process_mime_headers(env, mime_parser, &mime_id, mime_headers);
+        
+        if(!mime_id )
+        {
+            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+                    "Error in parsing for mime headers.Mime id did not find");
+            return NULL;
+        }
+        
+        if(!mime_type)
+        {
+            AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI,
+                    "Mime type did not find");
+        }
+
+        /*We extract the mime headers. So lets search for the attachment.*/
+
+        pos = axiom_mime_parser_search_for_attachment(mime_parser, env, callback, callback_ctx, &buf_num,
+          len_array, buf_array, search_info, size, temp_mime_boundary, mime_id);
+
+        if(pos)
+        {
+            /*If it is small we are not caching. Hence the attachment 
+              is in memory. So store it in a buffer. */
+
+            if(!search_info->cached)
+            {
+                if(search_info->match_len2 == 0)
+                {
+                    /* mime_binary contains the attachment when it does not 
+                     * cached */
+
+                    mime_binary_len = axiom_mime_parser_calculate_part_len (
+                        env, buf_num, len_array, part_start, pos, buf_array[buf_num]);
+                    if(mime_binary_len > 0)
+                    {
+                        mime_binary = axiom_mime_parser_create_part(
+                            env, mime_binary_len, buf_num, len_array, part_start, pos, buf_array, mime_parser);
+                        if(!mime_binary)
+                        {
+                            return NULL;
+                        }
+                    }     
+                    else
+                    {
+                        return NULL;
                     }
-                    if ((end - type) > 0)
+                }
+        
+                else if(search_info->match_len2 > 0)
+                {
+                    mime_binary_len = axiom_mime_parser_calculate_part_len (
+                        env, buf_num - 1, len_array, part_start, pos, buf_array[buf_num - 1]);
+
+                    if(mime_binary_len > 0)
                     {
-                        temp_type = AXIS2_MALLOC(env->allocator,
-                            sizeof(axis2_char_t) * ((end - type) + 1));
-                        if (!temp_type)
+                        mime_binary = axiom_mime_parser_create_part(
+                            env, soap_len, buf_num - 1, len_array, part_start, pos, buf_array, mime_parser);
+                        if(!mime_binary)
                         {
-                            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
-                                "No memory. Failed in creating Content-Type");
                             return NULL;
                         }
-                        memcpy(temp_type, type, (end - type));
-                        temp_type[end - type] = '\0';
-                        type = temp_type;
+                    }
+                    else
+                    {
+                        return NULL;
                     }
                 }
             }
-            if (id)
+           
+            /* The functionality below is common when it is cached or not. It deals with remaining
+             * after a particualr attachment, Those may be related to a end of mime_boundary or 
+             * another attachment */
+
+            if(search_info->match_len2 == 0)
             {
-                id += axutil_strlen(AXIOM_MIME_HEADER_CONTENT_ID);
-                while (id && *id && *id != ':')
+                malloc_len = len_array[buf_num] - search_info->match_len1 - temp_mime_boundary_size;
+                if(malloc_len < 0)
                 {
-                    id++;
+                    return NULL;
                 }
-                if (id)
+                else
                 {
-                    while (id && *id && *id != '<')
+                    buffer = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * (
+                        size + 1));
+
+                    if(malloc_len > 0)
                     {
-                        id++;
+                        memcpy(buffer, pos + temp_mime_boundary_size, malloc_len);
                     }
-                    id++;
-                    pos = axutil_strstr(id, ">");
-                    if (pos)
+                    
+                    /*When the last buffer only containing -- we know this is the end 
+                     of the attachments. Hence we don't need to read again*/
+
+                    if(malloc_len != 2)
                     {
-                        axis2_char_t *mime_id = NULL;
-                        int mime_id_len = 0;
-                        mime_id_len = (int)(pos - id);
-                        mime_id = AXIS2_MALLOC(env->allocator,
-                            sizeof(axis2_char_t) * mime_id_len + 1); 
-                        /* The MIME ID will be freed by the SOAP builder */
-                        if (mime_id)
+                        if(axiom_mime_parser_is_more_data(mime_parser, env, callback_info))
                         {
-                            axiom_data_handler_t *data_handler = NULL;
-                            memcpy(mime_id, id, mime_id_len);
-                            mime_id[mime_id_len] = '\0';
-                            data_handler =
-                                axiom_data_handler_create(env, NULL, type);
-
-                            AXIS2_FREE(env->allocator, type);
-
-                            axiom_data_handler_set_binary_data(data_handler,
-                                env, mime_binary, mime_binary_len - 2);
-                            axutil_hash_set(mime_parser->mime_parts_map,
-                                mime_id, AXIS2_HASH_KEY_STRING, data_handler);
+                            len = callback(buffer + malloc_len, size - malloc_len, (void *) callback_ctx);        
                         }
-                        else
+                        if(len >= 0)
                         {
-                            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
-                                "No memory. Failed in creating MIME ID");
-                            return NULL;
+                            len_array[buf_num] = malloc_len + len;
                         }
                     }
+
+                    /* This means there is another attachment */
+                    else
+                    {
+                        len_array[buf_num] = malloc_len;
+                    }
+                    axiom_mime_parser_clear_buffers(env, buf_array, part_start, buf_num);
+                    buf_array[buf_num] = buffer;
                 }
-            }
-            else
+            }   
+            else if(search_info->match_len2 > 0)
             {
-                axis2_char_t temp_boundry[1024];
-                sprintf(temp_boundry, "--%s--", mime_boundary);
-                if (body_mime && axutil_strstr(body_mime, temp_boundry))
+                malloc_len = len_array[buf_num] - search_info->match_len2;
+
+                if(malloc_len < 0)
                 {
-                    break;
+                    return NULL;
+                }
+                else
+                {
+                    buffer = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * (
+                        size + 1));
+
+                    if(malloc_len > 0)
+                    {
+                        memcpy(buffer, buf_array[buf_num] + search_info->match_len2, malloc_len);
+                    }
+                    if(malloc_len != 2)
+                    {
+                        if(axiom_mime_parser_is_more_data(mime_parser, env, callback_info))
+                        {
+                            len = callback(buffer + malloc_len, size - malloc_len, (void *) callback_ctx);
+                        }
+                        if(len >= 0)
+                        {
+                            len_array[buf_num] = malloc_len + len;
+                        }
+                    }
+                    else
+                    {
+                        len_array[buf_num] = malloc_len;
+                    }
+                    axiom_mime_parser_clear_buffers(env, buf_array, part_start, buf_num);
+                    buf_array[buf_num] = buffer;
                 }
+            }              
+        }
+        else
+        {
+            return NULL;
+        }
+
+        /*We have the attachment now either cached or not. So lets put it in the mime_parts 
+         * hash map with the mime_id. Remember at this moment we have already processed the 
+         * mime_headers and mime_id is already there */        
+
+        /* In this case user has not specified the attachment dir . So we cached it to a memory
+         * buffer. Hence the data_handler type we need to create is different */
+
+        if((search_info->cached) && (!mime_parser->attachment_dir))
+        {
+            mime_binary = (axis2_char_t *)search_info->handler;
+            mime_binary_len = search_info->binary_size;
+        }
+
+        /* Storing the attachment in the hash map with the id*/
+
+        status = axiom_mime_parser_store_attachment(env, mime_parser, mime_id,
+            mime_type, mime_binary, mime_binary_len, search_info->cached);
+
+        /*Check wether we encounter --MIMEBOUNDARY-- to find the end of mime*/
+
+        if(buf_array[buf_num])
+        {
+            /* Here we check for the end of mime */            
+
+            end_of_mime = (AXIOM_MIME_BOUNDARY_BYTE == *(buf_array[buf_num])) &&
+                            (AXIOM_MIME_BOUNDARY_BYTE == *(buf_array[buf_num] + 1));
+            if(end_of_mime)
+            {
+                AXIS2_FREE(env->allocator, buf_array[buf_num]);
+                buf_array[buf_num] = NULL;
             }
-            body_mime = temp_body_mime;
         }
-    }                           /* end while (!end_of_mime) */
+
+        if(mime_headers)
+        {
+            AXIS2_FREE(env->allocator, mime_headers);
+            mime_headers = NULL;
+        }    
+
+        if(status != AXIS2_SUCCESS)
+        {
+            return NULL;
+        }
+    }   
+
+    /*Do the necessary cleaning */
 
     if (buf_array)
     {
@@ -462,49 +957,1016 @@
         len_array = NULL;
     }
 
-    AXIS2_FREE(env->allocator, buffer);
+    if(temp_mime_boundary)
+    {
+        AXIS2_FREE(env->allocator, temp_mime_boundary);
+        temp_mime_boundary = NULL;
+    }
+    
+    if(search_info)
+    {
+        AXIS2_FREE(env->allocator, search_info);
+        search_info = NULL;
+    }
 
     return mime_parser->mime_parts_map;
-}
 
-AXIS2_EXTERN axutil_hash_t *AXIS2_CALL
-axiom_mime_parser_get_mime_parts_map(
-    axiom_mime_parser_t *mime_parser,
-    const axutil_env_t *env)
-{
-    return mime_parser->mime_parts_map;
 }
 
-AXIS2_EXTERN int AXIS2_CALL
-axiom_mime_parser_get_soap_body_len(
-    axiom_mime_parser_t *mime_parser,
-    const axutil_env_t *env)
-{
-    return mime_parser->soap_body_len;
-}
+/*This method will search for \r\n\r\n */
 
-AXIS2_EXTERN axis2_char_t *AXIS2_CALL
-axiom_mime_parser_get_soap_body_str(
-    axiom_mime_parser_t *mime_parser,
-    const axutil_env_t *env)
+static axis2_char_t *axiom_mime_parser_search_for_crlf(
+    const axutil_env_t * env,
+    AXIS2_READ_INPUT_CALLBACK callback,
+    void *callback_ctx,
+    int *buf_num,
+    int *len_array,
+    axis2_char_t **buf_array,
+    axiom_search_info_t *search_info,
+    int size,
+    axiom_mime_parser_t *mime_parser)
 {
-    return mime_parser->soap_body_str;
+    axis2_char_t *found = NULL;
+    int len = 0;    
+
+    search_info->search_str = "\r\n\r\n";
+    search_info->buffer1 = NULL;
+    search_info->buffer2 = NULL;
+    search_info->len1 = 0;
+    search_info->len2 = 0;
+    search_info->match_len1 = 0;
+    search_info->match_len2 = 0;
+    search_info->primary_search = AXIS2_FALSE;
+    search_info->cached = AXIS2_FALSE;
+    search_info->handler = NULL;
+    search_info->binary_size = 0;
+
+    /*First do a search in the first buffer*/
+
+    if(buf_array[*buf_num])
+    {
+        search_info->buffer1 = buf_array[*buf_num];
+        search_info->len1 = len_array[*buf_num];
+        found = axiom_mime_parser_search_string(search_info, env);
+    }
+
+    while(!found)
+    {
+        /*Let's read another buffer and do a boundary search in both*/
+
+        *buf_num = *buf_num + 1;
+        buf_array[*buf_num] = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * (size + 1));
+
+        if(buf_array[*buf_num])
+        {
+            len = callback(buf_array[*buf_num], size, (void *) callback_ctx);
+        }
+        if(len > 0)
+        {
+            len_array[*buf_num] = len;
+            search_info->buffer2 = buf_array[*buf_num];
+            search_info->len2 = len;
+            found = axiom_mime_parser_search_string(search_info, env);
+        }
+        else
+        {
+            break;
+        }
+        if(!found)
+        {
+            /*Let's do a full search in the second buffer*/
+
+            search_info->buffer1 = buf_array[*buf_num];
+            search_info->len1 = len_array[*buf_num];
+            search_info->primary_search = AXIS2_FALSE;
+            search_info->buffer2 = NULL;
+            search_info->len2 = 0;
+            found = axiom_mime_parser_search_string(search_info, env);
+        }
+    }
+
+    return found;
 }
 
-AXIS2_EXTERN void AXIS2_CALL
-axiom_mime_parser_set_chunk_buffer_size(
-    axiom_mime_parser_t *mime_parser,
-    const axutil_env_t *env,
-    int size)
+/* This method will search for the mime_boundary after the SOAP part 
+ * of the message */
+
+static axis2_char_t *axiom_mime_parser_search_for_soap(
+    const axutil_env_t * env,
+    AXIS2_READ_INPUT_CALLBACK callback,
+    void *callback_ctx,
+    int *buf_num,
+    int *len_array,
+    axis2_char_t **buf_array,
+    axiom_search_info_t *search_info,
+    int size,
+    axis2_char_t *mime_boundary,
+    axiom_mime_parser_t *mime_parser)
 {
-    mime_parser->chunk_buffer_size = size;
+    axis2_char_t *found = NULL;
+    int len = 0;    
+    
+    /* What we need to search is the mime_boundary */
+
+    search_info->search_str = mime_boundary;
+    search_info->buffer1 = NULL;
+    search_info->buffer2 = NULL;
+    search_info->len1 = 0;
+    search_info->len2 = 0;
+    search_info->match_len1 = 0;
+    search_info->match_len2 = 0;
+    search_info->primary_search = AXIS2_FALSE;
+
+    if(buf_array[*buf_num])
+    {
+        search_info->buffer1 = buf_array[*buf_num];
+        search_info->len1 = len_array[*buf_num];
+        found = axiom_mime_parser_search_string(search_info, env);
+
+        /* Inside this search primary_search flag will be set to TRUE */
+    }
+
+    while(!found)
+    {
+        /* We need to create the second buffer and do the search for the 
+         * mime_boundary in the both the buffers */
+
+        *buf_num = *buf_num + 1;
+        buf_array[*buf_num] = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * (size + 1));
+
+        if(buf_array[*buf_num])
+        {
+            len = callback(buf_array[*buf_num], size, (void *) callback_ctx);
+        }
+        if(len > 0)
+        {
+            /* In this search we are matching end part of the first
+             * buffer and starting part of the previous buffer */
+            len_array[*buf_num] = len;
+            search_info->buffer2 = buf_array[*buf_num];
+            search_info->len2 = len;
+            found = axiom_mime_parser_search_string(search_info, env);
+        }
+        else
+        {
+            break;
+        }
+        if(!found)
+        {
+            search_info->buffer1 = buf_array[*buf_num];
+            search_info->len1 = len_array[*buf_num];
+            search_info->primary_search = AXIS2_FALSE;
+            search_info->buffer2 = NULL;
+            search_info->len2 = 0;
+            found = axiom_mime_parser_search_string(search_info, env);
+        }
+    }
+
+    return found;
 }
 
-AXIS2_EXTERN void AXIS2_CALL
-axiom_mime_parser_set_max_chunk_buffers(
+/*The caching is done in this function. Caching happens when we did not 
+  find the mime_boundary in initial two buffers. So the maximum size
+  that we are keeping in memory is 2 * size. This size can be configurable from
+  the aixs.xml. The caching may starts when the search failed with the
+  second buffer.  */
+
+static axis2_char_t *axiom_mime_parser_search_for_attachment(
     axiom_mime_parser_t *mime_parser,
-    const axutil_env_t *env,
-    int num)
+    const axutil_env_t * env,
+    AXIS2_READ_INPUT_CALLBACK callback,
+    void *callback_ctx,
+    int *buf_num,
+    int *len_array,
+    axis2_char_t **buf_array,
+    axiom_search_info_t *search_info,
+    int size,
+    axis2_char_t *mime_boundary,
+    axis2_char_t *mime_id)
 {
-    mime_parser->max_chunk_buffers = num;
-}
+    axis2_char_t *found = NULL;
+    int len = 0;   
+    axis2_status_t status = AXIS2_FAILURE;
+    axis2_char_t *temp = NULL;    
+    int temp_length = 0;
+    axis2_char_t *file_name = NULL;
+
+    search_info->search_str = mime_boundary;
+    search_info->buffer1 = NULL;
+    search_info->buffer2 = NULL;
+    search_info->len1 = 0;
+    search_info->len2 = 0;
+    search_info->match_len1 = 0;
+    search_info->match_len2 = 0;
+    search_info->primary_search = AXIS2_FALSE;
+    search_info->cached = AXIS2_FALSE;
+    search_info->handler = NULL;
+
+    /*First search in the incoming buffer*/
+
+    if(buf_array[*buf_num])
+    {
+        search_info->buffer1 = buf_array[*buf_num];
+        search_info->len1 = len_array[*buf_num];
+        found = axiom_mime_parser_search_string(search_info, env);
+    }
+
+    while(!found)
+    {
+        if(search_info->cached)
+        {
+            if(mime_parser->attachment_dir)
+            {
+                if(!(search_info->handler))
+                {
+                    /* If the File is not opened yet we will open it*/
+                    file_name = axutil_stracat(env, mime_parser->attachment_dir, 
+                        mime_id);
+                    if(!file_name)
+                    {
+                        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+                            "Caching file name creation error");
+                        return NULL;
+                    }
+                    search_info->handler = (void *)fopen(file_name, "ab+");
+                    if(!(search_info->handler))
+                    {
+                            return NULL;
+                    }
+                }
+            
+                /*So lets cache the previous buffer which has undergone the
+                full search and the partial search.  */
+
+                status = axiom_mime_parser_cache_to_file(env, buf_array[*buf_num - 1], 
+                    len_array[*buf_num - 1], search_info->handler);            
+            }
+
+            else
+            {
+                /* Here the user has not specified the caching File location. So we are 
+                 * not going to cache. Instead we store the attachment in the buffer */
+                status = axiom_mime_parser_cache_to_buffer(env, buf_array[*buf_num - 1], 
+                    len_array[*buf_num - 1], search_info, mime_parser);
+            }
+
+            if(status == AXIS2_FAILURE)
+            {
+                return NULL;
+            }
+            /*Here we interchange the buffers.*/
+
+            temp = buf_array[*buf_num - 1];    
+            buf_array[*buf_num - 1] = buf_array[*buf_num];
+            buf_array[*buf_num] = temp;
+            temp_length = len_array[*buf_num - 1];
+            len_array[*buf_num - 1] = len_array[*buf_num];
+            len_array[*buf_num] = temp_length;
+            if(buf_array[*buf_num])
+            {
+                /*The cached buffer is the one which get filled.*/
+                len = callback(buf_array[*buf_num], size, (void *) callback_ctx);
+            }
+        }
+
+        /*Size of the data in memory not yet risen to the caching threasold
+         *So we can create the second buffer */
+        else
+        {
+            *buf_num = *buf_num + 1;
+            buf_array[*buf_num] = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * (size + 1));
+
+            if(buf_array[*buf_num])
+            {
+                len = callback(buf_array[*buf_num], size, (void *) callback_ctx);
+            }
+        }
+        
+        /*Doing  a complete search in newly cretaed buffer*/       
+ 
+        if(len > 0)
+        {
+            len_array[*buf_num] = len;
+            search_info->buffer2 = buf_array[*buf_num];
+            search_info->len2 = len;
+            found = axiom_mime_parser_search_string(search_info, env);
+        }
+        else
+        {
+            break;
+        }
+
+        /* Now there are two buffers. If the searching string is not 
+         * here then we must cache the first buffer */
+                
+        if(!found)
+        {
+            /*So now we must start caching*/
+            search_info->buffer1 = buf_array[*buf_num];
+            search_info->len1 = len_array[*buf_num];
+            search_info->primary_search = AXIS2_FALSE;
+            search_info->buffer2 = NULL;
+            search_info->len2 = 0;
+            found = axiom_mime_parser_search_string(search_info, env);
+            if(!found)
+            {
+                /* So at the begining of the next search we start
+                 * that only after caching this data */
+                search_info->cached = AXIS2_TRUE;   
+            }
+        }
+    }
+
+    /* Here we are out of the loop. If there is no error then this means 
+     * the searching string is found */
+
+    if(search_info->cached)
+    {
+        /* If the attachment is cached then we need to cache the 
+         * final buffer */
+
+        if(search_info->match_len2 == 0)
+        {
+            /* This is the case where we found the whole string in one buffer 
+             * So we need to cache previous buffer and the data up to the starting
+             * point of the search string in the current buffer */
+
+            if(mime_parser->attachment_dir)
+            {
+                status = axiom_mime_parser_cache_to_file(env, buf_array[*buf_num - 1], 
+                    len_array[*buf_num - 1], search_info->handler);
+                if(status == AXIS2_SUCCESS)
+                {
+                    status = axiom_mime_parser_cache_to_file(env, buf_array[*buf_num], 
+                        found - buf_array[*buf_num], search_info->handler);
+                }
+            }
+            
+            /* If the callback is not there then the data is appended to the buffer */
+
+            else
+            {
+                status = axiom_mime_parser_cache_to_buffer(env, buf_array[*buf_num - 1],
+                    len_array[*buf_num - 1], search_info, mime_parser);
+                if(status == AXIS2_SUCCESS)
+                {
+                    status = axiom_mime_parser_cache_to_buffer(env, buf_array[*buf_num], 
+                        found - buf_array[*buf_num], search_info, mime_parser);
+                }
+            }
+        }
+        else if(search_info->match_len2 > 0)
+        {
+            /*Here the curent buffer has partial mime boundary. So we need 
+            to cache only the previous buffer. */
+            if(mime_parser->attachment_dir)
+            {
+                status = axiom_mime_parser_cache_to_file(env, buf_array[*buf_num - 1], 
+                    search_info->match_len1, search_info->handler);
+            }
+            else
+            {
+                status = axiom_mime_parser_cache_to_buffer(env, buf_array[*buf_num - 1],
+                    search_info->match_len1, search_info, mime_parser);
+            }
+        }
+        else
+        {
+            return NULL;
+        }
+
+        if(status == AXIS2_FAILURE)
+        {
+            return NULL;
+        }
+    }
+
+    /* Parsing is done so lets close the relative handlers */
+
+    if(search_info->handler && mime_parser->attachment_dir)
+    {
+        if(fclose((FILE *)(search_info->handler)) == 0)
+        {
+            status = AXIS2_SUCCESS;
+        }
+        else
+        {
+            status = AXIS2_FAILURE;
+        }
+
+        AXIS2_FREE(env->allocator, file_name);
+        file_name = NULL;        
+
+        if(status == AXIS2_FAILURE)
+        {
+            return NULL;
+        }
+    }
+    return found;
+}
+
+
+/*following two functions are used to extract important information 
+  from the buffer list. eg: SOAP, MIME_HEADERS*/
+
+/*marker is the starting buffer of the required 
+     part and pos is the end point of that part  */
+
+static int axiom_mime_parser_calculate_part_len (
+    const axutil_env_t *env,
+    int buf_num,
+    int *len_list,
+    int marker,
+    axis2_char_t *pos,
+    axis2_char_t *buf)
+{
+    int part_len = 0;    
+    int i = 0;
+
+    for(i = marker; i < buf_num; i++)
+    {
+        part_len += len_list[i];
+    }
+
+    part_len = part_len + (pos - buf);
+    
+    return part_len;
+}
+
+static axis2_char_t * axiom_mime_parser_create_part(
+    const axutil_env_t *env,
+    int part_len,
+    int buf_num,
+    int *len_list,
+    int marker,
+    axis2_char_t *pos,
+    axis2_char_t **buf_list,
+    axiom_mime_parser_t *mime_parser)
+{
+    /*We will copy the set of buffers which contains the required part.
+     This part can be the SOAP message , mime headers or the mime 
+     binary in the case of none cahced.*/
+
+    axis2_char_t *part_str = NULL;
+    int i = 0;
+    int temp = 0;
+
+    part_str = AXIS2_MALLOC(env->allocator, sizeof(char) * (part_len + 1));
+    
+
+    if (!part_str)
+    {
+        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+            "No memory. Failed in creating buffer");
+        return NULL;
+    }
+
+    /* Copy from the part starting buffer to the 
+     * curent buffer */ 
+
+    for (i = marker; i < buf_num; i++)
+    {
+        if (buf_list[i])
+        {
+            memcpy(part_str + temp, buf_list[i], len_list[i]);
+            temp += len_list[i];
+        }
+    }
+    /* Finally we are copying from the final portion */
+
+    memcpy(part_str + temp, buf_list[i], pos - buf_list[i]);
+
+    part_str[part_len] = '\0';
+
+    return part_str; 
+}
+
+AXIS2_EXTERN axutil_hash_t *AXIS2_CALL
+axiom_mime_parser_get_mime_parts_map(
+    axiom_mime_parser_t * mime_parser,
+    const axutil_env_t * env)
+{
+    return mime_parser->mime_parts_map;
+}
+
+AXIS2_EXTERN int AXIS2_CALL
+axiom_mime_parser_get_soap_body_len(
+    axiom_mime_parser_t * mime_parser,
+    const axutil_env_t * env)
+{
+    return mime_parser->soap_body_len;
+}
+
+AXIS2_EXTERN axis2_char_t *AXIS2_CALL
+axiom_mime_parser_get_soap_body_str(
+    axiom_mime_parser_t * mime_parser,
+    const axutil_env_t * env)
+{
+    return mime_parser->soap_body_str;
+}
+
+/*This is the new search function. This will first do a
+search for the entire search string.Then will do a search 
+for the partial string which can be divided among two buffers.*/
+
+
+static axis2_char_t *axiom_mime_parser_search_string(
+    axiom_search_info_t *search_info,
+    const axutil_env_t *env)
+{
+    axis2_char_t *pos = NULL;
+    axis2_char_t *old_pos = NULL;
+    axis2_char_t *found = NULL;
+    int str_length = 0;
+    int search_length = 0;
+
+    str_length = strlen(search_info->search_str);
+
+    /*First lets search the entire buffer*/
+    if(!search_info->primary_search)
+    {
+        old_pos = search_info->buffer1;
+
+        do
+        {
+            /*find the first byte. We need to adhere to this
+             approach rather than straightaway using strstr
+             because the buffer1 can be containg binary data*/
+
+            pos = NULL;
+
+            search_length = search_info->buffer1 + search_info->len1
+                                - old_pos - str_length + 1;
+
+            if(search_length < 0)
+            {
+                break;
+            }
+
+            if (old_pos)
+            {
+                pos = memchr(old_pos, *(search_info->search_str),
+                        search_length);
+            }
+
+            /* found it so lets check the remaining */
+
+            if (pos)
+            {
+                found = axutil_strstr(pos, search_info->search_str);
+                if(found)
+                {
+                    search_info->match_len1 = found - search_info->buffer1;
+                    break;
+                }
+                else
+                {
+                    old_pos = pos + 1;
+                }
+            }
+        }
+        while (pos);
+    }
+
+    search_info->primary_search = AXIS2_TRUE;
+
+    if(found)
+    {
+        return found;
+    }
+
+    /*So we didn't find the string in the buffer
+     lets check whether it is divided in two buffers*/
+
+    else
+    {
+        int offset = 0;
+        pos = NULL;
+        old_pos = NULL;
+        found = NULL;
+        search_length = 0;
+
+        if(search_info->buffer2)
+        {
+            old_pos = search_info->buffer1 + search_info->len1 - str_length + 1;
+            do
+            {
+                /*First check the starting byte*/
+                pos = NULL;
+                found = NULL;
+
+                search_length = search_info->buffer1 + search_info->len1 - old_pos;
+
+                if(search_length < 0)
+                {
+                    break;
+                }
+
+                pos = memchr(old_pos, *(search_info->search_str), search_length);
+
+                if(pos)
+                {
+                    offset = search_info->buffer1 + search_info->len1 - pos;
+
+                    /*First match the beginng to offset in buffer1*/
+
+                    if(offset > 0)
+                    {
+                        if(memcmp(pos, search_info->search_str, offset)
+                          == 0)
+                        {
+                            found = pos;
+                        }
+
+                        /*We found something in buffer1 so lets match the
+                          remaining in buffer2*/
+
+                        if(found)
+                        {
+                            if(memcmp(search_info->buffer2, search_info->search_str + offset,
+                               str_length - offset ) == 0)
+                            {
+                                search_info->match_len2 = str_length - offset;
+                                search_info->match_len1 = found - search_info->buffer1;
+                                break;
+                            }
+                            else
+                            {
+                                old_pos = pos + 1;
+                            }
+                        }
+                        else
+                        {
+                            old_pos = pos + 1;
+                        }
+                    }
+                }
+            }
+            while(pos);
+
+            /* We will set this to AXIS2_FALSE so when the next time this
+             * search method is called it will do a full search first for buffer1 */
+            search_info->primary_search = AXIS2_FALSE;
+
+            return found;
+        }
+        else
+        {
+            return NULL;
+        }
+    }
+}
+
+
+/* This method creates a data_handler out of the attachment 
+ * and store the data_handler in the mime_parts map */
+
+static axis2_status_t 
+axiom_mime_parser_store_attachment(
+    const axutil_env_t *env,
+    axiom_mime_parser_t *mime_parser,
+    axis2_char_t *mime_id,
+    axis2_char_t *mime_type,
+    axis2_char_t *mime_binary,
+    int mime_binary_len,
+    axis2_bool_t cached)
+{
+	if (mime_parser->mime_parts_map)
+    {
+        if (mime_id)
+        {
+            axiom_data_handler_t *data_handler = NULL;
+
+            /* Handling the case where attachment is cached to a file*/
+
+            if(!mime_binary && cached)
+            {
+                axis2_char_t *attachment_location = NULL;
+
+                attachment_location = axutil_stracat(env, 
+                    mime_parser->attachment_dir, mime_id);
+                if(attachment_location)
+                {
+                    data_handler = axiom_data_handler_create(env, 
+                        attachment_location, mime_type);
+                    if(data_handler)
+                    {
+                        axiom_data_handler_set_cached(data_handler, env, AXIS2_TRUE);
+                    }
+                    AXIS2_FREE(env->allocator, attachment_location);
+                    attachment_location = NULL; 
+                }
+            }
+
+            /* Attachment is in memory, either it is small to be cached or
+             * user does not provided the attachment cached directory */
+
+            else if(mime_binary)
+            {
+                data_handler = axiom_data_handler_create(env, 
+                    NULL, mime_type);
+                if(data_handler)
+                {
+                    axiom_data_handler_set_binary_data(data_handler,
+                        env, mime_binary, mime_binary_len - 2);
+                }
+            }
+            axutil_hash_set(mime_parser->mime_parts_map,
+                    mime_id, AXIS2_HASH_KEY_STRING, data_handler);
+            if(mime_type)
+            {
+                AXIS2_FREE(env->allocator, mime_type);
+            }
+        }
+        else
+        {
+            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+                "Mime Id or Mime rype not found");
+            return AXIS2_FAILURE;
+            /*axis2_char_t temp_boundry[1024];
+            sprintf(temp_boundry, "--%s--", mime_boundary);
+            if (body_mime && axutil_strstr(body_mime, temp_boundry))
+            {
+                break;
+            }*/
+        }
+        return AXIS2_SUCCESS;
+    }	
+    else
+    {
+        return AXIS2_FAILURE;
+    }    
+}
+
+/* This method will process the mime_headers for a particualr
+   attacment and return the mime_id  */
+
+
+static axis2_char_t *
+    axiom_mime_parser_process_mime_headers(
+    const axutil_env_t *env,
+    axiom_mime_parser_t *mime_parser,
+    axis2_char_t **mime_id,
+    axis2_char_t *mime_headers)
+{
+    axis2_char_t *id = NULL;
+    axis2_char_t *type = NULL;
+    axis2_char_t *pos = NULL;      
+
+    /* Get the MIME ID */
+    if (mime_headers)
+    {
+        id = axutil_strcasestr(mime_headers, AXIOM_MIME_HEADER_CONTENT_ID);
+        type = axutil_strcasestr(mime_headers,
+            AXIOM_MIME_HEADER_CONTENT_TYPE);
+        if (type)
+        {
+            axis2_char_t *end = NULL;
+            axis2_char_t *temp_type = NULL;
+            type += axutil_strlen(AXIOM_MIME_HEADER_CONTENT_TYPE);
+            while (type && *type && *type != ':')
+            {
+                type++;
+            }
+            type++;
+            while (type && *type && *type == ' ')
+            {
+                type++;
+            }
+            end = type;
+            while (end && *end && !isspace(*end))
+            {
+                end++;
+            }
+            if ((end - type) > 0)
+            {
+                temp_type = AXIS2_MALLOC(env->allocator,
+                    sizeof(axis2_char_t) * ((end - type) + 1));
+                if (!temp_type)
+                {
+                    AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+                        "No memory. Failed in creating Content-Type");
+                    return NULL;
+                }
+                memcpy(temp_type, type, (end - type));
+                temp_type[end - type] = '\0';
+                type = temp_type;
+            }
+        }
+        if (id)
+        {
+            id += axutil_strlen(AXIOM_MIME_HEADER_CONTENT_ID);
+            while (id && *id && *id != ':')
+            {
+                id++;
+            }
+            if (id)
+            {
+                while (id && *id && *id != '<')
+                {
+                    id++;
+                }
+                id++;
+                pos = axutil_strstr(id, ">");
+                if (pos)
+                {
+                    int mime_id_len = 0;
+                    mime_id_len = (int)(pos - id);
+                    *mime_id = AXIS2_MALLOC(env->allocator,
+                        sizeof(axis2_char_t) * mime_id_len + 1); 
+                    /* The MIME ID will be freed by the SOAP builder */
+                    if (*mime_id)
+                    {
+                        memcpy(*mime_id, id, mime_id_len);
+                        (*mime_id)[mime_id_len] = '\0';
+                    }
+                    else
+                    {
+                        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+                            "No memory. Failed in creating MIME ID");
+                        return NULL;
+                    }
+                }
+            }
+        }
+        else
+        {
+            /*axis2_char_t temp_boundry[1024];
+            sprintf(temp_boundry, "--%s--", mime_boundary);
+            if (body_mime && axutil_strstr(body_mime, temp_boundry))
+            {
+                break;
+            }*/
+            return NULL;
+        }
+        return type;
+    }
+    else
+    {
+        return NULL;
+    }	
+} 
+
+
+/*This is used to free some unwanted buffers. For example we did
+not want the buffers which contains the data before the soap
+envelope starts. */
+
+static void axiom_mime_parser_clear_buffers(
+    const axutil_env_t *env,
+    axis2_char_t **buf_list,
+    int free_from,
+    int free_to)
+{
+    int i = 0;
+
+    for(i = free_from; i <= free_to; i++)
+    {
+        if(buf_list[i])
+        {
+            AXIS2_FREE(env->allocator, buf_list[i]);
+            buf_list[i] = NULL;
+        }   
+    }
+    return;
+}
+
+
+/* Instead of caching to a file this method will cache it
+ * to a buffer */
+
+static axis2_status_t axiom_mime_parser_cache_to_buffer(
+    const axutil_env_t *env,
+    axis2_char_t *buf,
+    int buf_len,
+    axiom_search_info_t *search_info,
+    axiom_mime_parser_t *mime_parser)
+{
+    axis2_char_t *data_buffer = NULL;
+    axis2_char_t *temp_buf = NULL;
+    int mime_binary_len = 0;
+
+    temp_buf = (axis2_char_t *)search_info->handler;
+    mime_binary_len = search_info->binary_size + buf_len;
+
+    if(mime_binary_len > 0)
+    {
+        data_buffer = AXIS2_MALLOC(env->allocator, 
+            sizeof(axis2_char_t) * (mime_binary_len));
+
+
+        if(data_buffer)
+        {
+            if(temp_buf && search_info->binary_size > 0)
+            {
+                memcpy(data_buffer, temp_buf, search_info->binary_size);
+                AXIS2_FREE(env->allocator, temp_buf);
+                temp_buf = NULL;
+            }
+            memcpy(data_buffer + (search_info->binary_size), 
+                buf, buf_len);
+            search_info->binary_size = mime_binary_len;
+            search_info->handler = (void *)data_buffer;
+
+            return AXIS2_SUCCESS;
+        }
+        else
+        {
+            return AXIS2_FAILURE;
+        }
+    }
+    else
+    {
+        return AXIS2_FAILURE;
+    }
+}
+
+
+AXIS2_EXTERN void AXIS2_CALL
+axiom_mime_parser_set_buffer_size(
+    axiom_mime_parser_t *mime_parser,
+    const axutil_env_t *env,
+    int size)
+{
+    mime_parser->buffer_size = size;
+}
+
+AXIS2_EXTERN void AXIS2_CALL
+axiom_mime_parser_set_max_buffers(
+    axiom_mime_parser_t *mime_parser,
+    const axutil_env_t *env,
+    int num)
+{
+    mime_parser->max_buffers = num;
+}
+
+AXIS2_EXTERN void AXIS2_CALL
+axiom_mime_parser_set_attachment_dir(
+    axiom_mime_parser_t *mime_parser,
+    const axutil_env_t *env,
+    axis2_char_t *attachment_dir)
+{
+    mime_parser->attachment_dir = attachment_dir;
+}
+
+
+/* This method will tell whether there are more data in the 
+ * stream */
+
+static axis2_bool_t axiom_mime_parser_is_more_data(
+    axiom_mime_parser_t *mime_parser,
+    const axutil_env_t *env,
+    axis2_callback_info_t *callback_info)
+{
+    /* In the case of axutil_http_chunked stream it is the 
+     * end of chunk */
+
+    if(callback_info->chunked_stream)
+    {
+        if(axutil_http_chunked_stream_get_end_of_chunks(
+            callback_info->chunked_stream, env))
+        {
+            return AXIS2_FALSE;
+        }
+        else
+        {
+            return AXIS2_TRUE;
+        }
+    }
+
+    /* When we are using content length or any wrapped 
+     * stream it will be the unread_length */
+
+    else if(callback_info->unread_len == 0)
+    {
+        return AXIS2_FALSE;
+    }
+    else
+    {
+        return AXIS2_TRUE;
+    }
+}
+
+static axis2_status_t 
+axiom_mime_parser_cache_to_file(
+    const axutil_env_t* env,
+    axis2_char_t *buf,
+    int buf_len,
+    void *handler)
+{
+    int len = 0;
+    FILE *fp = NULL;
+
+    fp = (FILE *)handler;
+
+    len = fwrite(buf, 1, buf_len, fp);
+    if(len < 0)
+    {
+        return AXIS2_FAILURE;
+    }
+    else
+    {
+        return AXIS2_SUCCESS;
+    }
+}
+

Copied: webservices/axis2/trunk/c/axiom/src/attachments/mime_part.c (from r674731, webservices/axis2/branches/c/post_1_4_mtom/c/axiom/src/attachments/mime_part.c)
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/c/axiom/src/attachments/mime_part.c?p2=webservices/axis2/trunk/c/axiom/src/attachments/mime_part.c&p1=webservices/axis2/branches/c/post_1_4_mtom/c/axiom/src/attachments/mime_part.c&r1=674731&r2=678680&rev=678680&view=diff
==============================================================================
--- webservices/axis2/branches/c/post_1_4_mtom/c/axiom/src/attachments/mime_part.c (original)
+++ webservices/axis2/trunk/c/axiom/src/attachments/mime_part.c Tue Jul 22 01:43:36 2008
@@ -398,7 +398,7 @@
  * with small buffers and attachment locations. */
 
 
-AXIS2_EXTERN axutil_array_list_t  *AXIS2_CALL
+AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL
 axiom_mime_part_create_part_list(
     const axutil_env_t *env,
     axis2_char_t *soap_body,
@@ -500,7 +500,7 @@
     
     if(!soap_part)
     {
-        return AXIS2_FAILURE;
+        return NULL;
     }    
 
     /* The atachment's mime_boundary will start after a new line charator */

Propchange: webservices/axis2/trunk/c/axiom/src/om/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Tue Jul 22 01:43:36 2008
@@ -0,0 +1,2 @@
+.deps
+.libs

Modified: webservices/axis2/trunk/c/axiom/src/om/om_output.c
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/c/axiom/src/om/om_output.c?rev=678680&r1=678679&r2=678680&view=diff
==============================================================================
--- webservices/axis2/trunk/c/axiom/src/om/om_output.c (original)
+++ webservices/axis2/trunk/c/axiom/src/om/om_output.c Tue Jul 22 01:43:36 2008
@@ -24,7 +24,7 @@
 #include <axiom_soap_const.h>
 #include <axutil_array_list.h>
 #include <axutil_uuid_gen.h>
-#include <axiom_mime_output.h>
+#include <axiom_mime_part.h>
 
 #define AXIS2_DEFAULT_CHAR_SET_ENCODING  "UTF-8"
 
@@ -60,12 +60,12 @@
 
     axutil_array_list_t *binary_node_list;
 
-    axiom_mime_output_t *mime_output;
-
     axis2_char_t *mime_boundry;
 
     axis2_char_t *content_type;
 
+    axutil_array_list_t *mime_parts;
+
 };
 
 AXIS2_EXTERN axiom_output_t *AXIS2_CALL
@@ -96,9 +96,9 @@
     om_output->xml_version = NULL;
     om_output->ignore_xml_declaration = AXIS2_TRUE;
     om_output->binary_node_list = NULL;
-    om_output->mime_output = NULL;
     om_output->mime_boundry = NULL;
     om_output->content_type = NULL;
+    om_output->mime_parts = NULL;
 
     return om_output;
 }
@@ -137,10 +137,6 @@
         axutil_array_list_free(om_output->binary_node_list, env);
     }
 
-    if (om_output->mime_output)
-    {
-        axiom_mime_output_free(om_output->mime_output, env);
-    }
     if (om_output->content_type)
     {
         AXIS2_FREE(env->allocator, om_output->content_type);
@@ -292,13 +288,9 @@
 
         om_output->content_type =
             (axis2_char_t *)
-            axiom_mime_output_get_content_type_for_mime(om_output->mime_output,
-                                                        env,
-                                                        om_output->mime_boundry,
-                                                        om_output->
-                                                        root_content_id,
-                                                        om_output->
-                                                        char_set_encoding,
+            axiom_mime_part_get_content_type_for_mime(env, om_output->mime_boundry,
+                                                        om_output->root_content_id,
+                                                        om_output->char_set_encoding,
                                                         soap_content_type);
         return om_output->content_type;
     }
@@ -631,12 +623,16 @@
 
 }
 
-axis2_byte_t *AXIS2_CALL
-axiom_output_flush(
+/* This method will be called from transport. After this method each and every
+ * message part needs to be send are stored in an arraylits. So the transport 
+ * sender should correctly figure out how to send from the given information.
+ */ 
+
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL 
+    axiom_output_flush(
     axiom_output_t * om_output,
-    const axutil_env_t * env,
-    axis2_byte_t ** output_stream,
-    int *output_stream_size)
+    const axutil_env_t * env)
 {
     const axis2_char_t *soap_content_type = NULL;
 
@@ -644,12 +640,13 @@
 
     if (om_output->do_optimize)
     {
-        axis2_byte_t *byte_stream = NULL;
         axis2_char_t *root_content_id = NULL;
-        axis2_char_t *buffer =
-            (axis2_char_t *) axiom_xml_writer_get_xml(om_output->xml_writer,
+        axis2_char_t *buffer = NULL;
+
+        /* Extracting the soap part */
+
+        buffer = axiom_xml_writer_get_xml(om_output->xml_writer,
                                                       env);
-        int stream_size = 0;
         if (om_output->is_soap11)
         {
             soap_content_type = AXIOM_SOAP11_CONTENT_TYPE;
@@ -658,21 +655,41 @@
         {
             soap_content_type = AXIOM_SOAP12_CONTENT_TYPE;
         }
-        om_output->mime_output = axiom_mime_output_create(env);
+        
+        /* The created mime_boundary for this soap message */
+        
         om_output->mime_boundry = axiom_output_get_mime_boundry(om_output, env);
+        
+        /* This is also created for attachments*/
         root_content_id = axiom_output_get_root_content_id(om_output, env);
-        axiom_mime_output_complete(om_output->mime_output,
-                                   env, &byte_stream, &stream_size,
-                                   buffer, om_output->binary_node_list,
-                                   om_output->mime_boundry,
-                                   om_output->root_content_id,
-                                   om_output->char_set_encoding,
-                                   soap_content_type);
-
-        *output_stream = byte_stream;
-        *output_stream_size = stream_size;
-
-        return byte_stream;
+        
+        /* different parts of the message is added according to their order
+         * to an arraylist */
+        om_output->mime_parts = axiom_mime_part_create_part_list( 
+                                    env, buffer, om_output->binary_node_list,
+                                    om_output->mime_boundry, 
+                                    om_output->root_content_id, 
+                                    om_output->char_set_encoding,
+                                    soap_content_type);
+        
+        if(om_output->mime_parts)
+        {
+            return AXIS2_SUCCESS;
+        }
+        else
+        {
+            return AXIS2_FAILURE;
+        }
     }
-    return NULL;
+    return AXIS2_SUCCESS;
 }
+
+AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL
+axiom_output_get_mime_parts(
+    axiom_output_t * om_output,
+    const axutil_env_t * env)
+{
+    AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
+    return om_output->mime_parts;
+}
+

Modified: webservices/axis2/trunk/c/include/axis2_const.h
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/c/include/axis2_const.h?rev=678680&r1=678679&r2=678680&view=diff
==============================================================================
--- webservices/axis2/trunk/c/include/axis2_const.h (original)
+++ webservices/axis2/trunk/c/include/axis2_const.h Tue Jul 22 01:43:36 2008
@@ -352,11 +352,9 @@
 
     /* globally enable MTOM */
 #define AXIS2_ENABLE_MTOM "enableMTOM"
-#define AXIS2_ATTACHMENT_TEMP_DIR "attachmentDIR"
-#define AXIS2_CACHE_ATTACHMENTS "cacheAttachments"
-#define AXIS2_FILE_SIZE_THRESHOLD "sizeThreshold"
-#define AXIS2_MTOM_CHUNK_BUFFER_SIZE "MTOMChunkBufferSize"
-#define AXIS2_MTOM_MAX_CHUNK_BUFFERS "MTOMMaxChunkBuffers"
+#define AXIS2_ATTACHMENT_DIR "attachmentDIR"
+#define AXIS2_MTOM_BUFFER_SIZE "MTOMBufferSize"
+#define AXIS2_MTOM_MAX_BUFFERS "MTOMMaxBuffers"
 
     /* op_ctx persistance */
 #define AXIS2_PERSIST_OP_CTX "persistOperationContext"

Modified: webservices/axis2/trunk/c/include/axis2_http_client.h
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/c/include/axis2_http_client.h?rev=678680&r1=678679&r2=678680&view=diff
==============================================================================
--- webservices/axis2/trunk/c/include/axis2_http_client.h (original)
+++ webservices/axis2/trunk/c/include/axis2_http_client.h Tue Jul 22 01:43:36 2008
@@ -38,6 +38,8 @@
 #include <axis2_http_simple_request.h>
 #include <axutil_url.h>
 
+
+
 #ifdef __cplusplus
 extern "C"
 {
@@ -231,6 +233,29 @@
         void *client,
         const axutil_env_t * env);
 
+    AXIS2_EXTERN axis2_status_t AXIS2_CALL
+    axis2_http_client_set_mime_parts(
+        axis2_http_client_t * client,
+        const axutil_env_t * env,
+        axutil_array_list_t *mime_parts);
+
+    AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL
+    axis2_http_client_get_mime_parts(
+        const axis2_http_client_t * client,
+        const axutil_env_t * env);
+
+    AXIS2_EXTERN axis2_status_t AXIS2_CALL
+    axis2_http_client_set_doing_mtom(
+        axis2_http_client_t * client,
+        const axutil_env_t * env,
+        axis2_bool_t doing_mtom);
+
+    AXIS2_EXTERN axis2_bool_t AXIS2_CALL
+    axis2_http_client_get_doing_mtom(
+        const axis2_http_client_t * client,
+        const axutil_env_t * env);
+
+
     /** @} */
 #ifdef __cplusplus
 }

Modified: webservices/axis2/trunk/c/include/axis2_http_sender.h
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/c/include/axis2_http_sender.h?rev=678680&r1=678679&r2=678680&view=diff
==============================================================================
--- webservices/axis2/trunk/c/include/axis2_http_sender.h (original)
+++ webservices/axis2/trunk/c/include/axis2_http_sender.h Tue Jul 22 01:43:36 2008
@@ -201,7 +201,7 @@
                         axis2_http_sender_set_om_output (sender, env, om_output)
 
     /** Set http version. */
-#define AXIOM_SENDER_SET_HTTP_VERSION(sender, env, version)\
+#define AXIS2_HTTP_SENDER_SET_HTTP_VERSION(sender, env, version)\
                         axis2_http_sender_set_http_version (sender, env, version)
 
     /** Frees the soap over http sender. */

Modified: webservices/axis2/trunk/c/include/axis2_http_simple_response.h
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/c/include/axis2_http_simple_response.h?rev=678680&r1=678679&r2=678680&view=diff
==============================================================================
--- webservices/axis2/trunk/c/include/axis2_http_simple_response.h (original)
+++ webservices/axis2/trunk/c/include/axis2_http_simple_response.h Tue Jul 22 01:43:36 2008
@@ -298,6 +298,26 @@
     axis2_http_simple_response_create_default(
         const axutil_env_t * env);
 
+    AXIS2_EXTERN axutil_array_list_t *AXIS2_CALL
+    axis2_http_simple_response_get_mime_parts(
+        axis2_http_simple_response_t * simple_response,
+        const axutil_env_t * env);
+
+    AXIS2_EXTERN void AXIS2_CALL
+    axis2_http_simple_response_set_mime_parts(
+        axis2_http_simple_response_t * simple_response,
+        const axutil_env_t * env,
+        axutil_array_list_t *mime_parts);
+
+    axis2_status_t AXIS2_CALL
+    axis2_http_simple_response_set_http_version(
+        axis2_http_simple_response_t * simple_response,
+        const axutil_env_t * env,
+        axis2_char_t *http_version);
+
+
+
+
     /** @} */
 #ifdef __cplusplus
 }

Modified: webservices/axis2/trunk/c/include/axis2_http_status_line.h
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/c/include/axis2_http_status_line.h?rev=678680&r1=678679&r2=678680&view=diff
==============================================================================
--- webservices/axis2/trunk/c/include/axis2_http_status_line.h (original)
+++ webservices/axis2/trunk/c/include/axis2_http_status_line.h Tue Jul 22 01:43:36 2008
@@ -110,6 +110,14 @@
         const axutil_env_t * env,
         const axis2_char_t * str);
 
+    AXIS2_EXTERN void AXIS2_CALL
+    axis2_http_status_line_set_http_version(
+        axis2_http_status_line_t * status_line,
+        const axutil_env_t * env,
+        axis2_char_t *http_version);
+
+
+
     /** @} */
 #ifdef __cplusplus
 }