/home/dko/projects/mobilec/trunk/src/fipa_acl.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 <stdio.h>
00033 #include <stdlib.h>
00034 #include <string.h>
00035 #ifndef _WIN32
00036 #include <strings.h>
00037 #else
00038 #define strcasecmp(a, b) \
00039   _stricmp(a, b)
00040 #endif
00041 #include "include/fipa_acl.h"
00042 #include "include/mc_error.h"
00043 #include "include/macros.h"
00044 
00045 #define FREEMEM(x) \
00046   if (x != NULL) free(x)
00047 
00048 /* fipa_acl_message */
00049 fipa_acl_message_t* fipa_acl_message_New(void)
00050 {
00051   fipa_acl_message_t* acl;
00052   acl = (fipa_acl_message_t*)malloc(sizeof(fipa_acl_message_t));
00053   memset(acl, 0, sizeof(fipa_acl_message_t));
00054   return acl;
00055 }
00056 
00057 int fipa_acl_message_Destroy(fipa_acl_message_t* message)
00058 {
00059 
00060   if (message == NULL) return 0;
00061   fipa_agent_identifier_Destroy(message->sender);
00062   fipa_agent_identifier_set_Destroy(message->receiver);
00063   fipa_agent_identifier_set_Destroy(message->reply_to);
00064   fipa_string_Destroy(message->content);
00065   fipa_expression_Destroy(message->language);
00066   fipa_expression_Destroy(message->encoding);
00067   fipa_expression_Destroy(message->ontology);
00068   fipa_word_Destroy(message->protocol);
00069   fipa_expression_Destroy(message->conversation_id);
00070   fipa_expression_Destroy(message->reply_with);
00071   fipa_expression_Destroy(message->in_reply_to);
00072   fipa_DateTime_Destroy(message->reply_by);
00073   
00074   free(message);
00075   return 0;
00076 }
00077 
00078 fipa_acl_message_t* fipa_acl_message_Copy(fipa_acl_message_t* src)
00079 {
00080   fipa_acl_message_t* copy;
00081   if (src == NULL) return NULL;
00082   copy = fipa_acl_message_New();
00083   copy->performative = src->performative;
00084   copy->sender = fipa_agent_identifier_Copy(src->sender);
00085   copy->receiver = fipa_agent_identifier_set_Copy(src->receiver);
00086   copy->reply_to = fipa_agent_identifier_set_Copy(src->reply_to);
00087   copy->content = fipa_string_Copy(src->content);
00088   copy->language = fipa_expression_Copy(src->language);
00089   copy->encoding = fipa_expression_Copy(src->encoding);
00090   copy->ontology = fipa_expression_Copy(src->ontology);
00091   copy->protocol = fipa_word_Copy(src->protocol);
00092   copy->conversation_id = fipa_expression_Copy(src->conversation_id);
00093   copy->reply_with = fipa_expression_Copy(src->reply_with);
00094   copy->in_reply_to = fipa_expression_Copy(src->in_reply_to);
00095   copy->reply_by = fipa_DateTime_Copy(src->reply_by);
00096 
00097   return copy;
00098 }
00099 
00100 /* fipa_message_string */
00101 fipa_message_string_t* fipa_message_string_New(void)
00102 {
00103   fipa_message_string_t* str;
00104   str = (fipa_message_string_t*)malloc(sizeof(fipa_message_string_t));
00105   memset(str, 0, sizeof(fipa_message_string_t));
00106   return str;
00107 }
00108 
00109 int fipa_message_string_Destroy(fipa_message_string_t* message)
00110 {
00111   if (message == NULL) return 0;
00112   if (message->message != NULL) {
00113     free(message->message);
00114   }
00115   free(message); 
00116   return 0;
00117 }
00118 
00119 fipa_message_string_t* fipa_message_string_Copy(fipa_message_string_t* src)
00120 {
00121   fipa_message_string_t* copy;
00122   if (src == NULL) return NULL;
00123   copy->message = strdup(src->message);
00124   copy->parse = copy->message + (src->parse - src->message);
00125   return copy;
00126 }
00127 
00128 /* fipa_url_sequence */
00129 fipa_url_sequence_t* fipa_url_sequence_New(void)
00130 {
00131   fipa_url_sequence_t* sequence;
00132   sequence = (fipa_url_sequence_t*)malloc(sizeof(fipa_url_sequence_t));
00133   memset(sequence, 0, sizeof(fipa_url_sequence_t));
00134   return sequence;
00135 }
00136 
00137 int fipa_url_sequence_Destroy(fipa_url_sequence_t* sequence)
00138 {
00139   int i;
00140   if (sequence == NULL) return 0;
00141   for (i = 0; i < sequence->num; i++) {
00142     fipa_url_Destroy(sequence->urls[i]);
00143   }
00144   free(sequence->urls); 
00145   free(sequence);
00146   return 0;
00147 }
00148 
00149 fipa_url_sequence_t* fipa_url_sequence_Copy(fipa_url_sequence_t* src)
00150 {
00151   int i;
00152   fipa_url_sequence_t* copy;
00153   if (src == NULL) return NULL;
00154   copy = fipa_url_sequence_New();
00155   copy->num = src->num;
00156   copy->urls = (fipa_url_t**)malloc(
00157       sizeof(fipa_url_t*) * src->num);
00158   for( i = 0; i < src->num; i++) {
00159     copy->urls[i] = fipa_url_Copy(src->urls[i]);
00160   }
00161   return copy;
00162 }
00163 
00164 /* fipa_agent_identifier_set */
00165 fipa_agent_identifier_set_t* fipa_agent_identifier_set_New(void)
00166 {
00167   fipa_agent_identifier_set_t* set;
00168   set = (fipa_agent_identifier_set_t*)malloc(sizeof(fipa_agent_identifier_set_t));
00169   memset(set, 0, sizeof(fipa_agent_identifier_set_t));
00170   return set;
00171 }
00172 
00173 int fipa_agent_identifier_set_Destroy(fipa_agent_identifier_set_t* idset)
00174 {
00175   int i;
00176   if (idset == NULL) return 0;
00177   for(i = 0; i < idset->num; i++) {
00178     fipa_agent_identifier_Destroy(idset->fipa_agent_identifiers[i]);
00179   }
00180   free(idset->fipa_agent_identifiers); 
00181   free(idset);
00182   return 0;
00183 }
00184 
00185 fipa_agent_identifier_set_t* fipa_agent_identifier_set_Copy(
00186     fipa_agent_identifier_set_t* src)
00187 {
00188   int i;
00189   fipa_agent_identifier_set_t* copy;
00190 
00191   if (src == NULL) { return NULL; }
00192   copy = fipa_agent_identifier_set_New();
00193   copy->num = src->num;
00194   copy->retain_order = src->retain_order;
00195   copy->fipa_agent_identifiers = (fipa_agent_identifier_t**)malloc(
00196       sizeof(fipa_agent_identifier_t*) * src->num);
00197   for(i = 0; i < src->num; i++) {
00198     copy->fipa_agent_identifiers[i] = fipa_agent_identifier_Copy(
00199         src->fipa_agent_identifiers[i]);
00200   }
00201 
00202   return copy;
00203 }
00204 
00205 /* fipa_agent_identifier */
00206 fipa_agent_identifier_t* fipa_agent_identifier_New(void)
00207 {
00208   fipa_agent_identifier_t* id;
00209   id = (fipa_agent_identifier_t*)malloc(sizeof(fipa_agent_identifier_t));
00210   memset(id, 0, sizeof(fipa_agent_identifier_t));
00211   return id;
00212 }
00213 
00214 int fipa_agent_identifier_Destroy(fipa_agent_identifier_t* id)
00215 {
00216   if (id == NULL) return 0;
00217   if (id->name != NULL) {
00218     free(id->name);
00219   }
00220   fipa_url_sequence_Destroy(id->addresses);
00221   fipa_agent_identifier_set_Destroy(id->resolvers);
00222   free(id); 
00223   return 0;
00224 }
00225 
00226 fipa_agent_identifier_t* fipa_agent_identifier_Copy(fipa_agent_identifier_t* src)
00227 {
00228   fipa_agent_identifier_t* copy;
00229   if (src == NULL) return NULL;
00230   copy = fipa_agent_identifier_New();
00231   copy->name = strdup(src->name);
00232   copy->addresses = fipa_url_sequence_Copy(src->addresses);
00233   copy->resolvers = fipa_agent_identifier_set_Copy(src->resolvers);
00234   return copy;
00235 }
00236 
00237 /* fipa_expression */
00238 fipa_expression_t* fipa_expression_New(void)
00239 {
00240   fipa_expression_t* expr;
00241   expr = (fipa_expression_t*)malloc(sizeof(fipa_expression_t));
00242   memset(expr, 0, sizeof(fipa_expression_t));
00243   return expr;
00244 }
00245 
00246 int fipa_expression_Destroy(fipa_expression_t* expr)
00247 {
00248   int i;
00249   if (expr == NULL) return 0;
00250   switch (expr->type) {
00251     case FIPA_EXPR_WORD:
00252       fipa_word_Destroy(expr->content.word);
00253       break;
00254     case FIPA_EXPR_STRING:
00255       fipa_string_Destroy(expr->content.string);
00256       break;
00257     case FIPA_EXPR_NUMBER:
00258       fipa_number_Destroy(expr->content.number);
00259       break;
00260     case FIPA_EXPR_DATETIME:
00261       fipa_DateTime_Destroy(expr->content.datetime);
00262       break;
00263     case FIPA_EXPR_EXPRESSION:
00264       if (expr->content.expression == NULL) break;
00265       for (i = 0; expr->content.expression[i] != NULL; i++) {
00266         fipa_expression_Destroy(expr->content.expression[i]);
00267       }
00268       FREEMEM(expr->content.expression);
00269       break;
00270     default:
00271       break;
00272   }
00273   free(expr);
00274   return 0;
00275 }
00276 
00277 fipa_expression_t* fipa_expression_Copy(fipa_expression_t* src)
00278 {
00279   int i, num;
00280   fipa_expression_t* copy;
00281   if (src == NULL) return NULL;
00282   copy = fipa_expression_New();
00283   copy->type = src->type;
00284   switch(src->type) {
00285     case FIPA_EXPR_WORD:
00286       copy->content.word = fipa_word_Copy(src->content.word);
00287       break;
00288     case FIPA_EXPR_STRING:
00289       copy->content.string = fipa_string_Copy(src->content.string);
00290       break;
00291     case FIPA_EXPR_NUMBER:
00292       copy->content.number = fipa_number_Copy(src->content.number);
00293       break;
00294     case FIPA_EXPR_DATETIME:
00295       copy->content.datetime = fipa_DateTime_Copy(src->content.datetime);
00296       break;
00297     case FIPA_EXPR_EXPRESSION:
00298       /* We need to figure out how many expressions there are first. */
00299       for(i = 0; src->content.expression[i] != NULL; i++);
00300       /* Now copy them */
00301       num = i;
00302       copy->content.expression = (fipa_expression_t**)malloc(
00303           sizeof(fipa_expression_t*) * (num + 1));
00304       for(i = 0; i < num; i++) {
00305         copy->content.expression[i] = fipa_expression_Copy(
00306             src->content.expression[i] );
00307       }
00308       copy->content.expression[num] = NULL;
00309       break;
00310     default:
00311       fipa_expression_Destroy(copy);
00312       return NULL;
00313   }
00314   return copy;
00315 }
00316       
00317 /* fipa_word */
00318 fipa_word_t* fipa_word_New(void)
00319 {
00320   fipa_word_t* word;
00321   word = (fipa_word_t*)malloc(sizeof(fipa_word_t));
00322   memset(word, 0, sizeof(fipa_word_t));
00323   return word;
00324 }
00325 
00326 int fipa_word_Destroy(fipa_word_t* word)
00327 {
00328   if (word == NULL) return 0;
00329   if (word->content != NULL) {
00330     free( word->content );
00331   }
00332   free(word);
00333   return 0;
00334 }
00335 
00336 fipa_word_t* fipa_word_Copy(fipa_word_t* src)
00337 {
00338   fipa_word_t* copy;
00339   if (src == NULL) return NULL;
00340   copy = fipa_word_New();
00341   copy->content = strdup(src->content);
00342   return copy;
00343 }
00344 
00345 /* fipa_string */
00346 fipa_string_t* fipa_string_New(void)
00347 {
00348   fipa_string_t* str;
00349   str = (fipa_string_t*)malloc(sizeof(fipa_string_t));
00350   memset(str, 0, sizeof(fipa_string_t));
00351   return str;
00352 }
00353 
00354 int fipa_string_Destroy(fipa_string_t* str)
00355 {
00356   if (str == NULL) return 0;
00357   if (str->content != NULL) {
00358     free(str->content);
00359   }
00360   free(str);
00361   return 0;
00362 }
00363 
00364 fipa_string_t* fipa_string_Copy(fipa_string_t* src)
00365 {
00366   fipa_string_t* copy;
00367   if (src == NULL) return NULL;
00368   copy = fipa_string_New();
00369   copy->content = strdup(src->content);
00370   return copy;
00371 }
00372 
00373 /* fipa_DateTime */
00374 fipa_DateTime_t* fipa_DateTime_New(void)
00375 {
00376   fipa_DateTime_t* dt;
00377   dt = (fipa_DateTime_t*)malloc(sizeof(fipa_DateTime_t));
00378   memset(dt, 0, sizeof(fipa_DateTime_t));
00379   return dt;
00380 }
00381 
00382 int fipa_DateTime_Destroy(fipa_DateTime_t* dt)
00383 {
00384   if(dt == NULL) return 0;
00385   free(dt);
00386   return 0;
00387 }
00388 
00389 fipa_DateTime_t* fipa_DateTime_Copy(fipa_DateTime_t* src)
00390 {
00391   fipa_DateTime_t* copy;
00392   if (src == NULL) return NULL;
00393   copy = fipa_DateTime_New();
00394   *copy = *src;
00395   return copy;
00396 }
00397 
00398 /* fipa_url */
00399 fipa_url_t* fipa_url_New(void)
00400 {
00401   fipa_url_t* url;
00402   url = (fipa_url_t*)malloc(sizeof(fipa_url_t));
00403   memset(url, 0, sizeof(fipa_url_t));
00404   return url;
00405 }
00406 
00407 int fipa_url_Destroy(fipa_url_t* url)
00408 {
00409   if (url == NULL) return 0;
00410   if (url->str != NULL) {
00411     free(url->str);
00412   }
00413   free(url);
00414   return 0;
00415 }
00416 
00417 fipa_url_t* fipa_url_Copy(fipa_url_t* src)
00418 {
00419   fipa_url_t* copy;
00420   if (src == NULL) return NULL;
00421   copy = fipa_url_New();
00422   copy->str = strdup(src->str);
00423   return copy;
00424 }
00425 
00426 /* fipa_Number */
00427 fipa_number_t* fipa_number_New(void)
00428 {
00429   fipa_number_t* num;
00430   num = (fipa_number_t*)malloc(sizeof(fipa_number_t));
00431   memset(num, 0, sizeof(fipa_number_t));
00432   return num;
00433 }
00434 
00435 int fipa_number_Destroy(fipa_number_t* number)
00436 {
00437   if (number == NULL) return 0;
00438   if (number->str != NULL){
00439     free(number->str);
00440   }
00441   free(number);
00442   return 0;
00443 }
00444 
00445 fipa_number_t* fipa_number_Copy(fipa_number_t* src)
00446 {
00447   fipa_number_t* copy;
00448   if (src == NULL) return NULL;
00449   copy = fipa_number_New();
00450   copy->str = strdup(src->str);
00451   return copy;
00452 }
00453 
00454 /* Parsing Functions */
00455 int fipa_acl_Parse(fipa_acl_message_p acl, fipa_message_string_p message)
00456 {
00457   int err = 0;
00458   if (fipa_GetAtom(message,'(')) {
00459     err = MC_ERR_PARSE;
00460     goto exit;
00461   }
00462   if (fipa_message_type_Parse(&(acl->performative), message)) {
00463     err = MC_ERR_PARSE;
00464     goto exit;
00465   }
00466   while(fipa_GetAtom(message, ')')){
00467     err = fipa_message_parameter_Parse(acl, message);
00468     if (err) return err;
00469   }
00470 
00471 exit:
00472   return err;
00473 }
00474 
00475 int fipa_message_parameter_Parse(fipa_acl_message_p acl, fipa_message_string_p message)
00476 {
00477   int err;
00478   fipa_word_t* word = NULL;
00479   char* parameter;
00480   if((err = fipa_GetAtom(message, ':'))) return err;
00481   if((err = fipa_word_Parse(&word, message))) return err;
00482   parameter = word->content;
00483   if (!strcmp(parameter, "sender")) {
00484     err = fipa_agent_identifier_Parse(&(acl->sender), message);
00485   } else if (!strcmp(parameter, "receiver")) {
00486     err = fipa_agent_identifier_set_Parse(&(acl->receiver), message);
00487   } else if (!strcmp(parameter, "content")) {
00488     err = fipa_string_Parse(&(acl->content), message);
00489   } else if (!strcmp(parameter, "reply-with")) {
00490     err = fipa_expression_Parse(&(acl->reply_with), message);
00491   } else if (!strcmp(parameter, "reply-by")) {
00492     err = fipa_datetime_Parse(&(acl->reply_by), message);
00493   } else if (!strcmp(parameter, "in-reply-to")) {
00494     err = fipa_expression_Parse(&(acl->in_reply_to), message);
00495   } else if (!strcmp(parameter, "reply-to")) {
00496     err = fipa_agent_identifier_set_Parse(&(acl->reply_to), message);
00497   } else if (!strcmp(parameter, "language")) {
00498     err = fipa_expression_Parse(&(acl->language), message);
00499   } else if (!strcmp(parameter, "encoding")) {
00500     err = fipa_expression_Parse(&(acl->encoding), message);
00501   } else if (!strcmp(parameter, "ontology")) {
00502     err = fipa_expression_Parse(&(acl->ontology), message);
00503   } else if (!strcmp(parameter, "protocol")) {
00504     err = fipa_word_Parse(&(acl->protocol), message);
00505   } else if (!strcmp(parameter, "conversation-id")) {
00506     err = fipa_expression_Parse(&(acl->conversation_id), message);
00507   } else {
00508     /* FIXME: We do not deal with user defined parameters yet. */
00509     fprintf(stderr, "FIXME: No handling of user defined parameters. %s:%d\n",
00510         __FILE__, __LINE__);
00511     err = MC_ERR_PARSE;
00512   }
00513   fipa_word_Destroy(word);
00514   return err;
00515 }
00516 
00517 int fipa_message_type_Parse(
00518     enum fipa_performative_e* performative, 
00519     fipa_message_string_p message
00520     )
00521 {
00522   int err = 0;
00523   fipa_word_p word;
00524   err = fipa_word_Parse(&word, message);
00525   if (err) return err;
00526   if(!strcasecmp(word->content, "accept-proposal")) {
00527     *performative = FIPA_ACCEPT_PROPOSAL;
00528   } else if (!strcasecmp(word->content, "agree")) {
00529     *performative = FIPA_AGREE;
00530   } else if (!strcasecmp(word->content, "cancel")) {
00531     *performative = FIPA_CANCEL;
00532   } else if (!strcasecmp(word->content, "call-for-proposal")) {
00533     *performative = FIPA_CALL_FOR_PROPOSAL;
00534   } else if (!strcasecmp(word->content, "confirm")) {
00535     *performative = FIPA_CONFIRM;
00536   } else if (!strcasecmp(word->content, "disconfirm")) {
00537     *performative = FIPA_DISCONFIRM;
00538   } else if (!strcasecmp(word->content, "failure")) {
00539     *performative = FIPA_FAILURE;
00540   } else if (!strcasecmp(word->content, "inform")) {
00541     *performative = FIPA_INFORM;
00542   } else if (!strcasecmp(word->content, "inform-if")) {
00543     *performative = FIPA_INFORM_IF;
00544   } else if (!strcasecmp(word->content, "inform-ref")) {
00545     *performative = FIPA_INFORM_REF;
00546   } else if (!strcasecmp(word->content, "not-understood")) {
00547     *performative = FIPA_NOT_UNDERSTOOD;
00548   } else if (!strcasecmp(word->content, "propogate")) {
00549     *performative = FIPA_PROPOGATE;
00550   } else if (!strcasecmp(word->content, "propose")) {
00551     *performative = FIPA_PROPOSE;
00552   } else if (!strcasecmp(word->content, "proxy")) {
00553     *performative = FIPA_PROXY;
00554   } else if (!strcasecmp(word->content, "query-if")) {
00555     *performative = FIPA_QUERY_IF;
00556   } else if (!strcasecmp(word->content, "query-ref")) {
00557     *performative = FIPA_QUERY_REF;
00558   } else if (!strcasecmp(word->content, "refuse")) {
00559     *performative = FIPA_REFUSE;
00560   } else if (!strcasecmp(word->content, "reject-proposal")) {
00561     *performative = FIPA_REJECT_PROPOSAL;
00562   } else if (!strcasecmp(word->content, "request")) {
00563     *performative = FIPA_REQUEST;
00564   } else if (!strcasecmp(word->content, "request-when")) {
00565     *performative = FIPA_REQUEST_WHEN;
00566   } else if (!strcasecmp(word->content, "request-whenever")) {
00567     *performative = FIPA_REQUEST_WHENEVER;
00568   } else if (!strcasecmp(word->content, "subscribe")) {
00569     *performative = FIPA_SUBSCRIBE;
00570   } else {
00571     fprintf(stderr, "Unknown performative: '%s'. %s:%d\n",
00572         word->content, __FILE__, __LINE__);
00573     err = MC_ERR_PARSE;
00574   }
00575   fipa_word_Destroy(word);
00576   return err;
00577 }
00578 
00579 int fipa_GetAtom(
00580     fipa_message_string_p message,
00581     char expected_atom
00582     )
00583 {
00584   while
00585     (
00586      (*(message->parse) >= 0x00) &&
00587      (*(message->parse) <= 0x20)
00588     )
00589     {
00590       if (*(message->parse) == 0x00)
00591         return MC_ERR_PARSE;
00592       message->parse++;
00593     }
00594   if( *(message->parse) == expected_atom) {
00595     message->parse++;
00596     return MC_SUCCESS;
00597   } else {
00598     return MC_ERR_PARSE;
00599   }
00600 }
00601 
00602 int fipa_word_Parse(fipa_word_t** word, fipa_message_string_p message)
00603 {
00604   char* tmp;
00605   int i = 0;
00606   /* Get rid of leading whitespace */
00607   while
00608     (
00609      (*(message->parse)>=0x00) &&
00610      (*(message->parse)<=0x20)
00611     )
00612     {
00613       /* If we encounter a null zero, return error. */
00614       if (*(message->parse) == '\0') {
00615         return MC_ERR_PARSE;
00616       }
00617       message->parse++;
00618     }
00619   /* Count number of characters in word */
00620   tmp = message->parse;
00621   while (*tmp > 0x20) {
00622     tmp++;
00623     i++;
00624   }
00625   *word = (fipa_word_t*)malloc(sizeof(fipa_word_t));
00626   CHECK_NULL(*word, exit(0););
00627   (*word)->content = malloc
00628     (
00629      sizeof(char) * (i+1)
00630     );
00631   CHECK_NULL((*word)->content, exit(0););
00632 
00633   /* Copy word */
00634   i = 0;
00635   while( *(message->parse) > 0x20 ) {
00636     ((*word)->content)[i] = *(message->parse);
00637     message->parse++;
00638     i++;
00639   }
00640   ((*word)->content)[i] = '\0';
00641   return MC_SUCCESS;
00642 }
00643 
00644 int fipa_CheckNextToken(const fipa_message_string_p message, const char* token)
00645 {
00646   char* tmp = message->parse;
00647   while 
00648     (
00649      (*tmp >= 0x00) &&
00650      (*tmp <= 0x20)
00651     )
00652       tmp++;
00653   while (*token != '\0') {
00654     if (*token != *tmp) {
00655       return 0; /* False value, not error code */
00656     }
00657     token++;
00658     tmp++;
00659   }
00660   return 1; /* True */
00661 }
00662 
00663 int fipa_expression_Parse(fipa_expression_t** expression, fipa_message_string_p message)
00664 {
00665   int i=0;
00666   *expression = (fipa_expression_t*)malloc(sizeof(fipa_expression_t));
00667   /* The expression may contain a word, string, date, or list of expressions. First,
00668    * lets check the recursive case, which is a parentheses-bound list of 
00669    * expressions. */
00670   if (fipa_CheckNextToken(message, "(")) {
00671     (*expression)->type = FIPA_EXPR_EXPRESSION;
00672     if(fipa_GetAtom(message, '(')) {
00673       /* This should never happen */
00674       fprintf(stderr, "Fatal error. %s:%d\n", __FILE__, __LINE__);
00675       exit(0);
00676     }
00677     for 
00678       (
00679        i = 0; 
00680        !fipa_expression_Parse( &(((*expression)->content.expression)[i]), message);
00681        i++
00682       );
00683     if(fipa_GetAtom(message, ')')) {
00684       fprintf(stderr, "Parse error. %s:%d\n", __FILE__, __LINE__);
00685       return MC_ERR_PARSE;
00686     }
00687   } else if (
00688       /* The expression may be a date-time */
00689       !fipa_datetime_Parse(&((*expression)->content.datetime), message)
00690       ) 
00691   {
00692     (*expression)->type = FIPA_EXPR_DATETIME;
00693   } else if (
00694       /* The expression may be a string */
00695       !fipa_string_Parse(&((*expression)->content.string), message)
00696       )
00697   {
00698     (*expression)->type = FIPA_EXPR_STRING;
00699   } else if (
00700       /* The expression may be a word */
00701       !fipa_word_Parse(&((*expression)->content.word), message)
00702       )
00703   {
00704     (*expression)->type=FIPA_EXPR_WORD;
00705   }
00706   else
00707   {
00708     /* It's not correct */
00709     return MC_ERR_PARSE;
00710   }
00711   return MC_SUCCESS;
00712 }
00713 
00714 int fipa_GetNextWord(char** word, const fipa_message_string_p message)
00715 {
00716   char *tmp;
00717   int i = 0;
00718   int j;
00719   /* Skip leading whitespace */
00720   tmp = message->parse;
00721   while
00722     (
00723      (*tmp >= 0x00) &&
00724      (*tmp <= 0x20)
00725     )
00726       tmp++;
00727   /* See how big the word is */
00728   /* The first character has special rules */
00729   if
00730     (
00731      ((*tmp >= 0x00) && (*tmp <= 0x20)) ||
00732      (*tmp == '(') ||
00733      (*tmp == ')') ||
00734      (*tmp == '#') ||
00735      ((*tmp >= 0x30) && (*tmp <= 0x39)) || /* May not start with a digit */
00736      (*tmp == '-') ||
00737      (*tmp == '@')
00738     )
00739       return ERR;
00740   i++;
00741   tmp++;
00742   /* Count the rest of the chars */
00743   while
00744     (
00745      ((*tmp < 0x00) || (*tmp > 0x20)) &&
00746      (*tmp != '(') &&
00747      (*tmp != ')')
00748     ) {
00749       i++;
00750       tmp++;
00751     }
00752   /* Allocate the memory */
00753   *word = (char*)malloc(sizeof(char) * (i+1));
00754 
00755   for (j = 0; j < i; j++) {
00756     *((*word) + j) = *(message->parse+j);
00757   }
00758   *((*word)+j) = '\0';
00759   return MC_SUCCESS;
00760 }
00761 
00762 int fipa_GetWholeToken(char** word, fipa_message_string_p message)
00763 {
00764   char *tmp;
00765   int i = 0;
00766   int j;
00767   /* Skip leading whitespace */
00768   tmp = message->parse;
00769   while
00770     (
00771      (*tmp >= 0x00) &&
00772      (*tmp <= 0x20)
00773     )
00774     {
00775       tmp++;
00776       message->parse++;
00777     }
00778   /* See how big the word is */
00779   i++;
00780   tmp++;
00781   /* Count the rest of the chars */
00782   while
00783     (
00784      ((*tmp < 0x00) || (*tmp > 0x20))
00785     ) {
00786       i++;
00787       tmp++;
00788     }
00789   /* Allocate the memory */
00790   *word = (char*)malloc(sizeof(char) * (i+1));
00791 
00792   for (j = 0; j < i; j++) {
00793     *((*word) + j) = *(message->parse+j);
00794   }
00795   *((*word)+j) = '\0';
00796   return MC_SUCCESS;
00797 }
00798 
00799 int fipa_datetime_Parse(fipa_DateTime_p* datetime, fipa_message_string_p message)
00800 {
00801   char *word;
00802   char *tmp;
00803   int i;
00804   char buf[5];
00805   /* Check to see if there is a sign */
00806   fipa_GetWholeToken(&word, message);
00807   tmp = word;
00808   if (
00809       (*tmp == '+') ||
00810       (*tmp == '-')
00811      )
00812     tmp++;
00813   /* The next 8 characters must be digits */
00814   for(i = 0; i < 8; i++) {
00815     if (*tmp < 0x30 || *tmp > 0x39) {
00816       free(word);
00817       return MC_ERR_PARSE;
00818     }
00819     tmp++;
00820   }
00821   /* Next character must be 'T' */
00822   if (*tmp == 'T') {
00823     tmp++;
00824   } else {
00825     free(word);
00826     return MC_ERR_PARSE;
00827   }
00828   /* Next 9 characters must be digits */
00829   for(i = 0; i < 9; i++) {
00830     if(*tmp < 0x30 || *tmp > 0x39) {
00831       free(word);
00832       return MC_ERR_PARSE;
00833     }
00834     tmp++;
00835   }
00836 
00837   /* If we get here, the string is definately a date-time. */
00838   *datetime = (fipa_DateTime_p)malloc(sizeof(fipa_DateTime_t));
00839   tmp = word;
00840   switch(*tmp) {
00841     case '+':
00842       (*datetime)->sign = '+';
00843       tmp++;
00844       message->parse++;
00845       break;
00846     case '-':
00847       (*datetime)->sign = '-';
00848       tmp++;
00849       message->parse++;
00850       break;
00851     default:
00852       break;
00853   }
00854 
00855   /* Get the year */
00856   for(i = 0; i < 4; i++) {
00857     buf[i] = *tmp;
00858     tmp++;
00859     message->parse++;
00860   }
00861   buf[i] = '\0';
00862   (*datetime)->year = atoi(buf);
00863 
00864   /* Get the month */
00865   for(i = 0; i < 2; i++) {
00866     buf[i] = *tmp;
00867     tmp++;
00868     message->parse++;
00869   }
00870   buf[i] = '\0';
00871   (*datetime)->month = atoi(buf);
00872 
00873   /* Get the day */
00874   for(i = 0; i < 2; i++) {
00875     buf[i] = *tmp;
00876     tmp++;
00877     message->parse++;
00878   }
00879   buf[i] = '\0';
00880   (*datetime)->month = atoi(buf);
00881 
00882   /* Skip the T */
00883   if (*tmp != 'T') {
00884     /* Something is very wrong */
00885     fprintf(stderr, "Fatal Error. %s:%d\n", __FILE__, __LINE__);
00886     exit(0);
00887   }
00888   tmp++;
00889   message->parse++;
00890 
00891   /* Get the hour */
00892   for(i = 0; i < 2; i++) {
00893     buf[i] = *tmp;
00894     tmp++;
00895     message->parse++;
00896   }
00897   buf[i] = '\0';
00898   (*datetime)->hour = atoi(buf);
00899 
00900   /* Get the minute */
00901   for(i = 0; i < 2; i++) {
00902     buf[i] = *tmp;
00903     tmp++;
00904     message->parse++;
00905   }
00906   buf[i] = '\0';
00907   (*datetime)->minute = atoi(buf);
00908 
00909   /* Get the second */
00910   for(i = 0; i < 2; i++) {
00911     buf[i] = *tmp;
00912     tmp++;
00913     message->parse++;
00914   }
00915   buf[i] = '\0';
00916   (*datetime)->second = atoi(buf);
00917 
00918   /* Get the millisecond */
00919   for(i = 0; i < 3; i++) {
00920     buf[i] = *tmp;
00921     tmp++;
00922     message->parse++;
00923   }
00924   buf[i] = '\0';
00925   (*datetime)->millisecond = atoi(buf);
00926 
00927   if (*tmp == 'Z') {
00928     (*datetime)->is_utc = 1;
00929     message->parse++;
00930   }
00931   else
00932     (*datetime)->is_utc = 0;
00933   free(word);
00934   return MC_SUCCESS;
00935 }
00936 
00937 int fipa_string_Parse( fipa_string_p* fipa_string, fipa_message_string_p message)
00938 {
00939   int len;
00940   char *tmp;
00941   /* Eat the starting quotation mark */
00942   if(fipa_GetAtom(message, '\"')) {
00943     return MC_ERR_PARSE;
00944   }
00945 
00946   tmp = message->parse;
00947   len = 0;
00948   while 
00949     (
00950      (*tmp != '\0')
00951     )
00952     {
00953       if (*tmp == '\"') {
00954         break;
00955       }
00956       if (*tmp == '\\') {
00957         tmp++;
00958         len++;
00959       }
00960       tmp++;
00961       len++;
00962     }
00963   *fipa_string = (fipa_string_p)malloc(sizeof(fipa_string_t));
00964   (*fipa_string)->content = (char*)malloc
00965     (
00966      sizeof(char) * (len + 1)
00967     );
00968   len = 0;
00969   while (message->parse < tmp) {
00970     ((*fipa_string)->content)[len] = *(message->parse);
00971     len++;
00972     message->parse++;
00973   }
00974   ((*fipa_string)->content)[len] = '\0';
00975   /* Eat ending quotation mark */
00976   if(fipa_GetAtom(message, '\"')) {
00977     return MC_ERR_PARSE;
00978   }
00979   return MC_SUCCESS;
00980 }
00981 
00982 int fipa_agent_identifier_Parse(fipa_agent_identifier_p* aid, fipa_message_string_p message)
00983 {
00984   int err = 0;
00985   fipa_word_t* word = NULL;
00986   char *rewind;
00987   if
00988     (
00989      (err = fipa_GetAtom(message, '(') ) 
00990     ) return err;
00991   if
00992     (
00993      (err = fipa_word_Parse(&word, message) )
00994     ) 
00995     {
00996       fipa_word_Destroy(word);
00997       return err;
00998     }
00999   if (strcmp(word->content, "agent-identifier")) {
01000     free(word->content);
01001     fipa_word_Destroy(word);
01002     return MC_ERR_PARSE;
01003   }
01004   fipa_word_Destroy(word);
01005   word = NULL;
01006   if 
01007     (
01008      (err = fipa_GetAtom(message, ':') )
01009     ) return err;
01010   if
01011     (
01012      (err = fipa_word_Parse(&word, message))
01013     ) 
01014     {
01015       fipa_word_Destroy(word);
01016       return err;
01017     }
01018   if (strcmp(word->content, "name")) {
01019     return MC_ERR_PARSE;
01020   }
01021   fipa_word_Destroy(word);
01022   word = NULL;
01023   /* This is probably a valid aid, so allocate it. */
01024   *aid = (fipa_agent_identifier_p)malloc(sizeof(fipa_agent_identifier_t));
01025   memset(*aid, 0, sizeof(fipa_agent_identifier_t));
01026   if
01027     (
01028      (err = fipa_word_Parse(&word, message))
01029     )
01030     {
01031       fipa_word_Destroy(word);
01032       return err;
01033     }
01034   (*aid)->name = (char*)malloc
01035     (
01036      sizeof(char) * 
01037      (strlen(word->content)+1)
01038     );
01039   CHECK_NULL((*aid)->name, exit(0););
01040   strcpy((*aid)->name, word->content);
01041   /* No need to keep the word around... */
01042   fipa_word_Destroy(word);
01043 
01044   /* Now we need to see if there are addresses and/or resolvers. */
01045 
01046   rewind = message->parse;
01047   if
01048     (
01049      (!(err = fipa_GetAtom(message, ':')))
01050     ) 
01051     {
01052       if
01053         (
01054          (err = fipa_word_Parse(&word, message))
01055         ) {
01056           message->parse = rewind;
01057           fipa_word_Destroy(word);
01058           return MC_ERR_PARSE;
01059         }
01060 
01061       if (!strcmp(word->content, "addresses"))
01062       {
01063         err = fipa_url_sequence_Parse(&((*aid)->addresses), message);
01064         if(err) {
01065           message->parse = rewind;
01066           fipa_word_Destroy(word);
01067           return err;
01068         }
01069       } else if (!strcmp(word->content, "resolvers"))
01070       {
01071         err = fipa_agent_identifier_set_Parse(&((*aid)->resolvers), message);
01072         if (err) {
01073           message->parse = rewind;
01074           fipa_word_Destroy(word);
01075           return err;
01076         }
01077       } else {
01078         message->parse = rewind;
01079       }
01080     }
01081   /* Parse final ')' */
01082   err = fipa_GetAtom(message, ')');
01083   fipa_word_Destroy(word);
01084   if (err) {return MC_ERR_PARSE;}
01085   return MC_SUCCESS;
01086   /* FIXME: We will deal with resolvers and custom fields later */
01087 }
01088 
01089 int fipa_url_sequence_Parse(fipa_url_sequence_p* urls, fipa_message_string_p message)
01090 {
01091   int err;
01092   fipa_word_p word;
01093   int i;
01094   if
01095     (
01096      (err = fipa_GetAtom(message, '(') )
01097     ) return err;
01098   if
01099     (
01100      (err = fipa_word_Parse(&word, message) )
01101     ) return err;
01102   if ( strcmp(word->content, "sequence")) {
01103     fipa_word_Destroy(word);
01104     return MC_ERR_PARSE;
01105   }
01106   fipa_word_Destroy(word);
01107   *urls = fipa_url_sequence_New();
01108   /* FIXME: We only alloc space for 20 addresses. In the future, we should count
01109    * how many addresses there are and allocate that much. */
01110   (*urls)->urls = (fipa_url_t**)malloc(sizeof(fipa_url_t*)*20);
01111   i = 0;
01112   (*urls)->num = 0;
01113   while( fipa_GetAtom(message, ')') ) {
01114     fipa_url_Parse(&(*urls)->urls[i], message);
01115     i++;
01116     (*urls)->num++;
01117   }
01118   return 0;
01119 }
01120 
01121 int fipa_url_Parse(fipa_url_p* url, fipa_message_string_p message)
01122 {
01123   fipa_word_p word = NULL;
01124   int err;
01125   *url = (fipa_url_t*)malloc(sizeof(fipa_url_t));
01126   err = fipa_word_Parse(&word, message);
01127   if (err) {
01128     free(*url);
01129     if(word == NULL) fipa_word_Destroy(word);
01130     fprintf(stderr, "Error parsing. %s:%d\n", __FILE__, __LINE__);
01131     return err;
01132   }
01133   (*url)->str = strdup(word->content);
01134   fipa_word_Destroy(word);
01135   return 0;
01136 }
01137 
01138 /* We will use the following function to parse both agent identifier
01139  * sets and sequences, since they are exactly the same except sequences
01140  * retain the order of agent id's. */
01141 int fipa_agent_identifier_set_Parse(fipa_agent_identifier_set_p* agent_ids, fipa_message_string_p message)
01142 {
01143   int err;
01144   fipa_word_p word;
01145   int i=0;
01146   /* FIXME */
01147   if
01148     (
01149      (err = fipa_GetAtom(message, '(') )
01150     ) return err;
01151   if
01152     (
01153      (err = fipa_word_Parse(&word, message) )
01154     ) return err;
01155   if (!strcmp(word->content, "set")) {
01156     *agent_ids = (fipa_agent_identifier_set_p)malloc(sizeof(struct fipa_agent_identifier_set_s));
01157     (*agent_ids)->retain_order = 0;
01158   } else if (!strcmp(word->content, "sequence")) {
01159     *agent_ids = (fipa_agent_identifier_set_p)malloc(sizeof(struct fipa_agent_identifier_set_s));
01160     (*agent_ids)->retain_order = 1;
01161   } else {
01162     free(word->content);
01163     free(word);
01164     return MC_ERR_PARSE;
01165   }
01166   free(word->content);
01167   free(word);
01168   (*agent_ids)->fipa_agent_identifiers = 
01169     (fipa_agent_identifier_p*)malloc(20 * sizeof(fipa_agent_identifier_t*));
01170   while( fipa_GetAtom(message, ')') ) {
01171     err = fipa_agent_identifier_Parse
01172       (&(((*agent_ids)->fipa_agent_identifiers)[i]), message);
01173     if(err) return err;
01174     i++;
01175   }
01176   (*agent_ids)->num = i;
01177   return MC_SUCCESS;
01178 }
01179 
01180 /* Composing Functions */
01181 
01182 int fipa_acl_Compose(dynstring_t** msg, fipa_acl_message_t* acl)
01183 {
01184   *msg = dynstring_New();
01185   dynstring_Append(*msg, "(");
01186   fipa_performative_Compose(*msg, acl->performative);
01187   if (acl->sender != NULL) {
01188     dynstring_Append(*msg, ":sender ");
01189     fipa_agent_identifier_Compose(*msg, acl->sender);
01190     dynstring_Append(*msg, "\n");
01191   }
01192   if (acl->receiver != NULL) {
01193     dynstring_Append(*msg, ":receiver ");
01194     fipa_agent_identifier_set_Compose(*msg, acl->receiver);
01195     dynstring_Append(*msg, "\n");
01196   }
01197   if (acl->reply_to) {
01198     dynstring_Append(*msg, ":reply-to ");
01199     fipa_agent_identifier_set_Compose(*msg, acl->reply_to);
01200     dynstring_Append(*msg, "\n");
01201   }
01202   if (acl->content) {
01203     dynstring_Append(*msg, ":content ");
01204     fipa_string_Compose(*msg, acl->content);
01205     dynstring_Append(*msg, "\n");
01206   }
01207   if (acl->language) {
01208     dynstring_Append(*msg, ":language ");
01209     fipa_expression_Compose(*msg, acl->language);
01210     dynstring_Append(*msg, "\n");
01211   }
01212   if (acl->encoding) {
01213     dynstring_Append(*msg, ":encoding ");
01214     fipa_expression_Compose(*msg, acl->encoding);
01215     dynstring_Append(*msg, "\n");
01216   }
01217   if (acl->ontology) {
01218     dynstring_Append(*msg, ":ontology ");
01219     fipa_expression_Compose(*msg, acl->ontology);
01220     dynstring_Append(*msg, "\n");
01221   }
01222   if (acl->protocol) {
01223     dynstring_Append(*msg, ":protocol ");
01224     fipa_word_Compose(*msg, acl->protocol);
01225     dynstring_Append(*msg, "\n");
01226   }
01227   if (acl->conversation_id) {
01228     dynstring_Append(*msg, ":conversation-id ");
01229     fipa_expression_Compose(*msg, acl->conversation_id);
01230     dynstring_Append(*msg, "\n");
01231   }
01232   if (acl->reply_with) {
01233     dynstring_Append(*msg, ":reply-with ");
01234     fipa_expression_Compose(*msg, acl->reply_with);
01235     dynstring_Append(*msg, "\n");
01236   }
01237   if (acl->in_reply_to) {
01238     dynstring_Append(*msg, ":in-reply-to ");
01239     fipa_expression_Compose(*msg, acl->in_reply_to);
01240     dynstring_Append(*msg, "\n");
01241   }
01242   if (acl->reply_by) {
01243     dynstring_Append(*msg, ":reply-by ");
01244     fipa_DateTime_Compose(*msg, acl->reply_by);
01245     dynstring_Append(*msg, "\n");
01246   }
01247   dynstring_Append(*msg, ")");
01248   return 0;
01249 }
01250 
01251 int fipa_performative_Compose(dynstring_t* msg, enum fipa_performative_e performative)
01252 {
01253   switch(performative) {
01254     case FIPA_ACCEPT_PROPOSAL:
01255       dynstring_Append(msg, "accept-proposal ");
01256       break;
01257     case FIPA_AGREE:
01258       dynstring_Append(msg, "agree ");
01259       break;
01260     case FIPA_CANCEL:
01261       dynstring_Append(msg, "cancel ");
01262       break;
01263     case FIPA_CALL_FOR_PROPOSAL:
01264       dynstring_Append(msg, "call-for-proposal ");
01265       break;
01266     case FIPA_CONFIRM:
01267       dynstring_Append(msg, "confirm ");
01268       break;
01269     case FIPA_DISCONFIRM:
01270       dynstring_Append(msg, "disconfirm ");
01271       break;
01272     case FIPA_FAILURE:
01273       dynstring_Append(msg, "failure ");
01274       break;
01275     case FIPA_INFORM:
01276       dynstring_Append(msg, "inform ");
01277       break;
01278     case FIPA_INFORM_IF:
01279       dynstring_Append(msg, "inform-if ");
01280       break;
01281     case FIPA_INFORM_REF:
01282       dynstring_Append(msg, "inform-ref ");
01283       break;
01284     case FIPA_NOT_UNDERSTOOD:
01285       dynstring_Append(msg, "not-understood ");
01286       break;
01287     case FIPA_PROPOGATE:
01288       dynstring_Append(msg, "propogate ");
01289       break;
01290     case FIPA_PROPOSE:
01291       dynstring_Append(msg, "propose ");
01292       break;
01293     case FIPA_PROXY:
01294       dynstring_Append(msg, "proxy ");
01295       break;
01296     case FIPA_QUERY_IF:
01297       dynstring_Append(msg, "query-if ");
01298       break;
01299     case FIPA_QUERY_REF:
01300       dynstring_Append(msg, "query-ref ");
01301       break;
01302     case FIPA_REFUSE:
01303       dynstring_Append(msg, "refuse ");
01304       break;
01305     case FIPA_REJECT_PROPOSAL:
01306       dynstring_Append(msg, "reject-proposal ");
01307       break;
01308     case FIPA_REQUEST:
01309       dynstring_Append(msg, "request ");
01310       break;
01311     case FIPA_REQUEST_WHEN:
01312       dynstring_Append(msg, "request-when ");
01313       break;
01314     case FIPA_REQUEST_WHENEVER:
01315       dynstring_Append(msg, "request-whenever ");
01316       break;
01317     case FIPA_SUBSCRIBE:
01318       dynstring_Append(msg, "subscribe ");
01319       break;
01320     default:
01321       return MC_ERR_PARSE;
01322   }
01323   return 0;
01324 }
01325 
01326 int fipa_url_sequence_Compose(dynstring_t* msg, fipa_url_sequence_t* urls)
01327 {
01328   int i;
01329   if(urls == NULL) return 0;
01330   if(urls->num == 0) return 0;
01331   dynstring_Append(msg, "(sequence ");
01332   for(i = 0; i < urls->num; i++) {
01333     fipa_url_Compose(msg, urls->urls[i]);
01334   }
01335   dynstring_Append(msg, ") ");
01336   return 0;
01337 }
01338 
01339 int fipa_agent_identifier_set_Compose(dynstring_t* msg, fipa_agent_identifier_set_t* ids)
01340 {
01341   int i;
01342   if(ids == NULL) return 0;
01343   if(ids->num == 0) return 0;
01344   dynstring_Append(msg, "(sequence ");
01345   for(i = 0; i < ids->num; i++) {
01346     fipa_agent_identifier_Compose(msg, ids->fipa_agent_identifiers[i]);
01347   }
01348   dynstring_Append(msg, ") ");
01349   return 0;
01350 }
01351 
01352 int fipa_agent_identifier_Compose(dynstring_t* msg, fipa_agent_identifier_t* id)
01353 {
01354   if(id == NULL) return 0;
01355   dynstring_Append(msg, "(agent-identifier ");
01356   dynstring_Append(msg, ":name ");
01357   dynstring_Append(msg, id->name);
01358   dynstring_Append(msg, " ");
01359 
01360   if (id->addresses != NULL) {
01361     if (id->addresses->num != 0) {
01362       dynstring_Append(msg, ":addresses ");
01363       fipa_url_sequence_Compose(msg, id->addresses);
01364     }
01365   }
01366 
01367   if (id->resolvers != NULL) {
01368     if (id->resolvers->num != 0) {
01369       dynstring_Append(msg, ":resolvers ");
01370       fipa_agent_identifier_set_Compose(msg, id->resolvers);
01371     }
01372   }
01373 
01374   dynstring_Append(msg, ") ");
01375   return 0;
01376 }
01377 
01378 int fipa_expression_Compose(dynstring_t* msg, fipa_expression_t* expr)
01379 {
01380   fipa_expression_t* tmp_expr;
01381   if (expr == NULL) return 0;
01382   switch(expr->type) {
01383     case FIPA_EXPR_WORD:
01384       fipa_word_Compose(msg, expr->content.word);
01385       break;
01386     case FIPA_EXPR_STRING:
01387       fipa_string_Compose(msg, expr->content.string);
01388       break;
01389     case FIPA_EXPR_NUMBER:
01390       fipa_number_Compose(msg, expr->content.number);
01391       break;
01392     case FIPA_EXPR_DATETIME:
01393       fipa_DateTime_Compose(msg, expr->content.datetime);
01394       break;
01395     case FIPA_EXPR_EXPRESSION:
01396       tmp_expr = expr->content.expression[0];
01397       while(tmp_expr != NULL) {
01398         fipa_expression_Compose(msg, tmp_expr);
01399         tmp_expr++;
01400       }
01401       break;
01402     default:
01403       return MC_ERR_PARSE;
01404   }
01405   return 0;
01406 }
01407 
01408 int fipa_word_Compose(dynstring_t* msg, fipa_word_t* word)
01409 {
01410   if (word == NULL) return 0;
01411   dynstring_Append(msg, word->content);
01412   dynstring_Append(msg, " ");
01413   return 0;
01414 }
01415 
01416 int fipa_string_Compose(dynstring_t* msg, fipa_string_t* string)
01417 {
01418   if (string == NULL) return 0;
01419   dynstring_Append(msg, "\"");
01420   dynstring_Append(msg, string->content);
01421   dynstring_Append(msg, "\" ");
01422   return 0;
01423 }
01424 
01425 int fipa_DateTime_Compose(dynstring_t* msg, fipa_DateTime_t* date)
01426 {
01427   char buf[40];
01428 
01429   if(date == NULL) return 0;
01430   dynstring_Append(msg, &date->sign);
01431   sprintf(buf, "%04d%02d%02dT%02d%02d%02d%03d", 
01432       date->year,
01433       date->month,
01434       date->day,
01435       date->hour,
01436       date->minute,
01437       date->second,
01438       date->millisecond
01439       );
01440   dynstring_Append(msg, buf);
01441   return 0;
01442 }
01443 
01444 
01445 int fipa_url_Compose(dynstring_t* msg, fipa_url_t* url)
01446 {
01447   if(url == NULL) return 0;
01448   dynstring_Append(msg, url->str);
01449   dynstring_Append(msg, " ");
01450   return 0;
01451 }
01452 
01453 int fipa_number_Compose(dynstring_t* msg, fipa_number_t* number)
01454 {
01455   if (number == NULL) return 0;
01456   dynstring_Append(msg, number->str);
01457   dynstring_Append(msg, " ");
01458   return 0;
01459 }
01460 
01461 struct fipa_acl_message_s* fipa_Reply(
01462     struct fipa_acl_message_s* acl)
01463 {
01464   /* Constuct a reply to the function argument */
01465   struct fipa_acl_message_s* acl_reply;
01466 
01467   acl_reply = fipa_acl_message_New();
01468 
01469   /* Set up the receiver */
01470   /* If the 'reply-to' field is set, use that. */
01471   if (acl->reply_to != NULL && acl->reply_to->num != 0) {
01472     acl_reply->receiver = fipa_agent_identifier_set_Copy(acl->reply_to);
01473   } else {
01474     acl_reply->receiver = fipa_agent_identifier_set_New();
01475     acl_reply->receiver->num = 1;
01476     acl_reply->receiver->retain_order = 0;
01477 
01478     acl_reply->receiver->fipa_agent_identifiers = (fipa_agent_identifier_t**)malloc(
01479         sizeof(fipa_agent_identifier_t*));
01480     acl_reply->receiver->fipa_agent_identifiers[0] = fipa_agent_identifier_Copy(
01481         acl->sender );
01482   }
01483   
01484   return acl_reply;
01485 }
01486 
01487 #undef FREEMEM

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