Poco::BinaryWriter と Poco::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日からのダウンロード数:1111
Subversion
・フリーの Subversion ホスティングサービス Assemblaで、ソースコードを管理しています。
Reference
・http://pocoproject.org にある Streams のプレセンテーション。(PDF)
![]() |
Copyright © 2010 Round Square Inc. All rights reserved. |
---|
0 Comments.