| /* Copyright information is at the end of the file */ |
| |
| /*========================================================================= |
| ** XML-RPC Array Functions |
| **========================================================================= |
| */ |
| |
| #include "xmlrpc_config.h" |
| |
| #include <stddef.h> |
| #include <stdlib.h> |
| |
| #include "xmlrpc.h" |
| #include "xmlrpc_int.h" |
| |
| |
| void |
| xmlrpc_abort_if_array_bad(xmlrpc_value * const arrayP) { |
| |
| if (arrayP == NULL) |
| abort(); |
| else if (arrayP->_type != XMLRPC_TYPE_ARRAY) |
| abort(); |
| else { |
| size_t const arraySize = |
| XMLRPC_MEMBLOCK_SIZE(xmlrpc_value*, &arrayP->_block); |
| xmlrpc_value ** const contents = |
| XMLRPC_MEMBLOCK_CONTENTS(xmlrpc_value*, &arrayP->_block); |
| |
| if (contents == NULL) |
| abort(); |
| else { |
| unsigned int xmIndex; |
| |
| for (xmIndex = 0; xmIndex < arraySize; ++xmIndex) { |
| xmlrpc_value * const itemP = contents[xmIndex]; |
| if (itemP == NULL) |
| abort(); |
| else if (itemP->_refcount < 1) |
| abort(); |
| } |
| } |
| } |
| } |
| |
| |
| |
| void |
| xmlrpc_destroyArrayContents(xmlrpc_value * const arrayP) { |
| /*---------------------------------------------------------------------------- |
| Dispose of the contents of an array (but not the array value itself). |
| The value is not valid after this. |
| -----------------------------------------------------------------------------*/ |
| size_t const arraySize = |
| XMLRPC_MEMBLOCK_SIZE(xmlrpc_value*, &arrayP->_block); |
| xmlrpc_value ** const contents = |
| XMLRPC_MEMBLOCK_CONTENTS(xmlrpc_value*, &arrayP->_block); |
| |
| unsigned int xmIndex; |
| |
| XMLRPC_ASSERT_ARRAY_OK(arrayP); |
| |
| /* Release our reference to each item in the array */ |
| for (xmIndex = 0; xmIndex < arraySize; ++xmIndex) { |
| xmlrpc_value * const itemP = contents[xmIndex]; |
| xmlrpc_DECREF(itemP); |
| } |
| XMLRPC_MEMBLOCK_CLEAN(xmlrpc_value *, &arrayP->_block); |
| } |
| |
| |
| |
| int |
| xmlrpc_array_size(xmlrpc_env * const env, |
| const xmlrpc_value * const array) { |
| |
| int retval; |
| |
| /* Suppress a compiler warning about uninitialized variables. */ |
| retval = 0; |
| |
| XMLRPC_ASSERT_ENV_OK(env); |
| XMLRPC_ASSERT_VALUE_OK(array); |
| XMLRPC_TYPE_CHECK(env, array, XMLRPC_TYPE_ARRAY); |
| |
| retval = (int)XMLRPC_TYPED_MEM_BLOCK_SIZE(xmlrpc_value*, &array->_block); |
| |
| cleanup: |
| if (env->fault_occurred) |
| return -1; |
| else |
| return retval; |
| } |
| |
| |
| |
| void |
| xmlrpc_array_append_item(xmlrpc_env * const envP, |
| xmlrpc_value * const arrayP, |
| xmlrpc_value * const valueP) { |
| |
| XMLRPC_ASSERT_ENV_OK(envP); |
| XMLRPC_ASSERT_VALUE_OK(arrayP); |
| |
| if (xmlrpc_value_type(arrayP) != XMLRPC_TYPE_ARRAY) |
| xmlrpc_env_set_fault_formatted( |
| envP, XMLRPC_TYPE_ERROR, "Value is not an array"); |
| else { |
| size_t const size = |
| XMLRPC_MEMBLOCK_SIZE(xmlrpc_value *, &arrayP->_block); |
| |
| XMLRPC_MEMBLOCK_RESIZE(xmlrpc_value *, envP, &arrayP->_block, size+1); |
| |
| if (!envP->fault_occurred) { |
| xmlrpc_value ** const contents = |
| XMLRPC_MEMBLOCK_CONTENTS(xmlrpc_value*, &arrayP->_block); |
| xmlrpc_INCREF(valueP); |
| contents[size] = valueP; |
| } |
| } |
| } |
| |
| |
| |
| void |
| xmlrpc_array_read_item(xmlrpc_env * const envP, |
| const xmlrpc_value * const arrayP, |
| unsigned int const xmIndex, |
| xmlrpc_value ** const valuePP) { |
| |
| XMLRPC_ASSERT_ENV_OK(envP); |
| XMLRPC_ASSERT_VALUE_OK(arrayP); |
| XMLRPC_ASSERT_PTR_OK(valuePP); |
| |
| if (arrayP->_type != XMLRPC_TYPE_ARRAY) |
| xmlrpc_env_set_fault_formatted( |
| envP, XMLRPC_TYPE_ERROR, "Attempt to read array item from " |
| "a value that is not an array"); |
| else { |
| xmlrpc_value ** const contents = |
| XMLRPC_MEMBLOCK_CONTENTS(xmlrpc_value *, &arrayP->_block); |
| size_t const size = |
| XMLRPC_MEMBLOCK_SIZE(xmlrpc_value *, &arrayP->_block); |
| |
| if (xmIndex >= size) |
| xmlrpc_env_set_fault_formatted( |
| envP, XMLRPC_INDEX_ERROR, "Array index %u is beyond end " |
| "of %u-item array", xmIndex, (unsigned int)size); |
| else { |
| *valuePP = contents[xmIndex]; |
| xmlrpc_INCREF(*valuePP); |
| } |
| } |
| } |
| |
| |
| |
| xmlrpc_value * |
| xmlrpc_array_get_item(xmlrpc_env * const envP, |
| const xmlrpc_value * const arrayP, |
| int const xmIndex) { |
| |
| xmlrpc_value * valueP; |
| |
| if (xmIndex < 0) |
| xmlrpc_env_set_fault_formatted( |
| envP, XMLRPC_INDEX_ERROR, "Index %d is negative."); |
| else { |
| xmlrpc_array_read_item(envP, arrayP, xmIndex, &valueP); |
| |
| if (!envP->fault_occurred) |
| xmlrpc_DECREF(valueP); |
| } |
| if (envP->fault_occurred) |
| valueP = NULL; |
| |
| return valueP; |
| } |
| |
| |
| |
| /* Copyright (C) 2001 by First Peer, Inc. All rights reserved. |
| ** Copyright (C) 2001 by Eric Kidd. All rights reserved. |
| ** |
| ** Redistribution and use in source and binary forms, with or without |
| ** modification, are permitted provided that the following conditions |
| ** are met: |
| ** 1. Redistributions of source code must retain the above copyright |
| ** notice, this list of conditions and the following disclaimer. |
| ** 2. Redistributions in binary form must reproduce the above copyright |
| ** notice, this list of conditions and the following disclaimer in the |
| ** documentation and/or other materials provided with the distribution. |
| ** 3. The name of the author may not be used to endorse or promote products |
| ** derived from this software without specific prior written permission. |
| ** |
| ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND |
| ** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| ** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| ** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE |
| ** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
| ** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
| ** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
| ** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
| ** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
| ** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| ** SUCH DAMAGE. */ |