-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi,

I have implemented the new axis2_stream as well as I have modified the
existing stream abstraction. Pls apply the pathches, review the code
and commit.

- - Sahan
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (GNU/Linux)
Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org

iQEVAwUBQ8Hb8qnIlEsDdb85AQKMgQf/Q8Np9b3ylMKStwPW1TbK9Pd0oDm6sx8l
DOJ8bnhTBPDZe/90nJl1QSmu6kdxRC1BkdM34fOs+xBQxfMAIQbvHxy+9Jg4Velj
FeHg/DQqvhIfeqSPC4LIHN+QEjANtb6L6U+SQHICu0OzDA2deP5iNpFni8/jLEKA
/ALXg9q3+q6q7yNrkU4MYv1Fg+AbCuOjAXJzjDDDKX95Va5ikGuYYkyAm9InlaL+
nesmMRlu4eWzNECTwnX3YsKcSaxeH+dwJ1N3ch4uBqMApXzTDeDyrwZIhfxE2syN
dMuQwE+6ryibKzV/mBFK2HtXWEsW1AXEtiBAwhvg/6C+UiUetfOv6w==
=/UMe
-----END PGP SIGNATURE-----

/*
 * Copyright 2004,2005 The Apache Software Foundation.
 *
 * Licensed 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 <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <axis2_stream.h>

/** 
 * @brief Stream struct impl
 *	Axis2 Stream impl  
 */
typedef struct axis2_stream_impl axis2_stream_impl_t;  
  
struct axis2_stream_impl
{
	axis2_stream_t stream;
	axis2_stream_type_t stream_type;
	int len;
	int max_len;
	/* Only one of these is used for a perticlar
	 * instance depending on the type
	 */
	axis2_char_t *buffer;
	FILE *fp;
	int socket;	
};

#define AXIS2_INTF_TO_IMPL(stream) ((axis2_stream_impl_t *)(stream))

/********************************Function headers******************************/
axis2_status_t AXIS2_CALL 
axis2_stream_free (axis2_stream_t *stream, axis2_env_t **env);

/** basic stream operatons **/
int AXIS2_CALL
axis2_stream_write_basic(axis2_stream_t *stream, axis2_env_t **env, 
						const void *buffer, size_t count);
int AXIS2_CALL 
axis2_stream_read_basic (axis2_stream_t *stream, axis2_env_t **env, 
						void *buffer, size_t count);
int AXIS2_CALL 
axis2_stream_get_len_basic (axis2_stream_t *stream, axis2_env_t **env);

int AXIS2_CALL 
axis2_stream_skip_basic (axis2_stream_t *stream, axis2_env_t **env, int count);

int AXIS2_CALL 
axis2_stream_get_char_basic (axis2_stream_t *stream, axis2_env_t **env);

int AXIS2_CALL 
axis2_stream_unget_char_basic (axis2_stream_t *stream, axis2_env_t **env, 
						int ch);

/** file stream operations **/
int AXIS2_CALL
axis2_stream_write_file(axis2_stream_t *stream, axis2_env_t **env, 
						const void *buffer, size_t count);
int AXIS2_CALL 
axis2_stream_read_file (axis2_stream_t *stream, axis2_env_t **env, 
						void *buffer, size_t count);
int AXIS2_CALL 
axis2_stream_get_len_file (axis2_stream_t *stream, axis2_env_t **env);

int AXIS2_CALL 
axis2_stream_skip_file (axis2_stream_t *stream, axis2_env_t **env, int count);

int AXIS2_CALL 
axis2_stream_get_char_file (axis2_stream_t *stream, axis2_env_t **env);

int AXIS2_CALL 
axis2_stream_unget_char_file (axis2_stream_t *stream, axis2_env_t **env, 
						int ch);
/** socket stream operations **/
int AXIS2_CALL
axis2_stream_write_socket(axis2_stream_t *stream, axis2_env_t **env, 
						const void *buffer, size_t count);
int AXIS2_CALL 
axis2_stream_read_socket (axis2_stream_t *stream, axis2_env_t **env, 
						void *buffer, size_t count);
int AXIS2_CALL 
axis2_stream_get_len_socket (axis2_stream_t *stream, axis2_env_t **env);

int AXIS2_CALL 
axis2_stream_skip_socket (axis2_stream_t *stream, axis2_env_t **env, int count);

int AXIS2_CALL 
axis2_stream_get_char_socket (axis2_stream_t *stream, axis2_env_t **env);

