jsxdrapi.c
来自「一个基于alice开发的机器人」· C语言 代码 · 共 691 行 · 第 1/2 页
C
691 行
if (xdr->mode == JSXDR_ENCODE) {
if (!xdr->ops->setbytes(xdr, bytes, len))
return JS_FALSE;
} else {
if (!xdr->ops->getbytes(xdr, bytes, len))
return JS_FALSE;
}
len = xdr->ops->tell(xdr);
if (len % JSXDR_ALIGN) {
padlen = JSXDR_ALIGN - (len % JSXDR_ALIGN);
if (xdr->mode == JSXDR_ENCODE) {
if (!xdr->ops->setbytes(xdr, padbuf, padlen))
return JS_FALSE;
} else {
if (!xdr->ops->seek(xdr, padlen, JSXDR_SEEK_CUR))
return JS_FALSE;
}
}
return JS_TRUE;
}
/**
* Convert between a C string and the XDR representation:
* leading 32-bit count, then counted vector of chars,
* then possibly \0 padding to multiple of 4.
*/
JS_PUBLIC_API(JSBool)
JS_XDRCString(JSXDRState *xdr, char **sp)
{
uint32 len;
if (xdr->mode == JSXDR_ENCODE)
len = strlen(*sp);
JS_XDRUint32(xdr, &len);
if (xdr->mode == JSXDR_DECODE) {
if (!(*sp = (char *) JS_malloc(xdr->cx, len + 1)))
return JS_FALSE;
}
if (!JS_XDRBytes(xdr, *sp, len)) {
if (xdr->mode == JSXDR_DECODE)
JS_free(xdr->cx, *sp);
return JS_FALSE;
}
if (xdr->mode == JSXDR_DECODE) {
(*sp)[len] = '\0';
} else if (xdr->mode == JSXDR_FREE) {
JS_free(xdr->cx, *sp);
*sp = NULL;
}
return JS_TRUE;
}
JS_PUBLIC_API(JSBool)
JS_XDRCStringOrNull(JSXDRState *xdr, char **sp)
{
uint32 null = (*sp == NULL);
if (!JS_XDRUint32(xdr, &null))
return JS_FALSE;
if (null) {
*sp = NULL;
return JS_TRUE;
}
return JS_XDRCString(xdr, sp);
}
/*
* Convert between a JS (Unicode) string and the XDR representation.
*/
JS_PUBLIC_API(JSBool)
JS_XDRString(JSXDRState *xdr, JSString **strp)
{
uint32 i, len, padlen, nbytes;
jschar *chars = NULL, *raw;
if (xdr->mode == JSXDR_ENCODE)
len = JSSTRING_LENGTH(*strp);
if (!JS_XDRUint32(xdr, &len))
return JS_FALSE;
nbytes = len * sizeof(jschar);
if (xdr->mode == JSXDR_DECODE) {
if (!(chars = (jschar *) JS_malloc(xdr->cx, nbytes + sizeof(jschar))))
return JS_FALSE;
} else {
chars = JSSTRING_CHARS(*strp);
}
padlen = nbytes % JSXDR_ALIGN;
if (padlen) {
padlen = JSXDR_ALIGN - padlen;
nbytes += padlen;
}
if (!(raw = (jschar *) xdr->ops->raw(xdr, nbytes)))
goto bad;
if (xdr->mode == JSXDR_ENCODE) {
for (i = 0; i < len; i++)
raw[i] = JSXDR_SWAB16(chars[i]);
if (padlen)
memset((char *)raw + nbytes - padlen, 0, padlen);
} else if (xdr->mode == JSXDR_DECODE) {
for (i = 0; i < len; i++)
chars[i] = JSXDR_SWAB16(raw[i]);
chars[len] = 0;
if (!(*strp = JS_NewUCString(xdr->cx, chars, len)))
goto bad;
}
return JS_TRUE;
bad:
if (xdr->mode == JSXDR_DECODE)
JS_free(xdr->cx, chars);
return JS_FALSE;
}
JS_PUBLIC_API(JSBool)
JS_XDRStringOrNull(JSXDRState *xdr, JSString **strp)
{
uint32 null = (*strp == NULL);
if (!JS_XDRUint32(xdr, &null))
return JS_FALSE;
if (null) {
*strp = NULL;
return JS_TRUE;
}
return JS_XDRString(xdr, strp);
}
JS_PUBLIC_API(JSBool)
JS_XDRDouble(JSXDRState *xdr, jsdouble **dp)
{
jsdouble d;
if (xdr->mode == JSXDR_ENCODE)
d = **dp;
#if IS_BIG_ENDIAN
if (!JS_XDRUint32(xdr, (uint32 *)&d + 1) ||
!JS_XDRUint32(xdr, (uint32 *)&d))
#else
if (!JS_XDRUint32(xdr, (uint32 *)&d) ||
!JS_XDRUint32(xdr, (uint32 *)&d + 1))
#endif
return JS_FALSE;
if (xdr->mode == JSXDR_DECODE) {
*dp = JS_NewDouble(xdr->cx, d);
if (!*dp)
return JS_FALSE;
}
return JS_TRUE;
}
/* These are magic pseudo-tags: see jsapi.h, near the top, for real tags. */
#define JSVAL_XDRNULL 0x8
#define JSVAL_XDRVOID 0xA
JS_PUBLIC_API(JSBool)
JS_XDRValue(JSXDRState *xdr, jsval *vp)
{
uint32 type;
if (xdr->mode == JSXDR_ENCODE) {
if (JSVAL_IS_NULL(*vp))
type = JSVAL_XDRNULL;
else if (JSVAL_IS_VOID(*vp))
type = JSVAL_XDRVOID;
else
type = JSVAL_TAG(*vp);
}
if (!JS_XDRUint32(xdr, &type))
return JS_FALSE;
switch (type) {
case JSVAL_XDRNULL:
*vp = JSVAL_NULL;
break;
case JSVAL_XDRVOID:
*vp = JSVAL_VOID;
break;
case JSVAL_STRING: {
JSString *str;
if (xdr->mode == JSXDR_ENCODE)
str = JSVAL_TO_STRING(*vp);
if (!JS_XDRString(xdr, &str))
return JS_FALSE;
if (xdr->mode == JSXDR_DECODE)
*vp = STRING_TO_JSVAL(str);
break;
}
case JSVAL_DOUBLE: {
jsdouble *dp;
if (xdr->mode == JSXDR_ENCODE)
dp = JSVAL_TO_DOUBLE(*vp);
if (!JS_XDRDouble(xdr, &dp))
return JS_FALSE;
if (xdr->mode == JSXDR_DECODE)
*vp = DOUBLE_TO_JSVAL(dp);
break;
}
case JSVAL_OBJECT: {
JSObject *obj;
if (xdr->mode == JSXDR_ENCODE)
obj = JSVAL_TO_OBJECT(*vp);
if (!js_XDRObject(xdr, &obj))
return JS_FALSE;
if (xdr->mode == JSXDR_DECODE)
*vp = OBJECT_TO_JSVAL(obj);
break;
}
case JSVAL_BOOLEAN: {
uint32 b;
if (xdr->mode == JSXDR_ENCODE)
b = (uint32) JSVAL_TO_BOOLEAN(*vp);
if (!JS_XDRUint32(xdr, &b))
return JS_FALSE;
if (xdr->mode == JSXDR_DECODE)
*vp = BOOLEAN_TO_JSVAL((JSBool) b);
break;
}
default: {
uint32 i;
JS_ASSERT(type & JSVAL_INT);
if (xdr->mode == JSXDR_ENCODE)
i = (uint32) JSVAL_TO_INT(*vp);
if (!JS_XDRUint32(xdr, &i))
return JS_FALSE;
if (xdr->mode == JSXDR_DECODE)
*vp = INT_TO_JSVAL((int32) i);
break;
}
}
return JS_TRUE;
}
JS_PUBLIC_API(JSBool)
JS_XDRScript(JSXDRState *xdr, JSScript **scriptp)
{
if (!js_XDRScript(xdr, scriptp, NULL))
return JS_FALSE;
if (xdr->mode == JSXDR_DECODE)
js_CallNewScriptHook(xdr->cx, *scriptp, NULL);
return JS_TRUE;
}
#define CLASS_REGISTRY_MIN 8
#define CLASS_INDEX_TO_ID(i) ((i)+1)
#define CLASS_ID_TO_INDEX(id) ((id)-1)
typedef struct JSRegHashEntry {
JSDHashEntryHdr hdr;
const char *name;
uint32 index;
} JSRegHashEntry;
JS_PUBLIC_API(JSBool)
JS_XDRRegisterClass(JSXDRState *xdr, JSClass *clasp, uint32 *idp)
{
uintN numclasses, maxclasses;
JSClass **registry;
numclasses = xdr->numclasses;
maxclasses = xdr->maxclasses;
if (numclasses == maxclasses) {
maxclasses = (maxclasses == 0) ? CLASS_REGISTRY_MIN : maxclasses << 1;
registry = (JSClass **)
JS_realloc(xdr->cx, xdr->registry, maxclasses * sizeof(JSClass *));
if (!registry)
return JS_FALSE;
xdr->registry = registry;
xdr->maxclasses = maxclasses;
} else {
JS_ASSERT(numclasses && numclasses < maxclasses);
registry = xdr->registry;
}
registry[numclasses] = clasp;
if (xdr->reghash) {
JSRegHashEntry *entry = (JSRegHashEntry *)
JS_DHashTableOperate(xdr->reghash, clasp->name, JS_DHASH_ADD);
if (!entry) {
JS_ReportOutOfMemory(xdr->cx);
return JS_FALSE;
}
entry->name = clasp->name;
entry->index = numclasses;
}
*idp = CLASS_INDEX_TO_ID(numclasses);
xdr->numclasses = ++numclasses;
return JS_TRUE;
}
JS_PUBLIC_API(uint32)
JS_XDRFindClassIdByName(JSXDRState *xdr, const char *name)
{
uintN i, numclasses;
numclasses = xdr->numclasses;
if (numclasses >= 10) {
JSRegHashEntry *entry;
/* Bootstrap reghash from registry on first overpopulated Find. */
if (!xdr->reghash) {
xdr->reghash = JS_NewDHashTable(JS_DHashGetStubOps(), NULL,
sizeof(JSRegHashEntry),
numclasses);
if (xdr->reghash) {
for (i = 0; i < numclasses; i++) {
JSClass *clasp = xdr->registry[i];
entry = (JSRegHashEntry *)
JS_DHashTableOperate(xdr->reghash, clasp->name,
JS_DHASH_ADD);
entry->name = clasp->name;
entry->index = i;
}
}
}
/* If we managed to create reghash, use it for O(1) Find. */
if (xdr->reghash) {
entry = (JSRegHashEntry *)
JS_DHashTableOperate(xdr->reghash, name, JS_DHASH_LOOKUP);
if (JS_DHASH_ENTRY_IS_BUSY(&entry->hdr))
return CLASS_INDEX_TO_ID(entry->index);
}
}
/* Only a few classes, or we couldn't malloc reghash: use linear search. */
for (i = 0; i < numclasses; i++) {
if (!strcmp(name, xdr->registry[i]->name))
return CLASS_INDEX_TO_ID(i);
}
return 0;
}
JS_PUBLIC_API(JSClass *)
JS_XDRFindClassById(JSXDRState *xdr, uint32 id)
{
uintN i = CLASS_ID_TO_INDEX(id);
if (i >= xdr->numclasses)
return NULL;
return xdr->registry[i];
}
#endif /* JS_HAS_XDR */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?