1 /* Copyright information is at the end of the file */
3 /*=========================================================================
4 ** XML-RPC Array Functions
5 **=========================================================================
8 #include "xmlrpc_config.h"
13 #include "xmlrpc-c/util.h"
14 #include "xmlrpc-c/base.h"
15 #include "xmlrpc-c/base_int.h"
20 xmlrpc_abort_if_array_bad(xmlrpc_value * const arrayP) {
24 else if (arrayP->_type != XMLRPC_TYPE_ARRAY)
27 unsigned int const arraySize =
28 XMLRPC_MEMBLOCK_SIZE(xmlrpc_value*, &arrayP->_block);
29 xmlrpc_value ** const contents =
30 XMLRPC_MEMBLOCK_CONTENTS(xmlrpc_value*, &arrayP->_block);
37 for (index = 0; index < arraySize; ++index) {
38 xmlrpc_value * const itemP = contents[index];
41 else if (itemP->_refcount < 1)
51 xmlrpc_destroyArrayContents(xmlrpc_value * const arrayP) {
52 /*----------------------------------------------------------------------------
53 Dispose of the contents of an array (but not the array value itself).
54 The value is not valid after this.
55 -----------------------------------------------------------------------------*/
56 unsigned int const arraySize =
57 XMLRPC_MEMBLOCK_SIZE(xmlrpc_value*, &arrayP->_block);
58 xmlrpc_value ** const contents =
59 XMLRPC_MEMBLOCK_CONTENTS(xmlrpc_value*, &arrayP->_block);
63 XMLRPC_ASSERT_ARRAY_OK(arrayP);
65 /* Release our reference to each item in the array */
66 for (index = 0; index < arraySize; ++index) {
67 xmlrpc_value * const itemP = contents[index];
70 XMLRPC_MEMBLOCK_CLEAN(xmlrpc_value *, &arrayP->_block);
76 xmlrpc_array_size(xmlrpc_env * const env,
77 const xmlrpc_value * const array) {
81 /* Suppress a compiler warning about uninitialized variables. */
84 XMLRPC_ASSERT_ENV_OK(env);
85 XMLRPC_ASSERT_VALUE_OK(array);
86 XMLRPC_TYPE_CHECK(env, array, XMLRPC_TYPE_ARRAY);
88 retval = XMLRPC_TYPED_MEM_BLOCK_SIZE(xmlrpc_value*, &array->_block);
91 if (env->fault_occurred)
100 xmlrpc_array_append_item(xmlrpc_env * const envP,
101 xmlrpc_value * const arrayP,
102 xmlrpc_value * const valueP) {
104 XMLRPC_ASSERT_ENV_OK(envP);
105 XMLRPC_ASSERT_VALUE_OK(arrayP);
107 if (xmlrpc_value_type(arrayP) != XMLRPC_TYPE_ARRAY)
108 xmlrpc_env_set_fault_formatted(
109 envP, XMLRPC_TYPE_ERROR, "Value is not an array");
112 XMLRPC_MEMBLOCK_SIZE(xmlrpc_value *, &arrayP->_block);
114 XMLRPC_MEMBLOCK_RESIZE(xmlrpc_value *, envP, &arrayP->_block, size+1);
116 if (!envP->fault_occurred) {
117 xmlrpc_value ** const contents =
118 XMLRPC_MEMBLOCK_CONTENTS(xmlrpc_value*, &arrayP->_block);
119 xmlrpc_INCREF(valueP);
120 contents[size] = valueP;
128 xmlrpc_array_read_item(xmlrpc_env * const envP,
129 const xmlrpc_value * const arrayP,
130 unsigned int const index,
131 xmlrpc_value ** const valuePP) {
133 XMLRPC_ASSERT_ENV_OK(envP);
134 XMLRPC_ASSERT_VALUE_OK(arrayP);
135 XMLRPC_ASSERT_PTR_OK(valuePP);
137 if (arrayP->_type != XMLRPC_TYPE_ARRAY)
138 xmlrpc_env_set_fault_formatted(
139 envP, XMLRPC_TYPE_ERROR, "Attempt to read array item from "
140 "a value that is not an array");
142 xmlrpc_value ** const contents =
143 XMLRPC_MEMBLOCK_CONTENTS(xmlrpc_value *, &arrayP->_block);
145 XMLRPC_MEMBLOCK_SIZE(xmlrpc_value *, &arrayP->_block);
148 xmlrpc_env_set_fault_formatted(
149 envP, XMLRPC_INDEX_ERROR, "Array index %u is beyond end "
150 "of %u-item array", index, (unsigned int)size);
152 *valuePP = contents[index];
153 xmlrpc_INCREF(*valuePP);
161 xmlrpc_array_get_item(xmlrpc_env * const envP,
162 const xmlrpc_value * const arrayP,
163 int const indexArg) {
165 /* We must maintain the historical thread-safeness of
166 xmlrpc_array_get_item(). That means we can't call
167 xmlrpc_read_array(), because it modifies the reference count
168 of its arguments, thus is not thread-safe.
170 The Xmlrpc-c method registry is an example of an application that
171 relies on thread-safeness of xmlrpc_array_get_item() -- it uses
172 xmlrpc_value's to represent the registry, and multiple server
173 threads read the registry simultaneously.
176 xmlrpc_value * valueP;
178 XMLRPC_ASSERT_ENV_OK(envP);
179 XMLRPC_ASSERT_VALUE_OK(arrayP);
184 xmlrpc_env_set_fault_formatted(
185 envP, XMLRPC_INDEX_ERROR, "Index %d is negative.", indexArg);
187 unsigned int const index = indexArg;
189 if (arrayP->_type != XMLRPC_TYPE_ARRAY)
190 xmlrpc_env_set_fault_formatted(
191 envP, XMLRPC_TYPE_ERROR, "Attempt to read array item from "
192 "a value that is not an array");
194 xmlrpc_value ** const contents =
195 XMLRPC_MEMBLOCK_CONTENTS(xmlrpc_value *, &arrayP->_block);
197 XMLRPC_MEMBLOCK_SIZE(xmlrpc_value *, &arrayP->_block);
200 xmlrpc_env_set_fault_formatted(
201 envP, XMLRPC_INDEX_ERROR, "Array index %u is beyond end "
202 "of %u-item array", index, (unsigned int)size);
204 valueP = contents[index];
213 xmlrpc_array_new(xmlrpc_env * const envP) {
214 /*----------------------------------------------------------------------------
215 Create an empty array xmlrpc_value.
216 -----------------------------------------------------------------------------*/
217 xmlrpc_value * arrayP;
219 xmlrpc_createXmlrpcValue(envP, &arrayP);
220 if (!envP->fault_occurred) {
221 arrayP->_type = XMLRPC_TYPE_ARRAY;
222 XMLRPC_MEMBLOCK_INIT(xmlrpc_value*, envP, &arrayP->_block, 0);
223 if (envP->fault_occurred)
231 /* Copyright (C) 2001 by First Peer, Inc. All rights reserved.
232 ** Copyright (C) 2001 by Eric Kidd. All rights reserved.
234 ** Redistribution and use in source and binary forms, with or without
235 ** modification, are permitted provided that the following conditions
237 ** 1. Redistributions of source code must retain the above copyright
238 ** notice, this list of conditions and the following disclaimer.
239 ** 2. Redistributions in binary form must reproduce the above copyright
240 ** notice, this list of conditions and the following disclaimer in the
241 ** documentation and/or other materials provided with the distribution.
242 ** 3. The name of the author may not be used to endorse or promote products
243 ** derived from this software without specific prior written permission.
245 ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
246 ** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
247 ** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
248 ** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
249 ** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
250 ** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
251 ** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
252 ** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
253 ** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
254 ** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF