📄 ejsxml.c
字号:
int bytes, len; if (argc != 1 || !ejsVarIsString(argv[0])) { ejsError(ep, EJS_ARG_ERROR, "Bad args. Usage: save(fileName);"); return -1; } fileName = argv[0]->string; /* MOB -- not romable Need rom code in MPR not MprServices */ /* * Convert to a string */ buf = mprCreateBuf(ep, E4X_BUF_SIZE, E4X_BUF_MAX); if (xmlToString(ep, buf, thisObj, -1) < 0) { mprFree(buf); return -1; } file = mprOpen(ep, fileName, O_CREAT | O_TRUNC | O_WRONLY | O_TEXT, 0664); if (file == 0) { ejsError(ep, EJS_IO_ERROR, "Can't open: %s, %d", fileName, mprGetOsError()); return -1; } len = mprGetBufLength(buf); bytes = mprWrite(file, buf->start, len); if (bytes != len) { ejsError(ep, EJS_IO_ERROR, "Can't write to: %s", fileName); mprClose(file); return -1; } mprWrite(file, "\n", 1); mprFree(buf); mprClose(file); return 0;}/******************************************************************************/static int toString(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv){ MprBuf *buf; buf = mprCreateBuf(ep, E4X_BUF_SIZE, E4X_BUF_MAX); if (xmlToString(ep, buf, thisObj, -1) < 0) { mprFree(buf); return -1; } ejsWriteVarAsString(ep, ep->result, (char*) buf->start); mprFree(buf); return 0;}/******************************************************************************//* MOB -- need to support XMLList */static int xmlToString(Ejs *ep, MprBuf *buf, EjsVar *obj, int indentLevel){ EjsProperty *pp; EjsVar *vp; char *varBuf; int endTag, sawElements; if (indentLevel < 0) { mprPutStringToBuf(buf, "<?xml version=\"1.0\"?>"); } switch (obj->type) { case EJS_TYPE_STRING: if (obj->flags & EJS_XML_FLAGS_ATTRIBUTE) { mprPutFmtStringToBuf(buf, " %s=\"%s\"", &ejsGetPropertyPtr(obj)->name[1], obj->string); /* No new line */ } else if (obj->flags & EJS_XML_FLAGS_COMMENT) { mprPutCharToBuf(buf, '\n'); indent(buf, indentLevel); mprPutFmtStringToBuf(buf, "<!-- %s -->", obj->string); } else if (obj->flags & EJS_XML_FLAGS_TEXT) { mprPutStringToBuf(buf, obj->string); } else {// indent(buf, indentLevel); mprPutStringToBuf(buf, obj->string);// mprPutCharToBuf(buf, '\n'); } break; default: /* Primitive types come here */ indent(buf, indentLevel); /* MOB -- rc */ varBuf = ejsVarToString(ep, obj); mprPutStringToBuf(buf, varBuf); break; case EJS_TYPE_OBJECT: if (obj->objectState->baseClass == ejsGetClass(ep, 0, "XML")) { if (!obj->objectState->visited) { obj->objectState->visited = 1; /* MOB -- opt. Flags would be quicker */ if (strcmp(ejsGetPropertyPtr(obj)->name, E4X_PARENT_PROPERTY) == 0) { return 0; } /* * MOB -- short term fix for tags with no body but with * attributes */ if (getNumElements(obj) == 0 && 0) { /* * XML element is simple with no elements, so return just * the text. */ if (getText(buf, obj) < 0) { ejsError(ep, EJS_IO_ERROR, "XML is to big to convert to a string"); obj->objectState->visited = 0; return -1; } } else if (obj->flags & (EJS_XML_FLAGS_ELEMENT)) { /* * XML object is complex (has elements) so return full XML * content. */ mprPutCharToBuf(buf, '\n'); indent(buf, indentLevel); /* * When called from toString, obj is not a property */ if (indentLevel >= 0) { mprPutFmtStringToBuf(buf, "<%s", ejsGetPropertyPtr(obj)->name); endTag = 0; } else { endTag = 1; } sawElements = 0; pp = ejsGetFirstProperty(obj, 0); while (pp) { vp = ejsGetVarPtr(pp); if (! (vp->flags & EJS_XML_FLAGS_ATTRIBUTE)) { if (endTag == 0) { endTag++; mprPutStringToBuf(buf, ">"); } } if (vp->flags & EJS_XML_FLAGS_ELEMENT) { if (strcmp(ejsGetPropertyPtr(vp)->name, E4X_PARENT_PROPERTY) != 0) { sawElements++; } } if (xmlToString(ep, buf, ejsGetVarPtr(pp), indentLevel + 1) < 0){ return -1; } pp = ejsGetNextProperty(pp, 0); } if (indentLevel >= 0) { if (sawElements) { mprPutCharToBuf(buf, '\n'); indent(buf, indentLevel); } mprPutFmtStringToBuf(buf, "</%s>", ejsGetPropertyPtr(obj)->name); } } obj->objectState->visited = 0; } return 0; } if (obj->objectState->baseClass == ejsGetClass(ep, 0, "XMLList")) { indent(buf, indentLevel); /* MOB -- TBD */ return 0; } /* * All other objects. Allow other objects to override toString */ if (ejsRunMethod(ep, obj->objectState->baseClass, "toString", 0) < 0) { return -1; } if (ejsVarIsString(ep->result)) { indent(buf, indentLevel); mprPutStringToBuf(buf, obj->string); } break; } return 0;}/******************************************************************************/static void indent(MprBuf *bp, int level){ int i; for (i = 0; i < level; i++) { mprPutCharToBuf(bp, '\t'); }}/******************************************************************************/static int valueOf(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv){ if (argc != 0) { mprAssert(0); return -1; } switch (thisObj->type) { default: case EJS_TYPE_UNDEFINED: case EJS_TYPE_NULL: case EJS_TYPE_CMETHOD: case EJS_TYPE_OBJECT: case EJS_TYPE_METHOD: case EJS_TYPE_STRING_CMETHOD: ejsWriteVar(ep, ep->result, thisObj, EJS_SHALLOW_COPY); break; case EJS_TYPE_STRING: ejsWriteVarAsInteger(ep, ep->result, atoi(thisObj->string)); break; case EJS_TYPE_BOOL: case EJS_TYPE_INT:#if BLD_FEATURE_INT64 case EJS_TYPE_INT64:#endif#if BLD_FEATURE_FLOATING_POINT case EJS_TYPE_FLOAT:#endif ejsWriteVar(ep, ep->result, thisObj, EJS_SHALLOW_COPY); break; } return 0;}/******************************************************************************/static int getList(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv){ const char *nodeName; EjsProperty *pp; EjsVar *list, *vp; if (argc != 1) { nodeName = 0; } else { nodeName = argv[0]->string; } list = ejsCreateArray(ep, 0); pp = ejsGetFirstProperty(thisObj, EJS_ENUM_ALL); while (pp) { vp = ejsGetVarPtr(pp); if (vp->type == EJS_TYPE_OBJECT) { if (strcmp(ejsGetPropertyPtr(vp)->name, E4X_PARENT_PROPERTY) != 0) { if (vp->flags & EJS_XML_FLAGS_ELEMENT && (nodeName == 0 || strcmp(nodeName, pp->name) == 0)) { ejsAddArrayElt(ep, list, vp, EJS_SHALLOW_COPY); } } } pp = ejsGetNextProperty(pp, EJS_ENUM_ALL); } ejsSetReturnValueAndFree(ep, list); return 0;}/******************************************************************************/static int getNumElements(EjsVar *obj){ EjsProperty *pp; int count; count = 0; pp = ejsGetFirstProperty(obj, EJS_ENUM_ALL); while (pp) { if (ejsGetVarPtr(pp)->flags & EJS_XML_FLAGS_ELEMENT) { count++; } pp = ejsGetNextProperty(pp, EJS_ENUM_ALL); } return count;}/******************************************************************************//* MOB - This needs to be a public method */static int getText(MprBuf *buf, EjsVar *obj){ EjsProperty *pp; EjsVar *vp; pp = ejsGetFirstProperty(obj, EJS_ENUM_ALL); while (pp) { vp = ejsGetVarPtr(pp); if (vp->flags & EJS_XML_FLAGS_TEXT) { /* MOB -- should test for overflow */ mprPutStringToBuf(buf, vp->string); } pp = ejsGetNextProperty(pp, EJS_ENUM_ALL); } return 0;}/******************************************************************************//******************************************************************************//******************************** Internal Methods ****************************//******************************************************************************/static EjsVar *createXmlListProperty(Ejs *ep, EjsVar *obj, const char *property){ return ejsGetVarPtr(ejsCreateProperty(ep, obj, property));}/******************************************************************************/static int deleteXmlListProperty(Ejs *ep, EjsVar *obj, const char *property){ return ejsDeleteProperty(ep, obj, property);}/******************************************************************************/static EjsVar *getXmlListProperty(Ejs *ep, EjsVar *obj, const char *property){ // Must always return XML or XMLList event for comments and attributes return ejsGetVarPtr(ejsGetSimpleProperty(ep, obj, property));}/******************************************************************************/static EjsVar *setXmlListProperty(Ejs *ep, EjsVar *obj, const char *property, const EjsVar *value){ EjsProperty *pp; EjsVar *vp; pp = ejsGetSimpleProperty(ep, obj, property); if (pp == 0) { mprAssert(pp); return 0; } vp = ejsGetVarPtr(pp); if (ejsWriteVar(ep, vp, value, EJS_SHALLOW_COPY) < 0){ mprAssert(0); return 0; } return ejsGetVarPtr(pp);}/******************************************************************************//* NEWstatic EjsVar *putXmlListProperty(EjsVar *op, const char *property, EjsVar *value){ if ((value->objectState->baseClass != XML && value->objectState->baseClass != XMLList) || value->string[0] != '<') { c = value.toString(); } else { value = ejsDupVar(value); ?? } if (isdigit(*property)) { // ERROR return 0; } if (*property == '@') { if (op->objectState->baseClass == XMLList) { if (op->obj.LENGTH_PROPERTY == 0) { c = ""; } else { // Catenate all result of toString on all elts in list } } else { c = c.toString(); } // Replace existing attribute of same name or insert return; } for (i = op->obj.LENGTH - 1; i >= 0; i--) { // Delete item of same name } if (not Found) { Append new Xml object - set [[name]], [[class]] == "element" }} *//******************************************************************************/#elsevoid ejs4xDummy() {}/******************************************************************************/#endif /* BLD_FEATURE_EJS_E4X *//* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim:tw=78 * vim600: sw=4 ts=4 fdm=marker * vim<600: sw=4 ts=4 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -