~ubuntu-branches/ubuntu/natty/xmlrpc-c/natty

« back to all changes in this revision

Viewing changes to src/xmlrpc_struct.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2011-01-06 18:56:02 UTC
  • mfrom: (1.1.6 upstream)
  • Revision ID: james.westby@ubuntu.com-20110106185602-09og2x3suqlzbf6s
Tags: 1.16.32-0ubuntu1
* New upstream version (stable release). LP: #659591.
  - No unresolved symbols in the shared libraries. LP: #690779.
  - Builds with --no-add-needed and --as-needed.
* Rename shared library packages.
* Add symbols files.

Show diffs side-by-side

added added

removed removed

Lines of Context:
31
31
 
32
32
#include "xmlrpc-c/base.h"
33
33
#include "xmlrpc-c/base_int.h"
 
34
#include "int.h"
34
35
 
35
36
#define KEY_ERROR_BUFFER_SZ (32)
36
37
 
115
116
 
116
117
 
117
118
 
118
 
/*=========================================================================
119
 
**  get_hash
120
 
**=========================================================================
121
 
**  A mindlessly simple hash function. Please feel free to write something
122
 
**  more clever if this produces bad results.
123
 
*/
124
 
 
125
 
static unsigned char 
126
 
get_hash(const char * const key, 
127
 
         size_t       const key_len) {
128
 
 
129
 
    unsigned char retval;
 
119
static uint32_t
 
120
hashStructKey(const char * const key, 
 
121
              size_t       const keyLen) {
 
122
 
 
123
    uint32_t hash;
130
124
    size_t i;
131
125
 
132
126
    XMLRPC_ASSERT(key != NULL);
133
127
    
134
 
    retval = 0;
135
 
    for (i = 0; i < key_len; i++)
136
 
        retval += key[i];
137
 
    return retval;
 
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
 
130
       lower 5 bits.
 
131
    */
 
132
    for (hash = 0, i = 0; i < keyLen; ++i)
 
133
        hash = hash + key[i] + (hash << 5);
 
134
 
 
135
    return hash;
138
136
}
139
137
 
140
138
 
149
147
static int 
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) {
153
151
 
154
152
    size_t size, i;
155
 
    unsigned char hash;
156
 
    _struct_member *contents;
157
 
    xmlrpc_value *keyval;
158
 
    char *keystr;
159
 
    size_t keystr_size;
 
153
    uint32_t searchHash;
 
154
    _struct_member * contents;  /* array */
 
155
    xmlrpc_value * keyvalP;
 
156
    const char * keystr;
 
157
    size_t keystrSize;
160
158
 
161
159
    XMLRPC_ASSERT_VALUE_OK(strctP);
162
160
    XMLRPC_ASSERT(key != NULL);
163
161
 
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)
174
172
                return i;
175
173
        }   
176
174
    }
270
268
 
271
269
 
272
270
 
273
 
static void
274
 
findValueVNoRef(xmlrpc_env *    const envP,
275
 
                xmlrpc_value *  const structP,
276
 
                xmlrpc_value *  const keyP,
277
 
                xmlrpc_value ** const valuePP) {
 
271
void
 
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);
308
306
                *valuePP = members[index].value;
309
307
                
310
308
                XMLRPC_ASSERT_VALUE_OK(*valuePP);
 
309
                
 
310
                xmlrpc_INCREF(*valuePP);
311
311
            }
312
312
        }
313
313
    }
315
315
 
316
316
 
317
317
 
318
 
void
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);
328
 
 
329
 
    if (!envP->fault_occurred && *valuePP)
330
 
        xmlrpc_INCREF(*valuePP);
331
 
}
332
 
 
333
 
 
334
 
 
335
318
/*=========================================================================
336
319
**  xmlrpc_struct_read_value...
337
320
**=========================================================================
398
381
    
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.
405
 
        */
406
 
        findValueVNoRef(envP, structP, keyP, &retval);
 
384
        xmlrpc_struct_find_value_v(envP, structP, keyP, &retval);
407
385
 
408
386
        if (!envP->fault_occurred) {
409
387
            if (retval == NULL) {
413
391
                    (int)keyLen, key);
414
392
                /* We should fix the error message to format the key
415
393
                   for display */
416
 
            }
 
394
            } else
 
395
                /* For backward compatibility.  */
 
396
                xmlrpc_DECREF(retval);
417
397
        }
418
398
        xmlrpc_DECREF(keyP);
419
399
    }
518
498
        xmlrpc_DECREF(old_value);
519
499
    } else {
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,
525
505
                               &new_member, 1);
526
506
        XMLRPC_FAIL_IF_FAULT(envP);