
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */  
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <guththila_buffer.h>

int GUTHTHILA_CALL
guththila_buffer_init(guththila_buffer_t * buffer,int size,const axutil_env_t * env) 
{

    buffer->type = GUTHTHILA_MULTIPLE_BUFFER;
    buffer->data_size =(size_t *) AXIS2_MALLOC(env->allocator,sizeof(size_t)*GUTHTHILA_BUFFER_NUMBER_OF_BUFFERS);
    buffer->buffs_size =(size_t *) AXIS2_MALLOC(env->allocator,sizeof(size_t)*GUTHTHILA_BUFFER_NUMBER_OF_BUFFERS);
    buffer->buff =(guththila_char_t **) AXIS2_MALLOC(env->allocator,sizeof(guththila_char_t *)*GUTHTHILA_BUFFER_NUMBER_OF_BUFFERS);
    buffer->cur_buff = -1;
    buffer->pre_tot_data = 0;
    buffer->no_buffers = GUTHTHILA_BUFFER_NUMBER_OF_BUFFERS;
    buffer->xml = NULL;
	if (size > 0)
    {
        buffer->buff[0] =(guththila_char_t *) AXIS2_MALLOC(env->allocator,sizeof(guththila_char_t) * size);
        buffer->data_size[0] = 0;
        buffer->buffs_size[0] = size;
        buffer->cur_buff = 0;
    }
    return GUTHTHILA_SUCCESS;
}

int GUTHTHILA_CALL
guththila_buffer_un_init(guththila_buffer_t * buffer,const axutil_env_t * env) 
{
    int i = 0;
    
    if (buffer->type == GUTHTHILA_SINGLE_BUFFER && buffer->buff && buffer->cur_buff == 0)
    {

            
        if (buffer->buffs_size)
            AXIS2_FREE(env->allocator, buffer->buffs_size);
        if (buffer->data_size)
            AXIS2_FREE(env->allocator, buffer->data_size);
        if(buffer->xml)
            AXIS2_FREE(env->allocator,buffer->xml);

	AXIS2_FREE(env->allocator, buffer->buff);
    
    }
    else if (buffer->type == GUTHTHILA_MULTIPLE_BUFFER && buffer->buff)
    {
        for (i = 0; i <= buffer->cur_buff; i++)
        {
            AXIS2_FREE(env->allocator, buffer->buff[i]);
        }
        if(buffer->xml)
            AXIS2_FREE(env->allocator,buffer->xml);
        AXIS2_FREE(env->allocator, buffer->buff);
        if (buffer->data_size)
            AXIS2_FREE(env->allocator, buffer->data_size);
        if (buffer->buffs_size)
            AXIS2_FREE(env->allocator, buffer->buffs_size);
    }
    return GUTHTHILA_SUCCESS;
}

int GUTHTHILA_CALL
guththila_buffer_init_for_buffer(guththila_buffer_t * buffer,char *buff,int size,const axutil_env_t * env) 
{
    buffer->type = GUTHTHILA_SINGLE_BUFFER;
    buffer->buff =(char **) AXIS2_MALLOC(env->allocator,sizeof(char *) * GUTHTHILA_BUFFER_DEF_SIZE);
    buffer->buff[0] = buff;
    buffer->cur_buff = 0;
    buffer->buffs_size =(size_t *) AXIS2_MALLOC(env->allocator,sizeof(size_t) * GUTHTHILA_BUFFER_DEF_SIZE);
    buffer->buffs_size[0] = size;
    buffer->pre_tot_data = 0;
    buffer->data_size =(size_t *) AXIS2_MALLOC(env->allocator,sizeof(size_t) * GUTHTHILA_BUFFER_DEF_SIZE);
    buffer->data_size[0] = size;
    buffer->no_buffers = 1;
    buffer->xml = NULL;
    return GUTHTHILA_SUCCESS;
}

void *GUTHTHILA_CALL
guththila_buffer_get(guththila_buffer_t * buffer,const axutil_env_t * env) 
{
    size_t size = 0, current_size = 0;
    int i = 0;

    for (i = 0; i <= buffer->cur_buff; i++)
    {
        size += buffer->data_size[i];
    }
    buffer->xml = (char *) AXIS2_MALLOC(env->allocator, sizeof(char) * (size + 1));
    for (i = 0; i <= buffer->cur_buff; i++)
    {
        memcpy(buffer->xml + current_size, buffer->buff[i], buffer->data_size[i]);
        current_size += buffer->data_size[i];
    }
    
    buffer->xml[current_size] = '\0';
    return buffer->xml;
}

