Boost logo

Boost :

Subject: Re: [boost] [boost::endian] Request for comments/interest
From: Terry Golubiewski (tjgolubi_at_[hidden])
Date: 2010-05-27 02:12:39


I was responding to some of the examples in Robert Stewart's reply, which I
snipped unfortunately.
I hadn't even looked at your library yet. I see that most of my comments do
not apply to your code.

Often, when I receive a "message" over-the-wire, I only want to examine some
fields of the message and ignore the rest.
Different sections of code process different parts of received messages, so
it would be dangerous to do in-place swapping (for my way of doing things).

Beman's approach has gradually become more integer-centric over time, with
alignment support and supporting odd-sized integers.
I believe that the endian problem is primarily an interface problem.
Here is a simplified version of Beman's approach that is quite simple and
just wraps a user-type T, so you would just write

struct MyMessage {
  endian<big, MyType> big_field;
  endian<little, MyType> lil_field;
  endian<native, MyType> scary_field;
}; // Message

in your over-the-wire messages and then

MyType x = msg.big_field;
msg.lil_field = x;

Here's the (draft, possibly naive) code for this approach.

terry

namespace boost { namespace interface {

struct uninitialized_t { };
static const uninitialized_t uninitialized;

enum endian_t { little, big };

#ifdef BOOST_BIG_ENDIAN
  static const endian_t native = big;
#else
  static const endian_t native = little;
#endif

namespace detail {

template<endian_t E, class T, std::size_t L> inline
void Retrieve(T* value, const array<uint8_t, L>& bytes);

template<endian_t E, class T std::size_t L> inline
void Store(array<uint8_t, L>& bytes, const T& value);

} // detail

#pragma pack(push, 1)

template<endian_t E, class T>
class endian {
public:
  static const endian_t endian_type = E;
  typedef T value_type;

private:
  static const std::size_t storage_size = sizeof(T);
  array<uint8_t, storage_size> m_storage;

public:
  endian() { detail::Store<endian_type>(m_storage, T()); }

  endian(uninitialized_t) { }

  endian(const value_type& x)
    { detail::Store<endian_type>(m_storage, x); }

  value_type value() const {
    value_type rval;
    detail::Retrieve<endian_type>(&rval, m_storage);
    return rval;
  } // value

  operator value_type() const { return value(); }

  endian& operator=(const value_type& rhs) {
    detail::Store<endian_type>(m_storage, rhs);
    return *this;
  } // operator=

  }; // endian

// Specialize for native endian types.
template<endian_t E, class T>
class endian<native, T> {
public:
  static const endian_t endian_type = native;
  typedef T value_type;

private:
  T m_value;

public:
  endian() : m_value() { }
  endian(uninitiazed_t) { }
  endian(const value_type& x) : m_value(x) { }
  value_type value() const { return m_value; }
  operator value_type() const { return value(); }
  endian& operator=(const value_type& rhs) { m_value = rhs; }
}; // endian

#pragma pack(pop)

} } // boost::interface


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