[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-devel
Subject:    Re: Byte order conversions
From:       Rüdiger_Knörig <ruediger () knoerig ! de>
Date:       2004-10-27 12:29:31
Message-ID: 200410271429.31772.ruediger () knoerig ! de
[Download RAW message or body]

Am Mittwoch, 27. Oktober 2004 14:42 schrieb Szombathelyi György:
> Hello!
>
> Is there anyone who knows convenient byte-order conversion functions in
> QT/kdelibs? If not, then what about adding some functions like
> {be2me,le2me,me2be,me2le}_{16,32,64) (prefixed with the usual 'K')?. As
> I browse through the code, every piece of code which requires this
> functionality implements its own solution, usually with ugly macros and
> #ifdef WORDS_BIGENDIAN conditionals.
>
> If it's ok, I'll volunteer for implementing (read: steal from somewhere
>
> :) ) these.
>
> Bye,
> György
>
> >> Visit http://mail.kde.org/mailman/listinfo/kde-devel#unsub to
> >> unsubscribe <<
The attachment contains a template class which will do the job. For automatic 
conversion of custom datatypes the autoconf macros AC_C_BIGENDIAN(), 
AC_CHECK_SIZE(short) and AC_CHECK_SIZE(int) have to be executed.
If these macros exist you can convert from host endianess via:
ConvertEndianess<double>::convert(doubleval,Endian::BigEndian);
or change the endianess via
ConvertEndianess<double>::swapEndianess(doubleval);

["ConvertEndianess.h" (text/x-chdr)]

/***************************************************************************
 *   Copyright (C) 2003 by Rüdiger Knörig                                  *
 *   ruediger@knoerig.de                                                   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 ***************************************************************************/

 /**
  * @file ConvertEndianess.h
  * @brief This file provides a template class for endianess conversion.
  * @author Ruediger Knoerig
  */

#ifndef _ENDIANESSCONVERTER_TEMPLATE_CLASS_RUDI_2003_
#define _ENDIANESSCONVERTER_TEMPLATE_CLASS_RUDI_2003_

namespace Endian
{
  /** endianess definition */
  enum Endianess {
   LittleEndian=0, /**< little endian byte order (least significant byte first) */
   BigEndian=1, /**< big endian byte order (most significant byte first) */
   IgnoreEndian=2 /**< ignore endianess, don't do any conversion */
  };
}

/**
 * @brief utility class providing template byte order swapping.
 * @author Ruediger Knoerig
 */
template<class T,int length> class ByteSwapper
{
 public:
  /**
   * method doing the byte order swap
   * @param input input with byte order ABCD (for length-4-input)
   * @return output input with byte order DCBA (for length-4-input)
   */
  static const T swapBytes(T input);
};

/**
 * implementation of swap_bytes for generic lengths
 */
template<class T,int length> const T ByteSwapper<T,length>::swapBytes(T input)
{
  T output;
  char *src = reinterpret_cast<char *>(&input);
  char *dst = reinterpret_cast<char *>(&output)+length;
  do { *(--dst) = *(src++); }while(dst != reinterpret_cast<char *>(&output));
  return output;
}

/**
 * @brief specialization of ByteSwapper for length=1.
 * @author Ruediger Knoerig
 */
template<class T> class ByteSwapper<T,1>
{
 public:
  /**
   * method doing the byte order swap for length-1 inputs
   * @param input length-1-input
   * @return output input
   */
  static const T swapBytes(T input) { return input; }
};

/**
 * @brief specialization of ByteSwapper for length=2.
 * @author Ruediger Knoerig
 */

#if SIZEOF_SHORT==2
template<class T> class ByteSwapper<T,2>
{
 public:
  /**
   * method doing the byte order swap
   * The algorithm has been taken from http://www.pyrogon.com/poshlib/posh_8c-source.html.
   * @param input length-2-input AB
   * @return output input with byte order BA
   */
  static const T swapBytes(T input);
};

template<class T> const T ByteSwapper<T,2>::swapBytes(T input)
{
  unsigned short ip = *reinterpret_cast<unsigned short *>(&input);
  unsigned short op = ip >> 8;
  op |= (ip << 8);
  return *reinterpret_cast<T *>(&op);
}
#endif

#if SIZEOF_INT==4
/**
 * @brief specialization of ByteSwapper for length=4.
 * @author Ruediger Knoerig
 */
template<class T> class ByteSwapper<T,4>
{
 public:
  /**
   * method doing the byte order swap
   * The algorithm has been taken from http://www.pyrogon.com/poshlib/posh_8c-source.html.
   * @param input length-4-input ABCD
   * @return output input with byte order DCBA
   */
  static const T swapBytes(T input);
};

template<class T> const T ByteSwapper<T,4>::swapBytes(T input)
{
 unsigned int ip = *reinterpret_cast<unsigned int *>(&input);
 unsigned int op = ( ip & 0xFF ) << 24;
 op |= ( ip & 0xFF00 ) << 8;
 op |= ( ip >> 8 ) & 0xFF00;
 op  |= ( ip >> 24 );
 return *reinterpret_cast<T *>(&op);
}
#endif


/**
 * @brief Template class for generic endianess conversion.
 * @author Ruediger Knoerig
 */
template<class T> class ConvertEndianess : public ByteSwapper< T,sizeof(T)>
{
 public:
  /** constructor */
  ConvertEndianess() {}

  /** destructor */
  virtual ~ConvertEndianess() {}

  /**
   * method for inverting the byte order of the input
   * @param input input data with byte sequence ABCD
   * @return output output data with byte sequence DCBA
   */
  static const T swapEndianess(T input) { return swapBytes(input); }

  /**
   * @brief method for converting the byte order of input from/to host endianess.
   * The host byte order is checked by the macro WORDS_BIGENDIAN, which in turn
   * is set by AC_C_BIGENDIAN().
   * @param input value to convert
   * @param endianess desired endianess @see Endian::Endianess
   * @return input input in new byte order
   */
  static const T convert(T input,Endian::Endianess endianess);
};


template<class T> const T ConvertEndianess<T>::convert(T input,Endian::Endianess endianess)
{
#ifdef WORDS_BIGENDIAN
 return ((endianess==Endian::LittleEndian) ? swapBytes(input) : input);
#else
 return ((endianess==Endian::BigEndian) ? swapBytes(input) : input);
#endif
}

#endif


>> Visit http://mail.kde.org/mailman/listinfo/kde-devel#unsub to unsubscribe <<


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic