~ubuntu-branches/ubuntu/breezy/orbit2/breezy

« back to all changes in this revision

Viewing changes to src/idl-compiler/orbit-idl-c-demarshal.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher
  • Date: 2005-09-06 16:37:02 UTC
  • mfrom: (1.2.1 upstream) (2.1.1 sarge)
  • Revision ID: james.westby@ubuntu.com-20050906163702-hrqi0ctymth53bnn
Tags: 1:2.12.4-0ubuntu1
* New upstream version.
* debian/patches/100-compile-name-server.patch:
  - updated.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#include "config.h"
2
 
 
3
 
#include <string.h>
4
 
 
5
 
#include "orbit-idl-c-backend.h"
6
 
 
7
 
static void c_demarshal_generate(OIDL_Marshal_Node *node, OIDL_C_Marshal_Info *cmi);
8
 
static void c_demarshal_datum(OIDL_Marshal_Node *node, OIDL_C_Marshal_Info *cmi);
9
 
static void c_demarshal_loop(OIDL_Marshal_Node *node, OIDL_C_Marshal_Info *cmi);
10
 
static void c_demarshal_switch(OIDL_Marshal_Node *node, OIDL_C_Marshal_Info *cmi);
11
 
static void c_demarshal_complex(OIDL_Marshal_Node *node, OIDL_C_Marshal_Info *cmi);
12
 
static void c_demarshal_set(OIDL_Marshal_Node *node, OIDL_C_Marshal_Info *cmi);
13
 
static void c_demarshal_validate_curptr(OIDL_Marshal_Node *node, OIDL_C_Marshal_Info *cmi);
14
 
static void c_demarshal_alignfor(OIDL_Marshal_Node *node, OIDL_C_Marshal_Info *cmi);
15
 
static void c_demarshal_generate_alloc(OIDL_Marshal_Node *node, OIDL_C_Marshal_Info *cmi);
16
 
static void c_demarshal_generate_check(OIDL_Marshal_Length *len, OIDL_C_Marshal_Info *cmi);
17
 
 
18
 
 
19
 
void
20
 
c_demarshalling_generate(OIDL_Marshal_Node *node, OIDL_C_Info *ci, gboolean in_skels, gboolean subfunc)
21
 
{
22
 
  OIDL_C_Marshal_Info cmi;
23
 
 
24
 
  cmi.ci = ci;
25
 
  cmi.last_tail_align = 1;
26
 
  cmi.endian_swap_pass = TRUE;
27
 
  cmi.in_skels = in_skels?1:0;
28
 
  cmi.subfunc = subfunc;
29
 
 
30
 
  cmi.marshal_error_exit = "goto _ORBIT_demarshal_error";
31
 
  cmi.curptr_in_local = FALSE;
32
 
  cmi.alloc_on_stack = in_skels;
33
 
  if(in_skels)
34
 
    cmi.orb_name = "ORBIT_SERVANT_TO_ORB(_ORBIT_servant)";
35
 
  else
36
 
    cmi.orb_name = "_ORBIT_recv_buffer->connection->orb_data";
37
 
 
38
 
  if(node->flags & MN_ENDIAN_DEPENDANT)
39
 
    {
40
 
      gboolean start_in_local;
41
 
      OIDL_Marshal_Length *len;
42
 
 
43
 
      len = node->pre;
44
 
      c_demarshal_validate_curptr(node, &cmi);
45
 
      start_in_local = cmi.curptr_in_local;
46
 
      c_demarshal_alignfor(node, &cmi);
47
 
      cmi.last_tail_align = node->iiop_head_align; /* We already did the alignment outside of the 'if' */
48
 
      if(len)
49
 
        {
50
 
          c_demarshal_generate_check(len, &cmi);
51
 
          node->pre = NULL;
52
 
        }
53
 
 
54
 
      fprintf(ci->fh, "if(giop_msg_conversion_needed(_ORBIT_recv_buffer)) {\n");
55
 
      c_demarshal_generate(node, &cmi);
56
 
      fprintf(ci->fh, "} else {\n");
57
 
      cmi.last_tail_align = node->iiop_head_align; /* We already did the alignment outside of the 'if' */
58
 
      cmi.endian_swap_pass = FALSE;
59
 
      cmi.curptr_in_local = start_in_local;
60
 
      c_demarshal_generate(node, &cmi);
61
 
      fprintf(ci->fh, "}\n");
62
 
      node->pre = len;
63
 
    }
64
 
  else
65
 
    {
66
 
      cmi.last_tail_align = 1;
67
 
      cmi.endian_swap_pass = FALSE;
68
 
      cmi.curptr_in_local = FALSE;
69
 
      c_demarshal_generate(node, &cmi);
70
 
    }
71
 
}
72
 
 
73
 
