1/* BEGIN LICENSE BLOCK 2 * Version: CMPL 1.1 3 * 4 * The contents of this file are subject to the Cisco-style Mozilla Public 5 * License Version 1.1 (the "License"); you may not use this file except 6 * in compliance with the License. You may obtain a copy of the License 7 * at www.eclipse-clp.org/license. 8 * 9 * Software distributed under the License is distributed on an "AS IS" 10 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See 11 * the License for the specific language governing rights and limitations 12 * under the License. 13 * 14 * The Original Code is The ECLiPSe Constraint Logic Programming System. 15 * The Initial Developer of the Original Code is Cisco Systems, Inc. 16 * Portions created by the Initial Developer are 17 * Copyright (C) 1994-2006 Cisco Systems, Inc. All Rights Reserved. 18 * 19 * Contributor(s): Kees Schuerman, ECRC 20 * 21 * END LICENSE BLOCK */ 22/********************************************************************** 23** System: Parallel Distributed System 24** File: pds.mdt.c 25** Author: Kees Schuerman 26** SccsId: "@(#)pds.mdt.c 1.5 24 Nov 1995" 27** Description: Message Data Types 28*********************************************************************** 29** Message Data Description 30** ------------------------ 31** A message data description defines the contents of a message, i.e. 32** the type and number of message data elements. A type of a message 33** data element is a standard C-type, a C-structure, or a single 34** dimensional array. The elements of the array and the fields of the 35** structure can again be standard C-types, C-structures and single 36** dimensional arrays. 37** The transmission of pointers is supported by the possibility to 38** transmit 64-bit addresses and the availability of primitives to 39** convert between pointers and 64-bit addresses. 40** The transmission of unions, bit-fields, and linked data structures 41** is not supported. 42** 43** 44** Alignment Requirements 45** ---------------------- 46** Data conversions from the local format to XDR format (XDR: eXternal 47** Data Representation) and vice versa are based on standard C-type 48** format conversions. 49** It is therefore important to know exactly where to fetch/store local 50** representation of the most basic elements (i.e. of standard C-type). 51** This depends on the alignment requirements of the standard C-types, 52** which may be machine dependent, and if they are part of a C-structure, 53** also of the C-structure alignment requirements. 54** A C-structure inherits its alignment requirements from its fields, 55** i.e. when the alignment is required to be on n bytes then both the 56** starting address and the size of the C-structure are multiples of 57** n bytes. C-structure alignment is thus fully determined by the 58** alignment requirements of the standard C-types. 59** 60** 61** Message Data Type Definition 62** ---------------------------- 63** Message data types are defined in terms of standard and earlier 64** defined message data types. The standard message data types are: 65** 66** MDT_BYTE 67** MDT_HWORD 68** MDT_WORD 69** MDT_DWORD 70** MDT_ADDRESS 71** MDT_CHAR 72** MDT_UCHAR 73** MDT_INT8 74** MDT_UINT8 75** MDT_INT16 76** MDT_UINT16 77** MDT_INT32 78** MDT_UINT32 79** MDT_SP_FLOAT 80** MDT_DP_FLOAT 81** 82** Message data types can be defined dynamically by means of the primitive 83** pds_type_define(). Its input is a message data type definition using 84** the constructors 85** 86** MDT_BEGIN 87** MDT_END 88** MDT_STRUCT_OPEN 89** MDT_STRUCT_CLOSE 90** MDT_ARRAY_OF 91** 92** and may use any existing message data type. A message data type 93** definition starts with MDT_BEGIN, followed by either a structure 94** definition or an array definition, and ends with MDT_END. A structure 95** definition starts with MDT_STRUCT_OPEN, has at least one field 96** definition, and ends with MDT_STRUCT_CLOSE. The field definitions of 97** a structure definition are message data types, structure definitions 98** or array definitions. An array definition starts with MDT_ARRAY_OF, 99** followed by an array count (i.e. the number of elements in the array) 100** and an array element definition. An array element definition, like a 101** structure element definition, can be message data types, structure 102** definitions or array definitions. 103** 104** The following two examples show the message data type definitions for 105** a structure and an array. 106** 107** MDT_BEGIN 108** MDT_STRUCT_OPEN struct { 109** MDT_CHAR char c1; 110** MDT_INT32 pds_int32 i1; 111** MDT_INT32 pds_int32 i2; 112** MDT_SP_FLOAT pds_sp_float f1; 113** MDT_CHAR char c2; 114** MDT_STRUCT_CLOSE } 115** MDT_END 116** 117** MDT_BEGIN 118** MDT_ARRAY_OF pds_int32 i[12]; 119** 12 120** MDT_INT32 121** MDT_END 122** 123** The following example uses the structure defined above. We assume that 124** it is identified with MDT_S1. 125** 126** MDT_BEGIN 127** MDT_ARRAY_OF 128** 17 129** MDT_ARRAY_OF 130** 9 131** MDT_S1 132** MDT_END 133** 134** This could for example be used for the transmission of the following 135** C-variable: a 2-dimensional array of structures. 136** 137** typedef struct { 138** char c1; 139** pds_int32 i1; 140** pds_int32 i2; 141** pds_sp_float f1; 142** char c2; 143** } variable [17][9]; 144** 145** Message data type definitions are used to control the conversion of 146** the message data between local format and XDR format. It carries 147** information on location and type of the data. The exact location is 148** determined by taking into account the (platform dependent) alignment 149** requirements as discussed above. 150** 151** 152** Message Data Type Identifiers 153** ----------------------------- 154** For identification purposes every message data type has an associated 155** message data type interface number, a message data type number, and a 156** message data type identifier. A message data type interface consists 157** thus of a set of message data type definitions. Defining such an 158** interface involves selecting a unique interface number and a unique 159** type number for every message data type. The result is a unique 160** type identifier for every message data type. 161** 162** 163** Message Data Type Tables 164** ------------------------ 165** A message data type interface is defined by a a message data type 166** table which containts the type definitions of the interface's message 167** data types. There are therefore as many message data type tables as 168** there are message data type interfaces. The associated table and table 169** entry of a message data type can be derived from its type identifier. 170***********************************************************************/ 171 172#include "machine.h" /* architecture specific constant definitions */ 173 174#include <stdio.h> 175#include <stdlib.h> 176#include <string.h> 177#include <rpc/rpc.h> 178 179#include "pds.types.h" 180#include "pds.error.h" 181#include "pds.mem.h" 182#include "pds.mdt.h" 183#include "pds.xdr.h" 184 185 186/********************************************************************** 187** Configuration 188***********************************************************************/ 189 190#define MDT_HEAP_SIZE 0x100000 191#define MDT_MAX_NOF_INTFCS 256 /* max number of interfaces */ 192#define MDT_MAX_NOF_TYPES 256 /* max number of types per interface */ 193 194 195/********************************************************************** 196** Align Options 197***********************************************************************/ 198 199#define MDT_ENCODE 0x01 200#define MDT_DECODE 0x02 201 202 203/********************************************************************** 204** Padding 205***********************************************************************/ 206 207#define MDT_PAD 0 208 209 210/********************************************************************** 211** Message Data Types (MDT), Interface Numbers, and Type Numbers 212***********************************************************************/ 213 214#define IntfcNo(MDT) ((MDT) / 0x10000) 215#define TypeNo(MDT) ((MDT) % 0x10000) 216 217 218/********************************************************************** 219** Type Definitions 220***********************************************************************/ 221 222typedef struct { 223 msg_type_no_t type_no; /* message type number */ 224 unsigned int def_size; /* size of message type definition */ 225 unsigned int idr_align; /* alignment of internal data representation */ 226 unsigned int idr_size; /* size of internal data representation */ 227 unsigned int xdr_size; /* size of external data representation */ 228 msg_typedef_t * def; /* message type definition */ 229} mdt_t; /* entry of message data type table */ 230 231typedef struct { 232 msg_intfc_no_t intfc_no; /* message type interface number */ 233 mdt_t * msg_types; /* message type table */ 234} msg_intfcs_t; /* message type interface table */ 235 236 237 238/********************************************************************** 239** Some Global Variables 240***********************************************************************/ 241 242static pds_heap_descriptor_t mdt_phd; /* private heap */ 243 244static int mdt_initialised = 0; /* state */ 245 246static msg_typedef_t mdt_byte = MDT_BYTE; /* message */ 247static msg_typedef_t mdt_hword = MDT_HWORD; /* data type */ 248static msg_typedef_t mdt_word = MDT_WORD; /* definitions */ 249static msg_typedef_t mdt_dword = MDT_DWORD; /* . */ 250static msg_typedef_t mdt_address = MDT_ADDRESS; /* . */ 251static msg_typedef_t mdt_char = MDT_CHAR; 252static msg_typedef_t mdt_uchar = MDT_UCHAR; 253static msg_typedef_t mdt_int8 = MDT_INT8; 254static msg_typedef_t mdt_uint8 = MDT_UINT8; 255static msg_typedef_t mdt_int16 = MDT_INT16; 256static msg_typedef_t mdt_uint16 = MDT_UINT16; 257static msg_typedef_t mdt_int32 = MDT_INT32; 258static msg_typedef_t mdt_uint32 = MDT_UINT32; 259static msg_typedef_t mdt_sp_float = MDT_SP_FLOAT; 260static msg_typedef_t mdt_dp_float = MDT_DP_FLOAT; /* . */ 261 262/* standard types table */ 263static mdt_t std_types[MDT_MAX_NOF_TYPES]; 264 265/* type interface table */ 266static msg_intfcs_t msg_intfcs[MDT_MAX_NOF_INTFCS]; 267 268static l_mutex_t mdt_mutex; /* protects type interface table */ 269 270#define MsgDD_Lock() l_mutex_lock(&mdt_mutex) 271#define MsgDD_Unlock() l_mutex_unlock(&mdt_mutex) 272 273 274 275/********************************************************************** 276** Runtime Consistency Checking 277***********************************************************************/ 278 279#if defined(NDEBUG) 280#define mdt_assert(ex) 281#else 282#define mdt_assert(ex) { \ 283 if (!(ex)) { \ 284 (void) fprintf(stderr, \ 285 "PDS MPS-M Assertion Failed:"); \ 286 (void) fprintf(stderr, " file \"%s\"", __FILE__); \ 287 (void) fprintf(stderr, " line %d\n", __LINE__); \ 288 exit(1); \ 289 } \ 290} 291#endif /* NDEBUG */ 292#define mdt_assert_always() { \ 293 (void) fprintf(stderr, \ 294 "PDS MPS-M Assertion Failed:"); \ 295 (void) fprintf(stderr, " file \"%s\"", __FILE__); \ 296 (void) fprintf(stderr, " line %d\n", __LINE__); \ 297 exit(1); \ 298} 299 300 301 302 303/********************************************************************** 304************************ Some Local Primitives *********************** 305***********************************************************************/ 306 307#if defined(__STDC__) 308static pds_ret_t idrmsg_pad_info(msg_typedef_t * * msg_typedef, 309 pds_size_t * size, 310 unsigned int * align); 311static pds_ret_t idrmsg_array_info(msg_typedef_t * * msg_typedef, 312 pds_size_t * size, 313 unsigned int * align); 314static pds_ret_t idrmsg_struct_info(msg_typedef_t * * msg_typedef, 315 pds_size_t * size, 316 unsigned int * align); 317static pds_ret_t idrmsg_opaque_info(msg_typedef_t * * msg_typedef, 318 pds_size_t * size, 319 unsigned int * align); 320static pds_ret_t xdrmsg_pad_info(msg_typedef_t * * msg_typedef, 321 pds_size_t * size); 322static pds_ret_t xdrmsg_array_info(msg_typedef_t * * msg_typedef, 323 pds_size_t * size); 324static pds_ret_t xdrmsg_struct_info(msg_typedef_t * * msg_typedef, 325 pds_size_t * size); 326static pds_ret_t xdrmsg_opaque_info(msg_typedef_t * * msg_typedef, 327 pds_size_t * size); 328static bool_t xdr_msg_stdtype(XDR * xdrs, 329 msg_typedef_t * * msg_typedef, 330 msg_data_t * * msg_data); 331static bool_t xdr_msg_pad(XDR * xdrs, 332 msg_typedef_t * * msg_typedef, 333 msg_data_t * * msg_data); 334static bool_t xdr_msg_array(XDR * xdrs, 335 msg_typedef_t * * msg_typedef, 336 msg_data_t * * msg_data); 337static bool_t xdr_msg_structure(XDR * xdrs, 338 msg_typedef_t * * msg_typedef, 339 msg_data_t * * msg_data); 340static bool_t xdr_msg_opaque(XDR * xdrs, 341 msg_typedef_t * * msg_typedef, 342 msg_data_t * * msg_data); 343#else /* __STDC__ */ 344static pds_ret_t idrmsg_pad_info(); 345static pds_ret_t idrmsg_array_info(); 346static pds_ret_t idrmsg_struct_info(); 347static pds_ret_t idrmsg_opaque_info(); 348static pds_ret_t xdrmsg_pad_info(); 349static pds_ret_t xdrmsg_array_info(); 350static pds_ret_t xdrmsg_struct_info(); 351static pds_ret_t xdrmsg_opaque_info(); 352static bool_t xdr_msg_stdtype(); 353static bool_t xdr_msg_pad(); 354static bool_t xdr_msg_array(); 355static bool_t xdr_msg_structure(); 356static bool_t xdr_msg_opaque(); 357#endif /* __STDC__ */ 358 359 360static pds_ret_t 361get_matching_index(msg_type,intfc_index,type_index) 362 msg_type_t msg_type; 363 unsigned * intfc_index; 364 unsigned * type_index; 365{ 366 mdt_t * msg_types; 367 unsigned intfc_no; 368 unsigned type_no; 369 unsigned index; 370 371 /* initialise indexes to default value */ 372 *intfc_index = 0; 373 *type_index = 0; 374 375 /* derive intfc_index */ 376 intfc_no = IntfcNo(msg_type); 377 index = intfc_no % 0x10 + intfc_no / 0x10; 378 index = index % (MDT_MAX_NOF_INTFCS / 2); 379 if (msg_intfcs[index].intfc_no == intfc_no) 380 *intfc_index = index; 381 else { 382 index = MDT_MAX_NOF_INTFCS - 1; 383 while (index && 384 (msg_intfcs[index].intfc_no != intfc_no)) 385 index--; 386 if (!index) 387 return(PDS_INVAL); 388 else 389 *intfc_index = index; 390 } 391 mdt_assert(msg_intfcs[index].msg_types); 392 393 /* derive type_index */ 394 msg_types = msg_intfcs[index].msg_types; 395 type_no = TypeNo(msg_type); 396 index = type_no % 0x10 + type_no / 0x10; 397 index = index % (MDT_MAX_NOF_TYPES / 2); 398 if (msg_types[index].type_no == type_no) 399 *type_index = index; 400 else { 401 index = MDT_MAX_NOF_TYPES - 1; 402 while (index && 403 (msg_types[index].type_no != type_no)) 404 index--; 405 if (!index) 406 return(PDS_INVAL); 407 else 408 *type_index = index; 409 } 410 mdt_assert(msg_types[index].def); 411 412 return(PDS_OK); 413} 414 415 416static pds_ret_t 417get_free_index(msg_type,intfc_index,type_index) 418 msg_type_t msg_type; 419 unsigned * intfc_index; 420 unsigned * type_index; 421{ 422 mdt_t * msg_types; 423 unsigned intfc_no; 424 unsigned type_no; 425 unsigned index; 426 int i; 427 428 if (get_matching_index(msg_type,intfc_index,type_index) == PDS_OK) 429 return(PDS_INVAL); 430 431 /* derive intfc_index */ 432 intfc_no = IntfcNo(msg_type); 433 index = *intfc_index; 434 if (!index) { 435 index = intfc_no % 0x10 + intfc_no / 0x10; 436 index = index % (MDT_MAX_NOF_INTFCS / 2); 437 if (!msg_intfcs[index].intfc_no) 438 *intfc_index = index; 439 else { 440 index = MDT_MAX_NOF_INTFCS - 1; 441 while (index && msg_intfcs[index].intfc_no) 442 index--; 443 if (!index) 444 return(PDS_NORESOURCES); 445 else 446 *intfc_index = index; 447 } 448 449 /* allocate message type table */ 450 msg_types = (mdt_t *) 451 pds_mem_alloc(&mdt_phd, 452 MDT_MAX_NOF_TYPES * sizeof(mdt_t)); 453 if (!msg_types) 454 return(PDS_NOMEMORY); 455 /* initialise message type table */ 456 for (i=0;i<MDT_MAX_NOF_TYPES;i++) { 457 msg_types[i].type_no = (msg_type_no_t) 0; 458 msg_types[i].def = (msg_typedef_t *) 0; 459 msg_types[i].def_size = 0; 460 msg_types[i].idr_align = 1; 461 msg_types[i].idr_size = 0; 462 msg_types[i].xdr_size = 0; 463 } 464 465 msg_intfcs[index].intfc_no = intfc_no; 466 msg_intfcs[index].msg_types = msg_types; 467 *type_index = (msg_type & 0xffff) % (MDT_MAX_NOF_TYPES / 2); 468 return(PDS_OK); 469 } 470 else { 471 /* derive type_index */ 472 msg_types = msg_intfcs[index].msg_types; 473 type_no = TypeNo(msg_type); 474 index = type_no % 0x10 + type_no / 0x10; 475 index = index % (MDT_MAX_NOF_TYPES / 2); 476 if (!msg_types[index].type_no) 477 *type_index = index; 478 else { 479 index = MDT_MAX_NOF_TYPES - 1; 480 while (index && msg_types[index].type_no) 481 index--; 482 if (!index) 483 return(PDS_NORESOURCES); 484 else 485 *type_index = index; 486 } 487 return(PDS_OK); 488 } 489} 490 491 492static pds_ret_t 493get_mdt(msg_type,mdt) 494 msg_type_t msg_type; 495 mdt_t * * mdt; 496{ 497 unsigned intfc_index; 498 unsigned type_index; 499 pds_ret_t pret; 500 501 if (!IntfcNo(msg_type)) { 502 if ((msg_type < MDT_STD_MIN) || (msg_type > MDT_STD_MAX)) 503 return(PDS_INVAL); 504 else { 505 *mdt = &std_types[msg_type]; 506 return(PDS_OK); 507 } 508 } 509 510 pret = get_matching_index(msg_type,&intfc_index,&type_index); 511 if (pret != PDS_OK) 512 return(pret); 513 else { 514 *mdt = &msg_intfcs[intfc_index].msg_types[type_index]; 515 return(PDS_OK); 516 } 517} 518 519 520/* 521** Primitive: padalign() 522** Description: aligns ptr on <align>-byte boundary. When in encoding 523** mode, padding with nil-bytes takes place. 524*/ 525 526static void 527padalign(ptr,align,size,option) 528 char * * ptr; 529 unsigned align; 530 unsigned * size; 531 msg_option_t option; 532{ 533 int i; 534 long count; 535 536 mdt_assert(align>0); 537 538 count = (*ptr - (char *) 0) % align; 539 if (count <= 0) 540 count = -count; 541 else 542 count = align - count; 543 if (option == MDT_ENCODE) /* pad with zeros */ 544 for (i=0;i<count;i++) 545 (*ptr)[i] = 0; 546 *ptr = *ptr + count; 547 if (size) 548 *size = count; 549} 550 551 552/* 553** Primitive: derive_std_alignments() 554** Description: derives the alignment requirements of the standard 555** message data types and records this in the message 556** data type table. 557*/ 558 559static void 560derive_std_alignments() 561{ 562 struct { 563 char c; 564 pds_half_word_t t; 565 } pds_hword_str; 566 567 struct { 568 char c; 569 pds_word_t t; 570 } pds_word_str; 571 572 struct { 573 char c; 574 pds_double_word_t t; 575 } pds_dword_str; 576 577 struct { 578 char c; 579 pds_address_t t; 580 } pds_address_str; 581 582 struct { 583 char c; 584 pds_int8 t; 585 } pds_int8_str; 586 587 struct { 588 char c; 589 pds_uint8 t; 590 } pds_uint8_str; 591 592 struct { 593 char c; 594 pds_int16 t; 595 } pds_int16_str; 596 597 struct { 598 char c; 599 pds_uint16 t; 600 } pds_uint16_str; 601 602 struct { 603 char c; 604 pds_int32 t; 605 } pds_int32_str; 606 607 struct { 608 char c; 609 pds_uint32 t; 610 } pds_uint32_str; 611 612 struct { 613 char c; 614 pds_sp_float t; 615 } pds_sp_float_str; 616 617 struct { 618 char c; 619 pds_dp_float t; 620 } pds_dp_float_str; 621 622 mdt_assert(sizeof(pds_byte_t) == 1); 623 mdt_assert(sizeof(char) == 1); 624 mdt_assert(sizeof(unsigned char) == 1); 625 626 std_types[MDT_BYTE].idr_align = 1; 627 std_types[MDT_HWORD].idr_align = sizeof(pds_hword_str) - 628 sizeof(pds_hword_str.t); 629 std_types[MDT_WORD].idr_align = sizeof(pds_word_str) - 630 sizeof(pds_word_str.t); 631 std_types[MDT_DWORD].idr_align = sizeof(pds_dword_str) - 632 sizeof(pds_dword_str.t); 633 std_types[MDT_ADDRESS].idr_align = sizeof(pds_address_str) - 634 sizeof(pds_address_str.t); 635 std_types[MDT_CHAR].idr_align = 1; 636 std_types[MDT_UCHAR].idr_align = 1; 637 std_types[MDT_INT8].idr_align = sizeof(pds_int8_str) - 638 sizeof(pds_int8_str.t); 639 std_types[MDT_UINT8].idr_align = sizeof(pds_uint8_str) - 640 sizeof(pds_uint8_str.t); 641 std_types[MDT_INT16].idr_align = sizeof(pds_int16_str) - 642 sizeof(pds_int16_str.t); 643 std_types[MDT_UINT16].idr_align = sizeof(pds_uint16_str) - 644 sizeof(pds_uint16_str.t); 645 std_types[MDT_INT32].idr_align = sizeof(pds_int32_str) - 646 sizeof(pds_int32_str.t); 647 std_types[MDT_UINT32].idr_align = sizeof(pds_uint32_str) - 648 sizeof(pds_uint32_str.t); 649 std_types[MDT_SP_FLOAT].idr_align = sizeof(pds_sp_float_str) - 650 sizeof(pds_sp_float_str.t); 651 std_types[MDT_DP_FLOAT].idr_align = sizeof(pds_dp_float_str) - 652 sizeof(pds_dp_float_str.t); 653} 654 655 656static pds_ret_t 657idrmsg_mdt_info(msg_typedef,size,align) 658 msg_typedef_t * * msg_typedef; 659 pds_size_t * size; 660 unsigned int * align; 661{ 662 mdt_t * mdt; 663 pds_ret_t pret; 664 665 if ((pret = get_mdt(**msg_typedef,&mdt)) != PDS_OK) 666 return(pret); 667 668 *size = mdt->idr_size; 669 *align = mdt->idr_align; 670 (*msg_typedef)++; 671 return(PDS_OK); 672} 673 674 675static pds_ret_t 676xdrmsg_mdt_info(msg_typedef,size) 677 msg_typedef_t * * msg_typedef; 678 pds_size_t * size; 679{ 680 mdt_t * mdt; 681 pds_ret_t pret; 682 683 if ((pret = get_mdt(**msg_typedef,&mdt)) != PDS_OK) 684 return(pret); 685 686 *size = mdt->xdr_size; 687 (*msg_typedef)++; 688 return(PDS_OK); 689} 690 691 692static pds_ret_t 693idrmsg_pad_info(msg_typedef,size,align) 694 msg_typedef_t * * msg_typedef; 695 pds_size_t * size; 696 unsigned * align; 697{ 698 mdt_assert(**msg_typedef == MDT_PAD); 699 700 (*msg_typedef)++; 701 702 *size = (pds_size_t) **msg_typedef; 703 *align = 1; 704 705 (*msg_typedef)++; 706 707 return(PDS_OK); 708} 709 710 711static pds_ret_t 712xdrmsg_pad_info(msg_typedef,size) 713 msg_typedef_t * * msg_typedef; 714 pds_size_t * size; 715{ 716 mdt_assert(**msg_typedef == MDT_PAD); 717 718 (*msg_typedef)++; 719 720 /* skip pad_count */ 721 (*msg_typedef)++; 722 723 *size = 0; 724 725 return(PDS_OK); 726} 727 728 729static pds_ret_t 730idrmsg_array_info(msg_typedef,size,align) 731 msg_typedef_t * * msg_typedef; 732 pds_size_t * size; 733 unsigned * align; 734{ 735 pds_uint32 array_count; 736 pds_size_t element_size; 737 pds_ret_t pret; 738 739 mdt_assert(**msg_typedef == MDT_ARRAY_OF); 740 741 /* get array_count */ 742 (*msg_typedef)++; 743 array_count = (pds_uint32) **msg_typedef; 744 745 /* get element_size and alignment */ 746 (*msg_typedef)++; 747 if ((pret = idrmsg_opaque_info(msg_typedef,&element_size,align)) != PDS_OK) 748 return(pret); 749 else { 750 *size = array_count * element_size; 751 return(PDS_OK); 752 } 753} 754 755 756static pds_ret_t 757xdrmsg_array_info(msg_typedef,size) 758 msg_typedef_t * * msg_typedef; 759 pds_size_t * size; 760{ 761 pds_uint32 array_count; 762 pds_size_t element_size; 763 pds_ret_t pret; 764 765 mdt_assert(**msg_typedef == MDT_ARRAY_OF); 766 767 /* get array_count */ 768 (*msg_typedef)++; 769 array_count = (pds_uint32) **msg_typedef; 770 771 (*msg_typedef)++; 772 if (**msg_typedef == MDT_BYTE) { /* single opaque array */ 773 unsigned int remainder; 774 remainder = array_count % 4; 775 if (remainder) 776 *size = 4 + array_count + (4 - remainder); 777 else 778 *size = 4 + array_count; 779 (*msg_typedef)++; 780 } 781 else { 782 /* get element_size */ 783 if ((pret = xdrmsg_opaque_info(msg_typedef,&element_size)) != PDS_OK) 784 return(pret); 785 *size = array_count * element_size; 786 } 787 788 return(PDS_OK); 789} 790 791 792static pds_ret_t 793idrmsg_struct_info(msg_typedef,size,align) 794 msg_typedef_t * * msg_typedef; 795 pds_size_t * size; 796 unsigned int * align; 797{ 798 unsigned field_align; 799 pds_size_t field_size; 800 pds_size_t struct_size; 801 unsigned struct_align; 802 pds_ret_t pret; 803 804 mdt_assert(**msg_typedef == MDT_STRUCT_OPEN); 805 806 struct_size = 0; 807 struct_align = 1; 808 (*msg_typedef)++; 809 while (**msg_typedef != MDT_STRUCT_CLOSE) { 810 if ((pret = idrmsg_opaque_info(msg_typedef,&field_size,&field_align)) != PDS_OK) 811 return(pret); 812 struct_size += field_size; 813 if (field_align > struct_align) 814 struct_align = field_align; 815 } 816 (*msg_typedef)++; 817 *size = struct_size; 818 *align = struct_align; 819 820 return(PDS_OK); 821} 822 823 824static pds_ret_t 825xdrmsg_struct_info(msg_typedef,size) 826 msg_typedef_t * * msg_typedef; 827 pds_size_t * size; 828{ 829 pds_size_t field_size; 830 pds_size_t struct_size; 831 832 mdt_assert(**msg_typedef == MDT_STRUCT_OPEN); 833 834 struct_size = 0; 835 (*msg_typedef)++; 836 while (**msg_typedef != MDT_STRUCT_CLOSE) { 837 xdrmsg_opaque_info(msg_typedef,&field_size); 838 struct_size += field_size; 839 } 840 (*msg_typedef)++; 841 *size = struct_size; 842 843 return(PDS_OK); 844} 845 846 847static pds_ret_t 848idrmsg_opaque_info(msg_typedef,size,align) 849 msg_typedef_t * * msg_typedef; 850 pds_size_t * size; 851 unsigned int * align; 852{ 853 switch (**msg_typedef) { 854 case MDT_STRUCT_OPEN : 855 return(idrmsg_struct_info(msg_typedef,size,align)); 856 case MDT_STRUCT_CLOSE : 857 return(PDS_INVAL); 858 case MDT_ARRAY_OF : 859 return(idrmsg_array_info(msg_typedef,size,align)); 860 case MDT_PAD : 861 return(idrmsg_pad_info(msg_typedef,size,align)); 862 default : 863 return(idrmsg_mdt_info(msg_typedef,size,align)); 864 } 865} 866 867 868static pds_ret_t 869xdrmsg_opaque_info(msg_typedef,size) 870 msg_typedef_t * * msg_typedef; 871 pds_size_t * size; 872{ 873 switch (**msg_typedef) { 874 case MDT_STRUCT_OPEN : 875 return(xdrmsg_struct_info(msg_typedef,size)); 876 case MDT_STRUCT_CLOSE : 877 return(PDS_INVAL); 878 case MDT_ARRAY_OF : 879 return(xdrmsg_array_info(msg_typedef,size)); 880 case MDT_PAD : 881 return(xdrmsg_pad_info(msg_typedef,size)); 882 default : 883 return(xdrmsg_mdt_info(msg_typedef,size)); 884 } 885} 886 887 888static bool_t 889xdr_msg_stdtype(xdrs,msg_typedef,msg_data) 890 XDR * xdrs; 891 msg_typedef_t * * msg_typedef; 892 msg_data_t * * msg_data; 893{ 894 msg_type_t msg_type; 895 896 msg_type = **msg_typedef; 897 (*msg_typedef)++; 898 899 switch (msg_type) { 900 case MDT_BYTE : 901 if (xdr_pds_byte(xdrs,(pds_byte_t *) *msg_data)) { 902 *msg_data = (msg_data_t *) 903 ((char *) *msg_data + sizeof(pds_byte_t)); 904 return(1); 905 } else return(0); 906 case MDT_HWORD : 907 if (xdr_pds_half_word(xdrs,(pds_half_word_t *) *msg_data)) { 908 *msg_data = (msg_data_t *) 909 ((char *) *msg_data + sizeof(pds_half_word_t)); 910 return(1); 911 } else return(0); 912 case MDT_WORD : 913 if (xdr_pds_word(xdrs,(pds_word_t *) *msg_data)) { 914 *msg_data = (msg_data_t *) 915 ((char *) *msg_data + sizeof(pds_word_t)); 916 return(1); 917 } else return(0); 918 case MDT_DWORD : 919 if (xdr_pds_double_word(xdrs,(pds_double_word_t *) *msg_data)) { 920 *msg_data = (msg_data_t *) 921 ((char *) *msg_data + sizeof(pds_double_word_t)); 922 return(1); 923 } else return(0); 924 case MDT_ADDRESS : 925 if (xdr_pds_address(xdrs,(pds_address_t *) *msg_data)) { 926 *msg_data = (msg_data_t *) 927 ((char *) *msg_data + sizeof(pds_address_t)); 928 return(1); 929 } else return(0); 930 case MDT_CHAR : 931 if (xdr_pds_char(xdrs,(pds_char *) *msg_data)) { 932 *msg_data = (msg_data_t *) 933 ((char *) *msg_data + sizeof(pds_char)); 934 return(1); 935 } else return(0); 936 case MDT_UCHAR : 937 if (xdr_pds_u_char(xdrs,(pds_uchar *) *msg_data)) { 938 *msg_data = (msg_data_t *) 939 ((char *) *msg_data + sizeof(pds_uchar)); 940 return(1); 941 } else return(0); 942 case MDT_INT8 : 943 if (xdr_pds_int8(xdrs,(pds_int8 *) *msg_data)) { 944 *msg_data = (msg_data_t *) 945 ((char *) *msg_data + sizeof(pds_int8)); 946 return(1); 947 } else return(0); 948 case MDT_UINT8 : 949 if (xdr_pds_u_int8(xdrs,(pds_uint8 *) *msg_data)) { 950 *msg_data = (msg_data_t *) 951 ((char *) *msg_data + sizeof(pds_uint8)); 952 return(1); 953 } else return(0); 954 case MDT_INT16 : 955 if (xdr_pds_int16(xdrs,(pds_int16 *) *msg_data)) { 956 *msg_data = (msg_data_t *) 957 ((char *) *msg_data + sizeof(pds_int16)); 958 return(1); 959 } else return(0); 960 case MDT_UINT16 : 961 if (xdr_pds_u_int16(xdrs,(pds_uint16 *) *msg_data)) { 962 *msg_data = (msg_data_t *) 963 ((char *) *msg_data + sizeof(pds_uint16)); 964 return(1); 965 } else return(0); 966 case MDT_INT32 : 967 if (xdr_pds_int32(xdrs,(pds_int32 *) *msg_data)) { 968 *msg_data = (msg_data_t *) 969 ((char *) *msg_data + sizeof(pds_int32)); 970 return(1); 971 } else return(0); 972 case MDT_UINT32 : 973 if (xdr_pds_u_int32(xdrs,(pds_uint32 *) *msg_data)) { 974 *msg_data = (msg_data_t *) 975 ((char *) *msg_data + sizeof(pds_uint32)); 976 return(1); 977 } else return(0); 978 case MDT_SP_FLOAT : 979 if (xdr_pds_sp_float(xdrs,(pds_sp_float *) *msg_data)) { 980 *msg_data = (msg_data_t *) 981 ((char *) *msg_data + sizeof(pds_sp_float)); 982 return(1); 983 } else return(0); 984 case MDT_DP_FLOAT : 985 if (xdr_pds_dp_float(xdrs,(pds_dp_float *) *msg_data)) { 986 *msg_data = (msg_data_t *) 987 ((char *) *msg_data + sizeof(pds_dp_float)); 988 return(1); 989 } else return(0); 990 default : 991 return(0); 992 } 993} 994 995 996static bool_t 997xdr_msg_pad(xdrs,msg_typedef,msg_data) 998 XDR * xdrs; 999 msg_typedef_t * * msg_typedef; 1000 msg_data_t * * msg_data; 1001{ 1002 pds_uint32 pad_count; 1003 int i; 1004 1005 mdt_assert(**msg_typedef == MDT_PAD); 1006 1007 /* get pad_count */ 1008 (*msg_typedef)++; 1009 pad_count = (pds_uint32) **msg_typedef; 1010 1011 if (xdrs->x_op == XDR_ENCODE) { 1012 *msg_data = (msg_data_t *) 1013 ((char *) *msg_data + pad_count); 1014 } 1015 else { 1016 for (i=0;i<pad_count;i++) { 1017 * (char *) *msg_data = (char) 0; 1018 *msg_data = (msg_data_t *) 1019 ((char *) *msg_data + 1); 1020 } 1021 } 1022 1023 (*msg_typedef)++; 1024 1025 return(1); 1026} 1027 1028 1029static bool_t 1030xdr_msg_array(xdrs,msg_typedef,msg_data) 1031 XDR * xdrs; 1032 msg_typedef_t * * msg_typedef; 1033 msg_data_t * * msg_data; 1034{ 1035 pds_uint32 array_count; 1036 msg_typedef_t * def; 1037 int i; 1038 1039 mdt_assert(**msg_typedef == MDT_ARRAY_OF); 1040 1041 /* get array_count */ 1042 (*msg_typedef)++; 1043 array_count = (pds_uint32) **msg_typedef; 1044 1045 (*msg_typedef)++; 1046 if (**msg_typedef == MDT_BYTE) { /* single opaque array */ 1047 (*msg_typedef)++; 1048 if (!xdr_opaque(xdrs, (char *) *msg_data, (u_int) array_count)) 1049 return(0); 1050 *msg_data = (msg_data_t *) 1051 ((char *) *msg_data + array_count * sizeof(pds_byte_t)); 1052 } 1053 else { 1054 for (i=0;i<array_count;i++) { 1055 def = *msg_typedef; 1056 if (!xdr_msg_opaque(xdrs,&def,msg_data)) 1057 return(0); 1058 } 1059 *msg_typedef = def; 1060 } 1061 return(1); 1062} 1063 1064 1065static bool_t 1066xdr_msg_structure(xdrs,msg_typedef,msg_data) 1067 XDR * xdrs; 1068 msg_typedef_t * * msg_typedef; 1069 msg_data_t * * msg_data; 1070{ 1071 mdt_assert(**msg_typedef == MDT_STRUCT_OPEN); 1072 1073 (*msg_typedef)++; 1074 while (**msg_typedef != MDT_STRUCT_CLOSE) 1075 if (!xdr_msg_opaque(xdrs,msg_typedef,msg_data)) 1076 return(0); 1077 (*msg_typedef)++; 1078 return(1); 1079} 1080 1081 1082static bool_t 1083xdr_msg_opaque(xdrs,msg_typedef,msg_data) 1084 XDR * xdrs; 1085 msg_typedef_t * * msg_typedef; 1086 msg_data_t * * msg_data; 1087{ 1088 switch (**msg_typedef) { 1089 case MDT_STRUCT_OPEN : 1090 return(xdr_msg_structure(xdrs,msg_typedef,msg_data)); 1091 case MDT_STRUCT_CLOSE : 1092 return(0); 1093 case MDT_ARRAY_OF : 1094 return(xdr_msg_array(xdrs,msg_typedef,msg_data)); 1095 case MDT_PAD : 1096 return(xdr_msg_pad(xdrs,msg_typedef,msg_data)); 1097 default : 1098 return(xdr_msg_stdtype(xdrs,msg_typedef,msg_data)); 1099 } 1100} 1101 1102 1103 1104 1105/********************************************************************** 1106************************ Exported Primitives ************************ 1107***********************************************************************/ 1108 1109#define MDT_BUF_SIZE 512 1110 1111pds_ret_t 1112pds_types_init(address) 1113 char * address; 1114{ 1115 pds_byte_t idr_byte; 1116 pds_half_word_t idr_hword; 1117 pds_word_t idr_word; 1118 pds_double_word_t idr_dword; 1119 pds_address_t idr_address; 1120 pds_char idr_char; 1121 pds_uchar idr_uchar; 1122 pds_int8 idr_int8; 1123 pds_uint8 idr_uint8; 1124 pds_int16 idr_int16; 1125 pds_uint16 idr_uint16; 1126 pds_int32 idr_int32; 1127 pds_uint32 idr_uint32; 1128 pds_sp_float idr_sp_float; 1129 pds_dp_float idr_dp_float; 1130 1131 char buffer[MDT_BUF_SIZE]; 1132 unsigned int i,pos_old,pos_new; 1133 XDR xdrs; 1134 1135 mdt_assert(sizeof(msg_count_t) == sizeof(msg_typedef_t)); 1136 mdt_assert(sizeof(msg_type_t) == 4); 1137 1138 /* private heap for message type definitions */ 1139 if (pds_mem_init((char *) 0,address,MDT_HEAP_SIZE,&mdt_phd,1) == (char *) -1) 1140 return(PDS_NOMEMORY); 1141 1142 /* initialise message type interface table */ 1143 for (i=0;i<MDT_MAX_NOF_INTFCS;i++) { 1144 msg_intfcs[i].intfc_no = (msg_intfc_no_t) 0; 1145 msg_intfcs[i].msg_types = (mdt_t *) 0; 1146 } 1147 1148 /* initialise standard message type table */ 1149 for (i=0;i<MDT_MAX_NOF_TYPES;i++) { 1150 std_types[i].type_no = (msg_type_no_t) 0; 1151 std_types[i].def = (msg_typedef_t *) 0; 1152 std_types[i].def_size = 0; 1153 std_types[i].idr_align = 1; 1154 std_types[i].idr_size = 0; 1155 std_types[i].xdr_size = 0; 1156 } 1157 1158 derive_std_alignments(); 1159 1160 std_types[MDT_BYTE].type_no = MDT_BYTE; 1161 std_types[MDT_HWORD].type_no = MDT_HWORD; 1162 std_types[MDT_WORD].type_no = MDT_WORD; 1163 std_types[MDT_DWORD].type_no = MDT_DWORD; 1164 std_types[MDT_ADDRESS].type_no = MDT_ADDRESS; 1165 std_types[MDT_CHAR].type_no = MDT_CHAR; 1166 std_types[MDT_UCHAR].type_no = MDT_UCHAR; 1167 std_types[MDT_INT8].type_no = MDT_INT8; 1168 std_types[MDT_UINT8].type_no = MDT_UINT8; 1169 std_types[MDT_INT16].type_no = MDT_INT16; 1170 std_types[MDT_UINT16].type_no = MDT_UINT16; 1171 std_types[MDT_INT32].type_no = MDT_INT32; 1172 std_types[MDT_UINT32].type_no = MDT_UINT32; 1173 std_types[MDT_SP_FLOAT].type_no = MDT_SP_FLOAT; 1174 std_types[MDT_DP_FLOAT].type_no = MDT_DP_FLOAT; 1175 1176 std_types[MDT_BYTE].def = &mdt_byte; 1177 std_types[MDT_HWORD].def = &mdt_hword; 1178 std_types[MDT_WORD].def = &mdt_word; 1179 std_types[MDT_DWORD].def = &mdt_dword; 1180 std_types[MDT_ADDRESS].def = &mdt_address; 1181 std_types[MDT_CHAR].def = &mdt_char; 1182 std_types[MDT_UCHAR].def = &mdt_uchar; 1183 std_types[MDT_INT8].def = &mdt_int8; 1184 std_types[MDT_UINT8].def = &mdt_uint8; 1185 std_types[MDT_INT16].def = &mdt_int16; 1186 std_types[MDT_UINT16].def = &mdt_uint16; 1187 std_types[MDT_INT32].def = &mdt_int32; 1188 std_types[MDT_UINT32].def = &mdt_uint32; 1189 std_types[MDT_SP_FLOAT].def = &mdt_sp_float; 1190 std_types[MDT_DP_FLOAT].def = &mdt_dp_float; 1191 1192 std_types[MDT_BYTE].def_size = 1; 1193 std_types[MDT_HWORD].def_size = 1; 1194 std_types[MDT_WORD].def_size = 1; 1195 std_types[MDT_DWORD].def_size = 1; 1196 std_types[MDT_ADDRESS].def_size = 1; 1197 std_types[MDT_CHAR].def_size = 1; 1198 std_types[MDT_UCHAR].def_size = 1; 1199 std_types[MDT_INT8].def_size = 1; 1200 std_types[MDT_UINT8].def_size = 1; 1201 std_types[MDT_INT16].def_size = 1; 1202 std_types[MDT_UINT16].def_size = 1; 1203 std_types[MDT_INT32].def_size = 1; 1204 std_types[MDT_UINT32].def_size = 1; 1205 std_types[MDT_SP_FLOAT].def_size = 1; 1206 std_types[MDT_DP_FLOAT].def_size = 1; 1207 1208 std_types[MDT_BYTE].idr_size = sizeof(pds_byte_t); 1209 std_types[MDT_HWORD].idr_size = sizeof(pds_half_word_t); 1210 std_types[MDT_WORD].idr_size = sizeof(pds_word_t); 1211 std_types[MDT_DWORD].idr_size = sizeof(pds_double_word_t); 1212 std_types[MDT_ADDRESS].idr_size = sizeof(pds_address_t); 1213 std_types[MDT_CHAR].idr_size = sizeof(char); 1214 std_types[MDT_UCHAR].idr_size = sizeof(unsigned char); 1215 std_types[MDT_INT8].idr_size = sizeof(pds_int8); 1216 std_types[MDT_UINT8].idr_size = sizeof(pds_uint8); 1217 std_types[MDT_INT16].idr_size = sizeof(pds_int16); 1218 std_types[MDT_UINT16].idr_size = sizeof(pds_uint16); 1219 std_types[MDT_INT32].idr_size = sizeof(pds_int32); 1220 std_types[MDT_UINT32].idr_size = sizeof(pds_uint32); 1221 std_types[MDT_SP_FLOAT].idr_size = sizeof(pds_sp_float); 1222 std_types[MDT_DP_FLOAT].idr_size = sizeof(pds_dp_float); 1223 1224 xdrmem_create(&xdrs,(const caddr_t) buffer, 1225 (const u_int) MDT_BUF_SIZE, 1226 XDR_ENCODE); 1227 1228 pos_old = 0; 1229 1230 if (!xdr_pds_byte(&xdrs,&idr_byte)) return(PDS_NORESOURCES); 1231 pos_new = xdr_getpos(&xdrs); 1232 std_types[MDT_BYTE].xdr_size = pos_new - pos_old; 1233 pos_old = pos_new; 1234 1235 if (!xdr_pds_half_word(&xdrs,&idr_hword)) return(PDS_NORESOURCES); 1236 pos_new = xdr_getpos(&xdrs); 1237 std_types[MDT_HWORD].xdr_size = pos_new - pos_old; 1238 pos_old = pos_new; 1239 1240 if (!xdr_pds_word(&xdrs,&idr_word)) return(PDS_NORESOURCES); 1241 pos_new = xdr_getpos(&xdrs); 1242 std_types[MDT_WORD].xdr_size = pos_new - pos_old; 1243 pos_old = pos_new; 1244 1245 if (!xdr_pds_double_word(&xdrs,&idr_dword)) return(PDS_NORESOURCES); 1246 pos_new = xdr_getpos(&xdrs); 1247 std_types[MDT_DWORD].xdr_size = pos_new - pos_old; 1248 pos_old = pos_new; 1249 1250 if (!xdr_pds_address(&xdrs,&idr_address)) return(PDS_NORESOURCES); 1251 pos_new = xdr_getpos(&xdrs); 1252 std_types[MDT_ADDRESS].xdr_size = pos_new - pos_old; 1253 pos_old = pos_new; 1254 1255 if (!xdr_pds_char(&xdrs,&idr_char)) return(PDS_NORESOURCES); 1256 pos_new = xdr_getpos(&xdrs); 1257 std_types[MDT_CHAR].xdr_size = pos_new - pos_old; 1258 pos_old = pos_new; 1259 1260 if (!xdr_pds_u_char(&xdrs,&idr_uchar)) return(PDS_NORESOURCES); 1261 pos_new = xdr_getpos(&xdrs); 1262 std_types[MDT_UCHAR].xdr_size = pos_new - pos_old; 1263 pos_old = pos_new; 1264 1265 if (!xdr_pds_int8(&xdrs,&idr_int8)) return(PDS_NORESOURCES); 1266 pos_new = xdr_getpos(&xdrs); 1267 std_types[MDT_INT8].xdr_size = pos_new - pos_old; 1268 pos_old = pos_new; 1269 1270 if (!xdr_pds_u_int8(&xdrs,&idr_uint8)) return(PDS_NORESOURCES); 1271 pos_new = xdr_getpos(&xdrs); 1272 std_types[MDT_UINT8].xdr_size = pos_new - pos_old; 1273 pos_old = pos_new; 1274 1275 if (!xdr_pds_int16(&xdrs,&idr_int16)) return(PDS_NORESOURCES); 1276 pos_new = xdr_getpos(&xdrs); 1277 std_types[MDT_INT16].xdr_size = pos_new - pos_old; 1278 pos_old = pos_new; 1279 1280 if (!xdr_pds_u_int16(&xdrs,&idr_uint16)) return(PDS_NORESOURCES); 1281 pos_new = xdr_getpos(&xdrs); 1282 std_types[MDT_UINT16].xdr_size = pos_new - pos_old; 1283 pos_old = pos_new; 1284 1285 if (!xdr_pds_int32(&xdrs,&idr_int32)) return(PDS_NORESOURCES); 1286 pos_new = xdr_getpos(&xdrs); 1287 std_types[MDT_INT32].xdr_size = pos_new - pos_old; 1288 pos_old = pos_new; 1289 1290 if (!xdr_pds_u_int32(&xdrs,&idr_uint32)) return(PDS_NORESOURCES); 1291 pos_new = xdr_getpos(&xdrs); 1292 std_types[MDT_UINT32].xdr_size = pos_new - pos_old; 1293 pos_old = pos_new; 1294 1295 if (!xdr_pds_sp_float(&xdrs,&idr_sp_float)) return(PDS_NORESOURCES); 1296 pos_new = xdr_getpos(&xdrs); 1297 std_types[MDT_SP_FLOAT].xdr_size = pos_new - pos_old; 1298 pos_old = pos_new; 1299 1300 if (!xdr_pds_dp_float(&xdrs,&idr_dp_float)) return(PDS_NORESOURCES); 1301 pos_new = xdr_getpos(&xdrs); 1302 std_types[MDT_DP_FLOAT].xdr_size = pos_new - pos_old; 1303 1304 xdr_destroy(&xdrs); 1305 1306 l_mutex_init(&mdt_mutex); 1307 1308 mdt_initialised = 1; 1309 1310 return(PDS_OK); 1311} 1312 1313 1314bool_t 1315pds_type_xdr(xdrs,msg_type,msg_data) 1316 XDR * xdrs; 1317 msg_type_t msg_type; 1318 msg_data_t * msg_data; 1319{ 1320 msg_typedef_t * msg_typedef; 1321 mdt_t * mdt; 1322 1323#if !defined(TRUSTED) 1324 if ((!xdrs) || (!msg_data)) 1325 return((bool_t) 0); 1326#endif 1327 1328 mdt_assert(mdt_initialised); 1329 1330 if (get_mdt(msg_type,&mdt) != PDS_OK) 1331 return((bool_t) 0); 1332 1333 msg_typedef = mdt->def; 1334 if (!xdr_msg_opaque(xdrs,&msg_typedef,&msg_data)) 1335 return((bool_t) 0); 1336 1337 return((bool_t) 1); 1338} 1339 1340 1341bool_t 1342pds_msg_xdr(xdrs,msg_type,msg_count,msg_data) 1343 XDR * xdrs; 1344 msg_type_t msg_type; 1345 msg_count_t msg_count; 1346 msg_data_t * msg_data; 1347{ 1348 msg_typedef_t * msg_typedef; 1349 mdt_t * mdt; 1350 1351#if !defined(TRUSTED) 1352 if ((!xdrs) || (!msg_data)) 1353 return((bool_t) 0); 1354#endif 1355 1356 mdt_assert(mdt_initialised); 1357 1358 if (get_mdt(msg_type,&mdt) != PDS_OK) 1359 return((bool_t) 0); 1360 1361 while (msg_count > 0) { 1362 msg_typedef = mdt->def; 1363 if (!xdr_msg_opaque(xdrs,&msg_typedef,&msg_data)) 1364 return((bool_t) 0); 1365 msg_count--; 1366 } 1367 1368 return((bool_t) 1); 1369} 1370 1371 1372pds_ret_t 1373pds_type_size(msg_type,size,option) 1374 msg_type_t msg_type; 1375 pds_size_t * size; 1376 msg_option_t option; 1377{ 1378 mdt_t * mdt; 1379 pds_ret_t pret; 1380 1381#if !defined(TRUSTED) 1382 if (!size) 1383 return(PDS_INVAL); 1384#endif 1385 1386 mdt_assert(mdt_initialised); 1387 1388 if ((pret = get_mdt(msg_type,&mdt)) != PDS_OK) 1389 return(pret); 1390 1391 if (option == MDT_IDR) 1392 *size = mdt->idr_size; 1393#if !defined(TRUSTED) 1394 else if (option != MDT_XDR) 1395 return(PDS_INVAL); 1396#endif 1397 else 1398 *size = mdt->xdr_size; 1399 1400 return(PDS_OK); 1401} 1402 1403 1404pds_ret_t 1405pds_type_define(msg_intfc_no,msg_type_no,msg_typedef,msg_type) 1406 msg_intfc_no_t msg_intfc_no; 1407 msg_type_no_t msg_type_no; 1408 msg_typedef_t * msg_typedef; 1409 msg_type_t * msg_type; 1410{ 1411 unsigned intfc_index; 1412 unsigned type_index; 1413 mdt_t * mdt; 1414 pds_ret_t pret; 1415 msg_typedef_t * msg_typedef_start; 1416 unsigned idr_align; 1417 unsigned array_align; 1418 unsigned idr_size; 1419 unsigned xdr_size; 1420 unsigned def_size; 1421 unsigned array_size; 1422 msg_typedef_t * definition; 1423 msg_typedef_t * def; 1424 msg_typedef_t * array_def; 1425 char * address; 1426 unsigned pad_size; 1427 unsigned multiplier; 1428 int mdt_structure; 1429 int pad_done; 1430 1431#if !defined(TRUSTED) 1432 if ((!msg_typedef) || (!msg_type)) 1433 return(PDS_INVAL); 1434#endif 1435 1436 if (!msg_intfc_no || (msg_intfc_no > MSG_INTFC_NO_MAX) || 1437 !msg_type_no || (msg_type_no > MSG_TYPE_NO_MAX)) 1438 return(PDS_INVAL); 1439 1440 mdt_assert(mdt_initialised); 1441 1442 if (msg_typedef[0] != MDT_BEGIN) /* invalid type definition */ 1443 return(PDS_INVAL); 1444 if (msg_typedef[1] == MDT_END) /* empty type definition */ 1445 return(PDS_INVAL); 1446 1447 mdt_structure = 0; 1448 msg_typedef_start = msg_typedef; 1449 msg_typedef++; 1450 1451 /* 1452 ** Sanity check and size estimation of message type definition. 1453 */ 1454 1455 def_size = 0; 1456 1457 while (*msg_typedef != MDT_END) { 1458 switch (*msg_typedef) { 1459 case MDT_BEGIN : 1460 return(PDS_INVAL); 1461 case MDT_STRUCT_OPEN : 1462 if (*(msg_typedef-1) != MDT_BEGIN) 1463 return(PDS_INVAL); 1464 if (*(msg_typedef+1) == MDT_STRUCT_CLOSE) /* empty structure */ 1465 return(PDS_INVAL); 1466 if (mdt_structure) /* nested structure */ 1467 return(PDS_INVAL); 1468 mdt_structure = 1; 1469 def_size++; /* MDT_STRUCT_OPEN */ 1470 break; 1471 case MDT_STRUCT_CLOSE : 1472 if (*(msg_typedef+1) != MDT_END) 1473 return(PDS_INVAL); 1474 if (!mdt_structure) /* bracket mismatch */ 1475 return(PDS_INVAL); 1476 def_size += 2; /* pad definition */ 1477 def_size++; /* MDT_STRUCT_CLOSE */ 1478 break; 1479 case MDT_ARRAY_OF : 1480 if ((*(msg_typedef+2) == MDT_END) || 1481 (*(msg_typedef+2) == MDT_STRUCT_CLOSE)) /* invalid array */ 1482 return(PDS_INVAL); 1483 def_size ++; /* MDT_ARRAY_OF */ 1484 msg_typedef++; 1485 def_size ++; /* array count */ 1486 break; 1487 default : 1488 pret = get_mdt(*msg_typedef,&mdt); 1489 if (pret != PDS_OK) 1490 return(pret); 1491 if ((mdt_structure) && (mdt->idr_align > 1)) 1492 def_size += 2; /* pad definition */ 1493 def_size += mdt->def_size; /* subtype definition */ 1494 break; 1495 } 1496 msg_typedef++; 1497 } 1498 1499 /* allocate memory for temporary message type definition */ 1500 definition = (msg_typedef_t *) 1501 pds_mem_alloc(&mdt_phd,def_size * sizeof(msg_typedef_t)); 1502 if (!definition) 1503 return(PDS_NOMEMORY); 1504 1505 /* 1506 ** Generate message type definition 1507 */ 1508 1509 def = definition; 1510 msg_typedef = msg_typedef_start+1; 1511 1512 idr_align = 1; 1513 multiplier = 1; 1514 mdt_structure = 0; 1515 pad_done = 0; 1516 address = (char *) 0; 1517 1518 while (*msg_typedef != MDT_END) { 1519 switch (*msg_typedef) { 1520 case MDT_STRUCT_OPEN : 1521 mdt_structure = 1; 1522 *def++ = *msg_typedef; 1523 break; 1524 case MDT_STRUCT_CLOSE : 1525 /* insert definition for possible pad */ 1526 padalign(&address,idr_align,&pad_size,MDT_DECODE); 1527 if (pad_size > 0) { 1528 *def++ = MDT_PAD; 1529 *def++ = pad_size; 1530 } 1531 *def++ = *msg_typedef; 1532 break; 1533 case MDT_ARRAY_OF : 1534 /* insert definition for possible pad */ 1535 if (mdt_structure && !pad_done) { 1536 array_def = msg_typedef; 1537 pret = idrmsg_array_info(&array_def,&array_size,&array_align); 1538 if (pret != PDS_OK) 1539 return(pret); 1540 if (array_align > 1) { 1541 padalign(&address,array_align,&pad_size,MDT_DECODE); 1542 if (pad_size > 0) { 1543 *def++ = MDT_PAD; 1544 *def++ = pad_size; 1545 } 1546 } 1547 pad_done = 1; 1548 } 1549 1550 *def++ = *msg_typedef; 1551 /* append array count */ 1552 *def++ = *++msg_typedef; 1553 multiplier *= *msg_typedef; 1554 break; 1555 default : 1556 pret = get_mdt(*msg_typedef,&mdt); 1557 mdt_assert(pret == PDS_OK); 1558 1559 /* inherit alignment restrictions */ 1560 if (mdt->idr_align > idr_align) 1561 idr_align = mdt->idr_align; 1562 1563 /* insert definition for possible pad */ 1564 if (!pad_done && mdt_structure && (mdt->idr_align > 1)) { 1565 padalign(&address,mdt->idr_align,&pad_size,MDT_DECODE); 1566 if (pad_size > 0) { 1567 *def++ = MDT_PAD; 1568 *def++ = pad_size; 1569 } 1570 } 1571 1572 /* append subtype definition */ 1573 (void) memcpy((char *) def, 1574 (char *) mdt->def, 1575 mdt->def_size * sizeof(msg_typedef_t)); 1576 def = (msg_typedef_t *) def + mdt->def_size; 1577 address += multiplier * mdt->idr_size; 1578 1579 multiplier = 1; 1580 pad_done = 0; 1581 1582 break; 1583 } 1584 msg_typedef++; 1585 } 1586 1587 idr_size = address - (char *) 0; 1588 1589 mdt_assert((def-definition) <= def_size); 1590 1591 def_size = def-definition; 1592 1593 /* allocate memory for message type definition */ 1594 def = (msg_typedef_t *) 1595 pds_mem_alloc(&mdt_phd,def_size * sizeof(msg_typedef_t)); 1596 if (!def) 1597 return(PDS_NOMEMORY); 1598 1599 /* copy message type definition */ 1600 (void) memcpy((char *) def, 1601 (char *) definition, 1602 def_size * sizeof(msg_typedef_t)); 1603 1604 /* free memory for temporary message type definition */ 1605 pds_mem_free(&mdt_phd, (void_ptr) definition); 1606 1607 definition = def; 1608 1609#if !defined(NDEBUG) 1610 { 1611 unsigned mdt_align; 1612 unsigned mdt_size; 1613 1614 def = definition; 1615 pret = idrmsg_opaque_info(&def,&mdt_size,&mdt_align); 1616 1617 mdt_assert(pret == PDS_OK); 1618 mdt_assert(mdt_align == idr_align); 1619 mdt_assert(mdt_size == idr_size); 1620 } 1621#endif 1622 1623 /* derive xdr_size */ 1624 def = definition; 1625 if ((pret = xdrmsg_opaque_info(&def,&xdr_size)) != PDS_OK) { 1626 pds_mem_free(&mdt_phd, (void_ptr) definition); 1627 return(pret); 1628 } 1629 1630 MsgDD_Lock(); 1631 *msg_type = 0x10000 * msg_intfc_no + msg_type_no; 1632 pret = get_free_index(*msg_type,&intfc_index,&type_index); 1633 1634 if (pret != PDS_OK) { 1635 pds_mem_free(&mdt_phd, (void_ptr) definition); 1636 MsgDD_Unlock(); 1637 return(PDS_IMPLIM); 1638 } 1639 else { 1640 mdt = &msg_intfcs[intfc_index].msg_types[type_index]; 1641 mdt->type_no = msg_type_no; 1642 mdt->xdr_size = xdr_size; 1643 mdt->idr_size = idr_size; 1644 mdt->idr_align = idr_align; 1645 mdt->def_size = def_size; 1646 mdt->def = definition; 1647 MsgDD_Unlock(); 1648 return(PDS_OK); 1649 } 1650} 1651 1652