/home/dko/projects/mobilec/trunk/src/xml_parser.c

Go to the documentation of this file.
00001 /*[
00002  * Copyright (c) 2007 Integration Engineering Laboratory
00003                       University of California, Davis
00004  *
00005  * Permission to use, copy, and distribute this software and its
00006  * documentation for any purpose with or without fee is hereby granted,
00007  * provided that the above copyright notice appear in all copies and
00008  * that both that copyright notice and this permission notice appear
00009  * in supporting documentation.
00010  *
00011  * Permission to modify the software is granted, but not the right to
00012  * distribute the complete modified source code.  Modifications are to
00013  * be distributed as patches to the released version.  Permission to
00014  * distribute binaries produced by compiling modified sources is granted,
00015  * provided you
00016  *   1. distribute the corresponding source modifications from the
00017  *    released version in the form of a patch file along with the binaries,
00018  *   2. add special version identification to distinguish your version
00019  *    in addition to the base release version number,
00020  *   3. provide your name and address as the primary contact for the
00021  *    support of your modified version, and
00022  *   4. retain our contact information in regard to use of the base
00023  *    software.
00024  * Permission to distribute the released version of the source code along
00025  * with corresponding source modifications in the form of a patch file is
00026  * granted with same provisions 2 through 4 for binary distributions.
00027  *
00028  * This software is provided "as is" without express or implied warranty
00029  * to the extent permitted by applicable law.
00030 ]*/
00031 
00032 #include <mxml.h>
00033 #include <string.h>
00034 #include <stdlib.h>
00035 #define _XOPEN_SOURCE 600
00036 #include <stdlib.h>
00037 #ifndef _WIN32
00038 #include "config.h"
00039 #else
00040 #include "winconfig.h"
00041 #endif
00042 #include "include/interpreter_variable_data.h"
00043 #include "include/message.h"
00044 #include "include/xml_parser.h"
00045 #include "include/xml_helper.h"
00046 
00047 /* *** */
00048 /* agent_xml_parse */
00049 error_code_t agent_xml_parse(agent_p agent)
00050 {
00051   xml_parser_t xml_parser;
00052   xml_parser.root = agent->datastate->xml_agent_root;
00053   xml_parser.node = xml_parser.root;
00054   agent_xml_parse__mobile_agent(agent, &xml_parser);
00055   return MC_SUCCESS;
00056 }
00057 
00058 /* *** */
00059 /* agent_xml_parse__gaf_message */
00060 error_code_t 
00061 agent_xml_parse__mobile_agent
00062 (
00063  agent_p agent, 
00064  xml_parser_p xml_parser
00065  )
00066 {
00067   /* make sure this is the 'MOBILE_AGENT' tag */
00068   if ( 
00069       strcmp(
00070         (const char*)xml_get_element_name(xml_parser->node),
00071         "MOBILE_AGENT"
00072         )
00073      )
00074   {
00075     return MC_ERR_PARSE;
00076   }
00077   /* There is only one child node: AGENT_DATA*/
00078   xml_parser->node = (const mxml_node_t*)xml_get_child(
00079       xml_parser->node,
00080       "AGENT_DATA",
00081       1);
00082 
00083   return agent_xml_parse__agent_data(agent, xml_parser);
00084 }
00085 
00086 /* *** */
00087 /* agent_xml_parse__message */
00088 error_code_t
00089 agent_xml_parse__agent_data
00090 (
00091  agent_p agent,
00092  xml_parser_p xml_parser
00093  )
00094 {
00095   const mxml_node_t* agent_data_node;
00096   error_code_t err_code;
00097   
00098   if (xml_parser->node == NULL) {
00099     return MC_ERR_PARSE;
00100   }
00101 
00102   agent_data_node = xml_parser->node;
00103 
00104   xml_parser->node = xml_get_child(
00105       agent_data_node,
00106       "NAME", 
00107       1
00108       );
00109   if ( (err_code = agent_xml_parse__name(agent, xml_parser)) ) {
00110     return err_code;
00111   }
00112 
00113   xml_parser->node = xml_get_child(
00114       agent_data_node,
00115       "OWNER",
00116       1
00117       );
00118   if ( (err_code = agent_xml_parse__owner(agent, xml_parser)) ) {
00119     return err_code;
00120   }
00121 
00122   xml_parser->node = xml_get_child(
00123       agent_data_node,
00124       "HOME",
00125       1
00126       );
00127   if ( (err_code = agent_xml_parse__home(agent, xml_parser)) ) {
00128     return err_code;
00129   }
00130 
00131   xml_parser->node = xml_get_child(
00132       agent_data_node,
00133       "TASKS",
00134       1
00135       );
00136   if ( (err_code = agent_xml_parse__tasks(agent, xml_parser)) ) {
00137     return err_code;
00138   }
00139   return MC_SUCCESS;
00140 }
00141 
00142 /* *** */
00143 /* agent_xml_parse__name */
00144 error_code_t
00145 agent_xml_parse__name(agent_p agent, xml_parser_p xml_parser)
00146 {
00147   char* text;
00148   const mxml_node_t* name_node;
00149   if (xml_parser->node == NULL) {
00150     return MC_ERR_PARSE;
00151   }
00152   name_node = xml_parser->node;
00153 
00154   text = xml_get_text( name_node );
00155   CHECK_NULL(text, return MC_ERR_PARSE;);
00156 
00157   agent->name = (char*)malloc(
00158       sizeof(char)*(strlen(text)+1)
00159       );
00160   strcpy(
00161       agent->name,
00162       text
00163       );
00164   free(text);
00165   return MC_SUCCESS;
00166 }
00167 
00168 /* *** */
00169 /* agent_xml_parse__owner */
00170 error_code_t
00171 agent_xml_parse__owner(agent_p agent, xml_parser_p xml_parser)
00172 {
00173   char *text;
00174   const mxml_node_t* owner_node;
00175   if (xml_parser->node == NULL) {
00176     /* It's ok if there is no owner node: It is not a required field. */
00177     agent->owner = NULL;
00178     return MC_SUCCESS;
00179   }
00180   owner_node = xml_parser->node;
00181 
00182   text = xml_get_text( owner_node );
00183   CHECK_NULL(text, agent->owner=NULL;return MC_SUCCESS;);
00184   agent->owner = (char*)malloc(
00185       sizeof(char)*(strlen(text)+1)
00186       );
00187   strcpy(
00188       agent->owner,
00189       text
00190       );
00191   free(text);
00192   return MC_SUCCESS;
00193 }
00194 
00195 /* *** */
00196 /* agent_xml_parse__home */
00197 error_code_t
00198 agent_xml_parse__home(agent_p agent, xml_parser_p xml_parser)
00199 {
00200   char *text;
00201   const mxml_node_t* home_node;
00202   if (xml_parser->node == NULL) {
00203     /* It's ok if there is no home node: It is not a required field. */
00204     agent->home= NULL;
00205     return MC_SUCCESS;
00206   }
00207   home_node = xml_parser->node;
00208   text = xml_get_text( home_node );
00209   CHECK_NULL(text, agent->home=NULL;return MC_SUCCESS;);
00210   agent->home = (char*)malloc(
00211       sizeof(char)*(strlen(text)+1)
00212       );
00213   strcpy(
00214       agent->home,
00215       text
00216       );
00217   free(text);
00218   return MC_SUCCESS;
00219 }
00220 
00221 /* *** */
00222 /* agent_xml_parse__tasks */
00223 error_code_t
00224 agent_xml_parse__tasks(agent_p agent, xml_parser_p xml_parser)
00225 {
00226   int i;
00227   int code_num=0;
00228   int err_code;
00229   const char* attribute;
00230   const mxml_node_t* tasks_node;
00231   char buf[20];
00232 
00233   tasks_node = xml_parser->node;
00234 
00235   /* parse the 'task' attribute */
00236   attribute = mxmlElementGetAttr(
00237       (mxml_node_t*)tasks_node,
00238       "task"
00239       );
00240   if (attribute == NULL) {
00241     agent->datastate->number_of_tasks = 1;
00242   } else {
00243     agent->datastate->number_of_tasks = atoi((char*)attribute);
00244   }
00245   agent->datastate->tasks = (agent_task_p*)malloc(
00246       sizeof(agent_task_p) * agent->datastate->number_of_tasks
00247       );
00248 
00249   /* parse the 'num' attribute */
00250   attribute = mxmlElementGetAttr(
00251       (mxml_node_t*)tasks_node,
00252       "num"
00253       );
00254   if (attribute == NULL) {
00255     agent->datastate->task_progress = 0;
00256   } else {
00257     agent->datastate->task_progress = atoi((char*)attribute);
00258   }
00259 
00260   /* Allocate each task */
00261   for(i = 0; i<agent->datastate->number_of_tasks; i++) {
00262     agent->datastate->tasks[i] = agent_task_New();
00263   }
00264 
00265   /* Parse each task */
00266   for(i = 0; i < agent->datastate->number_of_tasks; i++) {
00267     sprintf(buf, "%d", i);
00268     xml_parser->node = mxmlFindElement(
00269         tasks_node,
00270         tasks_node,
00271         "TASK",
00272         "num",
00273         buf,
00274         MXML_DESCEND_FIRST );
00275     if(xml_parser->node == NULL) {
00276       fprintf(stderr,
00277           "ERROR: Could not find task num %d! %s:%d\n",
00278           i, __FILE__, __LINE__);
00279       return MC_ERR_PARSE;
00280     }
00281     agent_xml_parse__task(agent, xml_parser, i);
00282   }
00283 
00284   /* Need to get all of the agent codes. Even though we may execute only
00285    * one right now, in the future, the agent may decide at runtime which block
00286    * to execute, so we need them all. */
00287   xml_parser->node = mxmlFindElement
00288       (
00289        tasks_node,
00290        tasks_node,
00291        "AGENT_CODE",
00292        NULL,
00293        NULL,
00294        MXML_DESCEND
00295       );
00296 
00297 
00298   /* First we count the number of code blocks */
00299   while(xml_parser->node != NULL) {
00300     code_num++;
00301     xml_parser->node = mxmlFindElement
00302       (
00303        xml_parser->node,
00304        tasks_node,
00305        "AGENT_CODE",
00306        NULL,
00307        NULL,
00308        MXML_NO_DESCEND
00309       );
00310   }
00311 
00312   /* Allocate correct amount of memory for code blocks. */
00313   agent->datastate->agent_code_ids = (char**)malloc
00314     (
00315      (code_num+1) * sizeof(char*)
00316     );
00317   agent->datastate->agent_codes = (char**)malloc
00318     (
00319      (code_num+1) * sizeof(char*)
00320     );
00321   /* Set sigil */
00322   agent->datastate->agent_code_ids[code_num] = NULL;
00323   agent->datastate->agent_codes[code_num] = NULL;
00324 
00325   /* Go through all code again and parse */
00326   xml_parser->node = mxmlFindElement
00327       (
00328        tasks_node,
00329        tasks_node,
00330        "AGENT_CODE",
00331        NULL,
00332        NULL,
00333        MXML_DESCEND
00334       );
00335   i = 0;
00336   while(xml_parser->node != NULL) {
00337     err_code = agent_xml_parse__agent_code(agent, i, xml_parser);
00338     i++;
00339     xml_parser->node = mxmlFindElement
00340       (
00341        xml_parser->node,
00342        tasks_node,
00343        "AGENT_CODE",
00344        NULL,
00345        NULL,
00346        MXML_NO_DESCEND
00347       );
00348   }
00349 
00350   if (agent->datastate->agent_code == NULL) {
00351     /* Something is wrong. */
00352     fprintf(stderr, "Parse error: Agent code not found. %s:%d\n", __FILE__, __LINE__);
00353     return MC_ERR_PARSE;
00354   }
00355 
00356   return 0;
00357 }
00358 
00359 /* *** */
00360 /* agent_xml_parse__task */
00361 error_code_t
00362 agent_xml_parse__task(agent_p agent, xml_parser_p xml_parser, int index)
00363 {
00364   const char* attribute;
00365   const mxml_node_t* task_node;
00366   error_code_t err_code = MC_SUCCESS;
00367   CHECK_NULL(xml_parser->node, return MC_ERR_PARSE;);
00368   task_node = xml_parser->node;
00369 
00370   /* Parse the multiple DATA nodes */
00371   xml_parser->node = mxmlFindElement(
00372       task_node,
00373       task_node,
00374       "DATA",
00375       NULL,
00376       NULL,
00377       MXML_DESCEND_FIRST);
00378   while(xml_parser->node != NULL) {
00379     /* There may be no DATA nodes */
00380     if ((err_code = agent_xml_parse__data(agent, xml_parser, index)))
00381     {
00382       return err_code;
00383     }
00384     xml_parser->node = mxmlFindElement(
00385         xml_parser->node,
00386         task_node,
00387         "DATA",
00388         NULL,
00389         NULL,
00390         MXML_NO_DESCEND );
00391   }
00392 
00393   /* 'code_id' */
00394   attribute = mxmlElementGetAttr(
00395       (mxml_node_t*)task_node,
00396       "code_id");
00397   if (attribute != NULL) {
00398     agent->datastate->tasks[index]->code_id = malloc
00399       (
00400        sizeof(char) * 
00401        (strlen(attribute) + 1)
00402       );
00403     strcpy(agent->datastate->tasks[index]->code_id, attribute);
00404   } else {
00405     agent->datastate->tasks[index]->code_id = NULL;
00406   }
00407 
00408   /* 'num' - The number of this task (indexed from 0) */
00409   attribute = mxmlElementGetAttr(
00410       (mxml_node_t*)task_node,
00411       "num"
00412       );
00413   CHECK_NULL(attribute, return MC_ERR_PARSE;);
00414 
00415   /* 'complete' - Is this task complete?*/
00416   attribute = mxmlElementGetAttr(
00417       (mxml_node_t*)task_node,
00418       "complete"
00419       );
00420   CHECK_NULL(attribute, return MC_ERR_PARSE;);
00421   agent->datastate->tasks[index]->task_completed = 
00422     atoi((char*)attribute);
00423   
00424   /* 'server' - The server this task should be performed on */
00425   attribute = mxmlElementGetAttr(
00426       (mxml_node_t*)task_node,
00427       "server"
00428       );
00429   CHECK_NULL(attribute, return MC_ERR_PARSE;);
00430   agent->datastate->tasks[index]->server_name = 
00431     (char*)malloc(sizeof(char) * (strlen(attribute)+1) );
00432   strcpy(
00433       agent->datastate->tasks[index]->server_name,
00434       attribute
00435       );
00436 
00437   /* 'return' - The name of the return variable, if there is one */
00438   attribute = mxmlElementGetAttr(
00439       (mxml_node_t*)task_node,
00440       "return" );
00441   if (attribute == NULL) {
00442     agent->datastate->tasks[index]->var_name = strdup("no-return");
00443   } else {
00444     agent->datastate->tasks[index]->var_name = strdup(attribute);
00445   }
00446   CHECK_NULL(agent->datastate->tasks[index]->var_name, exit(1););
00447 
00448   return err_code;
00449 }
00450 
00451 /* *** */
00452 /* agent_xml_parse__data */
00453 error_code_t
00454 agent_xml_parse__data(agent_p agent, xml_parser_p xml_parser, int index)
00455 {
00456   const char* attribute;
00457   const char* attribute2;
00458   const mxml_node_t *data_node;
00459   int data_type_size;
00460   interpreter_variable_data_t* interp_variable;
00461   if (xml_parser->node == NULL) {
00462     return MC_ERR_PARSE;
00463   }
00464   if (strcmp(
00465         "DATA",
00466         xml_get_element_name(xml_parser->node) )
00467      )
00468   {
00469     return MC_ERR_PARSE;
00470   }
00471   data_node = xml_parser->node;
00472 
00473   /* Check to see if this is the return variable */
00474   attribute = mxmlElementGetAttr(
00475       data_node->parent,
00476       "return" );
00477   attribute2 = mxmlElementGetAttr(
00478       data_node,
00479       "name" );
00480   if (attribute != NULL && !strcmp(attribute, attribute2)) {
00481     /* This variable is the return variable. */
00482 
00483     /* Allocate Return data structure */
00484     /* FIXME: This may not be the right place to do this,
00485      * but it is safe and leak free. */
00486     agent->datastate->tasks[index]->agent_return_data = 
00487       interpreter_variable_data_New(); 
00488     interp_variable = agent->datastate->tasks[index]->agent_return_data;
00489   } else {
00490     interp_variable = interpreter_variable_data_New();
00491     agent_variable_list_Add(
00492         agent->datastate->tasks[index]->agent_variable_list,
00493         interp_variable );
00494   }
00495 
00496 
00497   /* Attributes we need to parse:
00498    * O dim          - dimension of the return data
00499    * O name         - name of the return variable
00500    * O persistent   - is the agent persistent for this task?
00501    * O type         - return variable type
00502    * O return_value - return value, if not an array
00503    * O code_id      - ID of the code block to execute. If this
00504    *                  attribute is missing, execute the first 
00505    *                  code block available.
00506    *
00507    * 'O' denotes optional attribute. */
00508 
00509 
00510   /* 'dim' */
00511   attribute = mxmlElementGetAttr(
00512       (mxml_node_t*)xml_parser->node,
00513       "dim"
00514       );
00515   if (attribute != NULL) {
00516     interp_variable->array_dim = 
00517       atoi((char*)attribute);
00518   } else {
00519     interp_variable->array_dim = 
00520       0;
00521   }
00522 
00523   /* 'name' */
00524   attribute = mxmlElementGetAttr(
00525       (mxml_node_t*)xml_parser->node,
00526       "name"
00527       );
00528   if (attribute != NULL) {
00529     interp_variable->name = 
00530       (char*)malloc(sizeof(char)*(strlen(attribute)+1));
00531     strcpy(
00532         interp_variable->name,
00533         attribute
00534         );
00535   }
00536 
00537   /* 'persistent' */
00538   attribute = mxmlElementGetAttr(
00539       (mxml_node_t*)data_node,
00540       "persistent"
00541       );
00542   if (attribute != NULL) {
00543     agent->datastate->tasks[index]->persistent = 
00544       atoi((char*)attribute);
00545   } else {
00546     agent->datastate->tasks[index]->persistent = 0;
00547   }
00548 
00549   /* 'type' */
00550   attribute = mxmlElementGetAttr(
00551       (mxml_node_t*)data_node,
00552       "type"
00553       );
00554   if (attribute != NULL) {
00555     CH_STRING_DATATYPE(
00556         attribute,
00557         interp_variable->data_type
00558         );
00559     CH_DATATYPE_SIZE(
00560         interp_variable->data_type,
00561         data_type_size
00562         );
00563   } else {
00564     interp_variable->data_type = 
00565       CH_UNDEFINETYPE;
00566     data_type_size = 0;
00567   }
00568 
00569   if (interp_variable->array_dim == 0) {
00570   /* 'return_value' */
00571     attribute = mxmlElementGetAttr(
00572         (mxml_node_t*)data_node,
00573         "value" );
00574     if (attribute != NULL && data_type_size != 0) {
00575       interp_variable->data =
00576         malloc(data_type_size);
00577       CH_DATATYPE_STR_TO_VAL(
00578           interp_variable->data_type,
00579           attribute,
00580           interp_variable->data
00581           );
00582     }
00583   } else {
00584     /* The only possible child node to parse are row nodes. */
00585     xml_parser->node = xml_get_child(
00586         xml_parser->node,
00587         "ROW",
00588         1
00589         );
00590     agent_xml_parse__row(interp_variable, xml_parser, index);
00591   }
00592   xml_parser->node = data_node;
00593   return MC_SUCCESS;
00594 }
00595 
00596 /* *** */
00597 /* agent_xml_parse__row */
00598 error_code_t
00599 agent_xml_parse__row(interpreter_variable_data_t* interp_variable, xml_parser_p xml_parser, int index)
00600 {
00601   int j;
00602   int data_type_size;
00603   int tmp;
00604   int num_elements;
00605   const mxml_node_t* row_node;
00606 
00607   if (xml_parser->node == NULL) {
00608     return MC_SUCCESS;
00609   }
00610 
00611   if (strcmp(
00612         xml_get_element_name(xml_parser->node),
00613         "ROW" )
00614      )
00615   {
00616     return MC_SUCCESS;
00617   }
00618   row_node = xml_parser->node;
00619 
00620   /* malloc mem for the task data elements */
00621   /* First, find the extents of the dimensions */
00622   if (interp_variable->array_dim != 0) {
00623     interp_variable->array_extent = (int*)
00624       malloc
00625       (
00626        sizeof(int) * 
00627        interp_variable->array_dim
00628       );
00629     tmp = 0;
00630     agent_xml_parse__fill_row_data(NULL,
00631         interp_variable->data_type,
00632         interp_variable->array_extent,
00633         row_node,
00634         &tmp);
00635     num_elements = 1;
00636     for (j = 0; j<interp_variable->array_dim; j++) {
00637       num_elements *= interp_variable->array_extent[j];
00638     }
00639 
00640     /* Allocate space for the return data */
00641     CH_DATATYPE_SIZE
00642       (
00643        interp_variable->data_type,
00644        data_type_size
00645       );
00646     interp_variable->data =
00647       malloc(num_elements * data_type_size);
00648 
00649     /* Get the data */
00650     tmp = 0;
00651     agent_xml_parse__fill_row_data(
00652         interp_variable->data,
00653         interp_variable->data_type,
00654         interp_variable->array_extent,
00655         row_node,
00656         &tmp );
00657   } else { 
00658     return MC_SUCCESS;
00659   }
00660   return MC_SUCCESS;
00661 }
00662 
00663 void agent_xml_parse__fill_row_data(
00664         void *data,
00665         ChType_t type,
00666         int *extent,
00667         const mxml_node_t* node,
00668         int *index) 
00669 {
00670   mxml_node_t* tmp_node;
00671   int i=0;
00672   char *buf;
00673   char *tmp;
00674 #ifndef _WIN32
00675   char *saveptr;
00676 #endif
00677   int datasize;
00678   /* Check to see if the child is an element or text. All children must be
00679    * either an element or text. If it is text, that means we are at the very bottom 
00680    * and we need to retrive data. */
00681   (*extent) = 0; 
00682   if (node->child->type == MXML_TEXT) {
00683     node = node->child;
00684     /* Now we parse the data */
00685     CH_DATATYPE_SIZE(type, datasize);
00686     buf = (char*)malloc(
00687         sizeof(char) +
00688         (strlen(node->value.text.string) + 1));
00689     strcpy(buf, node->value.text.string);
00690     /* Tokenize by commas */
00691 #ifndef _WIN32
00692     tmp = strtok_r(buf, ",", &saveptr);
00693 #else
00694     tmp = strtok(buf, ",");
00695 #endif
00696     while ( tmp != NULL) {
00697       switch(type) {
00698         case CH_CHARTYPE:
00699           if (data != NULL)
00700             ((char*)data)[*index] = *(char*)tmp;
00701           (*index)++;
00702           break;
00703         case CH_INTTYPE:
00704           if (data != NULL)
00705             ((int*)data)[*index] = strtol(tmp, NULL, 0);
00706           (*index)++;
00707           break;
00708         case CH_UINTTYPE:
00709           if (data != NULL)
00710             ((unsigned int*)data)[*index] = strtoul(tmp, NULL, 0);
00711           (*index)++;
00712           break;
00713         case CH_SHORTTYPE:
00714           if (data != NULL)
00715             ((short*)data)[*index] = (short)strtol(tmp, NULL, 0);
00716           (*index)++;
00717           break;
00718         case CH_USHORTTYPE:
00719           if (data != NULL)
00720             ((unsigned short*)data)[*index] = (unsigned short)strtol(tmp, NULL, 0);
00721           (*index)++;
00722           break;
00723         case CH_FLOATTYPE:
00724           if (data != NULL)
00725 #ifndef _WIN32
00726             ((float*)data)[*index] = strtof(tmp, NULL);
00727 #else   
00728           ((float*)data)[*index] = (float)strtod(tmp, NULL);
00729 #endif
00730           (*index)++;
00731           break;
00732         case CH_DOUBLETYPE:
00733           if (data != NULL)
00734             ((double*)data)[*index] = strtod(tmp, NULL);
00735           (*index)++;
00736           break;
00737         default:
00738           fprintf(stderr, 
00739               "Unsupported data type: %d %s:%d\n",
00740               type, __FILE__, __LINE__);
00741       }
00742 #ifndef _WIN32
00743       tmp = strtok_r(NULL, ",", &saveptr);
00744 #else
00745       tmp = strtok(NULL, ",");
00746 #endif
00747       (*extent)++;
00748     }
00749     free(buf);
00750   } else if (node->type == MXML_ELEMENT) {
00751     buf = (char*)malloc(sizeof(char)*10);
00752     buf[0] = '\0';
00753     sprintf(buf, "%d", i);
00754     tmp_node = mxmlFindElement(
00755         (mxml_node_t*)node,
00756         (mxml_node_t*)node,
00757         "ROW",
00758         "index",
00759         buf,
00760         MXML_DESCEND_FIRST);
00761     while (tmp_node != NULL) {
00762       (*extent)++;
00763       agent_xml_parse__fill_row_data(data, type,(extent+1), tmp_node, index);
00764       i++;
00765       buf[0] = '\0';
00766       sprintf(buf, "%d", i);
00767       tmp_node = mxmlFindElement(
00768           (mxml_node_t*)node,
00769           (mxml_node_t*)node,
00770           "ROW",
00771           "index",
00772           buf,
00773           MXML_DESCEND_FIRST);
00774     }
00775     free(buf);
00776   }
00777 }
00778 
00779 /* *** */
00780 /* agent_xml_parse__agent_code */
00781 error_code_t
00782 agent_xml_parse__agent_code(agent_p agent, int index, xml_parser_p xml_parser)
00783 {
00784   char *attribute;
00785   int cur_task = agent->datastate->task_progress;
00786   if( cur_task == agent->datastate->number_of_tasks )
00787     cur_task--;
00788   agent->datastate->agent_codes[index] = 
00789     xml_get_text
00790     (
00791      xml_parser->node
00792     );
00793 
00794   /* Get the code id */
00795   attribute = mxmlElementGetAttr
00796     (
00797      (mxml_node_t*)xml_parser->node,
00798      "id"
00799     );
00800   if (attribute) {
00801     agent->datastate->agent_code_ids[index] = malloc
00802       (
00803        sizeof(char) * 
00804        (strlen(attribute) + 1)
00805       );
00806     strcpy(agent->datastate->agent_code_ids[index], attribute);
00807   } else {
00808     agent->datastate->agent_code_ids[index] = malloc(sizeof(char));
00809     *(agent->datastate->agent_code_ids[index]) = '\0';
00810   }
00811   if (agent->datastate->tasks[cur_task]->code_id && attribute != NULL) {
00812     if (!strcmp(attribute, agent->datastate->tasks[cur_task]->code_id)) {
00813       agent->datastate->agent_code = agent->datastate->agent_codes[index];
00814     }
00815   } else {
00816     agent->datastate->agent_code = agent->datastate->agent_codes[0];
00817   }
00818   return MC_SUCCESS;
00819 }
00820 
00821 /* agent return parsing ******************************************************/
00822 error_code_t
00823 agent_return_xml_parse(agent_p agent)
00824 {
00825   xml_parser_t xml_parser;
00826   xml_parser.root = agent->datastate->xml_root;
00827   xml_parser.node = (const mxml_node_t*)xml_get_child(
00828       xml_parser.root,
00829       "NAME",
00830       1);
00831       
00832   agent_xml_parse__name(agent, &xml_parser);
00833 
00834   xml_parser.node = (const mxml_node_t*)xml_get_child(
00835       xml_parser.root,
00836       "OWNER",
00837       1);
00838 
00839   agent_xml_parse__owner(agent, &xml_parser);
00840 
00841   xml_parser.node = (const mxml_node_t*)xml_get_child(
00842       xml_parser.root,
00843       "HOME",
00844       1);
00845 
00846   agent_xml_parse__home(agent, &xml_parser);
00847 
00848   xml_parser.node = (const mxml_node_t*)xml_get_child(
00849       xml_parser.root,
00850       "TASK",
00851       1);
00852 
00853   agent_xml_parse__tasks(agent, &xml_parser);
00854   return MC_SUCCESS;
00855 }
00856 /* message parsing  **********************************************************/
00857 error_code_t
00858 message_xml_parse(message_p message)
00859 {
00860   int err_code;
00861   xml_parser_p xml_parser;
00862   xml_parser = (xml_parser_p)malloc(sizeof(xml_parser_t));
00863   xml_parser->root = message->xml_root;
00864   xml_parser->node = mxmlFindElement
00865     (
00866      (mxml_node_t*)xml_parser->root,
00867      (mxml_node_t*)xml_parser->root,
00868      "MOBILEC_MESSAGE",
00869      NULL,
00870      NULL,
00871      MXML_NO_DESCEND
00872     );
00873   if (xml_parser->node == NULL) {
00874     xml_parser->node = mxmlFindElement
00875       (
00876        (mxml_node_t*)xml_parser->root,
00877        (mxml_node_t*)xml_parser->root,
00878        "MOBILEC_MESSAGE",
00879        NULL,
00880        NULL,
00881        MXML_DESCEND
00882       );
00883   }
00884   if (xml_parser->node == NULL) {
00885     err_code = MC_ERR_PARSE;
00886     goto cleanup;
00887   }
00888   xml_parser->root = xml_parser->node;
00889   if(
00890       strcmp(
00891         (const char*)xml_get_element_name(xml_parser->node),
00892         "MOBILEC_MESSAGE"
00893         )
00894     )
00895   {
00896     fprintf(stderr, "Parse error. %s:%d\n", __FILE__, __LINE__);
00897     err_code = MC_ERR_PARSE;
00898     goto cleanup;
00899   }
00900   xml_parser->node = (const mxml_node_t*)xml_get_child
00901     (
00902      xml_parser->node,
00903      "MESSAGE",
00904      1
00905     );
00906   err_code = message_xml_parse__message(message, xml_parser);
00907 cleanup:
00908   free(xml_parser);
00909   return err_code;
00910 }
00911 
00912 error_code_t
00913 message_xml_parse__message(message_p message, xml_parser_p xml_parser)
00914 {
00915   const char* attribute;
00916   char* buf;
00917   char* hostname;
00918   char* port_str;
00919 #ifndef _WIN32
00920   char* save_ptr; /* Save ptr for re-entrant strtok */
00921 #endif
00922   int port;
00923   if (xml_parser->node == NULL) {
00924     return MC_ERR_PARSE;
00925   }
00926   attribute = mxmlElementGetAttr
00927     (
00928      (mxml_node_t*)xml_parser->node,
00929      "message"
00930     );
00931   if (!strcmp(attribute, "MOBILE_AGENT")) {
00932     message->message_type = MOBILE_AGENT;
00933     message->xml_payload = xml_get_child
00934       (
00935        xml_parser->node,
00936        "MOBILE_AGENT",
00937        1
00938       );
00939   } else if (!strcmp(attribute, "RETURN_MSG")) {
00940     message->message_type = RETURN_MSG;
00941     message->xml_payload = xml_get_child
00942       (
00943        xml_parser->node,
00944        "MOBILE_AGENT",
00945        1
00946       );
00947   } else if (!strcmp(attribute, "ACL")) {
00948     message->message_type = FIPA_ACL;
00949   } else if (!strcmp(attribute, "ENCRYPTION_INITIALIZE")) {
00950     message->message_type = ENCRYPTION_INITIALIZE;
00951     message->xml_payload = xml_get_child
00952       (
00953        xml_parser->node,
00954        "ENCRYPTION_DATA",
00955        1
00956       );
00957   } else if (!strcmp(attribute, "ENCRYPTED_DATA")) {
00958     message->message_type = ENCRYPTED_DATA;
00959     message->xml_payload = xml_get_child
00960       (
00961        xml_parser->node,
00962        "ENCRYPTED_DATA",
00963        1
00964       );
00965   } else if (!strcmp(attribute, "REQUEST_ENCRYPTION_INITIALIZE")) {
00966     message->message_type = REQUEST_ENCRYPTION_INITIALIZE;
00967   } else {
00968     fprintf(stderr, "Parse error. %s:%d\n", __FILE__, __LINE__);
00969     return MC_ERR_PARSE;
00970   }
00971   attribute = mxmlElementGetAttr
00972     (
00973      (mxml_node_t*)xml_parser->node,
00974      "from"
00975     );
00976   if(attribute != NULL) {
00977     /* Free 'from_address' first, if we need. */
00978     if(message->from_address) free(message->from_address);
00979     message->from_address = (char*)malloc
00980       (
00981        sizeof(char) * 
00982        (strlen(attribute)+1)
00983       );
00984     CHECK_NULL(message->from_address, exit(0););
00985     strcpy(message->from_address, attribute);
00986     buf = (char*)malloc
00987       (
00988        sizeof(char) * 
00989        (strlen(message->from_address)+1)
00990       );
00991     CHECK_NULL(buf, exit(0););
00992     strcpy(buf, message->from_address);
00993     hostname = strtok_r(buf, ":", &save_ptr);
00994     port_str = strtok_r(NULL, ":", &save_ptr);
00995     port = atoi(port_str);
00996     message->addr->sin_port = htons(port);
00997     free(buf);
00998   }
00999   return MC_SUCCESS;
01000 }
01001   
01002 

Generated on Mon Jun 23 16:01:12 2008 for Mobile-C by  doxygen 1.5.4