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

Go to the documentation of this file.
00001 /* SVN FILE INFO
00002  * $Revision: 181 $ : Last Committed Revision
00003  * $Date: 2008年07月01日 15:32:24 -0700 (2008年7月01日) $ : 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 Tue Oct 28 17:03:22 2008 for Mobile-C by doxygen 1.5.5

AltStyle によって変換されたページ (->オリジナル) /