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