filereadstream.h 2.9 KB

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