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