1 // Tencent is pleased to support the open source community by making RapidJSON available.
3 // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
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
8 // http://opensource.org/licenses/MIT
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.
15 #include "rapidjson.h"
17 #ifndef RAPIDJSON_STREAM_H_
18 #define RAPIDJSON_STREAM_H_
20 #include "encodings.h"
22 RAPIDJSON_NAMESPACE_BEGIN
24 ///////////////////////////////////////////////////////////////////////////////
27 /*! \class rapidjson::Stream
28 \brief Concept for reading and writing characters.
30 For read-only stream, no need to implement PutBegin(), Put(), Flush() and PutEnd().
32 For write-only stream, only need to implement Put() and Flush().
36 typename Ch; //!< Character type of the stream.
38 //! Read the current character from stream without moving the read cursor.
41 //! Read the current character from stream and moving the read cursor to next character.
44 //! Get the current read cursor.
45 //! \return Number of characters read from start.
48 //! Begin writing operation at the current read pointer.
49 //! \return The begin writer pointer.
52 //! Write a character.
58 //! End the writing operation.
59 //! \param begin The begin write pointer returned by PutBegin().
60 //! \return Number of characters written.
61 size_t PutEnd(Ch* begin);
66 //! Provides additional information for stream.
68 By using traits pattern, this type provides a default configuration for stream.
69 For custom stream, this type can be specialized for other configuration.
70 See TEST(Reader, CustomStringStream) in readertest.cpp for example.
72 template<typename Stream
>
74 //! Whether to make local copy of stream for optimization during parsing.
76 By default, for safety, streams do not use local copy optimization.
77 Stream that can be copied fast should specialize this, like StreamTraits<StringStream>.
79 enum { copyOptimization
= 0 };
82 //! Reserve n characters for writing to a stream.
83 template<typename Stream
>
84 inline void PutReserve(Stream
& stream
, size_t count
) {
89 //! Write character to a stream, presuming buffer is reserved.
90 template<typename Stream
>
91 inline void PutUnsafe(Stream
& stream
, typename
Stream::Ch c
) {
95 //! Put N copies of a character to a stream.
96 template<typename Stream
, typename Ch
>
97 inline void PutN(Stream
& stream
, Ch c
, size_t n
) {
98 PutReserve(stream
, n
);
99 for (size_t i
= 0; i
< n
; i
++)
100 PutUnsafe(stream
, c
);
103 ///////////////////////////////////////////////////////////////////////////////
106 //! Read-only string stream.
107 /*! \note implements Stream concept
109 template <typename Encoding
>
110 struct GenericStringStream
{
111 typedef typename
Encoding::Ch Ch
;
113 GenericStringStream(const Ch
*src
) : src_(src
), head_(src
) {}
115 Ch
Peek() const { return *src_
; }
116 Ch
Take() { return *src_
++; }
117 size_t Tell() const { return static_cast<size_t>(src_
- head_
); }
119 Ch
* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
120 void Put(Ch
) { RAPIDJSON_ASSERT(false); }
121 void Flush() { RAPIDJSON_ASSERT(false); }
122 size_t PutEnd(Ch
*) { RAPIDJSON_ASSERT(false); return 0; }
124 const Ch
* src_
; //!< Current read position.
125 const Ch
* head_
; //!< Original head of the string.
128 template <typename Encoding
>
129 struct StreamTraits
<GenericStringStream
<Encoding
> > {
130 enum { copyOptimization
= 1 };
133 //! String stream with UTF8 encoding.
134 typedef GenericStringStream
<UTF8
<> > StringStream
;
136 ///////////////////////////////////////////////////////////////////////////////
137 // InsituStringStream
139 //! A read-write string stream.
140 /*! This string stream is particularly designed for in-situ parsing.
141 \note implements Stream concept
143 template <typename Encoding
>
144 struct GenericInsituStringStream
{
145 typedef typename
Encoding::Ch Ch
;
147 GenericInsituStringStream(Ch
*src
) : src_(src
), dst_(0), head_(src
) {}
150 Ch
Peek() { return *src_
; }
151 Ch
Take() { return *src_
++; }
152 size_t Tell() { return static_cast<size_t>(src_
- head_
); }
155 void Put(Ch c
) { RAPIDJSON_ASSERT(dst_
!= 0); *dst_
++ = c
; }
157 Ch
* PutBegin() { return dst_
= src_
; }
158 size_t PutEnd(Ch
* begin
) { return static_cast<size_t>(dst_
- begin
); }
161 Ch
* Push(size_t count
) { Ch
* begin
= dst_
; dst_
+= count
; return begin
; }
162 void Pop(size_t count
) { dst_
-= count
; }
169 template <typename Encoding
>
170 struct StreamTraits
<GenericInsituStringStream
<Encoding
> > {
171 enum { copyOptimization
= 1 };
174 //! Insitu string stream with UTF8 encoding.
175 typedef GenericInsituStringStream
<UTF8
<> > InsituStringStream
;
177 RAPIDJSON_NAMESPACE_END
179 #endif // RAPIDJSON_STREAM_H_