From 0425aadc78680e53000fd0108b540d6eca048516 Mon Sep 17 00:00:00 2001 From: gmcdonald Date: Sat, 13 Feb 2010 01:32:03 +0000 Subject: Moving axis svn, part of TLP move INFRA-2441 git-svn-id: http://svn.apache.org/repos/asf/axis/axis2/c/core/trunk@909681 13f79535-47bb-0310-9956-ffa450edef68 --- util/src/stream.c | 719 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 719 insertions(+) create mode 100644 util/src/stream.c (limited to 'util/src/stream.c') diff --git a/util/src/stream.c b/util/src/stream.c new file mode 100644 index 0000000..1034a03 --- /dev/null +++ b/util/src/stream.c @@ -0,0 +1,719 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include + +/** basic stream operatons **/ +int AXIS2_CALL axutil_stream_write_basic( + axutil_stream_t *stream, + const axutil_env_t *env, + const void *buffer, + size_t count); + +int AXIS2_CALL axutil_stream_read_basic( + axutil_stream_t *stream, + const axutil_env_t *env, + void *buffer, + size_t count); + +int AXIS2_CALL axutil_stream_skip_basic( + axutil_stream_t *stream, + const axutil_env_t *env, + int count); + +/** file stream operations **/ +int AXIS2_CALL axutil_stream_write_file( + axutil_stream_t *stream, + const axutil_env_t *env, + const void *buffer, + size_t count); + +int AXIS2_CALL axutil_stream_read_file( + axutil_stream_t *stream, + const axutil_env_t *env, + void *buffer, + size_t count); + +int AXIS2_CALL axutil_stream_skip_file( + axutil_stream_t *stream, + const axutil_env_t *env, + int count); + +/** socket stream operations **/ +int AXIS2_CALL axutil_stream_write_socket( + axutil_stream_t *stream, + const axutil_env_t *env, + const void *buffer, + size_t count); + +int AXIS2_CALL axutil_stream_read_socket( + axutil_stream_t *stream, + const axutil_env_t *env, + void *buffer, + size_t count); + +int AXIS2_CALL axutil_stream_skip_socket( + axutil_stream_t *stream, + const axutil_env_t *env, + int count); + +AXIS2_EXTERN axutil_stream_t *AXIS2_CALL +axutil_stream_create_internal( + const axutil_env_t *env) +{ + axutil_stream_t *stream = NULL; + stream = (axutil_stream_t *)AXIS2_MALLOC(env->allocator, sizeof(axutil_stream_t)); + if(!stream) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Out of memory. Cannot create axutil stream"); + return NULL; + } + stream->buffer = NULL; + stream->buffer_head = NULL; + stream->fp = NULL; + stream->socket = -1; + stream->len = -1; + stream->max_len = -1; + stream->axis2_eof = EOF; + + return stream; +} + +void AXIS2_CALL +axutil_stream_free( + axutil_stream_t *stream, + const axutil_env_t *env) +{ + switch(stream->stream_type) + { + case AXIS2_STREAM_BASIC: + { + if(stream->buffer_head) + { + AXIS2_FREE(env->allocator, stream->buffer_head); + } + stream->buffer = NULL; + stream->len = -1; + break; + } + case AXIS2_STREAM_FILE: + { + stream->fp = NULL; + stream->len = -1; + break; + } + case AXIS2_STREAM_SOCKET: + { + if(stream->fp) + { + fclose(stream->fp); + } + stream->socket = -1; + stream->len = -1; + break; + } + default: + break; + } + + AXIS2_FREE(env->allocator, stream); +} + +void AXIS2_CALL +axutil_stream_free_void_arg( + void *stream, + const axutil_env_t *env) +{ + axutil_stream_t *stream_l = NULL; + + stream_l = (axutil_stream_t *)stream; + axutil_stream_free(stream_l, env); + return; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_stream_flush( + axutil_stream_t *stream, + const axutil_env_t *env) +{ + if(stream->fp) + { + if(fflush(stream->fp)) + { + return AXIS2_FAILURE; + } + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_stream_close( + axutil_stream_t *stream, + const axutil_env_t *env) +{ + switch(stream->stream_type) + { + case AXIS2_STREAM_BASIC: + { + if(stream->buffer_head) + { + AXIS2_FREE(env->allocator, stream->buffer_head); + } + stream->buffer = NULL; + stream->len = -1; + break; + } + case AXIS2_STREAM_FILE: + { + if(stream->fp) + { + if(fclose(stream->fp)) + { + return AXIS2_FAILURE; + } + } + stream->fp = NULL; + stream->len = -1; + break; + } + case AXIS2_STREAM_SOCKET: + { + if(stream->fp) + { + if(fclose(stream->fp)) + { + return AXIS2_FAILURE; + } + } + stream->socket = -1; + stream->len = -1; + break; + } + default: + break; + } + + return AXIS2_SUCCESS; +} + +/************************ Basic Stream Operations *****************************/ +AXIS2_EXTERN axutil_stream_t *AXIS2_CALL +axutil_stream_create_basic( + const axutil_env_t *env) +{ + axutil_stream_t *stream = NULL; + + AXIS2_ENV_CHECK(env, NULL); + stream = axutil_stream_create_internal(env); + if(!stream) + { + /* + * We leave the error returned by the + * axutil_stream_create_internal intact + */ + return NULL; + } + stream->stream_type = AXIS2_STREAM_BASIC; + stream->read = axutil_stream_read_basic; + stream->write = axutil_stream_write_basic; + stream->skip = axutil_stream_skip_basic; + stream->buffer = (axis2_char_t *)AXIS2_MALLOC(env->allocator, AXIS2_STREAM_DEFAULT_BUF_SIZE + * sizeof(axis2_char_t)); + stream->buffer_head = stream->buffer; + stream->len = 0; + stream->max_len = AXIS2_STREAM_DEFAULT_BUF_SIZE; + + if(!stream->buffer) + { + axutil_stream_free(stream, env); + return NULL; + } + return stream; +} + +int AXIS2_CALL +axutil_stream_read_basic( + axutil_stream_t *stream, + const axutil_env_t *env, + void *buffer, + size_t count) +{ + int len = 0; + char *buf = NULL; + + buf = stream->buffer; + if(!buf) + { + return -1; + } + if(!buffer) + { + return -1; + } + if((int)(count - 1) > stream->len) + /* We are sure that the difference lies within the int range */ + { + len = stream->len; + } + else + { + len = (int)(count - 1); + /* We are sure that the difference lies within the int range */ + } + memcpy(buffer, buf, len); + /* + * Finally we need to remove the read bytes from the stream + * adjust the length of the stream. + */ + stream->len -= len; + stream->buffer = buf + len; + ((axis2_char_t *)buffer)[len] = '\0'; + return len; +} + +int AXIS2_CALL +axutil_stream_write_basic( + axutil_stream_t *stream, + const axutil_env_t *env, + const void *buffer, + size_t count) +{ + int new_len = 0; + + if(!buffer) + return -1; + + new_len = (int)(stream->len + count); + /* We are sure that the difference lies within the int range */ + if(new_len > stream->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(!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->max_len = new_len + AXIS2_STREAM_DEFAULT_BUF_SIZE; + memcpy(tmp, stream->buffer, sizeof(axis2_char_t) * stream->len); + AXIS2_FREE(env->allocator, stream->buffer_head); + stream->buffer = tmp; + stream->buffer_head = tmp; + } + memcpy(stream->buffer + (stream->len * sizeof(axis2_char_t)), buffer, count); + stream->len += (int)count; + /* We are sure that the difference lies within the int range */ + return (int)count; +} + +int AXIS2_CALL +axutil_stream_get_len( + axutil_stream_t *stream, + const axutil_env_t *env) +{ + return stream->len; +} + +int AXIS2_CALL +axutil_stream_skip_basic( + axutil_stream_t *stream, + const axutil_env_t *env, + int count) +{ + int del_len = 0; + + if(count > 0) + { + if(count <= stream->len) + { + del_len = count; + } + else + { + del_len = stream->len; + } + stream->len -= del_len; + stream->buffer += del_len; + return del_len; + } + return -1; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axutil_stream_get_buffer( + const axutil_stream_t *stream, + const axutil_env_t *env) +{ + return stream->buffer; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_stream_flush_buffer( + axutil_stream_t *stream, + const axutil_env_t *env) +{ + stream->len = 0; + return AXIS2_SUCCESS; +} + +/********************* End of Basic Stream Operations *************************/ + +/************************** File Stream Operations ****************************/ +AXIS2_EXTERN axutil_stream_t *AXIS2_CALL +axutil_stream_create_file( + const axutil_env_t *env, + FILE * fp) +{ + axutil_stream_t *stream = NULL; + + AXIS2_ENV_CHECK(env, NULL); + stream = axutil_stream_create_internal(env); + if(!stream) + { + /* + * We leave the error returned by the + * axutil_stream_create_internal intact + */ + return NULL; + } + stream->stream_type = AXIS2_STREAM_FILE; + stream->fp = fp; + + stream->read = axutil_stream_read_file; + stream->write = axutil_stream_write_file; + stream->skip = axutil_stream_skip_file; + + return stream; +} + +int AXIS2_CALL +axutil_stream_read_file( + axutil_stream_t *stream, + const axutil_env_t *env, + void *buffer, + size_t count) +{ + FILE *fp = NULL; + + if(!stream->fp) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_FD, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Trying to do operation on invalid file descriptor"); + + return -1; + } + fp = stream->fp; + if(!buffer) + { + return -1; + } + return (int)fread(buffer, sizeof(axis2_char_t), count, fp); + /* We are sure that the difference lies within the int range */ +} + +int AXIS2_CALL +axutil_stream_write_file( + axutil_stream_t *stream, + const axutil_env_t *env, + const void *buffer, + size_t count) +{ + int len = 0; + FILE *fp = NULL; + + if(!(stream->fp)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_FD, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Trying to do operation on invalid file descriptor"); + + return -1; + } + fp = stream->fp; + if(!buffer) + return -1; + len = (int)fwrite(buffer, sizeof(axis2_char_t), count, fp); + /* We are sure that the difference lies within the int range */ + return len; +} + +int AXIS2_CALL +axutil_stream_skip_file( + axutil_stream_t *stream, + const axutil_env_t *env, + int count) +{ + int c = -1; + int i = count; + if(!(stream->fp)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_FD, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Trying to do operation on invalid file descriptor"); + return -1; + } + while(EOF != (c = fgetc(stream->fp)) && i > 0) + { + i--; + } + return count - i; +} + +/********************** End of File Stream Operations *************************/ + +/************************** Socket Stream Operations **************************/ +AXIS2_EXTERN axutil_stream_t *AXIS2_CALL +axutil_stream_create_socket( + const axutil_env_t *env, + int socket) +{ + axutil_stream_t *stream = NULL; + stream = axutil_stream_create_internal(env); + if(!stream) + { + /* + * We leave the error returned by the + * axutil_stream_create_internal intact + */ + return NULL; + } + + stream->read = axutil_stream_read_socket; + stream->write = axutil_stream_write_socket; + stream->skip = axutil_stream_skip_socket; + stream->stream_type = AXIS2_STREAM_SOCKET; + stream->socket = socket; + stream->fp = NULL; + + return stream; +} + +int AXIS2_CALL +axutil_stream_read_socket( + axutil_stream_t *stream, + const axutil_env_t *env, + void *buffer, + size_t count) +{ + int len = 0; + + if(-1 == stream->socket) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_SOCKET, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Trying to do operation on closed/not-opened socket"); + return -1; + } + if(!buffer) + { + return -1; + } + + len = (int)recv(stream->socket, buffer, (int)count, 0); + /* We are sure that the difference lies within the int range */ +#ifdef AXIS2_TCPMON + if (len > 1) + { + axis2_char_t *temp = NULL; + temp = (axis2_char_t *) AXIS2_MALLOC(env->allocator, (len + 1) * sizeof(axis2_char_t)); + if (temp) + { + memcpy(temp, buffer, len * sizeof(axis2_char_t)); + temp[len] = '\0'; + fprintf(stderr, "%s", temp); + AXIS2_FREE(env->allocator, temp); + } + } +#endif + return len; +} + +int AXIS2_CALL +axutil_stream_write_socket( + axutil_stream_t *stream, + const axutil_env_t *env, + const void *buffer, + size_t count) +{ + int len = 0; +#ifdef AXIS2_TCPMON + axis2_char_t *temp = NULL; +#endif + + if(-1 == stream->socket) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_SOCKET, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Trying to do operation on closed/not-opened socket"); + return -1; + } + if(!buffer) + return -1; + len = (int)send(stream->socket, buffer, (int)count, 0); + /* We are sure that the difference lies within the int range */ +#ifdef AXIS2_TCPMON + if (len > 0) + { + temp = + (axis2_char_t *) AXIS2_MALLOC(env->allocator, + (len + 1) * sizeof(axis2_char_t)); + if (temp) + { + memcpy(temp, buffer, len * sizeof(axis2_char_t)); + temp[len] = '\0'; + fprintf(stderr, "%s", temp); + AXIS2_FREE(env->allocator, temp); + } + } +#endif + return len; + +} + +int AXIS2_CALL +axutil_stream_skip_socket( + axutil_stream_t *stream, + const axutil_env_t *env, + int count) +{ + int len = 0; + int received = 0; + char buffer[2]; + + if(-1 == stream->socket) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_SOCKET, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Trying to do operation on closed/not-opened socket"); + return -1; + } + while(len < count) + { + received = recv(stream->socket, buffer, 1, 0); + if(received == 0) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOCKET_ERROR, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Socket has being shutdown"); + return -1; + } + if(received < 0) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SOCKET_ERROR, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Error while trying to read the socke"); + return -1; + } + len += received; + } + return len; +} + +AXIS2_EXTERN int AXIS2_CALL +axutil_stream_peek_socket( + axutil_stream_t *stream, + const axutil_env_t *env, + void *buffer, + size_t count) +{ + int len = 0; + + /* Added to prevent a segfault */ + AXIS2_PARAM_CHECK(env->error, stream, -1); + + if(-1 == stream->socket) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_SOCKET, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "Trying to do operation on closed/not-opened socket"); + return -1; + } + if(!buffer) + { + return -1; + } + + len = (int)recv(stream->socket, buffer, (int)count, MSG_PEEK); + /* We are sure that the difference lies within the int range */ + + return len; +} + +/********************** End of Socket Stream Operations ***********************/ + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_stream_set_read( + axutil_stream_t *stream, + const axutil_env_t *env, + AXUTIL_STREAM_READ func) +{ + stream->read = func; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_stream_set_write( + axutil_stream_t *stream, + const axutil_env_t *env, + AXUTIL_STREAM_WRITE func) +{ + stream->write = func; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_stream_set_skip( + axutil_stream_t *stream, + const axutil_env_t *env, + AXUTIL_STREAM_SKIP func) +{ + stream->skip = func; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN int AXIS2_CALL +axutil_stream_read( + axutil_stream_t *stream, + const axutil_env_t *env, + void *buffer, + size_t count) +{ + return stream->read(stream, env, buffer, count); +} + +AXIS2_EXTERN int AXIS2_CALL +axutil_stream_write( + axutil_stream_t *stream, + const axutil_env_t *env, + const void *buffer, + size_t count) +{ + return stream->write(stream, env, buffer, count); +} + +AXIS2_EXTERN int AXIS2_CALL +axutil_stream_skip( + axutil_stream_t *stream, + const axutil_env_t *env, + int count) +{ + return stream->skip(stream, env, count); +} -- cgit v1.1-32-gdbae