static void
74
 
c_demarshal_generate_heap_alloc(OIDL_Marshal_Node *node, OIDL_C_Marshal_Info *cmi)
75
 
{
76
 
  char *ctmp, *ctmp2;
77
 
 
78
 
  if(!(node->flags & MN_ISSTRING)) /* Strings get handled specially */
79
 
    {
80
 
      g_assert(node->nptrs > 0);
81
 
 
82
 
      ctmp2 = orbit_cbe_get_typespec_str(node->tree);
83
 
      node->nptrs--;
84
 
      ctmp = oidl_marshal_node_valuestr(node);
85
 
      node->nptrs++;
86
 
      fprintf(cmi->ci->fh, "%s = %s__alloc();\n", ctmp, ctmp2);
87
 
    }
88
 
 
89
 
}
90
 
 
91
 
static void
92
 
c_demarshal_generate_alloca_alloc(OIDL_Marshal_Node *node, OIDL_C_Marshal_Info *cmi)
93
 
{
94
 
  char *ctmp, *ctmp2;
95
 
 
96
 
  if(!(node->flags & MN_ISSTRING))
97
 
    {
98
 
      g_assert(node->nptrs > 0);
99
 
 
100
 
      ctmp2 = orbit_cbe_get_typespec_str(node->tree);
101
 
      node->nptrs--;
102
 
      ctmp = oidl_marshal_node_valuestr(node);
103
 
      node->nptrs++;
104
 
      fprintf(cmi->ci->fh, "%s = g_alloca(sizeof(%s));\n", ctmp, ctmp2);
105
 
    }
106
 
}
107
 
 
108
 
static void
109
 
c_demarshal_generate_alloc(OIDL_Marshal_Node *node, OIDL_C_Marshal_Info *cmi)
110
 
{
111
 
  if(!node->name)
112
 
    return;
113
 
 
114
 
  switch(node->where)
115
 
    {
116
 
    case MW_Heap:
117
 
      c_demarshal_generate_heap_alloc(node, cmi);
118
 
      break;
119
 
    case MW_Alloca:
120
 
      c_demarshal_generate_alloca_alloc(node, cmi);
121
 
      break;
122
 
    default:
123
 
      break;
124
 
    }
125
 
}
126
 
 
127
 
static void
128
 
c_demarshal_generate_check(OIDL_Marshal_Length *len, OIDL_C_Marshal_Info *cmi)
129
 
