Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 10:21:49

0001 // Tencent is pleased to support the open source community by making RapidJSON available.
0002 // 
0003 // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
0004 //
0005 // Licensed under the MIT License (the "License"); you may not use this file except
0006 // in compliance with the License. You may obtain a copy of the License at
0007 //
0008 // http://opensource.org/licenses/MIT
0009 //
0010 // Unless required by applicable law or agreed to in writing, software distributed 
0011 // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 
0012 // CONDITIONS OF ANY KIND, either express or implied. See the License for the 
0013 // specific language governing permissions and limitations under the License.
0014 
0015 #ifndef RAPIDJSON_ISTREAMWRAPPER_H_
0016 #define RAPIDJSON_ISTREAMWRAPPER_H_
0017 
0018 #include "stream.h"
0019 #include <iosfwd>
0020 #include <ios>
0021 
0022 #ifdef __clang__
0023 RAPIDJSON_DIAG_PUSH
0024 RAPIDJSON_DIAG_OFF(padded)
0025 #elif defined(_MSC_VER)
0026 RAPIDJSON_DIAG_PUSH
0027 RAPIDJSON_DIAG_OFF(4351) // new behavior: elements of array 'array' will be default initialized
0028 #endif
0029 
0030 RAPIDJSON_NAMESPACE_BEGIN
0031 
0032 //! Wrapper of \c std::basic_istream into RapidJSON's Stream concept.
0033 /*!
0034     The classes can be wrapped including but not limited to:
0035 
0036     - \c std::istringstream
0037     - \c std::stringstream
0038     - \c std::wistringstream
0039     - \c std::wstringstream
0040     - \c std::ifstream
0041     - \c std::fstream
0042     - \c std::wifstream
0043     - \c std::wfstream
0044 
0045     \tparam StreamType Class derived from \c std::basic_istream.
0046 */
0047    
0048 template <typename StreamType>
0049 class BasicIStreamWrapper {
0050 public:
0051     typedef typename StreamType::char_type Ch;
0052 
0053     //! Constructor.
0054     /*!
0055         \param stream stream opened for read.
0056     */
0057     BasicIStreamWrapper(StreamType &stream) : stream_(stream), buffer_(peekBuffer_), bufferSize_(4), bufferLast_(0), current_(buffer_), readCount_(0), count_(0), eof_(false) { 
0058         Read();
0059     }
0060 
0061     //! Constructor.
0062     /*!
0063         \param stream stream opened for read.
0064         \param buffer user-supplied buffer.
0065         \param bufferSize size of buffer in bytes. Must >=4 bytes.
0066     */
0067     BasicIStreamWrapper(StreamType &stream, char* buffer, size_t bufferSize) : stream_(stream), buffer_(buffer), bufferSize_(bufferSize), bufferLast_(0), current_(buffer_), readCount_(0), count_(0), eof_(false) { 
0068         RAPIDJSON_ASSERT(bufferSize >= 4);
0069         Read();
0070     }
0071 
0072     Ch Peek() const { return *current_; }
0073     Ch Take() { Ch c = *current_; Read(); return c; }
0074     size_t Tell() const { return count_ + static_cast<size_t>(current_ - buffer_); }
0075 
0076     // Not implemented
0077     void Put(Ch) { RAPIDJSON_ASSERT(false); }
0078     void Flush() { RAPIDJSON_ASSERT(false); } 
0079     Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
0080     size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
0081 
0082     // For encoding detection only.
0083     const Ch* Peek4() const {
0084         return (current_ + 4 - !eof_ <= bufferLast_) ? current_ : 0;
0085     }
0086 
0087 private:
0088     BasicIStreamWrapper();
0089     BasicIStreamWrapper(const BasicIStreamWrapper&);
0090     BasicIStreamWrapper& operator=(const BasicIStreamWrapper&);
0091 
0092     void Read() {
0093         if (current_ < bufferLast_)
0094             ++current_;
0095         else if (!eof_) {
0096             count_ += readCount_;
0097             readCount_ = bufferSize_;
0098             bufferLast_ = buffer_ + readCount_ - 1;
0099             current_ = buffer_;
0100 
0101             if (!stream_.read(buffer_, static_cast<std::streamsize>(bufferSize_))) {
0102                 readCount_ = static_cast<size_t>(stream_.gcount());
0103                 *(bufferLast_ = buffer_ + readCount_) = '\0';
0104                 eof_ = true;
0105             }
0106         }
0107     }
0108 
0109     StreamType &stream_;
0110     Ch peekBuffer_[4], *buffer_;
0111     size_t bufferSize_;
0112     Ch *bufferLast_;
0113     Ch *current_;
0114     size_t readCount_;
0115     size_t count_;  //!< Number of characters read
0116     bool eof_;
0117 };
0118 
0119 typedef BasicIStreamWrapper<std::istream> IStreamWrapper;
0120 typedef BasicIStreamWrapper<std::wistream> WIStreamWrapper;
0121 
0122 #if defined(__clang__) || defined(_MSC_VER)
0123 RAPIDJSON_DIAG_POP
0124 #endif
0125 
0126 RAPIDJSON_NAMESPACE_END
0127 
0128 #endif // RAPIDJSON_ISTREAMWRAPPER_H_