Boost logo

Boost :

Subject: Re: [boost] [endain_ext] Beman's Integer.Endian extensions towork with endian unaware data
From: vicente.botet (vicente.botet_at_[hidden])
Date: 2010-06-14 10:49:57


From: "Stewart, Robert" <Robert.Stewart_at_[hidden]>
To: <boost_at_[hidden]>
Sent: Monday, June 14, 2010 1:42 PM
Subject: Re: [boost] [endain_ext] Beman's Integer.Endian extensions towork with endian unaware data

>
> vicente.botet wrote:
>> Rob Stewart wrote:
>> > vicente.botet wrote:

> The MPL vectors are, IIUC, a sequential list of the endiannesses of each field in the domain_map's second template parameter, right?

Yes, it can be. But note also that when you have embeedded structures the mpl vector can contains the endianness or a mpl vector od endianness,i.e. it formes a tree.
 
> I don't quite get the "relative to the interface" part. It would seem more reasonable to declare how to convert each field's endianness to the first template parameter's endianness or else to simply declare each field's endianness (more below).

Maybe I'm overgenralizing, but I don't think so. The same C++ type can be have different endianness map relative to two interfaces. For example, a relay that receives a message from one normalized interface, change someting specific, and relays it throw another internal interface. The endianness used for the normalized and the internal should nto be the same. The domain map is used to manage with this.
 
>> >
>> > The type duplication is unfortunate, but that was necessary
>> > in Beman's approach, too.
>>
>> You mean Tom's approach?
>
> No, I did mean Beman's approach, which necessitates declaring a duplicate structure of endian types when you need or are given a native type structure (such as an OS or RTL structure) for an API. (struct tm, for example, would require a duplicate, endian-type-based structure in Beman's approach.)

This could be the case, but it is not always the case, as I have tried to explain in other posts, as all applications don't need to transform the message to the native format. Some will just copy some data to local variables and specific contexts that don't share the same structure at all.

>> The difference is that Tom used a different macro, so an
>> application needing to see the structure has fussion
>> sequence and to define the Tom swap function needed to declare both.
>
> I've totally lost track of how Tomas' worked, hence my wishing to see the same example in both approaches.

You can jump to the first post, that includes Tom approach to manage with swap in place for structures.

>> >> // convert from the network to the native domain
>> >> endian::convert_from<network>(m);
>> >
>> > Here you have declared that the current data in m is in
>> > network order and requested that it be converted to host
>> > order, right?
>>
>> Just a precission. Convert from *the point of view given by
>> the domain map 'network or "ifA"* to the native endian. I
>> repeat the use of the "network" point of view let some of you
>> think that it was big-endian,but it wsa not big-endian in all
>> the cases.
>
> So, this code, combined with the domain_map specialization above says that, m.a is big endian relative to "network" (or "ifA" if you had written endian::convert_from<ifA>(m)) and that "network" somehow implies a mapping to host order. I don't quite get the point of that relativity.

See above (two interfaces)
 
> If your domain_map were, instead, an endianness_map that merely noted the endianness of each field, then the foregoing would make more sense. I mean something like this:
>
> template <>
> struct endianness_map<X::big_c>
> {
> typedef mpl::vector<big,big> type;
> };

This will always be possible if a C++ structure can have just an endianness, but this will force you to define two structures with the same native format, but different endianness, and I think that you want to avoid this duplication.
 
> That would enable the following invocation, unless I'm mistaken:
>
> endian::convert_from(m);
>
> Here, "convert_from" implies from the endianness of "m" which is described by the endianness_map<X::big_c> specialization, to host order (implicit in the name). At that point, it seems that "to_host" would be clearer:
>
> endian::to_host(m);
>
> Isn't that possible and more straightforward?

This could be possible, as far as we restrict to one endiannes by C++ type.
 
> It would be nice if the BOOST_FUSION_ADAPT_STRUCT functionality could be reused to get the following syntax:
>
> BOOST_ENDIAN_ADAPT_STRUCT(X::big_c,
> (uint32_t, big, a)
> (uint16_t, big, b)
> )

Yes, if a single endianness is the common case, this could be useful.

>> > That's no different, other than implementation details,
>> > than what Tomas originally provided, IIUC.
>>
>> Tom's swap_in_place force to interpret all the fields of the
>> structure with the same endianness.
>
> Ah, right.
>
>> Here it is the code generated (gcc-4.4 -O3) to do the
>> conversion from big to little + the initialization of the variable.
>>
>> I don't understand this code, but IMO the code has been
>> completly inlined.

I have made the test using htons/l and the generated assembler is identical :)

    integer::convert_from<network>(m.a);
    //~ m.a.a=htonl(m.a.a);
    //~ m.a.b=htons(m.a.b);

Best,
Vicente


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk