118
/*=========================================================================
120
**=========================================================================
121
** A mindlessly simple hash function. Please feel free to write something
122
** more clever if this produces bad results.
126
get_hash(const char * const key,
127
size_t const key_len) {
129
unsigned char retval;
120
hashStructKey(const char * const key,
121
size_t const keyLen) {
132
126
XMLRPC_ASSERT(key != NULL);
135
for (i = 0; i < key_len; i++)
128
/* This is the Bernstein hash, optimized for lower case ASCII
129
keys. Note that the bytes of such a key differ only in their
132
for (hash = 0, i = 0; i < keyLen; ++i)
133
hash = hash + key[i] + (hash << 5);
150
148
find_member(xmlrpc_value * const strctP,
151
149
const char * const key,
152
size_t const key_len) {
150
size_t const keyLen) {
156
_struct_member *contents;
157
xmlrpc_value *keyval;
154
_struct_member * contents; /* array */
155
xmlrpc_value * keyvalP;
161
159
XMLRPC_ASSERT_VALUE_OK(strctP);
162
160
XMLRPC_ASSERT(key != NULL);
164
162
/* Look for our key. */
165
hash = get_hash(key, key_len);
163
searchHash = hashStructKey(key, keyLen);
166
164
size = XMLRPC_MEMBLOCK_SIZE(_struct_member, &strctP->_block);
167
165
contents = XMLRPC_MEMBLOCK_CONTENTS(_struct_member, &strctP->_block);
168
for (i = 0; i < size; i++) {
169
if (contents[i].key_hash == hash) {
170
keyval = contents[i].key;
171
keystr = XMLRPC_MEMBLOCK_CONTENTS(char, &keyval->_block);
172
keystr_size = XMLRPC_MEMBLOCK_SIZE(char, &keyval->_block)-1;
173
if (key_len == keystr_size && memcmp(key, keystr, key_len) == 0)
166
for (i = 0; i < size; ++i) {
167
if (contents[i].keyHash == searchHash) {
168
keyvalP = contents[i].key;
169
keystr = XMLRPC_MEMBLOCK_CONTENTS(char, &keyvalP->_block);
170
keystrSize = XMLRPC_MEMBLOCK_SIZE(char, &keyvalP->_block)-1;
171
if (keystrSize == keyLen && memcmp(key, keystr, keyLen) == 0)
274
findValueVNoRef(xmlrpc_env * const envP,
275
xmlrpc_value * const structP,
276
xmlrpc_value * const keyP,
277
xmlrpc_value ** const valuePP) {
272
xmlrpc_struct_find_value_v(xmlrpc_env * const envP,
273
xmlrpc_value * const structP,
274
xmlrpc_value * const keyP,
275
xmlrpc_value ** const valuePP) {
278
276
/*----------------------------------------------------------------------------
279
Same as xmlrpc_find_value_v(), except we don't increment the reference
280
count on the xmlrpc_value we return.
277
Given a key, retrieve a value from the struct. If the key is not
278
present, return NULL as *valuePP.
281
279
-----------------------------------------------------------------------------*/
282
280
XMLRPC_ASSERT_ENV_OK(envP);
283
281
XMLRPC_ASSERT_VALUE_OK(structP);
319
xmlrpc_struct_find_value_v(xmlrpc_env * const envP,
320
xmlrpc_value * const structP,
321
xmlrpc_value * const keyP,
322
xmlrpc_value ** const valuePP) {
323
/*----------------------------------------------------------------------------
324
Given a key, retrieve a value from the struct. If the key is not
325
present, return NULL as *valuePP.
326
-----------------------------------------------------------------------------*/
327
findValueVNoRef(envP, structP, keyP, valuePP);
329
if (!envP->fault_occurred && *valuePP)
330
xmlrpc_INCREF(*valuePP);
335
318
/*=========================================================================
336
319
** xmlrpc_struct_read_value...
337
320
**=========================================================================
399
382
keyP = xmlrpc_build_value(envP, "s#", key, keyLen);
400
383
if (!envP->fault_occurred) {
401
/* We cannot use xmlrpc_find_value_v here because
402
some legacy code uses xmlrpc_struct_get_value() from multiple
403
simultaneous threads and xmlrpc_find_value isn't thread safe
404
due to its manipulation of the reference count.
406
findValueVNoRef(envP, structP, keyP, &retval);
384
xmlrpc_struct_find_value_v(envP, structP, keyP, &retval);
408
386
if (!envP->fault_occurred) {
409
387
if (retval == NULL) {
518
498
xmlrpc_DECREF(old_value);
520
500
/* Add a new member. */
521
new_member.key_hash = get_hash(key, key_len);
522
new_member.key = keyvalP;
523
new_member.value = valueP;
501
new_member.keyHash = hashStructKey(key, key_len);
502
new_member.key = keyvalP;
503
new_member.value = valueP;
524
504
XMLRPC_MEMBLOCK_APPEND(_struct_member, envP, &strctP->_block,
526
506
XMLRPC_FAIL_IF_FAULT(envP);