From 0f36ab53cbac06b61d1b4b6509590759ed8c6703 Mon Sep 17 00:00:00 2001 From: Bardur Arantsson Date: Wed, 5 Oct 2016 18:45:08 +0200 Subject: Introduce jsoncons as replacement for jansson --- .../jsoncons_ext/csv/csv_serializer.hpp | 445 +++++++++++++++++++++ 1 file changed, 445 insertions(+) create mode 100644 vendor/jsoncons-0.99.2/jsoncons_ext/csv/csv_serializer.hpp (limited to 'vendor/jsoncons-0.99.2/jsoncons_ext/csv/csv_serializer.hpp') diff --git a/vendor/jsoncons-0.99.2/jsoncons_ext/csv/csv_serializer.hpp b/vendor/jsoncons-0.99.2/jsoncons_ext/csv/csv_serializer.hpp new file mode 100644 index 00000000..f331b629 --- /dev/null +++ b/vendor/jsoncons-0.99.2/jsoncons_ext/csv/csv_serializer.hpp @@ -0,0 +1,445 @@ +// Copyright 2013 Daniel Parker +// Distributed under the Boost license, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See https://github.com/danielaparker/jsoncons for latest version + +#ifndef JSONCONS_CSV_CSV_SERIALIZER_HPP +#define JSONCONS_CSV_CSV_SERIALIZER_HPP + +#include +#include +#include +#include +#include +#include +#include "jsoncons/jsoncons.hpp" +#include "jsoncons/output_format.hpp" +#include "jsoncons/json_output_handler.hpp" +#include // std::numeric_limits + +namespace jsoncons { namespace csv { + +template +struct csv_char_traits +{ +}; + +template <> +struct csv_char_traits +{ + static const std::string all_literal() {return "all";}; + + static const std::string minimal_literal() {return "minimal";}; + + static const std::string none_literal() {return "none";}; + + static const std::string nonnumeric_literal() {return "nonumeric";}; +}; + +template <> +struct csv_char_traits +{ + static const std::wstring all_literal() {return L"all";}; + + static const std::wstring minimal_literal() {return L"minimal";}; + + static const std::wstring none_literal() {return L"none";}; + + static const std::wstring nonnumeric_literal() {return L"nonumeric";}; +}; + +template +void escape_string(const CharT* s, + size_t length, + CharT quote_char, CharT quote_escape_char, + buffered_ostream& os) +{ + const CharT* begin = s; + const CharT* end = s + length; + for (const CharT* it = begin; it != end; ++it) + { + CharT c = *it; + if (c == quote_char) + { + os.put(quote_escape_char); + os.put(quote_char); + } + else + { + os.put(c); + } + } +} + +template +class basic_csv_serializer : public basic_json_output_handler +{ + struct stack_item + { + stack_item(bool is_object) + : is_object_(is_object), count_(0), skip_(false) + { + } + bool is_object() const + { + return is_object_; + } + + bool is_object_; + size_t count_; + bool skip_; + }; + buffered_ostream os_; + basic_csv_parameters parameters_; + basic_output_format format_; + std::vector stack_; + std::streamsize original_precision_; + std::ios_base::fmtflags original_format_flags_; + std::basic_ostringstream header_oss_; + buffered_ostream header_os_; + std::map,size_t> header_; + float_printer fp_; +public: + basic_csv_serializer(std::basic_ostream& os) + : + os_(os), + format_(), + stack_(), + original_precision_(), + original_format_flags_(), + header_os_(header_oss_), + header_(), + fp_(format_.precision()) + { + } + + basic_csv_serializer(std::basic_ostream& os, + basic_csv_parameters params) + : + os_(os), + parameters_(params), + format_(), + stack_(), + original_precision_(), + original_format_flags_(), + header_os_(header_oss_), + header_(), + fp_(format_.precision()) + { + } + + ~basic_csv_serializer() + { + } + +private: + + void do_begin_json() override + { + } + + void do_end_json() override + { + } + + void do_begin_object() override + { + stack_.push_back(stack_item(true)); + } + + void do_end_object() override + { + if (stack_.size() == 2) + { + os_.write(parameters_.line_delimiter()); + if (stack_[0].count_ == 0) + { + os_.write(header_oss_.str()); + os_.write(parameters_.line_delimiter()); + } + } + stack_.pop_back(); + + end_value(); + } + + void do_begin_array() override + { + stack_.push_back(stack_item(false)); + } + + void do_end_array() override + { + if (stack_.size() == 2) + { + os_.write(parameters_.line_delimiter()); + } + stack_.pop_back(); + + end_value(); + } + + void do_name(const CharT* name, size_t length) override + { + if (stack_.size() == 2) + { + if (stack_[0].count_ == 0) + { + if (stack_.back().count_ > 0) + { + os_.put(parameters_.field_delimiter()); + } + bool quote = false; + if (parameters_.quote_style() == quote_styles::all || parameters_.quote_style() == quote_styles::nonnumeric || + (parameters_.quote_style() == quote_styles::minimal && std::char_traits::find(name,length,parameters_.field_delimiter()) != nullptr)) + { + quote = true; + os_.put(parameters_.quote_char()); + } + jsoncons::csv::escape_string(name, length, parameters_.quote_char(), parameters_.quote_escape_char(), os_); + if (quote) + { + os_.put(parameters_.quote_char()); + } + header_[name] = stack_.back().count_; + } + else + { + typename std::map,size_t>::iterator it = header_.find(std::basic_string(name,length)); + if (it == header_.end()) + { + stack_.back().skip_ = true; + //std::cout << " Not found "; + } + else + { + stack_.back().skip_ = false; + while (stack_.back().count_ < it->second) + { + os_.put(parameters_.field_delimiter()); + ++stack_.back().count_; + } + // std::cout << " (" << it->value() << " " << stack_.back().count_ << ") "; + } + } + } + } + + void do_null_value() override + { + if (stack_.size() == 2 && !stack_.back().skip_) + { + if (stack_.back().is_object() && stack_[0].count_ == 0) + { + do_null_value(header_os_); + } + else + { + do_null_value(os_); + } + } + } + + void do_string_value(const CharT* val, size_t length) override + { + if (stack_.size() == 2 && !stack_.back().skip_) + { + if (stack_.back().is_object() && stack_[0].count_ == 0) + { + value(val,length,header_os_); + } + else + { + value(val,length,os_); + } + } + } + + void do_double_value(double val, uint8_t precision) override + { + if (stack_.size() == 2 && !stack_.back().skip_) + { + if (stack_.back().is_object() && stack_[0].count_ == 0) + { + value(val,header_os_); + } + else + { + value(val,os_); + } + } + } + + void do_integer_value(int64_t val) override + { + if (stack_.size() == 2 && !stack_.back().skip_) + { + if (stack_.back().is_object() && stack_[0].count_ == 0) + { + value(val,header_os_); + } + else + { + value(val,os_); + } + } + } + + void do_uinteger_value(uint64_t val) override + { + if (stack_.size() == 2 && !stack_.back().skip_) + { + if (stack_.back().is_object() && stack_[0].count_ == 0) + { + value(val,header_os_); + } + else + { + value(val,os_); + } + } + } + + void do_bool_value(bool val) override + { + if (stack_.size() == 2 && !stack_.back().skip_) + { + if (stack_.back().is_object() && stack_[0].count_ == 0) + { + value(val,header_os_); + } + else + { + value(val,os_); + } + } + } + + void value(const CharT* val, size_t length, buffered_ostream& os) + { + begin_value(os); + + bool quote = false; + if (parameters_.quote_style() == quote_styles::all || parameters_.quote_style() == quote_styles::nonnumeric || + (parameters_.quote_style() == quote_styles::minimal && std::char_traits::find(val, length, parameters_.field_delimiter()) != nullptr)) + { + quote = true; + os.put(parameters_.quote_char()); + } + jsoncons::csv::escape_string(val, length, parameters_.quote_char(), parameters_.quote_escape_char(), os); + if (quote) + { + os.put(parameters_.quote_char()); + } + + end_value(); + } + + void value(double val, buffered_ostream& os) + { + begin_value(os); + + if (is_nan(val) && format_.replace_nan()) + { + os.write(format_.nan_replacement()); + } + else if (is_pos_inf(val) && format_.replace_pos_inf()) + { + os.write(format_.pos_inf_replacement()); + } + else if (is_neg_inf(val) && format_.replace_neg_inf()) + { + os.write(format_.neg_inf_replacement()); + } + //else if (format_.floatfield() != 0) + //{ + // std::basic_ostringstream ss; + // ss.imbue(std::locale::classic()); + // ss.setf(format_.floatfield(), std::ios::floatfield); + // ss << std::showpoint << std::setprecision(format_.precision()) << val; + // os.write(ss.str()); + //} + else + { + fp_.print(val,format_.precision(),os); + } + + end_value(); + + } + + void value(int64_t val, buffered_ostream& os) + { + begin_value(os); + + std::basic_ostringstream ss; + ss << val; + os.write(ss.str()); + + end_value(); + } + + void value(uint64_t val, buffered_ostream& os) + { + begin_value(os); + + std::basic_ostringstream ss; + ss << val; + os.write(ss.str()); + + end_value(); + } + + void value(bool val, buffered_ostream& os) + { + begin_value(os); + + if (val) + { + auto buf = json_literals::true_literal(); + os.write(buf.first,buf.second); + } + else + { + auto buf = json_literals::false_literal(); + os.write(buf.first,buf.second); + } + + end_value(); + } + + void do_null_value(buffered_ostream& os) + { + begin_value(os); + auto buf = json_literals::null_literal(); + os.write(buf.first,buf.second); + end_value(); + + } + + void begin_value(buffered_ostream& os) + { + if (!stack_.empty()) + { + if (stack_.back().count_ > 0) + { + os.put(parameters_.field_delimiter()); + } + } + } + + void end_value() + { + if (!stack_.empty()) + { + ++stack_.back().count_; + } + } +}; + +typedef basic_csv_serializer csv_serializer; + +}} + +#endif -- cgit v1.2.3