def marshall(to, environment, type, decl, argname, to_where, exception="BAD_PARAM", is_union=0): assert isinstance(type, types.Type) d_type = type.deref() # If this is an array of base types, the quick marshalling option is used. # slice_cast is set to the casting required to cast the variable to a # pointer to the beginning of the array. There are 3 possibilities: # 1. The variable is a declarator, e.g. it is a member of a struct or a # union. No casting is required. slice_cast = "" # 2. The variable is not a declarator and its dimension is > 1, # cast the variable to its array slice pointer. # 3. Same as 2 but its dimension == 1, just cast the variable to a pointer # to its base class (because the type's array slice may not be # defined). if decl: assert isinstance(decl, idlast.Declarator) dims = decl.sizes() + type.dims() slice_cast = "" else: dims = type.dims() if len(dims) != 1: slice_cast = "(" + type.base(environment) + "_slice" + "*)" else: slice_cast = "(" + d_type.base(environment) + "*)" if is_union and not dims: if d_type.kind() in [ idltype.tk_any, idltype.tk_struct, idltype.tk_union, idltype.tk_sequence, idltype.tk_except, idltype.tk_fixed, ]: argname = "(*" + argname + ")" if dims: n_elements = reduce(lambda x, y: x * y, dims, 1) array_marshal_helpers = { idltype.tk_octet: ("omni::ALIGN_1", 1), idltype.tk_boolean: ("omni::ALIGN_1", 1), idltype.tk_short: ("omni::ALIGN_2", 2), idltype.tk_long: ("omni::ALIGN_4", 4), idltype.tk_ushort: ("omni::ALIGN_2", 2), idltype.tk_ulong: ("omni::ALIGN_4", 4), idltype.tk_float: ("omni::ALIGN_4", 4), idltype.tk_double: ("omni::ALIGN_8", 8), idltype.tk_longlong: ("omni::ALIGN_8", 8), idltype.tk_ulonglong: ("omni::ALIGN_8", 8) } kind = d_type.type().kind() if kind in array_marshal_helpers: (alignment, elmsize) = array_marshal_helpers[kind] if alignment != "omni::ALIGN_1": if kind == idltype.tk_double: to.out(""" #ifndef OMNI_MIXED_ENDIAN_DOUBLE""") to.out("""\ if (! @[email protected]_byte_swap()) { @[email protected]_octet_array((_CORBA_Octet*)(@slice_cast@@name@),@num@,@align@); } else """, where=to_where, name=argname, slice_cast=slice_cast, num=str(n_elements * elmsize), align=alignment) if kind == idltype.tk_double: to.out("""\ #endif""") # Do not return here. # let the code below to deal with the else block. else: if kind == idltype.tk_boolean: to.out(""" #if !defined(HAS_Cplusplus_Bool) || (SIZEOF_BOOL == 1)""") if n_elements <= SMALL_ARRAY_THRESHOLD: put_op = "put_small_octet_array" else: put_op = "put_octet_array" to.out( "@where@.@put_op@((_CORBA_Octet*)(@slice_cast@@name@),@num@);", where=to_where, put_op=put_op, name=argname, slice_cast=slice_cast, num=str(n_elements)) if kind == idltype.tk_boolean: to.out("""\ #else""") else: return # No quick route, generate iteration loop block = cxx.Block(to) akind = d_type.type().kind() # Valuetype chunked encoding needs to know array length before # we marshal it item by item. if akind in array_marshal_helpers: to.out("""\ @[email protected](@align@, @num@);""", where=to_where, num=str(n_elements * elmsize), align=alignment) elif akind == idltype.tk_char: to.out("""\ @[email protected](omni::ALIGN_1, @num@);""", where=to_where, num=str(n_elements)) elif akind == idltype.tk_longdouble: to.out("""\ @[email protected](omni::ALIGN_8, @num@);""", where=to_where, num=str(n_elements * 16)) loop = cxx.For(to, dims) indexing_string = loop.index() element_name = argname + indexing_string if dims != []: type_name = d_type.base(environment) if type_name == element_name: type_name = d_type.base() else: type_name = type.base(environment) if type_name == element_name: type_name = type.base() bounded = "" kind = d_type.type().kind() if d_type.interface(): if type_name.endswith("_ptr"): type_name = type_name[:-4] if isinstance(d_type.type().decl(), idlast.Forward): # hack to denote an interface forward declaration # kind is used to index the dictionary below kind = idltype.tk_objref * 1000 elif d_type.value() or d_type.valuebox(): if isinstance(d_type.type().decl(), idlast.ValueForward): kind = idltype.tk_value * 1000 elif d_type.string() or d_type.wstring(): bounded = str(d_type.type().bound()) if not d_type.is_basic_data_types() and not d_type.enum(): type_cast = "(const " + type_name + "&) " else: type_cast = "" special_marshal_functions = { idltype.tk_boolean: "@[email protected](@element_name@);", idltype.tk_octet: "@[email protected](@element_name@);", idltype.tk_char: "@[email protected](@element_name@);", idltype.tk_wchar: "@[email protected](@element_name@);", idltype.tk_string: "@[email protected](@element_name@,@bounded@);", idltype.tk_wstring: "@[email protected](@element_name@,@bounded@);", idltype.tk_objref: "@type@::_marshalObjRef(@element_name@,@to_where@);", idltype.tk_TypeCode: "::CORBA::TypeCode::marshalTypeCode(@element_name@,@to_where@);", idltype.tk_objref * 1000: "@type@_Helper::marshalObjRef(@element_name@,@to_where@);", idltype.tk_value: "@type@::_NP_marshal(@element_name@,@to_where@);", idltype.tk_value * 1000: "@type@_Helper::marshal(@element_name@,@to_where@);", idltype.tk_value_box: "@type@::_NP_marshal(@element_name@,@to_where@);", idltype.tk_abstract_interface: "@type@::_marshalObjRef(@element_name@,@to_where@);", idltype.tk_local_interface: "@type@::_marshalObjRef(@element_name@,@to_where@);", } if kind in special_marshal_functions: out_template = special_marshal_functions[kind] else: out_template = "@type_cast@@element_name@ >>= @to_where@;" to.out(out_template, to_where=to_where, element_name=element_name, bounded=bounded, type=type_name, type_cast=type_cast, dtype=type.member(environment)) loop.end() if dims != []: block.end() if kind == idltype.tk_boolean: to.out("""\ #endif""")
def visitException(node): scopedName = id.Name(node.scopedName()) name = scopedName.simple() outer_environment = id.lookup(node) environment = outer_environment.enter(name) scoped_name = scopedName.fullyQualify() # build the default ctor, copy ctor, assignment operator copy_ctor_body = output.StringStream() default_ctor_body = output.StringStream() default_ctor_args = [] assign_op_body = output.StringStream() has_default_ctor = 0 for m in node.members(): has_default_ctor = 1 memberType = types.Type(m.memberType()) if m.constrType(): memberType.type().decl().accept(self) d_memberType = memberType.deref() memberType_fqname = memberType.base() for d in m.declarators(): decl_scopedName = id.Name(d.scopedName()) decl_name = decl_scopedName.simple() decl_dims = d.sizes() full_dims = decl_dims + memberType.dims() is_array = full_dims != [] is_array_declarator = decl_dims != [] memberType_name_arg = memberType.op(types.IN, environment) if is_array_declarator: # we use the internal typedef'ed type if the member is an array # declarator memberType_name_arg = "const " +\ config.state['Private Prefix'] +\ "_" + decl_name elif d_memberType.sequence(): if memberType.typedef(): memberType_name_arg = "const " + id.Name(memberType.type( ).decl().scopedName()).unambiguous(environment) else: memberType_name_arg = "const " + memberType.sequenceTemplate( environment) elif memberType.typecode(): memberType_name_arg = "::CORBA::TypeCode_ptr" index = "" if is_array: blocks = [ cxx.Block(copy_ctor_body), cxx.Block(default_ctor_body), cxx.Block(assign_op_body) ] loops = [ cxx.For(copy_ctor_body, full_dims), cxx.For(default_ctor_body, full_dims), cxx.For(assign_op_body, full_dims) ] index = loops[0].index() # all the same copy_ctor_body.out("""\ @member_name@@index@ = _s.@member_name@@index@;""", member_name=decl_name, index=index) if (d_memberType.interface() and not is_array): # these are special resources which need to be explicitly # duplicated (but not if an array?) duplicate = memberType_fqname.replace("_ptr", "") + \ "::_duplicate" if isinstance(d_memberType.type().decl(), idlast.Forward): duplicate = duplicate.replace("::_dup", "_Helper::dup") default_ctor_body.out("""\ @duplicate@(_@member_name@@index@);""", duplicate=duplicate, member_name=decl_name, index=index) default_ctor_args.append(memberType_name_arg + " _" + decl_name) default_ctor_body.out("""\ @member_name@@index@ = _@member_name@@index@;""", member_name=decl_name, index=index) assign_op_body.out("""\ @member_name@@index@ = _s.@member_name@@index@;""", member_name=decl_name, index=index) if is_array: for loop in loops: loop.end() for block in blocks: block.end() default_ctor = output.StringStream() if has_default_ctor: default_ctor.out(template.exception_default_ctor, scoped_name=scoped_name, name=name, ctor_args=", ".join(default_ctor_args), default_ctor_body=str(default_ctor_body)) # write the main chunk stream.out(template.exception, scoped_name=scoped_name, name=name, copy_ctor_body=str(copy_ctor_body), default_ctor=str(default_ctor), ctor_args=", ".join(default_ctor_args), default_ctor_body=str(default_ctor_body), repoID=node.repoId(), assign_op_body=str(assign_op_body)) # deal with marshalling and demarshalling needs_marshalling = node.members() != [] marshal = output.StringStream() unmarshal = output.StringStream() for m in node.members(): memberType = types.Type(m.memberType()) d_memberType = memberType.deref() for d in m.declarators(): decl_scopedName = id.Name(d.scopedName()) decl_name = decl_scopedName.simple() is_array_declarator = d.sizes() != [] skutil.unmarshall(unmarshal, environment, memberType, d, decl_name, "_n") skutil.marshall(marshal, environment, memberType, d, decl_name, "_n") if needs_marshalling: stream.out(template.exception_operators, scoped_name=scoped_name, marshal=str(marshal), unmarshal=str(unmarshal)) return
def unmarshall(to, environment, type, decl, name, from_where, is_union=0): assert isinstance(type, types.Type) d_type = type.deref() # If this is an array of base types, the quick marshalling option is used. # slice_cast is set to the casting required to cast the variable to a # pointer to the beginning of the array. There are 3 possibilities: # 1. The variable is a declarator, e.g. it is a member of a struct or a # union. No casting is required. slice_cast = "" # 2. The variable is not a declarator and its dimension is > 1, # cast the variable to its array slice pointer. # 3. Same as 2 but its dimension == 1, just cast the variable to a pointer # to its base class (because the type's array slice may not be # defined). if decl: assert isinstance(decl, idlast.Declarator) dims = decl.sizes() + type.dims() slice_cast = "" else: dims = type.dims() if len(dims) != 1: slice_cast = "(" + type.base(environment) + "_slice" + "*)" else: slice_cast = "(" + d_type.base(environment) + "*)" if dims: if is_union: if decl.sizes(): # Anonymous array slice_type = name[3:] + "_slice" else: slice_type = type.base(environment) + "_slice" to.out("@name@ = new @slice_type@[@dim@];", name=name, slice_type=slice_type, dim=str(dims[0])) n_elements = reduce(lambda x, y: x * y, dims, 1) array_unmarshal_helpers = { idltype.tk_octet: ("get_octet_array", "(_CORBA_Octet*)"), idltype.tk_boolean: ("unmarshalArrayBoolean", "(_CORBA_Boolean*)"), idltype.tk_short: ("unmarshalArrayShort", "(_CORBA_Short*)"), idltype.tk_long: ("unmarshalArrayLong", "(_CORBA_Long*)"), idltype.tk_ushort: ("unmarshalArrayUShort", "(_CORBA_UShort*)"), idltype.tk_ulong: ("unmarshalArrayULong", "(_CORBA_ULong*)"), idltype.tk_float: ("unmarshalArrayFloat", "(_CORBA_Float*)"), idltype.tk_double: ("unmarshalArrayDouble", "(_CORBA_Double*)"), idltype.tk_longlong: ("unmarshalArrayLongLong", "(_CORBA_LongLong*)"), idltype.tk_ulonglong: ("unmarshalArrayULongLong", "(_CORBA_ULongLong*)") } kind = d_type.type().kind() if kind in array_unmarshal_helpers: (helper, typecast) = array_unmarshal_helpers[kind] to.out("@where@.@helper@(@typecast@(@slice_cast@@name@), @num@);", helper=helper, where=from_where, typecast=typecast, name=name, slice_cast=slice_cast, num=str(n_elements)) return # No quick route, generate iteration loop block = cxx.Block(to) loop = cxx.For(to, dims) indexing_string = loop.index() element_name = name + indexing_string if dims != []: type_name = d_type.base(environment) if type_name == element_name: type_name = d_type.base() else: type_name = type.base(environment) if type_name == element_name: type_name = type.base() bounded = "" kind = d_type.type().kind() if d_type.interface(): if type_name.endswith("_ptr"): type_name = type_name[:-4] if isinstance(d_type.type().decl(), idlast.Forward): # hack to denote an interface forward declaration # kind is used to index the associative array below kind = idltype.tk_objref * 1000 elif d_type.value() or d_type.valuebox(): if isinstance(d_type.type().decl(), idlast.ValueForward): kind = idltype.tk_value * 1000 elif d_type.string() or d_type.wstring(): bounded = str(d_type.type().bound()) special_unmarshal_functions = { idltype.tk_boolean: "@element_name@ = @[email protected]();", idltype.tk_octet: "@element_name@ = @[email protected]();", idltype.tk_char: "@element_name@ = @[email protected]();", idltype.tk_wchar: "@element_name@ = @[email protected]();", idltype.tk_string: "@element_name@ = @[email protected](@bounded@);", idltype.tk_wstring: "@element_name@ = @[email protected](@bounded@);", idltype.tk_objref: "@element_name@ = @type@::_unmarshalObjRef(@where@);", idltype.tk_TypeCode: "@element_name@ = ::CORBA::TypeCode::unmarshalTypeCode(@where@);", idltype.tk_objref * 1000: "@element_name@ = @type@_Helper::unmarshalObjRef(@where@);", idltype.tk_value: "@element_name@ = @type@::_NP_unmarshal(@where@);", idltype.tk_value * 1000: "@element_name@ = @type@_Helper::unmarshal(@where@);", idltype.tk_value_box: "@element_name@ = @type@::_NP_unmarshal(@where@);", idltype.tk_abstract_interface: "@element_name@ = @type@::_unmarshalObjRef(@where@);", idltype.tk_local_interface: "@element_name@ = @type@::_unmarshalObjRef(@where@);", } if kind in special_unmarshal_functions: out_template = special_unmarshal_functions[kind] else: if not dims and is_union and kind in [ idltype.tk_any, idltype.tk_struct, idltype.tk_union, idltype.tk_sequence, idltype.tk_except, idltype.tk_fixed ]: out_template = """\ @element_name@ = new @type@; (*@element_name@) <<= @where@; """ else: out_template = "(@type@&)@element_name@ <<= @where@;" to.out(out_template, type=type_name, element_name=element_name, where=from_where, bounded=bounded, dtype=type.member(environment)) loop.end() if dims != []: block.end()