Skip to content

Latest commit

 

History

History
263 lines (242 loc) · 8.96 KB

bundle.adoc

File metadata and controls

263 lines (242 loc) · 8.96 KB

<bundle> Field

The <bundle> is a container field, which aggregates multiple independent fields (of any kind) into a single one. The <bundle> field has all the common properties.

Member Fields

Member fields need to be listed as children XML elements of the <bundle>.

<?xml version="1.0" encoding="UTF-8"?>
<schema name="MyProtocol" endian="big">
    <fields>
        <bundle name="SomeBundle">
            <int name="SomeIntMember" type="uint8" />
            <set name="SomeSetMember" length="1">
                ...
            </set>
            <enum name="SomeEnumMember" type="uint8">
                ...
            </enum>
            <bundle name="SomeInnerBundle">
                ...
            </bundle>
        </bundle>
    </fields>
</schema>

If there is any other property defined as XML child of the <bundle>, then all the members must be wrapped in <members> XML element for separation.

<?xml version="1.0" encoding="UTF-8"?>
<schema name="MyProtocol" endian="big">
    <fields>
        <bundle name="SomeBundle">
            <displayName value="Proper Bundle Name" />
            <members>
                <int name="SomeIntMember" type="uint8" bitLength="3" />
                <set name="SomeSetMember" length="1">
                    ...
                </set>
                <enum name="SomeEnumMember" type="uint8">
                    ...
                </enum>
                <bundle name="SomeInnerBundle">
                    ...
                </bundle>
            </members>
        </bundle>
    </fields>
</schema>

Reusing Other <bundle>

Like any other field, <bundle> supports reuse of any other <bundle>. Such reuse copies all the fields from original <bundle> in addition to all the properties. Any new defined member field gets appended to the copied ones.

<?xml version="1.0" encoding="UTF-8"?>
<schema name="MyProtocol" endian="big">
    <fields>
        <bundle name="SomeBundle">
            <int name="F1" type="uint32" />
            <float name="F2" type="float" />
        </bundle>

        <bundle name="SomeOtherBundle" reuse="SomeBundle">
            <string name="F3" length="16" />
        </bundle>
    </fields>
</schema>

In the example above SomeOtherBundle has 3 member fields: F1, F2, and F3.

Replacing Member Fields

It is possible to replace some of the copied member fields after reuse using <replace> child node, which wraps the replacing fields.

<?xml version="1.0" encoding="UTF-8"?>
<schema name="MyProtocol" endian="big">
    <fields>
        <bundle name="SomeBundle">
            <int name="Mem1" type="uint8" />
            <enum name="Mem2" type="uint8">
                <validValue name="V0" val="0" />
                <validValue name="V1" val="1" />
            </enum>
        </bundle>

        <bundle name="SomeOtherBundle" reuse="SomeBundle">
            <replace>
                <set name="Mem2" type="uint8">
                    <bit name="B0" idx="0" />
                    <bit name="B1" idx="1" />
                </set>
            </replace>
        </bundle>
    </fields>
</schema>

The replacing field must have the same name as the reused member field it is replacing. The <replace> child node may have multiple member fields replacing the copied ones. The order of the fields inside the <replace> child node is not important, the order of the fields is determined by the original <bundle> field, which was reused.

It is possible to combine <replace>-ing copied member fields and extending the <bundle> with new fields.

<?xml version="1.0" encoding="UTF-8"?>
<schema name="MyProtocol" endian="big">
    <fields>
        <bundle name="SomeBundle">
            <int name="Mem1" type="uint8" />
            <enum name="Mem2" type="uint8">
                <validValue name="V0" val="0" />
                <validValue name="V1" val="1" />
            </enum>
        </bundle>

        <bundle name="SomeOtherBundle" reuse="SomeBundle">
            <replace>
                <set name="Mem2" type="uint8">
                    <bit name="B0" idx="0" />
                    <bit name="B1" idx="1" />
                </set>
            </replace>
            <members>
                <int name="Mem3" type="uint16" />
            </members>
        </bundle>
    </fields>
</schema>

The example above is equivalent to defining SomeOtherBundle <bundle> field in the following way.

<?xml version="1.0" encoding="UTF-8"?>
<schema name="MyProtocol" endian="big">
    <fields>
        <bundle name="SomeOtherBundle">
            <int name="Mem1" type="uint8" />
            <set name="Mem2" type="uint8">
                <bit name="B0" idx="0" />
                <bit name="B1" idx="1" />
            </set>
            <int name="Mem3" type="uint16" />
        </bundle>
    </fields>
</schema>

Alias Names to Member Fields

Sometimes an existing member field may be renamed and/or moved. It is possible to create alias names for the fields to keep the old client code being able to compile and work. Please refer to Aliases chapter for more details.

Extra Validity Conditions

The valid operation of every <bundle> means invoking the valid operation for every one of its member fields. However, the valid values of fields may be interdependent. There may be a need to introduce extra validity checks on the <bundle> contents. To do so the validCond property referencing appropriate member fields of the <bundle> itself can be used. The syntax is the same as with the <optional> field’s existence conditions (described later).

<?xml version="1.0" encoding="UTF-8"?>
<schema ...>
    <fields>
        <bundle name="SomeBundle" validCond="$Mem1 != $Mem2">
            <int name="Mem1" type="uint8" />
            <int name="Mem2" type="uint16" />
        </bundle>
    </fields>
</schema>

In case of multiple conditions the validCond needs to be specified as the <validCond> child node with a single <and> or <or> immediate child. Nested <and> and/or <or> conditions are allowed in the same way as with the <optional> field’s existence conditions. The only difference is that the inner child nodes must be named validCond instead of cond.

<?xml version="1.0" encoding="UTF-8"?>
<schema ...>
    <fields>
        <bundle name="SomeBundle">
            <members>
                <int name="Mem1" type="uint8" />
                <int name="Mem2" type="uint16" />
            </members>
            <validCond>
                <or>
                    <validCond value="$Mem1 = 0" />
                    <validCond value="$Mem2 != 0" />
                </or>
            </validCond>
        </bundle>
    </fields>
</schema>

In case some other <bundle> have similar fields and the same extra validity conditions apply to the <bundle> field being defined, it is possible to copy the conditions using copyValidCondFrom property.

<?xml version="1.0" encoding="UTF-8"?>
<schema ...>
    <fields>
        <bundle name="SomeBundle" validCond="$Mem1 != $Mem2">
            <int name="Mem1" type="uint8" />
            <int name="Mem2" type="uint16" />
        </bundle>

        <bundle name="SomeOtherBundle" copyValidCondFrom="SomeBundle">
            <int name="Mem3" type="uint32" />
            <int name="Mem1" type="uint8" />
            <int name="Mem2" type="uint16" />
        </bundle>
    </fields>
</schema>

Note that copyValidCondFrom is an action property, which causes the copy of the original validity conditions. When such field is reused in the future the original definition doesn’t really have property named copyValidCondFrom to be copied, only the real validity condition(s). The SomeOtherBundle definition above is equivalent to:

<?xml version="1.0" encoding="UTF-8"?>
<schema ...>
    <fields>
        <bundle name="SomeOtherBundle" validCond="$Mem1 != $Mem2">
            <int name="Mem3" type="uint32" />
            <int name="Mem1" type="uint8" />
            <int name="Mem2" type="uint16" />
        </bundle>
    </fields>
</schema>

Use properties table for future references.