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

STL

开发平台:

Visual C++

  1. /* vim: set tabstop=4 : */
  2. #include "BzipStream.h"
  3. #include <assert.h>
  4. #include <string.h>
  5. #include <sstream>
  6. #ifdef _MSC_VER
  7. #   pragma comment(lib, "libbz2.lib")
  8. #endif
  9. /*
  10. #if defined(_WIN32) || defined(WIN32) || defined(_WIN64) || defined(WIN64)
  11. # include <io.h>
  12. #else
  13. # include <unistd.h>
  14. # include <sys/stat.h>
  15. # include <sys/types.h>
  16. # include <fcntl.h>
  17. # include <errno.h>
  18. #endif
  19. */
  20. #include <bzlib.h>
  21. #include "byte_io_impl.h"
  22. static const char* strbzerr(int err)
  23. {
  24. switch (err)
  25. {
  26. default:
  27. {
  28. static char szbuf[64];
  29. sprintf(szbuf, "unknow err=%d", err);
  30. return szbuf;
  31. }
  32. case BZ_OK: return "BZ_OK";
  33. case BZ_RUN_OK: return "BZ_RUN_OK";
  34. case BZ_FLUSH_OK: return "BZ_FLUSH_OK";
  35. case BZ_FINISH_OK: return "BZ_FINISH_OK";
  36. case BZ_STREAM_END: return "BZ_STREAM_END";
  37. case BZ_CONFIG_ERROR: return "BZ_CONFIG_ERROR";
  38. case BZ_SEQUENCE_ERROR: return "BZ_SEQUENCE_ERROR";
  39. case BZ_PARAM_ERROR: return "BZ_PARAM_ERROR";
  40. case BZ_MEM_ERROR: return "BZ_MEM_ERROR";
  41. case BZ_DATA_ERROR: return "BZ_DATA_ERROR";
  42. case BZ_DATA_ERROR_MAGIC:return "BZ_DATA_ERROR_MAGIC";
  43. case BZ_UNEXPECTED_EOF: return "BZ_UNEXPECTED_EOF";
  44. case BZ_OUTBUFF_FULL: return "BZ_OUTBUFF_FULL";
  45. case BZ_IO_ERROR: return "BZ_IO_ERROR";
  46. }
  47. }
  48. namespace febird {
  49. // only can call on unopened BzipInputStream
  50. void BzipInputStream::open(const char* fpath, const char* mode)
  51. {
  52. assert(0 == m_fp);
  53. int err;
  54. m_cf = fopen(fpath, mode);
  55. if (0 == m_cf)
  56. {
  57. std::ostringstream oss;
  58. oss << "mode=" << mode;
  59. throw OpenFileException(fpath, oss.str().c_str());
  60. }
  61. m_fp = BZ2_bzReadOpen(&err, m_cf
  62. , 0    // verbosity, 0 will not print msg
  63. , 0    // small
  64. , NULL // unused
  65. , 0    // nUnused
  66. );
  67. if (0 == m_fp)
  68. {
  69. std::ostringstream oss;
  70. oss << "mode=" << mode << ", err=" << strbzerr(err);
  71. throw OpenFileException(fpath, oss.str().c_str());
  72. }
  73. }
  74. void BzipInputStream::dopen(int fd, const char* mode)
  75. {
  76. assert(0 == m_fp);
  77. int err;
  78. #ifdef _MSC_VER
  79. m_cf = _fdopen(fd, mode);
  80. #else
  81. m_cf = fdopen(fd, mode);
  82. #endif
  83. if (0 == m_cf)
  84. {
  85. std::ostringstream oss;
  86. oss << "fd=" << fd << ", mode=" << mode;
  87. throw OpenFileException("<fd>", oss.str().c_str());
  88. }
  89. m_fp = BZ2_bzReadOpen(&err, m_cf
  90. , 0    // verbosity, 0 will not print msg
  91. , 0    // small
  92. , NULL // unused
  93. , 0    // nUnused
  94. );
  95. if (0 == m_fp)
  96. {
  97. std::ostringstream oss;
  98. oss << "fd=" << fd << ", mode=" << mode << ", err=" << strbzerr(err);
  99. throw OpenFileException("<fd>", oss.str().c_str());
  100. }
  101. }
  102. void BzipInputStream::close()
  103. {
  104. assert(m_fp);
  105. assert(m_cf);
  106. int err;
  107. BZ2_bzReadClose(&err, m_fp);
  108. ::fclose(m_cf);
  109. m_fp = 0;
  110. m_cf = 0;
  111. if (BZ_OK != err)
  112. {
  113. std::ostringstream oss;
  114. oss << "BZ2_bzReadClose err=" << strbzerr(err)
  115. << ", in " << BOOST_CURRENT_FUNCTION;
  116. throw OpenFileException("<fd>", oss.str().c_str());
  117. }
  118. }
  119. BzipInputStream::~BzipInputStream()
  120. {
  121. if (m_fp)
  122. this->close();
  123. }
  124. BzipInputStream::BzipInputStream(const char* fpath, const char* mode)
  125. {
  126. m_fp = 0;
  127. m_cf = 0;
  128.     open(fpath, mode);
  129. }
  130. BzipInputStream::BzipInputStream(int fd, const char* mode)
  131. {
  132. m_fp = 0;
  133.   m_cf = 0;
  134.    dopen(fd, mode);
  135. }
  136. bool BzipInputStream::eof() const
  137. {
  138. assert(m_cf);
  139. assert(m_fp);
  140. return !!::feof(m_cf);
  141. }
  142. size_t BzipInputStream::read(void* buf, size_t size)
  143. {
  144. assert(m_cf);
  145. assert(m_fp);
  146. int err = BZ_OK;
  147. int nRead = BZ2_bzRead(&err, m_fp, buf, size);
  148. if (BZ_OK != err)
  149. {
  150. std::ostringstream oss;
  151. oss << "BZ2_bzRead err=" << strbzerr(err)
  152. << ", in " << BOOST_CURRENT_FUNCTION;
  153. throw OpenFileException("<fd>", oss.str().c_str());
  154. }
  155. assert(nRead <= (int)size);
  156. return (size_t)nRead;
  157. }
  158. FEBIRD_GEN_ensureRead (BzipInputStream::)
  159. ///////////////////////////////////////////////////////
  160. // only can call on unopened BzipOutputStream
  161. void BzipOutputStream::open(const char* fpath, const char* mode)
  162. {
  163. assert(0 == m_fp);
  164. int err;
  165. m_cf = fopen(fpath, mode);
  166. if (0 == m_cf)
  167. {
  168. std::ostringstream oss;
  169. oss << "mode=" << mode;
  170. throw OpenFileException(fpath, oss.str().c_str());
  171. }
  172. m_fp = BZ2_bzWriteOpen(&err, m_cf
  173. ,  9   // blocksize100k
  174. ,  0   // verbosity
  175. , 30   // workFactor, default=30
  176. );
  177. if (0 == m_fp)
  178. {
  179. std::ostringstream oss;
  180. oss << "mode=" << mode << ", err=" << strbzerr(err);
  181. throw OpenFileException(fpath, oss.str().c_str());
  182. }
  183. }
  184. void BzipOutputStream::dopen(int fd, const char* mode)
  185. {
  186. assert(0 == m_fp);
  187. int err;
  188. #ifdef _MSC_VER
  189. m_cf = _fdopen(fd, mode);
  190. #else
  191. m_cf = fdopen(fd, mode);
  192. #endif
  193. if (0 == m_cf)
  194. {
  195. std::ostringstream oss;
  196. oss << "fd=" << fd << ", mode=" << mode;
  197. throw OpenFileException("<fd>", oss.str().c_str());
  198. }
  199. m_fp = BZ2_bzWriteOpen(&err, m_cf
  200. ,  9   // blocksize100k
  201. ,  0   // verbosity
  202. , 30   // workFactor, default=30
  203. );
  204. if (0 == m_fp)
  205. {
  206. std::ostringstream oss;
  207. oss << "fd=" << fd << ", mode=" << mode << ", err=" << strbzerr(err);
  208. throw OpenFileException("<fd>", oss.str().c_str());
  209. }
  210. }
  211. void BzipOutputStream::close()
  212. {
  213. assert(m_fp);
  214. assert(m_cf);
  215. int err = BZ_OK;
  216. int abandon = 0;
  217. unsigned in_lo32, in_hi32, out_lo32, out_hi32;
  218. BZ2_bzWriteClose64(&err, m_fp, abandon, &in_lo32, &in_hi32, &out_lo32, &out_hi32);
  219. ::fclose(m_cf);
  220. m_fp = 0;
  221. m_cf = 0;
  222. if (BZ_OK != err)
  223. {
  224. std::ostringstream oss;
  225. oss << "BZ2_bzWriteClose64 err=" << strbzerr(err)
  226. << ", in " << BOOST_CURRENT_FUNCTION;
  227. throw IOException(oss.str().c_str());
  228. }
  229. }
  230. BzipOutputStream::~BzipOutputStream()
  231. {
  232. if (m_fp)
  233. this->close();
  234. }
  235. BzipOutputStream::BzipOutputStream(const char* fpath, const char* mode)
  236. {
  237. m_fp = 0;
  238. m_cf = 0;
  239.     open(fpath, mode);
  240. }
  241. BzipOutputStream::BzipOutputStream(int fd, const char* mode)
  242. {
  243. m_fp = 0;
  244. m_cf = 0;
  245.     dopen(fd, mode);
  246. }
  247. void BzipOutputStream::flush()
  248. {
  249. assert(m_fp);
  250. assert(m_cf);
  251. if (fflush(m_cf) == EOF)
  252. throw DelayedWriteFailException(BOOST_CURRENT_FUNCTION);
  253. }
  254. size_t BzipOutputStream::write(const void* buf, size_t size)
  255. {
  256. assert(m_fp);
  257. assert(m_cf);
  258. int err = BZ_OK;
  259. BZ2_bzWrite(&err, m_fp, (void*)buf, size);
  260. if (BZ_OK != err)
  261. {
  262. std::ostringstream oss;
  263. oss << "BZ2_bzWrite err=" << strbzerr(err)
  264. << ", in " << BOOST_CURRENT_FUNCTION;
  265. throw IOException(oss.str().c_str());
  266. }
  267. return size;
  268. }
  269. FEBIRD_GEN_ensureWrite(BzipOutputStream::)
  270. } // namespace febird