#include "orbit-c-backend.h" #include static void cbe_output_marshal_type_atom(CBEMarshalInfo *mi); static void cbe_output_marshal_type_string(CBEMarshalInfo *mi); static void cbe_output_marshal_type_wide_string(CBEMarshalInfo *mi); static void cbe_output_marshal_type_any(CBEMarshalInfo *mi); static void cbe_output_marshal_type_object(CBEMarshalInfo *mi); static void cbe_output_marshal_type_sequence(CBEMarshalInfo *mi); static void cbe_output_marshal_type_array(CBEMarshalInfo *mi); static void cbe_output_marshal_type_struct(CBEMarshalInfo *mi); static void cbe_output_marshal_type_union(CBEMarshalInfo *mi); static void cbe_output_marshal_type_fixed(CBEMarshalInfo *mi); static void cbe_output_marshal_type_typecode(CBEMarshalInfo *mi); static int loopvarnames = 0; void cbe_marshaller_align(CBEMarshalInfo *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_message_buffer_do_alignment(GIOP_MESSAGE_BUFFER(_ORBIT_send_buffer), %d);\n", boundary); } void cbe_output_marshaller(CBEMarshalInfo *mi) { IDL_tree ts; loopvarnames++; mi->typespec = ts = cbe_get_typespec(mi->param); switch(IDL_NODE_TYPE(ts)) { case IDLN_TYPE_INTEGER: case IDLN_TYPE_FLOAT: case IDLN_TYPE_CHAR: case IDLN_TYPE_WIDE_CHAR: case IDLN_TYPE_BOOLEAN: case IDLN_TYPE_OCTET: case IDLN_TYPE_ENUM: cbe_output_marshal_type_atom(mi); break; case IDLN_TYPE_FIXED: cbe_output_marshal_type_fixed(mi); break; case IDLN_TYPE_STRING: cbe_output_marshal_type_string(mi); break; case IDLN_TYPE_WIDE_STRING: cbe_output_marshal_type_wide_string(mi); break; case IDLN_TYPE_ANY: cbe_output_marshal_type_any(mi); break; case IDLN_TYPE_OBJECT: case IDLN_INTERFACE: cbe_output_marshal_type_object(mi); break; case IDLN_TYPE_SEQUENCE: cbe_output_marshal_type_sequence(mi); break; case IDLN_TYPE_ARRAY: cbe_output_marshal_type_array(mi); break; case IDLN_TYPE_STRUCT: case IDLN_EXCEPT_DCL: cbe_output_marshal_type_struct(mi); break; case IDLN_TYPE_UNION: cbe_output_marshal_type_union(mi); break; case IDLN_TYPE_TYPECODE: cbe_output_marshal_type_typecode(mi); break; default: g_warning("NOT producing marshaller for %s", IDL_tree_type_names[IDL_NODE_TYPE(ts)]); break; } loopvarnames--; } static void cbe_output_marshal_type_atom(CBEMarshalInfo *mi) { /* If we don't need to align-up for a parameter, why bother doing the work? */ cbe_marshaller_align(mi); fprintf(mi->of, " giop_%s(GIOP_%s_BUFFER(_ORBIT_send_buffer), &%s, sizeof(%s));\n", mi->require_indirect?"send_buffer_append_mem_indirect":"message_buffer_append_mem", mi->require_indirect?"SEND":"MESSAGE", mi->param_name, mi->param_name); mi->previous_param = mi->typespec; } static void cbe_output_marshal_type_fixed(CBEMarshalInfo *mi) { g_error("Not yet implemented."); } static void cbe_output_marshal_type_string(CBEMarshalInfo *mi) { CBEMarshalInfo submi = *mi; fprintf(mi->of, " {\n"); fprintf(mi->of, " GIOP_unsigned_long len = %s?(strlen(%s)+1):0;\n", mi->param_name, mi->param_name); submi.param_name = "len"; submi.typespec = IDL_type_integer_new(0, IDL_INTEGER_TYPE_LONG); submi.param = submi.typespec; submi.require_indirect = TRUE; cbe_output_marshaller(&submi); IDL_tree_free(submi.typespec); fprintf(mi->of, " if(%s)\n", mi->param_name); fprintf(mi->of, " giop_message_buffer_append_mem(GIOP_MESSAGE_BUFFER(_ORBIT_send_buffer), %s, len);\n", mi->param_name); fprintf(mi->of, " }\n"); mi->previous_param = mi->typespec; } static void cbe_output_marshal_type_wide_string(CBEMarshalInfo *mi) { /* XXX fixme: Not sure what this is supposed to look like - do "something" for now */ cbe_output_marshal_type_string(mi); } static void cbe_output_marshal_type_any(CBEMarshalInfo *mi) { fprintf(mi->of, "ORBit_marshal_any(_ORBIT_send_buffer, &(%s));\n", mi->param_name); } static void cbe_output_marshal_type_object(CBEMarshalInfo *mi) { fprintf(mi->of, "ORBit_marshal_object(_ORBIT_send_buffer, %s);\n", mi->param_name); } static void cbe_output_marshal_type_sequence(CBEMarshalInfo *mi) { GString *subname = g_string_new(NULL); CBEMarshalInfo submi = *mi; IDL_tree anint; fprintf(mi->of, " {\n"); if(!cbe_type_is_fixed_length(mi->typespec)) { fprintf(mi->of, " GIOP_unsigned_long i%d;\n", loopvarnames); } submi.typespec = anint = submi.param = IDL_type_integer_new(0, IDL_INTEGER_TYPE_LONG); IDL_TYPE_INTEGER(anint).f_signed = 0; g_string_sprintf(subname, "(%s)._length", mi->param_name); submi.param_name = subname->str;; cbe_output_marshaller(&submi); if(cbe_type_is_fixed_length(mi->param)) { submi.typespec = submi.param = IDL_TYPE_SEQUENCE(mi->typespec).simple_type_spec; cbe_marshaller_align(&submi); fprintf(mi->of, "giop_message_buffer_append_mem(GIOP_MESSAGE_BUFFER(_ORBIT_send_buffer), (%s)._buffer, sizeof((%s)._buffer[0])*((%s)._length));\n", mi->param_name, mi->param_name, mi->param_name); } else { /* Here we output the marshaller for a sequence elements that are complex - i.e. not in a contigous memory region that we can send straight to the wire */ submi.param = submi.typespec = cbe_get_typespec(IDL_TYPE_SEQUENCE(mi->typespec).simple_type_spec); if(cbe_get_type_head_alignment(submi.param) <= cbe_get_type_tail_alignment(submi.param)) { cbe_marshaller_align(&submi); submi.previous_param = submi.param; } else submi.previous_param = NULL; fprintf(mi->of, " for(i%d = 0; i%d < (%s)._length; i%d++) {\n", loopvarnames, loopvarnames, mi->param_name, loopvarnames); g_string_sprintf(subname, "(%s)._buffer[i%d]", mi->param_name, loopvarnames); submi.param_name = subname->str; cbe_output_marshaller(&submi); fprintf(mi->of, " }\n"); } fprintf(mi->of, " }\n"); g_string_free(subname, TRUE); mi->previous_param = submi.previous_param; IDL_tree_free(anint); } static void cbe_output_marshal_type_array(CBEMarshalInfo *mi) { GString *tmpstr = g_string_new(NULL); int dimn; IDL_tree curitem, dcl; CBEMarshalInfo submi = *mi; char *id; gboolean needs_per_loop_alignment; dcl = IDL_get_parent_node(mi->typespec, IDLN_ANY, NULL);/* Get the IDLN_LIST */ dcl = IDL_get_parent_node(dcl, IDLN_ANY, NULL);/* Get the member or type_dcl */ g_assert(dcl && (IDL_NODE_TYPE(dcl) == IDLN_MEMBER || IDL_NODE_TYPE(dcl) == IDLN_TYPE_DCL)); if(cbe_type_is_fixed_length(IDL_TYPE_DCL(dcl).type_spec)) { submi.typespec = submi.param = IDL_TYPE_DCL(dcl).type_spec; cbe_marshaller_align(&submi); id = orbit_cbe_get_typename(mi->typespec); fprintf(mi->of, "giop_message_buffer_append_mem(GIOP_MESSAGE_BUFFER(_ORBIT_send_buffer), %s, sizeof(%s));", mi->param_name, id); g_free(id); mi->previous_param = IDL_TYPE_DCL(dcl).type_spec; } else { 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)) { submi.param = submi.typespec = IDL_TYPE_DCL(dcl).type_spec; cbe_marshaller_align(&submi); 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); } submi.param = submi.typespec = IDL_TYPE_DCL(dcl).type_spec; if(!needs_per_loop_alignment) submi.previous_param = submi.param; else submi.previous_param = NULL; submi.param_name = tmpstr->str; loopvarnames += dimn; cbe_output_marshaller(&submi); 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"); mi->previous_param = submi.previous_param; } g_string_free(tmpstr, TRUE); } static void cbe_output_marshal_type_struct(CBEMarshalInfo *mi) { IDL_tree curitem, curmember, thenode = NULL; GString *subname = g_string_new(NULL); CBEMarshalInfo submi = *mi; submi.param = NULL; if(!IDL_TYPE_STRUCT(mi->typespec).member_list) return; if(cbe_type_is_fixed_length(mi->typespec)) { submi.param = submi.typespec = IDL_LIST(IDL_TYPE_STRUCT(mi->typespec).member_list).data; cbe_marshaller_align(&submi); fprintf(mi->of, "giop_message_buffer_append_mem(GIOP_MESSAGE_BUFFER(_ORBIT_send_buffer), &(%s), sizeof(%s));\n", mi->param_name, mi->param_name); mi->previous_param = mi->typespec; } else { for(curitem = IDL_TYPE_STRUCT(mi->typespec).member_list; curitem; curitem = IDL_LIST(curitem).next) { for(curmember = IDL_MEMBER(IDL_LIST(curitem).data).dcls; curmember; curmember = IDL_LIST(curmember).next) { submi.previous_param = submi.param; submi.param = cbe_get_typespec(IDL_LIST(curmember).data); switch(IDL_NODE_TYPE(IDL_LIST(curmember).data)) { case IDLN_TYPE_ARRAY: thenode = IDL_TYPE_ARRAY(IDL_LIST(curmember).data).ident; break; case IDLN_IDENT: thenode = IDL_LIST(curmember).data; break; default: g_error("Unknown member dcl node type %s", IDL_tree_type_names[IDL_NODE_TYPE(IDL_LIST(curmember).data)]); } g_string_sprintf(subname, "(%s).%s", mi->param_name, IDL_IDENT(thenode).str); submi.param_name = subname->str; cbe_output_marshaller(&submi); } } mi->previous_param = submi.previous_param; } g_string_free(subname, TRUE); } static void cbe_output_marshal_type_union(CBEMarshalInfo *mi) { GString *subname = g_string_new(NULL); IDL_tree curitem, curcase, ts = NULL; CBEMarshalInfo submi = *mi; gboolean had_default = FALSE; g_string_sprintf(subname, "(%s)._d", mi->param_name); submi.param_name = subname->str; submi.param = submi.typespec = IDL_TYPE_UNION(mi->typespec).switch_type_spec; cbe_output_marshaller(&submi); fprintf(mi->of, " switch((%s)._d) {\n", mi->param_name); for(curitem = IDL_TYPE_UNION(mi->typespec).switch_body; curitem; curitem = IDL_LIST(curitem).next) { for(curcase = IDL_CASE_STMT(IDL_LIST(curitem).data).labels; curcase; curcase = IDL_LIST(curcase).next) { if(IDL_LIST(curcase).data) { fprintf(mi->of, " case "); orbit_cbe_write_const(mi->of, IDL_LIST(curcase).data); fprintf(mi->of, ":\n"); } else { had_default = TRUE; fprintf(mi->of, " default:\n"); } } ts = IDL_CASE_STMT(IDL_LIST(curitem).data).element_spec; /* the IDL_MEMBER */ /* shades of LISP :-) */ g_string_sprintf(subname, "(%s)._u.%s", mi->param_name, IDL_IDENT(IDL_LIST(IDL_MEMBER(ts).dcls).data).str); submi.param_name = subname->str; submi.param = submi.typespec = IDL_MEMBER(ts).type_spec; submi.previous_param = IDL_TYPE_UNION(mi->typespec).switch_type_spec; cbe_output_marshaller(&submi); fprintf(mi->of, " break;"); } if(!had_default) fprintf(mi->of, "default:\n"); /* Eliminate gcc warnings */ fprintf(mi->of, "}\n"); g_string_free(subname, TRUE); mi->previous_param = mi->param; } static void cbe_output_marshal_type_typecode(CBEMarshalInfo *mi) { fprintf(mi->of, "ORBit_encode_CORBA_TypeCode(%s, _ORBIT_send_buffer);\n", mi->param_name); }