Back to index

lightning-sunbird  0.9+nobinonly
Classes | Defines | Typedefs | Functions
xpt_xdr.c File Reference
#include "xpt_xdr.h"
#include "nspr.h"
#include <string.h>

Go to the source code of this file.

Classes

struct  XPTHashRecord
struct  XPTHashTable

Defines

#define ENCODING(cursor)   ((cursor)->state->mode == XPT_ENCODE)
#define CURS_POOL_OFFSET_RAW(cursor)
#define CURS_POOL_OFFSET(cursor)   (CURS_POOL_OFFSET_RAW(cursor) - 1)
#define CURS_POINT(cursor)   ((cursor)->state->pool->data[CURS_POOL_OFFSET(cursor)])
#define DBG(x)   (0)
#define CHECK_COUNT_(cursor, space)
#define CHECK_COUNT(cursor, space)
#define XPT_GROW_CHUNK   8192
#define XPT_HASHSIZE   512

Typedefs

typedef struct XPTHashRecord XPTHashRecord

Functions

static PRBool CheckForRepeat (XPTCursor *cursor, void **addrp, XPTPool pool, PRUint32 len, XPTCursor *new_cursor, PRBool *already)
static XPTHashTableXPT_NewHashTable (XPTArena *arena)
static void trimrecord (XPTArena *arena, XPTHashRecord *record)
static void XPT_HashTableDestroy (XPTHashTable *table)
static voidXPT_HashTableAdd (XPTHashTable *table, void *key, void *value)
static voidXPT_HashTableLookup (XPTHashTable *table, void *key)
 XPT_NewXDRState (XPTMode mode, char *data, PRUint32 len)
 XPT_DestroyXDRState (XPTState *state)
 XPT_GetXDRDataLength (XPTState *state, XPTPool pool, PRUint32 *len)
 XPT_GetXDRData (XPTState *state, XPTPool pool, char **data, PRUint32 *len)
 XPT_DataOffset (XPTState *state, PRUint32 *data_offsetp)
static PRBool GrowPool (XPTArena *arena, XPTDatapool *pool, PRUint32 old_size, PRUint32 exact, PRUint32 at_least)
 XPT_SetDataOffset (XPTState *state, PRUint32 data_offset)
 XPT_MakeCursor (XPTState *state, XPTPool pool, PRUint32 len, XPTCursor *cursor)
 XPT_SeekTo (XPTCursor *cursor, PRUint32 offset)
 XPT_NewString (XPTArena *arena, PRUint16 length, char *bytes)
 XPT_NewStringZ (XPTArena *arena, char *bytes)
 XPT_DoStringInline (XPTArena *arena, XPTCursor *cursor, XPTString **strp)
 XPT_DoString (XPTArena *arena, XPTCursor *cursor, XPTString **strp)
 XPT_DoCString (XPTArena *arena, XPTCursor *cursor, char **identp)
 XPT_GetOffsetForAddr (XPTCursor *cursor, void *addr)
 XPT_SetOffsetForAddr (XPTCursor *cursor, void *addr, PRUint32 offset)
 XPT_SetAddrForOffset (XPTCursor *cursor, PRUint32 offset, void *addr)
 XPT_GetAddrForOffset (XPTCursor *cursor, PRUint32 offset)
 XPT_DoIID (XPTCursor *cursor, nsID *iidp)
 XPT_Do64 (XPTCursor *cursor, PRInt64 *u64p)
 XPT_Do32 (XPTCursor *cursor, PRUint32 *u32p)
 XPT_Do16 (XPTCursor *cursor, PRUint16 *u16p)
 XPT_Do8 (XPTCursor *cursor, PRUint8 *u8p)

Class Documentation

struct XPTHashRecord

Definition at line 106 of file xpt_xdr.c.

Collaboration diagram for XPTHashRecord:
Class Members
void * key
struct XPTHashRecord * next
void * value
struct XPTHashTable

Definition at line 114 of file xpt_xdr.c.

Collaboration diagram for XPTHashTable:
Class Members
XPTArena * arena
XPTHashRecord * buckets