{
130
 
  char *curptr_name;
131
 
  char len_str[1024];
132
 
  gboolean is_const = TRUE;
133
 
 
134
 
  if(!len)
135
 
    return;
136
 
 
137
 
  if(len->mult_expr)
138
 
    {
139
 
      char *fqn = oidl_marshal_node_valuestr(len->mult_expr);
140
 
 
141
 
      is_const = FALSE;
142
 
      g_snprintf(len_str, sizeof(len_str), "%d + %s*%s", len->len, len->mult_const, fqn);
143
 
      g_free(fqn);
144
 
    }
145
 
  else
146
 
    g_snprintf(len_str, sizeof(len_str), "%d", len->len);
147
 
  curptr_name = cmi->curptr_in_local?"_ORBIT_curptr":"_ORBIT_recv_buffer->cur";
148
 
  fprintf(cmi->ci->fh, "{\nregister const long _ORBIT_checklen = %s;\n", len_str);
149
 
  if(is_const)
150
 
    fprintf(cmi->ci->fh, "if((%s + %s) > _ORBIT_buf_end)\n",
151
 
            curptr_name, "_ORBIT_checklen");
152
 
  else
153
 
    fprintf(cmi->ci->fh, "if((%s + %s) < %s || (%s + %s) > _ORBIT_buf_end)\n", curptr_name, "_ORBIT_checklen", curptr_name,
154
 
            curptr_name, "_ORBIT_checklen");
155
 
  fprintf(cmi->ci->fh, "%s;\n", cmi->marshal_error_exit);
156
 
  fprintf(cmi->ci->fh, "}\n");
157
 
}
158
 
 
159
 
static void
160
 
c_demarshal_generate(OIDL_Marshal_Node *node, OIDL_C_Marshal_Info *cmi)
161
 
{
162
 
  if(!node) return;
163
 
 
164
 
  if(node->flags & MN_NOMARSHAL) return;
165
 
  if(node->use_count) return;
166
 
 
167
 
  node->use_count++;
168
 
 
169
 
  if(!cmi->curptr_in_local && node->flags & MN_NEED_CURPTR_LOCAL)
170
 
    c_demarshal_validate_curptr(node, cmi); /* Help out c_demarshal_generate_check, which will prefer to use the local var */
171
 
 
172
 
  c_demarshal_generate_check(node->pre, cmi);
173
 
 
174
 
  /* This needs to be done _after_ generate_check because we don't
175
 
     want to free the data for a parameter if it cannot possibly be
176
 
     demarshalled - the marshal_error_exit label points to stuff that
177
 
     knows how to free the demarshalled version of that parameter */
178
 
  if(node->marshal_error_exit)
179
 
    cmi->marshal_error_exit = node->marshal_error_exit;
180
 
 
181
 
  if(node->flags & MN_TOPLEVEL)
182
 
    c_demarshal_generate_alloc(node, cmi);
183
 
 
184
 
  c_demarshal_validate_curptr(node, cmi);
185
 
 
186
 
  switch(node->type) {
187
 
  case MARSHAL_DATUM:
188
 
    c_demarshal_datum(node, cmi);
189
 
    break;
190
 
  case MARSHAL_LOOP:
191
 
    c_demarshal_loop(node, cmi);
192
 
    break;
193
 
  case MARSHAL_SWITCH:
194
 
    c_demarshal_switch(node, cmi);
195
 
    break;
196
 
  case MARSHAL_COMPLEX:
197
 
    c_demarshal_complex(node, cmi);
198
 
    break;
199
 
  case MARSHAL_SET:
200
 
    c_demarshal_set(node, cmi);
201
 
    break;
202
 
  default:
203
 
    g_assert_not_reached();
204
 
    break;
205
 
  }
206
 
 
207
 
  c_demarshal_generate_check(node->post, cmi);
208
 
 
209
 
  node->use_count--;
210
 
}
211
 
 
212
 
static void
213
 
c_demarshal_update_curptr(OIDL_Marshal_Node *node, char *sizestr, OIDL_C_Marshal_Info *cmi)
214
 
{
215
 
  if((node->flags & MN_DEMARSHAL_UPDATE_AFTER)
216
 
     || (node->flags & MN_LOOPED))
217
 
    fprintf(cmi->ci->fh, "_ORBIT_curptr += %s;\n", sizestr);
218
 
}
219
 
 
220
 
static void
221
 
c_demarshal_validate_curptr(OIDL_Marshal_Node *node, OIDL_C_Marshal_Info *cmi)
222
 
