filereadstream.h 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. // Tencent is pleased to support the open source community by making RapidJSON
  2. // available.
  3. //
  4. // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All
  5. // rights reserved.
  6. //
  7. // Licensed under the MIT License (the "License"); you may not use this file
  8. // except in compliance with the License. You may obtain a copy of the License
  9. // at
  10. //
  11. // http://opensource.org/licenses/MIT
  12. //
  13. // Unless required by applicable law or agreed to in writing, software
  14. // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  15. // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  16. // License for the specific language governing permissions and limitations under
  17. // the License.
  18. #ifndef RAPIDJSON_FILEREADSTREAM_H_
  19. #define RAPIDJSON_FILEREADSTREAM_H_
  20. #include <cstdio>
  21. #include "stream.h"
  22. #ifdef __clang__
  23. RAPIDJSON_DIAG_PUSH
  24. RAPIDJSON_DIAG_OFF(padded)
  25. RAPIDJSON_DIAG_OFF(unreachable - code)
  26. RAPIDJSON_DIAG_OFF(missing - noreturn)
  27. #endif
  28. RAPIDJSON_NAMESPACE_BEGIN
  29. //! File byte stream for input using fread().
  30. /*!
  31. \note implements Stream concept
  32. */
  33. class FileReadStream {
  34. public:
  35. typedef char Ch; //!< Character type (byte).
  36. //! Constructor.
  37. /*!
  38. \param fp File pointer opened for read.
  39. \param buffer user-supplied buffer.
  40. \param bufferSize size of buffer in bytes. Must >=4 bytes.
  41. */
  42. FileReadStream(std::FILE *fp, char *buffer, size_t bufferSize)
  43. : fp_(fp),
  44. buffer_(buffer),
  45. bufferSize_(bufferSize),
  46. bufferLast_(0),
  47. current_(buffer_),
  48. readCount_(0),
  49. count_(0),
  50. eof_(false) {
  51. RAPIDJSON_ASSERT(fp_ != 0);
  52. RAPIDJSON_ASSERT(bufferSize >= 4);
  53. Read();
  54. }
  55. Ch Peek() const { return *current_; }
  56. Ch Take() {
  57. Ch c = *current_;
  58. Read();
  59. return c;
  60. }
  61. size_t Tell() const {
  62. return count_ + static_cast<size_t>(current_ - buffer_);
  63. }
  64. // Not implemented
  65. void Put(Ch) { RAPIDJSON_ASSERT(false); }
  66. void Flush() { RAPIDJSON_ASSERT(false); }
  67. Ch *PutBegin() {
  68. RAPIDJSON_ASSERT(false);
  69. return 0;
  70. }
  71. size_t PutEnd(Ch *) {
  72. RAPIDJSON_ASSERT(false);
  73. return 0;
  74. }
  75. // For encoding detection only.
  76. const Ch *Peek4() const {
  77. return (current_ + 4 - !eof_ <= bufferLast_) ? current_ : 0;
  78. }
  79. private:
  80. void Read() {
  81. if (current_ < bufferLast_)
  82. ++current_;
  83. else if (!eof_) {
  84. count_ += readCount_;
  85. readCount_ = std::fread(buffer_, 1, bufferSize_, fp_);
  86. bufferLast_ = buffer_ + readCount_ - 1;
  87. current_ = buffer_;
  88. if (readCount_ < bufferSize_) {
  89. buffer_[readCount_] = '\0';
  90. ++bufferLast_;
  91. eof_ = true;
  92. }
  93. }
  94. }
  95. std::FILE *fp_;
  96. Ch *buffer_;
  97. size_t bufferSize_;
  98. Ch *bufferLast_;
  99. Ch *current_;
  100. size_t readCount_;
  101. size_t count_; //!< Number of characters read
  102. bool eof_;
  103. };
  104. RAPIDJSON_NAMESPACE_END
  105. #ifdef __clang__
  106. RAPIDJSON_DIAG_POP
  107. #endif
  108. #endif // RAPIDJSON_FILESTREAM_H_