mirror of
				https://github.com/Atmosphere-NX/Atmosphere.git
				synced 2025-10-26 02:05:47 +02:00 
			
		
		
		
	
		
			
				
	
	
		
			224 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			224 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| // Tencent is pleased to support the open source community by making RapidJSON available.
 | |
| //
 | |
| // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
 | |
| //
 | |
| // Licensed under the MIT License (the "License"); you may not use this file except
 | |
| // in compliance with the License. You may obtain a copy of the License at
 | |
| //
 | |
| // http://opensource.org/licenses/MIT
 | |
| //
 | |
| // Unless required by applicable law or agreed to in writing, software distributed
 | |
| // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
 | |
| // CONDITIONS OF ANY KIND, either express or implied. See the License for the
 | |
| // specific language governing permissions and limitations under the License.
 | |
| 
 | |
| #include "rapidjson.h"
 | |
| 
 | |
| #ifndef RAPIDJSON_STREAM_H_
 | |
| #define RAPIDJSON_STREAM_H_
 | |
| 
 | |
| #include "encodings.h"
 | |
| 
 | |
| RAPIDJSON_NAMESPACE_BEGIN
 | |
| 
 | |
| ///////////////////////////////////////////////////////////////////////////////
 | |
| //  Stream
 | |
| 
 | |
| /*! \class rapidjson::Stream
 | |
|     \brief Concept for reading and writing characters.
 | |
| 
 | |
|     For read-only stream, no need to implement PutBegin(), Put(), Flush() and PutEnd().
 | |
| 
 | |
|     For write-only stream, only need to implement Put() and Flush().
 | |
| 
 | |
| \code
 | |
| concept Stream {
 | |
|     typename Ch;    //!< Character type of the stream.
 | |
| 
 | |
|     //! Read the current character from stream without moving the read cursor.
 | |
|     Ch Peek() const;
 | |
| 
 | |
|     //! Read the current character from stream and moving the read cursor to next character.
 | |
|     Ch Take();
 | |
| 
 | |
|     //! Get the current read cursor.
 | |
|     //! \return Number of characters read from start.
 | |
|     size_t Tell();
 | |
| 
 | |
|     //! Begin writing operation at the current read pointer.
 | |
|     //! \return The begin writer pointer.
 | |
|     Ch* PutBegin();
 | |
| 
 | |
|     //! Write a character.
 | |
|     void Put(Ch c);
 | |
| 
 | |
|     //! Flush the buffer.
 | |
|     void Flush();
 | |
| 
 | |
|     //! End the writing operation.
 | |
|     //! \param begin The begin write pointer returned by PutBegin().
 | |
|     //! \return Number of characters written.
 | |
|     size_t PutEnd(Ch* begin);
 | |
| }
 | |
| \endcode
 | |
| */
 | |
| 
 | |
| //! Provides additional information for stream.
 | |
| /*!
 | |
|     By using traits pattern, this type provides a default configuration for stream.
 | |
|     For custom stream, this type can be specialized for other configuration.
 | |
|     See TEST(Reader, CustomStringStream) in readertest.cpp for example.
 | |
| */
 | |
| template<typename Stream>
 | |
| struct StreamTraits {
 | |
|     //! Whether to make local copy of stream for optimization during parsing.
 | |
|     /*!
 | |
|         By default, for safety, streams do not use local copy optimization.
 | |
|         Stream that can be copied fast should specialize this, like StreamTraits<StringStream>.
 | |
|     */
 | |
|     enum { copyOptimization = 0 };
 | |
| };
 | |
| 
 | |
| //! Reserve n characters for writing to a stream.
 | |
| template<typename Stream>
 | |
| inline void PutReserve(Stream& stream, size_t count) {
 | |
|     (void)stream;
 | |
|     (void)count;
 | |
| }
 | |
| 
 | |
| //! Write character to a stream, presuming buffer is reserved.
 | |
| template<typename Stream>
 | |
| inline void PutUnsafe(Stream& stream, typename Stream::Ch c) {
 | |
|     stream.Put(c);
 | |
| }
 | |
| 
 | |
| //! Put N copies of a character to a stream.
 | |
| template<typename Stream, typename Ch>
 | |
| inline void PutN(Stream& stream, Ch c, size_t n) {
 | |
|     PutReserve(stream, n);
 | |
|     for (size_t i = 0; i < n; i++)
 | |
|         PutUnsafe(stream, c);
 | |
| }
 | |
| 
 | |
| ///////////////////////////////////////////////////////////////////////////////
 | |
| // GenericStreamWrapper
 | |
| 
 | |
| //! A Stream Wrapper
 | |
| /*! \tThis string stream is a wrapper for any stream by just forwarding any
 | |
|     \treceived message to the origin stream.
 | |
|     \note implements Stream concept
 | |
| */
 | |
| 
 | |
| #if defined(_MSC_VER) && _MSC_VER <= 1800
 | |
| RAPIDJSON_DIAG_PUSH
 | |
| RAPIDJSON_DIAG_OFF(4702)  // unreachable code
 | |
