Samisa Abeysinghe wrote: > Hi Sahan, > Are we using the 'platforms' concept when it comes to dealing with sockets? > In the method axis2_stream_create_socket, we really associate the soket to a file descriptor, hence I think we should not be using the term 'create' as it is misleading. As per my understanding goes, one creates the socket and associate it with our stream. Am I correct? > > Thanks, > Samisa... > Sahan Gamage wrote: >
> 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 >> >> ------------------------------------------------------------------------ >> /* * 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 >> Hmm.. the name seems to be misleading. What is actually happenning is as you've said, associating a socket. So what about axis2_stream_create_with_socket and axis2_stream_create_with_file and keeping the axis2_stream_create_basic (since it actually creates a buffer). Also I will be introducing the platforms concept for sockets. So there will be a axis2_network_handler.h (abstraction) and different (platform specific) implementations. - Sahan
