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**      ndrmi5.c
80**
81**  FACILITY:
82**
83**      Interface Definition Language (IDL) Compiler
84**
85**  ABSTRACT:
86**
87**      NDR marshalling routines for - International characters
88**
89*/
90#if HAVE_CONFIG_H
91#include <config.h>
92#endif
93
94#include <dce/idlddefs.h>
95#include <ndrmi.h>
96#include <lsysdep.h>
97#include <assert.h>
98
99/*****************************************************************************/
100/*                                                                           */
101/* Fill in the cs-shadow element associated with an array of [cs_char]       */
102/* Note that all such arrays have dimension 1 and lower bound and data limit */
103/*     fixed                                                                 */
104/*                                                                           */
105/*****************************************************************************/
106
107static void rpc_ss_ndr_m_array_shadow (
108    rpc_void_p_t struct_addr,   /* [in] Address of struct array is a field of.
109                                    NULL if array is a parameter */
110    idl_ulong_int *struct_offset_vec_ptr,   /* [in] Base of offset vector for
111                                structure.  NULL if array is parameter */
112    idl_ulong_int *offset_vec_ptr,  /* [in] NULL if array is parameter */
113    IDL_cs_shadow_elt_t *cs_shadow, /* [in] */
114    idl_ulong_int shadow_index,     /* [in] index into cs-shadow */
115    idl_byte **p_defn_vec_ptr,      /* [in] Points after IDL_DT_CS_ARRAY */
116                                    /* [out] Points after array defn indices */
117    IDL_msp_t IDL_msp
118)
119{
120    idl_byte *defn_vec_ptr;
121    idl_byte array_type;
122    idl_ulong_int array_defn_index;
123    idl_byte *array_defn_ptr;
124    idl_boolean allocate;       /* TRUE => [in] size for [out] array */
125    IDL_bound_pair_t *bounds_list;
126    idl_ulong_int cs_type_defn_index;
127    idl_byte *cs_type_defn_ptr;
128    idl_ulong_int routine_index;
129    void (**routine_ptr)();
130    idl_byte ln_type = 0;           /* Data type of [length_is] item */
131    idl_ulong_int ln_index;     /* Index in shadow of [length_is] item */
132    idl_byte sz_type = 0;           /* Data type of [size_is] item */
133    idl_ulong_int sz_index;     /* Index in shadow of [size_is] item */
134    /* Parameters for ..._net_size */
135    idl_ulong_int l_storage_len;
136    idl_ulong_int w_storage_len;
137    idl_cs_convert_t convert_type;
138    /* Parameters for ..._to_netcs */
139    rpc_void_p_t ldata;
140    idl_ulong_int l_data_len;
141    rpc_void_p_t wdata;
142    idl_ulong_int w_data_len;
143
144    /* begin */
145
146    defn_vec_ptr = *p_defn_vec_ptr;
147    cs_shadow[shadow_index].IDL_release = idl_false;
148    array_type = *defn_vec_ptr;
149    defn_vec_ptr++;
150    allocate = (array_type == IDL_DT_ALLOCATE);
151
152    if (allocate)
153    {
154        array_type = *defn_vec_ptr;
155        defn_vec_ptr++;
156    }
157
158    defn_vec_ptr++;         /* Properties byte */
159    IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr);    /* Full array definition */
160    IDL_GET_LONG_FROM_VECTOR(array_defn_index, defn_vec_ptr);
161
162    if (array_type == IDL_DT_FIXED_ARRAY)
163    {
164        /* No shadow for fixed array of [cs_char] */
165        *p_defn_vec_ptr = defn_vec_ptr;
166        return;
167    }
168
169    /* Address of local form of array */
170    if (struct_addr != NULL)
171        ldata = (rpc_void_p_t)((idl_byte *)struct_addr + *offset_vec_ptr);
172    else
173        ldata = IDL_msp->IDL_param_vec[shadow_index + 1];
174
175    array_defn_ptr = IDL_msp->IDL_type_vec + array_defn_index;
176    array_defn_ptr++;       /* dimensionality */
177
178    /* Bounds information */
179
180    if (array_type == IDL_DT_VARYING_ARRAY)
181    {
182      if (IDL_msp->IDL_type_vec[TVEC_INT_REP_OFFSET] != NDR_LOCAL_INT_REP)
183        rpc_ss_fixed_bounds_from_vector(1, array_defn_ptr, &bounds_list,
184                                        IDL_msp);
185      else
186        bounds_list = (IDL_bound_pair_t *)array_defn_ptr;
187        array_defn_ptr += IDL_FIXED_BOUND_PAIR_WIDTH;
188        l_storage_len = bounds_list[0].upper - bounds_list[0].lower + 1;
189    }
190    else    /* Conformant or open */
191    {
192        /* Skip over lower bound entirely and upper bound kind */
193        array_defn_ptr += IDL_CONF_BOUND_PAIR_WIDTH/2 + 1;
194        sz_type = *array_defn_ptr;
195        IDL_GET_LONG_FROM_VECTOR(sz_index, array_defn_ptr);
196        if (struct_addr != NULL)
197        {
198            l_storage_len = rpc_ss_get_typed_integer(sz_type,
199                     (rpc_void_p_t)((idl_byte *)struct_addr
200                                        + *(struct_offset_vec_ptr + sz_index)),
201                     IDL_msp);
202        }
203        else
204        {
205            l_storage_len = rpc_ss_get_typed_integer(sz_type,
206                                     IDL_msp->IDL_param_vec[sz_index], IDL_msp);
207        }
208        sz_index--;     /* Shadow has one less elt than param or offset vec */
209    }
210
211    /* Data limit information */
212
213    if ((array_type == IDL_DT_VARYING_ARRAY)
214        || (array_type == IDL_DT_OPEN_ARRAY))
215    {
216        /* Skip over lower data limit entirely and upper data limit kind */
217        array_defn_ptr += IDL_DATA_LIMIT_PAIR_WIDTH/2 + 1;
218        ln_type = *array_defn_ptr;
219        IDL_GET_LONG_FROM_VECTOR(ln_index, array_defn_ptr);
220        if (struct_addr != NULL)
221        {
222            l_data_len = rpc_ss_get_typed_integer(ln_type,
223                     (rpc_void_p_t)((idl_byte *)struct_addr
224                                        + *(struct_offset_vec_ptr + ln_index)),
225                     IDL_msp);
226        }
227        else
228        {
229            l_data_len = rpc_ss_get_typed_integer(ln_type,
230                                     IDL_msp->IDL_param_vec[ln_index], IDL_msp);
231        }
232        ln_index--;     /* Shadow has one less elt than param or offset vec */
233    }
234    else
235        l_data_len = l_storage_len;
236
237    /* array_defn_ptr is now pointing to the base type, which has [cs_char] */
238
239    array_defn_ptr += 2;       /* IDL_DT_CS_TYPE and properties byte */
240    IDL_GET_LONG_FROM_VECTOR(cs_type_defn_index, array_defn_ptr);
241    cs_type_defn_ptr = IDL_msp->IDL_type_vec + cs_type_defn_index;
242    IDL_DISCARD_LONG_FROM_VECTOR(cs_type_defn_ptr); /* Size of local type */
243    IDL_GET_LONG_FROM_VECTOR(routine_index, cs_type_defn_ptr);
244    routine_ptr = IDL_msp->IDL_rtn_vec + routine_index;
245
246    /* Call ..._net_size */
247
248    (*(routine_ptr + IDL_RTN_NET_SIZE_INDEX))(IDL_msp->IDL_h,
249            *(IDL_msp->IDL_cs_tags_p->p_marsh_tag),
250            l_storage_len,
251            &convert_type,
252            (array_type == IDL_DT_VARYING_ARRAY) ? NULL : &w_storage_len,
253            &IDL_msp->IDL_status);
254
255    if (IDL_msp->IDL_status != error_status_ok)
256        DCETHREAD_RAISE(rpc_x_ss_pipe_comm_error);
257
258    if ((array_type == IDL_DT_CONF_ARRAY)
259        || (array_type == IDL_DT_OPEN_ARRAY))
260    {
261        rpc_ss_put_typed_integer(w_storage_len, sz_type,
262                               (rpc_void_p_t)&cs_shadow[sz_index].IDL_data);
263    }
264
265    if (allocate)
266        goto common_return;
267
268    if (convert_type == idl_cs_no_convert)
269    {
270        cs_shadow[shadow_index].IDL_data.IDL_storage_p = ldata;
271	w_data_len = l_data_len ; /* wire data length same as local */
272        goto alloc_return;
273    }
274
275    if (array_type == IDL_DT_VARYING_ARRAY)
276    {
277        w_storage_len = l_storage_len;
278    }
279
280    /* Allocate a conversion buffer
281                 - cs_type_defn_ptr now points at network type */
282
283    wdata = (idl_void_p_t)rpc_ss_mem_alloc(&IDL_msp->IDL_mem_handle,
284                 w_storage_len * rpc_ss_type_size(cs_type_defn_ptr, IDL_msp));
285    cs_shadow[shadow_index].IDL_data.IDL_storage_p = wdata;
286    cs_shadow[shadow_index].IDL_release = true;
287
288    /* Call ..._to_netcs */
289
290    (*(routine_ptr + IDL_RTN_TO_NETCS_INDEX))(IDL_msp->IDL_h,
291            *(IDL_msp->IDL_cs_tags_p->p_marsh_tag),
292            ldata,
293            l_data_len,
294            wdata,
295            (array_type == IDL_DT_CONF_ARRAY) ? NULL : &w_data_len,
296            &IDL_msp->IDL_status);
297    if (IDL_msp->IDL_status != error_status_ok)
298        DCETHREAD_RAISE(rpc_x_ss_pipe_comm_error);
299
300 alloc_return:;
301
302    if ((array_type == IDL_DT_VARYING_ARRAY)
303        || (array_type == IDL_DT_OPEN_ARRAY))
304    {
305        rpc_ss_put_typed_integer(w_data_len, ln_type,
306                               (rpc_void_p_t)&cs_shadow[ln_index].IDL_data);
307    }
308
309 common_return:
310    ;
311
312    *p_defn_vec_ptr = defn_vec_ptr;
313
314    if (IDL_msp->IDL_type_vec[TVEC_INT_REP_OFFSET] != NDR_LOCAL_INT_REP)
315        if (array_type == IDL_DT_VARYING_ARRAY)
316          rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle, (byte_p_t)bounds_list);
317    return ;
318}
319
320/*****************************************************************************/
321/*                                                                           */
322/* Build a cs-shadow for marshalling a structure                             */
323/*                                                                           */
324/*****************************************************************************/
325
326void rpc_ss_ndr_m_struct_cs_shadow (
327
328    rpc_void_p_t struct_addr,           /* [in] Address of struct */
329    idl_byte struct_type ATTRIBUTE_UNUSED,               /* [in] FIXED_STRUCT or CONF_STRUCT */
330    idl_ulong_int shadow_length,        /* [in] Number of structure fields */
331    idl_ulong_int offset_index,         /* [in] Start of struct's offset vec */
332    idl_byte *defn_vec_ptr,             /* [in] Posn following shadow length */
333    IDL_cs_shadow_elt_t **p_cs_shadow,  /* [out] Address of cs-shadow */
334    IDL_msp_t IDL_msp
335)
336{
337    idl_ulong_int *struct_offset_vec_ptr; /* Start of offsets for this struct */
338    idl_ulong_int *offset_vec_ptr;
339    idl_byte type_byte;
340    IDL_cs_shadow_elt_t *cs_shadow;
341    idl_ulong_int shadow_index;     /* Index into cs-shadow */
342
343    /* Allocate the cs-shadow */
344    cs_shadow = (IDL_cs_shadow_elt_t *)rpc_ss_mem_alloc
345        (&IDL_msp->IDL_mem_handle, shadow_length * sizeof(IDL_cs_shadow_elt_t));
346
347    struct_offset_vec_ptr = IDL_msp->IDL_offset_vec + offset_index;
348    offset_vec_ptr = struct_offset_vec_ptr + 1;
349                                        /* Skip over size at start of offsets */
350
351    shadow_index = 0;
352    do {
353        type_byte = *defn_vec_ptr;
354        defn_vec_ptr++;
355        switch(type_byte)
356        {
357            case IDL_DT_CS_ARRAY:
358                rpc_ss_ndr_m_array_shadow(struct_addr, struct_offset_vec_ptr,
359                        offset_vec_ptr, cs_shadow, shadow_index, &defn_vec_ptr,
360                        IDL_msp);
361                shadow_index++;
362                offset_vec_ptr++;
363                break;
364            /* For fields that are not array of [cs_char],
365             advance the definition and offset pointers and shadow index
366             in step. And note they have no translation storage */
367            case IDL_DT_BYTE:
368            case IDL_DT_CHAR:
369            case IDL_DT_BOOLEAN:
370            case IDL_DT_DOUBLE:
371            case IDL_DT_ENUM:
372            case IDL_DT_FLOAT:
373            case IDL_DT_SMALL:
374            case IDL_DT_SHORT:
375            case IDL_DT_LONG:
376            case IDL_DT_HYPER:
377            case IDL_DT_USMALL:
378            case IDL_DT_USHORT:
379            case IDL_DT_ULONG:
380            case IDL_DT_UHYPER:
381            case IDL_DT_IGNORE:
382            case IDL_DT_V1_ENUM:
383            case IDL_DT_ERROR_STATUS:
384                offset_vec_ptr++;
385                cs_shadow[shadow_index].IDL_release = idl_false;
386                shadow_index++;
387                break;
388            case IDL_DT_FIXED_ARRAY:
389            case IDL_DT_VARYING_ARRAY:
390            case IDL_DT_CONF_ARRAY:
391            case IDL_DT_OPEN_ARRAY:
392                /* Properties byte */
393                defn_vec_ptr++;
394                IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr);
395                                                    /* Full array definition */
396                IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr);
397                                                /* Flattened array definition */
398                offset_vec_ptr++;
399                cs_shadow[shadow_index].IDL_release = idl_false;
400                shadow_index++;
401                break;
402            case IDL_DT_ENC_UNION:
403            case IDL_DT_N_E_UNION:
404            case IDL_DT_FULL_PTR:
405            case IDL_DT_UNIQUE_PTR:
406            case IDL_DT_REF_PTR:
407            case IDL_DT_TRANSMIT_AS:
408            case IDL_DT_REPRESENT_AS:
409            case IDL_DT_CS_TYPE:
410                /* Properties byte */
411                defn_vec_ptr++;
412                IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr);
413                offset_vec_ptr++;
414                cs_shadow[shadow_index].IDL_release = idl_false;
415                shadow_index++;
416                break;
417            case IDL_DT_STRING:
418            case IDL_DT_NDR_ALIGN_2:
419            case IDL_DT_NDR_ALIGN_4:
420            case IDL_DT_NDR_ALIGN_8:
421            case IDL_DT_BEGIN_NESTED_STRUCT:
422            case IDL_DT_END_NESTED_STRUCT:
423            case IDL_DT_V1_ARRAY:
424            case IDL_DT_V1_STRING:
425            case IDL_DT_CS_ATTRIBUTE:
426            case IDL_DT_CS_RLSE_SHADOW:
427                break;
428            case IDL_DT_RANGE:
429                IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr);
430                IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr);
431                break;
432            case IDL_DT_EOL:
433                break;
434            default:
435#ifdef DEBUG_INTERP
436                printf("rpc_ss_ndr_m_struct_cs_shadow:unrecognized type %d\n",
437                        type_byte);
438                exit(0);
439#endif
440                DCETHREAD_RAISE(rpc_x_coding_error);
441        }
442    } while (type_byte != IDL_DT_EOL);
443
444    /* Give the caller the address of the cs-shadow */
445    *p_cs_shadow = cs_shadow;
446}
447
448/*****************************************************************************/
449/*                                                                            */
450/*  Marshall a fixed array of [cs_char] or a [cs_char] which is not in an     */
451/*  array                                                                     */
452/*                                                                            */
453/*****************************************************************************/
454static void rpc_ss_ndr_m_cs_farr_or_single
455(
456    rpc_void_p_t data_addr,             /* [in] Address of array or char */
457    IDL_bound_pair_t *bounds_list,      /* [in] - for array or char treated
458                                                    as array */
459    idl_ulong_int cs_type_defn_index,   /* [in] */
460    idl_ulong_int l_storage_len,        /* [in] number of elements */
461    IDL_msp_t IDL_msp
462)
463{
464    idl_byte *cs_type_defn_ptr;
465    idl_ulong_int routine_index;
466    void (**routine_ptr)();
467    /* Parameters for ..._net_size */
468    idl_cs_convert_t convert_type;
469    /* Parameters for ..._to_netcs */
470    rpc_void_p_t wdata;
471
472    cs_type_defn_ptr = IDL_msp->IDL_type_vec + cs_type_defn_index;
473    IDL_DISCARD_LONG_FROM_VECTOR(cs_type_defn_ptr); /* Size of local type */
474    IDL_GET_LONG_FROM_VECTOR(routine_index, cs_type_defn_ptr);
475    routine_ptr = IDL_msp->IDL_rtn_vec + routine_index;
476
477    /* Call ..._net_size */
478    (*(routine_ptr + IDL_RTN_NET_SIZE_INDEX))(IDL_msp->IDL_h,
479            *(IDL_msp->IDL_cs_tags_p->p_marsh_tag),
480            l_storage_len,
481            &convert_type,
482            NULL,
483            &IDL_msp->IDL_status);
484    if (IDL_msp->IDL_status != error_status_ok)
485        DCETHREAD_RAISE(rpc_x_ss_pipe_comm_error);
486
487    if (convert_type == idl_cs_no_convert)
488    {
489        rpc_ss_ndr_m_fix_or_conf_arr(data_addr, 1, bounds_list,
490                                        cs_type_defn_ptr, 0, IDL_msp);
491    }
492    else
493    {
494        /* Allocate a conversion buffer
495                 - cs_type_defn_ptr now points at network type */
496        wdata = (idl_void_p_t)rpc_ss_mem_alloc(&IDL_msp->IDL_mem_handle,
497                 l_storage_len * rpc_ss_type_size(cs_type_defn_ptr, IDL_msp));
498        /* Call ..._to_netcs */
499        (*(routine_ptr + IDL_RTN_TO_NETCS_INDEX))(IDL_msp->IDL_h,
500                *(IDL_msp->IDL_cs_tags_p->p_marsh_tag),
501                data_addr,
502                l_storage_len,
503                wdata,
504                NULL,
505                &IDL_msp->IDL_status);
506        if (IDL_msp->IDL_status != error_status_ok)
507            DCETHREAD_RAISE(rpc_x_ss_pipe_comm_error);
508        /* Marshall the converted data */
509        rpc_ss_ndr_m_fix_or_conf_arr(wdata, 1, bounds_list,
510                                 cs_type_defn_ptr, IDL_M_DO_NOT_POINT, IDL_msp);
511        /* Release conversion buffer */
512        rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle, (byte_p_t)wdata);
513    }
514}
515
516/*****************************************************************************/
517/*                                                                            */
518/*  Marshall a fixed array of [cs_char]                                       */
519/*                                                                            */
520/*****************************************************************************/
521void rpc_ss_ndr_m_fixed_cs_array
522(
523    rpc_void_p_t array_addr,        /* [in] Address of array */
524    idl_byte **p_defn_vec_ptr,      /* [in] Points at DT_FIXED_ARRAY */
525                                    /* [out] Points after array defn */
526    IDL_msp_t IDL_msp
527)
528{
529    idl_byte *defn_vec_ptr;
530    idl_ulong_int array_defn_index;
531    idl_byte *array_defn_ptr;
532    IDL_bound_pair_t *bounds_list;
533    idl_ulong_int cs_type_defn_index;
534
535    defn_vec_ptr = *p_defn_vec_ptr;
536    defn_vec_ptr += 2;      /* DT_FIXED_ARRAY and properties byte */
537    IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr);    /* Full array definition */
538    IDL_GET_LONG_FROM_VECTOR(array_defn_index, defn_vec_ptr);
539    array_defn_ptr = IDL_msp->IDL_type_vec + array_defn_index;
540    array_defn_ptr++;       /* dimensionality */
541    if (IDL_msp->IDL_type_vec[TVEC_INT_REP_OFFSET] != NDR_LOCAL_INT_REP)
542      rpc_ss_fixed_bounds_from_vector(1, array_defn_ptr, &bounds_list,
543                                        IDL_msp);
544    else
545      bounds_list = (IDL_bound_pair_t *)array_defn_ptr;
546    array_defn_ptr += IDL_FIXED_BOUND_PAIR_WIDTH;
547    /* array_defn_ptr is now pointing to the base type, which has [cs_char] */
548    array_defn_ptr++;       /* IDL_DT_CS_TYPE */
549    IDL_GET_LONG_FROM_VECTOR(cs_type_defn_index, array_defn_ptr);
550
551    rpc_ss_ndr_m_cs_farr_or_single(array_addr, bounds_list, cs_type_defn_index,
552                                bounds_list[0].upper - bounds_list[0].lower + 1,
553                                     IDL_msp);
554
555    *p_defn_vec_ptr = defn_vec_ptr;
556    if (IDL_msp->IDL_type_vec[TVEC_INT_REP_OFFSET] != NDR_LOCAL_INT_REP)
557      rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle, (byte_p_t)bounds_list);
558}
559
560/*****************************************************************************/
561/*                                                                            */
562/*  Marshall a [cs_char] which is not an array element                        */
563/*                                                                            */
564/*****************************************************************************/
565void rpc_ss_ndr_marsh_cs_char
566(
567    rpc_void_p_t char_addr,             /* [in] Address */
568    idl_ulong_int cs_type_defn_index,   /* [in] */
569    IDL_msp_t IDL_msp
570)
571{
572    IDL_bound_pair_t bound_pair;    /* To treat the character as an array */
573
574    bound_pair.upper = 0;
575    bound_pair.lower = 0;
576    rpc_ss_ndr_m_cs_farr_or_single(char_addr, &bound_pair, cs_type_defn_index,
577                                    1, IDL_msp);
578}
579
580/****************************************************************************/
581/*                                                                           */
582/*  Marshall an array of [cs_char]                                           */
583/*                                                                           */
584/****************************************************************************/
585
586void rpc_ss_ndr_marsh_cs_array (
587
588    rpc_void_p_t array_addr,    /* [in] Used only for fixed arrays */
589    IDL_cs_shadow_elt_t *cs_shadow,  /* [in] Address of cs-shadow
590                                            (Not used for fixed arrays) */
591    idl_ulong_int shadow_index, /* [in] Index in cs_shadow of array */
592    idl_boolean in_struct,      /* [in] TRUE => array is structure field */
593    idl_byte **p_defn_vec_ptr,  /* [in] Type following DT_CS_ARRAY
594                                   [out] After array indirection words */
595    IDL_msp_t IDL_msp
596)
597{
598    idl_byte array_type;
599    idl_byte *defn_vec_ptr = 0;
600    idl_ulong_int array_defn_index;
601    idl_byte *array_defn_ptr = 0;
602    IDL_bound_pair_t bound_pair;
603    IDL_bound_pair_t *bounds_list;
604    idl_ulong_int Z_value;
605    IDL_bound_pair_t range_pair;
606    idl_byte ln_type;           /* Data type of [length_is] item */
607    idl_ulong_int ln_index;     /* Index in shadow of [length_is] item */
608    idl_byte sz_type;           /* Data type of [size_is] item */
609    idl_ulong_int sz_index;     /* Index in shadow of [size_is] item */
610    idl_ulong_int cs_type_defn_index;
611    idl_byte *cs_type_defn_ptr = 0 ;
612
613    /* begin */
614
615    array_type = **p_defn_vec_ptr;
616    if (array_type == IDL_DT_FIXED_ARRAY)
617    {
618        rpc_ss_ndr_m_fixed_cs_array(array_addr, p_defn_vec_ptr, IDL_msp);
619        return;
620    }
621
622    defn_vec_ptr = *p_defn_vec_ptr;
623    defn_vec_ptr += 2;      /* Array type and properties byte */
624
625    IDL_DISCARD_LONG_FROM_VECTOR(defn_vec_ptr);    /* Full array definition */
626    IDL_GET_LONG_FROM_VECTOR(array_defn_index, defn_vec_ptr);
627
628    *p_defn_vec_ptr = defn_vec_ptr;
629
630    if (array_type == IDL_DT_ALLOCATE)
631    {
632        /* Nothing to marshall */
633        return;
634    }
635
636    /* Marshall from shadow */
637
638    array_defn_ptr = IDL_msp->IDL_type_vec + array_defn_index;
639    array_defn_ptr++;       /* dimensionality */
640
641    /* Bounds information */
642
643    if (array_type == IDL_DT_VARYING_ARRAY)
644    {
645        if (IDL_msp->IDL_type_vec[TVEC_INT_REP_OFFSET] != NDR_LOCAL_INT_REP)
646            rpc_ss_fixed_bounds_from_vector(1, array_defn_ptr, &bounds_list,
647                                            IDL_msp);
648        else
649            bounds_list = (IDL_bound_pair_t *)array_defn_ptr;
650        array_defn_ptr += IDL_FIXED_BOUND_PAIR_WIDTH;
651    }
652    else    /* Conformant or varying */
653    {
654        bound_pair.lower = 1;       /* Fake the bounds as 1..Z */
655
656        /* Skip over lower bound entirely and upper bound kind */
657
658        array_defn_ptr += IDL_CONF_BOUND_PAIR_WIDTH/2 + 1;
659
660        sz_type = *array_defn_ptr;
661
662        IDL_GET_LONG_FROM_VECTOR(sz_index, array_defn_ptr);
663
664        sz_index--;     /* Shadow has one less elt than param or offset vec */
665
666        bound_pair.upper = rpc_ss_get_typed_integer(sz_type,
667                            (rpc_void_p_t)&cs_shadow[sz_index].IDL_data,
668                            IDL_msp);
669
670        bounds_list = &bound_pair;
671        if ( ! in_struct )
672        {
673            /* Marshall the Z-value */
674            IDL_MARSH_LONG(&bound_pair.upper);
675        }
676    }
677
678    /* Data limit information */
679
680    if ((array_type == IDL_DT_VARYING_ARRAY)
681        || (array_type == IDL_DT_OPEN_ARRAY))
682    {
683        array_defn_ptr++;       /* We know the lower data limit is fixed */
684        IDL_GET_LONG_FROM_VECTOR(range_pair.lower, array_defn_ptr);
685        array_defn_ptr++;       /* We know upper data limit is [length_is] */
686        ln_type = *array_defn_ptr;  /* A */
687        IDL_GET_LONG_FROM_VECTOR(ln_index, array_defn_ptr);
688        ln_index--;     /* Shadow has one less elt than param or offset vec */
689        range_pair.upper = rpc_ss_get_typed_integer(ln_type,
690                            (rpc_void_p_t)&cs_shadow[ln_index].IDL_data,
691                            IDL_msp);   /* B */
692        range_pair.upper += range_pair.lower;   /* A + B */
693    }
694
695    /* array_defn_ptr is now pointing to the base type, which has [cs_char] */
696
697    array_defn_ptr++;       /* IDL_DT_CS_TYPE */
698
699    IDL_GET_LONG_FROM_VECTOR(cs_type_defn_index, array_defn_ptr);
700
701    cs_type_defn_ptr = IDL_msp->IDL_type_vec + cs_type_defn_index;
702
703    IDL_DISCARD_LONG_FROM_VECTOR(cs_type_defn_ptr); /* Size of local type */
704    IDL_DISCARD_LONG_FROM_VECTOR(cs_type_defn_ptr); /* Routine index */
705
706    /* Now pointing at network type definition */
707
708    /* Marshall the data */
709
710    if (array_type == IDL_DT_CONF_ARRAY)
711    {
712        rpc_ss_ndr_m_fix_or_conf_arr(
713                                cs_shadow[shadow_index].IDL_data.IDL_storage_p,
714                                1, bounds_list, cs_type_defn_ptr,
715                                IDL_M_DO_NOT_POINT, IDL_msp);
716    }
717    else
718    {
719        Z_value = bounds_list[0].upper - bounds_list[0].lower + 1;
720        rpc_ss_ndr_m_var_or_open_arr(
721                                cs_shadow[shadow_index].IDL_data.IDL_storage_p,
722                                &Z_value, 1, &range_pair,
723                                cs_type_defn_ptr, IDL_M_DO_NOT_POINT, IDL_msp);
724    }
725
726    if (IDL_msp->IDL_type_vec[TVEC_INT_REP_OFFSET] != NDR_LOCAL_INT_REP)
727      if (array_type == IDL_DT_VARYING_ARRAY)
728        rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle, (byte_p_t)bounds_list);
729
730    return ;
731}
732
733/*****************************************************************************/
734/*                                                                            */
735/*  Release translation buffers pointed to by a cs_shadow, then release the   */
736/*  shadow                                                                    */
737/*                                                                            */
738/*****************************************************************************/
739void rpc_ss_ndr_m_rlse_cs_shadow
740(
741    IDL_cs_shadow_elt_t *cs_shadow,  /* [in] Address of cs-shadow */
742    idl_ulong_int shadow_length,     /* [in] Number of structure fields */
743    IDL_msp_t IDL_msp
744)
745{
746    unsigned32 i;
747
748    for (i=0; i<shadow_length; i++)
749    {
750        if (cs_shadow[i].IDL_release)
751        {
752            rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle,
753                                 (byte_p_t)cs_shadow[i].IDL_data.IDL_storage_p);
754        }
755    }
756    rpc_ss_mem_item_free(&IDL_msp->IDL_mem_handle, (byte_p_t)cs_shadow);
757}
758
759/*****************************************************************************/
760/*                                                                           */
761/* Build a cs-shadow for marshalling a parameter list                        */
762/*                                                                           */
763/*****************************************************************************/
764
765void rpc_ss_ndr_m_param_cs_shadow
766(
767    idl_byte *type_vec_ptr,     /* [in] After shadow length */
768    idl_ulong_int param_index,  /* [in] Index for first parameter */
769                                /* Later used for index of current parameter */
770    idl_ulong_int shadow_length,    /* [in] Size of cs-shadow */
771    IDL_cs_shadow_elt_t **p_cs_shadow,  /* [out] Address of cs-shadow */
772    IDL_msp_t IDL_msp
773)
774{
775    idl_byte type_byte;
776    IDL_cs_shadow_elt_t *cs_shadow;
777    unsigned32 i;
778
779    /* Allocate the cs-shadow */
780    cs_shadow = (IDL_cs_shadow_elt_t *)rpc_ss_mem_alloc
781                    (&IDL_msp->IDL_mem_handle, shadow_length
782                                                 * sizeof(IDL_cs_shadow_elt_t));
783    /* Initialize its "release" fields */
784    for (i=0; i<shadow_length; i++)
785        cs_shadow[i].IDL_release = idl_false;
786
787    /* Loop over parameters. Exit when DT_RLSE_SHADOW encountered */
788    for (i = 0; ; i++)
789    {
790        if (i != 0)
791        {
792            /* On entry we already have the parameter index the DT_CS_SHADOW
793                was attached to */
794            IDL_GET_LONG_FROM_VECTOR(param_index,type_vec_ptr);
795        }
796        do {
797            type_byte = *type_vec_ptr;
798            type_vec_ptr++;
799            switch(type_byte)
800            {
801                case IDL_DT_CS_ARRAY:
802                    rpc_ss_ndr_m_array_shadow(NULL, NULL, NULL,  cs_shadow,
803                            param_index - 1, &type_vec_ptr, IDL_msp);
804                    break;
805                /* For parameters that are not array of [cs_char],
806                 advance the definition pointer.
807                 And note they have no translation storage */
808                case IDL_DT_BYTE:
809                case IDL_DT_CHAR:
810                case IDL_DT_BOOLEAN:
811                case IDL_DT_DOUBLE:
812                case IDL_DT_ENUM:
813                case IDL_DT_FLOAT:
814                case IDL_DT_SMALL:
815                case IDL_DT_SHORT:
816                case IDL_DT_LONG:
817                case IDL_DT_HYPER:
818                case IDL_DT_USMALL:
819                case IDL_DT_USHORT:
820                case IDL_DT_ULONG:
821                case IDL_DT_UHYPER:
822                case IDL_DT_IGNORE:
823                case IDL_DT_V1_ENUM:
824                case IDL_DT_ERROR_STATUS:
825                case IDL_DT_IN_CONTEXT:
826                case IDL_DT_IN_OUT_CONTEXT:
827                case IDL_DT_OUT_CONTEXT:
828                    break;
829                case IDL_DT_FIXED_ARRAY:
830                case IDL_DT_VARYING_ARRAY:
831                case IDL_DT_CONF_ARRAY:
832                case IDL_DT_OPEN_ARRAY:
833                    /* Properties byte */
834                    type_vec_ptr++;
835                    IDL_DISCARD_LONG_FROM_VECTOR(type_vec_ptr);
836                                                    /* Full array definition */
837                    IDL_DISCARD_LONG_FROM_VECTOR(type_vec_ptr);
838                                                /* Flattened array definition */
839                    break;
840                case IDL_DT_FIXED_STRUCT:
841                case IDL_DT_CONF_STRUCT:
842                case IDL_DT_V1_CONF_STRUCT:
843                case IDL_DT_ENC_UNION:
844                case IDL_DT_N_E_UNION:
845                case IDL_DT_FULL_PTR:
846                case IDL_DT_UNIQUE_PTR:
847                case IDL_DT_REF_PTR:
848                case IDL_DT_TRANSMIT_AS:
849                case IDL_DT_REPRESENT_AS:
850                case IDL_DT_PIPE:
851                case IDL_DT_CS_TYPE:
852                    /* Properties byte */
853                    type_vec_ptr++;
854                    IDL_DISCARD_LONG_FROM_VECTOR(type_vec_ptr);
855                    break;
856                case IDL_DT_ALLOCATE_REF:
857                    rpc_ss_discard_allocate_ref(&type_vec_ptr);
858                    break;
859                case IDL_DT_FREE_REP:
860                    IDL_DISCARD_LONG_FROM_VECTOR(type_vec_ptr);
861                    break;
862                case IDL_DT_PASSED_BY_REF:
863                case IDL_DT_STRING:
864                case IDL_DT_ALLOCATE:
865                case IDL_DT_V1_ARRAY:
866                case IDL_DT_V1_STRING:
867                case IDL_DT_DELETED_NODES:
868                case IDL_DT_CS_ATTRIBUTE:
869                case IDL_DT_EOL:
870                    break;
871                case IDL_DT_RANGE:
872                    IDL_DISCARD_LONG_FROM_VECTOR(type_vec_ptr);
873                    IDL_DISCARD_LONG_FROM_VECTOR(type_vec_ptr);
874                    break;
875                case IDL_DT_CS_RLSE_SHADOW:
876                    *p_cs_shadow = cs_shadow;
877                    return;
878                default:
879#ifdef DEBUG_INTERP
880                    printf("rpc_ss_ndr_m_param_cs_shadow:unrecognized type %d\n",
881                                type_byte);
882                    exit(0);
883#endif
884                    DCETHREAD_RAISE(rpc_x_coding_error);
885            }
886        } while (type_byte != IDL_DT_EOL);
887    }
888}
889
890/*****************************************************************************/
891/*                                                                           */
892/*  Build the bounds list for a structure with a conformant [cs_char] array  */
893/*  field                                                                    */
894/*                                                                           */
895/*****************************************************************************/
896void rpc_ss_conf_struct_cs_bounds
897(
898    idl_byte *defn_vec_ptr,     /* [in] Points at bounds info*/
899    IDL_cs_shadow_elt_t *cs_shadow,  /* [in] Address of cs-shadow*/
900    IDL_bound_pair_t *bounds_list,   /* [out]*/
901    IDL_msp_t IDL_msp
902)
903{
904    idl_byte sz_type;           /* Data type of [size_is] item*/
905    idl_ulong_int sz_index;     /* Index in shadow of [size_is] item*/
906
907    bounds_list[0].lower = 1;       /* Fake the bounds as 1..Z*/
908    /* Skip over lower bound entirely and upper bound kind*/
909    defn_vec_ptr += IDL_CONF_BOUND_PAIR_WIDTH/2 + 1;
910    sz_type = *defn_vec_ptr;
911    IDL_GET_LONG_FROM_VECTOR(sz_index, defn_vec_ptr);
912    sz_index--;     /* Shadow has one less elt than offset vec*/
913    bounds_list[0].upper = rpc_ss_get_typed_integer(sz_type,
914                            (rpc_void_p_t)&cs_shadow[sz_index].IDL_data,
915                            IDL_msp);
916}
917