Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions include/jsoncons/sink.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -325,10 +325,52 @@ namespace jsoncons {
{
}

void append(const uint8_t* s, std::size_t length)
{
append_impl(*buf_ptr, s, length, 0);
}

void push_back(uint8_t ch)
{
buf_ptr->push_back(static_cast<value_type>(ch));
}

private:
template <typename C>
static auto append_impl(C& c, const uint8_t* s, std::size_t length, int)
-> decltype(c.append(s, length), void())
{
c.append(s, length);
}

template <typename C>
static auto append_impl(C& c, const uint8_t* s, std::size_t length, long)
-> decltype(c.insert(c.end(), s, s + length), void())
{
c.insert(c.end(), s, s + length);
}

template <typename C>
static void append_impl(C& c, const uint8_t* s, std::size_t length, ...)
{
reserve(c, length, 0);
for (std::size_t i = 0; i < length; ++i)
{
c.push_back(static_cast<typename C::value_type>(s[i]));
}
}

template <typename C>
static auto reserve(C& c, std::size_t length, int)
-> decltype(c.reserve(c.size() + length), void())
{
c.reserve(c.size() + length);
}

template <typename C>
static void reserve(C&, std::size_t, ...)
{
}
};

} // namespace jsoncons
Expand Down
133 changes: 133 additions & 0 deletions include/jsoncons/source.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,28 @@ namespace jsoncons {
return span<const value_type>(data, length);
}

span<const value_type> read_span(std::size_t length)
{
if (length == 0)
{
return span<const value_type>(data_, std::size_t(0));
}
if (length_ < length)
{
make_available(length);
}
if (length_ < length)
{
return span<const value_type>();
}

const value_type* data = data_;
data_ += length;
length_ -= length;
position_ += length;
return span<const value_type>(data, length);
}

std::size_t read(value_type* p, std::size_t length)
{
std::size_t len = 0;
Expand Down Expand Up @@ -395,6 +417,67 @@ namespace jsoncons {
}
}
private:
void reserve_buffer(std::size_t capacity)
{
if (capacity <= buffer_size_)
{
return;
}

value_type* new_buffer = std::allocator_traits<char_allocator_type>::allocate(alloc_, capacity);
if (length_ > 0)
{
std::memcpy(new_buffer, data_, sizeof(value_type)*length_);
}
if (buffer_)
{
std::allocator_traits<char_allocator_type>::deallocate(alloc_, buffer_, buffer_size_);
}
buffer_ = new_buffer;
buffer_size_ = capacity;
data_ = buffer_;
}

void make_available(std::size_t length)
{
if (length > buffer_size_)
{
if (length > default_max_buffer_size)
{
return;
}
reserve_buffer(length);
}
else if (length_ > 0 && data_ != buffer_)
{
std::memmove(buffer_, data_, sizeof(value_type)*length_);
data_ = buffer_;
}
else if (length_ == 0)
{
data_ = buffer_;
}

while (length_ < length && !stream_ptr_->eof())
{
JSONCONS_TRY
{
std::streamsize count = sbuf_->sgetn(reinterpret_cast<char_type*>(buffer_ + length_), buffer_size_ - length_);
std::size_t len = static_cast<std::size_t>(count);
length_ += len;
if (len == 0 || length_ < length)
{
stream_ptr_->clear(stream_ptr_->rdstate() | std::ios::eofbit);
}
}
JSONCONS_CATCH(const std::exception&)
{
stream_ptr_->clear(stream_ptr_->rdstate() | std::ios::badbit | std::ios::eofbit);
return;
}
}
}

