Build tool
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

bufio.h 1.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. #pragma once
  2. #include <iostream>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. namespace bufio {
  6. template<size_t bufsiz = 1024>
  7. class IBuf {
  8. public:
  9. IBuf(std::istream &is): is_(is) {}
  10. char get();
  11. int peek();
  12. int peek2();
  13. private:
  14. std::istream &is_;
  15. char buf_[bufsiz];
  16. size_t idx_ = 0;
  17. size_t len_ = 0;
  18. };
  19. template<size_t bufsiz = 1024>
  20. class OBuf {
  21. public:
  22. OBuf(std::ostream &os): os_(os) {}
  23. ~OBuf();
  24. void put(char ch);
  25. void put(const char *str, size_t len);
  26. void put(const char *str) { put(str, strlen(str)); }
  27. void put(const std::string &str) { put(str.c_str(), str.size()); }
  28. private:
  29. std::ostream &os_;
  30. char buf_[bufsiz];
  31. size_t idx_ = 0;
  32. };
  33. /*
  34. * IBuf
  35. */
  36. template<size_t bufsiz>
  37. inline char IBuf<bufsiz>::get() {
  38. if (idx_ < len_) {
  39. return buf_[idx_++];
  40. }
  41. idx_ = 0;
  42. is_.read(buf_, sizeof(buf_));
  43. len_ = is_.gcount();
  44. if (len_ == 0) {
  45. return EOF;
  46. }
  47. return buf_[idx_++];
  48. }
  49. template<size_t bufsiz>
  50. inline int IBuf<bufsiz>::peek() {
  51. if (idx_ < len_) {
  52. return buf_[idx_];
  53. } else {
  54. return is_.peek();
  55. }
  56. }
  57. template<size_t bufsiz>
  58. inline int IBuf<bufsiz>::peek2() {
  59. if (idx_ + 1 < len_) {
  60. return buf_[idx_ + 1];
  61. } else if (idx_ < len_) {
  62. return is_.peek();
  63. } else {
  64. is_.get();
  65. int ch = is_.peek();
  66. is_.unget();
  67. return ch;
  68. }
  69. }
  70. /*
  71. * OBuf
  72. */
  73. template<size_t bufsiz>
  74. inline OBuf<bufsiz>::~OBuf() {
  75. if (idx_ > 0) {
  76. os_.write(buf_, idx_);
  77. }
  78. }
  79. template<size_t bufsiz>
  80. inline void OBuf<bufsiz>::put(char ch) {
  81. buf_[idx_++] = ch;
  82. if (idx_ == sizeof(buf_)) {
  83. os_.write(buf_, sizeof(buf_));
  84. idx_ = 0;
  85. }
  86. }
  87. template<size_t bufsiz>
  88. inline void OBuf<bufsiz>::put(const char *str, size_t len) {
  89. size_t w = sizeof(buf_) - idx_ - 1;
  90. if (w > len) {
  91. w = len;
  92. }
  93. memcpy(buf_ + idx_, str, w);
  94. if (len - w > 0) {
  95. os_.write(buf_, idx_ + w);
  96. os_.write(str + w, len - w);
  97. idx_ = 0;
  98. } else {
  99. idx_ += w;
  100. }
  101. }
  102. }