📄 jsxdrapi.c
字号:
uint32 padlen; static char padbuf[JSXDR_ALIGN-1]; 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){ jsdpun u; if (xdr->mode == JSXDR_ENCODE) u.d = **dp; if (!JS_XDRUint32(xdr, &u.s.lo) || !JS_XDRUint32(xdr, &u.s.hi)) return JS_FALSE; if (xdr->mode == JSXDR_DECODE) { *dp = JS_NewDouble(xdr->cx, u.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 0xAJS_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 + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -