📄 jsxml.c
字号:
qn2 = (JSXMLQName *) JS_GetPrivate(cx, obj2); *bp = qname_identity(qn, qn2); } return JS_TRUE;}JS_FRIEND_DATA(JSExtendedClass) js_QNameClass = { { "QName", JSCLASS_HAS_PRIVATE | JSCLASS_CONSTRUCT_PROTOTYPE | JSCLASS_IS_EXTENDED | JSCLASS_HAS_CACHED_PROTO(JSProto_QName), JS_PropertyStub, JS_PropertyStub, qname_getProperty, NULL, JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, qname_finalize, NULL, NULL, NULL, NULL, NULL, NULL, qname_mark, NULL }, qname_equality, NULL, NULL, NULL, NULL, NULL, NULL, NULL};/* * Classes for the ECMA-357-internal types AttributeName and AnyName, which * are like QName, except that they have no property getters. They share the * qname_toString method, and therefore are exposed as constructable objects * in this implementation. */JS_FRIEND_DATA(JSClass) js_AttributeNameClass = { js_AttributeName_str, JSCLASS_HAS_PRIVATE | JSCLASS_CONSTRUCT_PROTOTYPE | JSCLASS_HAS_CACHED_PROTO(JSProto_AttributeName), JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, qname_finalize, NULL, NULL, NULL, NULL, NULL, NULL, qname_mark, NULL};JS_FRIEND_DATA(JSClass) js_AnyNameClass = { js_AnyName_str, JSCLASS_HAS_PRIVATE | JSCLASS_CONSTRUCT_PROTOTYPE | JSCLASS_HAS_CACHED_PROTO(JSProto_AnyName), JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, anyname_finalize, NULL, NULL, NULL, NULL, NULL, NULL, qname_mark, NULL};#define QNAME_ATTRS \ (JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_SHARED)static JSPropertySpec qname_props[] = { {js_uri_str, QNAME_URI, QNAME_ATTRS, 0, 0}, {js_localName_str, QNAME_LOCALNAME, QNAME_ATTRS, 0, 0}, {0,0,0,0,0}};static JSBoolqname_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){ JSClass *clasp; JSXMLQName *qn; JSString *str, *qualstr; size_t length; jschar *chars; clasp = OBJ_GET_CLASS(cx, obj); if (clasp == &js_AttributeNameClass || clasp == &js_AnyNameClass) { qn = (JSXMLQName *) JS_GetPrivate(cx, obj); } else { qn = (JSXMLQName *) JS_GetInstancePrivate(cx, obj, &js_QNameClass.base, argv); if (!qn) return JS_FALSE; } if (!qn->uri) { /* No uri means wildcard qualifier. */ str = ATOM_TO_STRING(cx->runtime->atomState.starQualifierAtom); } else if (IS_EMPTY(qn->uri)) { /* Empty string for uri means localName is in no namespace. */ str = cx->runtime->emptyString; } else { qualstr = ATOM_TO_STRING(cx->runtime->atomState.qualifierAtom); str = js_ConcatStrings(cx, qn->uri, qualstr); if (!str) return JS_FALSE; } str = js_ConcatStrings(cx, str, qn->localName); if (!str) return JS_FALSE; if (str && clasp == &js_AttributeNameClass) { length = JSSTRING_LENGTH(str); chars = (jschar *) JS_malloc(cx, (length + 2) * sizeof(jschar)); if (!chars) return JS_FALSE; *chars = '@'; js_strncpy(chars + 1, JSSTRING_CHARS(str), length); chars[++length] = 0; str = js_NewString(cx, chars, length, 0); if (!str) { JS_free(cx, chars); return JS_FALSE; } } *rval = STRING_TO_JSVAL(str); return JS_TRUE;}static JSFunctionSpec qname_methods[] = { {js_toString_str, qname_toString, 0,0,0}, {0,0,0,0,0}};JSXMLQName *js_NewXMLQName(JSContext *cx, JSString *uri, JSString *prefix, JSString *localName){ JSXMLQName *qn; qn = (JSXMLQName *) js_NewGCThing(cx, GCX_QNAME, sizeof(JSXMLQName)); if (!qn) return NULL; qn->object = NULL; qn->uri = uri; qn->prefix = prefix; qn->localName = localName; METER(xml_stats.qname); METER(xml_stats.liveqname); return qn;}voidjs_MarkXMLQName(JSContext *cx, JSXMLQName *qn){ GC_MARK(cx, qn->object, "object"); GC_MARK(cx, qn->uri, "uri"); GC_MARK(cx, qn->prefix, "prefix"); GC_MARK(cx, qn->localName, "localName");}voidjs_FinalizeXMLQName(JSContext *cx, JSXMLQName *qn){ UNMETER(xml_stats.liveqname);}JSObject *js_NewXMLQNameObject(JSContext *cx, JSString *uri, JSString *prefix, JSString *localName){ JSXMLQName *qn; qn = js_NewXMLQName(cx, uri, prefix, localName); if (!qn) return NULL; return js_GetXMLQNameObject(cx, qn);}JSObject *js_GetXMLQNameObject(JSContext *cx, JSXMLQName *qn){ JSObject *obj; obj = qn->object; if (obj) { JS_ASSERT(JS_GetPrivate(cx, obj) == qn); return obj; } obj = js_NewObject(cx, &js_QNameClass.base, NULL, NULL); if (!obj || !JS_SetPrivate(cx, obj, qn)) { cx->weakRoots.newborn[GCX_OBJECT] = NULL; return NULL; } qn->object = obj; METER(xml_stats.qnameobj); METER(xml_stats.liveqnameobj); return obj;}JSObject *js_GetAttributeNameObject(JSContext *cx, JSXMLQName *qn){ JSObject *obj; obj = qn->object; if (obj) { if (OBJ_GET_CLASS(cx, obj) == &js_AttributeNameClass) return obj; qn = js_NewXMLQName(cx, qn->uri, qn->prefix, qn->localName); if (!qn) return NULL; } obj = js_NewObject(cx, &js_AttributeNameClass, NULL, NULL); if (!obj || !JS_SetPrivate(cx, obj, qn)) { cx->weakRoots.newborn[GCX_OBJECT] = NULL; return NULL; } qn->object = obj; METER(xml_stats.qnameobj); METER(xml_stats.liveqnameobj); return obj;}JSObject *js_ConstructXMLQNameObject(JSContext *cx, jsval nsval, jsval lnval){ jsval argv[2]; /* * ECMA-357 11.1.2, * The _QualifiedIdentifier : PropertySelector :: PropertySelector_ * production, step 2. */ if (!JSVAL_IS_PRIMITIVE(nsval) && OBJ_GET_CLASS(cx, JSVAL_TO_OBJECT(nsval)) == &js_AnyNameClass) { nsval = JSVAL_NULL; } argv[0] = nsval; argv[1] = lnval; return js_ConstructObject(cx, &js_QNameClass.base, NULL, NULL, 2, argv);}static JSBoolIsXMLName(const jschar *cp, size_t n){ JSBool rv; jschar c; rv = JS_FALSE; if (n != 0 && JS_ISXMLNSSTART(*cp)) { while (--n != 0) { c = *++cp; if (!JS_ISXMLNS(c)) return rv; } rv = JS_TRUE; } return rv;}JSBooljs_IsXMLName(JSContext *cx, jsval v){ JSClass *clasp; JSXMLQName *qn; JSString *name; JSErrorReporter older; /* * Inline specialization of the QName constructor called with v passed as * the only argument, to compute the localName for the constructed qname, * without actually allocating the object or computing its uri and prefix. * See ECMA-357 13.1.2.1 step 1 and 13.3.2. */ if (!JSVAL_IS_PRIMITIVE(v) && (clasp = OBJ_GET_CLASS(cx, JSVAL_TO_OBJECT(v)), clasp == &js_QNameClass.base || clasp == &js_AttributeNameClass || clasp == &js_AnyNameClass)) { qn = (JSXMLQName *) JS_GetPrivate(cx, JSVAL_TO_OBJECT(v)); name = qn->localName; } else { older = JS_SetErrorReporter(cx, NULL); name = js_ValueToString(cx, v); JS_SetErrorReporter(cx, older); if (!name) { JS_ClearPendingException(cx); return JS_FALSE; } } return IsXMLName(JSSTRING_CHARS(name), JSSTRING_LENGTH(name));}static JSBoolNamespace(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){ jsval urival, prefixval; JSObject *uriobj; JSBool isNamespace, isQName; JSClass *clasp; JSString *empty, *prefix; JSXMLNamespace *ns, *ns2; JSXMLQName *qn; urival = argv[argc > 1]; isNamespace = isQName = JS_FALSE; if (!JSVAL_IS_PRIMITIVE(urival)) { uriobj = JSVAL_TO_OBJECT(urival); clasp = OBJ_GET_CLASS(cx, uriobj); isNamespace = (clasp == &js_NamespaceClass.base); isQName = (clasp == &js_QNameClass.base); }#ifdef __GNUC__ /* suppress bogus gcc warnings */ else uriobj = NULL;#endif if (!(cx->fp->flags & JSFRAME_CONSTRUCTING)) { /* Namespace called as function. */ if (argc == 1 && isNamespace) { /* Namespace called with one Namespace argument is identity. */ *rval = urival; return JS_TRUE; } /* Create and return a new QName object exactly as if constructed. */ obj = js_NewObject(cx, &js_NamespaceClass.base, NULL, NULL); if (!obj) return JS_FALSE; *rval = OBJECT_TO_JSVAL(obj); } METER(xml_stats.namespaceobj); METER(xml_stats.livenamespaceobj); /* * Create and connect private data to rooted obj early, so we don't have * to worry about rooting string newborns hanging off of the private data * further below. */ empty = cx->runtime->emptyString; ns = js_NewXMLNamespace(cx, empty, empty, JS_FALSE); if (!ns) return JS_FALSE; if (!JS_SetPrivate(cx, obj, ns)) return JS_FALSE; ns->object = obj; if (argc == 1) { if (isNamespace) { ns2 = (JSXMLNamespace *) JS_GetPrivate(cx, uriobj); ns->uri = ns2->uri; ns->prefix = ns2->prefix; } else if (isQName && (qn = (JSXMLQName *) JS_GetPrivate(cx, uriobj))->uri) { ns->uri = qn->uri; ns->prefix = qn->prefix; } else { ns->uri = js_ValueToString(cx, urival); if (!ns->uri) return JS_FALSE; /* NULL here represents *undefined* in ECMA-357 13.2.2 3(c)iii. */ if (!IS_EMPTY(ns->uri)) ns->prefix = NULL; } } else if (argc == 2) { if (isQName && (qn = (JSXMLQName *) JS_GetPrivate(cx, uriobj))->uri) { ns->uri = qn->uri; } else { ns->uri = js_ValueToString(cx, urival); if (!ns->uri) return JS_FALSE; } prefixval = argv[0]; if (IS_EMPTY(ns->uri)) { if (!JSVAL_IS_VOID(prefixval)) { prefix = js_ValueToString(cx, prefixval); if (!prefix) return JS_FALSE; if (!IS_EMPTY(prefix)) { JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_XML_NAMESPACE, js_ValueToPrintableString(cx, STRING_TO_JSVAL(prefix))); return JS_FALSE; } } } else if (JSVAL_IS_VOID(prefixval) || !js_IsXMLName(cx, prefixval)) { /* NULL here represents *undefined* in ECMA-357 13.2.2 4(d) etc. */ ns->prefix = NULL; } else { prefix = js_ValueToString(cx, prefixval); if (!prefix) return JS_FALSE; ns->prefix = prefix; } } return JS_TRUE;}static JSBoolQName(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){ jsval nameval, nsval; JSBool isQName, isNamespace; JSXMLQName *qn; JSString *uri, *prefix, *name; JSObject *nsobj; JSClass *clasp; JSXMLNamespace *ns; nameval = argv[argc > 1]; isQName = !JSVAL_IS_PRIMITIVE(nameval) && OBJ_GET_CLASS(cx, JSVAL_TO_OBJECT(nameval)) == &js_QNameClass.base; if (!(cx->fp->flags & JSFRAME_CONSTRUCTING)) { /* QName called as function. */ if (argc == 1 && isQName) { /* QName called with one QName argument is identity. */ *rval = nameval; return JS_TRUE; } /* * Create and return a new QName object exactly as if constructed. * Use the constructor's clasp so we can be shared by AttributeName * (see below after this function). */ obj = js_NewObject(cx, JS_ValueToFunction(cx, argv[-2])->clasp, NULL, NULL); if (!obj) return JS_FALSE; *rval = OBJECT_TO_JSVAL(obj); } METER(xml_stats.qnameobj); METER(xml_stats.liveqnameobj); if (isQName) { /* If namespace is not specified and name is a QName, clone it. */ qn = (JSXMLQName *) JS_GetPrivate(cx, JSVAL_TO_OBJECT(nameval)); if (argc == 1) { uri = qn->uri; prefix = qn->prefix; name = qn->localName; goto out; } /* Namespace and qname were passed -- use the qname's localName. */ nameval = STRING_TO_JSVAL(qn->localName); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -