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