Poco::BinaryWriter, Poco::BinaryReader

Poco::BinaryWriterPoco::BinaryReader を紹介します。
これらは、バイナリでの書き込み/読み出しを、それぞれ std::ostream/std::istream に対して行います。

Big Endian と Little Endian の変換機能も内包していて、デフォルトではその機種ネイティブの Endian になりますが、コンストラクタで指定することができます。
Poco::BinaryWriter::writeBOM() で、Byte Order Mark を書き込んでおき、Poco::BinaryReader::readBOM() を読み出すことにより、Endian の自動変換が実現できます。

BinaryWriterReaderTest.cpp

・各種データタイプのメンバ変数を持つ MyClass を作成し、メンバ変数をランダム化する Randomize() と
 次の operator を実装:
 - std::ostream に対する <<  - Poco::BinaryWriter に対する <<  - Poco::BinaryReader に対する >>
 - MyClass 代入用に =
 - MyClass 比較用に ==
Poco::BinaryWriter のコンストラクタで NETWORK_BYTE_ORDER (Big Endian) を指定し、
 Poco::BinaryWriter::writeBOM() で Byte Order Mak を書き込み。
Poco::BinaryReader は Endian 無指定だが、Poco::BinaryReader::readBOM() を呼ぶことにより、自動
 変換される。
・メンバ変数をランダム化してはテンポラリファイルに保存を繰り替えし、そのテンポラリファイルを
 読み込んで、保存したもののコピーと比較し、一致したら OK を表示。

#include <Poco/Format.h>
#include <Poco/Random.h>
#include <Poco/BinaryWriter.h>
#include <Poco/BinaryReader.h>
#include <Poco/TemporaryFile.h>
#include <Poco/FileStream.h>
 
#include <string>
#include <iostream>
 
#include "ScopedLogMessage.h"
#include "PrepareConsoleLogger.h"
 
const int kNumLoops = 2;
 
class MyClass
{
public:
	MyClass() :
		m_count		(0)
	,	m_bool		(false)
	,	m_char		(0)
	,	m_uChar		(0)
	,	m_short		(0)
	,	m_uShort	(0)
	,	m_int32		(0)
	,	m_uInt32	(0)
	,	m_int64		(0)
	,	m_uInt64	(0)
	,	m_double	(0.0)
	,	m_float		(0.0f)
	,	m_str		("")
	{
	}
	~MyClass()
	{
	}
	void Randomize(void)
	{
		m_bool		= m_rnd.nextBool();
		m_char		= static_cast<char>(m_rnd.next(0x7F) * (m_rnd.nextBool() ? -1:1));
		m_uChar		= static_cast<unsigned char>(m_rnd.nextChar());
		m_short		= static_cast<short>(m_rnd.next(0x7FFF) * (m_rnd.nextBool() ? -1:1));
		m_uShort	= static_cast<unsigned short>(m_rnd.next(0xFFFF));
		m_int32		= m_rnd.next(0x7FFFFFFF) * (m_rnd.nextBool() ? -1:1);
		m_uInt32	= m_rnd.next();
		m_int64		= m_rnd.next(0x7FFFFFFF);
		m_int64		= (m_int64 << 32) + m_rnd.next();
		m_uInt64	= m_rnd.next();
		m_uInt64	= ((m_uInt64 << 32) + m_rnd.next()) * (m_rnd.nextBool() ? -1:1);
		m_double	= static_cast<double>(m_rnd.next()/1000.0);
		m_float		= static_cast<float>(m_rnd.next()/1000.0);
		m_str		= Poco::format("MyClass #%z", ++m_count);
	}
	friend std::ostream& operator << (std::ostream& lhs, MyClass& rhs)
	{
		lhs << Poco::format("m_count  = %z",	rhs.m_count)	<< std::endl;
		lhs << Poco::format("m_bool   = %b",	rhs.m_bool)	<< std::endl;
		lhs << Poco::format("m_char   = %c",	rhs.m_char)	<< std::endl;
		lhs << Poco::format("m_uChar  = %?d",	rhs.m_uChar)	<< std::endl;
		lhs << Poco::format("m_short  = %hd",	rhs.m_short)	<< std::endl;
		lhs << Poco::format("m_uShort = %hu",	rhs.m_uShort)	<< std::endl;
		lhs << Poco::format("m_int32  = %d",	rhs.m_int32)	<< std::endl;
		lhs << Poco::format("m_uInt32 = %u",	rhs.m_uInt32)	<< std::endl;
		lhs << Poco::format("m_int64  = %Ld",	rhs.m_int64)	<< std::endl;
		lhs << Poco::format("m_uInt64 = %Lu",	rhs.m_uInt64)	<< std::endl;
		lhs << Poco::format("m_double = %f",	rhs.m_double)	<< std::endl;
		lhs << Poco::format("m_float  = %hf",	rhs.m_float)	<< std::endl;
		lhs << Poco::format("m_str    = %s",	rhs.m_str)	<< std::endl;
		return lhs;
	}
	friend Poco::BinaryWriter& operator << (Poco::BinaryWriter& lhs, MyClass& rhs)
	{
		lhs	<< rhs.m_count
			<< rhs.m_bool
			<< rhs.m_char
			<< rhs.m_uChar
			<< rhs.m_short
			<< rhs.m_uShort
			<< rhs.m_int32
			<< rhs.m_uInt32
			<< rhs.m_int64
			<< rhs.m_uInt64
			<< rhs.m_double
			<< rhs.m_float
			<< rhs.m_str;
		return lhs;
	}
	friend Poco::BinaryReader& operator >> (Poco::BinaryReader& lhs, MyClass& rhs)
	{
		lhs	>> rhs.m_count
			>> rhs.m_bool
			>> rhs.m_char
			>> rhs.m_uChar
			>> rhs.m_short
			>> rhs.m_uShort
			>> rhs.m_int32
			>> rhs.m_uInt32
			>> rhs.m_int64
			>> rhs.m_uInt64
			>> rhs.m_double
			>> rhs.m_float
			>> rhs.m_str;
		return lhs;
	}
	MyClass& operator = (const MyClass& other)
	{
		if(&other != this)
		{
			m_count		= other.m_count;
			m_bool		= other.m_bool;
			m_char		= other.m_char;
			m_uChar		= other.m_uChar;
			m_short		= other.m_short;
			m_uShort	= other.m_uShort;
			m_int32		= other.m_int32;
			m_uInt32	= other.m_uInt32;
			m_int64		= other.m_int64;
			m_uInt64	= other.m_uInt64;
			m_double	= other.m_double;
			m_float		= other.m_float;
			m_str		= other.m_str;
		}
		return *this;
	}
	bool operator == (const MyClass& other) const
	{
		return	(m_count	== other.m_count)	&&
			(m_bool		== other.m_bool)	&&
			(m_char		== other.m_char)	&&
			(m_uChar	== other.m_uChar)	&&
			(m_short	== other.m_short)	&&
			(m_uShort	== other.m_uShort)	&&
			(m_int32	== other.m_int32)	&&
			(m_uInt32	== other.m_uInt32)	&&
			(m_int64	== other.m_int64)	&&
			(m_uInt64	== other.m_uInt64)	&&
			(m_double	== other.m_double)	&&
			(m_float	== other.m_float)	&&
			(m_str		== other.m_str);
	}
 
private:
	Poco::Random		m_rnd;
	std::size_t		m_count;
	bool			m_bool;
	char			m_char;
	unsigned char		m_uChar;
	short			m_short;
	unsigned short		m_uShort;
	Poco::Int32		m_int32;
	Poco::UInt32		m_uInt32;
	Poco::Int64		m_int64;
	Poco::UInt64		m_uInt64;
	double			m_double;
	float			m_float;
	std::string		m_str;
};
 