{
223
 
  gboolean desired_curptr_in_local_state;
224
 
 
225
 
  if(node->flags & MN_NEED_CURPTR_LOCAL)
226
 
    desired_curptr_in_local_state = TRUE;
227
 
  else if(node->flags & MN_NEED_CURPTR_RECVBUF)
228
 
    desired_curptr_in_local_state = FALSE;
229
 
  else
230
 
    return;
231
 
 
232
 
  if(desired_curptr_in_local_state != cmi->curptr_in_local)
233
 
    {
234
 
      if(desired_curptr_in_local_state)
235
 
        fprintf(cmi->ci->fh, "_ORBIT_curptr = _ORBIT_recv_buffer->cur;\n");
236
 
      else
237
 
        fprintf(cmi->ci->fh, "_ORBIT_recv_buffer->cur = _ORBIT_curptr;\n");
238
 
 
239
 
      cmi->curptr_in_local = desired_curptr_in_local_state;
240
 
    }
241
 
}
242
 
 
243
 
static void
244
 
c_demarshal_alignfor(OIDL_Marshal_Node *node, OIDL_C_Marshal_Info *cmi)
245
 
{
246
 
  /* do we need to generate an alignment space? */
247
 
  if(node->iiop_head_align > cmi->last_tail_align)
248
 
    {
249
 
      fprintf(cmi->ci->fh, "%s = ALIGN_ADDRESS(_ORBIT_curptr, %d);\n",
250
 
              cmi->curptr_in_local?"_ORBIT_curptr":"_ORBIT_recv_buffer->cur",
251
 
              node->iiop_head_align);
252
 
    }
253
 
 
254
 
  cmi->last_tail_align = node->iiop_tail_align;
255
 
}
256
 
 
257
 
static void
258
 
c_demarshal_datum(OIDL_Marshal_Node *node, OIDL_C_Marshal_Info *cmi)
259
 
{
260
 
  char *ctmp;
261
 
 
262
 
  ctmp = oidl_marshal_node_valuestr(node);
263
 
 
264
 
  c_demarshal_alignfor(node, cmi);
265
 
 
266
 
  if(cmi->endian_swap_pass
267
 
     && (node->flags & MN_ENDIAN_DEPENDANT)) {
268
 
    int n;
269
 
 
270
 
    n = node->u.datum_info.datum_size * 8;
271
 
 
272
 
    if(node->u.datum_info.needs_bswap)
273
 
      fprintf(cmi->ci->fh, "giop_byteswap((guchar *)&(%s), _ORBIT_curptr, %d);\n", ctmp, node->u.datum_info.datum_size);
274
 
    else {
275
 
      fprintf(cmi->ci->fh, "(*((guint%d *)&(%s))) = ", n, ctmp);
276
 
      fprintf(cmi->ci->fh, "GUINT%d_SWAP_LE_BE(*((guint%d *)_ORBIT_curptr));\n",
277
 
              n, n);
278
 
    }
279
 
  } else {
280
 
    fprintf(cmi->ci->fh, "%s = *((", ctmp);
281
 
    orbit_cbe_write_node_typespec(cmi->ci->fh, node);
282
 
    fprintf(cmi->ci->fh, "*)_ORBIT_curptr);\n");
283
 
  }
284
 
 
285
 
  {
286
 
    char buf[32];
287
 
    g_snprintf(buf, sizeof(buf), "%d", node->u.datum_info.datum_size);
288
 
    c_demarshal_update_curptr(node, buf, cmi);
289
 
  }
290
 
 
291
 
  g_free(ctmp);
292
 
}
293
 
 
294
 
/**
295
 
    LOOP is the (de)marshalling equivalent of IDL sequence, array, string,
296
 
    and wstring.  In all cases, there is a single underlying type ("subtype").
297
 
    Here, we are generating code which demarshals from a variable
298
 
    of a given type, which consists of elements of the type's subtype.
299
 
    There are 3 issues:
300
 
    - Where is the memory allocated?
301
 
    - Does the variable data need to be munged, either for endianness,
302
 
      format or alignment reasons?
303
 
    - Can the elements be agregated?
304
 
    All of these questions interact with each other.
305
 
**/
306
 
static void
307
 
