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