filereadstream.h 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  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 "rapidjson.h"
  17. #include <cstdio>
  18. RAPIDJSON_NAMESPACE_BEGIN
  19. //! File byte stream for input using fread().
  20. /*!
  21. \note implements Stream concept
  22. */
  23. class FileReadStream {
  24. public:
  25. typedef char Ch; //!< Character type (byte).
  26. //! Constructor.
  27. /*!
  28. \param fp File pointer opened for read.
  29. \param buffer user-supplied buffer.
  30. \param bufferSize size of buffer in bytes. Must >=4 bytes.
  31. */
  32. 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) {
  33. RAPIDJSON_ASSERT(fp_ != 0);
  34. RAPIDJSON_ASSERT(bufferSize >= 4);
  35. Read();
  36. }
  37. Ch Peek() const { return *current_; }
  38. Ch Take() { Ch c = *current_; Read(); return c; }
  39. size_t Tell() const { return count_ + static_cast<size_t>(current_ - buffer_); }
  40. // Not implemented
  41. void Put(Ch) { RAPIDJSON_ASSERT(false); }
  42. void Flush() { RAPIDJSON_ASSERT(false); }
  43. Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
  44. size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
  45. // For encoding detection only.
  46. const Ch* Peek4() const {
  47. return (current_ + 4 <= bufferLast_) ? current_ : 0;
  48. }
  49. private:
  50. void Read() {
  51. if (current_ < bufferLast_)
  52. ++current_;
  53. else if (!eof_) {
  54. count_ += readCount_;
  55. readCount_ = fread(buffer_, 1, bufferSize_, fp_);
  56. bufferLast_ = buffer_ + readCount_ - 1;
  57. current_ = buffer_;
  58. if (readCount_ < bufferSize_) {
  59. buffer_[readCount_] = '\0';
  60. ++bufferLast_;
  61. eof_ = true;
  62. }
  63. }
  64. }
  65. std::FILE* fp_;
  66. Ch *buffer_;
  67. size_t bufferSize_;
  68. Ch *bufferLast_;
  69. Ch *current_;
  70. size_t readCount_;
  71. size_t count_; //!< Number of characters read
  72. bool eof_;
  73. };
  74. RAPIDJSON_NAMESPACE_END
  75. #endif // RAPIDJSON_FILESTREAM_H_