c_demarshal_loop(OIDL_Marshal_Node *node, OIDL_C_Marshal_Info *cmi)
308
 
{
309
 
  char *ctmp, *ctmp_len, *ctmp_loop, *ctmp_contents;
310
 
  gboolean loopvar_set = FALSE;
311
 
 
312
 
  ctmp = oidl_marshal_node_valuestr(node);
313
 
  ctmp_loop = oidl_marshal_node_valuestr(node->u.loop_info.loop_var);
314
 
  ctmp_len = oidl_marshal_node_valuestr(node->u.loop_info.length_var);
315
 
  ctmp_contents = oidl_marshal_node_valuestr(node->u.loop_info.contents);
316
 
 
317
 
  c_demarshal_generate(node->u.loop_info.length_var, cmi);
318
 
  if(node->flags & MN_WIDESTRING)
319
 
    fprintf(cmi->ci->fh, "%s /= sizeof(CORBA_wchar);\n", ctmp_len);
320
 
 
321
 
  if(cmi->alloc_on_stack && (node->u.loop_info.contents->where == MW_Alloca)) {
322
 
    fprintf(cmi->ci->fh, "%s%s = g_alloca(sizeof(%s) * (%s%s));\n", ctmp, (node->flags & MN_ISSEQ)?"._buffer":"",
323
 
            ctmp_contents, ctmp_len, (node->flags & MN_WIDESTRING)?"+1":"");
324
 
    if(node->flags & MN_ISSEQ)
325
 
      fprintf(cmi->ci->fh, "%s._release = CORBA_FALSE;\n", ctmp);
326
 
  } else if(node->u.loop_info.contents->where == MW_Msg
327
 
            || node->where == MW_Null) {
328
 
    /* No allocation necessary */
329
 
  } else if(node->u.loop_info.contents->where == MW_Heap) {
330
 
    char *tname, *tcname;
331
 
    
332
 
    tname = orbit_cbe_get_typespec_str(node->tree);
333
 
    tcname = orbit_cbe_get_typespec_str(node->u.loop_info.contents->tree);
334
 
 
335
 
    if(node->flags & MN_ISSEQ) {
336
 
      IDL_tree seq = orbit_cbe_get_typespec(node->tree);
337
 
      if(orbit_cbe_type_is_builtin(node->u.loop_info.contents->tree))
338
 
        fprintf(cmi->ci->fh, "%s._buffer = CORBA_sequence_%s_allocbuf(%s);\n", ctmp, tcname+strlen("CORBA_"), ctmp_len);
339
 
      else {
340
 
        if(IDL_TYPE_SEQUENCE(seq).positive_int_const) {
341
 
          /* bounded */
342
 
          fprintf(cmi->ci->fh,"%s._maximum = ",ctmp);
343
 
          orbit_cbe_write_const(cmi->ci->fh, IDL_TYPE_SEQUENCE(seq).positive_int_const);
344
 
          fprintf(cmi->ci->fh,";\n");
345
 
          fprintf(cmi->ci->fh, "%s._buffer = CORBA_sequence_%s_allocbuf(%s._maximum);\n", ctmp, tcname, ctmp);
346
 
        } else {
347
 
          /* unbounded */
348
 
          fprintf(cmi->ci->fh, "%s._maximum = %s._length;\n",ctmp,ctmp);
349
 
          fprintf(cmi->ci->fh, "%s._buffer = CORBA_sequence_%s_allocbuf(%s);\n", ctmp, tcname, ctmp_len);
350
 
        }
351
 
      }
352
 
      fprintf(cmi->ci->fh, "%s._release = CORBA_TRUE;\n", ctmp);
353
 
    } else if(node->flags & MN_ISSTRING)
354
 
      fprintf(cmi->ci->fh, "%s = CORBA_%sstring_alloc(%s%s);\n", ctmp, (node->flags & MN_WIDESTRING)?"w":"",
355
 
              ctmp_len,
356
 
              (node->flags & MN_WIDESTRING)?"+1":"");
357
 
    g_free(tcname);
358
 
    g_free(tname);
359
 
  } else
360
 
    g_error("Don't know how to allocate node %p", node);
361
 
 
362
 
  if((!cmi->endian_swap_pass || !(node->u.loop_info.contents->flags & MN_ENDIAN_DEPENDANT))
363
 
     && (node->u.loop_info.contents->flags & MN_COALESCABLE)) {
364
 
    GString *tmpstr, *tmpstr2;
365
 
 
366
 
    c_demarshal_alignfor(node->u.loop_info.contents, cmi);
367
 
 
368
 
    tmpstr = g_string_new(NULL);
369
 
    tmpstr2 = g_string_new(NULL);
370
 
    g_string_printf(tmpstr, "sizeof(%s) * %s", ctmp_contents, ctmp_len);
371
 
    /* XXX badhack - what if 'node' is a pointer thingie? Need to find out whether to append '._buffer' or '->_buffer' */
372
 
    g_string_printf(tmpstr2, "%s%s", ctmp, (node->flags & MN_ISSEQ)?"._buffer":"");
373
 
 
374
 
    if(cmi->alloc_on_stack && (node->u.loop_info.contents->where & MW_Msg))
375
 
      {
376
 
        fprintf(cmi->ci->fh, "*(((gulong*)_ORBIT_curptr)-1) = ORBIT_MEMHOW_NONE;\n");
377
 
        fprintf(cmi->ci->fh, "%s = (", tmpstr2->str);
378
 
        orbit_cbe_write_typespec(cmi->ci->fh, node->u.loop_info.contents->tree);
379
 
        fprintf(cmi->ci->fh, "*)_ORBIT_curptr;\n");
380
 
      }
381
 
    else
382
 
      fprintf(cmi->ci->fh, "memcpy(%s, _ORBIT_curptr, %s);\n", tmpstr2->str, tmpstr->str);
383
 
 
384
 
    c_demarshal_update_curptr(node, tmpstr->str, cmi);
385
 
 
386
 
    g_string_free(tmpstr2, TRUE);
387
 
    g_string_free(tmpstr, TRUE);
388
 
  } else {
389
 
    cmi->last_tail_align = MIN(cmi->last_tail_align, node->u.loop_info.contents->iiop_tail_align);
390
 
    c_demarshal_validate_curptr(node->u.loop_info.contents, cmi); /* We must explicitly do this here,
391
 
                                                                     otherwise bad things will happen -
392
 
                                                                     it will keep updating local from recvbuf or vice versa,
393
 
                                                                     inside the loop, and that is Very Bad(tm) */
394
 
    fprintf(cmi->ci->fh, "for(%s = 0; %s < %s; %s++) {\n", ctmp_loop, ctmp_loop, ctmp_len, ctmp_loop);
395
 
    /* XXX: what does the next line (loop_var) do? Anything useful? */
396
 
    /* c_demarshal_generate(node->u.loop_info.loop_var, cmi); */
397
 
    g_assert(node->u.loop_info.loop_var->flags & MN_NOMARSHAL);
398
 
    /* this next line does the element-by-element work! */
399
 
    c_demarshal_generate(node->u.loop_info.contents, cmi);
400
 
    fprintf(cmi->ci->fh, "}\n\n");
401
 
    loopvar_set = TRUE;
402
 
  }
403
 
  if(node->flags & MN_WIDESTRING)
404
 
    {
405
 
      /* NUL-terminate it */
406
 
      if(!loopvar_set)
407
 
        fprintf(cmi->ci->fh, "%s = %s;\n", ctmp_loop, ctmp_len);
408
 
      fprintf(cmi->ci->fh, "%s = 0;\n", ctmp_contents);
409
 
    }
410
 
 
411
 
  g_free(ctmp_contents);
412
 
  g_free(ctmp_len);
413
 
  g_free(ctmp_loop);
414
 
  g_free(ctmp);
415
 
}
416
 
 
417
 
static void
418
 
c_demarshal_switch(OIDL_Marshal_Node *node, OIDL_C_Marshal_Info *cmi)
419
 
{
420
 
  char *ctmp;
421
 
  GSList *ltmp;
422
 
  guint8 last_tail_align;
423
 
  gboolean need_default;
424
 
 
425
 
  c_demarshal_generate(node->u.switch_info.discrim, cmi);
426
 
 
427
 
  last_tail_align = cmi->last_tail_align;
428
 
 
429
 
  ctmp = oidl_marshal_node_valuestr(node->u.switch_info.discrim);
430
 
  fprintf(cmi->ci->fh, "switch(%s) {\n", ctmp);
431
 
  g_free(ctmp);
432
 
 
433
 
  need_default = TRUE;
434
 
  for(ltmp = node->u.switch_info.cases; ltmp; ltmp = g_slist_next(ltmp)) {
435
 
    GSList *ltmp2;
436
 
    OIDL_Marshal_Node *sub;
437
 
 
438
 
    cmi->last_tail_align = last_tail_align;
439
 
 
440
 
    sub = ltmp->data;
441
 
    g_assert(sub->type == MARSHAL_CASE);
442
 
    if(sub->u.case_info.labels) {
443
 
      for(ltmp2 = sub->u.case_info.labels; ltmp2; ltmp2 = g_slist_next(ltmp2)) {
444
 
        if(ltmp2->data) {
445
 
          fprintf(cmi->ci->fh, "case ");
446
 
          orbit_cbe_write_const_node(cmi->ci->fh, ltmp2->data);
447
 
          fprintf(cmi->ci->fh, ":\n");
448
 
        } else {
449
 
          fprintf(cmi->ci->fh, "default:\n");
450
 
          need_default = FALSE;
451
 
        }
452
 
      }
453
 
    } else {
454
 
      fprintf(cmi->ci->fh, "default:\n");
455
 
      need_default = FALSE;
456
 
    }
457
 
    c_demarshal_generate(sub->u.case_info.contents, cmi);
458
 
    fprintf(cmi->ci->fh, "break;\n");
459
 
  }
460
 
  if(need_default) {
461
 
    fprintf(cmi->ci->fh, "default:\nbreak;\n");
462
 
  }
463
 
  fprintf(cmi->ci->fh, "}\n");
464
 
 
465
 
  cmi->last_tail_align = node->iiop_tail_align;
466
 
}
467
 
 
468
 
static void
469
 
c_demarshal_complex(OIDL_Marshal_Node *node, OIDL_C_Marshal_Info *cmi)
470
 
{
471
 
  char *ctmp;
472
 
  const char *do_dup;
473
 
 
474
 
  ctmp = oidl_marshal_node_valuestr(node);
475
 
 
476
 
  if(cmi->subfunc)
477
 
    do_dup = "do_dup";
478
 
  else
479
 
    do_dup = (cmi->alloc_on_stack && (node->where & (MW_Alloca|MW_Msg)))?"CORBA_FALSE":"CORBA_TRUE";
480
 
 
481
 
  switch(node->u.complex_info.type) {
482
 
  case CX_CORBA_FIXED:
483
 
    g_error("Don't know how to demarshal a CORBA_fixed yet.");
484
 
    break;
485
 
  case CX_CORBA_ANY:
486
 
    fprintf(cmi->ci->fh, "if(ORBit_demarshal_any(_ORBIT_recv_buffer, &(%s), %s, %s))\n%s;\n",
487
 
            ctmp, do_dup, cmi->orb_name, cmi->marshal_error_exit);
488
 
    break;
489
 
  case CX_CORBA_OBJECT:
490
 
    fprintf(cmi->ci->fh, "if(ORBit_demarshal_object(&(%s), _ORBIT_recv_buffer, %s))\n%s;\n",
491
 
            ctmp, cmi->orb_name, cmi->marshal_error_exit);
492
 
    break;
493
 
  case CX_CORBA_TYPECODE:
494
 
    fprintf(cmi->ci->fh, "if(ORBit_decode_CORBA_TypeCode(&%s, _ORBIT_recv_buffer))\n%s;\n", ctmp,
495
 
            cmi->marshal_error_exit);
496
 
    break;
497
 
  case CX_CORBA_CONTEXT:
498
 
    if(cmi->in_skels)
499
 
      fprintf(cmi->ci->fh, "if(ORBit_Context_demarshal(NULL, &_ctx, _ORBIT_recv_buffer))\n%s;\n",
500
 
              cmi->marshal_error_exit);
501
 
    break;
502
 
  case CX_NATIVE:
503
 
    g_error("Don't know how to demarshal a NATIVE yet.");
504
 
    break;
505
 
  case CX_MARSHAL_METHOD:
506
 
    {
507
 
      OIDL_Type_Marshal_Info *tmi;
508
 
      char *ctmp, *ctmp2;
509
 
 
510
 
      tmi = oidl_marshal_context_find(cmi->ci->ctxt, node->tree);
511
 
 
512
 
      ctmp = oidl_marshal_node_valuestr(node);
513
 
      ctmp2 = orbit_cbe_get_typespec_str(node->tree);
514
 
 
515
 
      switch(tmi->mtype)
516
 
        {
517
 
        case MARSHAL_FUNC:
518
 
          fprintf(cmi->ci->fh, "if(%s_demarshal(_ORBIT_recv_buffer, %s(%s), %s, ev))\n%s;\n", ctmp2,
519
 
                  (node->flags & MN_ISSLICE)?"":"&",
520
 
                  ctmp, do_dup,
521
 
                  cmi->marshal_error_exit);
522
 
          break;
523
 
        case MARSHAL_ANY:
524
 
          fprintf(cmi->ci->fh, "{ gpointer _valref = &(%s);\n", ctmp);
525
 
          fprintf(cmi->ci->fh, "if(ORBit_demarshal_value(TC_%s, &_valref, _ORBIT_recv_buffer, %s, %s))\n%s;\n",
526
 
                  ctmp2, do_dup, cmi->orb_name, cmi->marshal_error_exit);
527
 
          fprintf(cmi->ci->fh, "}\n");
528
 
          break;
529
 
        default:
530
 
          g_assert_not_reached();
531
 
          break;
532
 
        }
533
 
    }    
534
 
    break;
535
 
  default:
536
 
    g_assert_not_reached();
537
 
    break;
538
 
  }
539
 
 
540
 
  g_free(ctmp);
541
 
}
542
 
 
543
 
