Poco::ByteOrder

Poco::ByteOrder を紹介します。

Poco::ByteOrder は、各種データ型に対応した Big-Endian と Little-Endian 間のバイトオーダー変換用のスタティックメソッドを持っています。

ByteOrderTest.cpp

・0x12 を元データとして、次の4とおりの変換を
 Poco::Int16, Poco::UInt16, Poco::Int32, Poco::UInt32, Poco::Int64, Poco::UInt64
 の各型毎に行い、その結果を表示:
 - Poco::ByteOrder::flipBytes() -> Poco::ByteOrder::flipBytes()
 - Poco::ByteOrder::toBigEndian() -> Poco::ByteOrder::fromBigEndian()
 - Poco::ByteOrder::toLittleEndian() -> Poco::ByteOrder::fromLittleEndian()
 - Poco::ByteOrder::toNetwork() -> Poco::ByteOrder::fromNetwork()

#include <Poco/Format.h>
#include <Poco/TypeList.h>
#include <Poco/String.h>
#include <Poco/ByteOrder.h>
 
#include <string>
 
#include "ScopedLogMessage.h"
#include "PrepareConsoleLogger.h"
 
#if defined(POCO_ARCH_BIG_ENDIAN)
	const std::string kEndianString = "big-endian";
#else
	const std::string kEndianString = "little-endian";
#endif
 
enum EIntType
{
	eInt16 = 0
,	eUInt16
,	eInt32
,	eUInt32
#if defined(POCO_HAVE_INT64)
,	eInt64
,	eUInt64
#endif
};
 
const std::string intName[] =
{
	"Int16 "
,	"UInt16"
,	"Int32 "
,	"UInt32"
#if defined(POCO_HAVE_INT64)
,	"Int64 "
,	"UInt64"
#endif
};
 
const std::string intFormat[] =
{
	"0x%04?X"
,	"0x%04?X"
,	"0x%08?X"
,	"0x%08?X"
#if defined(POCO_HAVE_INT64)
,	"0x%016?X"
,	"0x%016?X"
#endif
};
 
enum ETestType
{
	eTestFlipBytes = 0
,	eTestBigEndian
,	eTestLittleEndian
,	eTestNetwork
,	eTestNumKind
};
 
const std::string testDesc[] =
{
	"flipBytes, flipBytes"
,	"toBigEndian, fromBigEndian"
,	"toLittleEndian, fromLittleEndian"
,	"toNetwork, fromNetwork"
};
 
typedef Poco::TypeListType<
	Poco::Int16
,	Poco::UInt16
,	Poco::Int32
,	Poco::UInt32
#if defined(POCO_HAVE_INT64)
,	Poco::Int64
,	Poco::UInt64
#endif
>::HeadType IntTypeList;
 
template<EIntType N>
void TestCommon(ScopedLogMessage& msg, int testType)
{
	typedef typename Poco::TypeGetter<N, IntTypeList>::HeadType	IntType;
 
	typedef IntType (*TestFunc)(IntType norm);
	TestFunc func[] = {	Poco::ByteOrder::flipBytes
			,	Poco::ByteOrder::toBigEndian
			,	Poco::ByteOrder::toLittleEndian
			,	Poco::ByteOrder::toNetwork	};
	TestFunc invt[] = {	Poco::ByteOrder::flipBytes
			,	Poco::ByteOrder::fromBigEndian
			,	Poco::ByteOrder::fromLittleEndian
			,	Poco::ByteOrder::fromNetwork	};
 
	IntType norm = 0x12;
	IntType converted = (func[testType])(norm);
	IntType inverted = (invt[testType])(converted);
 
	std::string fmt("   %s fmt -> fmt -> fmt");
	Poco::replaceInPlace(fmt, std::string("fmt"), intFormat[N]);
	msg.Message(Poco::format(fmt.c_str(), intName[N], norm, converted, inverted));
}
 
template<EIntType N>
void TestByteOrder(ScopedLogMessage& msg, int testType)
{
	TestCommon<N>(msg, testType);
	TestByteOrder<static_cast<EIntType>(N+1)>(msg, testType);	// recursive call
}
 
#if defined(POCO_HAVE_INT64)
template<>
void TestByteOrder<eUInt64>(ScopedLogMessage& msg, int testType)
{
	TestCommon<eUInt64>(msg, testType);
}
#else
template<>
void TestByteOrder<eUInt32>(ScopedLogMessage& msg, int testType)
{
	TestCommon<eUInt32>(msg, testType);
}
#endif
 
int main(int /*argc*/, char** /*argv*/)
{
	PrepareConsoleLogger logger(Poco::Logger::ROOT, Poco::Message::PRIO_INFORMATION);
 
	ScopedLogMessage msg("ByteOrderTest ", "start", "end");
 
	msg.Message(Poco::format(" This is a %s computer system.", kEndianString));
 
	for(int i=eTestFlipBytes; i<eTestNumKind; ++i)
	{
		msg.Message(" " + testDesc[i] + ":");
		TestByteOrder<eInt16>(msg, i);
	}
 
	return 0;
}

Results of execution

– On little-endian computer