Define Documentation

#define CHECK_COUNT (   cursor,
  space 
)
Value:
(CHECK_COUNT_(cursor, space)                                                \
   ? PR_TRUE                                                                  \
   : (XPT_ASSERT(0),                                                          \
      fprintf(stderr, "FATAL: can't no room for %d in cursor\n", space),      \
      PR_FALSE))

Definition at line 92 of file xpt_xdr.c.

Value:
/* if we're in the header, then exceeding the data_offset is illegal */      \
((cursor)->pool == XPT_HEADER ?                                               \
 (ENCODING(cursor) &&                                                         \
  ((cursor)->state->data_offset &&                                            \
   ((cursor)->offset - 1 + (space) > (cursor)->state->data_offset))           \
  ? (DBG(("no space left in HEADER %d + %d > %d\n", (cursor)->offset,         \
          (space), (cursor)->state->data_offset)) && PR_FALSE)                \
  : PR_TRUE) :                                                                \
 /* if we're in the data area and we're about to exceed the allocation */     \
 (CURS_POOL_OFFSET(cursor) + (space) > (cursor)->state->pool->allocated ?     \
  /* then grow if we're in ENCODE mode */                                     \
  (ENCODING(cursor) ? GrowPool((cursor)->state->arena,                        \
                               (cursor)->state->pool,                         \
                               (cursor)->state->pool->allocated,              \
                               0, CURS_POOL_OFFSET(cursor) + (space))         \
   /* and fail if we're in DECODE mode */                                     \
   : (DBG(("can't extend in DECODE")) && PR_FALSE))                           \
  /* otherwise we're OK */                                                    \
  : PR_TRUE))

Definition at line 71 of file xpt_xdr.c.

Definition at line 61 of file xpt_xdr.c.

Definition at line 57 of file xpt_xdr.c.

Value:
((cursor)->pool == XPT_HEADER                                               \
   ? (cursor)->offset                                                         \
   : (XPT_ASSERT((cursor)->state->data_offset),                               \
      (cursor)->offset + (cursor)->state->data_offset))

Definition at line 51 of file xpt_xdr.c.

#define DBG (   x)    (0)

Definition at line 67 of file xpt_xdr.c.

#define ENCODING (   cursor)    ((cursor)->state->mode == XPT_ENCODE)

Definition at line 48 of file xpt_xdr.c.

#define XPT_GROW_CHUNK   8192

Definition at line 100 of file xpt_xdr.c.

#define XPT_HASHSIZE   512

Definition at line 112 of file xpt_xdr.c.


Typedef Documentation

typedef struct XPTHashRecord XPTHashRecord

Function Documentation

static PRBool CheckForRepeat ( XPTCursor cursor,
void **  addrp,
XPTPool  pool,
PRUint32  len,
XPTCursor new_cursor,
PRBool already 
) [static]

Definition at line 511 of file xpt_xdr.c.

{
    void *last = *addrp;

    *already = PR_FALSE;
    new_cursor->state = cursor->state;
    new_cursor->pool = pool;
    new_cursor->bits = 0;

    if (cursor->state->mode == XPT_DECODE) {

        last = XPT_GetAddrForOffset(new_cursor, new_cursor->offset);

        if (last) {
            *already = PR_TRUE;
            *addrp = last;
        }

    } else {

        new_cursor->offset = XPT_GetOffsetForAddr(new_cursor, last);
        if (new_cursor->offset) {
            *already = PR_TRUE;
            return PR_TRUE;
        }

        /* haven't already found it, so allocate room for it. */
        if (!XPT_MakeCursor(cursor->state, pool, len, new_cursor) ||
            !XPT_SetOffsetForAddr(new_cursor, *addrp, new_cursor->offset))
            return PR_FALSE;
    }
    return PR_TRUE;
}

Here is the call graph for this function:

static PRBool GrowPool ( XPTArena arena,
XPTDatapool pool,
PRUint32  old_size,
PRUint32  exact,
PRUint32  at_least 
) [static]

Definition at line 268 of file xpt_xdr.c.

