diff options
Diffstat (limited to 'Utilities/cmxmlrpc/xmlrpc_struct.c')
-rw-r--r-- | Utilities/cmxmlrpc/xmlrpc_struct.c | 608 |
1 files changed, 0 insertions, 608 deletions
diff --git a/Utilities/cmxmlrpc/xmlrpc_struct.c b/Utilities/cmxmlrpc/xmlrpc_struct.c deleted file mode 100644 index 50cc6db..0000000 --- a/Utilities/cmxmlrpc/xmlrpc_struct.c +++ /dev/null @@ -1,608 +0,0 @@ -/* Copyright (C) 2001 by First Peer, Inc. 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. */ - -#include "xmlrpc_config.h" - -#include <stddef.h> -#include <stdlib.h> -#include <string.h> - -#include "xmlrpc.h" -#include "xmlrpc_int.h" - -#define KEY_ERROR_BUFFER_SZ (32) - - -void -xmlrpc_destroyStruct(xmlrpc_value * const structP) { - - _struct_member * const members = - XMLRPC_MEMBLOCK_CONTENTS(_struct_member, &structP->_block); - size_t const size = - XMLRPC_MEMBLOCK_SIZE(_struct_member, &structP->_block); - - unsigned int i; - - for (i = 0; i < size; ++i) { - xmlrpc_DECREF(members[i].key); - xmlrpc_DECREF(members[i].value); - } - XMLRPC_MEMBLOCK_CLEAN(_struct_member, &structP->_block); -} - - - -/*========================================================================= -** xmlrpc_struct_new -**========================================================================= -** Create a new <struct> value. The corresponding destructor code -** currently lives in xmlrpc_DECREF. -** -** We store the individual members in an array of _struct_member. This -** contains a key, a hash code, and a value. We look up keys by doing -** a linear search of the hash codes. -*/ - -xmlrpc_value * -xmlrpc_struct_new(xmlrpc_env* env) -{ - xmlrpc_value *strct; - int strct_valid; - - XMLRPC_ASSERT_ENV_OK(env); - - /* Set up error handling preconditions. */ - strct_valid = 0; - - /* Allocate and fill out an empty structure. */ - strct = (xmlrpc_value*) malloc(sizeof(xmlrpc_value)); - XMLRPC_FAIL_IF_NULL(strct, env, XMLRPC_INTERNAL_ERROR, - "Could not allocate memory for struct"); - strct->_refcount = 1; - strct->_type = XMLRPC_TYPE_STRUCT; - XMLRPC_MEMBLOCK_INIT(_struct_member, env, &strct->_block, 0); - XMLRPC_FAIL_IF_FAULT(env); - strct_valid = 1; - - cleanup: - if (env->fault_occurred) { - if (strct) { - if (strct_valid) - xmlrpc_DECREF(strct); - else - free(strct); - } - return NULL; - } - return strct; -} - - - -/*========================================================================= -** xmlrpc_struct_size -**========================================================================= -** Return the number of key-value pairs contained in the struct. If the -** value is not a struct, return -1 and set a fault. -*/ - -int -xmlrpc_struct_size(xmlrpc_env* env, xmlrpc_value* strct) -{ - int retval; - - /* Suppress a compiler warning about uninitialized variables. */ - retval = 0; - - XMLRPC_ASSERT_ENV_OK(env); - XMLRPC_ASSERT_VALUE_OK(strct); - - XMLRPC_TYPE_CHECK(env, strct, XMLRPC_TYPE_STRUCT); - retval = (int)XMLRPC_MEMBLOCK_SIZE(_struct_member, &strct->_block); - - cleanup: - if (env->fault_occurred) - return -1; - return retval; -} - - - -/*========================================================================= -** get_hash -**========================================================================= -** A mindlessly simple hash function. Please feel free to write something -** more clever if this produces bad results. -*/ - -static unsigned char -get_hash(const char * const key, - size_t const key_len) { - - unsigned char retval; - size_t i; - - XMLRPC_ASSERT(key != NULL); - - retval = 0; - for (i = 0; i < key_len; i++) - retval += key[i]; - return retval; -} - - - -/*========================================================================= -** find_member -**========================================================================= -** Get the index of the member with the specified key, or -1 if no such -** member exists. -*/ - -static int -find_member(xmlrpc_value * const strctP, - const char * const key, - size_t const key_len) { - - size_t size, i; - unsigned char hash; - _struct_member *contents; - xmlrpc_value *keyval; - char *keystr; - size_t keystr_size; - - XMLRPC_ASSERT_VALUE_OK(strctP); - XMLRPC_ASSERT(key != NULL); - - /* Look for our key. */ - hash = get_hash(key, key_len); - size = XMLRPC_MEMBLOCK_SIZE(_struct_member, &strctP->_block); - contents = XMLRPC_MEMBLOCK_CONTENTS(_struct_member, &strctP->_block); - for (i = 0; i < size; i++) { - if (contents[i].key_hash == hash) { - keyval = contents[i].key; - keystr = XMLRPC_MEMBLOCK_CONTENTS(char, &keyval->_block); - keystr_size = XMLRPC_MEMBLOCK_SIZE(char, &keyval->_block)-1; - if (key_len == keystr_size && memcmp(key, keystr, key_len) == 0) - return (int)i; - } - } - return -1; -} - - - -/*========================================================================= -** xmlrpc_struct_has_key -**========================================================================= -*/ - -int -xmlrpc_struct_has_key(xmlrpc_env * const envP, - xmlrpc_value * const strctP, - const char * const key) { - - XMLRPC_ASSERT(key != NULL); - return xmlrpc_struct_has_key_n(envP, strctP, key, strlen(key)); -} - - - -int -xmlrpc_struct_has_key_n(xmlrpc_env * const envP, - xmlrpc_value * const strctP, - const char * const key, - size_t const key_len) { - int xmIndex; - - /* Suppress a compiler warning about uninitialized variables. */ - xmIndex = 0; - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT_VALUE_OK(strctP); - XMLRPC_ASSERT(key != NULL); - - XMLRPC_TYPE_CHECK(envP, strctP, XMLRPC_TYPE_STRUCT); - xmIndex = find_member(strctP, key, key_len); - - cleanup: - if (envP->fault_occurred) - return 0; - return (xmIndex >= 0); -} - - - -/*========================================================================= -** xmlrpc_struct_find_value... -**========================================================================= -** These functions look up a specified key value in a specified struct. -** If it exists, they return the value of the struct member. If not, -** they return a NULL to indicate such. -*/ - -/* It would be a nice extension to be able to look up a key that is - not a text string. -*/ - -void -xmlrpc_struct_find_value(xmlrpc_env * const envP, - xmlrpc_value * const structP, - const char * const key, - xmlrpc_value ** const valuePP) { -/*---------------------------------------------------------------------------- - Given a key, retrieve a value from the struct. If the key is not - present, return NULL as *valuePP. ------------------------------------------------------------------------------*/ - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT_VALUE_OK(structP); - XMLRPC_ASSERT_PTR_OK(key); - - if (structP->_type != XMLRPC_TYPE_STRUCT) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_TYPE_ERROR, "Value is not a struct. It is type #%d", - structP->_type); - else { - int xmIndex; - - /* Get our member index. */ - xmIndex = find_member(structP, key, strlen(key)); - if (xmIndex < 0) - *valuePP = NULL; - else { - _struct_member * const members = - XMLRPC_MEMBLOCK_CONTENTS(_struct_member, &structP->_block); - *valuePP = members[xmIndex].value; - - XMLRPC_ASSERT_VALUE_OK(*valuePP); - - xmlrpc_INCREF(*valuePP); - } - } -} - - - -void -xmlrpc_struct_find_value_v(xmlrpc_env * const envP, - xmlrpc_value * const structP, - xmlrpc_value * const keyP, - xmlrpc_value ** const valuePP) { -/*---------------------------------------------------------------------------- - Given a key, retrieve a value from the struct. If the key is not - present, return NULL as *valuePP. ------------------------------------------------------------------------------*/ - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT_VALUE_OK(structP); - XMLRPC_ASSERT_VALUE_OK(keyP); - - if (structP->_type != XMLRPC_TYPE_STRUCT) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_TYPE_ERROR, "Value is not a struct. It is type #%d", - structP->_type); - else { - if (keyP->_type != XMLRPC_TYPE_STRING) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_TYPE_ERROR, "Key value is not a string. " - "It is type #%d", - keyP->_type); - else { - int xmIndex; - - /* Get our member index. */ - xmIndex = find_member(structP, - XMLRPC_MEMBLOCK_CONTENTS(char, &keyP->_block), - XMLRPC_MEMBLOCK_SIZE(char, &keyP->_block)-1); - if (xmIndex < 0) - *valuePP = NULL; - else { - _struct_member * const members = - XMLRPC_MEMBLOCK_CONTENTS(_struct_member, &structP->_block); - *valuePP = members[xmIndex].value; - - XMLRPC_ASSERT_VALUE_OK(*valuePP); - - xmlrpc_INCREF(*valuePP); - } - } - } -} - - - -/*========================================================================= -** xmlrpc_struct_read_value... -**========================================================================= -** These fail if no member with the specified key exists. -** Otherwise, they are the same as xmlrpc_struct_find_value... -*/ - -void -xmlrpc_struct_read_value_v(xmlrpc_env * const envP, - xmlrpc_value * const structP, - xmlrpc_value * const keyP, - xmlrpc_value ** const valuePP) { - - xmlrpc_struct_find_value_v(envP, structP, keyP, valuePP); - - if (!envP->fault_occurred) { - if (*valuePP == NULL) { - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INDEX_ERROR, "No member of struct has key '%.*s'", - XMLRPC_MEMBLOCK_SIZE(char, &keyP->_block), - XMLRPC_MEMBLOCK_CONTENTS(char, &keyP->_block)); - } - } -} - - - -void -xmlrpc_struct_read_value(xmlrpc_env * const envP, - xmlrpc_value * const structP, - const char * const key, - xmlrpc_value ** const valuePP) { - - xmlrpc_struct_find_value(envP, structP, key, valuePP); - - if (!envP->fault_occurred) { - if (*valuePP == NULL) { - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INDEX_ERROR, "No member of struct has key '%s'", - key); - /* We should fix the error message to format the key for display */ - } - } -} - - - -/*========================================================================= -** xmlrpc_struct_get_value... -**========================================================================= -** These are for backward compatibility. They used to be the only ones. -** They're deprecated because they don't acquire a reference to the -** value they return. -*/ - -xmlrpc_value * -xmlrpc_struct_get_value_n(xmlrpc_env * const envP, - xmlrpc_value * const structP, - const char * const key, - size_t const keyLen) { - - xmlrpc_value * retval; - xmlrpc_value * keyP; - - keyP = xmlrpc_build_value(envP, "s#", key, keyLen); - if (!envP->fault_occurred) { - xmlrpc_struct_find_value_v(envP, structP, keyP, &retval); - - if (!envP->fault_occurred) { - if (retval == NULL) { - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INDEX_ERROR, - "No member of struct has key '%.*s'", - keyLen, key); - /* We should fix the error message to format the key - for display */ - } else - /* For backward compatibility. */ - xmlrpc_DECREF(retval); - } - xmlrpc_DECREF(keyP); - } - return retval; -} - - - -xmlrpc_value * -xmlrpc_struct_get_value(xmlrpc_env * const envP, - xmlrpc_value * const strctP, - const char * const key) { - - XMLRPC_ASSERT(key != NULL); - return xmlrpc_struct_get_value_n(envP, strctP, key, strlen(key)); -} - - - -/*========================================================================= -** xmlrpc_struct_set_value -**========================================================================= -*/ - -void -xmlrpc_struct_set_value(xmlrpc_env * const envP, - xmlrpc_value * const strctP, - const char * const key, - xmlrpc_value * const valueP) { - - XMLRPC_ASSERT(key != NULL); - xmlrpc_struct_set_value_n(envP, strctP, key, strlen(key), valueP); -} - - - -void -xmlrpc_struct_set_value_n(xmlrpc_env * const envP, - xmlrpc_value * const strctP, - const char * const key, - size_t const key_len, - xmlrpc_value * const valueP) { - - xmlrpc_value *keyval; - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT(key != NULL); - - /* Set up error handling preconditions. */ - keyval = NULL; - - XMLRPC_TYPE_CHECK(envP, strctP, XMLRPC_TYPE_STRUCT); - - /* Build an xmlrpc_value from our string. */ - keyval = xmlrpc_build_value(envP, "s#", key, key_len); - XMLRPC_FAIL_IF_FAULT(envP); - - /* Do the actual work. */ - xmlrpc_struct_set_value_v(envP, strctP, keyval, valueP); - - cleanup: - if (keyval) - xmlrpc_DECREF(keyval); -} - - - -void -xmlrpc_struct_set_value_v(xmlrpc_env * const envP, - xmlrpc_value * const strctP, - xmlrpc_value * const keyvalP, - xmlrpc_value * const valueP) { - - char *key; - size_t key_len; - int xmIndex; - _struct_member *members, *member, new_member; - xmlrpc_value *old_value; - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT_VALUE_OK(strctP); - XMLRPC_ASSERT_VALUE_OK(keyvalP); - XMLRPC_ASSERT_VALUE_OK(valueP); - - XMLRPC_TYPE_CHECK(envP, strctP, XMLRPC_TYPE_STRUCT); - XMLRPC_TYPE_CHECK(envP, keyvalP, XMLRPC_TYPE_STRING); - - key = XMLRPC_MEMBLOCK_CONTENTS(char, &keyvalP->_block); - key_len = XMLRPC_MEMBLOCK_SIZE(char, &keyvalP->_block) - 1; - xmIndex = find_member(strctP, key, key_len); - - if (xmIndex >= 0) { - /* Change the value of an existing member. (But be careful--the - ** original and new values might be the same object, so watch - ** the order of INCREF and DECREF calls!) */ - members = XMLRPC_MEMBLOCK_CONTENTS(_struct_member, &strctP->_block); - member = &members[xmIndex]; - - /* Juggle our references. */ - old_value = member->value; - member->value = valueP; - xmlrpc_INCREF(member->value); - xmlrpc_DECREF(old_value); - } else { - /* Add a new member. */ - new_member.key_hash = get_hash(key, key_len); - new_member.key = keyvalP; - new_member.value = valueP; - XMLRPC_MEMBLOCK_APPEND(_struct_member, envP, &strctP->_block, - &new_member, 1); - XMLRPC_FAIL_IF_FAULT(envP); - xmlrpc_INCREF(keyvalP); - xmlrpc_INCREF(valueP); - } - -cleanup: - return; -} - - - -/* Note that the order of keys and values is undefined, and may change - when you modify the struct. -*/ - -void -xmlrpc_struct_read_member(xmlrpc_env * const envP, - xmlrpc_value * const structP, - unsigned int const xmIndex, - xmlrpc_value ** const keyvalP, - xmlrpc_value ** const valueP) { - - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT_VALUE_OK(structP); - XMLRPC_ASSERT_PTR_OK(keyvalP); - XMLRPC_ASSERT_PTR_OK(valueP); - - if (structP->_type != XMLRPC_TYPE_STRUCT) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_TYPE_ERROR, "Attempt to read a struct member " - "of something that is not a struct"); - else { - _struct_member * const members = - XMLRPC_MEMBLOCK_CONTENTS(_struct_member, &structP->_block); - size_t const size = - XMLRPC_MEMBLOCK_SIZE(_struct_member, &structP->_block); - - if (xmIndex >= size) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INDEX_ERROR, "Index %u is beyond the end of " - "the %u-member structure", xmIndex, (unsigned int)size); - else { - _struct_member * const memberP = &members[xmIndex]; - *keyvalP = memberP->key; - xmlrpc_INCREF(memberP->key); - *valueP = memberP->value; - xmlrpc_INCREF(memberP->value); - } - } -} - - - -void -xmlrpc_struct_get_key_and_value(xmlrpc_env * const envP, - xmlrpc_value * const structP, - int const xmIndex, - xmlrpc_value ** const keyvalP, - xmlrpc_value ** const valueP) { -/*---------------------------------------------------------------------------- - Same as xmlrpc_struct_read_member(), except doesn't take a reference - to the returned value. - - This is obsolete. ------------------------------------------------------------------------------*/ - XMLRPC_ASSERT_ENV_OK(envP); - XMLRPC_ASSERT_VALUE_OK(structP); - XMLRPC_ASSERT_PTR_OK(keyvalP); - XMLRPC_ASSERT_PTR_OK(valueP); - - if (xmIndex < 0) - xmlrpc_env_set_fault_formatted( - envP, XMLRPC_INDEX_ERROR, "Index %d is negative."); - else { - xmlrpc_struct_read_member(envP, structP, xmIndex, keyvalP, valueP); - if (!envP->fault_occurred) { - xmlrpc_DECREF(*keyvalP); - xmlrpc_DECREF(*valueP); - } - } - if (envP->fault_occurred) { - *keyvalP = NULL; - *valueP = NULL; - } -} |