HexCodingStream.h
上传用户:kx_jwh
上传日期:2021-09-03
资源大小:76k
文件大小:4k
源码类别:

STL

开发平台:

Visual C++

  1. /* vim: set tabstop=4 : */
  2. #ifndef __febird_io_HexCodingStream_h__
  3. #define __febird_io_HexCodingStream_h__
  4. #if defined(_MSC_VER) && (_MSC_VER >= 1020)
  5. # pragma once
  6. #endif
  7. #include <assert.h>
  8. //#include <string.h>
  9. #include <stdio.h>
  10. #include <iostream>
  11. #include <boost/current_function.hpp>
  12. #include "IOException.h"
  13. #include "MemStream.h"
  14. #include "../DataBuffer.h"
  15. namespace febird {
  16. extern const unsigned char G_hex_val_hexTab[];
  17. void invalid_hex_char(unsigned char ch, const char* func);
  18. inline unsigned char hex_val(unsigned char ch, const char* func)
  19. {
  20. if (ch < '0' || ch >= 'f')
  21. invalid_hex_char(ch, func);
  22. unsigned char hv = G_hex_val_hexTab[ch-'0'];
  23. if (255 == hv)
  24. invalid_hex_char(ch, func);
  25. return hv;
  26. }
  27. inline unsigned char hex_val(unsigned char ch)
  28. {
  29. return hex_val(ch, BOOST_CURRENT_FUNCTION);
  30. }
  31. template<class ByteStream>
  32. class HexCodingStream
  33. {
  34. ByteStream* m_bs;
  35. unsigned char do_readByte(const char* func)
  36. {
  37. unsigned char h4 = m_bs->readByte();
  38. unsigned char l4 = m_bs->readByte();
  39. return hex_val(h4, func) << 4 | hex_val(l4, func);
  40. }
  41. public:
  42. typedef typename ByteStream::is_seekable is_seekable;
  43. explicit HexCodingStream(ByteStream* bs) : m_bs(bs) {}
  44. bool eof()  const throw() { return m_bs->eof(); }
  45. void flush() { m_bs->flush(); }
  46. unsigned char readByte()
  47. {
  48. return do_readByte(BOOST_CURRENT_FUNCTION);
  49. }
  50. int  getByte()
  51. {
  52. try {
  53. return do_readByte(BOOST_CURRENT_FUNCTION);
  54. } catch (const EndOfFileException& exp) {
  55. return -1;
  56. }
  57. }
  58. void writeByte(unsigned char b)
  59. {
  60. const char hexChar[] = "0123456789ABCDEF";
  61. m_bs->writeByte(hexChar[b >> 4]);
  62. m_bs->writeByte(hexChar[b & 15]);
  63. }
  64. void ensureRead(void* data, size_t length)
  65. {
  66. unsigned char* pb = (unsigned char*)(data);
  67. while (length)
  68. {
  69. *pb = do_readByte(BOOST_CURRENT_FUNCTION);
  70. pb++; length--;
  71. }
  72. }
  73. void ensureWrite(const void* data, size_t length)
  74. {
  75. const unsigned char* pb = (const unsigned char*)(data);
  76. while (length)
  77. {
  78. writeByte(*pb);
  79. pb++; length--;
  80. }
  81. }
  82. size_t read(void* data, size_t length)
  83. {
  84. unsigned char* pb = (unsigned char*)(data);
  85. try {
  86. while (length)
  87. {
  88. *pb = do_readByte(BOOST_CURRENT_FUNCTION);
  89. pb++; length--;
  90. }
  91. } catch (const EndOfFileException& exp) {
  92. // ignore
  93. }
  94. return pb - (unsigned char*)(data);
  95. }
  96. size_t write(const void* data, size_t length)
  97. {
  98. const unsigned char* pb = (const unsigned char*)(data);
  99. try {
  100. while (length)
  101. {
  102. writeByte(*pb);
  103. pb++; length--;
  104. }
  105. } catch (const OutOfSpaceException&) {
  106. // ignore
  107. }
  108. return pb - (unsigned char*)(data);
  109. }
  110. };
  111. //class AutoGrownMemIO; // declare
  112. typedef HexCodingStream<AutoGrownMemIO> HexAutoGrownMemIO;
  113. template<class SrcStream, class DstStream>
  114. DstStream& bin_dump_hex(SrcStream& src, DstStream& dst)
  115. {
  116. const size_t buf_len = 4*1024;
  117. DataBufferPtr data_buf(buf_len);
  118. AutoGrownMemIO hex_buf(2*buf_len);
  119. HexCodingStream<AutoGrownMemIO> hexMS(&hex_buf);
  120. try {
  121. while (true)
  122. {
  123. size_t len = src.read(data_buf->data(), buf_len);
  124. if (len) {
  125. hex_buf.seek(0);
  126. hexMS.write(data_buf->data(), len);
  127. dst.write((char*)hex_buf.buf(), 2*len);
  128. } else
  129. break;
  130. }
  131. } catch (EndOfFileException&) {
  132. // ignore...
  133. }
  134. return dst;
  135. }
  136. template<class SrcStream>
  137. class bin_dump_hex_manip
  138. {
  139. SrcStream& m_src;
  140. public:
  141. explicit bin_dump_hex_manip(SrcStream& src) : m_src(src) {}
  142. friend std::ostream& operator<<(std::ostream& os, bin_dump_hex_manip<SrcStream> x)
  143. {
  144. bin_dump_hex(x.m_src, os);
  145. return os;
  146. }
  147. };
  148. template<class SrcStream>
  149. bin_dump_hex_manip<SrcStream>
  150. bin_dump_hex(SrcStream& src)
  151. {
  152. return bin_dump_hex_manip<SrcStream>(src);
  153. }
  154. } // namespace febird
  155. #endif