int AXIS2_CALL 
axis2_stream_unget_char_socket (axis2_stream_t *stream, axis2_env_t **env, 
							int ch);
/************************* End of function headers ****************************/
/*
 * Internal function. Not exposed to outside
 */
AXIS2_DECLARE(axis2_stream_t *)
axis2_stream_create_internal (axis2_env_t **env)
{
	AXIS2_ENV_CHECK(env, NULL);
    	
	axis2_stream_impl_t *stream_impl = (axis2_stream_impl_t *)AXIS2_MALLOC(
						(*env)->allocator, sizeof(axis2_stream_impl_t));
	
	if(NULL == stream_impl)
	{
		AXIS2_ERROR_SET((*env)->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        return NULL;
	}
	stream_impl->buffer = NULL;
	stream_impl->fp = NULL;	
	stream_impl->socket = -1;
	stream_impl->stream.ops = (axis2_stream_ops_t *) AXIS2_MALLOC (
						(*env)->allocator, sizeof (axis2_stream_ops_t));
	if (NULL == stream_impl->stream.ops)
	{
		axis2_stream_free(&(stream_impl->stream), env);
		AXIS2_ERROR_SET((*env)->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
		return NULL;
	}
    stream_impl->stream.axis2_eof = EOF;
	
	stream_impl->stream.ops->free = axis2_stream_free;
	return &(stream_impl->stream);
}


axis2_status_t AXIS2_CALL
axis2_stream_free (axis2_stream_t *stream, axis2_env_t **env)
{
    axis2_stream_impl_t *stream_impl = NULL;
	AXIS2_FUNC_PARAM_CHECK(stream, env, AXIS2_FAILURE);
	
	stream_impl = AXIS2_INTF_TO_IMPL(stream);
	
	switch (stream_impl->stream_type)
	{
		case AXIS2_STREAM_BASIC:
		{
			if(NULL != stream_impl->buffer)
			{
				AXIS2_FREE((*env)->allocator, stream_impl->buffer);
			}
			stream_impl->buffer = NULL;
			stream_impl->len = -1;
			break;
		}
		case AXIS2_STREAM_FILE:
		{
			stream_impl->fp = NULL;
			stream_impl->len = -1;
			break;
		}
		case AXIS2_STREAM_SOCKET:
		{
			if(NULL != stream_impl->fp)
			{
				fclose(stream_impl->fp);
			}
			stream_impl->socket = -1;
			stream_impl->len = -1;
			break;
		}
	}
		
	if (NULL != stream_impl->stream.ops)
    {
        AXIS2_FREE ((*env)->allocator, stream_impl->stream.ops);
    }
   	AXIS2_FREE((*env)->allocator, stream_impl);
	
    return AXIS2_SUCCESS;
}

/************************ Basic Stream Operations *****************************/
AXIS2_DECLARE(axis2_stream_t *)
axis2_stream_create_basic (axis2_env_t **env)
{
	axis2_stream_t *def_stream = NULL;
	axis2_stream_impl_t *stream_impl = NULL;
	
	AXIS2_ENV_CHECK(env, NULL);
	def_stream = axis2_stream_create_internal(env);
	if(NULL == def_stream)
	{
		/*
		 * We leave the error returned by the 
		 * axis2_stream_create_internal intact
		 */
		return NULL;
	}
	stream_impl = AXIS2_INTF_TO_IMPL(def_stream);
	stream_impl->stream_type = AXIS2_STREAM_BASIC;
	stream_impl->stream.ops->read = axis2_stream_read_basic;
	stream_impl->stream.ops->write = axis2_stream_write_basic;
	stream_impl->stream.ops->get_len = axis2_stream_get_len_basic;
	stream_impl->stream.ops->skip = axis2_stream_skip_basic;
	stream_impl->stream.ops->get_char = axis2_stream_get_char_basic;
	stream_impl->stream.ops->unget_char = axis2_stream_unget_char_basic;
	stream_impl->buffer = (axis2_char_t*)AXIS2_MALLOC((*env)->allocator, 
						AXIS2_STREAM_DEFAULT_BUF_SIZE*sizeof(axis2_char_t));
	stream_impl->len = 0;
	stream_impl->max_len = 	AXIS2_STREAM_DEFAULT_BUF_SIZE;
	
	if(NULL == stream_impl->buffer)
	{
		axis2_stream_free(def_stream, env);
		return NULL;	
	}
	return def_stream;
}


int AXIS2_CALL 
axis2_stream_read_basic (axis2_stream_t *stream, axis2_env_t **env, 
						void *buffer, size_t count)
{
    int i = 0;
	int len = 0;
	char *buf = NULL;
	
	AXIS2_FUNC_PARAM_CHECK(stream, env, AXIS2_CRTICAL_FAILURE);
	
	buf = AXIS2_INTF_TO_IMPL(stream)->buffer;
	if(NULL == buf)
	{
		return -1;
	}
    if (NULL == buffer)
	{
        return -1;
	}
	if((count - 1) > AXIS2_INTF_TO_IMPL(stream)->len)
	{
		len = AXIS2_INTF_TO_IMPL(stream)->len;
	}
	else
	{
		len = count - 1;
	}
	memcpy(buffer, buf, len);
    /*
	 * Finally we need to remove the read bytes from the stream
	 * adjust the length of the stream.
	 */
	AXIS2_INTF_TO_IMPL(stream)->len -= i;
	memmove(buf, buf + i * sizeof(axis2_char_t), 
						AXIS2_INTF_TO_IMPL(stream)->len * sizeof(axis2_char_t));
	((axis2_char_t *) buffer)[len] = '\0';
    return len;
}

int AXIS2_CALL
axis2_stream_write_basic(axis2_stream_t *stream, axis2_env_t **env, 
						const void *buffer, size_t count)
{
	axis2_stream_impl_t *stream_impl = NULL;
	int new_len = 0;
	
	AXIS2_FUNC_PARAM_CHECK(stream, env, AXIS2_CRTICAL_FAILURE);
	if (NULL == buffer)
		return -1;
	
	stream_impl = AXIS2_INTF_TO_IMPL(stream);
	new_len = stream_impl->len + count;
	if(new_len > stream_impl->max_len)
	{
		axis2_char_t *tmp = (axis2_char_t *)AXIS2_MALLOC((*env)->allocator,
						sizeof(axis2_char_t)*(new_len + 
						AXIS2_STREAM_DEFAULT_BUF_SIZE));
		if(NULL == tmp)
		{
			AXIS2_ERROR_SET((*env)->error, AXIS2_ERROR_NO_MEMORY, 
						AXIS2_FAILURE);
			return -1;
		}
		/* 
		 * pre allocation: extra AXIS2_STREAM_DEFAULT_BUF_SIZE more bytes 
		 * allocated 
		 */
		stream_impl->max_len = new_len + AXIS2_STREAM_DEFAULT_BUF_SIZE;
		memcpy(tmp, stream_impl->buffer, sizeof(axis2_char_t)*stream_impl->len);
		AXIS2_FREE((*env)->allocator, stream_impl->buffer);
		stream_impl->buffer = tmp;
	}
	memcpy(stream_impl->buffer + (stream_impl->len * sizeof(axis2_char_t)), 
						buffer, count);
	stream_impl->len += count;	
    return count;
}


int AXIS2_CALL 
axis2_stream_get_len_basic (axis2_stream_t *stream, axis2_env_t **env)
{
	AXIS2_FUNC_PARAM_CHECK(stream, env, AXIS2_CRTICAL_FAILURE);
	return AXIS2_INTF_TO_IMPL(stream)->len;
}

int AXIS2_CALL 
axis2_stream_skip_basic (axis2_stream_t *stream, axis2_env_t **env, int count)
{
	axis2_stream_impl_t *stream_impl = NULL;
	int del_len = 0;
	AXIS2_FUNC_PARAM_CHECK(stream, env, AXIS2_CRTICAL_FAILURE);
	
	stream_impl = AXIS2_INTF_TO_IMPL(stream);
	if(count > 0)
	{
		if(count <= stream_impl->len)
		{
			del_len= count;
		}
		else
		{
			del_len = stream_impl->len;
		}
		stream_impl->len -= del_len;
		memmove(stream_impl->buffer, stream_impl->buffer + 
					del_len * sizeof(axis2_char_t), 
					stream_impl->len * sizeof(axis2_char_t));
		return del_len;
	}
	return -1;
}

int AXIS2_CALL 
axis2_stream_get_char_basic (axis2_stream_t *stream, axis2_env_t **env)
{
	axis2_char_t *buf = NULL;
	int ret = -1;
	
	AXIS2_FUNC_PARAM_CHECK(stream, env, AXIS2_CRTICAL_FAILURE);
	buf = AXIS2_INTF_TO_IMPL(stream)->buffer;
	if(AXIS2_INTF_TO_IMPL(stream)->len <= 0)
	{
		return -1;
	}
	ret = buf[0];
	AXIS2_INTF_TO_IMPL(stream)->len--;
	memmove(buf, buf + sizeof(axis2_char_t), 
						AXIS2_INTF_TO_IMPL(stream)->len * sizeof(axis2_char_t));
	return ret;
}

int AXIS2_CALL 
axis2_stream_unget_char_basic (axis2_stream_t *stream, axis2_env_t **env, 
						int ch)
{
	axis2_stream_impl_t *stream_impl = NULL;
	int new_len = 0;
	axis2_char_t *tmp = NULL;
	AXIS2_FUNC_PARAM_CHECK(stream, env, AXIS2_CRTICAL_FAILURE);
	
	stream_impl = AXIS2_INTF_TO_IMPL(stream);
	new_len = stream_impl->len + 1;
	if(new_len > stream_impl->max_len)
	{
		tmp = (axis2_char_t *)AXIS2_MALLOC((*env)->allocator,
						sizeof(axis2_char_t)*(new_len + 
						AXIS2_STREAM_DEFAULT_BUF_SIZE));
		if(NULL == tmp)
		{
			AXIS2_ERROR_SET((*env)->error, AXIS2_ERROR_NO_MEMORY, 
						AXIS2_FAILURE);
			return -1;
		}
		/* 
		 * pre allocation: extra AXIS2_STREAM_DEFAULT_BUF_SIZE more bytes 
		 * allocated 
		 */
		stream_impl->max_len = new_len + AXIS2_STREAM_DEFAULT_BUF_SIZE;
		memcpy(tmp + 1, stream_impl->buffer, 
						sizeof(axis2_char_t)*stream_impl->len);
		AXIS2_FREE((*env)->allocator, stream_impl->buffer);
		stream_impl->buffer = tmp;
	}
	tmp[0] = ch;
    return ch;
}
/********************* End of Basic Stream Operations *************************/

/************************** File Stream Operations ****************************/
AXIS2_DECLARE(axis2_stream_t *)
axis2_stream_create_file (axis2_env_t **env, FILE *fp)
{
	axis2_stream_t *def_stream = NULL;
	axis2_stream_impl_t *stream_impl = NULL;
	
	AXIS2_ENV_CHECK(env, NULL);
	def_stream = axis2_stream_create_internal(env);
	if(NULL == def_stream)
	{
		/*
		 * We leave the error returned by the 
		 * axis2_stream_create_internal intact
		 */
		return NULL;
	}
	stream_impl = AXIS2_INTF_TO_IMPL(def_stream);
	stream_impl->stream_type = AXIS2_STREAM_FILE;
	stream_impl->fp = fp;
	
	stream_impl->stream.ops->read = axis2_stream_read_file;
	stream_impl->stream.ops->write = axis2_stream_write_file;
	stream_impl->stream.ops->get_len = axis2_stream_get_len_file;
	stream_impl->stream.ops->skip = axis2_stream_skip_file;
	stream_impl->stream.ops->get_char = axis2_stream_get_char_file;
	stream_impl->stream.ops->unget_char = axis2_stream_unget_char_file;
	
	return def_stream;
}


int AXIS2_CALL 
axis2_stream_read_file (axis2_stream_t *stream, axis2_env_t **env, 
						void *buffer, size_t count)
{
	FILE *fp = NULL;
	AXIS2_FUNC_PARAM_CHECK(stream, env, AXIS2_CRTICAL_FAILURE);
	
	if(NULL == AXIS2_INTF_TO_IMPL(stream)->fp)
	{
		AXIS2_ERROR_SET((*env)->error, AXIS2_ERROR_INVALID_FD, AXIS2_FAILURE);
		return -1;
	}
	fp = AXIS2_INTF_TO_IMPL(stream)->fp;
    if (NULL == buffer)
	{
        return -1;
	}
	return fread(buffer, sizeof(axis2_char_t), count, fp);	
}

int AXIS2_CALL
axis2_stream_write_file(axis2_stream_t *stream, axis2_env_t **env, 
						const void *buffer, size_t count)
{
    int len = 0;
	FILE *fp = NULL;
	
	if(NULL == AXIS2_INTF_TO_IMPL(stream)->fp)
	{
		AXIS2_ERROR_SET((*env)->error, AXIS2_ERROR_INVALID_FD, AXIS2_FAILURE);
		return -1;
	}
	fp = AXIS2_INTF_TO_IMPL(stream)->fp;
	AXIS2_FUNC_PARAM_CHECK(stream, env, AXIS2_CRTICAL_FAILURE);
	if (NULL == buffer)
		return -1;
	len = fwrite(buffer, sizeof(axis2_char_t), count, fp);
	return len;
}


int AXIS2_CALL 
axis2_stream_get_len_file (axis2_stream_t *stream, axis2_env_t **env)
{
	AXIS2_FUNC_PARAM_CHECK(stream, env, AXIS2_CRTICAL_FAILURE);
	return -1;
}

int AXIS2_CALL 
axis2_stream_skip_file (axis2_stream_t *stream, axis2_env_t **env, int count)
{
	axis2_stream_impl_t *stream_impl = NULL;
	axis2_char_t c = -1;
	int i = count;
	AXIS2_FUNC_PARAM_CHECK(stream, env, AXIS2_CRTICAL_FAILURE);
	if(NULL == AXIS2_INTF_TO_IMPL(stream)->fp)
	{
		AXIS2_ERROR_SET((*env)->error, AXIS2_ERROR_INVALID_FD, AXIS2_FAILURE);
		return -1;
	}
	while(EOF != (c = fgetc(stream_impl->fp)) && i > 0)
	{
		i--;
	}
	return count - i;
}

int AXIS2_CALL 
axis2_stream_get_char_file (axis2_stream_t *stream, axis2_env_t **env)
{
	AXIS2_FUNC_PARAM_CHECK(stream, env, AXIS2_CRTICAL_FAILURE);
	if(NULL == AXIS2_INTF_TO_IMPL(stream)->fp)
	{
		AXIS2_ERROR_SET((*env)->error, AXIS2_ERROR_INVALID_FD, AXIS2_FAILURE);
		return -1;
	}
	return fgetc(AXIS2_INTF_TO_IMPL(stream)->fp);
}

int AXIS2_CALL 
axis2_stream_unget_char_file (axis2_stream_t *stream, axis2_env_t **env, 
						int ch)
{
	AXIS2_FUNC_PARAM_CHECK(stream, env, AXIS2_CRTICAL_FAILURE);
	if(NULL == AXIS2_INTF_TO_IMPL(stream)->fp)
	{
		AXIS2_ERROR_SET((*env)->error, AXIS2_ERROR_INVALID_FD, AXIS2_FAILURE);
		return -1;
	}
	return ungetc(ch, AXIS2_INTF_TO_IMPL(stream)->fp);
}
/********************** End of File Stream Operations *************************/

/************************** Socket Stream Operations **************************/
AXIS2_DECLARE(axis2_stream_t *)
axis2_stream_create_socket (axis2_env_t **env, int socket)
{
	axis2_stream_t *def_stream = NULL;
	axis2_stream_impl_t *stream_impl = NULL;
	
	AXIS2_ENV_CHECK(env, NULL);
	def_stream = axis2_stream_create_internal(env);
	if(NULL == def_stream)
	{
		/*
		 * We leave the error returned by the 
		 * axis2_stream_create_internal intact
		 */
		return NULL;
	}
	
	stream_impl = AXIS2_INTF_TO_IMPL(def_stream);
	stream_impl->stream.ops->read = axis2_stream_read_socket;
	stream_impl->stream.ops->write = axis2_stream_write_socket;
	stream_impl->stream.ops->get_len = axis2_stream_get_len_socket;
	stream_impl->stream.ops->skip = axis2_stream_skip_socket;
	stream_impl->stream.ops->get_char = axis2_stream_get_char_socket;
	stream_impl->stream.ops->unget_char = axis2_stream_unget_char_socket;
	
	stream_impl->stream_type = AXIS2_STREAM_SOCKET;
	stream_impl->socket = socket;
	stream_impl->fp = fdopen(socket, "w+");
	if(NULL == stream_impl->fp)
	{
		axis2_stream_free(def_stream, env);
		AXIS2_ERROR_SET((*env)->error, AXIS2_ERROR_SOCKET_STREAM_CREATION, 
						AXIS2_FAILURE);
		return NULL;
	}
	
	return def_stream;
}


int AXIS2_CALL 
axis2_stream_read_socket (axis2_stream_t *stream, axis2_env_t **env, 
						void *buffer, size_t count)
{
	FILE *fp = NULL;
	
	AXIS2_FUNC_PARAM_CHECK(stream, env, AXIS2_CRTICAL_FAILURE);
	
	if(-1 == AXIS2_INTF_TO_IMPL(stream)->socket)
	{
		AXIS2_ERROR_SET((*env)->error, AXIS2_ERROR_INVALID_SOCKET, 
						AXIS2_FAILURE);
		return -1;
	}
	fp = AXIS2_INTF_TO_IMPL(stream)->fp;
	if(NULL == fp)
	{
		AXIS2_ERROR_SET((*env)->error, AXIS2_ERROR_INVALID_FD, AXIS2_FAILURE);
		return -1;
	}
    if (NULL == buffer)
	{
        return -1;
	}
	return fread(buffer, sizeof(axis2_char_t), count, fp);	
}

int AXIS2_CALL
axis2_stream_write_socket(axis2_stream_t *stream, axis2_env_t **env, 
						const void *buffer, size_t count)
{
    int len = 0;
	FILE *fp = NULL;
			
	AXIS2_FUNC_PARAM_CHECK(stream, env, AXIS2_CRTICAL_FAILURE);
	
	if(-1 == AXIS2_INTF_TO_IMPL(stream)->socket)
	{
		AXIS2_ERROR_SET((*env)->error, AXIS2_ERROR_INVALID_SOCKET, 
						AXIS2_FAILURE);
		return -1;
	}
	if(NULL == AXIS2_INTF_TO_IMPL(stream)->fp)
	{
		AXIS2_ERROR_SET((*env)->error, AXIS2_ERROR_INVALID_FD, AXIS2_FAILURE);
		return -1;
	}
	fp = AXIS2_INTF_TO_IMPL(stream)->fp;
	if (NULL == buffer)
		return -1;
	len = fwrite(buffer, sizeof(axis2_char_t), count, fp);
	return len;
}


int AXIS2_CALL 
axis2_stream_get_len_socket (axis2_stream_t *stream, axis2_env_t **env)
{
	AXIS2_FUNC_PARAM_CHECK(stream, env, AXIS2_CRTICAL_FAILURE);
	return -1;
}

int AXIS2_CALL 
axis2_stream_skip_socket (axis2_stream_t *stream, axis2_env_t **env, int count)
{
	axis2_stream_impl_t *stream_impl = NULL;
	axis2_char_t c = -1;
	int i = count;
	AXIS2_FUNC_PARAM_CHECK(stream, env, AXIS2_CRTICAL_FAILURE);
	
	if(-1 == AXIS2_INTF_TO_IMPL(stream)->socket)
	{
		AXIS2_ERROR_SET((*env)->error, AXIS2_ERROR_INVALID_SOCKET, 
						AXIS2_FAILURE);
		return -1;
	}
	while(EOF != (c = fgetc(stream_impl->fp)) && i > 0)
	{
		i--;
	}
	return count - i;
}

int AXIS2_CALL 
axis2_stream_get_char_socket (axis2_stream_t *stream, axis2_env_t **env)
{
	AXIS2_FUNC_PARAM_CHECK(stream, env, AXIS2_CRTICAL_FAILURE);
	if(-1 == AXIS2_INTF_TO_IMPL(stream)->socket)
	{
		AXIS2_ERROR_SET((*env)->error, AXIS2_ERROR_INVALID_SOCKET, 
						AXIS2_FAILURE);
		return -1;
	}
	if(NULL == AXIS2_INTF_TO_IMPL(stream)->fp)
	{
		AXIS2_ERROR_SET((*env)->error, AXIS2_ERROR_INVALID_FD, AXIS2_FAILURE);
		return -1;
	}
	return fgetc(AXIS2_INTF_TO_IMPL(stream)->fp);
}

int AXIS2_CALL 
axis2_stream_unget_char_socket (axis2_stream_t *stream, axis2_env_t **env, 
						int ch)
{
	AXIS2_FUNC_PARAM_CHECK(stream, env, AXIS2_CRTICAL_FAILURE);
	if(-1 == AXIS2_INTF_TO_IMPL(stream)->socket)
	{
		AXIS2_ERROR_SET((*env)->error, AXIS2_ERROR_INVALID_SOCKET, 
						AXIS2_FAILURE);
		return -1;
	}
	if(NULL == AXIS2_INTF_TO_IMPL(stream)->fp)
	{
		AXIS2_ERROR_SET((*env)->error, AXIS2_ERROR_INVALID_FD, AXIS2_FAILURE);
		return -1;
	}
	return ungetc(ch, AXIS2_INTF_TO_IMPL(stream)->fp);
}
/********************** End of Socket Stream Operations ***********************/
Index: axis2_stream.h
===================================================================
--- axis2_stream.h      (revision 359972)
+++ axis2_stream.h      (working copy)
@@ -17,116 +17,152 @@
 #ifndef AXIS2_STREAM_H
 #define AXIS2_STREAM_H
 
-#include <axis2_allocator.h>
+#include <axis2.h>
+#include <axis2_defines.h>
+#include <axis2_env.h>
+#include <stdio.h>
 
 #ifdef __cplusplus
 extern "C"
 {
 #endif
 
-    struct axis2_stream;
-    struct axis2_stream_ops;
+typedef struct axis2_stream axis2_stream_t;
+typedef struct axis2_stream_ops axis2_stream_ops_t;
+typedef enum axis2_stream_type axis2_stream_type_t;
 
+#define AXIS2_STREAM_DEFAULT_BUF_SIZE 512
 /**
  * @defgroup axis2_stream Stream
  * @ingroup axis2_util 
  * @{
  */
 
-  /** 
-    * \brief Axis2 stream ops struct
-    *
-    * Encapsulator struct for ops of axis2_stream
-    */
-  AXIS2_DECLARE_DATA  typedef struct axis2_stream_ops
-    {
+/**
+* \brief Axis2 stream types
+*
+* This is used to create a stream to correspond to 
+* perticular i/o mtd
+*/
+enum axis2_stream_type 
+{
+       AXIS2_STREAM_BASIC = 0,
+       AXIS2_STREAM_FILE,
+       AXIS2_STREAM_SOCKET
+};
 
-      /**
-       * deletes the stream
-       * @return axis2_status_t AXIS2_SUCCESS on success else AXIS2_FAILURE
-       */
 
-       axis2_status_t (AXIS2_CALL *free) (struct axis2_stream *stream);
-       
-      /**
-        * reads from stream
-        * @param buffer buffer into which the content is to be read
-        * @param size size of the buffer
-        * @return satus of the op. AXIS2_SUCCESS on success else AXIS2_FAILURE
-        */
-        axis2_status_t (AXIS2_CALL *read) (void *buffer
-                       , size_t count);
-               /**
-        * writes into stream
-        * @param buffer buffer to be written
-        * @param size size of the buffer
-        * @return satus of the op. AXIS2_SUCCESS on success else AXIS2_FAILURE
-        */
-        axis2_status_t (AXIS2_CALL *write) 
-                       (const void *buffer, size_t count);
-               
-               /**
-                * open a file for read according to the file options given
-                * @param file_name file to be opened
-                * @param options file options given.
-                * @return status code
-                */ 
-               void * (AXIS2_CALL  *file_open)
-                       (const char *file_name, const char *options);
-               
-               /**
-                * close a file
-                * @param file_ptr file pointer of the file need to be closed
-                * @return status code
-                */
-               axis2_status_t (AXIS2_CALL *file_close) 
-                               (void *file_ptr);
-               
-               /** reads a once character from a file
-                * @param file_ptr pointer to the file to be read from
-                * @return char read
-                */
-               axis2_char_t (AXIS2_CALL *file_get_char) 
-                               (void *file_ptr);
-               
-               /** write a previously read character back to the file stream
-                * @param chr charater to write back
-                * @param file_ptr file pointer from which chr is read 
previously
-                *        and need to be written back to
-                * @return status code
-                */
-               axis2_status_t (AXIS2_CALL *file_unget_char) 
-                               (const char chr, void *file_ptr);
-                               
-    } axis2_stream_ops_t;
+/** 
+* \brief Axis2 stream ops struct
+*
+* Encapsulator struct for ops of axis2_stream
+*/
+AXIS2_DECLARE_DATA struct axis2_stream_ops
+{
 
-  /** 
-    * \brief Axis2 Stream struct
-    *
-    * Stream is the encapsulating struct for all stream related ops
-    */
-    typedef struct axis2_stream
-    {
-        /** Stream related ops */
-        struct axis2_stream_ops *ops;
-               int axis2_eof;
-    } axis2_stream_t;
+       /**
+        * Deletes the stream
+        * @return axis2_status_t AXIS2_SUCCESS on success else AXIS2_FAILURE
+        */
+       axis2_status_t (AXIS2_CALL *free)(axis2_stream_t *stream, axis2_env_t 
**env);
+   
+       /**
+        * reads from stream
+        * @param buffer buffer into which the content is to be read
+        * @param count size of the buffer
+        * @return so: of bytes read
+        */
+   
+       int (AXIS2_CALL *read) (axis2_stream_t *stream, axis2_env_t **env, 
+                                               void *buffer, size_t count);
+       /**
+        * writes into stream
+        * @param buffer buffer to be written
+        * @param count size of the buffer
+        * @return no: of bytes actually written
+        */
+       int (AXIS2_CALL *write) (axis2_stream_t *stream, 
+                                               axis2_env_t **env, const void 
*buffer, size_t count);
+       /**
+        * Skips over and discards n bytes of data from this input stream.
+        * @param count number of bytes to be discarded
+        * @return no: of bytes actually skipped
+        */
+       int (AXIS2_CALL *skip) (axis2_stream_t *stream, axis2_env_t **env, 
+                                               int count);
+                                               
+       /**
+        * Reads  the next character from stream and returns it as an unsigned 
char 
+        * cast to an int, or EOF on end of file or error.
+        * @return next character in the stream
+        */
+       int (AXIS2_CALL *get_char) (axis2_stream_t *stream, axis2_env_t **env);
+       
+       /**
+        * Pushes a character back to stream, cast to unsigned char, where it 
is 
+        * available for subsequent read operations
+        * @param charachter to be pushed
+        * @return the pushed character or EOF if an error
+        */
+       int (AXIS2_CALL *unget_char) (axis2_stream_t *stream, axis2_env_t 
**env, 
+                                               int ch);
 
-#define AXIS2_STREAM_FREE(stream) ((stream->ops)->free(stream))
+       /**
+        * Returns the length of the stream (applicable only to basic stream)
+        * @return Length of the buffer if its type is basic, else -1
+        * (we can't define a length of a stream unless it is just a buffer)
+        */
+       int (AXIS2_CALL *get_len) (axis2_stream_t *stream, axis2_env_t **env);
+       
+};
 
-#define AXIS2_STREAM_READ(stream, buffer, count) \
-               ((stream)->ops->read(buffer, count))
-#define AXIS2_STREAM_WRITE(stream, buffer, count) \
-               ((stream->ops)->write(buffer, count))
-#define AXIS2_STREAM_FILE_OPEN(stream, file_name, options) \
-               ((stream->ops)->file_open(file_name, options))
-#define AXIS2_STREAM_FILE_CLOSE(stream, file_ptr) \
-               ((stream->ops)->file_close(file_ptr))
-#define AXIS2_STREAM_FILE_GET_CHAR(stream, file_ptr) \
-               ((stream->ops)->file_get_char(file_ptr))
-#define AXIS2_STREAM_FILE_UNGET_CHAR(stream, chr, file_ptr) \
-               ((stream->ops)->file_unget_char(chr, file_ptr)) 
+/** 
+* \brief Axis2 Stream struct
+*
+* Stream is the encapsulating struct for all stream related ops
+*/
+AXIS2_DECLARE_DATA struct axis2_stream
+{
+       /** Stream related ops */
+       axis2_stream_ops_t *ops;
+    /** Stream End of File */
+    int axis2_eof;
+};
 
+/** \brief Constructor for creating an in memory stream
+  * @return axis2_stream (in memory)
+  */
+AXIS2_DECLARE(axis2_stream_t *) axis2_stream_create_basic (axis2_env_t **env);
+
+/** \brief Constructor for creating a file stream
+  * @param valid file pointer (opened file)
+  * @return axis2_stream (file)
+  */
+AXIS2_DECLARE(axis2_stream_t *)
+axis2_stream_create_file (axis2_env_t **env, FILE *fp);
+
+/** \brief Constructor for creating a file stream
+  * @param valid socket (opened socket)
+  * @return axis2_stream (socket)
+  */
+AXIS2_DECLARE(axis2_stream_t *)
+axis2_stream_create_socket (axis2_env_t **env, int socket);
+
+#define AXIS2_STREAM_FREE(stream, env) ((stream->ops)->free(stream, env))
+#define AXIS2_STREAM_READ(stream, env, buffer, count) \
+               ((stream)->ops->read(stream, env, buffer, count))
+#define AXIS2_STREAM_WRITE(stream, env, buffer, count) \
+               ((stream)->ops->write(stream, env, buffer, count))
+#define AXIS2_STREAM_SKIP(stream, env, count) \
+               ((stream)->ops->write(stream, env, count))
+#define AXIS2_STREAM_GET_CHAR(stream, env) \
+               ((stream)->ops->get_char(stream, env))
+#define AXIS2_STREAM_UNGET_CHAR(stream, env, ch) \
+               ((stream)->ops->unget_char(stream, env, ch))
+
+#define AXIS2_STREAM_BASIC_GET_LEN(stream, env) \
+               ((stream)->ops->get_len(stream, env))
+
 /** @} */
     
 #ifdef __cplusplus

Reply via email to