1/*
2 * Copyright (c) 2010 Apple Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1.  Redistributions of source code must retain the above copyright
11 *     notice, this list of conditions and the following disclaimer.
12 * 2.  Redistributions in binary form must reproduce the above copyright
13 *     notice, this list of conditions and the following disclaimer in the
14 *     documentation and/or other materials provided with the distribution.
15 * 3.  Neither the name of Apple Inc. ("Apple") nor the names of its
16 *     contributors may be used to endorse or promote products derived from
17 *     this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 *
30 * Portions of this software have been released under the following terms:
31 *
32 * (c) Copyright 1989-1993 OPEN SOFTWARE FOUNDATION, INC.
33 * (c) Copyright 1989-1993 HEWLETT-PACKARD COMPANY
34 * (c) Copyright 1989-1993 DIGITAL EQUIPMENT CORPORATION
35 *
36 * To anyone who acknowledges that this file is provided "AS IS"
37 * without any express or implied warranty:
38 * permission to use, copy, modify, and distribute this file for any
39 * purpose is hereby granted without fee, provided that the above
40 * copyright notices and this notice appears in all source code copies,
41 * and that none of the names of Open Software Foundation, Inc., Hewlett-
42 * Packard Company or Digital Equipment Corporation be used
43 * in advertising or publicity pertaining to distribution of the software
44 * without specific, written prior permission.  Neither Open Software
45 * Foundation, Inc., Hewlett-Packard Company nor Digital
46 * Equipment Corporation makes any representations about the suitability
47 * of this software for any purpose.
48 *
49 * Copyright (c) 2007, Novell, Inc. All rights reserved.
50 * Redistribution and use in source and binary forms, with or without
51 * modification, are permitted provided that the following conditions
52 * are met:
53 *
54 * 1.  Redistributions of source code must retain the above copyright
55 *     notice, this list of conditions and the following disclaimer.
56 * 2.  Redistributions in binary form must reproduce the above copyright
57 *     notice, this list of conditions and the following disclaimer in the
58 *     documentation and/or other materials provided with the distribution.
59 * 3.  Neither the name of Novell Inc. nor the names of its contributors
60 *     may be used to endorse or promote products derived from this
61 *     this software without specific prior written permission.
62 *
63 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
64 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
65 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
66 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY
67 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
68 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
69 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
70 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
71 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
72 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
73 *
74 * @APPLE_LICENSE_HEADER_END@
75 */
76
77/*
78**
79**      ndrmi.c
80**
81**  FACILITY:
82**
83**      Interface Definition Language (IDL) Compiler
84**
85**  ABSTRACT:
86**
87**      NDR marshalling interpreter main module
88**
89*/
90#if HAVE_CONFIG_H
91#include <config.h>
92#endif
93
94#include <stdio.h>
95#include <dce/idlddefs.h>
96#include <ndrmi.h>
97#include <lsysdep.h>
98#include <assert.h>
99
100/*
101 *  Forward function references
102 */
103
104/* None */
105
106/******************************************************************************/
107/*                                                                            */
108/*  Attach the current buffer to the iovector                                 */
109/*                                                                            */
110/******************************************************************************/
111void rpc_ss_attach_buff_to_iovec
112(
113    IDL_msp_t IDL_msp
114)
115{
116    rpc_iovector_elt_t *p_elt;
117
118    if (IDL_msp->IDL_pickling_handle != NULL)
119    {
120        idl_es_encode_attach_buff(IDL_msp);
121        return;
122    }
123
124    p_elt = &(IDL_msp->IDL_iovec.elt[IDL_msp->IDL_elts_in_use]);
125    if (IDL_msp->IDL_stack_packet_status == IDL_stack_packet_in_use_k)
126    {
127        IDL_msp->IDL_stack_packet_status = IDL_stack_packet_used_k;
128        p_elt->buff_dealloc = NULL_FREE_RTN;
129        p_elt->flags = rpc_c_iovector_elt_reused;
130    }
131    else if (IDL_msp->IDL_stack_packet_status == IDL_stack_packet_part_used_k)
132    {
133        p_elt->buff_dealloc = NULL_FREE_RTN;
134        p_elt->flags = rpc_c_iovector_elt_reused;
135    }
136    else
137    {
138        p_elt->buff_dealloc = (rpc_buff_dealloc_fn_t)free;
139        p_elt->flags = 0;
140    }
141    p_elt->buff_addr = (byte_p_t)IDL_msp->IDL_buff_addr;
142    p_elt->buff_len = IDL_BUFF_SIZE;
143    p_elt->data_addr = (byte_p_t)IDL_msp->IDL_data_addr;
144    p_elt->data_len = IDL_msp->IDL_mp - IDL_msp->IDL_data_addr;
145    (IDL_msp->IDL_elts_in_use)++;
146    IDL_msp->IDL_buff_addr = NULL;
147}
148
149/******************************************************************************/
150/*                                                                            */
151/*  If all the iovector slots are full or we are marshalling pipe data        */
152/*  or [transmit_as] data by pointing, despatch the iovector and reset the    */
153/*  slot count to zero                                                        */
154/*                                                                            */
155/******************************************************************************/
156void rpc_ss_xmit_iovec_if_necess
157(
158    /* [in] */ idl_boolean attached_pointed_at,  /* TRUE => last element added
159                                     to iovector was a pointer to user data */
160    IDL_msp_t IDL_msp
161)
162{
163    if (IDL_msp->IDL_pickling_handle != NULL)
164    {
165        return;     /* Data already captured by rpc_ss_attach_buff_to_iovec */
166    }
167
168    if ( (IDL_msp->IDL_elts_in_use == IDL_IOVECTOR_SIZE)
169        || (attached_pointed_at
170              && (IDL_msp->IDL_marsh_pipe || IDL_msp->IDL_m_xmit_level > 0)) )
171    {
172        /* Despatch the iovector */
173        IDL_msp->IDL_iovec.num_elt = IDL_msp->IDL_elts_in_use;
174        rpc_call_transmit( (rpc_call_handle_t)IDL_msp->IDL_call_h,
175                           (rpc_iovector_p_t)&IDL_msp->IDL_iovec,
176                           (unsigned32 *)&IDL_msp->IDL_status );
177        if (IDL_msp->IDL_status != error_status_ok)
178            DCETHREAD_RAISE(rpc_x_ss_pipe_comm_error);
179        /* And re-initialize the iovector */
180        IDL_msp->IDL_elts_in_use = 0;
181        /* If there is a stack packet, mark it as reusable */
182        if (IDL_msp->IDL_stack_packet_addr != NULL)
183            IDL_msp->IDL_stack_packet_status = IDL_stack_packet_unused_k;
184    }
185}
186
187/******************************************************************************/
188/*                                                                            */
189/*  Open a new buffer                                                         */
190/*  The usable length of the buffer is set up so that the last address        */
191/*  in the data area is (7 mod 8)                                             */
192/*                                                                            */
193/******************************************************************************/
194void rpc_ss_ndr_marsh_init_buffer
195(
196    IDL_msp_t IDL_msp
197)
198{
199    idl_byte *beyond_usable_buffer; /* (0 mod 8) address of byte beyond usable
200                                        buffer area */
201
202    if (IDL_msp->IDL_stack_packet_status == IDL_stack_packet_unused_k)
203    {
204        IDL_msp->IDL_buff_addr = IDL_msp->IDL_stack_packet_addr;
205        IDL_msp->IDL_stack_packet_status = IDL_stack_packet_in_use_k;
206        beyond_usable_buffer = (idl_byte *)
207            (((IDL_msp->IDL_buff_addr + IDL_STACK_PACKET_SIZE)
208                                                     - (idl_byte *)0) & (~7));
209    }
210    else if (IDL_msp->IDL_stack_packet_status == IDL_stack_packet_part_used_k)
211    {
212        /* IDL_mp was pointing at the first free location in the stack packet
213            and has not been changed by the "marshall by pointing" */
214        IDL_msp->IDL_buff_addr = IDL_msp->IDL_mp;
215        IDL_msp->IDL_stack_packet_status = IDL_stack_packet_in_use_k;
216        beyond_usable_buffer = (idl_byte *)
217            (((IDL_msp->IDL_stack_packet_addr + IDL_STACK_PACKET_SIZE)
218                                                     - (idl_byte *)0) & (~7));
219    }
220    else
221    {
222        if (IDL_msp->IDL_pickling_handle != NULL)
223        {
224            /* This is the only case where we may be doing an encoding */
225            idl_ulong_int buff_size;
226
227            idl_es_encode_init_buffer(&buff_size, IDL_msp);
228            beyond_usable_buffer = (idl_byte *)
229                                     (((IDL_msp->IDL_buff_addr + buff_size)
230                                                     - (idl_byte *)0) & (~7));
231        }
232        else
233        {
234#ifdef DEBUG
235            /* Zero marshalling buffers. */
236            IDL_msp->IDL_buff_addr = (idl_byte *)calloc(1, IDL_BUFF_SIZE);
237#else
238            IDL_msp->IDL_buff_addr = (idl_byte *)malloc(IDL_BUFF_SIZE);
239#endif /* DEBUG */
240            if (IDL_msp->IDL_buff_addr == NULL)
241                DCETHREAD_RAISE(rpc_x_no_memory);
242            beyond_usable_buffer = (idl_byte *)
243                                     (((IDL_msp->IDL_buff_addr + IDL_BUFF_SIZE)
244                                                     - (idl_byte *)0) & (~7));
245        }
246    }
247    IDL_msp->IDL_data_addr = (idl_byte *)
248                ((((IDL_msp->IDL_buff_addr - (idl_byte *)0) + 7) & (~7))
249                                             + IDL_msp->IDL_mp_start_offset);
250    IDL_msp->IDL_mp = IDL_msp->IDL_data_addr;
251    IDL_msp->IDL_left_in_buff = beyond_usable_buffer - IDL_msp->IDL_data_addr;
252}
253
254/******************************************************************************/
255/*                                                                            */
256/*  Marshall an array by making an iovector element point at it               */
257/*                                                                            */
258/******************************************************************************/
259void rpc_ss_ndr_marsh_by_pointing
260(
261    /* [in] */  idl_ulong_int element_count,
262    /* [in] */  idl_ulong_int element_size,
263    /* [in] */  rpc_void_p_t array_addr,
264    IDL_msp_t IDL_msp
265)
266{
267    rpc_iovector_elt_t *p_elt;
268    idl_ulong_int array_size_in_bytes;
269
270    /* Close the current buffer if one is open */
271    if (IDL_msp->IDL_buff_addr != NULL)
272    {
273        if ((IDL_msp->IDL_stack_packet_status == IDL_stack_packet_in_use_k)
274            && (IDL_msp->IDL_left_in_buff >= 8))
275        {
276            /* Can use the rest of the stack packet later */
277            IDL_msp->IDL_stack_packet_status = IDL_stack_packet_part_used_k;
278        }
279        rpc_ss_attach_buff_to_iovec( IDL_msp );
280        rpc_ss_xmit_iovec_if_necess( idl_false, IDL_msp );
281        IDL_msp->IDL_left_in_buff = 0;
282        IDL_msp->IDL_mp_start_offset = (IDL_msp->IDL_mp - (idl_byte *)0) % 8;
283    }
284
285    p_elt = &(IDL_msp->IDL_iovec.elt[IDL_msp->IDL_elts_in_use]);
286    array_size_in_bytes = element_count * element_size;
287    p_elt->buff_dealloc = NULL_FREE_RTN;
288    if ( (IDL_msp->IDL_side == IDL_server_side_k)
289         || IDL_msp->IDL_marsh_pipe
290         || (IDL_msp->IDL_m_xmit_level > 0) )
291    {
292        /* Run time must copy the data before server stub stack is unwound
293            or pipe or [transmit_as] buffer is reused */
294        p_elt->flags = rpc_c_iovector_elt_reused;
295    }
296    else
297        p_elt->flags = 0;
298    p_elt->buff_addr = (byte_p_t)array_addr;
299    p_elt->buff_len = array_size_in_bytes;
300    p_elt->data_addr = (byte_p_t)array_addr;
301    p_elt->data_len = array_size_in_bytes;
302    (IDL_msp->IDL_elts_in_use)++;
303    rpc_ss_xmit_iovec_if_necess( idl_true, IDL_msp );
304    IDL_msp->IDL_mp_start_offset =
305                     (IDL_msp->IDL_mp_start_offset + array_size_in_bytes) % 8;
306}
307
308/******************************************************************************/
309/*                                                                            */
310/*  If we have an array whose base type is such that it could be marshalled   */
311/*  by pointing, but its size is below the threshold level for having its own */
312/*  iovector_elt, marshall it by block copying into one or more buffers       */
313/*                                                                            */
314/******************************************************************************/
315void rpc_ss_ndr_marsh_by_copying
316(
317    /* [in] */  idl_ulong_int element_count,
318    /* [in] */  idl_ulong_int element_size,
319    /* [in] */  rpc_void_p_t array_addr,
320    IDL_msp_t IDL_msp
321)
322{
323    idl_ulong_int bytes_required;   /* Number of bytes left to copy */
324    idl_ulong_int bytes_to_copy;  /* Number of bytes to copy into this buffer */
325
326    bytes_required = element_count * element_size;
327    while (bytes_required != 0)
328    {
329        rpc_ss_ndr_marsh_check_buffer( 1, IDL_msp);
330        if (bytes_required > IDL_msp->IDL_left_in_buff)
331            bytes_to_copy = IDL_msp->IDL_left_in_buff;
332        else
333            bytes_to_copy = bytes_required;
334        memcpy(IDL_msp->IDL_mp, array_addr, bytes_to_copy);
335        IDL_msp->IDL_mp += bytes_to_copy;
336        IDL_msp->IDL_left_in_buff -= bytes_to_copy;
337        bytes_required -= bytes_to_copy;
338        array_addr = (rpc_void_p_t)((idl_byte *)array_addr + bytes_to_copy);
339    }
340}
341
342/******************************************************************************/
343/*                                                                            */
344/*  Marshall a structure                                                      */
345/*                                                                            */
346/******************************************************************************/
347void rpc_ss_ndr_marsh_struct
348(
349    /* [in] */  idl_byte struct_type,   /* DT_FIXED_STRUCT, DT_CONF_STRUCT
350                                            or DT_V1_CONF_STRUCT */
351    /* [in] */  idl_ulong_int defn_index,
352    /* [in] */  rpc_void_p_t struct_addr,
353    IDL_msp_t IDL_msp
354)
355{
356    idl_ulong_int offset_index;
357    idl_byte *defn_vec_ptr;
358    idl_ulong_int *struct_offset_vec_ptr; /* Start of offsets for this struct */
359    idl_ulong_int *offset_vec_ptr;
360    idl_byte type_byte;
361    idl_ulong_int offset;
362    idl_ulong_int field_defn_index;
363    idl_byte *field_defn_ptr;
364    idl_ulong_int conf_dims = 0;    /* Number of dimensions of conformance info */
365    IDL_bound_pair_t *conf_bounds = NULL;   /* Bounds list from conformance info */
366    IDL_bound_pair_t normal_conf_bounds[IDL_NORMAL_DIMS];
367    IDL_bound_pair_t range_bounds; /* Bounds list from range info */
368    idl_ulong_int *Z_values = NULL;
369    idl_ulong_int normal_Z_values[IDL_NORMAL_DIMS];
370    IDL_bound_pair_t *range_list;
371    IDL_bound_pair_t normal_range_list[IDL_NORMAL_DIMS];
372    idl_boolean v1_array = idl_false;
373    idl_ulong_int node_number;
374    long already_marshalled;
375    idl_ulong_int switch_index; /* Index of switch field for non-encapsulated
376                                                                        union */
377    idl_ushort_int v1_size;     /* Number of elements in open [v1_array] */
378    idl_boolean add_null;
379    idl_ulong_int shadow_length = 0;    /* Number of elements in a cs_shadow */
380    IDL_cs_shadow_elt_t *cs_shadow = NULL;
381    unsigned32 i;
382
383    defn_vec_ptr = IDL_msp->IDL_type_vec + defn_index;
384    IDL_GET_LONG_FROM_VECTOR(offset_index,defn_vec_ptr);
385    struct_offset_vec_ptr = IDL_msp->IDL_offset_vec + offset_index;
386    offset_vec_ptr = struct_offset_vec_ptr + 1;
387                                        /* Skip over size at start of offsets */
388
389    IDL_INIT_RANGE(range_bounds);
390
391    if ( (struct_type == IDL_DT_CONF_STRUCT)
392        || (struct_type == IDL_DT_V1_CONF_STRUCT) )
393    {
394        /* Next integer in the definition vector is index to a fully flattened
395            array rep for the conformant array field */
396        IDL_GET_LONG_FROM_VECTOR(field_defn_index,defn_vec_ptr);
397        field_defn_ptr = IDL_msp->IDL_type_vec + field_defn_index;
398        conf_dims = (idl_ulong_int)*field_defn_ptr;
399        if (conf_dims > IDL_NORMAL_DIMS)
400        {
401            conf_bounds = NULL;
402            Z_values = NULL;
403        }
404        else
405        {
406            conf_bounds = normal_conf_bounds;
407            Z_values = normal_Z_values;
408        }
409        field_defn_ptr++;
410        if (*defn_vec_ptr == IDL_DT_CS_SHADOW)
411        {
412            /* Need to set up I-char machinery */
413            defn_vec_ptr++;
414            IDL_GET_LONG_FROM_VECTOR(shadow_length, defn_vec_ptr);
415            rpc_ss_ndr_m_struct_cs_shadow(struct_addr, struct_type,
416                                          shadow_length, offset_index,
417                                          defn_vec_ptr, &cs_shadow, IDL_msp);
418            if (*(field_defn_ptr
419                 + conf_dims * IDL_CONF_BOUND_PAIR_WIDTH) == IDL_DT_CS_TYPE)
420            {
421                rpc_ss_conf_struct_cs_bounds(field_defn_ptr, cs_shadow,
422                                         conf_bounds, IDL_msp);
423            }
424            else
425                rpc_ss_build_bounds_list( &field_defn_ptr, NULL, struct_addr,
426                    struct_offset_vec_ptr, conf_dims, &conf_bounds, IDL_msp );
427        }
428        else
429            rpc_ss_build_bounds_list( &field_defn_ptr, NULL, struct_addr,
430                    struct_offset_vec_ptr, conf_dims, &conf_bounds, IDL_msp );
431        rpc_ss_Z_values_from_bounds(conf_bounds, conf_dims, &Z_values,IDL_msp);
432        if (struct_type == IDL_DT_V1_CONF_STRUCT)
433        {
434            v1_size = 1;
435            for (i=0; i<conf_dims; i++)
436                v1_size *= Z_values[i];
437            IDL_MARSH_CUSHORT( &v1_size );
438        }
439        else
440            rpc_ss_ndr_marsh_Z_values( conf_dims, Z_values, IDL_msp );
441    }
442
443    do {
444        type_byte = *defn_vec_ptr;
445        defn_vec_ptr++;
446        switch(type_byte)
447        {
448            case IDL_DT_CS_SHADOW:
449                /* I-char machinery  - struct has varying array(s) of [cs_char]
450                    but no conformant array of [cs_char] */
451                IDL_GET_LONG_FROM_VECTOR(shadow_length, defn_vec_ptr);
452                rpc_ss_ndr_m_struct_cs_shadow(struct_addr, struct_type,
453                                          shadow_length, offset_index,
454                                          defn_vec_ptr, &cs_shadow, IDL_msp);
455                break;
456            case IDL_DT_BYTE:
457                offset = *offset_vec_ptr;
458                offset_vec_ptr++;
459                IDL_CHECK_RANGE_BYTE( range_bounds, (idl_byte *)struct_addr + offset );
460                IDL_MARSH_BYTE( (idl_byte *)struct_addr + offset );
461                break;
462            case IDL_DT_CHAR:
463                offset = *offset_vec_ptr;
464                offset_vec_ptr++;
465                IDL_CHECK_RANGE_CHAR( range_bounds, (idl_byte *)struct_addr + offset );
466                IDL_MARSH_CHAR( (idl_byte *)struct_addr + offset );
467                break;
468            case IDL_DT_BOOLEAN:
469                offset = *offset_vec_ptr;
470                offset_vec_ptr++;
471                IDL_CHECK_RANGE_BOOLEAN( range_bounds, (idl_byte *)struct_addr + offset );
472                IDL_MARSH_BOOLEAN( (idl_byte *)struct_addr + offset );
473                break;
474            case IDL_DT_DOUBLE:
475                offset = *offset_vec_ptr;
476                offset_vec_ptr++;
477                IDL_CHECK_RANGE_DOUBLE( range_bounds, (idl_byte *)struct_addr + offset );
478                IDL_MARSH_DOUBLE( (idl_byte *)struct_addr + offset );
479                break;
480            case IDL_DT_ENUM:
481                offset = *offset_vec_ptr;
482                offset_vec_ptr++;
483                IDL_MARSH_ENUM( (idl_byte *)struct_addr + offset );
484                break;
485            case IDL_DT_FLOAT:
486                offset = *offset_vec_ptr;
487                offset_vec_ptr++;
488                IDL_CHECK_RANGE_FLOAT( range_bounds, (idl_byte *)struct_addr + offset );
489                IDL_MARSH_FLOAT( (idl_byte *)struct_addr + offset );
490                break;
491            case IDL_DT_SMALL:
492                offset = *offset_vec_ptr;
493                offset_vec_ptr++;
494                IDL_CHECK_RANGE_SMALL( range_bounds, (idl_byte *)struct_addr + offset );
495                IDL_MARSH_SMALL( (idl_byte *)struct_addr + offset );
496                break;
497            case IDL_DT_SHORT:
498                offset = *offset_vec_ptr;
499                offset_vec_ptr++;
500                IDL_CHECK_RANGE_SHORT( range_bounds, (idl_byte *)struct_addr + offset );
501                IDL_MARSH_SHORT( (idl_byte *)struct_addr + offset );
502                break;
503            case IDL_DT_LONG:
504                offset = *offset_vec_ptr;
505                offset_vec_ptr++;
506                IDL_CHECK_RANGE_LONG( range_bounds, (idl_byte *)struct_addr + offset );
507                IDL_MARSH_LONG( (idl_byte *)struct_addr + offset );
508                break;
509            case IDL_DT_HYPER:
510                offset = *offset_vec_ptr;
511                offset_vec_ptr++;
512                IDL_MARSH_HYPER( (idl_byte *)struct_addr + offset );
513                break;
514            case IDL_DT_USMALL:
515                offset = *offset_vec_ptr;
516                offset_vec_ptr++;
517                IDL_CHECK_RANGE_USMALL( range_bounds, (idl_byte *)struct_addr + offset );
518                IDL_MARSH_USMALL( (idl_byte *)struct_addr + offset );
519                break;
520            case IDL_DT_USHORT:
521                offset = *offset_vec_ptr;
522                offset_vec_ptr++;
523                IDL_CHECK_RANGE_USHORT( range_bounds, (idl_byte *)struct_addr + offset );
524                IDL_MARSH_USHORT( (idl_byte *)struct_addr + offset );
525                break;
526            case IDL_DT_ULONG:
527                offset = *offset_vec_ptr;
528                offset_vec_ptr++;
529                IDL_CHECK_RANGE_ULONG( range_bounds, (idl_byte *)struct_addr + offset );
530                IDL_MARSH_ULONG( (idl_byte *)struct_addr + offset );
531                break;
532            case IDL_DT_UHYPER:
533                offset = *offset_vec_ptr;
534                offset_vec_ptr++;
535                IDL_MARSH_UHYPER( (idl_byte *)struct_addr + offset );
536                break;
537            case IDL_DT_ERROR_STATUS:
538                offset = *offset_vec_ptr;
539                offset_vec_ptr++;
540                IDL_MARSH_ERROR_STATUS( (idl_byte *)struct_addr + offset );
541                break;
542            case IDL_DT_V1_ENUM:
543                offset = *offset_vec_ptr;
544                offset_vec_ptr++;
545                IDL_MARSH_V1_ENUM( (idl_byte *)struct_addr + offset );
546                break;
547            case IDL_DT_FIXED_ARRAY:
548                defn_vec_ptr++;     /* Skip over properties byte */
549                IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr);
550                                                    /* Full array definition */
551                IDL_GET_LONG_FROM_VECTOR(field_defn_index, defn_vec_ptr);
552                offset = *offset_vec_ptr;
553                offset_vec_ptr++;
554                rpc_ss_ndr_marsh_fixed_arr( field_defn_index,
555                            (idl_byte *)struct_addr+offset, 0, IDL_msp);
556                break;
557            case IDL_DT_VARYING_ARRAY:
558                defn_vec_ptr++;     /* Skip over properties byte */
559                IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr);
560                                                    /* Full array definition */
561                IDL_GET_LONG_FROM_VECTOR(field_defn_index, defn_vec_ptr);
562                offset = *offset_vec_ptr;
563                offset_vec_ptr++;
564                rpc_ss_ndr_marsh_varying_arr(field_defn_index,
565                        (rpc_void_p_t)((idl_byte *)struct_addr+offset),
566                        struct_addr, struct_offset_vec_ptr,
567                        (v1_array ? IDL_M_V1_ARRAY : 0),
568                        IDL_msp);
569                v1_array = idl_false;
570                break;
571            case IDL_DT_CONF_ARRAY:
572                defn_vec_ptr++;     /* Skip over properties byte */
573                IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr);
574                                                    /* Full array definition */
575                IDL_GET_LONG_FROM_VECTOR(field_defn_index, defn_vec_ptr);
576                offset = *offset_vec_ptr;   /* Must be last field of struct */
577                field_defn_ptr = IDL_msp->IDL_type_vec + field_defn_index
578                                   + 1; /* We already know the dimensionality */
579                IDL_ADV_DEFN_PTR_OVER_BOUNDS( field_defn_ptr, conf_dims );
580                assert (conf_bounds != NULL);
581                rpc_ss_ndr_m_fix_or_conf_arr(
582                        (rpc_void_p_t)((idl_byte *)struct_addr+offset),
583                        conf_dims, conf_bounds, field_defn_ptr,
584                        IDL_M_CONF_ARRAY, IDL_msp);
585                if (conf_dims > IDL_NORMAL_DIMS)
586                {
587                    rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle,
588                                         (byte_p_t)Z_values);
589                    rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle,
590                                         (byte_p_t)conf_bounds);
591                }
592                break;
593            case IDL_DT_OPEN_ARRAY:
594                defn_vec_ptr++;     /* Skip over properties byte */
595                IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr);
596                                                    /* Full array definition */
597                IDL_GET_LONG_FROM_VECTOR(field_defn_index, defn_vec_ptr);
598                offset = *offset_vec_ptr;   /* Must be last field of struct */
599                field_defn_ptr = IDL_msp->IDL_type_vec + field_defn_index
600                                   + 1; /* We already know the dimensionality */
601                IDL_ADV_DEFN_PTR_OVER_BOUNDS( field_defn_ptr, conf_dims );
602                if (conf_dims > IDL_NORMAL_DIMS)
603                    range_list = NULL;
604                else
605                    range_list = normal_range_list;
606                assert (conf_bounds != NULL);
607                rpc_ss_build_range_list( &field_defn_ptr,
608                            (rpc_void_p_t)((idl_byte *)struct_addr+offset),
609                             struct_addr, struct_offset_vec_ptr, conf_dims,
610                             conf_bounds, &range_list, &add_null, IDL_msp );
611                assert (Z_values != NULL);
612                rpc_ss_ndr_m_var_or_open_arr(
613                        (rpc_void_p_t)((idl_byte *)struct_addr+offset),
614                        Z_values, conf_dims, range_list, field_defn_ptr,
615                        ((v1_array ? IDL_M_V1_ARRAY : 0) | IDL_M_CONF_ARRAY
616                            | (add_null ? IDL_M_ADD_NULL : 0)),
617                        IDL_msp);
618                if (conf_dims > IDL_NORMAL_DIMS)
619                {
620                    rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle,
621                                            (byte_p_t)range_list);
622                    rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle,
623                                            (byte_p_t)Z_values);
624                    rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle,
625                                            (byte_p_t)conf_bounds);
626                }
627                v1_array = false;
628                break;
629            case IDL_DT_ENC_UNION:
630                defn_vec_ptr++;     /* Skip over properties byte */
631                IDL_GET_LONG_FROM_VECTOR(field_defn_index, defn_vec_ptr);
632                offset = *offset_vec_ptr;
633                offset_vec_ptr++;
634                rpc_ss_ndr_m_enc_union_or_ptees( (idl_byte *)struct_addr+offset,
635                                          field_defn_index, idl_false, IDL_msp);
636                break;
637            case IDL_DT_N_E_UNION:
638                defn_vec_ptr++;     /* Skip over properties byte */
639                IDL_GET_LONG_FROM_VECTOR(switch_index, defn_vec_ptr);
640                IDL_GET_LONG_FROM_VECTOR(field_defn_index, defn_vec_ptr);
641                offset = *offset_vec_ptr;
642                offset_vec_ptr++;
643                rpc_ss_ndr_m_n_e_union_or_ptees( (idl_byte *)struct_addr+offset,
644                                             switch_index, field_defn_index,
645                                             struct_addr, struct_offset_vec_ptr,
646                                             idl_false, IDL_msp);
647                break;
648            case IDL_DT_FULL_PTR:
649                defn_vec_ptr++;     /* Properties byte */
650                IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr);
651                                                /* Pointee definition */
652                offset = *offset_vec_ptr;
653                offset_vec_ptr++;
654                node_number = rpc_ss_register_node( IDL_msp->IDL_node_table,
655                        *(byte_p_t *)((idl_byte *)struct_addr+offset),
656                        ndr_false, &already_marshalled );
657                IDL_MARSH_ULONG( &node_number );
658                break;
659            case IDL_DT_UNIQUE_PTR:
660                defn_vec_ptr++;     /* Properties byte */
661                IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr);
662                                                /* Pointee definition */
663                offset = *offset_vec_ptr;
664                offset_vec_ptr++;
665                /* Get a value of 0 if pointer is null, 1 otherwise */
666                node_number =
667                        (*(byte_p_t *)((idl_byte *)struct_addr+offset) != NULL);
668                IDL_MARSH_ULONG( &node_number );
669                break;
670            case IDL_DT_REF_PTR:
671                defn_vec_ptr++;     /* Properties byte */
672                IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr);
673                                                /* Pointee definition */
674                offset_vec_ptr++;
675                /* Aligned 4-byte place holder */
676                IDL_MARSH_ALIGN_MP( IDL_msp, 4 );
677                rpc_ss_ndr_marsh_check_buffer( 4, IDL_msp );
678                IDL_msp->IDL_mp += 4;
679                IDL_msp->IDL_left_in_buff -= 4;
680                break;
681            case IDL_DT_IGNORE:
682                offset_vec_ptr++;
683                /* Aligned 4-byte place holder */
684                IDL_MARSH_ALIGN_MP( IDL_msp, 4 );
685                rpc_ss_ndr_marsh_check_buffer( 4, IDL_msp );
686                IDL_msp->IDL_mp += 4;
687                IDL_msp->IDL_left_in_buff -= 4;
688                break;
689            case IDL_DT_STRING:
690                /* Varying/open array code will do the right thing */
691                break;
692            case IDL_DT_TRANSMIT_AS:
693            case IDL_DT_REPRESENT_AS:
694                defn_vec_ptr++;     /* Skip over properties byte */
695                IDL_GET_LONG_FROM_VECTOR(field_defn_index, defn_vec_ptr);
696                offset = *offset_vec_ptr;
697                offset_vec_ptr++;
698                rpc_ss_ndr_marsh_xmit_as(field_defn_index,
699                                       (idl_byte *)struct_addr+offset, IDL_msp);
700                break;
701#if 0
702				case IDL_DT_INTERFACE:
703					 defn_vec_ptr++;	/* properties byte */
704					 IDL_GET_LONG_FROM_VECTOR(field_defn_index, defn_vec_ptr);
705					 offset = *offset_vec_ptr;
706					 offset_vec_ptr++;
707					 rpc_ss_ndr_marsh_interface(field_defn_index, (idl_byte*)struct_addr+offset, IDL_msp);
708					 break;
709#endif
710            case IDL_DT_V1_ARRAY:
711                v1_array = idl_true;
712                break;
713            case IDL_DT_V1_STRING:
714                defn_vec_ptr += 2;  /* DT_VARYING_ARRAY and properties */
715                IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr);
716                                                        /* Full array defn */
717                IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr);
718                                                      /* Flattened array defn */
719                offset = *offset_vec_ptr;
720                offset_vec_ptr++;
721                rpc_ss_ndr_marsh_v1_string((idl_byte *)struct_addr+offset,
722                                                       0, IDL_msp);
723                break;
724            case IDL_DT_CS_TYPE:
725                defn_vec_ptr++;     /* Skip over properties byte */
726                IDL_GET_LONG_FROM_VECTOR(field_defn_index, defn_vec_ptr);
727                offset = *offset_vec_ptr;
728                offset_vec_ptr++;
729                rpc_ss_ndr_marsh_cs_char((idl_byte *)struct_addr+offset,
730                                         field_defn_index, IDL_msp);
731                break;
732            case IDL_DT_CS_ATTRIBUTE:
733                /* Is followed by an array attribute, which is an integer */
734                rpc_ss_ndr_marsh_scalar(*defn_vec_ptr,
735                        (rpc_void_p_t)&cs_shadow[offset_vec_ptr
736                                        -(struct_offset_vec_ptr+1)].IDL_data,
737                        IDL_msp);
738                defn_vec_ptr++;     /* Attribute type */
739                offset_vec_ptr++;
740                break;
741            case IDL_DT_CS_ARRAY:
742                /* Is followed by an array description */
743                offset = *offset_vec_ptr;
744                rpc_ss_ndr_marsh_cs_array(
745                        (rpc_void_p_t)((idl_byte *)struct_addr+offset),
746                        cs_shadow,
747                        offset_vec_ptr-(struct_offset_vec_ptr+1),
748                        idl_true, &defn_vec_ptr, IDL_msp);
749                offset_vec_ptr++;
750                break;
751            case IDL_DT_CS_RLSE_SHADOW:
752                rpc_ss_ndr_m_rlse_cs_shadow(cs_shadow, shadow_length, IDL_msp);
753                break;
754            case IDL_DT_NDR_ALIGN_2:
755                IDL_MARSH_ALIGN_MP( IDL_msp, 2 );
756                break;
757            case IDL_DT_NDR_ALIGN_4:
758                IDL_MARSH_ALIGN_MP( IDL_msp, 4 );
759                break;
760            case IDL_DT_NDR_ALIGN_8:
761                IDL_MARSH_ALIGN_MP( IDL_msp, 8 );
762                break;
763            case IDL_DT_BEGIN_NESTED_STRUCT:
764            case IDL_DT_END_NESTED_STRUCT:
765            case IDL_DT_EOL:
766                break;
767            case IDL_DT_RANGE:
768                IDL_GET_RANGE_FROM_VECTOR( range_bounds, defn_vec_ptr );
769                break;
770            default:
771#ifdef DEBUG_INTERP
772                printf("rpc_ss_ndr_marsh_struct:unrecognized type %d\n",
773                        type_byte);
774                exit(0);
775#endif
776                DCETHREAD_RAISE(rpc_x_coding_error);
777        }
778    } while (type_byte != IDL_DT_EOL);
779}
780
781/******************************************************************************/
782/*                                                                            */
783/*  Marshall a contiguous set of elements one by one                          */
784/*                                                                            */
785/******************************************************************************/
786void rpc_ss_ndr_marsh_by_looping
787(
788    /* [in] */  idl_ulong_int element_count,
789    /* [in] */  idl_byte base_type,
790    /* [in] */  rpc_void_p_t array_addr,
791    /* [in] */  idl_ulong_int element_size,
792                                /* Used if array of constructed type */
793    /* [in] */  idl_ulong_int element_defn_index,
794                                /* Used if array of constructed type */
795    IDL_msp_t IDL_msp
796)
797{
798    unsigned32 i;
799    idl_ulong_int node_number;
800    long already_marshalled;
801
802    for (i=0; i<element_count; i++)
803    {
804        switch (base_type)
805        {
806            case IDL_DT_BOOLEAN:
807                IDL_MARSH_BOOLEAN( array_addr );
808                array_addr = (rpc_void_p_t)((idl_boolean *)(array_addr) + 1);
809                break;
810            case IDL_DT_BYTE:
811                IDL_MARSH_BYTE( array_addr );
812                array_addr = (rpc_void_p_t)((idl_byte *)(array_addr) + 1);
813                break;
814            case IDL_DT_CHAR:
815                IDL_MARSH_CHAR( array_addr );
816                array_addr = (rpc_void_p_t)((idl_char *)(array_addr) + 1);
817                break;
818            case IDL_DT_DOUBLE:
819                IDL_MARSH_DOUBLE( array_addr );
820                array_addr = (rpc_void_p_t)((idl_long_float *)(array_addr) + 1);
821                break;
822            case IDL_DT_ENUM:
823                IDL_MARSH_ENUM( array_addr );
824                array_addr = (rpc_void_p_t)((int *)(array_addr) + 1);
825                break;
826            case IDL_DT_V1_ENUM:
827                IDL_MARSH_V1_ENUM( array_addr );
828                array_addr = (rpc_void_p_t)((int *)(array_addr) + 1);
829                break;
830            case IDL_DT_FLOAT:
831                IDL_MARSH_FLOAT( array_addr );
832                array_addr = (rpc_void_p_t)
833                                         ((idl_short_float *)(array_addr) + 1);
834                break;
835            case IDL_DT_SMALL:
836                IDL_MARSH_SMALL( array_addr );
837                array_addr = (rpc_void_p_t)((idl_small_int *)(array_addr) + 1);
838                break;
839            case IDL_DT_SHORT:
840                IDL_MARSH_SHORT( array_addr );
841                array_addr = (rpc_void_p_t)((idl_short_int *)(array_addr) + 1);
842                break;
843            case IDL_DT_LONG:
844                IDL_MARSH_LONG( array_addr );
845                array_addr = (rpc_void_p_t)((idl_long_int *)(array_addr) + 1);
846                break;
847            case IDL_DT_HYPER:
848                IDL_MARSH_HYPER( array_addr );
849                array_addr = (rpc_void_p_t)((idl_hyper_int *)(array_addr) + 1);
850                break;
851            case IDL_DT_USMALL:
852                IDL_MARSH_USMALL( array_addr );
853                array_addr = (rpc_void_p_t)((idl_usmall_int *)(array_addr) + 1);
854                break;
855            case IDL_DT_USHORT:
856                IDL_MARSH_USHORT( array_addr );
857                array_addr = (rpc_void_p_t)((idl_ushort_int *)(array_addr) + 1);
858                break;
859            case IDL_DT_ULONG:
860                IDL_MARSH_ULONG( array_addr );
861                array_addr = (rpc_void_p_t)((idl_ulong_int *)(array_addr) + 1);
862                break;
863            case IDL_DT_ERROR_STATUS:
864                IDL_MARSH_ERROR_STATUS( array_addr );
865                array_addr = (rpc_void_p_t)((idl_ulong_int *)(array_addr) + 1);
866                break;
867            case IDL_DT_UHYPER:
868                IDL_MARSH_UHYPER( array_addr );
869                array_addr = (rpc_void_p_t)((idl_uhyper_int *)(array_addr) + 1);
870                break;
871            case IDL_DT_FIXED_STRUCT:
872                rpc_ss_ndr_marsh_struct( base_type, element_defn_index,
873                                                        array_addr, IDL_msp);
874                array_addr = (rpc_void_p_t)
875                                    ((idl_byte *)(array_addr) + element_size);
876                break;
877            case IDL_DT_FIXED_ARRAY:
878                /* Base type of pipe is array */
879                rpc_ss_ndr_marsh_fixed_arr( element_defn_index, array_addr,
880                                            0, IDL_msp );
881                array_addr = (rpc_void_p_t)
882                                    ((idl_byte *)(array_addr) + element_size);
883                break;
884            case IDL_DT_ENC_UNION:
885                rpc_ss_ndr_m_enc_union_or_ptees( array_addr, element_defn_index,
886                                                    idl_false, IDL_msp );
887                array_addr = (rpc_void_p_t)
888                                    ((idl_byte *)(array_addr) + element_size);
889                break;
890            case IDL_DT_FULL_PTR:
891                node_number = rpc_ss_register_node( IDL_msp->IDL_node_table,
892                                            *(byte_p_t *)array_addr,
893                                            ndr_false, &already_marshalled );
894                IDL_MARSH_ULONG( &node_number );
895                array_addr = (rpc_void_p_t)((rpc_void_p_t *)(array_addr) + 1);
896                break;
897            case IDL_DT_UNIQUE_PTR:
898                /* Get a value of 0 if pointer is null, 1 otherwise */
899                node_number = (*(byte_p_t *)array_addr != NULL);
900                IDL_MARSH_ULONG( &node_number );
901                array_addr = (rpc_void_p_t)((rpc_void_p_t *)(array_addr) + 1);
902                break;
903            case IDL_DT_STRING:
904#if defined(PACKED_BYTE_ARRAYS) && defined(PACKED_CHAR_ARRAYS) \
905 && defined(PACKED_SCALAR_ARRAYS)
906                if (IDL_msp->IDL_language == IDL_lang_c_k)
907                {
908                    idl_byte *element_defn_ptr;
909                    idl_ulong_int A=0, B;
910                    idl_ulong_int base_type_size;
911
912                    element_defn_ptr = IDL_msp->IDL_type_vec
913                                        + element_defn_index
914                                        + 1     /* Dimensionality */
915                                        + IDL_FIXED_BOUND_PAIR_WIDTH
916                                        + IDL_DATA_LIMIT_PAIR_WIDTH;
917                    /* Now pointing at base type of string */
918                    base_type_size = rpc_ss_type_size(element_defn_ptr,
919                                                                     IDL_msp);
920                    if (base_type_size == 1)
921                        B = (idl_ulong_int) strlen(array_addr) + 1;
922                    else
923                        B = rpc_ss_strsiz((idl_char *)array_addr,
924                                                               base_type_size);
925                    IDL_MARSH_ALIGN_MP(IDL_msp, 4);
926                    rpc_ss_ndr_marsh_check_buffer(8, IDL_msp);
927                    rpc_marshall_ulong_int(IDL_msp->IDL_mp, A);
928                    IDL_msp->IDL_mp += 4;
929                    rpc_marshall_ulong_int(IDL_msp->IDL_mp, B);
930                    IDL_msp->IDL_mp += 4;
931                    IDL_msp->IDL_left_in_buff -= 8;
932                    rpc_ss_ndr_marsh_by_copying(B, base_type_size, array_addr,
933                                                IDL_msp);
934                }
935                else
936#endif
937                {
938                    rpc_ss_ndr_marsh_varying_arr(element_defn_index, array_addr,
939                                                 NULL, NULL, 0, IDL_msp);
940                }
941                array_addr = (rpc_void_p_t)
942                                    ((idl_byte *)(array_addr) + element_size);
943                break;
944            case IDL_DT_V1_STRING:
945                rpc_ss_ndr_marsh_v1_string(array_addr, 0, IDL_msp);
946                array_addr = (rpc_void_p_t)
947                                    ((idl_byte *)(array_addr) + element_size);
948                break;
949            case IDL_DT_TRANSMIT_AS:
950            case IDL_DT_REPRESENT_AS:
951                rpc_ss_ndr_marsh_xmit_as( element_defn_index, array_addr,
952                                                                    IDL_msp );
953                array_addr = (rpc_void_p_t)
954                                    ((idl_byte *)(array_addr) + element_size);
955                break;
956#if 0
957				case IDL_DT_INTERFACE:
958					 rpc_ss_ndr_marsh_interface(element_defn_index, array_addr, IDL_msp);
959					 array_addr = (rpc_void_p_t)((idl_byte*)(array_addr) + element_size);
960					 break;
961#endif
962            default:
963#ifdef DEBUG_INTERP
964                printf(
965                      "rpc_ss_ndr_marsh_by_looping:unrecognized type %d\n",
966                        base_type);
967                exit(0);
968#endif
969                DCETHREAD_RAISE(rpc_x_coding_error);
970        }
971    }
972}
973
974/******************************************************************************/
975/*                                                                            */
976/* Marshall a fixed or conformant array                                       */
977/*                                                                            */
978/******************************************************************************/
979void rpc_ss_ndr_m_fix_or_conf_arr
980(
981    /* [in] */  rpc_void_p_t array_addr,
982    /* [in] */  idl_ulong_int dimensionality,
983    /* [in] */  IDL_bound_pair_t *bounds_list,
984    /* [in] */  idl_byte *defn_vec_ptr, /* Points at array base info */
985    /* [in] */  idl_ulong_int flags,
986    IDL_msp_t IDL_msp
987)
988{
989    idl_ulong_int element_count;
990    int i;
991    idl_ulong_int element_defn_index = 0;
992    idl_ulong_int element_offset_index;
993    idl_ulong_int element_size = 0;
994    idl_byte *element_defn_ptr;
995    idl_byte base_type;
996    idl_boolean marshall_by_pointing;
997    IDL_bound_pair_t *bound_p;	    /* Steps through bounds */
998
999    if ( (*defn_vec_ptr == IDL_DT_STRING)
1000        || (*defn_vec_ptr == IDL_DT_V1_STRING) )
1001    {
1002        /* Arrays of strings have a special representation */
1003        dimensionality--;
1004    }
1005
1006    /* Calculate the total number of elements to be transmited */
1007    element_count = 1;
1008    bound_p = bounds_list;
1009    for (i=dimensionality; i>0; i--)
1010    {
1011        element_count *= (bound_p->upper - bound_p->lower + 1);
1012	bound_p++;
1013    }
1014    if (element_count == 0)
1015        return;
1016
1017    rpc_ss_ndr_arr_align_and_opt( IDL_marshalling_k, dimensionality,
1018                                  &base_type, defn_vec_ptr,
1019                                  &marshall_by_pointing, IDL_msp );
1020
1021    if (base_type == IDL_DT_REF_PTR)
1022    {
1023        return;
1024    }
1025
1026    /* Marshall by pointing if possible and enough elements or chunk of pipe of
1027         array (only case where array base type is DT_FIXED_ARRAY) */
1028    if (marshall_by_pointing)
1029    {
1030        element_size = rpc_ss_type_size( defn_vec_ptr, IDL_msp );
1031        if (base_type != IDL_DT_FIXED_STRUCT)
1032        {
1033	    /*
1034	     * 	Marshall by pointing only if the object is at least
1035	     * 	IDL_POINT_THRESHOLD items in size, or it is the base type of a
1036	     * 	pipe (array of fixed array).  Since there is only a single pipe
1037	     * 	chunk per transmit, may as well point at it no matter its size.
1038             *  Can never marshall by pointing when pickling
1039	     */
1040            if (((element_count >= IDL_POINT_THRESHOLD)
1041                                    || (base_type == IDL_DT_FIXED_ARRAY))
1042                    && (! IDL_M_FLAGS_TEST(flags, IDL_M_DO_NOT_POINT))
1043                    && (IDL_msp->IDL_pickling_handle == NULL)
1044                )
1045                rpc_ss_ndr_marsh_by_pointing(element_count, element_size,
1046                                         array_addr, IDL_msp);
1047            else
1048                rpc_ss_ndr_marsh_by_copying(element_count, element_size,
1049                                         array_addr, IDL_msp);
1050	    return;
1051	}
1052	else  /* For NDR-aligned fixed structures */
1053	{
1054            /*
1055	     * 	The last element of the structure cannot, in general, be
1056	     * 	marshalled via the point-at optimization because of trailing
1057	     * 	pad is returned from the sizeof() function that is not included
1058	     * 	in NDR.
1059	     */
1060            element_count--;        /* So do the last one separately */
1061
1062	    /* If there are more that 1, do them by pointing */
1063	    if (element_count != 0)
1064	    {
1065		if (((element_count*element_size) >= IDL_POINT_THRESHOLD)
1066                        && (! IDL_M_FLAGS_TEST(flags, IDL_M_DO_NOT_POINT))
1067                        && (IDL_msp->IDL_pickling_handle == NULL)
1068                    )
1069		    rpc_ss_ndr_marsh_by_pointing(element_count, element_size,
1070					     array_addr, IDL_msp);
1071		else
1072		    rpc_ss_ndr_marsh_by_copying(element_count, element_size,
1073					     array_addr, IDL_msp);
1074	    }
1075
1076            /* Marshall the last element separately */
1077            defn_vec_ptr += 2;  /* See comment below */
1078            IDL_GET_LONG_FROM_VECTOR( element_defn_index, defn_vec_ptr );
1079            rpc_ss_ndr_marsh_struct(base_type, element_defn_index,
1080                                    (rpc_void_p_t)((idl_byte *)array_addr
1081                                         + element_count * element_size),
1082                                    IDL_msp);
1083        }
1084        return;
1085    }
1086
1087    if ( (base_type == IDL_DT_FIXED_STRUCT)
1088         || (base_type == IDL_DT_ENC_UNION)
1089         || (base_type == IDL_DT_TRANSMIT_AS)
1090         || (base_type == IDL_DT_REPRESENT_AS) )
1091    {
1092        defn_vec_ptr += 2;  /* Discard type and properties */
1093        /* If we are marshalling an array, not a pipe, defn_vec_ptr was
1094            4-byte aligned and DT_MODIFIED and modifier are discarded
1095            by the +=2 followed by GET_LONG */
1096        IDL_GET_LONG_FROM_VECTOR( element_defn_index, defn_vec_ptr );
1097        element_defn_ptr =  IDL_msp->IDL_type_vec + element_defn_index;
1098        IDL_GET_LONG_FROM_VECTOR(element_offset_index, element_defn_ptr);
1099        element_size = *(IDL_msp->IDL_offset_vec + element_offset_index);
1100    }
1101    else if ( (base_type == IDL_DT_STRING)
1102            || (base_type == IDL_DT_V1_STRING) )
1103    {
1104        rpc_ss_get_string_base_desc( defn_vec_ptr, &element_size,
1105                                               &element_defn_index, IDL_msp );
1106    }
1107    else if (base_type == IDL_DT_FIXED_ARRAY)
1108    {
1109        /* Base type of pipe is array */
1110        element_size = rpc_ss_type_size( defn_vec_ptr, IDL_msp );
1111        defn_vec_ptr += 2;  /* Base type and properties byte */
1112        IDL_DISCARD_LONG_FROM_VECTOR( defn_vec_ptr );   /* Full array defn */
1113        IDL_GET_LONG_FROM_VECTOR( element_defn_index, defn_vec_ptr );
1114    }
1115#if 0
1116	 else if (base_type == IDL_DT_INTERFACE)	{
1117		 element_size = sizeof(void*);
1118		 defn_vec_ptr += 2; /* skip base and properties bytes */
1119		 IDL_GET_LONG_FROM_VECTOR(element_defn_index, defn_vec_ptr);
1120	 }
1121#endif
1122
1123    /* element_index, element_defn_ptr may not be set, but in these cases
1124        the procedure calls following do not use them */
1125        rpc_ss_ndr_marsh_by_looping(element_count,
1126              base_type, array_addr, element_size, element_defn_index, IDL_msp);
1127}
1128
1129/******************************************************************************/
1130/*                                                                            */
1131/*  Marshall a fixed array                                                    */
1132/*                                                                            */
1133/******************************************************************************/
1134void rpc_ss_ndr_marsh_fixed_arr
1135(
1136    /* [in] */  idl_ulong_int defn_index,
1137    /* [in] */  rpc_void_p_t array_addr,
1138    /* [in] */  idl_ulong_int flags,
1139    IDL_msp_t IDL_msp
1140)
1141{
1142    idl_byte *defn_vec_ptr;
1143    idl_ulong_int dimensionality;
1144    IDL_bound_pair_t *bounds_list;
1145
1146    defn_vec_ptr = IDL_msp->IDL_type_vec + defn_index;
1147    dimensionality = (idl_ulong_int)*defn_vec_ptr;
1148    defn_vec_ptr++;
1149    /* By design defn_vec_ptr is now aligned (0 mod 4) */
1150    if (IDL_msp->IDL_type_vec[TVEC_INT_REP_OFFSET] != NDR_LOCAL_INT_REP)
1151      rpc_ss_fixed_bounds_from_vector(dimensionality, defn_vec_ptr,
1152				      &bounds_list, IDL_msp);
1153    else
1154      bounds_list = (IDL_bound_pair_t *)defn_vec_ptr;
1155    rpc_ss_ndr_m_fix_or_conf_arr( array_addr, dimensionality, bounds_list,
1156                    defn_vec_ptr + dimensionality * IDL_FIXED_BOUND_PAIR_WIDTH,
1157                    flags, IDL_msp );
1158    if (IDL_msp->IDL_type_vec[TVEC_INT_REP_OFFSET] != NDR_LOCAL_INT_REP)
1159      rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle, (byte_p_t)bounds_list);
1160}
1161
1162/******************************************************************************/
1163/*                                                                            */
1164/* Marshall A,B pairs                                                         */
1165/*                                                                            */
1166/******************************************************************************/
1167static void rpc_ss_ndr_marsh_A_B_pairs
1168(
1169    /* [in] */  idl_ulong_int dimensionality,
1170    /* [in] */  IDL_bound_pair_t *range_list,
1171    IDL_msp_t IDL_msp
1172)
1173{
1174    unsigned32 i;
1175    idl_ulong_int A,B;
1176
1177    for (i=0; i<dimensionality; i++)
1178    {
1179        A = range_list[i].lower;
1180        IDL_MARSH_ULONG( &A );
1181        B = range_list[i].upper - A;
1182        IDL_MARSH_ULONG( &B );
1183    }
1184}
1185
1186/******************************************************************************/
1187/*                                                                            */
1188/* Marshall a varying or open array                                           */
1189/*                                                                            */
1190/******************************************************************************/
1191static idl_byte null_byte = 0;
1192
1193void rpc_ss_ndr_m_var_or_open_arr
1194(
1195    /* [in] */  rpc_void_p_t array_addr,
1196    /* [in] */  idl_ulong_int *Z_values,
1197    /* [in] */  idl_ulong_int dimensionality,
1198    /* [in] */  IDL_bound_pair_t *range_list,
1199    /* [in] */  idl_byte *defn_vec_ptr, /* On entry points at array base info */
1200    /* [in] */ idl_ulong_int flags,
1201    IDL_msp_t IDL_msp
1202)
1203{
1204    idl_ulong_int element_defn_index = 0;
1205    idl_ulong_int element_size;
1206    idl_byte base_type;
1207    IDL_varying_control_t *control_data;    /* List of data used to control
1208                                                marshalling loops */
1209    IDL_varying_control_t normal_control_data[IDL_NORMAL_DIMS];
1210    int i;
1211    idl_byte *inner_slice_address;  /* Address of 1-dim subset of array */
1212    int dim;    /* Index through array dimensions */
1213    idl_boolean contiguous;
1214    idl_ulong_int element_count;
1215    idl_boolean marshall_by_pointing;
1216    rpc_void_p_t point_addr;    /* Address to be used in marsh by pointing */
1217    idl_ushort_int v1_count;
1218
1219    if ( (*defn_vec_ptr == IDL_DT_STRING)
1220        || (*defn_vec_ptr == IDL_DT_V1_STRING) )
1221    {
1222        /* Arrays of strings have a special representation */
1223        dimensionality--;
1224    }
1225
1226    if (IDL_M_FLAGS_TEST(flags, IDL_M_V1_ARRAY))
1227    {
1228        /* Marshall one short word of varyingness info */
1229        v1_count =  1;
1230        for ( i=0; (unsigned32)i<dimensionality; i++)
1231        {
1232            v1_count *= (range_list[i].upper - range_list[i].lower);
1233        }
1234        IDL_MARSH_CUSHORT( &v1_count );
1235        if (v1_count == 0)
1236        {
1237            if ( rpc_ss_bug_1_thru_31(IDL_BUG_1|IDL_BUG_2, IDL_msp) )
1238            {
1239                rpc_ss_ndr_arr_align_and_opt( IDL_marshalling_k, dimensionality,
1240                                              &base_type, defn_vec_ptr,
1241                                              &marshall_by_pointing, IDL_msp );
1242                if ( rpc_ss_bug_1_thru_31(IDL_BUG_1, IDL_msp)
1243                        && ( (base_type == IDL_DT_FIXED_STRUCT)
1244                                || (base_type == IDL_DT_ENC_UNION)
1245                                || (base_type == IDL_DT_TRANSMIT_AS) ) )
1246                {
1247                    /* -bug 1 and non-scalar base type for [v1_array] */
1248                    idl_ulong_int bug_1_align;
1249                    bug_1_align = rpc_ss_ndr_bug_1_align(defn_vec_ptr, IDL_msp);
1250                    IDL_MARSH_ALIGN_MP( IDL_msp, bug_1_align );
1251                }
1252            }
1253            return;
1254        }
1255    }
1256    else
1257    {
1258        if (IDL_M_FLAGS_TEST(flags, IDL_M_ADD_NULL))
1259        {
1260            /* This is a one-dimensional array and the count of elements
1261                to be marshalled does not include the trailing null */
1262            (range_list[0].upper)++;
1263        }
1264        rpc_ss_ndr_marsh_A_B_pairs(dimensionality, range_list, IDL_msp);
1265        if (IDL_M_FLAGS_TEST(flags, IDL_M_ADD_NULL))
1266        {
1267            (range_list[0].upper)--;
1268        }
1269        for ( i=0; (unsigned32)i<dimensionality; i++)
1270        {
1271            if (range_list[i].upper ==  range_list[i].lower)
1272            {
1273                /* No elements to marshall */
1274                return;
1275            }
1276        }
1277    }
1278
1279    rpc_ss_ndr_arr_align_and_opt( IDL_marshalling_k, dimensionality, &base_type,
1280                                defn_vec_ptr, &marshall_by_pointing, IDL_msp );
1281    if ((IDL_M_FLAGS_TEST(flags, IDL_M_ADD_NULL))
1282                    || (IDL_M_FLAGS_TEST(flags, IDL_M_DO_NOT_POINT)))
1283        marshall_by_pointing = idl_false;
1284
1285    if (base_type == IDL_DT_REF_PTR)
1286    {
1287        return;
1288    }
1289    else if ( (base_type == IDL_DT_STRING)
1290            || (base_type == IDL_DT_V1_STRING) )
1291        rpc_ss_get_string_base_desc(defn_vec_ptr, &element_size,
1292                                    &element_defn_index, IDL_msp);
1293    else
1294        element_size = rpc_ss_type_size(defn_vec_ptr, IDL_msp);
1295
1296    if (marshall_by_pointing)
1297    {
1298        point_addr = array_addr;
1299        rpc_ss_ndr_contiguous_elt( dimensionality, Z_values, range_list,
1300                                   element_size, &contiguous, &element_count,
1301                                   &point_addr );
1302        if (contiguous)
1303        {
1304            if (base_type != IDL_DT_FIXED_STRUCT)
1305            {
1306                if ((element_count >= IDL_POINT_THRESHOLD)
1307                            && (IDL_msp->IDL_pickling_handle == NULL)
1308                    )
1309                    rpc_ss_ndr_marsh_by_pointing(element_count, element_size,
1310                                             point_addr, IDL_msp);
1311                else
1312                    rpc_ss_ndr_marsh_by_copying(element_count, element_size,
1313                                             point_addr, IDL_msp);
1314		return;
1315	    }
1316	    else /* For NDR-aligned fixed structures */
1317	    {
1318		/*
1319		 * 	The last element of the structure cannot, in general, be
1320		 * 	marshalled via the point-at optimization because of trailing
1321		 * 	pad is returned from the sizeof() function that is not included
1322		 * 	in NDR.
1323		 */
1324                element_count--;        /* So do the last one separately */
1325
1326		/* If there are more that 1, do them by pointing */
1327		if (element_count != 0)
1328		{
1329		    if (((element_count*element_size) >= IDL_POINT_THRESHOLD)
1330                            && (IDL_msp->IDL_pickling_handle == NULL)
1331                        )
1332			rpc_ss_ndr_marsh_by_pointing(element_count, element_size,
1333						 point_addr, IDL_msp);
1334		    else
1335			rpc_ss_ndr_marsh_by_copying(element_count, element_size,
1336						 point_addr, IDL_msp);
1337		}
1338
1339                /* Marshall the last element separately */
1340                defn_vec_ptr += 4;  /* See comment below */
1341                IDL_GET_LONG_FROM_VECTOR( element_defn_index, defn_vec_ptr );
1342                rpc_ss_ndr_marsh_struct(base_type, element_defn_index,
1343                                    (rpc_void_p_t)((idl_byte *)point_addr
1344                                             + element_count * element_size),
1345                                    IDL_msp);
1346            }
1347            return;
1348        }
1349    }
1350
1351    if ( (base_type == IDL_DT_FIXED_STRUCT)
1352         || (base_type == IDL_DT_ENC_UNION)
1353         || (base_type == IDL_DT_TRANSMIT_AS)
1354         || (base_type == IDL_DT_REPRESENT_AS) )
1355    {
1356        /* Discard any of DT_MODIFIED, type, modifier, properties
1357            which may be present, and any filler bytes */
1358        defn_vec_ptr += 4;
1359        IDL_GET_LONG_FROM_VECTOR( element_defn_index, defn_vec_ptr );
1360    }
1361
1362    if (dimensionality > IDL_NORMAL_DIMS)
1363    {
1364        control_data = (IDL_varying_control_t *)rpc_ss_mem_alloc(
1365                                &IDL_msp->IDL_mem_handle,
1366                                dimensionality * sizeof(IDL_varying_control_t));
1367    }
1368    else
1369        control_data = normal_control_data;
1370    control_data[dimensionality-1].subslice_size = element_size;
1371    control_data[dimensionality-1].index_value =
1372                                            range_list[dimensionality-1].lower;
1373    for (i=dimensionality-2; i>=0; i--)
1374    {
1375        control_data[i].index_value = range_list[i].lower;
1376        control_data[i].subslice_size = control_data[i+1].subslice_size
1377                                                            * Z_values[i+1];
1378    }
1379
1380    do {
1381        inner_slice_address = (idl_byte *)array_addr;
1382        for (i=0; (unsigned32)i<dimensionality; i++)
1383        {
1384            inner_slice_address += control_data[i].index_value
1385                                        * control_data[i].subslice_size;
1386        }
1387        rpc_ss_ndr_marsh_by_looping(
1388                 range_list[dimensionality-1].upper
1389                                         - range_list[dimensionality-1].lower,
1390                 base_type, (rpc_void_p_t)inner_slice_address,
1391                 element_size, element_defn_index, IDL_msp);
1392        dim = dimensionality - 2;
1393        while (dim >= 0)
1394        {
1395            control_data[dim].index_value++;
1396            if (control_data[dim].index_value < (unsigned32)range_list[dim].upper)
1397                break;
1398            control_data[dim].index_value = range_list[dim].lower;
1399            dim--;
1400        }
1401    } while (dim >= 0);
1402
1403    if (dimensionality > IDL_NORMAL_DIMS)
1404        rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle, (byte_p_t)control_data);
1405
1406    if (IDL_M_FLAGS_TEST(flags, IDL_M_ADD_NULL))
1407    {
1408        /* Number of null bytes required is character width */
1409        for (i=0; (unsigned32)i<element_size; i++)
1410        {
1411            IDL_MARSH_BYTE( &null_byte );
1412        }
1413    }
1414}
1415
1416/******************************************************************************/
1417/*                                                                            */
1418/*  Marshall a varying array                                                  */
1419/*                                                                            */
1420/******************************************************************************/
1421void rpc_ss_ndr_marsh_varying_arr
1422(
1423    /* [in] */  idl_ulong_int defn_index,
1424                                    /* Index of start of array description */
1425    /* [in] */  rpc_void_p_t array_addr,
1426    /* [in] */  rpc_void_p_t struct_addr,   /* Address of structure array is
1427                                part of. NULL if array is not structure field */
1428    /* [in] */  idl_ulong_int *struct_offset_vec_ptr,
1429                                      /* NULL if array is not structure field */
1430    /* [in] */ idl_ulong_int flags,
1431    IDL_msp_t IDL_msp
1432)
1433{
1434    idl_byte *defn_vec_ptr;
1435    idl_ulong_int dimensionality;
1436    IDL_bound_pair_t *bounds_list;
1437    idl_ulong_int *Z_values;
1438    idl_ulong_int normal_Z_values[IDL_NORMAL_DIMS];
1439    IDL_bound_pair_t *range_list;
1440    IDL_bound_pair_t normal_range_list[IDL_NORMAL_DIMS];
1441    idl_boolean add_null;
1442    rpc_void_p_t array_data_addr; /* May need to decode descriptor to get
1443                                        the address of the array data */
1444
1445    defn_vec_ptr = IDL_msp->IDL_type_vec + defn_index;
1446    dimensionality = (idl_ulong_int)*defn_vec_ptr;
1447    defn_vec_ptr++;
1448    /* By design we are now longword aligned */
1449    if (IDL_msp->IDL_type_vec[TVEC_INT_REP_OFFSET] != NDR_LOCAL_INT_REP)
1450      rpc_ss_fixed_bounds_from_vector(dimensionality, defn_vec_ptr, &bounds_list,
1451                                    IDL_msp);
1452    else
1453      bounds_list = (IDL_bound_pair_t *)defn_vec_ptr;
1454    if (dimensionality > IDL_NORMAL_DIMS)
1455    {
1456        Z_values = NULL;
1457        range_list = NULL;
1458    }
1459    else
1460    {
1461        Z_values = normal_Z_values;
1462        range_list = normal_range_list;
1463    }
1464    rpc_ss_Z_values_from_bounds( bounds_list, dimensionality, &Z_values,
1465                                                                     IDL_msp );
1466    defn_vec_ptr += dimensionality * IDL_FIXED_BOUND_PAIR_WIDTH;
1467    /* The address of the array data is only needed when a range list is
1468        being built for [string] data */
1469        array_data_addr = array_addr;
1470
1471    rpc_ss_build_range_list( &defn_vec_ptr, array_data_addr, struct_addr,
1472                        struct_offset_vec_ptr, dimensionality, bounds_list,
1473                        &range_list, &add_null, IDL_msp );
1474    rpc_ss_ndr_m_var_or_open_arr( array_addr, Z_values, dimensionality,
1475                                  range_list, defn_vec_ptr,
1476                                  flags | (add_null ? IDL_M_ADD_NULL : 0),
1477                                  IDL_msp );
1478    if (dimensionality > IDL_NORMAL_DIMS)
1479    {
1480        rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle, (byte_p_t)range_list);
1481        rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle, (byte_p_t)Z_values);
1482    }
1483    if (IDL_msp->IDL_type_vec[TVEC_INT_REP_OFFSET] != NDR_LOCAL_INT_REP)
1484      rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle, (byte_p_t)bounds_list);
1485}
1486
1487/******************************************************************************/
1488/*                                                                            */
1489/*  Marshall the Z values for a conformant or open array                      */
1490/*                                                                            */
1491/******************************************************************************/
1492void rpc_ss_ndr_marsh_Z_values
1493(
1494    /* [in] */  idl_ulong_int dimensionality,
1495    /* [in] */  idl_ulong_int *Z_values,
1496    IDL_msp_t IDL_msp
1497)
1498{
1499    unsigned32 i;
1500
1501    for (i=0; i<dimensionality; i++)
1502    {
1503        IDL_MARSH_ULONG( &Z_values[i] );
1504    }
1505}
1506
1507/******************************************************************************/
1508/*                                                                            */
1509/*  Marshall a conformant array parameter                                     */
1510/*                                                                            */
1511/******************************************************************************/
1512static void rpc_ss_ndr_marsh_conf_arr
1513(
1514    /* [in] */  idl_ulong_int defn_index,
1515    /* [in] */  rpc_void_p_t array_addr,
1516    IDL_msp_t IDL_msp
1517)
1518{
1519    idl_byte *defn_vec_ptr;
1520    idl_ulong_int dimensionality;
1521    IDL_bound_pair_t *bounds_list;
1522    IDL_bound_pair_t normal_bounds_list[IDL_NORMAL_DIMS];
1523    idl_ulong_int *Z_values;
1524    idl_ulong_int normal_Z_values[IDL_NORMAL_DIMS];
1525
1526    defn_vec_ptr = IDL_msp->IDL_type_vec + defn_index;
1527    dimensionality = (idl_ulong_int)*defn_vec_ptr;
1528    defn_vec_ptr++;
1529    if (dimensionality > IDL_NORMAL_DIMS)
1530    {
1531        bounds_list = NULL;
1532        Z_values = NULL;
1533    }
1534    else
1535    {
1536        bounds_list = normal_bounds_list;
1537        Z_values = normal_Z_values;
1538    }
1539    rpc_ss_build_bounds_list( &defn_vec_ptr, array_addr, NULL, NULL,
1540                              dimensionality, &bounds_list, IDL_msp );
1541    rpc_ss_Z_values_from_bounds(bounds_list, dimensionality, &Z_values,IDL_msp);
1542    rpc_ss_ndr_marsh_Z_values( dimensionality, Z_values, IDL_msp );
1543    rpc_ss_ndr_m_fix_or_conf_arr( array_addr, dimensionality, bounds_list,
1544                                defn_vec_ptr, IDL_M_IS_PARAM | IDL_M_CONF_ARRAY,
1545                                 IDL_msp );
1546    if (dimensionality > IDL_NORMAL_DIMS)
1547    {
1548        rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle, (byte_p_t)Z_values);
1549        rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle, (byte_p_t)bounds_list);
1550    }
1551}
1552
1553/******************************************************************************/
1554/*                                                                            */
1555/*  Marshall an open array                                                    */
1556/*                                                                            */
1557/******************************************************************************/
1558void rpc_ss_ndr_marsh_open_arr
1559(
1560    /* [in] */  idl_ulong_int defn_index,
1561    /* [in] */  rpc_void_p_t array_addr,
1562    /* [in] */ idl_ulong_int flags,
1563    IDL_msp_t IDL_msp
1564)
1565{
1566    idl_byte *defn_vec_ptr;
1567    idl_ulong_int dimensionality;
1568    IDL_bound_pair_t *bounds_list;
1569    IDL_bound_pair_t normal_bounds_list[IDL_NORMAL_DIMS];
1570    idl_ulong_int *Z_values;
1571    idl_ulong_int normal_Z_values[IDL_NORMAL_DIMS];
1572    IDL_bound_pair_t *range_list;
1573    IDL_bound_pair_t normal_range_list[IDL_NORMAL_DIMS];
1574    idl_ushort_int v1_size;
1575    idl_boolean add_null;
1576    rpc_void_p_t array_data_addr; /* May need to decode descriptor to get
1577                                        the address of the array_data */
1578    unsigned32 i;
1579
1580    defn_vec_ptr = IDL_msp->IDL_type_vec + defn_index;
1581    dimensionality = (idl_ulong_int)*defn_vec_ptr;
1582    defn_vec_ptr++;
1583    if (dimensionality > IDL_NORMAL_DIMS)
1584    {
1585        bounds_list = NULL;
1586        Z_values = NULL;
1587        range_list = NULL;
1588    }
1589    else
1590    {
1591        bounds_list = normal_bounds_list;
1592        Z_values = normal_Z_values;
1593        range_list = normal_range_list;
1594    }
1595    {
1596        array_data_addr = array_addr;
1597    }
1598    rpc_ss_build_bounds_list( &defn_vec_ptr, array_data_addr, NULL, NULL,
1599                                    dimensionality, &bounds_list, IDL_msp );
1600    rpc_ss_Z_values_from_bounds( bounds_list, dimensionality, &Z_values,
1601                                                                     IDL_msp );
1602    rpc_ss_build_range_list( &defn_vec_ptr, array_data_addr, NULL,
1603                        NULL, dimensionality, bounds_list,
1604                        &range_list, &add_null, IDL_msp );
1605    if (IDL_M_FLAGS_TEST(flags, IDL_M_V1_ARRAY))
1606    {
1607        v1_size = 1;
1608        for ( i=0; i<dimensionality; i++ )
1609            v1_size *= Z_values[i];
1610        IDL_MARSH_CUSHORT( &v1_size );
1611    }
1612    else
1613        rpc_ss_ndr_marsh_Z_values( dimensionality, Z_values, IDL_msp );
1614    rpc_ss_ndr_m_var_or_open_arr( array_addr, Z_values, dimensionality,
1615                                  range_list, defn_vec_ptr,
1616                                  flags | (add_null ? IDL_M_ADD_NULL : 0),
1617                                  IDL_msp );
1618    if (dimensionality > IDL_NORMAL_DIMS)
1619    {
1620        rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle, (byte_p_t)range_list);
1621        rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle, (byte_p_t)Z_values);
1622        rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle, (byte_p_t)bounds_list);
1623    }
1624}
1625
1626/******************************************************************************/
1627/*                                                                            */
1628/*  Discard the description following DT_ALLOCATE_REF                         */
1629/*                                                                            */
1630/******************************************************************************/
1631void rpc_ss_discard_allocate_ref
1632(
1633    /* [in,out] */ idl_byte **p_type_vec_ptr
1634                            /* On entry type_vec_ptr points to type of parameter
1635                                         It is advanced over type definition */
1636)
1637{
1638    idl_byte type_byte;
1639    idl_byte *type_vec_ptr = *p_type_vec_ptr;
1640
1641    type_byte = *type_vec_ptr;
1642    type_vec_ptr++;
1643    switch (type_byte)
1644    {
1645        case IDL_DT_FIXED_STRUCT:
1646            type_vec_ptr++;     /* Ignore properties byte */
1647            IDL_DISCARD_LONG_FROM_VECTOR( type_vec_ptr );   /* Struct defn */
1648            break;
1649        case IDL_DT_FIXED_ARRAY:
1650        case IDL_DT_VARYING_ARRAY:
1651            type_vec_ptr++;     /* Ignore properties byte */
1652            IDL_DISCARD_LONG_FROM_VECTOR( type_vec_ptr );  /* Full array defn */
1653            IDL_DISCARD_LONG_FROM_VECTOR( type_vec_ptr );  /* Flat array defn */
1654            break;
1655        case IDL_DT_REF_PTR:
1656            type_vec_ptr++;     /* Ignore properties byte */
1657            IDL_DISCARD_LONG_FROM_VECTOR( type_vec_ptr );   /* Pointee defn */
1658            break;
1659        default:
1660#ifdef DEBUG_INTERP
1661            printf("rpc_ss_discard_allocate_ref:unrecognized type %d\n",
1662                        type_byte);
1663            exit(0);
1664#endif
1665            DCETHREAD_RAISE(rpc_x_coding_error);
1666    }
1667    *p_type_vec_ptr = type_vec_ptr;
1668}
1669
1670/******************************************************************************/
1671/*                                                                            */
1672/*  Control for marshalling                                                   */
1673/*                                                                            */
1674/******************************************************************************/
1675void rpc_ss_ndr_marsh_interp
1676(
1677    idl_ulong_int IDL_parameter_count, /* [in] -- Number of parameters to   */
1678                                  /* marshall in this call to the           */
1679                                  /* interpreter                            */
1680
1681    idl_ulong_int IDL_type_index,    /* [in] -- Offset into the type vector */
1682                               /* for the start of the parameter descriptions */
1683
1684    rpc_void_p_t IDL_param_vector[], /* [in,out] -- The addresses of each of */
1685                                  /* the the parameters thus it's size is   */
1686                                  /* the number of parameters in the        */
1687                                  /* signature of the operation             */
1688
1689    IDL_msp_t IDL_msp        /* [in,out] -- Pointer to marshalling state   */
1690)
1691{
1692    idl_byte *type_vec_ptr = NULL;
1693    idl_byte type_byte;
1694    idl_ulong_int param_index;
1695    rpc_void_p_t param_addr;
1696    idl_ulong_int defn_index;
1697#if 0
1698	 idl_ulong_int rtn_index, iid_index;
1699#endif
1700    idl_boolean type_has_pointers;
1701    idl_boolean v1_array = idl_false;
1702    idl_boolean is_string = idl_false;
1703    idl_ulong_int node_number;
1704    long already_marshalled;
1705    idl_byte *pointee_defn_ptr;
1706    IDL_pointee_desc_t pointee_desc;    /* Description of pointee */
1707    idl_ulong_int switch_index; /* Index of switch param for non-encapsulated
1708                                                                        union */
1709    idl_ulong_int routine_index; /* Index of rtn to be used to free referents
1710                       of [in]-only [transmit_as] or [represent_as] parameter */
1711    IDL_cs_shadow_elt_t *cs_shadow = NULL;     /* cs-shadow for parameter list */
1712    idl_ulong_int shadow_length;
1713    IDL_bound_pair_t range_bounds;
1714
1715    IDL_msp->IDL_marsh_pipe = idl_false;
1716    IDL_msp->IDL_m_xmit_level = 0;
1717    type_vec_ptr = (IDL_msp->IDL_type_vec) + IDL_type_index;
1718
1719    IDL_INIT_RANGE(range_bounds);
1720
1721    /* Loop over parameters */
1722    for ( ; IDL_parameter_count > 0; IDL_parameter_count -- )
1723    {
1724        IDL_GET_LONG_FROM_VECTOR(param_index,type_vec_ptr);
1725        param_addr = IDL_param_vector[param_index];
1726        do {
1727            type_byte = *type_vec_ptr;
1728            type_vec_ptr++;
1729            switch(type_byte)
1730            {
1731                case IDL_DT_BYTE:
1732                    IDL_CHECK_RANGE_BYTE( range_bounds, param_addr );
1733                    IDL_MARSH_BYTE( param_addr );
1734                    break;
1735                case IDL_DT_CHAR:
1736                    IDL_CHECK_RANGE_CHAR( range_bounds, param_addr );
1737                    IDL_MARSH_CHAR( param_addr );
1738                    break;
1739                case IDL_DT_BOOLEAN:
1740                    IDL_CHECK_RANGE_BOOLEAN( range_bounds, param_addr );
1741                    IDL_MARSH_BOOLEAN( param_addr );
1742                    break;
1743                case IDL_DT_DOUBLE:
1744                    IDL_CHECK_RANGE_DOUBLE( range_bounds, param_addr );
1745                    IDL_MARSH_DOUBLE( param_addr );
1746                    break;
1747                case IDL_DT_ENUM:
1748                    IDL_MARSH_ENUM( param_addr );
1749                    break;
1750                case IDL_DT_FLOAT:
1751                    IDL_CHECK_RANGE_FLOAT( range_bounds, param_addr );
1752                    IDL_MARSH_FLOAT( param_addr );
1753                    break;
1754                case IDL_DT_SMALL:
1755                    IDL_CHECK_RANGE_SMALL( range_bounds, param_addr );
1756                    IDL_MARSH_SMALL( param_addr );
1757                    break;
1758                case IDL_DT_SHORT:
1759                    IDL_CHECK_RANGE_SHORT( range_bounds, param_addr );
1760                    IDL_MARSH_SHORT( param_addr );
1761                    break;
1762                case IDL_DT_LONG:
1763                    IDL_CHECK_RANGE_LONG( range_bounds, param_addr );
1764                    IDL_MARSH_LONG( param_addr );
1765                    break;
1766                case IDL_DT_HYPER:
1767                    IDL_MARSH_HYPER( param_addr );
1768                    break;
1769                case IDL_DT_USMALL:
1770                    IDL_CHECK_RANGE_USMALL( range_bounds, param_addr );
1771                    IDL_MARSH_USMALL( param_addr );
1772                    break;
1773                case IDL_DT_USHORT:
1774                    IDL_CHECK_RANGE_USHORT( range_bounds, param_addr );
1775                    IDL_MARSH_USHORT( param_addr );
1776                    break;
1777                case IDL_DT_ULONG:
1778                    IDL_CHECK_RANGE_ULONG( range_bounds, param_addr );
1779                    IDL_MARSH_ULONG( param_addr );
1780                    break;
1781                case IDL_DT_UHYPER:
1782                    IDL_MARSH_UHYPER( param_addr );
1783                    break;
1784                case IDL_DT_V1_ENUM:
1785                    IDL_MARSH_V1_ENUM( param_addr );
1786                    break;
1787                case IDL_DT_ERROR_STATUS:
1788                    IDL_MARSH_ERROR_STATUS( param_addr );
1789                    break;
1790                case IDL_DT_FIXED_STRUCT:
1791                case IDL_DT_CONF_STRUCT:
1792                case IDL_DT_V1_CONF_STRUCT:
1793                    /* Properties byte */
1794                    type_has_pointers =
1795                             IDL_PROP_TEST(*type_vec_ptr, IDL_PROP_HAS_PTRS);
1796                    type_vec_ptr++;
1797                    IDL_GET_LONG_FROM_VECTOR(defn_index,type_vec_ptr);
1798                    rpc_ss_ndr_marsh_struct(type_byte, defn_index, param_addr,
1799                                                                     IDL_msp);
1800                    if (type_has_pointers)
1801                    {
1802                        rpc_ss_ndr_m_struct_pointees(type_byte, defn_index,
1803                                                     param_addr, IDL_msp);
1804                    }
1805                    break;
1806                case IDL_DT_FIXED_ARRAY:
1807                    /* Properties byte */
1808                    type_has_pointers =
1809                             IDL_PROP_TEST(*type_vec_ptr, IDL_PROP_HAS_PTRS);
1810                    type_vec_ptr++;
1811                    IDL_DISCARD_LONG_FROM_VECTOR(type_vec_ptr);
1812                                            /* Discard full array definition */
1813                    IDL_GET_LONG_FROM_VECTOR(defn_index,type_vec_ptr);
1814                    rpc_ss_ndr_marsh_fixed_arr(defn_index, param_addr,
1815                                               IDL_M_IS_PARAM, IDL_msp);
1816                    if (type_has_pointers)
1817                    {
1818                        rpc_ss_ndr_m_dfc_arr_ptees(defn_index, param_addr,
1819                                                     NULL, NULL, 0, IDL_msp);
1820                    }
1821                    break;
1822                case IDL_DT_VARYING_ARRAY:
1823                    /* Properties byte */
1824                    type_has_pointers =
1825                             IDL_PROP_TEST(*type_vec_ptr, IDL_PROP_HAS_PTRS);
1826                    type_vec_ptr++;
1827                    IDL_DISCARD_LONG_FROM_VECTOR(type_vec_ptr);
1828                                            /* Discard full array definition */
1829                    IDL_GET_LONG_FROM_VECTOR(defn_index,type_vec_ptr);
1830                    rpc_ss_ndr_marsh_varying_arr(defn_index, param_addr,
1831                                         NULL, NULL,
1832                                         (v1_array ? IDL_M_V1_ARRAY : 0)
1833                                             | (is_string ? IDL_M_IS_STRING : 0)
1834                                             | IDL_M_IS_PARAM,
1835                                         IDL_msp);
1836                    if (type_has_pointers)
1837                    {
1838                        rpc_ss_ndr_m_dvo_arr_ptees(defn_index, param_addr,
1839                                                        NULL, NULL, 0, IDL_msp);
1840                    }
1841                    v1_array = idl_false;
1842                    is_string = idl_false;
1843                    break;
1844                case IDL_DT_CONF_ARRAY:
1845                    /* Properties byte */
1846                    type_has_pointers =
1847                             IDL_PROP_TEST(*type_vec_ptr, IDL_PROP_HAS_PTRS);
1848                    type_vec_ptr++;
1849                    IDL_DISCARD_LONG_FROM_VECTOR(type_vec_ptr);
1850                                            /* Discard full array definition */
1851                    IDL_GET_LONG_FROM_VECTOR(defn_index,type_vec_ptr);
1852                    rpc_ss_ndr_marsh_conf_arr(defn_index, param_addr,
1853                                                                     IDL_msp);
1854                    if (type_has_pointers)
1855                    {
1856                        rpc_ss_ndr_m_dfc_arr_ptees(defn_index, param_addr,
1857                                         NULL, NULL, IDL_M_CONF_ARRAY, IDL_msp);
1858                    }
1859                    break;
1860                case IDL_DT_OPEN_ARRAY:
1861                    /* Properties byte */
1862                    type_has_pointers =
1863                             IDL_PROP_TEST(*type_vec_ptr, IDL_PROP_HAS_PTRS);
1864                    type_vec_ptr++;
1865                    IDL_DISCARD_LONG_FROM_VECTOR(type_vec_ptr);
1866                                            /* Discard full array definition */
1867                    IDL_GET_LONG_FROM_VECTOR(defn_index,type_vec_ptr);
1868                    rpc_ss_ndr_marsh_open_arr(defn_index, param_addr,
1869                                         (v1_array ? IDL_M_V1_ARRAY : 0)
1870                                            | (is_string ? IDL_M_IS_STRING : 0)
1871                                            | IDL_M_IS_PARAM | IDL_M_CONF_ARRAY,
1872                                         IDL_msp);
1873                    if (type_has_pointers)
1874                    {
1875                        rpc_ss_ndr_m_dvo_arr_ptees(defn_index, param_addr,
1876                                         NULL, NULL, IDL_M_CONF_ARRAY, IDL_msp);
1877                    }
1878                    v1_array = idl_false;
1879                    is_string = idl_false;
1880                    break;
1881                case IDL_DT_ENC_UNION:
1882                    /* Properties byte */
1883                    type_has_pointers =
1884                             IDL_PROP_TEST(*type_vec_ptr, IDL_PROP_HAS_PTRS);
1885                    type_vec_ptr++;
1886                    IDL_GET_LONG_FROM_VECTOR(defn_index,type_vec_ptr);
1887                    rpc_ss_ndr_m_enc_union_or_ptees( param_addr, defn_index,
1888                                                     idl_false, IDL_msp);
1889                    if (type_has_pointers)
1890                    {
1891                        rpc_ss_ndr_m_enc_union_or_ptees( param_addr, defn_index,
1892                                                         idl_true, IDL_msp);
1893                    }
1894                    break;
1895                case IDL_DT_N_E_UNION:
1896                    /* Properties byte */
1897                    type_has_pointers =
1898                             IDL_PROP_TEST(*type_vec_ptr, IDL_PROP_HAS_PTRS);
1899                    type_vec_ptr++;
1900                    IDL_GET_LONG_FROM_VECTOR(switch_index,type_vec_ptr);
1901                    IDL_GET_LONG_FROM_VECTOR(defn_index,type_vec_ptr);
1902                    rpc_ss_ndr_m_n_e_union_or_ptees( param_addr, switch_index,
1903                                                        defn_index, NULL, NULL,
1904                                                        idl_false, IDL_msp);
1905                    if (type_has_pointers)
1906                    {
1907                        rpc_ss_ndr_m_n_e_union_or_ptees( param_addr,
1908                                                 switch_index, defn_index, NULL,
1909                                                 NULL, idl_true, IDL_msp);
1910                    }
1911                    break;
1912                case IDL_DT_PASSED_BY_REF:
1913                    break;
1914                case IDL_DT_FULL_PTR:
1915                    type_vec_ptr++;     /* Properties byte */
1916                    IDL_GET_LONG_FROM_VECTOR(defn_index,type_vec_ptr);
1917                    node_number = rpc_ss_register_node( IDL_msp->IDL_node_table,
1918                                          (byte_p_t)*(rpc_void_p_t *)param_addr,
1919                                             idl_true, &already_marshalled );
1920                    IDL_MARSH_ULONG( &node_number );
1921                    if ( (*(rpc_void_p_t *)param_addr != NULL)
1922                                                     && !already_marshalled )
1923                    {
1924                        pointee_defn_ptr = IDL_msp->IDL_type_vec + defn_index;
1925                        pointee_desc.dimensionality = 0;
1926                        rpc_ss_pointee_desc_from_data( pointee_defn_ptr,
1927                                          (byte_p_t)*(rpc_void_p_t *)param_addr,
1928                                           NULL, NULL, &pointee_desc, IDL_msp );
1929                        rpc_ss_ndr_marsh_pointee( pointee_defn_ptr,
1930                                                    *(rpc_void_p_t *)param_addr,
1931                                                    idl_false, &pointee_desc,
1932                                                    IDL_msp );
1933                        rpc_ss_rlse_data_pointee_desc( &pointee_desc, IDL_msp );
1934                    }
1935                    break;
1936                case IDL_DT_UNIQUE_PTR:
1937                    type_vec_ptr++;     /* Properties byte */
1938                    IDL_GET_LONG_FROM_VECTOR(defn_index,type_vec_ptr);
1939                    node_number = (*(rpc_void_p_t *)param_addr != NULL);
1940                                                          /* 1 if not null */
1941                    IDL_MARSH_ULONG( &node_number );
1942                    if (*(rpc_void_p_t *)param_addr != NULL)
1943                    {
1944                        pointee_defn_ptr = IDL_msp->IDL_type_vec + defn_index;
1945                        pointee_desc.dimensionality = 0;
1946                        rpc_ss_pointee_desc_from_data( pointee_defn_ptr,
1947                                          (byte_p_t)*(rpc_void_p_t *)param_addr,
1948                                           NULL, NULL, &pointee_desc, IDL_msp );
1949                        rpc_ss_ndr_marsh_pointee( pointee_defn_ptr,
1950                                                    *(rpc_void_p_t *)param_addr,
1951                                                    idl_false, &pointee_desc,
1952                                                    IDL_msp );
1953                        rpc_ss_rlse_data_pointee_desc( &pointee_desc, IDL_msp );
1954                    }
1955                    break;
1956                case IDL_DT_REF_PTR:
1957                    type_vec_ptr++;     /* Properties byte */
1958                    IDL_GET_LONG_FROM_VECTOR(defn_index,type_vec_ptr);
1959                    pointee_defn_ptr = IDL_msp->IDL_type_vec + defn_index;
1960                    pointee_desc.dimensionality = 0;
1961                    rpc_ss_pointee_desc_from_data( pointee_defn_ptr,
1962                                          (byte_p_t)*(rpc_void_p_t *)param_addr,
1963                                           NULL, NULL, &pointee_desc, IDL_msp );
1964                    rpc_ss_ndr_marsh_pointee( pointee_defn_ptr,
1965                                                    *(rpc_void_p_t *)param_addr,
1966                                                    idl_false, &pointee_desc,
1967                                                    IDL_msp );
1968                    rpc_ss_rlse_data_pointee_desc( &pointee_desc, IDL_msp );
1969                    break;
1970                case IDL_DT_STRING:
1971                    /* Varying/open array code will do the right thing */
1972                    is_string = idl_true;
1973                    break;
1974                case IDL_DT_TRANSMIT_AS:
1975                case IDL_DT_REPRESENT_AS:
1976                    type_vec_ptr++;     /* Properties byte */
1977                    IDL_GET_LONG_FROM_VECTOR(defn_index,type_vec_ptr);
1978                    rpc_ss_ndr_marsh_xmit_as(defn_index, param_addr, IDL_msp);
1979                    break;
1980#if 0
1981               case IDL_DT_INTERFACE:
1982                    type_vec_ptr++;	/* skip properties */
1983                    IDL_GET_LONG_FROM_VECTOR(defn_index, type_vec_ptr);
1984                    rpc_ss_ndr_marsh_interface(defn_index, param_addr, IDL_msp);
1985                    break;
1986					 case IDL_DT_DYN_INTERFACE:
1987                    type_vec_ptr++;     /* Properties byte */
1988                    IDL_GET_LONG_FROM_VECTOR(rtn_index,type_vec_ptr);
1989                    IDL_GET_LONG_FROM_VECTOR(iid_index,type_vec_ptr);
1990                    rpc_ss_ndr_marsh_dyn_interface(rtn_index, param_addr,
1991								  ((idl_uuid_t*) IDL_param_vector[iid_index]), IDL_msp);
1992                   break;
1993#endif
1994
1995                case IDL_DT_ALLOCATE:
1996                    /* Do nothing except move to next parameter */
1997                    if ((*type_vec_ptr == IDL_DT_STRING)
1998                                          || (*type_vec_ptr == IDL_DT_V1_ARRAY))
1999                        type_vec_ptr++;
2000                    type_vec_ptr += 2;     /* Array type and properties byte */
2001                    IDL_DISCARD_LONG_FROM_VECTOR(type_vec_ptr);
2002                                                        /* Full array defn */
2003                    IDL_DISCARD_LONG_FROM_VECTOR(type_vec_ptr);
2004                                                      /* Flattened array defn */
2005                    break;
2006                case IDL_DT_ALLOCATE_REF:
2007                    /* Do nothing except move to next parameter */
2008                    rpc_ss_discard_allocate_ref(&type_vec_ptr);
2009                    break;
2010                case IDL_DT_PIPE:
2011                    type_vec_ptr++;     /* Properties byte */
2012                    IDL_GET_LONG_FROM_VECTOR(defn_index,type_vec_ptr);
2013                    if (IDL_msp->IDL_side == IDL_client_side_k)
2014                        rpc_ss_ndr_marsh_pipe(defn_index, param_addr, IDL_msp);
2015                    break;
2016                case IDL_DT_IN_CONTEXT:
2017                case IDL_DT_IN_OUT_CONTEXT:
2018                case IDL_DT_OUT_CONTEXT:
2019                    rpc_ss_ndr_marsh_context(type_byte, param_addr, IDL_msp);
2020                    break;
2021                case IDL_DT_V1_ARRAY:
2022                    v1_array = idl_true;
2023                    break;
2024                case IDL_DT_V1_STRING:
2025                    type_vec_ptr += 2;  /* DT_VARYING_ARRAY and properties */
2026                    IDL_DISCARD_LONG_FROM_VECTOR(type_vec_ptr);
2027                                                        /* Full array defn */
2028                    IDL_DISCARD_LONG_FROM_VECTOR(type_vec_ptr);
2029                                                      /* Flattened array defn */
2030                    rpc_ss_ndr_marsh_v1_string(param_addr, IDL_M_IS_PARAM,
2031                                                                     IDL_msp);
2032                    break;
2033                case IDL_DT_FREE_REP:
2034                    IDL_GET_LONG_FROM_VECTOR(routine_index, type_vec_ptr);
2035                    if (IDL_msp->IDL_side == IDL_server_side_k)
2036                    {
2037                        /* Only applies on server side */
2038                        (*(IDL_msp->IDL_rtn_vec + routine_index))(param_addr);
2039                    }
2040                    break;
2041                case IDL_DT_DELETED_NODES:
2042                    rpc_ss_ndr_marsh_deletes(IDL_msp);
2043                    break;
2044                case IDL_DT_CS_ATTRIBUTE:
2045                    /* Is followed by the (integer) type of the attribute */
2046                    assert (type_vec_ptr != NULL);
2047                    rpc_ss_ndr_marsh_scalar(*type_vec_ptr,
2048                            (rpc_void_p_t)&cs_shadow[param_index-1].IDL_data,
2049                            IDL_msp);
2050                    type_vec_ptr++;     /* Attribute type */
2051                    break;
2052                case IDL_DT_CS_TYPE:
2053                    type_vec_ptr++;     /* Properties byte */
2054                    IDL_GET_LONG_FROM_VECTOR(defn_index,type_vec_ptr);
2055                    rpc_ss_ndr_marsh_cs_char(param_addr, defn_index, IDL_msp);
2056                    break;
2057                case IDL_DT_CS_ARRAY:
2058                    /* Is followed by an array description */
2059                    assert (cs_shadow != NULL);
2060                    rpc_ss_ndr_marsh_cs_array(param_addr, cs_shadow,
2061                            param_index-1, idl_false, &type_vec_ptr, IDL_msp);
2062                    break;
2063
2064                case IDL_DT_CS_SHADOW:
2065                    IDL_GET_LONG_FROM_VECTOR(shadow_length, type_vec_ptr);
2066                    assert (cs_shadow != NULL);
2067                    rpc_ss_ndr_m_param_cs_shadow(
2068                                type_vec_ptr, param_index, shadow_length,
2069                                &cs_shadow, IDL_msp);
2070                    break;
2071                case IDL_DT_CS_RLSE_SHADOW:
2072                    rpc_ss_ndr_m_rlse_cs_shadow(cs_shadow, IDL_parameter_count,
2073                                                                     IDL_msp);
2074                    break;
2075                case IDL_DT_RANGE:
2076                    IDL_GET_RANGE_FROM_VECTOR(range_bounds, type_vec_ptr);
2077                    break;
2078                case IDL_DT_EOL:
2079                    break;
2080                default:
2081#ifdef DEBUG_INTERP
2082                    printf("rpc_ss_ndr_marsh_interp:unrecognized type %d\n",
2083                        type_byte);
2084                    exit(0);
2085#endif
2086                    DCETHREAD_RAISE(rpc_x_coding_error);
2087            }
2088        } while (type_byte != IDL_DT_EOL);
2089    }
2090
2091    /* For pickling, round the buffer out to a multiple of 8 bytes */
2092    if (IDL_msp->IDL_pickling_handle != NULL)
2093    {
2094        IDL_MARSH_ALIGN_MP(IDL_msp, 8);
2095    }
2096
2097    /* If there is a current buffer, attach it to the iovector */
2098    if (IDL_msp->IDL_buff_addr != NULL)
2099    {
2100        rpc_ss_attach_buff_to_iovec( IDL_msp );
2101    }
2102    /* Make the iovector ready for the rpc_call_transceive call */
2103    IDL_msp->IDL_iovec.num_elt = IDL_msp->IDL_elts_in_use;
2104    /* And nothing else needs to be cleaned up */
2105    IDL_msp->IDL_elts_in_use = 0;
2106}
2107