123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350 |
- //
- // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
- //
- // Distributed under the Boost Software License, Version 1.0. (See accompanying
- // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
- //
- // Official repository: https://github.com/boostorg/json
- //
- #ifndef BOOST_JSON_DETAIL_STREAM_HPP
- #define BOOST_JSON_DETAIL_STREAM_HPP
- BOOST_JSON_NS_BEGIN
- namespace detail {
- class const_stream
- {
- friend class local_const_stream;
- char const* p_;
- char const* end_;
- public:
- const_stream() = default;
- const_stream(
- const_stream const&) = default;
- const_stream(
- char const* data,
- std::size_t size) noexcept
- : p_(data)
- , end_(data + size)
- {
- }
- size_t
- used(char const* begin) const noexcept
- {
- return static_cast<
- size_t>(p_ - begin);
- }
- size_t
- remain() const noexcept
- {
- return end_ - p_;
- }
- char const*
- data() const noexcept
- {
- return p_;
- }
- operator bool() const noexcept
- {
- return p_ < end_;
- }
- // unchecked
- char
- operator*() const noexcept
- {
- BOOST_ASSERT(p_ < end_);
- return *p_;
- }
- // unchecked
- const_stream&
- operator++() noexcept
- {
- BOOST_ASSERT(p_ < end_);
- ++p_;
- return *this;
- }
- void
- skip(std::size_t n) noexcept
- {
- BOOST_ASSERT(n <= remain());
- p_ += n;
- }
- void
- skip_to(const char* p) noexcept
- {
- BOOST_ASSERT(p <= end_ && p >= p_);
- p_ = p;
- }
- };
- class local_const_stream
- : public const_stream
- {
- const_stream& src_;
- public:
- explicit
- local_const_stream(
- const_stream& src) noexcept
- : const_stream(src)
- , src_(src)
- {
- }
- ~local_const_stream()
- {
- src_.p_ = p_;
- }
- void
- clip(std::size_t n) noexcept
- {
- if(static_cast<std::size_t>(
- src_.end_ - p_) > n)
- end_ = p_ + n;
- else
- end_ = src_.end_;
- }
- };
- class const_stream_wrapper
- {
- const char*& p_;
- const char* const end_;
- friend class clipped_const_stream;
- public:
- const_stream_wrapper(
- const char*& p,
- const char* end)
- : p_(p)
- , end_(end)
- {
- }
- void operator++() noexcept
- {
- ++p_;
- }
- void operator+=(std::size_t n) noexcept
- {
- p_ += n;
- }
- void operator=(const char* p) noexcept
- {
- p_ = p;
- }
- char operator*() const noexcept
- {
- return *p_;
- }
- operator bool() const noexcept
- {
- return p_ < end_;
- }
-
- const char* begin() const noexcept
- {
- return p_;
- }
- const char* end() const noexcept
- {
- return end_;
- }
- std::size_t remain() const noexcept
- {
- return end_ - p_;
- }
- std::size_t remain(const char* p) const noexcept
- {
- return end_ - p;
- }
- std::size_t used(const char* p) const noexcept
- {
- return p_ - p;
- }
- };
- class clipped_const_stream
- : public const_stream_wrapper
- {
- const char* clip_;
- public:
- clipped_const_stream(
- const char*& p,
- const char* end)
- : const_stream_wrapper(p, end)
- , clip_(end)
- {
- }
- void operator=(const char* p)
- {
- p_ = p;
- }
- const char* end() const noexcept
- {
- return clip_;
- }
- operator bool() const noexcept
- {
- return p_ < clip_;
- }
- std::size_t remain() const noexcept
- {
- return clip_ - p_;
- }
- std::size_t remain(const char* p) const noexcept
- {
- return clip_ - p;
- }
- void
- clip(std::size_t n) noexcept
- {
- if(static_cast<std::size_t>(
- end_ - p_) > n)
- clip_ = p_ + n;
- else
- clip_ = end_;
- }
- };
- //--------------------------------------
- class stream
- {
- friend class local_stream;
- char* p_;
- char* end_;
- public:
- stream(
- stream const&) = default;
- stream(
- char* data,
- std::size_t size) noexcept
- : p_(data)
- , end_(data + size)
- {
- }
- size_t
- used(char* begin) const noexcept
- {
- return static_cast<
- size_t>(p_ - begin);
- }
- size_t
- remain() const noexcept
- {
- return end_ - p_;
- }
- char*
- data() noexcept
- {
- return p_;
- }
- operator bool() const noexcept
- {
- return p_ < end_;
- }
- // unchecked
- char&
- operator*() noexcept
- {
- BOOST_ASSERT(p_ < end_);
- return *p_;
- }
- // unchecked
- stream&
- operator++() noexcept
- {
- BOOST_ASSERT(p_ < end_);
- ++p_;
- return *this;
- }
- // unchecked
- void
- append(
- char const* src,
- std::size_t n) noexcept
- {
- BOOST_ASSERT(remain() >= n);
- std::memcpy(p_, src, n);
- p_ += n;
- }
- // unchecked
- void
- append(char c) noexcept
- {
- BOOST_ASSERT(p_ < end_);
- *p_++ = c;
- }
- void
- advance(std::size_t n) noexcept
- {
- BOOST_ASSERT(remain() >= n);
- p_ += n;
- }
- };
- class local_stream
- : public stream
- {
- stream& src_;
- public:
- explicit
- local_stream(
- stream& src)
- : stream(src)
- , src_(src)
- {
- }
- ~local_stream()
- {
- src_.p_ = p_;
- }
- };
- } // detail
- BOOST_JSON_NS_END
- #endif
|