Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:38:59

0001 //
0002 // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
0003 //
0004 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0005 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0006 //
0007 // Official repository: https://github.com/boostorg/json
0008 //
0009 
0010 #ifndef BOOST_JSON_DETAIL_STREAM_HPP
0011 #define BOOST_JSON_DETAIL_STREAM_HPP
0012 
0013 namespace boost {
0014 namespace json {
0015 namespace detail {
0016 
0017 class const_stream
0018 {
0019     friend class local_const_stream;
0020 
0021     char const* p_;
0022     char const* end_;
0023 
0024 public:
0025     const_stream() = default;
0026 
0027     const_stream(
0028         char const* data,
0029         std::size_t size) noexcept
0030         : p_(data)
0031         , end_(data + size)
0032     {
0033     }
0034 
0035     size_t
0036     used(char const* begin) const noexcept
0037     {
0038         return static_cast<
0039             size_t>(p_ - begin);
0040     }
0041 
0042     size_t
0043     remain() const noexcept
0044     {
0045         return end_ - p_;
0046     }
0047 
0048     char const*
0049     data() const noexcept
0050     {
0051         return p_;
0052     }
0053 
0054     operator bool() const noexcept
0055     {
0056         return p_ < end_;
0057     }
0058 
0059     // unchecked
0060     char
0061     operator*() const noexcept
0062     {
0063         BOOST_ASSERT(p_ < end_);
0064         return *p_;
0065     }
0066 
0067     // unchecked
0068     const_stream&
0069     operator++() noexcept
0070     {
0071         BOOST_ASSERT(p_ < end_);
0072         ++p_;
0073         return *this;
0074     }
0075 
0076     void
0077     skip(std::size_t n) noexcept
0078     {
0079         BOOST_ASSERT(n <= remain());
0080         p_ += n;
0081     }
0082 
0083     void
0084     skip_to(const char* p) noexcept
0085     {
0086         BOOST_ASSERT(p <= end_ && p >= p_);
0087         p_ = p;
0088     }
0089 };
0090 
0091 class local_const_stream
0092     : public const_stream
0093 {
0094     const_stream& src_;
0095 
0096 public:
0097     explicit
0098     local_const_stream(
0099         const_stream& src) noexcept
0100         : const_stream(src)
0101         , src_(src)
0102     {
0103     }
0104 
0105     ~local_const_stream()
0106     {
0107         src_.p_ = p_;
0108     }
0109 
0110     void
0111     clip(std::size_t n) noexcept
0112     {
0113         if(static_cast<std::size_t>(
0114             src_.end_ - p_) > n)
0115             end_ = p_ + n;
0116         else
0117             end_ = src_.end_;
0118     }
0119 };
0120 
0121 class const_stream_wrapper
0122 {
0123     const char*& p_;
0124     const char* const end_;
0125 
0126     friend class clipped_const_stream;
0127 public:
0128     const_stream_wrapper(
0129         const char*& p,
0130         const char* end)
0131         : p_(p)
0132         , end_(end)
0133     {
0134     }
0135 
0136     void operator++() noexcept
0137     {
0138         ++p_;
0139     }
0140 
0141     void operator+=(std::size_t n) noexcept
0142     {
0143         p_ += n;
0144     }
0145 
0146     void operator=(const char* p) noexcept
0147     {
0148         p_ = p;
0149     }
0150 
0151     char operator*() const noexcept
0152     {
0153         return *p_;
0154     }
0155 
0156     operator bool() const noexcept
0157     {
0158         return p_ < end_;
0159     }
0160 
0161     const char* begin() const noexcept
0162     {
0163         return p_;
0164     }
0165 
0166     const char* end() const noexcept
0167     {
0168         return end_;
0169     }
0170 
0171     std::size_t remain() const noexcept
0172     {
0173         return end_ - p_;
0174     }
0175 
0176     std::size_t remain(const char* p) const noexcept
0177     {
0178         return end_ - p;
0179     }
0180 
0181     std::size_t used(const char* p) const noexcept
0182     {
0183         return p_ - p;
0184     }
0185 };
0186 
0187 class clipped_const_stream
0188     : public const_stream_wrapper
0189 {
0190     const char* clip_;
0191 
0192 public:
0193     clipped_const_stream(
0194         const char*& p,
0195         const char* end)
0196         : const_stream_wrapper(p, end)
0197         , clip_(end)
0198     {
0199     }
0200 
0201     void operator=(const char* p)
0202     {
0203         p_ = p;
0204     }
0205 
0206     const char* end() const noexcept
0207     {
0208         return clip_;
0209     }
0210 
0211     operator bool() const noexcept
0212     {
0213         return p_ < clip_;
0214     }
0215 
0216     std::size_t remain() const noexcept
0217     {
0218         return clip_ - p_;
0219     }
0220 
0221     std::size_t remain(const char* p) const noexcept
0222     {
0223         return clip_ - p;
0224     }
0225 
0226     void
0227     clip(std::size_t n) noexcept
0228     {
0229         if(static_cast<std::size_t>(
0230             end_ - p_) > n)
0231             clip_ = p_ + n;
0232         else
0233             clip_ = end_;
0234     }
0235 };
0236 
0237 //--------------------------------------
0238 
0239 class stream
0240 {
0241     friend class local_stream;
0242 
0243     char* p_;
0244     char* end_;
0245 
0246 public:
0247     stream(
0248         char* data,
0249         std::size_t size) noexcept
0250         : p_(data)
0251         , end_(data + size)
0252     {
0253     }
0254 
0255     size_t
0256     used(char* begin) const noexcept
0257     {
0258         return static_cast<
0259             size_t>(p_ - begin);
0260     }
0261 
0262     size_t
0263     remain() const noexcept
0264     {
0265         return end_ - p_;
0266     }
0267 
0268     char*
0269     data() noexcept
0270     {
0271         return p_;
0272     }
0273 
0274     operator bool() const noexcept
0275     {
0276         return p_ < end_;
0277     }
0278 
0279     // unchecked
0280     char&
0281     operator*() noexcept
0282     {
0283         BOOST_ASSERT(p_ < end_);
0284         return *p_;
0285     }
0286 
0287     // unchecked
0288     stream&
0289     operator++() noexcept
0290     {
0291         BOOST_ASSERT(p_ < end_);
0292         ++p_;
0293         return *this;
0294     }
0295 
0296     // unchecked
0297     void
0298     append(
0299         char const* src,
0300         std::size_t n) noexcept
0301     {
0302         BOOST_ASSERT(remain() >= n);
0303         std::memcpy(p_, src, n);
0304         p_ += n;
0305     }
0306 
0307     // unchecked
0308     void
0309     append(char c) noexcept
0310     {
0311         BOOST_ASSERT(p_ < end_);
0312         *p_++ = c;
0313     }
0314 
0315     void
0316     advance(std::size_t n) noexcept
0317     {
0318         BOOST_ASSERT(remain() >= n);
0319         p_ += n;
0320     }
0321 };
0322 
0323 class local_stream
0324     : public stream
0325 {
0326     stream& src_;
0327 
0328 public:
0329     explicit
0330     local_stream(
0331         stream& src)
0332         : stream(src)
0333         , src_(src)
0334     {
0335     }
0336 
0337     ~local_stream()
0338     {
0339         src_.p_ = p_;
0340     }
0341 };
0342 
0343 } // detail
0344 } // namespace json
0345 } // namespace boost
0346 
0347 #endif