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

📄 xml_to_soap.c

📁 PHP v6.0 For Linux 运行环境:Win9X/ WinME/ WinNT/ Win2K/ WinXP
💻 C
📖 第 1 页 / 共 2 页
字号:
		}		/* Next, we begin to convert actual values. if no children, then must be a scalar value. */		if (!Q_Size(&el->children)) {			if (!type && parent_array && parent_array->kids_type[0]) {				type = parent_array->kids_type;			}			if (!type || !strcmp(type, TOKEN_STRING)) {				XMLRPC_SetValueString(xCurrent, el->text.str, el->text.len);			}			else if (!strcmp(type, TOKEN_INT)) {				XMLRPC_SetValueInt(xCurrent, atoi(el->text.str));			}			else if (!strcmp(type, TOKEN_BOOLEAN)) {				XMLRPC_SetValueBoolean(xCurrent, atoi(el->text.str));			}			else if (!strcmp(type, TOKEN_DOUBLE) ||						!strcmp(type, TOKEN_FLOAT)) {				XMLRPC_SetValueDouble(xCurrent, atof(el->text.str));			}			else if (!strcmp(type, TOKEN_NULL)) {				/* already an empty val. do nothing. */			}			else if (!strcmp(type, TOKEN_DATETIME)) {				XMLRPC_SetValueDateTime_ISO8601(xCurrent, el->text.str);			}			else if (!strcmp(type, TOKEN_BASE64)) {				struct buffer_st buf;				base64_decode(&buf, el->text.str, el->text.len);				XMLRPC_SetValueBase64(xCurrent, buf.data, buf.offset);				buffer_delete(&buf);			}		}		/* Element has children, thus a vector, or "compound type" in soap-speak. */		else {			struct array_info* ai = NULL;			xml_element* iter = (xml_element*)Q_Head(&el->children);			if (!type || !strcmp(type, TOKEN_STRUCT)) {				XMLRPC_SetIsVector(xCurrent, xmlrpc_vector_struct);			}			else if (!strcmp(type, TOKEN_ARRAY) || arrayType != NULL) {				/* determine magic associated with soap array type.				   this is passed down as we recurse, so our children have access to the info. */				ai = parse_array_type_info(arrayType);	// alloc'ed ai free'd below.				XMLRPC_SetIsVector(xCurrent, xmlrpc_vector_array);			}			else {				/* mixed is probably closest thing we have to compound type. */				XMLRPC_SetIsVector(xCurrent, xmlrpc_vector_mixed);			}			/* Recurse, adding values as we go.  Check for error during recursion			   and if found, bail.  this short-circuits us out of the recursion. */			while ( iter && !XMLRPC_RequestGetError(request) ) {				XMLRPC_VALUE xNext = NULL;				/* top level elements don't actually represent values, so we just pass the				   current value along until we are deep enough. */				if ( depth <= 2 ||					  (rtype == xmlrpc_request_response && depth <= 3) ) {					xml_element_to_SOAP_REQUEST_worker(request, NULL, ai, xCurrent, iter, depth);				}				/* ready to do some actual de-serialization. create a new empty value and				   pass that along to be init'd, then add it to our current vector. */				else {					xNext = XMLRPC_CreateValueEmpty();					xml_element_to_SOAP_REQUEST_worker(request, xCurrent, ai, xNext, iter, depth);					XMLRPC_AddValueToVector(xCurrent, xNext);				}				iter = (xml_element*)Q_Next(&el->children);			}			/* cleanup */			if (ai) {				free(ai);			}		}	}	return xCurrent;}/* Convert soap xml dom to XMLRPC_VALUE, sans request info.  untested. */XMLRPC_VALUE xml_element_to_SOAP_VALUE(xml_element* el){	return xml_element_to_SOAP_REQUEST_worker(NULL, NULL, NULL, NULL, el, 0);}/* Convert soap xml dom to XMLRPC_REQUEST */XMLRPC_VALUE xml_element_to_SOAP_REQUEST(XMLRPC_REQUEST request, xml_element* el){	if (request) {		return XMLRPC_RequestSetData(request, xml_element_to_SOAP_REQUEST_worker(request, NULL, NULL, NULL, el, 0));	}	return NULL;}/* translates data structures to soap/xml. recursive */xml_element* SOAP_to_xml_element_worker(XMLRPC_REQUEST request, XMLRPC_VALUE node) {#define BUF_SIZE 128	xml_element* elem_val = NULL;	if (node) {		int bFreeNode = 0;  /* sometimes we may need to free 'node' variable */		char buf[BUF_SIZE];		XMLRPC_VALUE_TYPE_EASY type = XMLRPC_GetValueTypeEasy(node);		char* pName = NULL, *pAttrType = NULL;		/* create our return value element */		elem_val = xml_elem_new();		switch (type) {		case xmlrpc_type_struct:		case xmlrpc_type_mixed:		case xmlrpc_type_array:			if (type == xmlrpc_type_array) {				/* array's are _very_ special in soap.				   TODO: Should handle sparse/partial arrays here. */				/* determine soap array type. */				const char* type = get_array_soap_type(node);				xml_element_attr* attr_array_type = NULL;				/* specify array kids type and array size. */				snprintf(buf, sizeof(buf), "%s[%i]", type, XMLRPC_VectorSize(node));				attr_array_type = new_attr(TOKEN_ARRAY_TYPE, buf);				Q_PushTail(&elem_val->attrs, attr_array_type);				pAttrType = TOKEN_ARRAY;			}			/* check for fault, which is a rather special case. 			   (can't these people design anything consistent/simple/elegant?) */			else if (type == xmlrpc_type_struct) {				int fault_type = get_fault_type(node);				if (fault_type) {					if (fault_type == 1) {						/* gen fault from xmlrpc style fault codes              						    notice that we get a new node, which must be freed herein. */						node = gen_fault_xmlrpc(node, elem_val);						bFreeNode = 1;					}					pName = TOKEN_FAULT;				}			}			{				/* recurse through sub-elements */				XMLRPC_VALUE xIter = XMLRPC_VectorRewind(node);				while ( xIter ) {					xml_element* next_el = SOAP_to_xml_element_worker(request, xIter);					if (next_el) {						Q_PushTail(&elem_val->children, next_el);					}					xIter = XMLRPC_VectorNext(node);				}			}			break;			/* handle scalar types */		case xmlrpc_type_empty:			pAttrType = TOKEN_NULL;			break;		case xmlrpc_type_string:			pAttrType = TOKEN_STRING;			simplestring_addn(&elem_val->text, XMLRPC_GetValueString(node), XMLRPC_GetValueStringLen(node));			break;		case xmlrpc_type_int:			pAttrType = TOKEN_INT;			snprintf(buf, BUF_SIZE, "%i", XMLRPC_GetValueInt(node));			simplestring_add(&elem_val->text, buf);			break;		case xmlrpc_type_boolean:			pAttrType = TOKEN_BOOLEAN;			snprintf(buf, BUF_SIZE, "%i", XMLRPC_GetValueBoolean(node));			simplestring_add(&elem_val->text, buf);			break;		case xmlrpc_type_double:			pAttrType = TOKEN_DOUBLE;			snprintf(buf, BUF_SIZE, "%f", XMLRPC_GetValueDouble(node));			simplestring_add(&elem_val->text, buf);			break;		case xmlrpc_type_datetime:			{				time_t tt = XMLRPC_GetValueDateTime(node);				struct tm *tm = localtime (&tt);				pAttrType = TOKEN_DATETIME;				if(strftime (buf, BUF_SIZE, "%Y-%m-%dT%H:%M:%SZ", tm)) {					simplestring_add(&elem_val->text, buf);				}			}			break;		case xmlrpc_type_base64:			{				struct buffer_st buf;				pAttrType = TOKEN_BASE64;				base64_encode(&buf, XMLRPC_GetValueBase64(node), XMLRPC_GetValueStringLen(node));				simplestring_addn(&elem_val->text, buf.data, buf.offset );				buffer_delete(&buf);			}			break;			break;		default:			break;		}		/* determining element's name is a bit tricky, due to soap semantics. */		if (!pName) {			/* if the value's type is known... */			if (pAttrType) {				/* see if it has an id (key). If so, use that as name, and type as an attribute. */				pName = (char*)XMLRPC_GetValueID(node);				if (pName) {					Q_PushTail(&elem_val->attrs, new_attr(TOKEN_TYPE, pAttrType));				}				/* otherwise, use the type as the name. */				else {					pName = pAttrType;				}			}			/* if the value's type is not known... (a rare case?) */			else {				/* see if it has an id (key). otherwise, default to generic "item" */				pName = (char*)XMLRPC_GetValueID(node);				if (!pName) {					pName = "item";				}			}		}		elem_val->name = strdup(pName);		/* cleanup */		if (bFreeNode) {			XMLRPC_CleanupValue(node);		}	}	return elem_val;}/* convert XMLRPC_VALUE to soap xml dom.  untested. */xml_element* SOAP_VALUE_to_xml_element(XMLRPC_VALUE node) {	return SOAP_to_xml_element_worker(NULL, node);}/* convert XMLRPC_REQUEST to soap xml dom. */xml_element* SOAP_REQUEST_to_xml_element(XMLRPC_REQUEST request) {	xml_element* root = xml_elem_new();	/* safety first. */	if (root) {		xml_element* body = xml_elem_new();		root->name = strdup("SOAP-ENV:Envelope");		/* silly namespace stuff */		Q_PushTail(&root->attrs, new_attr("xmlns:SOAP-ENV", "http://schemas.xmlsoap.org/soap/envelope/"));		Q_PushTail(&root->attrs, new_attr("xmlns:xsi", "http://www.w3.org/1999/XMLSchema-instance"));		Q_PushTail(&root->attrs, new_attr("xmlns:xsd", "http://www.w3.org/1999/XMLSchema"));		Q_PushTail(&root->attrs, new_attr("xmlns:SOAP-ENC", "http://schemas.xmlsoap.org/soap/encoding/"));		Q_PushTail(&root->attrs, new_attr("xmlns:si", "http://soapinterop.org/xsd"));		Q_PushTail(&root->attrs, new_attr("xmlns:ns6", "http://testuri.org"));		Q_PushTail(&root->attrs, new_attr("SOAP-ENV:encodingStyle", "http://schemas.xmlsoap.org/soap/encoding/"));		/* Q_PushHead(&root->attrs, new_attr("xmlns:ks", "http://kitchen.sink.org/soap/everything/under/sun"));		       JUST KIDDING!! :-)  ---->                ------------------------------------------------- */		if (body) {			/* go ahead and serialize first... */			xml_element* el_serialized =  			SOAP_to_xml_element_worker(request, 												XMLRPC_RequestGetData(request));			/* check for fault, in which case, there is no intermediate element */			if (el_serialized && !strcmp(el_serialized->name, TOKEN_FAULT)) {				Q_PushTail(&body->children, el_serialized);			}			/* usual case: not a fault. Add Response element in between. */			else {				xml_element* rpc = xml_elem_new();				if (rpc) {					const char* methodname = XMLRPC_RequestGetMethodName(request);					XMLRPC_REQUEST_TYPE rtype = XMLRPC_RequestGetRequestType(request);					/* if we are making a request, we want to use the methodname as is. */					if (rtype == xmlrpc_request_call) {						if (methodname) {							rpc->name = strdup(methodname);						}					}					/* if it's a response, we append "Response". Also, given xmlrpc-epi					   API/architecture, it's likely that we don't have a methodname for					   the response, so we have to check that. */					else {						char buf[128];						snprintf(buf, sizeof(buf), "%s%s", 									methodname ? methodname : "",									"Response");						rpc->name = strdup(buf);					}					/* add serialized data to method call/response.					   add method call/response to body element */					if (rpc->name) {						if(el_serialized) {							if(Q_Size(&el_serialized->children) && rtype == xmlrpc_request_call) {								xml_element* iter = (xml_element*)Q_Head(&el_serialized->children);								while(iter) {									Q_PushTail(&rpc->children, iter);									iter = (xml_element*)Q_Next(&el_serialized->children);								}								xml_elem_free_non_recurse(el_serialized);							}							else {								Q_PushTail(&rpc->children, el_serialized);							}						}						Q_PushTail(&body->children, rpc);					}					else {						/* no method name?!						   TODO: fault here...? */					}				}			}			body->name = strdup("SOAP-ENV:Body");			Q_PushTail(&root->children, body);		}	}	return root;}

⌨️ 快捷键说明

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