Boost logo

Boost :

Subject: [boost] [endain_ext] Beman's Integer.Endian extensions to work with endian unaware data
From: vicente.botet (vicente.botet_at_[hidden])
Date: 2010-06-10 18:12:22


Hi,

I have a implemented a prototype that allows to make endian conversions in place respect to an endian point of view (domain) of endian unaware data. The point of view is represented by a map from the native data types to an endian tree, which have mpl sequences as nodes and the leaves are the endianess of the integer types.

namespace endian {
    struct big {};
    struct little {};
# ifdef BOOST_BIG_ENDIAN
    typedef big native ;
# elsif BOOST_LITTLE_ENDIAN
    typedef little native ;
# error "Endian not detected."
# endif

}

Two functions to convert any data in place are provided:

template <typename Domain, typename T>
void convert_from(T& r);

template <typename Domain, typename T>
void convert_to(T& r);

The default implementation works for fusion sequences. So the user will need to adapt the structures so them are viewed as fusion sequences or overload the functions.

Next follows an example that defines 3 structures, and a point of view (domain) that see one of then as big, the second as little and the third as a mix of big and little.

using namespace boost;
// native structs definition
namespace X {
struct big_c {
    uint32_t a;
    uint16_t b;
};
struct little_c {
    int32_t a;
    int16_t b;
};
struct mixed_c {
    big_c a;
    little_c b;
};
}

// definition of a point of view (domain)
struct network {};

// mapping of native types to an endian tree for the network point of view (domain)
namespace boost { namespace endian {
    template <>
    struct domain_map <network, X::big_c> {
        typedef mpl::vector<big,big> type;
    };
    template <>
    struct domain_map <network, X::little_c> {
        typedef mpl::vector<little,little> type;
    };
    
}}

// view of the structures as fusion sequences
BOOST_FUSION_ADAPT_STRUCT(X::big_c,
    (uint32_t, a)
    (uint16_t, b)
)
BOOST_FUSION_ADAPT_STRUCT(X::little_c,
    (int32_t, a)
    (int16_t, b)
)
BOOST_FUSION_ADAPT_STRUCT(X::mixed_c,
    (X::big_c, a)
    (X::little_c, b)
)

int main( int argc, char * argv[] ) {

    X::mixed_c m;
    // fill with data from the 'network' domain (emulating the reception from the domain 'network')
    m.a.a=0x01020304;
    m.a.b=0x0A0B;
    m.b.a=0x04030201;
    m.b.b=0x0B0A;
    
    std::cout << std::hex << m.a.a << std::endl;
    std::cout << std::hex << m.a.b << std::endl;
    std::cout << std::hex << m.b.a << std::endl;
    std::cout << std::hex << m.b.b << std::endl;
    
    // convert from the network to the native domain
    endian::convert_from<network>(m);
    std::cout << std::hex << m.a.a << std::endl;
    std::cout << std::hex << m.a.b << std::endl;
    std::cout << std::hex << m.b.a << std::endl;
    std::cout << std::hex << m.b.b << std::endl;

    // work with the native variable
    // ...

    // convert from the native to the network domain
    endian::convert_from<network>(m);
    std::cout << std::hex << m.a.a << std::endl;
    std::cout << std::hex << m.a.b << std::endl;
    std::cout << std::hex << m.b.a << std::endl;
    std::cout << std::hex << m.b.b << std::endl;

    return 0;
}

The result is:
1020304
a0b
4030201
b0a
1020304
a0b
4030201
b0a
1020304
a0b
4030201
b0a

The library could define three predefined maps for the domain endian::native, endian::big, endian::little, which maps every leaf to the corresponding endian type.

I have not see the assembler generated, but the design is there to do nothing when the in place conversion concerns the same endianness.

The library is based on the one from Beman's.
* I have split the the endian class on two levels:
  - endian_pack
  - endian.
* replaced the enum class endianness by a endianness tag (see above)
* I have added an endian_view class that is a reference to a native type viewed with a specific endianess (a kind of endian_cast).
* An last I have added on top the requested 'in place conversion' functions.

The last two features work with endian anaware data. I could add pure conversions if needed on endian anaware data.

The used names for functions and classes and under what namespace put them should yet be determined.

All the sources can be found in the sandbox under http://svn.boost.org/svn/boost/sandbox/endian_ext. Documentation will come later :(.

As always, comments are welcome :)
_____________________
Vicente Juan Botet Escribá
http://viboes.blogspot.com/


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