From 8fc41296cd27af9757f571627f7fd16befc9b8aa Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Mon, 21 Sep 2009 19:04:36 +0200 Subject: Rewrote eurephiaXML_ResultMsg() to also support adding an xmlNode* with more info The eurephia result XML document is also changed, and all parsing of the result must be rewritten. To simplify this parsing, a new function is introduced, eurephiaXML_ParseResultMsg(). --- common/eurephia_xml.c | 72 ++++++++++++++++++++++++++++++++++++++++++++------- common/eurephia_xml.h | 13 +++++++++- 2 files changed, 75 insertions(+), 10 deletions(-) (limited to 'common') diff --git a/common/eurephia_xml.c b/common/eurephia_xml.c index e78d2b3..80f2ccd 100644 --- a/common/eurephia_xml.c +++ b/common/eurephia_xml.c @@ -141,7 +141,7 @@ int eurephiaXML_CreateDoc(eurephiaCTX *ctx, int format, const char *eurephiaRoot * * @param ctx eurephiaCTX * @param doc xmlDoc pointer to the XML document - * @param nodeset The expected root node to be found + * @param nodeset The expected root node to be found. * @param req_format The minimum format version to be accepted * * @return Returns pointer to the given xmlNode tag. On failure, NULL is returned. @@ -173,14 +173,15 @@ xmlNode *eurephiaXML_getRoot(eurephiaCTX *ctx, xmlDoc *doc, const char *nodeset, /** * Creates a simple result message, formatted as an XML document. * - * @param ctx eurephiaCTX - * @param type Can be exmlRESULT or exmlERROR. The former is used for informational messages. - * @param fmt stdarg format string + * @param ctx eurephiaCTX + * @param type Can be exmlRESULT or exmlERROR. The former is used for informational messages. + * @param info_n xmlNode with more details about the result + * @param fmt stdarg format string * * @return Returns a valid eurephia XML document as a properly formatted result message. * On failure, NULL is returned */ -xmlDoc *eurephiaXML_ResultMsg(eurephiaCTX *ctx, exmlResultType type, const char *fmt, ... ) { + xmlDoc *eurephiaXML_ResultMsg(eurephiaCTX *ctx, exmlResultType type, xmlNode *info_n, const char *fmt, ... ) { va_list ap; xmlChar msg[2050], *xmlfmt = NULL; xmlDoc *msgdoc = NULL; @@ -195,26 +196,79 @@ xmlDoc *eurephiaXML_ResultMsg(eurephiaCTX *ctx, exmlResultType type, const char va_end(ap); free_nullsafe(ctx, xmlfmt); + eurephiaXML_CreateDoc(ctx, 1, "Result", &msgdoc, &msg_n); + assert( (msgdoc != NULL) && (msg_n != NULL) ); + switch( type ) { case exmlRESULT: - eurephiaXML_CreateDoc(ctx, 1, "Result", &msgdoc, &msg_n); + xmlNewProp(msg_n, (xmlChar *) "status", (xmlChar *) "Result"); break; case exmlERROR: - eurephiaXML_CreateDoc(ctx, 1, "Error", &msgdoc, &msg_n); + xmlNewProp(msg_n, (xmlChar *) "status", (xmlChar *) "Error"); break; default: eurephia_log(ctx, LOG_ERROR, 0, "Wrong XML result message type (%i)", type); return NULL; } - assert( (msgdoc != NULL) && (msg_n != NULL) ); - xmlAddChild(msg_n, xmlNewText(msg)); + xmlNewChild(msg_n, NULL, (xmlChar *) "Message", msg); + + if( info_n != NULL ) { + // Create a new child tag (Details) and copy the info nodes into this tag + xmlAddChild(xmlNewChild(msg_n, NULL, (xmlChar *) "Details", NULL), + xmlCopyNode(info_n, 1)); + } return msgdoc; } +/** + * Parses an eurephia Result XML document + * + * @param ctx eurephiaCTX + * @param resxml The result XML document + * + * @return Returns a pointer to an eurephiaRESULT structure containing the results. + * On failure NULL is returned. This structure can be freed with free_nullsafe(). + * + * @remark If the result XML document is freed, the information in eurephiaRESULT will be invalidated + * Immediately. However, the eurephiaRESULT pointer must still be freed. + */ +eurephiaRESULT *eurephiaXML_ParseResultMsg(eurephiaCTX *ctx, xmlDoc *resxml) { + eurephiaRESULT *res = NULL; + xmlNode *res_n = NULL; + char *str = NULL; + + assert( (ctx != NULL) && (resxml != NULL) ); + + res_n = eurephiaXML_getRoot(ctx, resxml, "Result", 1); + if( res_n == NULL) { + eurephia_log(ctx, LOG_ERROR, 0, "Could not find a valid tag"); + return NULL; + } + + res = (eurephiaRESULT *) malloc_nullsafe(ctx, sizeof(eurephiaRESULT) + 2); + assert( res != NULL ); + + str = xmlGetAttrValue(res_n->properties, "status"); + if( strcmp(str, "Error") == 0 ) { + res->resultType = exmlERROR; + } else if( strcmp(str, "Result") == 0 ) { + res->resultType = exmlRESULT; + } else { + free_nullsafe(ctx, res); + eurephia_log(ctx, LOG_ERROR, 0, "Invalid result status"); + return NULL; + } + + res->message = xmlGetNodeContent(res_n, "Message"); + res->details = xmlFindNode(res_n, "Details"); + return res; +} + + /** * Return the text content of a given xmlNode * diff --git a/common/eurephia_xml.h b/common/eurephia_xml.h index 51ee9dd..614394a 100644 --- a/common/eurephia_xml.h +++ b/common/eurephia_xml.h @@ -44,6 +44,16 @@ typedef enum _exmlResultType { exmlRESULT = 1, /**< Operation successful. Additi #ifdef HAVE_LIBXML2 #include +/** + * Structure which is used when parsing eurephia Result XML documents + */ +typedef struct _eurephiaRESULT { + exmlResultType resultType; /**< Indicates what kind of result we received */ + const char *message; /**< String containing the result message */ + xmlNode *details; /**< A result message can attach an XML node with even more + detailed information */ +} eurephiaRESULT; + /** * Simple iterator macro for iterating xmlNode pointers * @@ -58,7 +68,8 @@ xmlNode *xmlFindNode(xmlNode *node, const char *key); int eurephiaXML_CreateDoc(eurephiaCTX *ctx, int format, const char *rootname, xmlDoc **doc, xmlNode **root_n); xmlNode *eurephiaXML_getRoot(eurephiaCTX *ctx, xmlDoc *doc, const char *nodeset, int min_format); -xmlDoc *eurephiaXML_ResultMsg(eurephiaCTX *ctx, exmlResultType type, const char *fmt, ... ); +xmlDoc *eurephiaXML_ResultMsg(eurephiaCTX *ctx, exmlResultType type, xmlNode *info_n, const char *fmt, ... ); +eurephiaRESULT *eurephiaXML_ParseResultMsg(eurephiaCTX *ctx, xmlDoc *resxml); inline char *xmlExtractContent(xmlNode *n); inline char *xmlGetNodeContent(xmlNode *node, const char *key); -- cgit