| RAPIDJSON_DIAG_OFF(4512)  // assignment operator could not be generated
 | |
| #endif
 | |
| 
 | |
| template <typename InputStream, typename Encoding = UTF8<> >
 | |
| class GenericStreamWrapper {
 | |
| public:
 | |
|     typedef typename Encoding::Ch Ch;
 | |
|     GenericStreamWrapper(InputStream& is): is_(is) {}
 | |
| 
 | |
|     Ch Peek() const { return is_.Peek(); }
 | |
|     Ch Take() { return is_.Take(); }
 | |
|     size_t Tell() { return is_.Tell(); }
 | |
|     Ch* PutBegin() { return is_.PutBegin(); }
 | |
|     void Put(Ch ch) { is_.Put(ch); }
 | |
|     void Flush() { is_.Flush(); }
 | |
|     size_t PutEnd(Ch* ch) { return is_.PutEnd(ch); }
 | |
| 
 | |
|     // wrapper for MemoryStream
 | |
|     const Ch* Peek4() const { return is_.Peek4(); }
 | |
| 
 | |
|     // wrapper for AutoUTFInputStream
 | |
|     UTFType GetType() const { return is_.GetType(); }
 | |
|     bool HasBOM() const { return is_.HasBOM(); }
 | |
| 
 | |
| protected:
 | |
|     InputStream& is_;
 | |
| };
 | |
| 
 | |
| #if defined(_MSC_VER) && _MSC_VER <= 1800
 | |
| RAPIDJSON_DIAG_POP
 | |
| #endif
 | |
| 
 | |
| ///////////////////////////////////////////////////////////////////////////////
 | |
| // StringStream
 | |
| 
 | |
| //! Read-only string stream.
 | |
| /*! \note implements Stream concept
 | |
| */
 | |
| template <typename Encoding>
 | |
| struct GenericStringStream {
 | |
|     typedef typename Encoding::Ch Ch;
 | |
| 
 | |
|     GenericStringStream(const Ch *src) : src_(src), head_(src) {}
 | |
| 
 | |
|     Ch Peek() const { return *src_; }
 | |
|     Ch Take() { return *src_++; }
 | |
|     size_t Tell() const { return static_cast<size_t>(src_ - head_); }
 | |
| 
 | |
|     Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
 | |
|     void Put(Ch) { RAPIDJSON_ASSERT(false); }
 | |
|     void Flush() { RAPIDJSON_ASSERT(false); }
 | |
|     size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
 | |
| 
 | |
|     const Ch* src_;     //!< Current read position.
 | |
|     const Ch* head_;    //!< Original head of the string.
 | |
| };
 | |
| 
 | |
| template <typename Encoding>
 | |
| struct StreamTraits<GenericStringStream<Encoding> > {
 | |
|     enum { copyOptimization = 1 };
 | |
| };
 | |
| 
 | |
| //! String stream with UTF8 encoding.
 | |
| typedef GenericStringStream<UTF8<> > StringStream;
 | |
| 
 | |
| ///////////////////////////////////////////////////////////////////////////////
 | |
| // InsituStringStream
 | |
| 
 | |
| //! A read-write string stream.
 | |
| /*! This string stream is particularly designed for in-situ parsing.
 | |
|     \note implements Stream concept
 | |
| */
 | |
| template <typename Encoding>
 | |
| struct GenericInsituStringStream {
 | |
|     typedef typename Encoding::Ch Ch;
 | |
| 
 | |
|     GenericInsituStringStream(Ch *src) : src_(src), dst_(0), head_(src) {}
 | |
| 
 | |
|     // Read
 | |
|     Ch Peek() { return *src_; }
 | |
|     Ch Take() { return *src_++; }
 | |
|     size_t Tell() { return static_cast<size_t>(src_ - head_); }
 | |
| 
 | |
|     // Write
 | |
|     void Put(Ch c) { RAPIDJSON_ASSERT(dst_ != 0); *dst_++ = c; }
 | |
| 
 | |
|     Ch* PutBegin() { return dst_ = src_; }
 | |
|     size_t PutEnd(Ch* begin) { return static_cast<size_t>(dst_ - begin); }
 | |
|     void Flush() {}
 | |
| 
 | |
|     Ch* Push(size_t count) { Ch* begin = dst_; dst_ += count; return begin; }
 | |
|     void Pop(size_t count) { dst_ -= count; }
 | |
| 
 | |
|     Ch* src_;
 | |
|     Ch* dst_;
 | |
|     Ch* head_;
 | |
| };
 | |
| 
 | |
| template <typename Encoding>
 | |
| struct StreamTraits<GenericInsituStringStream<Encoding> > {
 | |
|     enum { copyOptimization = 1 };
 | |
| };
 | |
| 
 | |
| //! Insitu string stream with UTF8 encoding.
 | |
| typedef GenericInsituStringStream<UTF8<> > InsituStringStream;
 | |
| 
 | |
| RAPIDJSON_NAMESPACE_END
 | |
| 
 | |
| #endif // RAPIDJSON_STREAM_H_
 |