void fill_buffer()
{
if (stream_ptr_->eof())
Expand Down Expand Up @@ -503,6 +586,17 @@ namespace jsoncons {
return span<const value_type>(data, length);
}

span<const value_type> read_span(std::size_t length)
{
if (std::size_t(end_ - current_) < length)
{
return span<const value_type>();
}
const value_type* data = current_;
current_ += length;
return span<const value_type>(data, length);
}

std::size_t read(value_type* p, std::size_t length)
{
std::size_t len;
Expand Down Expand Up @@ -596,6 +690,20 @@ namespace jsoncons {
return span<const value_type>(buffer_.data(), length);
}

span<const value_type> read_span(std::size_t length)
{
if (length > buffer_.size())
{
buffer_.resize(length);
}
std::size_t actual = read(buffer_.data(), length);
if (actual != length)
{
return span<const value_type>();
}
return span<const value_type>(buffer_.data(), length);
}

template <typename Category = iterator_category>
typename std::enable_if<std::is_same<Category,std::random_access_iterator_tag>::value, std::size_t>::type
read(value_type* data, std::size_t length)
Expand Down Expand Up @@ -712,6 +820,17 @@ namespace jsoncons {
return span<const value_type>(data, length);
}

span<const value_type> read_span(std::size_t length)
{
if (std::size_t(end_ - current_) < length)
{
return span<const value_type>();
}
const value_type* data = current_;
current_ += length;
return span<const value_type>(data, length);
}

std::size_t read(value_type* p, std::size_t length)
{
std::size_t len;
Expand Down Expand Up @@ -803,6 +922,20 @@ namespace jsoncons {
return span<const value_type>(buffer_.data(), length);
}

span<const value_type> read_span(std::size_t length)
{
if (length > buffer_.size())
{
buffer_.resize(length);
}
std::size_t actual = read(buffer_.data(), length);
if (actual != length)
{
return span<const value_type>();
}
return span<const value_type>(buffer_.data(), length);
}

template <typename Category = iterator_category>
typename std::enable_if<std::is_same<Category,std::random_access_iterator_tag>::value, std::size_t>::type
read(value_type* data, std::size_t length)
Expand Down
2 changes: 1 addition & 1 deletion include/jsoncons_ext/cbor/cbor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
#include <jsoncons_ext/cbor/cbor_cursor.hpp>
#include <jsoncons_ext/cbor/cbor_encoder.hpp>
#include <jsoncons_ext/cbor/cbor_reader.hpp>
#include <jsoncons_ext/cbor/cbor_view.hpp>
#include <jsoncons_ext/cbor/decode_cbor.hpp>
#include <jsoncons_ext/cbor/encode_cbor.hpp>

#endif // JSONCONS_EXT_CBOR_CBOR_HPP

65 changes: 14 additions & 51 deletions include/jsoncons_ext/cbor/cbor_encoder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -485,49 +485,48 @@ class basic_cbor_encoder final : public basic_json_visitor<char>
}
}

void write_utf8_string(const string_view& sv)
void write_type_and_length(uint8_t major_type, std::size_t length)
{
const size_t length = sv.size();

if (length <= 0x17)
{
// fixstr stores a byte array whose length is upto 31 bytes
binary::native_to_big(static_cast<uint8_t>(0x60 + length),
binary::native_to_big(static_cast<uint8_t>(major_type + length),
std::back_inserter(sink_));
}
else if (length <= 0xff)
{
binary::native_to_big(static_cast<uint8_t>(0x78),
binary::native_to_big(static_cast<uint8_t>(major_type + 0x18),
std::back_inserter(sink_));
binary::native_to_big(static_cast<uint8_t>(length),
std::back_inserter(sink_));
}
else if (length <= 0xffff)
{
binary::native_to_big(static_cast<uint8_t>(0x79),
binary::native_to_big(static_cast<uint8_t>(major_type + 0x19),
std::back_inserter(sink_));
binary::native_to_big(static_cast<uint16_t>(length),
std::back_inserter(sink_));
}
else if (length <= 0xffffffff)
{
binary::native_to_big(static_cast<uint8_t>(0x7a),
binary::native_to_big(static_cast<uint8_t>(major_type + 0x1a),
std::back_inserter(sink_));
binary::native_to_big(static_cast<uint32_t>(length),
std::back_inserter(sink_));
}
else if (uint64_t(length) <= (std::numeric_limits<std::uint64_t>::max)())
{
binary::native_to_big(static_cast<uint8_t>(0x7b),
binary::native_to_big(static_cast<uint8_t>(major_type + 0x1b),
std::back_inserter(sink_));
binary::native_to_big(static_cast<uint64_t>(length),
std::back_inserter(sink_));
}
}

for (auto c : sv)
{
sink_.push_back(c);
}
void write_utf8_string(const string_view& sv)
{
write_type_and_length(0x60, sv.size());

sink_.append(reinterpret_cast<const uint8_t*>(sv.data()), sv.size());
}

void write_bignum(bigint& n)
Expand Down Expand Up @@ -1069,45 +1068,9 @@ class basic_cbor_encoder final : public basic_json_visitor<char>

void write_byte_string(const byte_string_view& b)
{
if (b.size() <= 0x17)
{
// fixstr stores a byte array whose length is upto 31 bytes
binary::native_to_big(static_cast<uint8_t>(0x40 + b.size()),
std::back_inserter(sink_));
}
else if (b.size() <= 0xff)
{
binary::native_to_big(static_cast<uint8_t>(0x58),
std::back_inserter(sink_));
binary::native_to_big(static_cast<uint8_t>(b.size()),
std::back_inserter(sink_));
}
else if (b.size() <= 0xffff)
{
binary::native_to_big(static_cast<uint8_t>(0x59),
std::back_inserter(sink_));
binary::native_to_big(static_cast<uint16_t>(b.size()),
std::back_inserter(sink_));
}
else if (b.size() <= 0xffffffff)
{
binary::native_to_big(static_cast<uint8_t>(0x5a),
std::back_inserter(sink_));
binary::native_to_big(static_cast<uint32_t>(b.size()),
std::back_inserter(sink_));
}
else // if (b.size() <= 0xffffffffffffffff)
{
binary::native_to_big(static_cast<uint8_t>(0x5b),
std::back_inserter(sink_));
binary::native_to_big(static_cast<uint64_t>(b.size()),
std::back_inserter(sink_));
}
write_type_and_length(0x40, b.size());

for (auto c : b)
{
sink_.push_back(c);
}
sink_.append(b.data(), b.size());
}

JSONCONS_VISITOR_RETURN_TYPE visit_double(double val,
Expand Down
Loading
Loading