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

Generated on Fri May 16 14:49:54 2008 for Mobile-C by  doxygen 1.5.4