⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ejsxml.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 3 页
字号:
	}	return ejsGetVarPtr(pp);}/******************************************************************************//* NEWstatic EjsVar *setXmlProperty(Ejs *ep, EjsVar *op, const char *property, 	EjsVar *value){	if ((value->objectState->baseClass != XML && 			value->objectState->baseClass != XMLList) || 			value->string[0] != '<') {		ejsVarToString(luevalue.toString();		ejsRunMethod(ep, value, "toString", 0);		value = ejsDupVar(ep->result);	} else {		value = ejsDupVar(value);	}	if (isdigit(*property)) {		//	ERROR -- reserved for future versions		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"	}	mprFree(value);} *//******************************************************************************//************************************ Methods *********************************//******************************************************************************/static int load(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv){	const char	*fileName;	XmlState	*parser;	Exml		*xp;	MprFile		*file;	if (argc != 1 || !ejsVarIsString(argv[0])) {		ejsError(ep, EJS_ARG_ERROR, "Bad args. Usage: load(fileName);");		return -1;	}	fileName = argv[0]->string;		/* MOB -- not romable 		Need rom code in MPR not MprServices	*/	file = mprOpen(ep, fileName, O_RDONLY, 0664);	if (file == 0) {		ejsError(ep, EJS_IO_ERROR, "Can't open: %s", fileName);		return -1;	}	/* MOB -- should we empty thisObj of all existing properties ? */	xp = initParser(ep, thisObj, fileName);	parser = exmlGetParseArg(xp);	exmlSetInputStream(xp, readFileData, (void*) file);	if (exmlParse(xp) < 0) {		if (! ejsGotException(ep)) {			ejsError(ep, EJS_IO_ERROR, "Can't parse XML file: %s\nDetails %s", 				fileName, exmlGetErrorMsg(xp));		}		termParser(xp);		mprClose(file);		return -1;	}	ejsSetReturnValue(ep, parser->nodeStack[0].obj);	termParser(xp);	mprClose(file);	return 0;}/******************************************************************************/static int loadXmlString(Ejs *ep, EjsVar *thisObj, const char *xmlString){	XmlState	*parser;	Exml		*xp;	xp = initParser(ep, thisObj, "string");	parser = exmlGetParseArg(xp);	parser->inputBuf = xmlString;	parser->inputSize = strlen(xmlString);	exmlSetInputStream(xp, readStringData, (void*) 0);	if (exmlParse(xp) < 0) {		if (! ejsGotException(ep)) {			ejsError(ep, EJS_IO_ERROR, "Can't parse XML string\nError %s", 				exmlGetErrorMsg(xp));		}		termParser(xp);		return -1;	}	ejsSetReturnValue(ep, parser->nodeStack[0].obj);	termParser(xp);	return 0;}/******************************************************************************/static int text(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv){	EjsVar	*vp;	vp = ejsGetVarPtr(ejsGetSimpleProperty(ep, thisObj, E4X_TEXT_PROPERTY));	if (vp == 0) {		ejsSetReturnValueToString(ep, "");		return 0;	}	ejsSetReturnValue(ep, vp);	return 0;}/******************************************************************************//* *	Return the tag name */static int name(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv){	EjsVar	*vp;	vp = ejsGetVarPtr(ejsGetSimpleProperty(ep, thisObj, E4X_TAG_NAME_PROPERTY));	if (vp == 0) {		ejsSetReturnValueToString(ep, "");		return 0;	}	ejsSetReturnValue(ep, vp);#if UNDEFINED	char	*name;	/* MOB -- not ideal as we can't guarantee thisObj is a property */	name = ejsGetPropertyPtr(thisObj)->name; 	if (name == 0) {		name = "";	}	ejsSetReturnValueToString(ep, name); #endif	return 0;}/******************************************************************************//* MOB -- temporary only  */static int setText(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv){	if (argc != 1) {		ejsArgError(ep, "usage: setText(string)");	}	ejsSetProperty(ep, thisObj, E4X_TEXT_PROPERTY, argv[0]);	ejsSetReturnValue(ep, argv[0]);	return 0;}/******************************************************************************/static Exml *initParser(Ejs *ep, EjsVar *thisObj, const char *fileName){	XmlState	*parser;	Exml		*xp;	xp = exmlOpen(ep, 512, E4X_BUF_MAX);	mprAssert(xp);	/*	 *	Create the parser stack	 */	parser = mprAllocTypeZeroed(ep, XmlState);	parser->ep = ep;	parser->nodeStack[0].obj = thisObj;	parser->xmlClass = ejsGetClass(ep, 0, "XML");	parser->xmlListClass = ejsGetClass(ep, 0, "XMLList");	parser->fileName = fileName;	exmlSetParseArg(xp, parser);	exmlSetParserHandler(xp, parserHandler);	return xp;}/******************************************************************************/static void termParser(Exml *xp){	mprFree(exmlGetParseArg(xp));	exmlClose(xp);}/******************************************************************************//* *	XML parsing callback. Called for each elt and attribute/value pair.  *	For speed, we handcraft the object model here rather than calling  *	putXmlProperty. * *	"<!-- txt -->"		parseHandler(efd, , EXML_COMMENT); *	"<elt"				parseHandler(efd, , EXML_NEW_ELT); *	"...att=value"		parseHandler(efd, , EXML_NEW_ATT); *	"<elt ...>"			parseHandler(efd, , EXML_ELT_DEFINED); *	"<elt/>"			parseHandler(efd, , EXML_SOLO_ELT_DEFINED); *	"<elt> ...<"		parseHandler(efd, , EXML_ELT_DATA); *	"...</elt>"			parseHandler(efd, , EXML_END_ELT); * *	Note: we recurse on every new nested elt. */static int parserHandler(Exml *xp, int state, const char *tagName, 	const char *attName, const char *value){	XmlState		*parser;	XmlTagState		*tos;	EjsVar			*currentNode, *vp, *tagNode, *parent, *vpx;	EjsProperty		*pp;	Ejs				*ep;	char			*name;	parser = (XmlState*) xp->parseArg;	ep = parser->ep;	tos = &parser->nodeStack[parser->topOfStack];	currentNode = tos->obj;	mprAssert(state >= 0);	mprAssert(tagName && *tagName);	switch (state) {	case EXML_PI:		/*		 *	By using a property name with a leading space, we can store		 *	non-user-visible processing instructions as regular properties.		 */		pp = ejsCreateSimpleNonUniqueProperty(ep, currentNode, E4X_PI_PROPERTY);		ejsMakePropertyEnumerable(pp, 1);		vp = ejsGetVarPtr(pp);		ejsWriteVarAsString(ep, vp, value);		ejsSetVarFlags(vp, EJS_XML_FLAGS_PI);		break;	case EXML_COMMENT:		/*		 *	By using a property name with a leading space, we can store		 *	non- user-visible comments as regular properties.		 */		pp = ejsCreateSimpleNonUniqueProperty(ep, currentNode, 			E4X_COMMENT_PROPERTY);		ejsMakePropertyEnumerable(pp, 1);		vp = ejsGetVarPtr(pp);		ejsWriteVarAsString(ep, vp, value);		ejsSetVarFlags(vp, EJS_XML_FLAGS_COMMENT);		break;	case EXML_NEW_ELT:		if (parser->topOfStack > E4X_MAX_NODE_DEPTH) {			ejsError(ep, EJS_IO_ERROR, 				"XML nodes nested too deeply in %s at line %d",				parser->fileName, exmlGetLineNumber(xp));			return MPR_ERR_BAD_SYNTAX;		}		name = mprStrdup(xp, tagName);		if (name == 0) {			return MPR_ERR_MEMORY;		}		if (cleanTagName(name) < 0) {			ejsError(ep, EJS_TYPE_ERROR, "Bad XML tag name in %s at %d",				parser->fileName, exmlGetLineNumber(xp));			mprFree(name);			return MPR_ERR_BAD_SYNTAX;		}		pp = ejsCreateSimpleNonUniqueProperty(ep, currentNode, name);		ejsMakePropertyEnumerable(pp, 1);		tagNode = ejsGetVarPtr(pp);		/* MOB -- OPT */		vpx = ejsCreateXml(ep);		vp = ejsWriteVar(ep, tagNode, vpx, EJS_SHALLOW_COPY);		ejsMakeObjLive(vp, 1);		ejsFreeVar(ep, vpx);		/* MOB -- return code */		pp = ejsSetPropertyToString(ep, vp, E4X_TAG_NAME_PROPERTY, name);		ejsMakePropertyEnumerable(pp, 0);		ejsSetVarFlags(vp, EJS_XML_FLAGS_ELEMENT);		ejsMakePropertyEnumerable(ejsGetPropertyPtr(vp), 1);		tos = &parser->nodeStack[++(parser->topOfStack)];		currentNode = tos->obj = vp;		tos->attributes = 0;		tos->comments = 0;		mprFree(name);		break;	case EXML_NEW_ATT:		if (mprAllocSprintf(MPR_LOC_ARGS(xp), &name, 0, "@%s", attName) < 0) {			return MPR_ERR_MEMORY;		}		pp = ejsCreateProperty(ep, currentNode, name);		ejsMakePropertyEnumerable(pp, 1);		vp = ejsGetVarPtr(pp);		ejsWriteVarAsString(ep, vp, value);		ejsSetVarFlags(vp, EJS_XML_FLAGS_ATTRIBUTE);		mprFree(name);		break;	case EXML_SOLO_ELT_DEFINED:		parser->topOfStack--;		mprAssert(parser->topOfStack >= 0);		tos = &parser->nodeStack[parser->topOfStack];		break;	case EXML_ELT_DEFINED:		if (parser->topOfStack > 0) {			parent = parser->nodeStack[parser->topOfStack - 1].obj;			ejsSetProperty(ep, currentNode, E4X_PARENT_PROPERTY, parent);		}		break;	case EXML_ELT_DATA:	case EXML_CDATA:		pp = ejsCreateSimpleNonUniqueProperty(ep, currentNode, 			E4X_TEXT_PROPERTY);		ejsMakePropertyEnumerable(pp, 1);		vp = ejsGetVarPtr(pp);		ejsWriteVarAsString(ep, vp, value);		ejsSetVarFlags(vp, EJS_XML_FLAGS_TEXT);		break;	case EXML_END_ELT:		/* 		 *	This is the closing element in a pair "<x>...</x>". 		 *	Pop the stack frame off the elt stack 		 */		parser->topOfStack--;		mprAssert(parser->topOfStack >= 0);		tos = &parser->nodeStack[parser->topOfStack];		break;	default:		ejsError(ep, EJS_IO_ERROR, "XML error in %s at %d\nDetails %s",			parser->fileName, exmlGetLineNumber(xp), exmlGetErrorMsg(xp));		mprAssert(0);		return MPR_ERR_BAD_SYNTAX;	}	return 0;}/******************************************************************************/static char *cleanTagName(char *name){	char	*cp;	for (cp = name; *cp; cp++) {		if (*cp == ':') {			*cp = '_';		} else if (!isalnum(*cp) && *cp != '_' && *cp != '$' && *cp != '@') {			return 0;		}	}	return name;}/******************************************************************************/static int readFileData(Exml *xp, void *data, char *buf, int size){	mprAssert(xp);	mprAssert(data);	mprAssert(buf);	mprAssert(size > 0);	return mprRead((MprFile*) data, buf, size);}/******************************************************************************/static int readStringData(Exml *xp, void *data, char *buf, int size){	XmlState	*parser;	int			rc, len;	mprAssert(xp);	mprAssert(buf);	mprAssert(size > 0);	parser = (XmlState*) xp->parseArg;	if (parser->inputPos < parser->inputSize) {		len = min(size, (parser->inputSize - parser->inputPos));		rc = mprMemcpy(buf, size, &parser->inputBuf[parser->inputPos], len);		parser->inputPos += len;		return rc;	}	return 0;}/******************************************************************************/static int save(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv){	const char	*fileName;	MprBuf		*buf;	MprFile		*file;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -