LinuxC/C++編程基礎(36) Poco::BinaryReader的實現

來源:互聯網
上載者:User

一.BinaryReader.h的定義如下:

#ifndef LINYANWENBINARYREADER_H_
#define LINYANWENBINARYREADER_H_

#include "Poco/TextConverter.h"
#include "Poco/Foundation.h"
#include <vector>
#include <istream>
namespace Linyanwen {
class TextEncoding;
class BinaryReader
 /// This class reads basic types (and std::vectors thereof)
 /// in binary form into an input stream.
 /// It provides an extractor-based interface similar to istream.
 /// The reader also supports automatic conversion from big-endian
 /// (network byte order) to little-endian and vice-versa.
 /// Use a BinaryWriter to create a stream suitable for a BinaryReader.
{
public:
 enum StreamByteOrder
 {
  NATIVE_BYTE_ORDER        = 1,  /// the host's native byte-order
  BIG_ENDIAN_BYTE_ORDER    = 2,  /// big-endian (network) byte-order
  NETWORK_BYTE_ORDER       = 2,  /// big-endian (network) byte-order
  LITTLE_ENDIAN_BYTE_ORDER = 3,  /// little-endian byte-order
  UNSPECIFIED_BYTE_ORDER   = 4   /// unknown, byte-order will be determined by reading the byte-order mark
 };
 BinaryReader(Poco::UInt8* _buffer,Poco::UInt32 _size);
 ~BinaryReader();
 BinaryReader& operator >>(bool& value);
 BinaryReader& operator >>(char& value);
 BinaryReader& operator >>(unsigned char& value);
 BinaryReader& operator >>(signed char& value);
 BinaryReader& operator >>(short& value);
 BinaryReader& operator >>(unsigned short& value);
 BinaryReader& operator >>(int& value);
 BinaryReader& operator >>(unsigned int& value);
 BinaryReader& operator >>(long& value);
 BinaryReader& operator >>(unsigned long& value);
 BinaryReader& operator >>(float& value);
 BinaryReader& operator >>(double& value);
 BinaryReader& operator >> (std::string& value);
 /****************************************/
 void   read7BitEncoded(Poco::UInt32& value);
 void   readRaw(std::streamsize length, std::string& value);
 // Reads length bytes of raw data into value.
 void   readRaw(char* buf, std::streamsize length);
 // Reads length bytes of raw data into buf.
 /****************************************/
 bool  good();
private:
 bool               _flipBytes;
 Poco::TextConverter*   _pTextConverter;
 Poco::UInt8*       buffer;
 Poco::UInt32       size;
 Poco::Int32        beg,end,cur;
};
inline bool BinaryReader::good(){
 return cur < size;//注意cur是從0開始,size是從1開始計數的,所以是'<'而不是'<='
}
} // namespace Linyanwen

#endif /* LINYANWENBINARYREADER_H_ */

 

二.BinaryReader.cpp的實現,如下:

