added some tests (we don't pass yet =) ), wrote some primitives
git-svn-id: svn://10.0.0.236/trunk@18087 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
parent
1629d20dfd
commit
b7788d4156
28
mozilla/xpcom/libxpt/Makefile.in
Normal file
28
mozilla/xpcom/libxpt/Makefile.in
Normal file
@ -0,0 +1,28 @@
|
||||
#!gmake
|
||||
# The contents of this file are subject to the Netscape Public License
|
||||
# Version 1.0 (the "NPL"); you may not use this file except in
|
||||
# compliance with the NPL. You may obtain a copy of the NPL at
|
||||
# http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
# for the specific language governing rights and limitations under the
|
||||
# NPL.
|
||||
#
|
||||
# The Initial Developer of this code under the NPL is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
# Reserved.
|
||||
|
||||
DEPTH = ../..
|
||||
topsrcdir = @top_srcdir@
|
||||
VPATH = @srcdir@
|
||||
srcdir = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
DIRS = public src
|
||||
|
||||
DIRS += tests
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
@ -25,6 +25,7 @@
|
||||
|
||||
#include <nspr.h>
|
||||
#include <plhash.h>
|
||||
#include <prmem.h>
|
||||
#include "xpt_struct.h"
|
||||
|
||||
typedef struct XPTState XPTState;
|
||||
@ -40,6 +41,9 @@ XPT_DoIdentifier(XPTCursor *cursor, char **identp);
|
||||
PRBool
|
||||
XPT_DoIID(XPTCursor *cursor, nsID *iidp);
|
||||
|
||||
PRBool
|
||||
XPT_Do64(XPTCursor *cursor, PRInt64 *u64p);
|
||||
|
||||
PRBool
|
||||
XPT_Do32(XPTCursor *cursor, uint32 *u32p);
|
||||
|
||||
@ -62,6 +66,8 @@ XPT_Do8(XPTCursor *cursor, uint8 *u8p);
|
||||
PRBool
|
||||
XPT_DoBits(XPTCursor *cursor, uint8 *u8p, int nbits);
|
||||
|
||||
#define XPT_DO_BITS(curs, field, width, scr) (PR_TRUE)
|
||||
|
||||
/* returns the number of bits skipped, which should be 0-7 */
|
||||
int
|
||||
XPT_FlushBits(XPTCursor *cursor);
|
||||
@ -78,52 +84,45 @@ typedef enum {
|
||||
|
||||
struct XPTState {
|
||||
XPTMode mode;
|
||||
XPTDatapool *pools[2];
|
||||
uint32 data_offset;
|
||||
XPTDatapool *pool;
|
||||
};
|
||||
|
||||
struct XPTDatapool {
|
||||
PLHashTable *offset_map;
|
||||
char *data;
|
||||
uint32 count;
|
||||
uint8 bit;
|
||||
uint32 allocated;
|
||||
};
|
||||
|
||||
struct XPTCursor {
|
||||
XPTState *state;
|
||||
XPTDatapool *pool;
|
||||
XPTPool pool;
|
||||
uint32 offset;
|
||||
uint32 len;
|
||||
uint8 bits;
|
||||
};
|
||||
|
||||
XPTState *
|
||||
XPT_NewXDRState(XPTMode mode, char *data, uint32 len);
|
||||
|
||||
PRBool
|
||||
XPT_MakeCursor(XPTState *state, XPTPool pool, XPTCursor *cursor);
|
||||
|
||||
void
|
||||
XPT_DestroyXDRState(XPTState *state);
|
||||
|
||||
void
|
||||
XPT_GetXDRData(XPTState *state, XPTPool pool, char **data, uint32 *len);
|
||||
|
||||
/*
|
||||
* On CreateCursor:
|
||||
* cursors are used to track position within the byte stream.
|
||||
* In encode/write mode, the cursor reserves an area of memory for a structure.
|
||||
* In decode/read mode, it simply tracks position.
|
||||
*
|
||||
* Usage will commonly be something like this (taken from XPT_DoString) for
|
||||
* out-of-line structures:
|
||||
*
|
||||
* // create my_cursor and reserve memory as required
|
||||
* XPT_CreateCursor(parent_cursor, XPT_DATA, str->length + 2, &my_cursor);
|
||||
* // write mode: store the offset for this structure in the parent cursor
|
||||
* // read mode: adjust my_cursor to point to the write offset
|
||||
* XPT_Do32(parent_cursor, &my_cursor->offset);
|
||||
*/
|
||||
/* set or get the data offset for the state, depending on mode */
|
||||
void
|
||||
XPT_DataOffset(XPTState *state, uint32 *data_offsetp);
|
||||
|
||||
void
|
||||
XPT_SetDataOffset(XPTState *state, uint32 data_offset);
|
||||
|
||||
PRBool
|
||||
XPT_CreateCursor(XPTCursor *base, XPTPool pool, uint32 len, XPTCursor *cursor);
|
||||
XPT_MakeCursor(XPTState *state, XPTPool pool, XPTCursor *cursor);
|
||||
|
||||
/* all data structures are big-endian */
|
||||
|
||||
@ -188,7 +187,7 @@ XPT_CreateCursor(XPTCursor *base, XPTPool pool, uint32 len, XPTCursor *cursor);
|
||||
#define XPT_ERROR_HANDLE(free_it) \
|
||||
error: \
|
||||
if (cursor->state->mode == XPT_DECODE) \
|
||||
PR_FREE_IF(free_it); \
|
||||
PR_FREEIF(free_it); \
|
||||
return PR_FALSE;
|
||||
|
||||
|
||||
|
||||
@ -19,81 +19,137 @@
|
||||
/* Implementation of XDR primitives. */
|
||||
|
||||
#include "xpt_xdr.h"
|
||||
#include <nspr.h>
|
||||
#include <string.h> /* strchr */
|
||||
|
||||
#define CHECK_COUNT(cursor) \
|
||||
((cursor)->offset == (cursor)->pool->allocated ? \
|
||||
((cursor)->state->mode == XPT_ENCODE ? XPT_GrowPool((cursor)->pool) : \
|
||||
PR_FALSE) : PR_TRUE)
|
||||
#define ENCODING(cursor) \
|
||||
((cursor)->state->mode == XPT_ENCODE)
|
||||
|
||||
#define CURS_POOL_OFFSET(cursor) \
|
||||
((cursor)->pool == XPT_HEADER \
|
||||
? (cursor)->offset \
|
||||
: (PR_ASSERT((cursor)->state->data_offset), \
|
||||
(cursor)->offset + (cursor)->state->data_offset))
|
||||
|
||||
/* can be used as lvalue */
|
||||
#define CURS_POINT(cursor) \
|
||||
(cursor)->state->pool->data[CURS_POOL_OFFSET(cursor)]
|
||||
|
||||
#define CHECK_COUNT(cursor, space) \
|
||||
/* if we're in the header, then exceeding the data_offset is illegal */ \
|
||||
((cursor)->pool == XPT_HEADER ? \
|
||||
((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) ? XPT_GrowPool((cursor)->state->pool) \
|
||||
/* and fail if we're in DECODE mode */ \
|
||||
: PR_FALSE) \
|
||||
/* otherwise we're OK */ \
|
||||
: PR_TRUE))
|
||||
|
||||
/* increase the data allocation for the pool by XPT_GROW_CHUNK */
|
||||
#define XPT_GROW_CHUNK 8192
|
||||
|
||||
static PLHashNumber
|
||||
null_hash(const void *key)
|
||||
{
|
||||
return (PLHashNumber)key;
|
||||
}
|
||||
|
||||
XPTState *
|
||||
XPT_NewXDRState(XPTMode mode, char *data, uint32 len)
|
||||
{
|
||||
#if 0 /* need to rethink pool management */
|
||||
XPTState *state;
|
||||
int i;
|
||||
|
||||
state = PR_NEW(XPTState);
|
||||
|
||||
if (!state)
|
||||
return NULL;
|
||||
|
||||
state->mode = mode;
|
||||
for (i = 0; i < 2; i++) {
|
||||
state->pools[i] = PR_NEW(XPTDatapool);
|
||||
if (!state->pools[i]) {
|
||||
if (i) {
|
||||
PR_FREE(state->pools[0]->data);
|
||||
PR_FREE(state->pools[0]);
|
||||
}
|
||||
PR_FREE(state);
|
||||
return NULL;
|
||||
}
|
||||
state->pools[i]->count = 0;
|
||||
state->pools[i]->bit = 0;
|
||||
if (mode == XPT_DECODE) {
|
||||
state->pools[i]->data = data;
|
||||
state->pools[i]->allocated = len;
|
||||
} else {
|
||||
state->pools[i]->data = PR_MALLOC(XPT_GROW_CHUNK);
|
||||
if (!state->pools[i]->data) {
|
||||
PR_FREE(state->pools[i]);
|
||||
if (i) {
|
||||
PR_FREE(state->pools[0]->data);
|
||||
PR_FREE(state->pools[0]);
|
||||
}
|
||||
PR_FREE(state);
|
||||
return NULL;
|
||||
}
|
||||
state->pools[i]->allocated = XPT_GROW_CHUNK;
|
||||
}
|
||||
state->pool = PR_NEW(XPTDatapool);
|
||||
if (!state->pool)
|
||||
goto err_free_state;
|
||||
|
||||
state->pool->count = 0;
|
||||
state->pool->offset_map = PL_NewHashTable(32, null_hash, PL_CompareValues,
|
||||
PL_CompareValues, NULL, NULL);
|
||||
|
||||
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 = PR_MALLOC(XPT_GROW_CHUNK);
|
||||
if (!state->pool->data)
|
||||
goto err_free_hash;
|
||||
state->pool->allocated = XPT_GROW_CHUNK;
|
||||
}
|
||||
#endif
|
||||
|
||||
return state;
|
||||
|
||||
err_free_hash:
|
||||
PL_HashTableDestroy(state->pool->offset_map);
|
||||
err_free_pool:
|
||||
PR_DELETE(state->pool);
|
||||
err_free_state:
|
||||
PR_DELETE(state);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
XPT_DestroyXDRState(XPTState *state)
|
||||
{
|
||||
#if 0 /* need to rethink pool management */
|
||||
int i;
|
||||
if (state->mode == XPT_ENCODE) {
|
||||
PR_FREE_IF(state->pool->data);
|
||||
PR_FREE(state->pool);
|
||||
PR_FREE(state);
|
||||
} else {
|
||||
PR_FREE(state->pool);
|
||||
PR_FREE(state);
|
||||
}
|
||||
#endif
|
||||
if (state->mode == XPT_ENCODE)
|
||||
PR_DELETE(state->pool->data);
|
||||
PR_DELETE(state->pool);
|
||||
PR_DELETE(state);
|
||||
}
|
||||
|
||||
void
|
||||
XPT_GetXDRData(XPTState *state, XPTPool pool, char **data, uint32 *len)
|
||||
{
|
||||
*data = state->pools[pool]->data;
|
||||
*len = state->pools[pool]->count;
|
||||
if (pool == XPT_HEADER) {
|
||||
*data = state->pool->data;
|
||||
*len = state->data_offset;
|
||||
} else {
|
||||
*data = state->pool->data + state->data_offset;
|
||||
*len = state->pool->count - state->data_offset;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
XPT_DataOffset(XPTState *state, uint32 *data_offsetp)
|
||||
{
|
||||
if (state->mode == XPT_DECODE)
|
||||
state->data_offset = *data_offsetp;
|
||||
else
|
||||
*data_offsetp = state->data_offset;
|
||||
}
|
||||
|
||||
void
|
||||
XPT_SetDataOffset(XPTState *state, uint32 data_offset)
|
||||
{
|
||||
state->data_offset = data_offset;
|
||||
}
|
||||
|
||||
PRBool
|
||||
XPT_MakeCursor(XPTState *state, XPTPool pool, XPTCursor *cursor)
|
||||
{
|
||||
cursor->state = state;
|
||||
cursor->pool = pool;
|
||||
cursor->bits = 0;
|
||||
if (pool == XPT_DATA) {
|
||||
if (!state->data_offset)
|
||||
return PR_FALSE;
|
||||
cursor->offset = state->data_offset;
|
||||
} else {
|
||||
cursor->offset = 0;
|
||||
}
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
static PRBool
|
||||
@ -142,7 +198,7 @@ XPT_DoCString(XPTCursor *cursor, char **identp)
|
||||
my_cursor, already);
|
||||
|
||||
if (mode == XPT_DECODE) {
|
||||
char *start = &my_cursor.pool->data[my_cursor.offset], *end;
|
||||
char *start = &CURS_POINT(&my_cursor), *end;
|
||||
int len;
|
||||
|
||||
end = strchr(start, 0); /* find the end of the string */
|
||||
@ -161,7 +217,7 @@ XPT_DoCString(XPTCursor *cursor, char **identp)
|
||||
*identp = ident;
|
||||
|
||||
if (!XPT_SetAddrForOffset(&my_cursor, my_cursor.offset, ident)) {
|
||||
PR_FREE(ident);
|
||||
PR_DELETE(ident);
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
@ -179,26 +235,28 @@ XPT_DoCString(XPTCursor *cursor, char **identp)
|
||||
uint32
|
||||
XPT_GetOffsetForAddr(XPTCursor *cursor, void *addr)
|
||||
{
|
||||
return 0;
|
||||
return (uint32)PL_HashTableLookup(cursor->state->pool->offset_map, addr);
|
||||
}
|
||||
|
||||
PRBool
|
||||
XPT_SetOffsetForAddr(XPTCursor *cursor, void **addr, uint32 offset)
|
||||
XPT_SetOffsetForAddr(XPTCursor *cursor, void *addr, uint32 offset)
|
||||
{
|
||||
*addr = NULL;
|
||||
return PR_FALSE;
|
||||
return PL_HashTableAdd(cursor->state->pool->offset_map,
|
||||
addr, (void *)offset) != NULL;
|
||||
}
|
||||
|
||||
PRBool
|
||||
XPT_SetAddrForOffset(XPTCursor *cursor, void *addr)
|
||||
{
|
||||
return PR_FALSE;
|
||||
return PL_HashTableAdd(cursor->state->pool->offset_map,
|
||||
(void *)cursor->offset, addr) != NULL;
|
||||
}
|
||||
|
||||
void *
|
||||
XPT_GetAddrForOffset(XPTCursor *cursor)
|
||||
{
|
||||
return PR_FALSE;
|
||||
return PL_HashTableLookup(cursor->state->pool->offset_map,
|
||||
(void *)cursor->offset);
|
||||
}
|
||||
|
||||
PRBool
|
||||
@ -209,7 +267,8 @@ XPT_CheckForRepeat(XPTCursor *cursor, void **addrp, XPTPool pool, int len,
|
||||
|
||||
*already = PR_FALSE;
|
||||
new_cursor->state = cursor->state;
|
||||
new_cursor->pool = cursor->state->pools[pool];
|
||||
new_cursor->pool = pool;
|
||||
new_cursor->bits = 0;
|
||||
|
||||
if (cursor->state->mode = XPT_DECODE) {
|
||||
|
||||
@ -256,27 +315,85 @@ XPT_DoIID(XPTCursor *cursor, nsID *iidp)
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
XPT_Do64(XPTCursor *cursor, PRInt64 *u64p)
|
||||
{
|
||||
return XPT_Do32(cursor, (uint32 *)u64p) &&
|
||||
XPT_Do32(cursor, ((uint32 *)u64p) + 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* When we're writing 32- or 16-bit quantities, we write a byte at a time to
|
||||
* avoid alignment issues. Someone could come and optimize this to detect
|
||||
* well-aligned cases and do a single store, if they cared. I might care
|
||||
* later.
|
||||
*/
|
||||
PRBool
|
||||
XPT_Do32(XPTCursor *cursor, uint32 *u32p)
|
||||
{
|
||||
return PR_FALSE;
|
||||
if (!CHECK_COUNT(cursor, 4))
|
||||
return PR_FALSE;
|
||||
if (ENCODING(cursor)) {
|
||||
CURS_POINT(cursor) = ((uint8 *)(u32p))[0];
|
||||
cursor->offset++;
|
||||
CURS_POINT(cursor) = ((uint8 *)(u32p))[1];
|
||||
cursor->offset++;
|
||||
CURS_POINT(cursor) = ((uint8 *)(u32p))[2];
|
||||
cursor->offset++;
|
||||
CURS_POINT(cursor) = ((uint8 *)(u32p))[3];
|
||||
} else {
|
||||
((uint8 *)(u32p))[0] = CURS_POINT(cursor);
|
||||
cursor->offset++;
|
||||
((uint8 *)(u32p))[1] = CURS_POINT(cursor);
|
||||
cursor->offset++;
|
||||
((uint8 *)(u32p))[2] = CURS_POINT(cursor);
|
||||
cursor->offset++;
|
||||
((uint8 *)(u32p))[3] = CURS_POINT(cursor);
|
||||
}
|
||||
cursor->offset++;
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
XPT_Do16(XPTCursor *cursor, uint16 *u16p)
|
||||
{
|
||||
return PR_FALSE;
|
||||
if (!CHECK_COUNT(cursor, 2))
|
||||
return PR_FALSE;
|
||||
if (ENCODING(cursor)) {
|
||||
CURS_POINT(cursor) = ((uint8 *)(u16p))[0];
|
||||
cursor->offset++;
|
||||
CURS_POINT(cursor) = ((uint8 *)(u16p))[1];
|
||||
} else {
|
||||
((uint8 *)(u16p))[0] = CURS_POINT(cursor);
|
||||
cursor->offset++;
|
||||
((uint8 *)(u16p))[1] = CURS_POINT(cursor);
|
||||
}
|
||||
cursor->offset++;
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
XPT_Do8(XPTCursor *cursor, uint8 *u8p)
|
||||
{
|
||||
return PR_FALSE;
|
||||
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;
|
||||
}
|
||||
|
||||
static PRBool
|
||||
do_bit(XPTCursor *cursor, uint8 *u8p, int bitno)
|
||||
{
|
||||
return PR_FALSE;
|
||||
#if 0
|
||||
int bit_value, delta, new_value;
|
||||
XPTDatapool *pool = cursor->pool;
|
||||
|
||||
@ -297,6 +414,7 @@ do_bit(XPTCursor *cursor, uint8 *u8p, int bitno)
|
||||
}
|
||||
|
||||
return CHECK_COUNT(cursor);
|
||||
#endif
|
||||
}
|
||||
|
||||
PRBool
|
||||
@ -335,6 +453,8 @@ XPT_FlushBits(XPTCursor *cursor)
|
||||
{
|
||||
int skipped = 8 - cursor->bits;
|
||||
|
||||
return 0;
|
||||
#if 0
|
||||
cursor->bits = 0;
|
||||
cursor->offset++;
|
||||
|
||||
@ -342,4 +462,5 @@ XPT_FlushBits(XPTCursor *cursor)
|
||||
return -1;
|
||||
|
||||
return skipped == 8 ? 0 : skipped;
|
||||
#endif
|
||||
}
|
||||
|
||||
42
mozilla/xpcom/libxpt/tests/Makefile.in
Normal file
42
mozilla/xpcom/libxpt/tests/Makefile.in
Normal file
@ -0,0 +1,42 @@
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public License
|
||||
# Version 1.0 (the "NPL"); you may not use this file except in
|
||||
# compliance with the NPL. You may obtain a copy of the NPL at
|
||||
# http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
# for the specific language governing rights and limitations under the
|
||||
# NPL.
|
||||
#
|
||||
# The Initial Developer of this code under the NPL is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
# Reserved.
|
||||
|
||||
DEPTH = ../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE = libxpt
|
||||
|
||||
CSRCS = PrimitiveTest.c
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
EX_LIBS = $(DIST)/lib/libxpt.$(LIB_SUFFIX) \
|
||||
$(NULL)
|
||||
|
||||
PROGS = $(addprefix $(OBJDIR)/, $(CSRCS:.c=))
|
||||
|
||||
TARGETS = $(PROGS)
|
||||
|
||||
$(PROGS):$(OBJDIR)/%: $(OBJDIR)/%.o $(EX_LIBS)
|
||||
@$(MAKE_OBJDIR)
|
||||
$(CC) -o $@ $@.o $(LDFLAGS) $(EX_LIBS) $(NSPR_LIBS) $(OS_LIBS)
|
||||
|
||||
install:: $(PROGS)
|
||||
$(INSTALL) $(PROGS) $(DIST)/bin
|
||||
109
mozilla/xpcom/libxpt/tests/PrimitiveTest.c
Normal file
109
mozilla/xpcom/libxpt/tests/PrimitiveTest.c
Normal file
@ -0,0 +1,109 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/* Test the xdr primitives from xpt_xdr.c */
|
||||
|
||||
#include "xpt_xdr.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#define PASS(msg) \
|
||||
printf("PASSED : %s\n", msg);
|
||||
|
||||
#define FAIL(msg) \
|
||||
fprintf(stderr, "FAILURE: %s\n", msg);
|
||||
|
||||
#define TRY_(msg, cond, silent) \
|
||||
if ((cond) && !silent) { \
|
||||
PASS(msg); \
|
||||
} else { \
|
||||
FAIL(msg); \
|
||||
return 1; \
|
||||
}
|
||||
|
||||
#define TRY(msg, cond) TRY_(msg, cond, 0)
|
||||
#define TRY_Q(msg, cond) TRY_(msg, cond, 1);
|
||||
|
||||
struct TestData {
|
||||
uint32 bit32;
|
||||
uint16 bit16;
|
||||
uint8 bit8[2];
|
||||
} input = { 0xdeadbeef, 0xcafe, {0xba, 0xbe} }, output = {0, 0, {0, 0} };
|
||||
|
||||
void
|
||||
dump_struct(char *label, struct TestData *str)
|
||||
{
|
||||
printf("%s: {%#08x, %#04x, {%#02x, %#02x}\n", label,
|
||||
str->bit32, str->bit16, str->bit8[0], str->bit8[1]);
|
||||
}
|
||||
|
||||
PRBool
|
||||
XDR(XPTCursor *cursor, struct TestData *str)
|
||||
{
|
||||
TRY("Do32", XPT_Do32(cursor, &str->bit32));
|
||||
TRY("Do16", XPT_Do16(cursor, &str->bit16));
|
||||
TRY("Do8", XPT_Do8 (cursor, &str->bit8[0]));
|
||||
TRY("Do8", XPT_Do8 (cursor, &str->bit8[1]));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
XPTState *state;
|
||||
XPTCursor curs, *cursor = &curs;
|
||||
char *data, *data2;
|
||||
uint32 len = 0, i;
|
||||
|
||||
TRY("NewState (ENCODE)", (state = XPT_NewXDRState(XPT_ENCODE, NULL, 0)));
|
||||
|
||||
XPT_SetDataOffset(state, 1024);
|
||||
|
||||
TRY("MakeCursor", XPT_MakeCursor(state, XPT_HEADER, cursor));
|
||||
|
||||
dump_struct("before", &input);
|
||||
|
||||
if (XDR(cursor, &input))
|
||||
return 1;
|
||||
|
||||
XPT_GetXDRData(state, XPT_HEADER, &data, &len);
|
||||
printf("XDR data %d bytes (really %d) at %p: ", len, sizeof input, data);
|
||||
for (i = 0; i < sizeof input / 4; i++)
|
||||
printf("%08x,", ((uint32 *)&input)[i]);
|
||||
printf("\n");
|
||||
|
||||
data2 = malloc(len);
|
||||
if (!data2) {
|
||||
printf("what the fuck?\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* TRY_Q("malloc", (data2 = malloc(len))); */
|
||||
memcpy(data2, data, len);
|
||||
XPT_DestroyXDRState(state);
|
||||
|
||||
TRY("NewState (DECODE)", (state = XPT_NewXDRState(XPT_DECODE, data, len)));
|
||||
|
||||
XPT_SetDataOffset(state, 1024);
|
||||
if (XDR(cursor, &output))
|
||||
return 1;
|
||||
|
||||
dump_struct("after", &output);
|
||||
XPT_DestroyXDRState(state);
|
||||
|
||||
return 0;
|
||||
}
|
||||
28
mozilla/xpcom/typelib/xpt/Makefile.in
Normal file
28
mozilla/xpcom/typelib/xpt/Makefile.in
Normal file
@ -0,0 +1,28 @@
|
||||
#!gmake
|
||||
# The contents of this file are subject to the Netscape Public License
|
||||
# Version 1.0 (the "NPL"); you may not use this file except in
|
||||
# compliance with the NPL. You may obtain a copy of the NPL at
|
||||
# http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
# for the specific language governing rights and limitations under the
|
||||
# NPL.
|
||||
#
|
||||
# The Initial Developer of this code under the NPL is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
# Reserved.
|
||||
|
||||
DEPTH = ../..
|
||||
topsrcdir = @top_srcdir@
|
||||
VPATH = @srcdir@
|
||||
srcdir = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
DIRS = public src
|
||||
|
||||
DIRS += tests
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
@ -25,6 +25,7 @@
|
||||
|
||||
#include <nspr.h>
|
||||
#include <plhash.h>
|
||||
#include <prmem.h>
|
||||
#include "xpt_struct.h"
|
||||
|
||||
typedef struct XPTState XPTState;
|
||||
@ -40,6 +41,9 @@ XPT_DoIdentifier(XPTCursor *cursor, char **identp);
|
||||
PRBool
|
||||
XPT_DoIID(XPTCursor *cursor, nsID *iidp);
|
||||
|
||||
PRBool
|
||||
XPT_Do64(XPTCursor *cursor, PRInt64 *u64p);
|
||||
|
||||
PRBool
|
||||
XPT_Do32(XPTCursor *cursor, uint32 *u32p);
|
||||
|
||||
@ -62,6 +66,8 @@ XPT_Do8(XPTCursor *cursor, uint8 *u8p);
|
||||
PRBool
|
||||
XPT_DoBits(XPTCursor *cursor, uint8 *u8p, int nbits);
|
||||
|
||||
#define XPT_DO_BITS(curs, field, width, scr) (PR_TRUE)
|
||||
|
||||
/* returns the number of bits skipped, which should be 0-7 */
|
||||
int
|
||||
XPT_FlushBits(XPTCursor *cursor);
|
||||
@ -78,52 +84,45 @@ typedef enum {
|
||||
|
||||
struct XPTState {
|
||||
XPTMode mode;
|
||||
XPTDatapool *pools[2];
|
||||
uint32 data_offset;
|
||||
XPTDatapool *pool;
|
||||
};
|
||||
|
||||
struct XPTDatapool {
|
||||
PLHashTable *offset_map;
|
||||
char *data;
|
||||
uint32 count;
|
||||
uint8 bit;
|
||||
uint32 allocated;
|
||||
};
|
||||
|
||||
struct XPTCursor {
|
||||
XPTState *state;
|
||||
XPTDatapool *pool;
|
||||
XPTPool pool;
|
||||
uint32 offset;
|
||||
uint32 len;
|
||||
uint8 bits;
|
||||
};
|
||||
|
||||
XPTState *
|
||||
XPT_NewXDRState(XPTMode mode, char *data, uint32 len);
|
||||
|
||||
PRBool
|
||||
XPT_MakeCursor(XPTState *state, XPTPool pool, XPTCursor *cursor);
|
||||
|
||||
void
|
||||
XPT_DestroyXDRState(XPTState *state);
|
||||
|
||||
void
|
||||
XPT_GetXDRData(XPTState *state, XPTPool pool, char **data, uint32 *len);
|
||||
|
||||
/*
|
||||
* On CreateCursor:
|
||||
* cursors are used to track position within the byte stream.
|
||||
* In encode/write mode, the cursor reserves an area of memory for a structure.
|
||||
* In decode/read mode, it simply tracks position.
|
||||
*
|
||||
* Usage will commonly be something like this (taken from XPT_DoString) for
|
||||
* out-of-line structures:
|
||||
*
|
||||
* // create my_cursor and reserve memory as required
|
||||
* XPT_CreateCursor(parent_cursor, XPT_DATA, str->length + 2, &my_cursor);
|
||||
* // write mode: store the offset for this structure in the parent cursor
|
||||
* // read mode: adjust my_cursor to point to the write offset
|
||||
* XPT_Do32(parent_cursor, &my_cursor->offset);
|
||||
*/
|
||||
/* set or get the data offset for the state, depending on mode */
|
||||
void
|
||||
XPT_DataOffset(XPTState *state, uint32 *data_offsetp);
|
||||
|
||||
void
|
||||
XPT_SetDataOffset(XPTState *state, uint32 data_offset);
|
||||
|
||||
PRBool
|
||||
XPT_CreateCursor(XPTCursor *base, XPTPool pool, uint32 len, XPTCursor *cursor);
|
||||
XPT_MakeCursor(XPTState *state, XPTPool pool, XPTCursor *cursor);
|
||||
|
||||
/* all data structures are big-endian */
|
||||
|
||||
@ -188,7 +187,7 @@ XPT_CreateCursor(XPTCursor *base, XPTPool pool, uint32 len, XPTCursor *cursor);
|
||||
#define XPT_ERROR_HANDLE(free_it) \
|
||||
error: \
|
||||
if (cursor->state->mode == XPT_DECODE) \
|
||||
PR_FREE_IF(free_it); \
|
||||
PR_FREEIF(free_it); \
|
||||
return PR_FALSE;
|
||||
|
||||
|
||||
|
||||
@ -19,81 +19,137 @@
|
||||
/* Implementation of XDR primitives. */
|
||||
|
||||
#include "xpt_xdr.h"
|
||||
#include <nspr.h>
|
||||
#include <string.h> /* strchr */
|
||||
|
||||
#define CHECK_COUNT(cursor) \
|
||||
((cursor)->offset == (cursor)->pool->allocated ? \
|
||||
((cursor)->state->mode == XPT_ENCODE ? XPT_GrowPool((cursor)->pool) : \
|
||||
PR_FALSE) : PR_TRUE)
|
||||
#define ENCODING(cursor) \
|
||||
((cursor)->state->mode == XPT_ENCODE)
|
||||
|
||||
#define CURS_POOL_OFFSET(cursor) \
|
||||
((cursor)->pool == XPT_HEADER \
|
||||
? (cursor)->offset \
|
||||
: (PR_ASSERT((cursor)->state->data_offset), \
|
||||
(cursor)->offset + (cursor)->state->data_offset))
|
||||
|
||||
/* can be used as lvalue */
|
||||
#define CURS_POINT(cursor) \
|
||||
(cursor)->state->pool->data[CURS_POOL_OFFSET(cursor)]
|
||||
|
||||
#define CHECK_COUNT(cursor, space) \
|
||||
/* if we're in the header, then exceeding the data_offset is illegal */ \
|
||||
((cursor)->pool == XPT_HEADER ? \
|
||||
((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) ? XPT_GrowPool((cursor)->state->pool) \
|
||||
/* and fail if we're in DECODE mode */ \
|
||||
: PR_FALSE) \
|
||||
/* otherwise we're OK */ \
|
||||
: PR_TRUE))
|
||||
|
||||
/* increase the data allocation for the pool by XPT_GROW_CHUNK */
|
||||
#define XPT_GROW_CHUNK 8192
|
||||
|
||||
static PLHashNumber
|
||||
null_hash(const void *key)
|
||||
{
|
||||
return (PLHashNumber)key;
|
||||
}
|
||||
|
||||
XPTState *
|
||||
XPT_NewXDRState(XPTMode mode, char *data, uint32 len)
|
||||
{
|
||||
#if 0 /* need to rethink pool management */
|
||||
XPTState *state;
|
||||
int i;
|
||||
|
||||
state = PR_NEW(XPTState);
|
||||
|
||||
if (!state)
|
||||
return NULL;
|
||||
|
||||
state->mode = mode;
|
||||
for (i = 0; i < 2; i++) {
|
||||
state->pools[i] = PR_NEW(XPTDatapool);
|
||||
if (!state->pools[i]) {
|
||||
if (i) {
|
||||
PR_FREE(state->pools[0]->data);
|
||||
PR_FREE(state->pools[0]);
|
||||
}
|
||||
PR_FREE(state);
|
||||
return NULL;
|
||||
}
|
||||
state->pools[i]->count = 0;
|
||||
state->pools[i]->bit = 0;
|
||||
if (mode == XPT_DECODE) {
|
||||
state->pools[i]->data = data;
|
||||
state->pools[i]->allocated = len;
|
||||
} else {
|
||||
state->pools[i]->data = PR_MALLOC(XPT_GROW_CHUNK);
|
||||
if (!state->pools[i]->data) {
|
||||
PR_FREE(state->pools[i]);
|
||||
if (i) {
|
||||
PR_FREE(state->pools[0]->data);
|
||||
PR_FREE(state->pools[0]);
|
||||
}
|
||||
PR_FREE(state);
|
||||
return NULL;
|
||||
}
|
||||
state->pools[i]->allocated = XPT_GROW_CHUNK;
|
||||
}
|
||||
state->pool = PR_NEW(XPTDatapool);
|
||||
if (!state->pool)
|
||||
goto err_free_state;
|
||||
|
||||
state->pool->count = 0;
|
||||
state->pool->offset_map = PL_NewHashTable(32, null_hash, PL_CompareValues,
|
||||
PL_CompareValues, NULL, NULL);
|
||||
|
||||
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 = PR_MALLOC(XPT_GROW_CHUNK);
|
||||
if (!state->pool->data)
|
||||
goto err_free_hash;
|
||||
state->pool->allocated = XPT_GROW_CHUNK;
|
||||
}
|
||||
#endif
|
||||
|
||||
return state;
|
||||
|
||||
err_free_hash:
|
||||
PL_HashTableDestroy(state->pool->offset_map);
|
||||
err_free_pool:
|
||||
PR_DELETE(state->pool);
|
||||
err_free_state:
|
||||
PR_DELETE(state);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
XPT_DestroyXDRState(XPTState *state)
|
||||
{
|
||||
#if 0 /* need to rethink pool management */
|
||||
int i;
|
||||
if (state->mode == XPT_ENCODE) {
|
||||
PR_FREE_IF(state->pool->data);
|
||||
PR_FREE(state->pool);
|
||||
PR_FREE(state);
|
||||
} else {
|
||||
PR_FREE(state->pool);
|
||||
PR_FREE(state);
|
||||
}
|
||||
#endif
|
||||
if (state->mode == XPT_ENCODE)
|
||||
PR_DELETE(state->pool->data);
|
||||
PR_DELETE(state->pool);
|
||||
PR_DELETE(state);
|
||||
}
|
||||
|
||||
void
|
||||
XPT_GetXDRData(XPTState *state, XPTPool pool, char **data, uint32 *len)
|
||||
{
|
||||
*data = state->pools[pool]->data;
|
||||
*len = state->pools[pool]->count;
|
||||
if (pool == XPT_HEADER) {
|
||||
*data = state->pool->data;
|
||||
*len = state->data_offset;
|
||||
} else {
|
||||
*data = state->pool->data + state->data_offset;
|
||||
*len = state->pool->count - state->data_offset;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
XPT_DataOffset(XPTState *state, uint32 *data_offsetp)
|
||||
{
|
||||
if (state->mode == XPT_DECODE)
|
||||
state->data_offset = *data_offsetp;
|
||||
else
|
||||
*data_offsetp = state->data_offset;
|
||||
}
|
||||
|
||||
void
|
||||
XPT_SetDataOffset(XPTState *state, uint32 data_offset)
|
||||
{
|
||||
state->data_offset = data_offset;
|
||||
}
|
||||
|
||||
PRBool
|
||||
XPT_MakeCursor(XPTState *state, XPTPool pool, XPTCursor *cursor)
|
||||
{
|
||||
cursor->state = state;
|
||||
cursor->pool = pool;
|
||||
cursor->bits = 0;
|
||||
if (pool == XPT_DATA) {
|
||||
if (!state->data_offset)
|
||||
return PR_FALSE;
|
||||
cursor->offset = state->data_offset;
|
||||
} else {
|
||||
cursor->offset = 0;
|
||||
}
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
static PRBool
|
||||
@ -142,7 +198,7 @@ XPT_DoCString(XPTCursor *cursor, char **identp)
|
||||
my_cursor, already);
|
||||
|
||||
if (mode == XPT_DECODE) {
|
||||
char *start = &my_cursor.pool->data[my_cursor.offset], *end;
|
||||
char *start = &CURS_POINT(&my_cursor), *end;
|
||||
int len;
|
||||
|
||||
end = strchr(start, 0); /* find the end of the string */
|
||||
@ -161,7 +217,7 @@ XPT_DoCString(XPTCursor *cursor, char **identp)
|
||||
*identp = ident;
|
||||
|
||||
if (!XPT_SetAddrForOffset(&my_cursor, my_cursor.offset, ident)) {
|
||||
PR_FREE(ident);
|
||||
PR_DELETE(ident);
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
@ -179,26 +235,28 @@ XPT_DoCString(XPTCursor *cursor, char **identp)
|
||||
uint32
|
||||
XPT_GetOffsetForAddr(XPTCursor *cursor, void *addr)
|
||||
{
|
||||
return 0;
|
||||
return (uint32)PL_HashTableLookup(cursor->state->pool->offset_map, addr);
|
||||
}
|
||||
|
||||
PRBool
|
||||
XPT_SetOffsetForAddr(XPTCursor *cursor, void **addr, uint32 offset)
|
||||
XPT_SetOffsetForAddr(XPTCursor *cursor, void *addr, uint32 offset)
|
||||
{
|
||||
*addr = NULL;
|
||||
return PR_FALSE;
|
||||
return PL_HashTableAdd(cursor->state->pool->offset_map,
|
||||
addr, (void *)offset) != NULL;
|
||||
}
|
||||
|
||||
PRBool
|
||||
XPT_SetAddrForOffset(XPTCursor *cursor, void *addr)
|
||||
{
|
||||
return PR_FALSE;
|
||||
return PL_HashTableAdd(cursor->state->pool->offset_map,
|
||||
(void *)cursor->offset, addr) != NULL;
|
||||
}
|
||||
|
||||
void *
|
||||
XPT_GetAddrForOffset(XPTCursor *cursor)
|
||||
{
|
||||
return PR_FALSE;
|
||||
return PL_HashTableLookup(cursor->state->pool->offset_map,
|
||||
(void *)cursor->offset);
|
||||
}
|
||||
|
||||
PRBool
|
||||
@ -209,7 +267,8 @@ XPT_CheckForRepeat(XPTCursor *cursor, void **addrp, XPTPool pool, int len,
|
||||
|
||||
*already = PR_FALSE;
|
||||
new_cursor->state = cursor->state;
|
||||
new_cursor->pool = cursor->state->pools[pool];
|
||||
new_cursor->pool = pool;
|
||||
new_cursor->bits = 0;
|
||||
|
||||
if (cursor->state->mode = XPT_DECODE) {
|
||||
|
||||
@ -256,27 +315,85 @@ XPT_DoIID(XPTCursor *cursor, nsID *iidp)
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
XPT_Do64(XPTCursor *cursor, PRInt64 *u64p)
|
||||
{
|
||||
return XPT_Do32(cursor, (uint32 *)u64p) &&
|
||||
XPT_Do32(cursor, ((uint32 *)u64p) + 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* When we're writing 32- or 16-bit quantities, we write a byte at a time to
|
||||
* avoid alignment issues. Someone could come and optimize this to detect
|
||||
* well-aligned cases and do a single store, if they cared. I might care
|
||||
* later.
|
||||
*/
|
||||
PRBool
|
||||
XPT_Do32(XPTCursor *cursor, uint32 *u32p)
|
||||
{
|
||||
return PR_FALSE;
|
||||
if (!CHECK_COUNT(cursor, 4))
|
||||
return PR_FALSE;
|
||||
if (ENCODING(cursor)) {
|
||||
CURS_POINT(cursor) = ((uint8 *)(u32p))[0];
|
||||
cursor->offset++;
|
||||
CURS_POINT(cursor) = ((uint8 *)(u32p))[1];
|
||||
cursor->offset++;
|
||||
CURS_POINT(cursor) = ((uint8 *)(u32p))[2];
|
||||
cursor->offset++;
|
||||
CURS_POINT(cursor) = ((uint8 *)(u32p))[3];
|
||||
} else {
|
||||
((uint8 *)(u32p))[0] = CURS_POINT(cursor);
|
||||
cursor->offset++;
|
||||
((uint8 *)(u32p))[1] = CURS_POINT(cursor);
|
||||
cursor->offset++;
|
||||
((uint8 *)(u32p))[2] = CURS_POINT(cursor);
|
||||
cursor->offset++;
|
||||
((uint8 *)(u32p))[3] = CURS_POINT(cursor);
|
||||
}
|
||||
cursor->offset++;
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
XPT_Do16(XPTCursor *cursor, uint16 *u16p)
|
||||
{
|
||||
return PR_FALSE;
|
||||
if (!CHECK_COUNT(cursor, 2))
|
||||
return PR_FALSE;
|
||||
if (ENCODING(cursor)) {
|
||||
CURS_POINT(cursor) = ((uint8 *)(u16p))[0];
|
||||
cursor->offset++;
|
||||
CURS_POINT(cursor) = ((uint8 *)(u16p))[1];
|
||||
} else {
|
||||
((uint8 *)(u16p))[0] = CURS_POINT(cursor);
|
||||
cursor->offset++;
|
||||
((uint8 *)(u16p))[1] = CURS_POINT(cursor);
|
||||
}
|
||||
cursor->offset++;
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
XPT_Do8(XPTCursor *cursor, uint8 *u8p)
|
||||
{
|
||||
return PR_FALSE;
|
||||
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;
|
||||
}
|
||||
|
||||
static PRBool
|
||||
do_bit(XPTCursor *cursor, uint8 *u8p, int bitno)
|
||||
{
|
||||
return PR_FALSE;
|
||||
#if 0
|
||||
int bit_value, delta, new_value;
|
||||
XPTDatapool *pool = cursor->pool;
|
||||
|
||||
@ -297,6 +414,7 @@ do_bit(XPTCursor *cursor, uint8 *u8p, int bitno)
|
||||
}
|
||||
|
||||
return CHECK_COUNT(cursor);
|
||||
#endif
|
||||
}
|
||||
|
||||
PRBool
|
||||
@ -335,6 +453,8 @@ XPT_FlushBits(XPTCursor *cursor)
|
||||
{
|
||||
int skipped = 8 - cursor->bits;
|
||||
|
||||
return 0;
|
||||
#if 0
|
||||
cursor->bits = 0;
|
||||
cursor->offset++;
|
||||
|
||||
@ -342,4 +462,5 @@ XPT_FlushBits(XPTCursor *cursor)
|
||||
return -1;
|
||||
|
||||
return skipped == 8 ? 0 : skipped;
|
||||
#endif
|
||||
}
|
||||
|
||||
42
mozilla/xpcom/typelib/xpt/tests/Makefile.in
Normal file
42
mozilla/xpcom/typelib/xpt/tests/Makefile.in
Normal file
@ -0,0 +1,42 @@
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public License
|
||||
# Version 1.0 (the "NPL"); you may not use this file except in
|
||||
# compliance with the NPL. You may obtain a copy of the NPL at
|
||||
# http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
# for the specific language governing rights and limitations under the
|
||||
# NPL.
|
||||
#
|
||||
# The Initial Developer of this code under the NPL is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
# Reserved.
|
||||
|
||||
DEPTH = ../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE = libxpt
|
||||
|
||||
CSRCS = PrimitiveTest.c
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
EX_LIBS = $(DIST)/lib/libxpt.$(LIB_SUFFIX) \
|
||||
$(NULL)
|
||||
|
||||
PROGS = $(addprefix $(OBJDIR)/, $(CSRCS:.c=))
|
||||
|
||||
TARGETS = $(PROGS)
|
||||
|
||||
$(PROGS):$(OBJDIR)/%: $(OBJDIR)/%.o $(EX_LIBS)
|
||||
@$(MAKE_OBJDIR)
|
||||
$(CC) -o $@ $@.o $(LDFLAGS) $(EX_LIBS) $(NSPR_LIBS) $(OS_LIBS)
|
||||
|
||||
install:: $(PROGS)
|
||||
$(INSTALL) $(PROGS) $(DIST)/bin
|
||||
109
mozilla/xpcom/typelib/xpt/tests/PrimitiveTest.c
Normal file
109
mozilla/xpcom/typelib/xpt/tests/PrimitiveTest.c
Normal file
@ -0,0 +1,109 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/* Test the xdr primitives from xpt_xdr.c */
|
||||
|
||||
#include "xpt_xdr.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#define PASS(msg) \
|
||||
printf("PASSED : %s\n", msg);
|
||||
|
||||
#define FAIL(msg) \
|
||||
fprintf(stderr, "FAILURE: %s\n", msg);
|
||||
|
||||
#define TRY_(msg, cond, silent) \
|
||||
if ((cond) && !silent) { \
|
||||
PASS(msg); \
|
||||
} else { \
|
||||
FAIL(msg); \
|
||||
return 1; \
|
||||
}
|
||||
|
||||
#define TRY(msg, cond) TRY_(msg, cond, 0)
|
||||
#define TRY_Q(msg, cond) TRY_(msg, cond, 1);
|
||||
|
||||
struct TestData {
|
||||
uint32 bit32;
|
||||
uint16 bit16;
|
||||
uint8 bit8[2];
|
||||
} input = { 0xdeadbeef, 0xcafe, {0xba, 0xbe} }, output = {0, 0, {0, 0} };
|
||||
|
||||
void
|
||||
dump_struct(char *label, struct TestData *str)
|
||||
{
|
||||
printf("%s: {%#08x, %#04x, {%#02x, %#02x}\n", label,
|
||||
str->bit32, str->bit16, str->bit8[0], str->bit8[1]);
|
||||
}
|
||||
|
||||
PRBool
|
||||
XDR(XPTCursor *cursor, struct TestData *str)
|
||||
{
|
||||
TRY("Do32", XPT_Do32(cursor, &str->bit32));
|
||||
TRY("Do16", XPT_Do16(cursor, &str->bit16));
|
||||
TRY("Do8", XPT_Do8 (cursor, &str->bit8[0]));
|
||||
TRY("Do8", XPT_Do8 (cursor, &str->bit8[1]));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
XPTState *state;
|
||||
XPTCursor curs, *cursor = &curs;
|
||||
char *data, *data2;
|
||||
uint32 len = 0, i;
|
||||
|
||||
TRY("NewState (ENCODE)", (state = XPT_NewXDRState(XPT_ENCODE, NULL, 0)));
|
||||
|
||||
XPT_SetDataOffset(state, 1024);
|
||||
|
||||
TRY("MakeCursor", XPT_MakeCursor(state, XPT_HEADER, cursor));
|
||||
|
||||
dump_struct("before", &input);
|
||||
|
||||
if (XDR(cursor, &input))
|
||||
return 1;
|
||||
|
||||
XPT_GetXDRData(state, XPT_HEADER, &data, &len);
|
||||
printf("XDR data %d bytes (really %d) at %p: ", len, sizeof input, data);
|
||||
for (i = 0; i < sizeof input / 4; i++)
|
||||
printf("%08x,", ((uint32 *)&input)[i]);
|
||||
printf("\n");
|
||||
|
||||
data2 = malloc(len);
|
||||
if (!data2) {
|
||||
printf("what the fuck?\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* TRY_Q("malloc", (data2 = malloc(len))); */
|
||||
memcpy(data2, data, len);
|
||||
XPT_DestroyXDRState(state);
|
||||
|
||||
TRY("NewState (DECODE)", (state = XPT_NewXDRState(XPT_DECODE, data, len)));
|
||||
|
||||
XPT_SetDataOffset(state, 1024);
|
||||
if (XDR(cursor, &output))
|
||||
return 1;
|
||||
|
||||
dump_struct("after", &output);
|
||||
XPT_DestroyXDRState(state);
|
||||
|
||||
return 0;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user