[0] ByteOrderTest start
[0]  This is a little-endian computer system.
[0]  flipBytes, flipBytes:
[0]    Int16  0x0012 -> 0x1200 -> 0x0012
[0]    UInt16 0x0012 -> 0x1200 -> 0x0012
[0]    Int32  0x00000012 -> 0x12000000 -> 0x00000012
[0]    UInt32 0x00000012 -> 0x12000000 -> 0x00000012
[0]    Int64  0x0000000000000012 -> 0x1200000000000000 -> 0x0000000000000012
[0]    UInt64 0x0000000000000012 -> 0x1200000000000000 -> 0x0000000000000012
[0]  toBigEndian, fromBigEndian:
[0]    Int16  0x0012 -> 0x1200 -> 0x0012
[0]    UInt16 0x0012 -> 0x1200 -> 0x0012
[0]    Int32  0x00000012 -> 0x12000000 -> 0x00000012
[0]    UInt32 0x00000012 -> 0x12000000 -> 0x00000012
[0]    Int64  0x0000000000000012 -> 0x1200000000000000 -> 0x0000000000000012
[0]    UInt64 0x0000000000000012 -> 0x1200000000000000 -> 0x0000000000000012
[0]  toLittleEndian, fromLittleEndian:
[0]    Int16  0x0012 -> 0x0012 -> 0x0012
[0]    UInt16 0x0012 -> 0x0012 -> 0x0012
[0]    Int32  0x00000012 -> 0x00000012 -> 0x00000012
[0]    UInt32 0x00000012 -> 0x00000012 -> 0x00000012
[0]    Int64  0x0000000000000012 -> 0x0000000000000012 -> 0x0000000000000012
[0]    UInt64 0x0000000000000012 -> 0x0000000000000012 -> 0x0000000000000012
[0]  toNetwork, fromNetwork:
[0]    Int16  0x0012 -> 0x1200 -> 0x0012
[0]    UInt16 0x0012 -> 0x1200 -> 0x0012
[0]    Int32  0x00000012 -> 0x12000000 -> 0x00000012
[0]    UInt32 0x00000012 -> 0x12000000 -> 0x00000012
[0]    Int64  0x0000000000000012 -> 0x1200000000000000 -> 0x0000000000000012
[0]    UInt64 0x0000000000000012 -> 0x1200000000000000 -> 0x0000000000000012
[0] ByteOrderTest end

– On big-endian computer

[0] ByteOrderTest start
[0]  This is a big-endian computer system.
[0]  flipBytes, flipBytes:
[0]    Int16  0x0012 -> 0x1200 -> 0x0012
[0]    UInt16 0x0012 -> 0x1200 -> 0x0012
[0]    Int32  0x00000012 -> 0x12000000 -> 0x00000012
[0]    UInt32 0x00000012 -> 0x12000000 -> 0x00000012
[0]    Int64  0x0000000000000012 -> 0x1200000000000000 -> 0x0000000000000012
[0]    UInt64 0x0000000000000012 -> 0x1200000000000000 -> 0x0000000000000012
[0]  toBigEndian, fromBigEndian:
[0]    Int16  0x0012 -> 0x0012 -> 0x0012
[0]    UInt16 0x0012 -> 0x0012 -> 0x0012
[0]    Int32  0x00000012 -> 0x00000012 -> 0x00000012
[0]    UInt32 0x00000012 -> 0x00000012 -> 0x00000012
[0]    Int64  0x0000000000000012 -> 0x0000000000000012 -> 0x0000000000000012
[0]    UInt64 0x0000000000000012 -> 0x0000000000000012 -> 0x0000000000000012
[0]  toLittleEndian, fromLittleEndian:
[0]    Int16  0x0012 -> 0x1200 -> 0x0012
[0]    UInt16 0x0012 -> 0x1200 -> 0x0012
[0]    Int32  0x00000012 -> 0x12000000 -> 0x00000012
[0]    UInt32 0x00000012 -> 0x12000000 -> 0x00000012
[0]    Int64  0x0000000000000012 -> 0x1200000000000000 -> 0x0000000000000012
[0]    UInt64 0x0000000000000012 -> 0x1200000000000000 -> 0x0000000000000012
[0]  toNetwork, fromNetwork:
[0]    Int16  0x0012 -> 0x0012 -> 0x0012
[0]    UInt16 0x0012 -> 0x0012 -> 0x0012
[0]    Int32  0x00000012 -> 0x00000012 -> 0x00000012
[0]    UInt32 0x00000012 -> 0x00000012 -> 0x00000012
[0]    Int64  0x0000000000000012 -> 0x0000000000000012 -> 0x0000000000000012
[0]    UInt64 0x0000000000000012 -> 0x0000000000000012 -> 0x0000000000000012
[0] ByteOrderTest end

Downloads

ここをクリックすると、makefile や VC++ プロジェクトなど一式がダウンロードできます。
(2013.05.31 updated)
・2010年7月13日からのダウンロード数:781

Subversion

・フリーの Subversion ホスティングサービス Assemblaで、ソースコードを管理しています。

Reference

http://pocoproject.org にある Types のプレセンテーション。(PDF)

Powered by POCO Copyright © 2010 Round Square Inc. All rights reserved.


Leave a Comment


NOTE - You can use these HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>