int main(int /*argc*/, char** /*argv*/)
{
	PrepareConsoleLogger logger(Poco::Logger::ROOT, Poco::Message::PRIO_INFORMATION);
 
	ScopedLogMessage msg("BinaryWriterReaderTest ", "start", "end");
 
	MyClass myClass;
	MyClass myClassCopy[kNumLoops];
 
	Poco::TemporaryFile file[kNumLoops];
 
	for(int i=0; i<kNumLoops; ++i)
	{
		Poco::FileOutputStream ostr(file[i].path());
 
		myClass.Randomize();
 
		msg.Message(Poco::format(" Write myClass #%d to temporary file #%d", i+1, i+1));
		Poco::BinaryWriter writer(ostr, Poco::BinaryWriter::NETWORK_BYTE_ORDER);
		writer.writeBOM();
		writer << myClass;
		myClassCopy[i] = myClass;
 
		msg.Message(Poco::format("  Dump myClass #%d", i+1));
		std::cout << myClass;
	}
 
	for(int i=0; i<kNumLoops; ++i)
	{
		Poco::FileInputStream istr(file[i].path());
 
		Poco::BinaryReader reader(istr);
		reader.readBOM();
		reader >> myClass;
		msg.Message(Poco::format(" Read  myClass #%d from temporary file #%d [%s]"
					, i+1
					, i+1
					, std::string((myClass == myClassCopy[i]) ? "OK":"NG")));
 
		msg.Message(Poco::format("  Dump myClass #%d", i+1));
		std::cout << myClass;
	}
 
	return 0;
}

Results of execution

[0] BinaryWriterReaderTest start
[0]  Write myClass #1 to temporary file #1
[0]   Dump myClass #1
m_count  = 1
m_bool   = 1
m_char   = ?
m_uChar  = 85
m_short  = -4065
m_uShort = 5093
m_long   = 270786656
m_uLong  = 987867007
m_int64  = 3884473213221576847
m_uInt64 = 14837439087065197879
m_double = 574402.793000
m_float  = 2083766.750000
m_str    = MyClass #1
[0]  Write myClass #2 to temporary file #2
[0]   Dump myClass #2
m_count  = 2
m_bool   = 1
m_char   = {
m_uChar  = 250
m_short  = -24219
m_uShort = 22575
m_long   = 3258173354
m_uLong  = 814509040
m_int64  = 3924086675732884012
m_uInt64 = 11735476326727523416
m_double = 75489.708000
m_float  = 478944.718750
m_str    = MyClass #2
[0]  Read  myClass #1 from temporary file #1 [OK]
[0]   Dump myClass #1
m_count  = 1
m_bool   = 1
m_char   = ?
m_uChar  = 85
m_short  = -4065
m_uShort = 5093
m_long   = 270786656
m_uLong  = 987867007
m_int64  = 3884473213221576847
m_uInt64 = 14837439087065197879
m_double = 574402.793000
m_float  = 2083766.750000
m_str    = MyClass #1
[0]  Read  myClass #2 from temporary file #2 [OK]
[0]   Dump myClass #2
m_count  = 2
m_bool   = 1
m_char   = {
m_uChar  = 250
m_short  = -24219
m_uShort = 22575
m_long   = 3258173354
m_uLong  = 814509040
m_int64  = 3924086675732884012
m_uInt64 = 11735476326727523416
m_double = 75489.708000
m_float  = 478944.718750
m_str    = MyClass #2
[0] BinaryWriterReaderTest end

Downloads

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

Subversion

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

Reference

http://pocoproject.org にある Streams のプレセンテーション。(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>