Ejemplo n.º 1
0
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""")
Ejemplo n.º 2
0
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
Ejemplo n.º 3
0
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()