{
    PRUint32 total_size;
    char *newdata;

    if (exact) {
        XPT_ASSERT(exact > pool->allocated);
        total_size = exact;
    } else {
        total_size = pool->allocated + XPT_GROW_CHUNK;
        if (at_least > total_size)
            total_size = at_least;
    }

    newdata = XPT_MALLOC(arena, total_size);
    if (!newdata)
        return PR_FALSE;
    if (pool->data) {
        if (old_size)
            memcpy(newdata, pool->data, old_size);
        XPT_FREE(arena, pool->data);
    }
    pool->data = newdata;
    pool->allocated = total_size;
    return PR_TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void trimrecord ( XPTArena arena,
XPTHashRecord record 
) [static]

Definition at line 128 of file xpt_xdr.c.

                                                               {
    if (record == NULL)
        return;
    trimrecord(arena, record->next);
    XPT_DELETE(arena, record);
}

Here is the caller graph for this function:

XPT_DataOffset ( XPTState state,
PRUint32 data_offsetp 
)

Definition at line 255 of file xpt_xdr.c.

{
    if (state->mode == XPT_DECODE)
        XPT_SetDataOffset(state, *data_offsetp);
    else
        *data_offsetp = state->data_offset;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 222 of file xpt_xdr.c.

{
    XPTArena *arena = state->arena;

    if (state->pool->offset_map)
        XPT_HashTableDestroy(state->pool->offset_map);
    if (state->mode == XPT_ENCODE)
        XPT_DELETE(arena, state->pool->data);
    XPT_DELETE(arena, state->pool);
    XPT_DELETE(arena, state);
    if (arena)
        XPT_DestroyArena(arena);
}

Here is the call graph for this function:

Here is the caller graph for this function:

XPT_Do16 ( XPTCursor cursor,
PRUint16 u16p 
)

Definition at line 624 of file xpt_xdr.c.

{
    union {
        PRUint8 b8[2];
        PRUint16 b16;
    } u;

    if (!CHECK_COUNT(cursor, 2))
        return PR_FALSE;

    if (ENCODING(cursor)) {
        u.b16 = XPT_SWAB16(*u16p);
        CURS_POINT(cursor) = u.b8[0];
        cursor->offset++;
        CURS_POINT(cursor) = u.b8[1];
    } else {
        u.b8[0] = CURS_POINT(cursor);
        cursor->offset++;
        u.b8[1] = CURS_POINT(cursor);
        *u16p = XPT_SWAB16(u.b16);
    }
    cursor->offset++;

    return PR_TRUE;
}

Here is the caller graph for this function:

XPT_Do32 ( XPTCursor cursor,
PRUint32 u32p 
)

Definition at line 590 of file xpt_xdr.c.

{
    union {
        PRUint8 b8[4];
        PRUint32 b32;
    } u;

    if (!CHECK_COUNT(cursor, 4))
        return PR_FALSE;

    if (ENCODING(cursor)) {
        u.b32 = XPT_SWAB32(*u32p);
        CURS_POINT(cursor) = u.b8[0];
        cursor->offset++;
        CURS_POINT(cursor) = u.b8[1];
        cursor->offset++;
        CURS_POINT(cursor) = u.b8[2];
        cursor->offset++;
        CURS_POINT(cursor) = u.b8[3];
    } else {
        u.b8[0] = CURS_POINT(cursor);
        cursor->offset++;
        u.b8[1] = CURS_POINT(cursor);
        cursor->offset++;
        u.b8[2] = CURS_POINT(cursor);
        cursor->offset++;
        u.b8[3] = CURS_POINT(cursor);
        *u32p = XPT_SWAB32(u.b32);
    }
    cursor->offset++;
    return PR_TRUE;
}

Here is the caller graph for this function:

XPT_Do64 ( XPTCursor cursor,
PRInt64 u64p 
)

Definition at line 577 of file xpt_xdr.c.

{
    return XPT_Do32(cursor, (PRUint32 *)u64p) &&
        XPT_Do32(cursor, ((PRUint32 *)u64p) + 1);
}

Here is the call graph for this function:

Here is the caller graph for this function:

XPT_Do8 ( XPTCursor cursor,
PRUint8 u8p 
)

Definition at line 651 of file xpt_xdr.c.

{
    if (!CHECK_COUNT(cursor, 1))
        return PR_FALSE;
    if (cursor->state->mode == XPT_ENCODE)
        CURS_POINT(cursor) = *u8p;
    else
        *u8p = CURS_POINT(cursor);

    cursor->offset++;

    return PR_TRUE;
}

Here is the caller graph for this function:

XPT_DoCString ( XPTArena arena,
XPTCursor cursor,
char **  identp 
)

Definition at line 416 of file xpt_xdr.c.

{
    XPTCursor my_cursor;
    char *ident = *identp;
    PRUint32 offset = 0;

    XPTMode mode = cursor->state->mode;

    if (mode == XPT_DECODE) {
        char *start, *end;
        int len;

        if (!XPT_Do32(cursor, &offset))
            return PR_FALSE;

        if (!offset) {
            *identp = NULL;
            return PR_TRUE;
        }

        my_cursor.pool = XPT_DATA;
        my_cursor.offset = offset;
        my_cursor.state = cursor->state;
        start = &CURS_POINT(&my_cursor);

        end = strchr(start, 0); /* find the end of the string */
        if (!end) {
            fprintf(stderr, "didn't find end of string on decode!\n");
            return PR_FALSE;
        }
        len = end - start;
        XPT_ASSERT(len > 0);

        ident = XPT_MALLOC(arena, len + 1u);
        if (!ident)
            return PR_FALSE;

        memcpy(ident, start, (size_t)len);
        ident[len] = 0;
        *identp = ident;

    } else {

        if (!ident) {
            offset = 0;
            if (!XPT_Do32(cursor, &offset))
                return PR_FALSE;
            return PR_TRUE;
        }

        if (!XPT_MakeCursor(cursor->state, XPT_DATA, strlen(ident) + 1,
                            &my_cursor) ||
            !XPT_Do32(cursor, &my_cursor.offset))
            return PR_FALSE;

        while(*ident)
            if (!XPT_Do8(&my_cursor, (PRUint8 *)ident++))
                return PR_FALSE;
        if (!XPT_Do8(&my_cursor, (PRUint8 *)ident)) /* write trailing zero */
            return PR_FALSE;
    }

    return PR_TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

XPT_DoIID ( XPTCursor cursor,
nsID iidp 
)

Definition at line 560 of file xpt_xdr.c.

{
    int i;

    if (!XPT_Do32(cursor, &iidp->m0) ||
        !XPT_Do16(cursor, &iidp->m1) ||
        !XPT_Do16(cursor, &iidp->m2))
        return PR_FALSE;

    for (i = 0; i < 8; i++)
        if (!XPT_Do8(cursor, (PRUint8 *)&iidp->m3[i]))
            return PR_FALSE;

    return PR_TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

XPT_DoString ( XPTArena arena,
XPTCursor cursor,
XPTString **  strp 
)

Definition at line 403 of file xpt_xdr.c.

{
    XPTCursor my_cursor;
    XPTString *str = *strp;
    PRBool already;

    XPT_PREAMBLE_NO_ALLOC(cursor, strp, XPT_DATA, str->length + 2, my_cursor,
                          already)

    return XPT_DoStringInline(arena, &my_cursor, strp);
}

Here is the call graph for this function:

Here is the caller graph for this function:

XPT_DoStringInline ( XPTArena arena,
XPTCursor cursor,
XPTString **  strp 
)

Definition at line 367 of file xpt_xdr.c.

{
    XPTString *str = *strp;
    XPTMode mode = cursor->state->mode;
    int i;

    if (mode == XPT_DECODE) {
        str = XPT_NEWZAP(arena, XPTString);
        if (!str)
            return PR_FALSE;
        *strp = str;
    }

    if (!XPT_Do16(cursor, &str->length))
        goto error;

    if (mode == XPT_DECODE)
        if (!(str->bytes = XPT_MALLOC(arena, str->length + 1u)))
            goto error;

    for (i = 0; i < str->length; i++)
        if (!XPT_Do8(cursor, (PRUint8 *)&str->bytes[i]))
            goto error_2;

    if (mode == XPT_DECODE)
        str->bytes[str->length] = 0;

    return PR_TRUE;
 error_2:
    XPT_DELETE(arena, str->bytes);
 error:
    XPT_DELETE(arena, str);
    return PR_FALSE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

XPT_GetAddrForOffset ( XPTCursor cursor,
PRUint32  offset 
)

Definition at line 504 of file xpt_xdr.c.

{
    return XPT_HashTableLookup(cursor->state->pool->offset_map, (void *)offset);
}

Here is the call graph for this function:

Here is the caller graph for this function:

XPT_GetOffsetForAddr ( XPTCursor cursor,
void addr 
)

Definition at line 484 of file xpt_xdr.c.

Here is the call graph for this function:

Here is the caller graph for this function:

XPT_GetXDRData ( XPTState state,
XPTPool  pool,
char **  data,
PRUint32 len 
)

Definition at line 243 of file xpt_xdr.c.

{
    if (pool == XPT_HEADER) {
        *data = state->pool->data;
    } else {
        *data = state->pool->data + state->data_offset;
    }
    *len = state->next_cursor[pool] - 1;
}

Here is the caller graph for this function:

XPT_GetXDRDataLength ( XPTState state,
XPTPool  pool,
PRUint32 len 
)

Definition at line 237 of file xpt_xdr.c.

{
    *len = state->next_cursor[pool] - 1;
}

Here is the caller graph for this function:

static void* XPT_HashTableAdd ( XPTHashTable table,
void key,
void value 
) [static]

Definition at line 144 of file xpt_xdr.c.

                                                              {
    XPTHashRecord **bucketloc = table->buckets +
        (((PRUint32)key) % XPT_HASHSIZE);
    XPTHashRecord *bucket;

    while (*bucketloc != NULL)
        bucketloc = &((*bucketloc)->next);

    bucket = XPT_NEW(table->arena, XPTHashRecord);
    bucket->key = key;
    bucket->value = value;
    bucket->next = NULL;
    *bucketloc = bucket;
    return value;
}

Here is the caller graph for this function:

static void XPT_HashTableDestroy ( XPTHashTable table) [static]

Definition at line 136 of file xpt_xdr.c.

                                          {
    int i;
    for (i = 0; i < XPT_HASHSIZE; i++)
        trimrecord(table->arena, table->buckets[i]);
    XPT_FREE(table->arena, table);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void* XPT_HashTableLookup ( XPTHashTable table,
void key 
) [static]

Definition at line 161 of file xpt_xdr.c.

                                                    {
    XPTHashRecord *bucket = table->buckets[(PRUint32)key % XPT_HASHSIZE];
    while (bucket != NULL) {
        if (bucket->key == key)
            return bucket->value;
        bucket = bucket->next;
    }
    return NULL;
}

Here is the caller graph for this function:

XPT_MakeCursor ( XPTState state,
XPTPool  pool,
PRUint32  len,
XPTCursor cursor 
)

Definition at line 309 of file xpt_xdr.c.

{
    cursor->state = state;
    cursor->pool = pool;
    cursor->bits = 0;
    cursor->offset = state->next_cursor[pool];

    if (!(CHECK_COUNT(cursor, len)))
        return PR_FALSE;

    /* this check should be in CHECK_CURSOR */
    if (pool == XPT_DATA && !state->data_offset) {
        fprintf(stderr, "no data offset for XPT_DATA cursor!\n");
        return PR_FALSE;
    }

    state->next_cursor[pool] += len;

    return PR_TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static XPTHashTable* XPT_NewHashTable ( XPTArena arena) [static]

Definition at line 120 of file xpt_xdr.c.

                                  {
    XPTHashTable *table;
    table = XPT_NEWZAP(arena, XPTHashTable);
    if (table)
        table->arena = arena;
    return table;
}

Here is the caller graph for this function:

XPT_NewString ( XPTArena arena,
PRUint16  length,
char *  bytes 
)

Definition at line 339 of file xpt_xdr.c.

{
    XPTString *str = XPT_NEW(arena, XPTString);
    if (!str)
        return NULL;
    str->length = length;
    /* Alloc one extra to store the trailing nul. */
    str->bytes = XPT_MALLOC(arena, length + 1u);
    if (!str->bytes) {
        XPT_DELETE(arena, str);
        return NULL;
    }
    memcpy(str->bytes, bytes, length);
    /* nul-terminate it. */
    str->bytes[length] = '\0';
    return str;
}

Here is the call graph for this function:

Here is the caller graph for this function:

XPT_NewStringZ ( XPTArena arena,
char *  bytes 
)

Definition at line 358 of file xpt_xdr.c.

{
    PRUint32 length = strlen(bytes);
    if (length > 0xffff)
        return NULL;            /* too long */
    return XPT_NewString(arena, (PRUint16)length, bytes);
}

Here is the call graph for this function:

Here is the caller graph for this function:

XPT_NewXDRState ( XPTMode  mode,
char *  data,
PRUint32  len 
)

Definition at line 172 of file xpt_xdr.c.

{
    XPTState *state;
    XPTArena *arena;

    arena = XPT_NewArena(512, sizeof(double), "an XDRState");
    if (!arena)
        return NULL;

    state = XPT_NEWZAP(arena, XPTState);
    if (!state)
        goto err_free_arena;

    state->arena = arena;
    state->mode = mode;
    state->pool = XPT_NEW(arena, XPTDatapool);
    state->next_cursor[0] = state->next_cursor[1] = 1;
    if (!state->pool)
        goto err_free_state;

    state->pool->count = 0;
    state->pool->offset_map = XPT_NewHashTable(arena);

    if (!state->pool->offset_map)
        goto err_free_pool;
    if (mode == XPT_DECODE) {
        state->pool->data = data;
        state->pool->allocated = len;
    } else {
        state->pool->data = XPT_MALLOC(arena, XPT_GROW_CHUNK);
        if (!state->pool->data)
            goto err_free_hash;
        state->pool->allocated = XPT_GROW_CHUNK;
    }

    return state;

 err_free_hash:
    XPT_HashTableDestroy(state->pool->offset_map);
 err_free_pool:
    XPT_DELETE(arena, state->pool);
 err_free_state:
    XPT_DELETE(arena, state);
 err_free_arena:
    if (arena)
        XPT_DestroyArena(arena);
    return NULL;
}

Here is the call graph for this function:

Here is the caller graph for this function:

XPT_SeekTo ( XPTCursor cursor,
PRUint32  offset 
)

Definition at line 331 of file xpt_xdr.c.

{
    /* XXX do some real checking and update len and stuff */
    cursor->offset = offset;
    return PR_TRUE;
}

Here is the caller graph for this function:

XPT_SetAddrForOffset ( XPTCursor cursor,
PRUint32  offset,
void addr 
)

Definition at line 497 of file xpt_xdr.c.

{
    return XPT_HashTableAdd(cursor->state->pool->offset_map,
                            (void *)offset, addr) != NULL;
}

Here is the call graph for this function:

XPT_SetDataOffset ( XPTState state,
PRUint32  data_offset 
)

Definition at line 297 of file xpt_xdr.c.

{
   state->data_offset = data_offset;
   /* make sure we've allocated enough space for the header */
   if (state->mode == XPT_ENCODE &&
       data_offset > state->pool->allocated) {
       (void)GrowPool(state->arena, state->pool, state->pool->allocated, 
                      data_offset, 0);
   }
}

Here is the call graph for this function:

Here is the caller graph for this function:

XPT_SetOffsetForAddr ( XPTCursor cursor,
void addr,
PRUint32  offset 
)

Definition at line 490 of file xpt_xdr.c.

{
    return XPT_HashTableAdd(cursor->state->pool->offset_map,
                            addr, (void *)offset) != NULL;
}

Here is the call graph for this function:

Here is the caller graph for this function: