#include "orbit-c-backend.h" #include static void cbe_output_demarshal_type_integer(CBEDemarshalInfo *mi); static void cbe_output_demarshal_type_float(CBEDemarshalInfo *mi); static void cbe_output_demarshal_type_char(CBEDemarshalInfo *mi); static void cbe_output_demarshal_type_wide_char(CBEDemarshalInfo *mi); static void cbe_output_demarshal_type_boolean(CBEDemarshalInfo *mi); static void cbe_output_demarshal_type_octet(CBEDemarshalInfo *mi); static void cbe_output_demarshal_type_enum(CBEDemarshalInfo *mi); static void cbe_output_demarshal_type_fixed(CBEDemarshalInfo *mi); static void cbe_output_demarshal_type_string(CBEDemarshalInfo *mi); static void cbe_output_demarshal_type_wide_string(CBEDemarshalInfo *mi); static void cbe_output_demarshal_type_any(CBEDemarshalInfo *mi); static void cbe_output_demarshal_type_object(CBEDemarshalInfo *mi); static void cbe_output_demarshal_type_sequence(CBEDemarshalInfo *mi); static void cbe_output_demarshal_type_array(CBEDemarshalInfo *mi); static void cbe_output_demarshal_type_struct(CBEDemarshalInfo *mi); static void cbe_output_demarshal_type_union(CBEDemarshalInfo *mi); static void cbe_output_demarshal_case_stmt(CBEDemarshalInfo *mi); static void cbe_output_demarshal_type_typecode(CBEDemarshalInfo *mi); static int loopvarnames = 0; void cbe_demarshaller_align(CBEDemarshalInfo *mi) { int boundary; boundary = cbe_get_type_head_alignment(cbe_get_typespec(mi->param)); if(boundary <= 1) return; if( !mi->previous_param || (cbe_get_type_tail_alignment(cbe_get_typespec(mi->previous_param)) < boundary)) fprintf(mi->of, " GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur = ALIGN_ADDRESS(GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur, %d);\n", boundary); } void cbe_output_demarshaller(CBEDemarshalInfo *dmi) { IDL_tree ts; loopvarnames++; switch(IDL_NODE_TYPE(dmi->param)) { case IDLN_CASE_STMT: dmi->typespec = ts = dmi->param; break; default: dmi->typespec = ts = cbe_get_typespec(dmi->param); } switch(IDL_NODE_TYPE(ts)) { case IDLN_TYPE_INTEGER: cbe_output_demarshal_type_integer(dmi); break; case IDLN_TYPE_FLOAT: cbe_output_demarshal_type_float(dmi); break; case IDLN_TYPE_CHAR: cbe_output_demarshal_type_char(dmi); break; case IDLN_TYPE_WIDE_CHAR: cbe_output_demarshal_type_wide_char(dmi); break; case IDLN_TYPE_BOOLEAN: cbe_output_demarshal_type_boolean(dmi); break; case IDLN_TYPE_ENUM: cbe_output_demarshal_type_enum(dmi); break; case IDLN_TYPE_OCTET: cbe_output_demarshal_type_octet(dmi); break; case IDLN_TYPE_FIXED: cbe_output_demarshal_type_fixed(dmi); break; case IDLN_TYPE_STRING: cbe_output_demarshal_type_string(dmi); break; case IDLN_TYPE_WIDE_STRING: cbe_output_demarshal_type_wide_string(dmi); break; case IDLN_TYPE_ANY: cbe_output_demarshal_type_any(dmi); break; case IDLN_TYPE_OBJECT: case IDLN_INTERFACE: cbe_output_demarshal_type_object(dmi); break; case IDLN_TYPE_SEQUENCE: cbe_output_demarshal_type_sequence(dmi); break; case IDLN_TYPE_ARRAY: cbe_output_demarshal_type_array(dmi); break; case IDLN_TYPE_STRUCT: case IDLN_EXCEPT_DCL: cbe_output_demarshal_type_struct(dmi); break; case IDLN_TYPE_UNION: cbe_output_demarshal_type_union(dmi); break; case IDLN_CASE_STMT: cbe_output_demarshal_case_stmt(dmi); /* Part of unions */ break; case IDLN_TYPE_TYPECODE: cbe_output_demarshal_type_typecode(dmi); break; default: g_warning("NOT producing demarshaller for %s", IDL_tree_type_names[IDL_NODE_TYPE(ts)]); break; } loopvarnames--; } static void cbe_output_demarshal_type_atom(CBEDemarshalInfo *mi) { cbe_demarshaller_align(mi); if(mi->byteswap_version) fprintf(mi->of, " GET_ATOM(%s);\n", mi->param_name); else { fprintf(mi->of, " %s = *((", mi->param_name); orbit_cbe_write_typespec(mi->of, mi->typespec); fprintf(mi->of, " *)GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur);\n"); fprintf(mi->of, " ((char *)GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur) += sizeof("); orbit_cbe_write_typespec(mi->of, mi->typespec); fprintf(mi->of, ");\n"); } mi->previous_param = mi->typespec; } static void cbe_output_demarshal_type_integer(CBEDemarshalInfo *mi) { cbe_output_demarshal_type_atom(mi); } static void cbe_output_demarshal_type_float(CBEDemarshalInfo *mi) { cbe_output_demarshal_type_atom(mi); } static void cbe_output_demarshal_type_fixed(CBEDemarshalInfo *mi) { g_assert(!"Not yet implemented\n"); } static void cbe_output_demarshal_type_char(CBEDemarshalInfo *mi) { cbe_output_demarshal_type_atom(mi); } static void cbe_output_demarshal_type_wide_char(CBEDemarshalInfo *mi) { cbe_output_demarshal_type_atom(mi); } static void cbe_output_demarshal_type_string(CBEDemarshalInfo *mi) { CBEDemarshalInfo submi = *mi; IDL_tree anint = IDL_type_integer_new(0, IDL_INTEGER_TYPE_LONG); submi.param_name = "len"; submi.typespec = anint; submi.param = submi.typespec; fprintf(mi->of, " {\n"); fprintf(mi->of, " GIOP_unsigned_long len;\n"); cbe_output_demarshaller(&submi); IDL_tree_free(anint); if(mi->allocate_memory) { fprintf(mi->of, " %s = CORBA_string_alloc(len);\n", mi->param_name); fprintf(mi->of, " if(len)\n"); fprintf(mi->of, " strncpy(%s,\nGIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur,\nlen);\n", mi->param_name); fprintf(mi->of, " else\n(%s)[0] = '\\0';\n", mi->param_name); fprintf(mi->of, " ((char *)GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur) += len;\n"); } else { /* We cheat, and use the 0's in the length as the zero-byte of the zero-length string */ fprintf(mi->of, " %s = len?(GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur):(((char *)GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur) - sizeof(CORBA_unsigned_long));", mi->param_name); fprintf(mi->of, " ((char *)GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur) += len;\n"); } fprintf(mi->of, " }\n"); mi->previous_param = mi->typespec; } static void cbe_output_demarshal_type_wide_string(CBEDemarshalInfo *mi) { g_assert(!"Not yet implemented\n"); } static void cbe_output_demarshal_type_boolean(CBEDemarshalInfo *mi) { cbe_output_demarshal_type_atom(mi); } static void cbe_output_demarshal_type_octet(CBEDemarshalInfo *mi) { cbe_output_demarshal_type_atom(mi); } static void cbe_output_demarshal_type_any(CBEDemarshalInfo *mi) { fprintf(mi->of, "ORBit_demarshal_any(_ORBIT_recv_buffer, &(%s), %s, %s);\n", mi->param_name, mi->allocate_memory?"CORBA_TRUE":"CORBA_FALSE", mi->orb_name); } static void cbe_output_demarshal_type_object(CBEDemarshalInfo *mi) { fprintf(mi->of, "%s = ORBit_demarshal_object(_ORBIT_recv_buffer, %s);\n", mi->param_name, mi->orb_name); } static void cbe_output_demarshal_type_enum(CBEDemarshalInfo *mi) { cbe_output_demarshal_type_atom(mi); } static void cbe_output_demarshal_type_sequence(CBEDemarshalInfo *mi) { GString *tmpstr = g_string_new(NULL); CBEDemarshalInfo subdmi = *mi; IDL_tree anint; g_string_sprintf(tmpstr, "(%s)._length", mi->param_name); subdmi.param_name = tmpstr->str; subdmi.typespec = anint = subdmi.param = IDL_type_integer_new(0, IDL_INTEGER_TYPE_LONG); IDL_TYPE_INTEGER(anint).f_signed = 0; cbe_output_demarshaller(&subdmi); subdmi.param = subdmi.typespec = IDL_TYPE_SEQUENCE(mi->typespec).simple_type_spec; if(cbe_type_is_fixed_length(subdmi.param)) { fprintf(mi->of, "(%s)._release = CORBA_%s;\n", mi->param_name, mi->allocate_memory?"TRUE":"FALSE"); if(mi->allocate_memory) { fprintf(mi->of, "(%s)._buffer = memcpy(ORBit_alloc((%s)._length * sizeof((%s)._buffer[0]), NULL, NULL), GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur, (%s)._length * sizeof((%s)._buffer[0]));\n", mi->param_name, mi->param_name, mi->param_name, mi->param_name, mi->param_name); } else { fprintf(mi->of, "(%s)._buffer = GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur;\n", mi->param_name); } fprintf(mi->of, "((char *)GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur) += ((%s)._length) * sizeof((%s)._buffer[0]);\n", mi->param_name, mi->param_name); mi->previous_param = subdmi.typespec; } else { fprintf(mi->of, "(%s)._release = CORBA_TRUE;\n", mi->param_name); fprintf(mi->of, "(%s)._buffer = CORBA_sequence_", mi->param_name); orbit_cbe_write_typename(mi->of, IDL_TYPE_SEQUENCE(mi->typespec).simple_type_spec); fprintf(mi->of, "_allocbuf((%s)._length);\n", mi->param_name); if(cbe_get_type_head_alignment(subdmi.param) <= cbe_get_type_tail_alignment(subdmi.param)) { cbe_demarshaller_align(&subdmi); subdmi.previous_param = subdmi.param; } else subdmi.previous_param = NULL; g_string_sprintf(tmpstr, "(%s)._buffer[i%d]", mi->param_name, loopvarnames); subdmi.param_name = tmpstr->str; fprintf(mi->of, " {\n int i%d;\n for(i%d = 0; i%d < (%s)._length; i%d++) {\n", loopvarnames, loopvarnames, loopvarnames, mi->param_name, loopvarnames); cbe_output_demarshaller(&subdmi); fprintf(mi->of, " }\n}\n"); IDL_tree_free(anint); mi->previous_param = subdmi.previous_param; } g_string_free(tmpstr, TRUE); } static void cbe_output_demarshal_type_array(CBEDemarshalInfo *mi) { GString *tmpstr = g_string_new(NULL); int dimn; IDL_tree curitem, dcl; CBEDemarshalInfo subdmi = *mi; char *id; gboolean needs_per_loop_alignment; dcl = IDL_get_parent_node(mi->typespec, IDLN_ANY, NULL); /* list */ dcl = IDL_get_parent_node(dcl, IDLN_ANY, NULL); /* member|type_dcl */ g_assert(dcl && (IDL_NODE_TYPE(dcl) == IDLN_MEMBER || IDL_NODE_TYPE(dcl) == IDLN_TYPE_DCL)); if((!cbe_type_is_endian_sensitive(IDL_TYPE_DCL(dcl).type_spec) || !mi->byteswap_version) && cbe_type_is_fixed_length(IDL_TYPE_DCL(dcl).type_spec)) { subdmi.typespec = subdmi.param = IDL_TYPE_DCL(dcl).type_spec; cbe_demarshaller_align(&subdmi); id = orbit_cbe_get_typename(mi->typespec); /* need to test this... :-) */ fprintf(mi->of, " memcpy(%s, GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur, sizeof(%s));\n", mi->param_name, (IDL_NODE_TYPE(dcl)==IDLN_MEMBER)?(mi->param_name):id); fprintf(mi->of, " ((char *)GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur) += sizeof(%s);\n", (IDL_NODE_TYPE(dcl)==IDLN_MEMBER)?(mi->param_name):id); g_free(id); mi->previous_param = IDL_TYPE_DCL(dcl).type_spec; return; } fprintf(mi->of, " {\n"); dimn = 0; fprintf(mi->of, " int n%d", loopvarnames + dimn); for(dimn = 1, curitem = IDL_LIST(IDL_TYPE_ARRAY(mi->typespec).size_list).next; curitem; dimn++, curitem = IDL_LIST(curitem).next) { fprintf(mi->of, ", n%d", dimn + loopvarnames); } fprintf(mi->of, ";\n"); if(cbe_get_type_head_alignment(IDL_TYPE_DCL(dcl).type_spec) <= cbe_get_type_tail_alignment(IDL_TYPE_DCL(dcl).type_spec)) { subdmi.param = subdmi.typespec = IDL_TYPE_DCL(dcl).type_spec; cbe_demarshaller_align(&subdmi); needs_per_loop_alignment = FALSE; } else needs_per_loop_alignment = TRUE; for(dimn = 0, curitem = IDL_TYPE_ARRAY(mi->typespec).size_list; curitem; dimn++, curitem = IDL_LIST(curitem).next) { fprintf(mi->of, " for(n%d = 0; n%d < %" IDL_LL "d; n%d++) {\n", dimn + loopvarnames, dimn + loopvarnames, IDL_INTEGER(IDL_LIST(curitem).data).value, dimn + loopvarnames); } g_string_sprintf(tmpstr, "(%s)", mi->param_name); for(dimn = 0, curitem = IDL_TYPE_ARRAY(mi->typespec).size_list; curitem; dimn++, curitem = IDL_LIST(curitem).next) { g_string_sprintfa(tmpstr, "[n%d]", dimn + loopvarnames); } subdmi.param = subdmi.typespec = IDL_TYPE_DCL(dcl).type_spec; if(!needs_per_loop_alignment) subdmi.previous_param = subdmi.param; else subdmi.previous_param = NULL; subdmi.param_name = tmpstr->str; loopvarnames += dimn; cbe_output_demarshaller(&subdmi); loopvarnames -= dimn; for(dimn--, curitem = IDL_TYPE_ARRAY(mi->typespec).size_list; curitem; dimn--, curitem = IDL_LIST(curitem).next) { fprintf(mi->of, " } /* end loop for n%d */\n", dimn + loopvarnames); } fprintf(mi->of, " }\n"); g_string_free(tmpstr, TRUE); mi->previous_param = subdmi.previous_param; } static void cbe_output_demarshal_type_struct(CBEDemarshalInfo *mi) { GString *tmpstr = g_string_new(NULL); CBEDemarshalInfo subdmi = *mi; IDL_tree curitem, curdcl, theid = NULL; if(!IDL_TYPE_STRUCT(mi->typespec).member_list) return; if(!mi->byteswap_version && cbe_type_is_fixed_length(mi->typespec)) { subdmi.typespec = subdmi.param = IDL_LIST(IDL_TYPE_STRUCT(mi->typespec).member_list).data; cbe_demarshaller_align(&subdmi); fprintf(mi->of, " memcpy(&%s, GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur, sizeof(%s));\n", mi->param_name, mi->param_name); fprintf(mi->of, " ((char *)GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur) += sizeof(%s);\n", mi->param_name); mi->previous_param = mi->typespec; return; } for(curitem = IDL_TYPE_STRUCT(mi->typespec).member_list; curitem; curitem = IDL_LIST(curitem).next) { for(curdcl = IDL_MEMBER(IDL_LIST(curitem).data).dcls; curdcl; curdcl = IDL_LIST(curdcl).next) { subdmi.param = subdmi.typespec = cbe_get_typespec(IDL_LIST(curdcl).data); switch(IDL_NODE_TYPE(IDL_LIST(curdcl).data)) { case IDLN_TYPE_ARRAY: theid = IDL_TYPE_ARRAY(IDL_LIST(curdcl).data).ident; break; case IDLN_IDENT: theid = IDL_LIST(curdcl).data; break; default: g_error("Unknown member dcl node type %s", IDL_tree_type_names[IDL_NODE_TYPE(IDL_LIST(curdcl).data)]); } g_string_sprintf(tmpstr, "(%s).%s", mi->param_name, IDL_IDENT(theid).str); subdmi.param_name = tmpstr->str; cbe_output_demarshaller(&subdmi); } } g_string_free(tmpstr, TRUE); mi->previous_param = subdmi.param; } static void cbe_output_demarshal_type_union(CBEDemarshalInfo *mi) { GString *tmpstr = g_string_new(NULL); CBEDemarshalInfo subdmi = *mi; IDL_tree curitem; g_string_sprintf(tmpstr, "(%s)._d", mi->param_name); subdmi.param_name = tmpstr->str; subdmi.param = subdmi.typespec = IDL_TYPE_UNION(mi->typespec).switch_type_spec; cbe_output_demarshaller(&subdmi); subdmi.had_default = FALSE; fprintf(mi->of, " switch((%s)._d) {\n", mi->param_name); g_string_sprintf(tmpstr, "(%s)._u", mi->param_name); subdmi.param_name = tmpstr->str; for(curitem = IDL_TYPE_UNION(mi->typespec).switch_body; curitem; curitem = IDL_LIST(curitem).next) { subdmi.param = subdmi.typespec = IDL_LIST(curitem).data; cbe_output_demarshaller(&subdmi); } if(!subdmi.had_default) fprintf(mi->of, "default:\n"); fprintf(mi->of, "}\n\n"); /* There is no way we can know the exact alignment at compile time, but if we put the union as a whole in here, the MINimum possible alignment can be calculated */ mi->previous_param = mi->param; g_string_free(tmpstr, TRUE); } static void cbe_output_demarshal_case_stmt(CBEDemarshalInfo *mi) { GString *tmpstr = g_string_new(NULL); IDL_tree curitem; CBEDemarshalInfo subdmi = *mi; for(curitem = IDL_CASE_STMT(mi->typespec).labels; curitem; curitem = IDL_LIST(curitem).next) { if(IDL_LIST(curitem).data) { fprintf(mi->of, " case "); orbit_cbe_write_const(mi->of, IDL_LIST(curitem).data); fprintf(mi->of, ":\n"); } else { fprintf(mi->of, " default:\n"); mi->had_default = TRUE; } } g_string_sprintf(tmpstr, "(%s).%s", mi->param_name, IDL_IDENT(IDL_LIST(IDL_MEMBER(IDL_CASE_STMT(mi->typespec).element_spec).dcls).data).str); subdmi.param_name = tmpstr->str; subdmi.param = subdmi.typespec = IDL_MEMBER(IDL_CASE_STMT(mi->typespec).element_spec).type_spec; cbe_output_demarshaller(&subdmi); mi->previous_param = subdmi.previous_param; g_string_free(tmpstr, TRUE); fprintf(mi->of, "break;"); } static void cbe_output_demarshal_type_typecode(CBEDemarshalInfo *mi) { cbe_demarshaller_align(mi); fprintf(mi->of, "ORBit_decode_CORBA_TypeCode(&%s, _ORBIT_recv_buffer);\n", mi->param_name); }