/home/dko/projects/mobilec/tags/MobileC-v1.10.2/MobileC-v1.10.2/src/fipa_acl.c

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

Generated on Fri Jul 11 17:59:44 2008 for Mobile-C by  doxygen 1.5.4