346 lines
5.2 KiB
C++
346 lines
5.2 KiB
C++
//
|
|
// 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(
|
|
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(
|
|
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
|