#include "LinyanwenBinaryReader.h"
#include "Poco/BinaryReader.h"
#include "Poco/ByteOrder.h"
#include "Poco/TextEncoding.h"
#include <algorithm>
namespace Linyanwen {

BinaryReader::BinaryReader(Poco::UInt8* _buffer,Poco::UInt32 _size):buffer(_buffer),size(_size)
  ,beg(0),cur(0),end(_size),_pTextConverter(0)
{
#if defined(POCO_ARCH_BIG_ENDIAN)
 _flipBytes = (BinaryReader::NETWORK_BYTE_ORDER == LITTLE_ENDIAN_BYTE_ORDER);
#else
 _flipBytes = (BinaryReader::NETWORK_BYTE_ORDER == BIG_ENDIAN_BYTE_ORDER);
#endif
}
BinaryReader::~BinaryReader()
{
 delete _pTextConverter;
}

BinaryReader& BinaryReader::operator >> (bool& value)
{
// _istr.read((char*) &value, sizeof(value));
 *((char*)&value) = *(buffer+cur);
 ++cur;
 return *this;
}
BinaryReader& BinaryReader::operator >> (char& value)
{
// _istr.read((char*) &value, sizeof(value));
 *((char*)&value) = *(buffer+cur);
 ++cur;
 return *this;
}
BinaryReader& BinaryReader::operator >> (unsigned char& value)
{
// _istr.read((char*) &value, sizeof(value));
 *((char*)&value) = *(buffer+cur);
 ++cur;
 return *this;
}
BinaryReader& BinaryReader::operator >> (signed char& value)
{
// _istr.read((char*) &value, sizeof(value));
 *((char*)&value) = *(buffer+cur);
 ++cur;
 return *this;
}
BinaryReader& BinaryReader::operator >> (short& value)
{
// _istr.read((char*) &value, sizeof(value));
 for(int i=0;i<sizeof(value);++i)
  *((char*)&value+i) = *(buffer+cur+i);
 cur = cur + sizeof(value);
 if (_flipBytes) value = Poco::ByteOrder::flipBytes(value);
 return *this;
}
BinaryReader& BinaryReader::operator >> (unsigned short& value)
{
// _istr.read((char*) &value, sizeof(value));
 for(int i=0;i<sizeof(value);++i)
   *((char*)&value+i) = *(buffer+cur+i);
 cur = cur + sizeof(value);
 if (_flipBytes) value = Poco::ByteOrder::flipBytes(value);
 return *this;
}
BinaryReader& BinaryReader::operator >> (int& value)
{
// _istr.read((char*) &value, sizeof(value));
 for(int i=0;i<sizeof(value);++i)
  *((char*)&value+i) = *(buffer+cur+i);
 cur = cur + sizeof(value);
 if (_flipBytes) value = Poco::ByteOrder::flipBytes(value);
 return *this;
}
BinaryReader& BinaryReader::operator >> (unsigned int& value)
{
// _istr.read((char*) &value, sizeof(value));
 for(int i=0;i<sizeof(value);++i)
  *((char*)&value+i) = *(buffer+cur+i);
 cur = cur + sizeof(value);
 if (_flipBytes) value = Poco::ByteOrder::flipBytes(value);
 return *this;
}
BinaryReader& BinaryReader::operator >> (long& value)
{
// _istr.read((char*) &value, sizeof(value));
 for(int i=0;i<sizeof(value);++i)
  *((char*)&value+i) = *(buffer+cur+i);
 cur = cur + sizeof(value);
#if defined(POCO_LONG_IS_64_BIT)
 if (_flipBytes) value = Poco::ByteOrder::flipBytes((Poco::Int64) value);
#else
 if (_flipBytes) value = Poco::ByteOrder::flipBytes((Poco::Int32) value);
#endif
 return *this;
}
BinaryReader& BinaryReader::operator >> (unsigned long& value)
{
// _istr.read((char*) &value, sizeof(value));
 for(int i=0;i<sizeof(value);++i)
  *((char*)&value+i) = *(buffer+cur+i);
 cur = cur + sizeof(value);
#if defined(POCO_LONG_IS_64_BIT)
 if (_flipBytes) value = Poco::ByteOrder::flipBytes((Poco::UInt64) value);
#else
 if (_flipBytes) value = Poco::ByteOrder::flipBytes((Poco::UInt32) value);
#endif
 return *this;
}
BinaryReader& BinaryReader::operator >> (float& value)
{
 if (_flipBytes)
 {
  char* ptr = (char*) &value;
  ptr += sizeof(value);
  for (unsigned i = 0; i < sizeof(value); ++i)
//   _istr.read(--ptr, 1);
   *(--ptr) = *(buffer+cur+i);
  cur = cur + sizeof(value);
 }
 else
 {
//  _istr.read((char*) &value, sizeof(value));
  for(int i=0;i<sizeof(value);++i)
   *((char*)&value+i) = *(buffer+cur+i);
  cur = cur + sizeof(value);
 }
 return *this;
}
BinaryReader& BinaryReader::operator >> (double& value)
{
 if (_flipBytes)
 {
  char* ptr = (char*) &value;
  ptr += sizeof(value);
  for (unsigned i = 0; i < sizeof(value); ++i)
//   _istr.read(--ptr, 1);
   *(--ptr) = *(buffer+cur+i);
  cur = cur + sizeof(value);
 }
 else
 {
//  _istr.read((char*) &value, sizeof(value));
  for(int i=0;i<sizeof(value);++i)
   *((char*)&value+i) = *(buffer+cur+i);
  cur = cur + sizeof(value);
 }
 return *this;
}

BinaryReader& BinaryReader::operator >> (std::string& value)
{
 Poco::UInt32 size = 0;
 read7BitEncoded(size);
 value.clear();
 if (!good()) return *this;
 value.reserve(size);
 while (size--)
 {
  char c;
//  if (!_istr.read(&c, 1).good()) break;
  if(!good()) break;
  *((char*)&c) = *(buffer+cur);
  ++cur;
  value += c;
 }
 if (_pTextConverter)
 {
  std::string converted;
  _pTextConverter->convert(value, converted);
  std::swap(value, converted);
 }
 return *this;
}
void BinaryReader::read7BitEncoded(Poco::UInt32& value)
{
 char c;
 value = 0;
 int s = 0;
 do
 {
  c = 0;
//  _istr.read(&c, 1);
  *((char*)&c) = *(buffer+cur);
  ++cur;
  Poco::UInt32 x = (c & 0x7F);
  x <<= s;
  value += x;
  s += 7;
 }
 while (c & 0x80);
}

void BinaryReader::readRaw(std::streamsize length, std::string& value)
{
 value.clear();
 value.reserve(static_cast<std::string::size_type>(length));
 while (length--)
 {
  char c;
//  if (!_istr.read(&c, 1).good()) break;
  if(!good()) break;
  *((char*)&c) = *(buffer+cur);
  ++cur;
  value += c;
 }
}
void BinaryReader::readRaw(char* buf, std::streamsize length)
{
// _istr.read(buffer, length);
 for(int i=0;i<length;++i)
  *(buf+i) = *(buffer+cur+i);
 cur = cur + length;
}
} // namespace Linyanwen

 

轉載請註明出處:山水間部落格,http://blog.csdn.net/linyanwen99/article/details/8599680

 

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.