You are viewing a plain text version of this content. The canonical link for it is here.
Posted to c-dev@axis.apache.org by Sahan Gamage <sa...@wso2.com> on 2006/01/09 04:43:47 UTC
[Axis2] New stream implemetation and API
-----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-----
Re: [Axis2] New stream implemetation and API
Posted by Sahan Gamage <sa...@wso2.com>.
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
Re: [Axis2] New stream implemetation and API
Posted by Samisa Abeysinghe <sa...@wso2.com>.
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:
>-----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
>
>