blob: 01e1268841d413a17a0130c14c2e795cd8b1e0b8 [file] [log] [blame]
/*
* 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 <axis2_defines.h>
#include <stdio.h>
#include <axis2_util.h>
#include <oxs_constants.h>
#include <oxs_buffer.h>
#include <oxs_axiom.h>
#include <oxs_error.h>
struct oxs_buffer
{
unsigned char* data; /* will be adjusted based on oxs_buffer_remove_head method */
unsigned char* original_data; /* to free the data */
int size;
int max_size;
oxs_AllocMode alloc_mode;
};
AXIS2_EXTERN oxs_buffer_t *AXIS2_CALL
oxs_buffer_create(
const axutil_env_t *env)
{
oxs_buffer_t *buffer = NULL;
buffer = (oxs_buffer_t*)AXIS2_MALLOC(env->allocator, sizeof(oxs_buffer_t));
if(!buffer)
{
AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
"[rampart]insufficient memory. oxs buffer creation failed");
return NULL;
}
buffer->data = NULL;
buffer->original_data = NULL;
buffer->size = 0;
buffer->max_size = 0;
buffer->alloc_mode = oxs_alloc_mode_double; /* increase the size exponentially */
return buffer;
}
AXIS2_EXTERN axis2_status_t AXIS2_CALL
oxs_buffer_free(
oxs_buffer_t *buffer,
const axutil_env_t *env)
{
if(buffer->original_data)
{
AXIS2_FREE(env->allocator, buffer->original_data);
}
AXIS2_FREE(env->allocator, buffer);
buffer = NULL;
return AXIS2_SUCCESS;
}
AXIS2_EXTERN axis2_status_t AXIS2_CALL
oxs_buffer_remove_head(
oxs_buffer_t *buffer,
const axutil_env_t *env,
int size)
{
if(!buffer->data)
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
"[rampart]oxs_buffer_remove_head failed. data is NULL");
return AXIS2_FAILURE;
}
/*If the size to be removed is less than the buffer size*/
if(size < buffer->size)
{
buffer->size -= size;
buffer->max_size -= size; /* since we are not freeing the head, effective max_size is less */
buffer->data += size;
}
else
{
buffer->size = 0;
buffer->data = NULL;
}
return AXIS2_SUCCESS;
}
AXIS2_EXTERN axis2_status_t AXIS2_CALL
oxs_buffer_populate(
oxs_buffer_t *buffer,
const axutil_env_t *env,
unsigned char *data,
int size)
{
if((!data) || (size <= 0))
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
"[rampart]Cannot populate data to oxs buffer. data is not valid");
return AXIS2_FAILURE;
}
oxs_buffer_set_max_size(buffer, env, size);
memcpy(buffer->data, data, size);
buffer->size = size;
buffer->data[size] = '\0';
return AXIS2_SUCCESS;
}
AXIS2_EXTERN axis2_status_t AXIS2_CALL
oxs_buffer_append(
oxs_buffer_t *buffer,
const axutil_env_t *env,
unsigned char *data,
int size)
{
if((!data) || (size <= 0))
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
"[rampart]Cannot append data to oxs buffer. data is not valid");
return AXIS2_FAILURE;
}
oxs_buffer_set_max_size(buffer, env, buffer->size + size);
memcpy(buffer->data + buffer->size, data, size);
buffer->size += size;
return AXIS2_SUCCESS;
}
AXIS2_EXTERN axis2_status_t AXIS2_CALL
oxs_buffer_read_file(
oxs_buffer_t *buffer,
const axutil_env_t *env,
const axis2_char_t *filename)
{
unsigned char fbuffer[1024];
FILE * f;
int len;
f = fopen(filename, "rb");
if(!f)
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
"[rampart]cannot open file %s. Populating oxs buffer from file failed.", filename);
return AXIS2_FAILURE;
}
while(1)
{
len = fread(fbuffer, 1, sizeof(fbuffer), f);
if(len == 0)
{
break; /*Stop reading*/
}
else if(len < 0)
{
fclose(f);
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
"[rampart]Cannot read file %s. Populating oxs buffer from file failed.", filename);
return AXIS2_FAILURE;
}
if(oxs_buffer_append(buffer, env, fbuffer, len) != AXIS2_SUCCESS)
{
fclose(f);
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
"[rampart]Cannot append data to oxs buffer. Populating buffer from %s failed.",
filename);
return AXIS2_FAILURE;
}
}/*End of while*/
fclose(f);
return AXIS2_SUCCESS;
}
AXIS2_EXTERN axis2_status_t AXIS2_CALL
oxs_buffer_set_size(
oxs_buffer_t *buffer,
const axutil_env_t *env,
int size)
{
/*First we need to make sure that the max size has a value greater or equal value*/
if(oxs_buffer_set_max_size(buffer, env, size) != AXIS2_SUCCESS)
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "[rampart] oxs_buffer_set_max_size failed");
return AXIS2_FAILURE;
}
/*Now set the size*/
buffer->size = size;
return AXIS2_SUCCESS;
}
AXIS2_EXTERN axis2_status_t AXIS2_CALL
oxs_buffer_set_max_size(
oxs_buffer_t *buffer,
const axutil_env_t *env,
int size)
{
unsigned char* new_data;
unsigned int new_size = 0;
if(size <= buffer->max_size)
{
return AXIS2_SUCCESS;
}
switch(buffer->alloc_mode)
{
case oxs_alloc_mode_exact:
new_size = size + 8;
break;
case oxs_alloc_mode_double:
new_size = 2 * size + 32;
break;
}
if(new_size < OXS_BUFFER_INITIAL_SIZE)
{
new_size = OXS_BUFFER_INITIAL_SIZE;
}
new_data = (unsigned char*)AXIS2_MALLOC(env->allocator, new_size);
if(!new_data)
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
"[rampart]cannot increase the size of oxs buffer. Insufficient memory");
return AXIS2_FAILURE;
}
if(buffer->data)
{
/* Copy existing data */
new_data = memcpy(new_data, buffer->data, buffer->size);
}
if(buffer->original_data)
{
/* we don't need the original data now. buffer->data is part of buffer->original_data.
* Since we are going to change the pointer of buffer->data, we can free original_data
*/
AXIS2_FREE(env->allocator, buffer->original_data);
}
buffer->data = new_data;
buffer->original_data = new_data;
buffer->max_size = new_size;
return AXIS2_SUCCESS;
}
AXIS2_EXTERN unsigned char* AXIS2_CALL
oxs_buffer_get_data(
oxs_buffer_t *buffer,
const axutil_env_t *env)
{
return buffer->data;
}
AXIS2_EXTERN int AXIS2_CALL
oxs_buffer_get_size(
oxs_buffer_t *buffer,
const axutil_env_t *env)
{
return buffer->size;
}
AXIS2_EXTERN int AXIS2_CALL
oxs_buffer_get_max_size(
oxs_buffer_t *buffer,
const axutil_env_t *env)
{
return buffer->max_size;
}
#if 0 /* this seemed to be not used 1.3.0*/
AXIS2_EXTERN axis2_status_t AXIS2_CALL
oxs_buffer_prepend(
oxs_buffer_t *buffer,
const axutil_env_t *env,
unsigned char *data,
int size)
{
AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
if(size > 0)
{
if(!data)
{
oxs_error(env, OXS_ERROR_LOCATION, OXS_ERROR_INVALID_DATA, "Passed data is NULL");
return AXIS2_FAILURE;
}
buffer->max_size = buffer->size + size;
memmove(buffer->data + size, buffer->data, buffer->size);
memcpy(buffer->data, data, size);
buffer->size += size;
}
return AXIS2_SUCCESS;
}
AXIS2_EXTERN oxs_buffer_t *AXIS2_CALL
oxs_buffer_dup(
oxs_buffer_t *buffer,
const axutil_env_t *env)
{
oxs_buffer_t *buf = NULL;
buf = oxs_buffer_create(env);
if(!buf)
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "[rampart]duplicating oxs buffer failed");
return NULL;
}
if(oxs_buffer_populate(buf, env, oxs_buffer_get_data(buffer, env),
oxs_buffer_get_size(buffer, env)) != AXIS2_SUCCESS)
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
"[rampart]populating buffer failed. Cannot duplicate given oxs buffer");
oxs_buffer_free(buf, env);
return NULL;
}
return buf;
}
AXIS2_EXTERN axis2_status_t AXIS2_CALL
oxs_buffer_remove_tail(
oxs_buffer_t *buffer,
const axutil_env_t *env,
int size)
{
AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
if(size < buffer->size)
{
buffer->size -= size;
}
else
{
buffer->size = 0;
}
if(buffer->size < buffer->max_size)
{
if(buffer->data)
{
oxs_error(env, OXS_ERROR_LOCATION, OXS_ERROR_INVALID_DATA, "");
return AXIS2_FAILURE;
}
memset(buffer->data + buffer->size, 0, buffer->max_size - buffer->size);
}
return AXIS2_SUCCESS;
}
#endif