From fdeed0348e530b8537509f1c9aee5f536745b03e Mon Sep 17 00:00:00 2001 From: danielaparker Date: Mon, 18 May 2020 11:45:36 -0400 Subject: [PATCH] Example update --- README.md | 15 ++- doc/Examples.md | 59 +++++----- doc/ref/basic_json_cursor.md | 81 ++++---------- doc/ref/bson/basic_bson_cursor.md | 15 +-- doc/ref/cbor/basic_cbor_cursor.md | 7 +- doc/ref/cbor/cbor.md | 8 +- doc/ref/ubjson/ubjson.md | 8 +- examples/src/cbor_examples.cpp | 8 +- examples/src/json_cursor_examples.cpp | 36 +++--- examples/src/readme_examples.cpp | 14 +-- examples/src/ubjson_examples.cpp | 8 +- include/jsoncons/json_cursor.hpp | 105 ++++++++++-------- include/jsoncons/staj_cursor.hpp | 104 ++++++++++++++--- include/jsoncons_ext/bson/bson_cursor.hpp | 51 +++++---- include/jsoncons_ext/cbor/cbor_cursor.hpp | 11 +- include/jsoncons_ext/csv/csv_cursor.hpp | 7 ++ .../jsoncons_ext/msgpack/msgpack_cursor.hpp | 11 +- include/jsoncons_ext/ubjson/ubjson_cursor.hpp | 11 +- tests/src/staj_view_tests.cpp | 76 ++++++++++--- 19 files changed, 365 insertions(+), 270 deletions(-) diff --git a/README.md b/README.md index e951a64359..7e76323fc5 100644 --- a/README.md +++ b/README.md @@ -400,21 +400,20 @@ int main() name = ev.get(); return false; } - else if (name == "rated") + if (name == "rated") { name.clear(); return true; } - else - { - return false; - } + return false; }; - json_cursor cursor(data, filter); - for (; !cursor.done(); cursor.next()) + json_cursor cursor(data); + + auto filtered_c = cursor | filter; + for (; !filtered_c.done(); filtered_c.next()) { - const auto& event = cursor.current(); + const auto& event = filtered_c.current(); switch (event.event_type()) { case staj_event_type::string_value: diff --git a/doc/Examples.md b/doc/Examples.md index d65135fed8..ecce0fde73 100644 --- a/doc/Examples.md +++ b/doc/Examples.md @@ -562,54 +562,45 @@ end_array #include #include -// A stream filter to filter out all events except name -// and restrict name to "author" +// Filter out all events except names of authors -struct author_filter +int main() { - bool accept_next_ = false; + std::ifstream is("book_catalog.json"); + + json_cursor cursor(is); - bool operator()(const staj_event& event, const ser_context&) + bool author_next = false; + auto filtered_c = cursor | + [&](const staj_event& event, const ser_context&) -> bool { - if (event.event_type() == staj_event_type::key && + if (event.event_type() == staj_event_type::key && event.get() == "author") { - accept_next_ = true; + author_next = true; return false; } - else if (accept_next_) + if (author_next) { - accept_next_ = false; + author_next = false; return true; } - else + return false; + }; + + for (; !filtered_c.done(); filtered_c.next()) + { + const auto& event = filtered_c.current(); + switch (event.event_type()) { - accept_next_ = false; - return false; + case staj_event_type::string_value: + std::cout << event.get() << "\n"; + break; + default: + std::cout << "Unhandled event type: " << event.event_type() << " " << "\n"; + break; } } -}; - -int main() -{ - std::ifstream is("book_catalog.json"); - - author_filter filter; - json_cursor cursor(is, filter); - - for (; !cursor.done(); cursor.next()) - { - const auto& event = cursor.current(); - switch (event.event_type()) - { - case staj_event_type::string_value: - std::cout << event.get() << "\n"; - break; - default: - std::cout << "Unhandled event type: " << event.event_type() << " " << "\n"; - break; - } - } } ``` Output: diff --git a/doc/ref/basic_json_cursor.md b/doc/ref/basic_json_cursor.md index 34ff82f731..0d0ee44826 100644 --- a/doc/ref/basic_json_cursor.md +++ b/doc/ref/basic_json_cursor.md @@ -40,55 +40,22 @@ wjson_cursor |`basic_json_cursor` const Allocator& alloc = Allocator()); // (1) template - basic_json_cursor(Source&& source, - std::function&, const ser_context&)> filter, - const basic_json_decode_options& options = basic_json_decode_options(), - std::function err_handler = default_json_parsing(), - const Allocator& alloc = Allocator()); // (2) - - template - basic_json_cursor(Source&& source, std::error_code& ec); // (3) + basic_json_cursor(Source&& source, std::error_code& ec); // (2) template basic_json_cursor(Source&& source, const basic_json_decode_options& options, - std::error_code& ec) // (4) + std::error_code& ec) // (3) template basic_json_cursor(Source&& source, const basic_json_decode_options& options, std::function err_handler, - std::error_code& ec) // (5) - - template - basic_json_cursor(Source&& source, - std::function&, const ser_context&)> filter, - std::error_code& ec); // (6) - - template - basic_json_cursor(Source&& source, - std::function&, const ser_context&)> filter, - const basic_json_decode_options& options, - std::error_code& ec) // (7) - - template - basic_json_cursor(Source&& source, - std::function&, const ser_context&)> filter, - const basic_json_decode_options& options, - std::function err_handler, - std::error_code& ec) // (8) - - template - basic_json_cursor(std::allocator_arg_t, const Allocator& alloc, - Source&& source, - std::function&, const ser_context&)> filter, - const basic_json_decode_options& options, - std::function err_handler, - std::error_code& ec); // (9) + std::error_code& ec) // (4) -Constructors (1)-(2) read from a character sequence or stream and throw a +Constructor (1) reads from a character sequence or stream and throws a [ser_error](ser_error.md) if a parsing error is encountered while processing the initial event. -Constructors (3)-(9) read from a character sequence or stream and set `ec` +Constructors (2)-(4) read from a character sequence or stream and set `ec` if a parsing error is encountered while processing the initial event. Note: It is the programmer's responsibility to ensure that `basic_json_cursor` does not outlive the source, @@ -259,41 +226,33 @@ end_array using namespace jsoncons; -struct author_filter +int main() { - bool accept_next_ = false; + std::ifstream is("book_catalog.json"); - bool operator()(const staj_event& event, const ser_context&) + json_cursor cursor(is); + + bool author_next = false; + auto filtered_c = cursor | + [&](const staj_event& event, const ser_context&) -> bool { - if (event.event_type() == staj_event_type::key && + if (event.event_type() == staj_event_type::key && event.get() == "author") { - accept_next_ = true; + author_next = true; return false; } - else if (accept_next_) + if (author_next) { - accept_next_ = false; + author_next = false; return true; } - else - { - accept_next_ = false; - return false; - } - } -}; + return false; + }; -int main() -{ - std::ifstream is("book_catalog.json"); - - author_filter filter; - json_cursor cursor(is, filter); - - for (; !cursor.done(); cursor.next()) + for (; !filtered_c.done(); filtered_c.next()) { - const auto& event = cursor.current(); + const auto& event = filtered_c.current(); switch (event.event_type()) { case staj_event_type::string_value: diff --git a/doc/ref/bson/basic_bson_cursor.md b/doc/ref/bson/basic_bson_cursor.md index 1ac3b9d028..6d34139064 100644 --- a/doc/ref/bson/basic_bson_cursor.md +++ b/doc/ref/bson/basic_bson_cursor.md @@ -239,16 +239,12 @@ struct author_filter accept_next_ = true; return false; } - else if (accept_next_) + if (accept_next_) { accept_next_ = false; return true; } - else - { - accept_next_ = false; - return false; - } + return false; } }; @@ -257,11 +253,12 @@ int main() std::ifstream is("book_catalog.json"); author_filter filter; - bson_cursor cursor(is, filter); + bson_cursor cursor(is); - for (; !cursor.done(); cursor.next()) + auto filtered_c = cursor | filter; + for (; !filtered_c.done(); filtered_c.next()) { - const auto& event = cursor.current(); + const auto& event = filtered_c.current(); switch (event.event_type()) { case staj_event_type::string_value: diff --git a/doc/ref/cbor/basic_cbor_cursor.md b/doc/ref/cbor/basic_cbor_cursor.md index 1a61419efe..eafd98e858 100644 --- a/doc/ref/cbor/basic_cbor_cursor.md +++ b/doc/ref/cbor/basic_cbor_cursor.md @@ -258,11 +258,12 @@ int main() std::ifstream is("book_catalog.json"); author_filter filter; - cbor_cursor cursor(is, filter); + cbor_cursor cursor(is); - for (; !cursor.done(); cursor.next()) + auto filtered_c = cursor | filter; + for (; !filtered_c.done(); filtered_c.next()) { - const auto& event = cursor.current(); + const auto& event = filtered_c.current(); switch (event.event_type()) { case staj_event_type::string_value: diff --git a/doc/ref/cbor/cbor.md b/doc/ref/cbor/cbor.md index 90402c31e7..442132b087 100644 --- a/doc/ref/cbor/cbor.md +++ b/doc/ref/cbor/cbor.md @@ -341,10 +341,12 @@ int main() return (ev.tag() == semantic_tag::bigdec) || (ev.tag() == semantic_tag::bigfloat); }; - cbor::cbor_bytes_cursor cursor(data, filter); - for (; !cursor.done(); cursor.next()) + cbor::cbor_bytes_cursor cursor(data); + + auto filtered_c = cursor | filter; + for (; !filtered_c.done(); filtered_c.next()) { - const auto& event = cursor.current(); + const auto& event = filtered_c.current(); switch (event.event_type()) { case staj_event_type::string_value: diff --git a/doc/ref/ubjson/ubjson.md b/doc/ref/ubjson/ubjson.md index 8135478d65..b3376b3ba8 100644 --- a/doc/ref/ubjson/ubjson.md +++ b/doc/ref/ubjson/ubjson.md @@ -219,10 +219,12 @@ int main() return (ev.event_type() == staj_event_type::double_value) && (ev.get() < 30.0); }; - ubjson::ubjson_bytes_cursor cursor(data, filter); - for (; !cursor.done(); cursor.next()) + ubjson::ubjson_bytes_cursor cursor(data); + + auto filtered_c = cursor | filter; + for (; !filtered_c.done(); filtered_c.next()) { - const auto& event = cursor.current(); + const auto& event = filtered_c.current(); switch (event.event_type()) { case staj_event_type::double_value: diff --git a/examples/src/cbor_examples.cpp b/examples/src/cbor_examples.cpp index e1764b33fb..35df0f1bab 100644 --- a/examples/src/cbor_examples.cpp +++ b/examples/src/cbor_examples.cpp @@ -531,10 +531,12 @@ namespace { return (ev.tag() == semantic_tag::bigdec) || (ev.tag() == semantic_tag::bigfloat); }; - cbor::cbor_bytes_cursor cursor(data, filter); - for (; !cursor.done(); cursor.next()) + cbor::cbor_bytes_cursor cursor(data); + + auto filtered_c = cursor | filter; + for (; !filtered_c.done(); filtered_c.next()) { - const auto& event = cursor.current(); + const auto& event = filtered_c.current(); switch (event.event_type()) { case staj_event_type::string_value: diff --git a/examples/src/json_cursor_examples.cpp b/examples/src/json_cursor_examples.cpp index 9ce7d4b34f..50aa793622 100644 --- a/examples/src/json_cursor_examples.cpp +++ b/examples/src/json_cursor_examples.cpp @@ -106,40 +106,32 @@ namespace { } } - struct author_filter + // Filtering the stream + void filtering_a_json_stream() { - bool accept_next_ = false; + json_cursor cursor(example); - bool operator()(const staj_event& event, const ser_context&) + bool author_next = false; + auto filtered_c = cursor | + [&](const staj_event& event, const ser_context&) -> bool { - if (event.event_type() == staj_event_type::key && + if (event.event_type() == staj_event_type::key && event.get() == "author") { - accept_next_ = true; + author_next = true; return false; } - else if (accept_next_) + if (author_next) { - accept_next_ = false; + author_next = false; return true; } - else - { - accept_next_ = false; - return false; - } - } - }; + return false; + }; - // Filtering the stream - void filtering_a_json_stream() - { - author_filter filter; - json_cursor cursor(example, filter); - - for (; !cursor.done(); cursor.next()) + for (; !filtered_c.done(); filtered_c.next()) { - const auto& event = cursor.current(); + const auto& event = filtered_c.current(); switch (event.event_type()) { case staj_event_type::string_value: diff --git a/examples/src/readme_examples.cpp b/examples/src/readme_examples.cpp index 27b181baed..8e30f5eed6 100644 --- a/examples/src/readme_examples.cpp +++ b/examples/src/readme_examples.cpp @@ -186,22 +186,20 @@ namespace { name = ev.get(); return false; } - else if (name == "rated") + if (name == "rated") { name.clear(); return true; } - else - { - return false; - } + return false; }; - json_cursor cursor(data, filter); + json_cursor cursor(data); - for (; !cursor.done(); cursor.next()) + auto filtered_c = cursor | filter; + for (; !filtered_c.done(); filtered_c.next()) { - const auto& event = cursor.current(); + const auto& event = filtered_c.current(); switch (event.event_type()) { case staj_event_type::string_value: diff --git a/examples/src/ubjson_examples.cpp b/examples/src/ubjson_examples.cpp index e0486fa3b2..b7a98e1d57 100644 --- a/examples/src/ubjson_examples.cpp +++ b/examples/src/ubjson_examples.cpp @@ -182,10 +182,12 @@ namespace { return (ev.event_type() == staj_event_type::double_value) && (ev.get() < 30.0); }; - ubjson::ubjson_bytes_cursor cursor(data, filter); - for (; !cursor.done(); cursor.next()) + ubjson::ubjson_bytes_cursor cursor(data); + + auto filtered_c = cursor | filter; + for (; !filtered_c.done(); filtered_c.next()) { - const auto& event = cursor.current(); + const auto& event = filtered_c.current(); switch (event.event_type()) { case staj_event_type::double_value: diff --git a/include/jsoncons/json_cursor.hpp b/include/jsoncons/json_cursor.hpp index 2b5b06b72d..c284f5010c 100644 --- a/include/jsoncons/json_cursor.hpp +++ b/include/jsoncons/json_cursor.hpp @@ -300,11 +300,6 @@ class basic_json_cursor : public basic_staj_cursor, private virtual ser_c read_next(ec); } - static bool accept_all(const basic_staj_event&, const ser_context&) - { - return true; - } - void read_buffer(std::error_code& ec) { buffer_.clear(); @@ -333,50 +328,6 @@ class basic_json_cursor : public basic_staj_cursor, private virtual ser_c } } - void read_next(std::error_code& ec) - { - parser_.restart(); - while (!parser_.stopped()) - { - if (parser_.source_exhausted()) - { - if (!source_.eof()) - { - read_buffer(ec); - if (ec) return; - } - else - { - eof_ = true; - } - } - parser_.parse_some(cursor_visitor_, ec); - if (ec) return; - } - } - - void read_next(basic_json_visitor& visitor, std::error_code& ec) - { - parser_.restart(); - while (!parser_.stopped()) - { - if (parser_.source_exhausted()) - { - if (!source_.eof()) - { - read_buffer(ec); - if (ec) return; - } - else - { - eof_ = true; - } - } - parser_.parse_some(visitor, ec); - if (ec) return; - } - } - void check_done() { std::error_code ec; @@ -444,6 +395,13 @@ class basic_json_cursor : public basic_staj_cursor, private virtual ser_c return parser_.column(); } + friend + staj_filter_view operator|(basic_json_cursor& cursor, + std::function&, const ser_context&)> pred) + { + return staj_filter_view(cursor, pred); + } + #if !defined(JSONCONS_NO_DEPRECATED) JSONCONS_DEPRECATED_MSG("Instead, use read_to(basic_json_visitor&)") void read(basic_json_visitor& visitor) @@ -459,6 +417,55 @@ class basic_json_cursor : public basic_staj_cursor, private virtual ser_c } #endif private: + + static bool accept_all(const basic_staj_event&, const ser_context&) + { + return true; + } + + void read_next(std::error_code& ec) + { + parser_.restart(); + while (!parser_.stopped()) + { + if (parser_.source_exhausted()) + { + if (!source_.eof()) + { + read_buffer(ec); + if (ec) return; + } + else + { + eof_ = true; + } + } + parser_.parse_some(cursor_visitor_, ec); + if (ec) return; + } + } + + void read_next(basic_json_visitor& visitor, std::error_code& ec) + { + parser_.restart(); + while (!parser_.stopped()) + { + if (parser_.source_exhausted()) + { + if (!source_.eof()) + { + read_buffer(ec); + if (ec) return; + } + else + { + eof_ = true; + } + } + parser_.parse_some(visitor, ec); + if (ec) return; + } + } }; using json_cursor = basic_json_cursor; diff --git a/include/jsoncons/staj_cursor.hpp b/include/jsoncons/staj_cursor.hpp index cd08c8f023..afb50e23aa 100644 --- a/include/jsoncons/staj_cursor.hpp +++ b/include/jsoncons/staj_cursor.hpp @@ -733,7 +733,7 @@ class basic_staj_visitor : public basic_json_visitor using char_type = CharT; using typename super_type::string_view_type; private: - std::function&, const ser_context&)> filter_; + std::function&, const ser_context&)> pred_; basic_staj_event event_; staj_cursor_state state_; @@ -742,13 +742,13 @@ class basic_staj_visitor : public basic_json_visitor std::size_t index_; public: basic_staj_visitor() - : filter_(accept), event_(staj_event_type::null_value), + : pred_(accept), event_(staj_event_type::null_value), state_(), data_(), shape_(), index_(0) { } - basic_staj_visitor(std::function&, const ser_context&)> filter) - : filter_(filter), event_(staj_event_type::null_value), + basic_staj_visitor(std::function&, const ser_context&)> pred) + : pred_(pred), event_(staj_event_type::null_value), state_(), data_(), shape_(), index_(0) { } @@ -1047,49 +1047,49 @@ class basic_staj_visitor : public basic_json_visitor bool visit_begin_object(semantic_tag tag, const ser_context& context, std::error_code&) override { event_ = basic_staj_event(staj_event_type::begin_object, tag); - return !filter_(event_, context); + return !pred_(event_, context); } bool visit_end_object(const ser_context& context, std::error_code&) override { event_ = basic_staj_event(staj_event_type::end_object); - return !filter_(event_, context); + return !pred_(event_, context); } bool visit_begin_array(semantic_tag tag, const ser_context& context, std::error_code&) override { event_ = basic_staj_event(staj_event_type::begin_array, tag); - return !filter_(event_, context); + return !pred_(event_, context); } bool visit_end_array(const ser_context& context, std::error_code&) override { event_ = basic_staj_event(staj_event_type::end_array); - return !filter_(event_, context); + return !pred_(event_, context); } bool visit_key(const string_view_type& name, const ser_context& context, std::error_code&) override { event_ = basic_staj_event(name, staj_event_type::key); - return !filter_(event_, context); + return !pred_(event_, context); } bool visit_null(semantic_tag tag, const ser_context& context, std::error_code&) override { event_ = basic_staj_event(staj_event_type::null_value, tag); - return !filter_(event_, context); + return !pred_(event_, context); } bool visit_bool(bool value, semantic_tag tag, const ser_context& context, std::error_code&) override { event_ = basic_staj_event(value, tag); - return !filter_(event_, context); + return !pred_(event_, context); } bool visit_string(const string_view_type& s, semantic_tag tag, const ser_context& context, std::error_code&) override { event_ = basic_staj_event(s, staj_event_type::string_value, tag); - return !filter_(event_, context); + return !pred_(event_, context); } bool visit_byte_string(const byte_string_view& s, @@ -1098,7 +1098,7 @@ class basic_staj_visitor : public basic_json_visitor std::error_code&) override { event_ = basic_staj_event(s, staj_event_type::byte_string_value, tag); - return !filter_(event_, context); + return !pred_(event_, context); } bool visit_byte_string(const byte_string_view& s, @@ -1107,7 +1107,7 @@ class basic_staj_visitor : public basic_json_visitor std::error_code&) override { event_ = basic_staj_event(s, staj_event_type::byte_string_value, custom_tag); - return !filter_(event_, context); + return !pred_(event_, context); } bool visit_uint64(uint64_t value, @@ -1116,7 +1116,7 @@ class basic_staj_visitor : public basic_json_visitor std::error_code&) override { event_ = basic_staj_event(value, tag); - return !filter_(event_, context); + return !pred_(event_, context); } bool visit_int64(int64_t value, @@ -1125,7 +1125,7 @@ class basic_staj_visitor : public basic_json_visitor std::error_code&) override { event_ = basic_staj_event(value, tag); - return !filter_(event_, context); + return !pred_(event_, context); } bool visit_half(uint16_t value, @@ -1134,7 +1134,7 @@ class basic_staj_visitor : public basic_json_visitor std::error_code&) override { event_ = basic_staj_event(half_arg, value, tag); - return !filter_(event_, context); + return !pred_(event_, context); } bool visit_double(double value, @@ -1143,7 +1143,7 @@ class basic_staj_visitor : public basic_json_visitor std::error_code&) override { event_ = basic_staj_event(value, tag); - return !filter_(event_, context); + return !pred_(event_, context); } bool visit_typed_array(const span& v, @@ -1359,6 +1359,74 @@ class basic_staj_cursor virtual const ser_context& context() const = 0; }; +template +class staj_filter_view : basic_staj_cursor +{ + basic_staj_cursor* cursor_; + std::function&, const ser_context&)> pred_; +public: + staj_filter_view(basic_staj_cursor& cursor, + std::function&, const ser_context&)> pred) + : cursor_(std::addressof(cursor)), pred_(pred) + { + while (!done() && !pred_(current(),context())) + { + cursor_->next(); + } + } + + bool done() const override + { + return cursor_->done(); + } + + const basic_staj_event& current() const override + { + return cursor_->current(); + } + + void read_to(basic_json_visitor& visitor) override + { + cursor_->read_to(visitor); + } + + void read_to(basic_json_visitor& visitor, + std::error_code& ec) override + { + cursor_->read_to(visitor, ec); + } + + void next() override + { + cursor_->next(); + while (!done() && !pred_(current(),context())) + { + cursor_->next(); + } + } + + void next(std::error_code& ec) override + { + cursor_->next(ec); + while (!done() && !pred_(current(),context()) && !ec) + { + cursor_->next(ec); + } + } + + const ser_context& context() const override + { + return cursor_->context(); + } + + friend + staj_filter_view operator|(staj_filter_view& cursor, + std::function&, const ser_context&)> pred) + { + return staj_filter_view(cursor, pred); + } +}; + using staj_event = basic_staj_event; using wstaj_event = basic_staj_event; diff --git a/include/jsoncons_ext/bson/bson_cursor.hpp b/include/jsoncons_ext/bson/bson_cursor.hpp index 9b77bb42a5..54a96cd70c 100644 --- a/include/jsoncons_ext/bson/bson_cursor.hpp +++ b/include/jsoncons_ext/bson/bson_cursor.hpp @@ -119,7 +119,7 @@ class basic_bson_cursor : public basic_staj_cursor, private virtual ser_co return parser_.done(); } - const basic_staj_event& current() const override + const staj_event& current() const override { return cursor_visitor_.event(); } @@ -158,26 +158,6 @@ class basic_bson_cursor : public basic_staj_cursor, private virtual ser_co read_next(ec); } - void read_next(std::error_code& ec) - { - parser_.restart(); - while (!parser_.stopped()) - { - parser_.parse(cursor_visitor_, ec); - if (ec) return; - } - } - - void read_next(basic_json_visitor& visitor, std::error_code& ec) - { - parser_.restart(); - while (!parser_.stopped()) - { - parser_.parse(visitor, ec); - if (ec) return; - } - } - const ser_context& context() const override { return *this; @@ -198,6 +178,13 @@ class basic_bson_cursor : public basic_staj_cursor, private virtual ser_co return parser_.column(); } + friend + staj_filter_view operator|(basic_bson_cursor& cursor, + std::function pred) + { + return staj_filter_view(cursor, pred); + } + #if !defined(JSONCONS_NO_DEPRECATED) JSONCONS_DEPRECATED_MSG("Instead, use read_to(basic_json_visitor&)") void read(basic_json_visitor& visitor) @@ -213,10 +200,30 @@ class basic_bson_cursor : public basic_staj_cursor, private virtual ser_co } #endif private: - static bool accept_all(const basic_staj_event&, const ser_context&) + static bool accept_all(const staj_event&, const ser_context&) { return true; } + + void read_next(std::error_code& ec) + { + parser_.restart(); + while (!parser_.stopped()) + { + parser_.parse(cursor_visitor_, ec); + if (ec) return; + } + } + + void read_next(basic_json_visitor& visitor, std::error_code& ec) + { + parser_.restart(); + while (!parser_.stopped()) + { + parser_.parse(visitor, ec); + if (ec) return; + } + } }; using bson_stream_cursor = basic_bson_cursor; diff --git a/include/jsoncons_ext/cbor/cbor_cursor.hpp b/include/jsoncons_ext/cbor/cbor_cursor.hpp index be833010b7..deb51d0b92 100644 --- a/include/jsoncons_ext/cbor/cbor_cursor.hpp +++ b/include/jsoncons_ext/cbor/cbor_cursor.hpp @@ -126,7 +126,7 @@ class basic_cbor_cursor : public basic_staj_cursor, private virtual ser_co return cursor_visitor_.is_typed_array(); } - const basic_staj_event& current() const override + const staj_event& current() const override { return cursor_visitor_.event(); } @@ -185,6 +185,13 @@ class basic_cbor_cursor : public basic_staj_cursor, private virtual ser_co return parser_.column(); } + friend + staj_filter_view operator|(basic_cbor_cursor& cursor, + std::function pred) + { + return staj_filter_view(cursor, pred); + } + #if !defined(JSONCONS_NO_DEPRECATED) JSONCONS_DEPRECATED_MSG("Instead, use read_to(basic_json_visitor&)") void read(basic_json_visitor& visitor) @@ -200,7 +207,7 @@ class basic_cbor_cursor : public basic_staj_cursor, private virtual ser_co } #endif private: - static bool accept_all(const basic_staj_event&, const ser_context&) + static bool accept_all(const staj_event&, const ser_context&) { return true; } diff --git a/include/jsoncons_ext/csv/csv_cursor.hpp b/include/jsoncons_ext/csv/csv_cursor.hpp index dd476214e2..5967c8c74f 100644 --- a/include/jsoncons_ext/csv/csv_cursor.hpp +++ b/include/jsoncons_ext/csv/csv_cursor.hpp @@ -393,6 +393,13 @@ class basic_csv_cursor : public basic_staj_cursor, private virtual ser_co return parser_.column(); } + friend + staj_filter_view operator|(basic_csv_cursor& cursor, + std::function&, const ser_context&)> pred) + { + return staj_filter_view(cursor, pred); + } + #if !defined(JSONCONS_NO_DEPRECATED) JSONCONS_DEPRECATED_MSG("Instead, use read_to(basic_json_visitor&)") void read(basic_json_visitor& visitor) diff --git a/include/jsoncons_ext/msgpack/msgpack_cursor.hpp b/include/jsoncons_ext/msgpack/msgpack_cursor.hpp index 045db63f91..9f628b610a 100644 --- a/include/jsoncons_ext/msgpack/msgpack_cursor.hpp +++ b/include/jsoncons_ext/msgpack/msgpack_cursor.hpp @@ -122,7 +122,7 @@ class basic_msgpack_cursor : public basic_staj_cursor, private virtual ser return parser_.done(); } - const basic_staj_event& current() const override + const staj_event& current() const override { return cursor_visitor_.event(); } @@ -181,6 +181,13 @@ class basic_msgpack_cursor : public basic_staj_cursor, private virtual ser return parser_.column(); } + friend + staj_filter_view operator|(basic_msgpack_cursor& cursor, + std::function pred) + { + return staj_filter_view(cursor, pred); + } + #if !defined(JSONCONS_NO_DEPRECATED) JSONCONS_DEPRECATED_MSG("Instead, use read_to(basic_json_visitor&)") void read(basic_json_visitor& visitor) @@ -196,7 +203,7 @@ class basic_msgpack_cursor : public basic_staj_cursor, private virtual ser } #endif private: - static bool accept_all(const basic_staj_event&, const ser_context&) + static bool accept_all(const staj_event&, const ser_context&) { return true; } diff --git a/include/jsoncons_ext/ubjson/ubjson_cursor.hpp b/include/jsoncons_ext/ubjson/ubjson_cursor.hpp index af210e499b..0995a6e32c 100644 --- a/include/jsoncons_ext/ubjson/ubjson_cursor.hpp +++ b/include/jsoncons_ext/ubjson/ubjson_cursor.hpp @@ -118,7 +118,7 @@ class basic_ubjson_cursor : public basic_staj_cursor, private virtual ser_ return parser_.done(); } - const basic_staj_event& current() const override + const staj_event& current() const override { return cursor_visitor_.event(); } @@ -177,6 +177,13 @@ class basic_ubjson_cursor : public basic_staj_cursor, private virtual ser_ return parser_.column(); } + friend + staj_filter_view operator|(basic_ubjson_cursor& cursor, + std::function pred) + { + return staj_filter_view(cursor, pred); + } + #if !defined(JSONCONS_NO_DEPRECATED) JSONCONS_DEPRECATED_MSG("Instead, use read_to(basic_json_visitor&)") void read(basic_json_visitor& visitor) @@ -192,7 +199,7 @@ class basic_ubjson_cursor : public basic_staj_cursor, private virtual ser_ } #endif private: - static bool accept_all(const basic_staj_event&, const ser_context&) + static bool accept_all(const staj_event&, const ser_context&) { return true; } diff --git a/tests/src/staj_view_tests.cpp b/tests/src/staj_view_tests.cpp index b95139e674..0ea2f563e7 100644 --- a/tests/src/staj_view_tests.cpp +++ b/tests/src/staj_view_tests.cpp @@ -41,24 +41,64 @@ TEST_CASE("jtaj_array_view tests") ] )"; - json_cursor cursor(s); - - auto view = staj_array(cursor); - - auto it = view.begin(); - auto end = view.end(); - - const auto& j1 = *it; - REQUIRE(j1.is_object()); - CHECK(j1["firstName"].as() == std::string("Tom")); - ++it; - const auto& j2 = *it; - CHECK(j2["firstName"].as() == std::string("Catherine")); - ++it; - const auto& j3 = *it; - CHECK(j3["firstName"].as() == std::string("William")); - ++it; - CHECK((it == end)); + SECTION("test 1") + { + json_cursor cursor(s); + + auto view = staj_array(cursor); + + auto it = view.begin(); + auto end = view.end(); + + const auto& j1 = *it; + REQUIRE(j1.is_object()); + CHECK(j1["firstName"].as() == std::string("Tom")); + ++it; + const auto& j2 = *it; + CHECK(j2["firstName"].as() == std::string("Catherine")); + ++it; + const auto& j3 = *it; + CHECK(j3["firstName"].as() == std::string("William")); + ++it; + CHECK((it == end)); + } + + SECTION("filter test") + { + json_cursor cursor(s); + + bool author_next = false; + auto filtered_c = cursor | + [&](const staj_event& event, const ser_context&) -> bool + { + if (event.event_type() == staj_event_type::key && + event.get() == "firstName") + { + author_next = true; + return false; + } + if (author_next) + { + author_next = false; + return true; + } + return false; + }; + + REQUIRE(!filtered_c.done()); + CHECK(filtered_c.current().event_type() == staj_event_type::string_value); + CHECK(filtered_c.current().get() == std::string("Tom")); + filtered_c.next(); + REQUIRE(!filtered_c.done()); + CHECK(filtered_c.current().event_type() == staj_event_type::string_value); + CHECK(filtered_c.current().get() == std::string("Catherine")); + filtered_c.next(); + REQUIRE(!filtered_c.done()); + CHECK(filtered_c.current().event_type() == staj_event_type::string_value); + CHECK(filtered_c.current().get() == std::string("William")); + filtered_c.next(); + REQUIRE(filtered_c.done()); + } } TEST_CASE("object_iterator test")