static void
544
 
c_demarshal_set(OIDL_Marshal_Node *node, OIDL_C_Marshal_Info *cmi)
545
 
{
546
 
  if((!cmi->endian_swap_pass || !(node->flags & MN_ENDIAN_DEPENDANT))
547
 
     && node->name
548
 
     && (node->flags & MN_COALESCABLE))
549
 
    {
550
 
      char *ctmp, *ctmp2;
551
 
 
552
 
      ctmp = oidl_marshal_node_valuestr(node);
553
 
 
554
 
      c_demarshal_alignfor(node, cmi);
555
 
 
556
 
      fprintf(cmi->ci->fh, "memcpy(&(%s), _ORBIT_curptr, sizeof(%s));\n", ctmp, ctmp);
557
 
      ctmp2 = g_strdup_printf("sizeof(%s)", ctmp);
558
 
 
559
 
      c_demarshal_update_curptr(node, ctmp2, cmi);
560
 
 
561
 
      g_free(ctmp2);
562
 
      g_free(ctmp);
563
 
    }
564
 
  else
565
 
    {
566
 
      /* No need to do this if it is coalescable - obviously will be no need to do it then */
567
 
      g_slist_foreach(node->u.set_info.subnodes, (GFunc)c_demarshal_generate_alloc, cmi);
568
 
 
569
 
      g_slist_foreach(node->u.set_info.subnodes, (GFunc)c_demarshal_generate, cmi);
570
 
    }
571
 
}