[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