Recovered/ holds the code linked only into the standalone exe (scripts/exe/build_exe.py), outside the Clank source dirs: - jsoncons/ and nProtect/ moved from scripts/exe/; GameGuard stand-in follows main's renamed entry points. - GPak/PakAuxiliary.cpp: Extract (virtualised in every build; 02-19 jumps out at 0x0065861E) rebuilt from the open GRF Editor decoder, after the visible 02-19 prologue; inline key and kRO keys 1-4. Apply traps (unreachable in 02-19). - GGHash/GGHash.cpp: CGGHash::Load/Check/VerifyHash trap (RagHash.dat check unreachable in 02-19). The whole client links: 984 units, 0 unresolved.
973 lines
26 KiB
C++
973 lines
26 KiB
C++
// Copyright 2013-2023 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_OPTIONS_HPP
|
|
#define JSONCONS_CSV_CSV_OPTIONS_HPP
|
|
|
|
#include <string>
|
|
#include <vector>
|
|
#include <utility> // std::pair
|
|
#include <unordered_map> // std::unordered_map
|
|
#include <map>
|
|
#include <limits> // std::numeric_limits
|
|
#include <cwchar>
|
|
#include <jsoncons/json_options.hpp>
|
|
|
|
namespace jsoncons { namespace csv {
|
|
|
|
enum class csv_column_type : uint8_t
|
|
{
|
|
string_t,integer_t,float_t,boolean_t,repeat_t
|
|
};
|
|
|
|
enum class quote_style_kind : uint8_t
|
|
{
|
|
minimal,all,nonnumeric,none
|
|
};
|
|
|
|
enum class csv_mapping_kind : uint8_t
|
|
{
|
|
n_rows = 1,
|
|
n_objects,
|
|
m_columns
|
|
};
|
|
|
|
#if !defined(JSONCONS_NO_DEPRECATED)
|
|
using mapping_kind = csv_mapping_kind;
|
|
JSONCONS_DEPRECATED_MSG("Instead, use quote_style_kind") typedef quote_style_kind quote_styles;
|
|
JSONCONS_DEPRECATED_MSG("Instead, use quote_style_kind") typedef quote_style_kind quote_style_type;
|
|
JSONCONS_DEPRECATED_MSG("Instead, use csv_mapping_kind") typedef csv_mapping_kind mapping_type;
|
|
#endif
|
|
|
|
enum class column_state {sequence,label};
|
|
|
|
struct csv_type_info
|
|
{
|
|
csv_type_info() = default;
|
|
csv_type_info(const csv_type_info&) = default;
|
|
csv_type_info(csv_type_info&&) = default;
|
|
|
|
csv_type_info(csv_column_type ctype, std::size_t lev, std::size_t repcount = 0) noexcept
|
|
{
|
|
col_type = ctype;
|
|
level = lev;
|
|
rep_count = repcount;
|
|
}
|
|
|
|
csv_column_type col_type;
|
|
std::size_t level;
|
|
std::size_t rep_count;
|
|
};
|
|
|
|
namespace detail {
|
|
|
|
template <class CharT,class Container>
|
|
void parse_column_names(const std::basic_string<CharT>& names,
|
|
Container& cont)
|
|
{
|
|
column_state state = column_state::sequence;
|
|
typename Container::value_type buffer(cont.get_allocator());
|
|
|
|
auto p = names.begin();
|
|
while (p != names.end())
|
|
{
|
|
switch (state)
|
|
{
|
|
case column_state::sequence:
|
|
{
|
|
switch (*p)
|
|
{
|
|
case ' ': case '\t':case '\r': case '\n':
|
|
++p;
|
|
break;
|
|
default:
|
|
buffer.clear();
|
|
state = column_state::label;
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case column_state::label:
|
|
{
|
|
switch (*p)
|
|
{
|
|
case ',':
|
|
cont.push_back(buffer);
|
|
buffer.clear();
|
|
++p;
|
|
state = column_state::sequence;
|
|
break;
|
|
default:
|
|
buffer.push_back(*p);
|
|
++p;
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (state == column_state::label)
|
|
{
|
|
cont.push_back(buffer);
|
|
buffer.clear();
|
|
}
|
|
}
|
|
|
|
template <class CharT,class Container>
|
|
void parse_column_types(const std::basic_string<CharT>& types,
|
|
Container& column_types)
|
|
{
|
|
const std::map<jsoncons::basic_string_view<CharT>,csv_column_type> type_dictionary =
|
|
{
|
|
|
|
{JSONCONS_STRING_VIEW_CONSTANT(CharT,"string"),csv_column_type::string_t},
|
|
{JSONCONS_STRING_VIEW_CONSTANT(CharT,"integer"),csv_column_type::integer_t},
|
|
{JSONCONS_STRING_VIEW_CONSTANT(CharT,"float"),csv_column_type::float_t},
|
|
{JSONCONS_STRING_VIEW_CONSTANT(CharT,"boolean"),csv_column_type::boolean_t}
|
|
};
|
|
|
|
column_state state = column_state::sequence;
|
|
int depth = 0;
|
|
std::basic_string<CharT> buffer;
|
|
|
|
auto p = types.begin();
|
|
while (p != types.end())
|
|
{
|
|
switch (state)
|
|
{
|
|
case column_state::sequence:
|
|
{
|
|
switch (*p)
|
|
{
|
|
case ' ': case '\t':case '\r': case '\n':
|
|
++p;
|
|
break;
|
|
case '[':
|
|
++depth;
|
|
++p;
|
|
break;
|
|
case ']':
|
|
JSONCONS_ASSERT(depth > 0);
|
|
--depth;
|
|
++p;
|
|
break;
|
|
case '*':
|
|
{
|
|
JSONCONS_ASSERT(column_types.size() != 0);
|
|
std::size_t offset = 0;
|
|
std::size_t level = column_types.size() > 0 ? column_types.back().level: 0;
|
|
if (level > 0)
|
|
{
|
|
for (auto it = column_types.rbegin();
|
|
it != column_types.rend() && level == it->level;
|
|
++it)
|
|
{
|
|
++offset;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
offset = 1;
|
|
}
|
|
column_types.emplace_back(csv_column_type::repeat_t,depth,offset);
|
|
++p;
|
|
break;
|
|
}
|
|
default:
|
|
buffer.clear();
|
|
state = column_state::label;
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case column_state::label:
|
|
{
|
|
switch (*p)
|
|
{
|
|
case '*':
|
|
{
|
|
auto it = type_dictionary.find(buffer);
|
|
if (it != type_dictionary.end())
|
|
{
|
|
column_types.emplace_back(it->second,depth);
|
|
buffer.clear();
|
|
}
|
|
else
|
|
{
|
|
JSONCONS_ASSERT(false);
|
|
}
|
|
state = column_state::sequence;
|
|
break;
|
|
}
|
|
case ',':
|
|
{
|
|
auto it = type_dictionary.find(buffer);
|
|
if (it != type_dictionary.end())
|
|
{
|
|
column_types.emplace_back(it->second,depth);
|
|
buffer.clear();
|
|
}
|
|
else
|
|
{
|
|
JSONCONS_ASSERT(false);
|
|
}
|
|
++p;
|
|
state = column_state::sequence;
|
|
break;
|
|
}
|
|
case ']':
|
|
{
|
|
JSONCONS_ASSERT(depth > 0);
|
|
auto it = type_dictionary.find(buffer);
|
|
if (it != type_dictionary.end())
|
|
{
|
|
column_types.emplace_back(it->second,depth);
|
|
buffer.clear();
|
|
}
|
|
else
|
|
{
|
|
JSONCONS_ASSERT(false);
|
|
}
|
|
--depth;
|
|
++p;
|
|
state = column_state::sequence;
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
buffer.push_back(*p);
|
|
++p;
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (state == column_state::label)
|
|
{
|
|
auto it = type_dictionary.find(buffer);
|
|
if (it != type_dictionary.end())
|
|
{
|
|
column_types.emplace_back(it->second,depth);
|
|
buffer.clear();
|
|
}
|
|
else
|
|
{
|
|
JSONCONS_ASSERT(false);
|
|
}
|
|
}
|
|
}
|
|
|
|
} // detail
|
|
|
|
template <class CharT>
|
|
class basic_csv_options;
|
|
|
|
template <class CharT>
|
|
class basic_csv_options_common
|
|
{
|
|
friend class basic_csv_options<CharT>;
|
|
public:
|
|
using char_type = CharT;
|
|
using string_type = std::basic_string<CharT>;
|
|
private:
|
|
char_type field_delimiter_;
|
|
char_type quote_char_;
|
|
char_type quote_escape_char_;
|
|
char_type subfield_delimiter_;
|
|
|
|
bool enable_nan_to_num_:1;
|
|
bool enable_inf_to_num_:1;
|
|
bool enable_neginf_to_num_:1;
|
|
bool enable_nan_to_str_:1;
|
|
bool enable_inf_to_str_:1;
|
|
bool enable_neginf_to_str_:1;
|
|
bool enable_str_to_nan_:1;
|
|
bool enable_str_to_inf_:1;
|
|
bool enable_str_to_neginf_:1;
|
|
|
|
string_type nan_to_num_;
|
|
string_type inf_to_num_;
|
|
string_type neginf_to_num_;
|
|
string_type nan_to_str_;
|
|
string_type inf_to_str_;
|
|
string_type neginf_to_str_;
|
|
string_type column_names_;
|
|
|
|
protected:
|
|
basic_csv_options_common()
|
|
: field_delimiter_(','),
|
|
quote_char_('\"'),
|
|
quote_escape_char_('\"'),
|
|
subfield_delimiter_(char_type()),
|
|
enable_nan_to_num_(false),
|
|
enable_inf_to_num_(false),
|
|
enable_neginf_to_num_(false),
|
|
enable_nan_to_str_(false),
|
|
enable_inf_to_str_(false),
|
|
enable_neginf_to_str_(false),
|
|
enable_str_to_nan_(false),
|
|
enable_str_to_inf_(false),
|
|
enable_str_to_neginf_(false)
|
|
{
|
|
}
|
|
|
|
basic_csv_options_common(const basic_csv_options_common&) = default;
|
|
basic_csv_options_common& operator=(const basic_csv_options_common&) = default;
|
|
|
|
virtual ~basic_csv_options_common() noexcept = default;
|
|
public:
|
|
|
|
char_type field_delimiter() const
|
|
{
|
|
return field_delimiter_;
|
|
}
|
|
|
|
const char_type subfield_delimiter() const
|
|
{
|
|
return subfield_delimiter_;
|
|
}
|
|
|
|
char_type quote_char() const
|
|
{
|
|
return quote_char_;
|
|
}
|
|
|
|
char_type quote_escape_char() const
|
|
{
|
|
return quote_escape_char_;
|
|
}
|
|
|
|
string_type column_names() const
|
|
{
|
|
return column_names_;
|
|
}
|
|
|
|
bool enable_nan_to_num() const
|
|
{
|
|
return enable_nan_to_num_;
|
|
}
|
|
|
|
bool enable_inf_to_num() const
|
|
{
|
|
return enable_inf_to_num_;
|
|
}
|
|
|
|
bool enable_neginf_to_num() const
|
|
{
|
|
return enable_neginf_to_num_ || enable_inf_to_num_;
|
|
}
|
|
|
|
bool enable_nan_to_str() const
|
|
{
|
|
return enable_nan_to_str_;
|
|
}
|
|
|
|
bool enable_str_to_nan() const
|
|
{
|
|
return enable_str_to_nan_;
|
|
}
|
|
|
|
bool enable_inf_to_str() const
|
|
{
|
|
return enable_inf_to_str_;
|
|
}
|
|
|
|
bool enable_str_to_inf() const
|
|
{
|
|
return enable_str_to_inf_;
|
|
}
|
|
|
|
bool enable_neginf_to_str() const
|
|
{
|
|
return enable_neginf_to_str_ || enable_inf_to_str_;
|
|
}
|
|
|
|
bool enable_str_to_neginf() const
|
|
{
|
|
return enable_str_to_neginf_ || enable_str_to_inf_;
|
|
}
|
|
|
|
string_type nan_to_num() const
|
|
{
|
|
return nan_to_num_;
|
|
}
|
|
|
|
string_type inf_to_num() const
|
|
{
|
|
return inf_to_num_;
|
|
}
|
|
|
|
string_type neginf_to_num() const
|
|
{
|
|
if (enable_neginf_to_num_)
|
|
{
|
|
return neginf_to_num_;
|
|
}
|
|
else if (enable_inf_to_num_)
|
|
{
|
|
string_type s;
|
|
s.push_back('-');
|
|
s.append(inf_to_num_);
|
|
return s;
|
|
}
|
|
else
|
|
{
|
|
return neginf_to_num_;
|
|
}
|
|
}
|
|
|
|
string_type nan_to_str() const
|
|
{
|
|
return nan_to_str_;
|
|
}
|
|
|
|
string_type inf_to_str() const
|
|
{
|
|
return inf_to_str_;
|
|
}
|
|
|
|
string_type neginf_to_str() const
|
|
{
|
|
if (enable_neginf_to_str_)
|
|
{
|
|
return neginf_to_str_;
|
|
}
|
|
else if (enable_inf_to_str_)
|
|
{
|
|
string_type s;
|
|
s.push_back('-');
|
|
s.append(inf_to_str_);
|
|
return s;
|
|
}
|
|
else
|
|
{
|
|
return neginf_to_str_; // empty string
|
|
}
|
|
}
|
|
};
|
|
|
|
template <class CharT>
|
|
class basic_csv_decode_options : public virtual basic_csv_options_common<CharT>
|
|
{
|
|
friend class basic_csv_options<CharT>;
|
|
using super_type = basic_csv_options_common<CharT>;
|
|
public:
|
|
using typename super_type::char_type;
|
|
using typename super_type::string_type;
|
|
|
|
private:
|
|
bool assume_header_:1;
|
|
bool ignore_empty_values_:1;
|
|
bool ignore_empty_lines_:1;
|
|
bool trim_leading_:1;
|
|
bool trim_trailing_:1;
|
|
bool trim_leading_inside_quotes_:1;
|
|
bool trim_trailing_inside_quotes_:1;
|
|
bool unquoted_empty_value_is_null_:1;
|
|
bool infer_types_:1;
|
|
bool lossless_number_:1;
|
|
char_type comment_starter_;
|
|
csv_mapping_kind mapping_;
|
|
std::size_t header_lines_;
|
|
std::size_t max_lines_;
|
|
string_type column_types_;
|
|
string_type column_defaults_;
|
|
public:
|
|
basic_csv_decode_options()
|
|
: assume_header_(false),
|
|
ignore_empty_values_(false),
|
|
ignore_empty_lines_(true),
|
|
trim_leading_(false),
|
|
trim_trailing_(false),
|
|
trim_leading_inside_quotes_(false),
|
|
trim_trailing_inside_quotes_(false),
|
|
unquoted_empty_value_is_null_(false),
|
|
infer_types_(true),
|
|
lossless_number_(false),
|
|
comment_starter_('\0'),
|
|
mapping_(),
|
|
header_lines_(0),
|
|
max_lines_((std::numeric_limits<std::size_t>::max)())
|
|
{}
|
|
|
|
basic_csv_decode_options(const basic_csv_decode_options& other) = default;
|
|
|
|
basic_csv_decode_options(basic_csv_decode_options&& other)
|
|
: super_type(std::forward<basic_csv_decode_options>(other)),
|
|
assume_header_(other.assume_header_),
|
|
ignore_empty_values_(other.ignore_empty_values_),
|
|
ignore_empty_lines_(other.ignore_empty_lines_),
|
|
trim_leading_(other.trim_leading_),
|
|
trim_trailing_(other.trim_trailing_),
|
|
trim_leading_inside_quotes_(other.trim_leading_inside_quotes_),
|
|
trim_trailing_inside_quotes_(other.trim_trailing_inside_quotes_),
|
|
unquoted_empty_value_is_null_(other.unquoted_empty_value_is_null_),
|
|
infer_types_(other.infer_types_),
|
|
lossless_number_(other.lossless_number_),
|
|
comment_starter_(other.comment_starter_),
|
|
mapping_(other.mapping_),
|
|
header_lines_(other.header_lines_),
|
|
max_lines_(other.max_lines_),
|
|
column_types_(std::move(other.column_types_)),
|
|
column_defaults_(std::move(other.column_defaults_))
|
|
{}
|
|
|
|
std::size_t header_lines() const
|
|
{
|
|
return (assume_header_ && header_lines_ <= 1) ? 1 : header_lines_;
|
|
}
|
|
|
|
bool assume_header() const
|
|
{
|
|
return assume_header_;
|
|
}
|
|
|
|
bool ignore_empty_values() const
|
|
{
|
|
return ignore_empty_values_;
|
|
}
|
|
|
|
bool ignore_empty_lines() const
|
|
{
|
|
return ignore_empty_lines_;
|
|
}
|
|
|
|
bool trim_leading() const
|
|
{
|
|
return trim_leading_;
|
|
}
|
|
|
|
bool trim_trailing() const
|
|
{
|
|
return trim_trailing_;
|
|
}
|
|
|
|
bool trim_leading_inside_quotes() const
|
|
{
|
|
return trim_leading_inside_quotes_;
|
|
}
|
|
|
|
bool trim_trailing_inside_quotes() const
|
|
{
|
|
return trim_trailing_inside_quotes_;
|
|
}
|
|
|
|
bool trim() const
|
|
{
|
|
return trim_leading_ && trim_trailing_;
|
|
}
|
|
|
|
bool trim_inside_quotes() const
|
|
{
|
|
return trim_leading_inside_quotes_ && trim_trailing_inside_quotes_;
|
|
}
|
|
|
|
bool unquoted_empty_value_is_null() const
|
|
{
|
|
return unquoted_empty_value_is_null_;
|
|
}
|
|
|
|
bool infer_types() const
|
|
{
|
|
return infer_types_;
|
|
}
|
|
|
|
bool lossless_number() const
|
|
{
|
|
return lossless_number_;
|
|
}
|
|
|
|
char_type comment_starter() const
|
|
{
|
|
return comment_starter_;
|
|
}
|
|
|
|
csv_mapping_kind mapping_kind() const
|
|
{
|
|
return mapping_ != csv_mapping_kind() ? mapping_ : (assume_header() || this->column_names().size() > 0 ? csv_mapping_kind::n_objects : csv_mapping_kind::n_rows);
|
|
}
|
|
|
|
#if !defined(JSONCONS_NO_DEPRECATED)
|
|
csv_mapping_kind mapping() const
|
|
{
|
|
return mapping_kind();
|
|
}
|
|
#endif
|
|
|
|
std::size_t max_lines() const
|
|
{
|
|
return max_lines_;
|
|
}
|
|
|
|
string_type column_types() const
|
|
{
|
|
return column_types_;
|
|
}
|
|
|
|
string_type column_defaults() const
|
|
{
|
|
return column_defaults_;
|
|
}
|
|
};
|
|
|
|
template <class CharT>
|
|
class basic_csv_encode_options : public virtual basic_csv_options_common<CharT>
|
|
{
|
|
friend class basic_csv_options<CharT>;
|
|
using super_type = basic_csv_options_common<CharT>;
|
|
public:
|
|
using typename super_type::char_type;
|
|
using typename super_type::string_type;
|
|
private:
|
|
quote_style_kind quote_style_;
|
|
float_chars_format float_format_;
|
|
int8_t precision_;
|
|
string_type line_delimiter_;
|
|
public:
|
|
basic_csv_encode_options()
|
|
: quote_style_(quote_style_kind::minimal),
|
|
float_format_(float_chars_format::general),
|
|
precision_(0)
|
|
{
|
|
line_delimiter_.push_back('\n');
|
|
}
|
|
|
|
basic_csv_encode_options(const basic_csv_encode_options& other) = default;
|
|
|
|
basic_csv_encode_options(basic_csv_encode_options&& other)
|
|
: super_type(std::forward<basic_csv_encode_options>(other)),
|
|
quote_style_(other.quote_style_),
|
|
float_format_(other.float_format_),
|
|
precision_(other.precision_),
|
|
line_delimiter_(std::move(other.line_delimiter_))
|
|
{
|
|
}
|
|
|
|
quote_style_kind quote_style() const
|
|
{
|
|
return quote_style_;
|
|
}
|
|
|
|
float_chars_format float_format() const
|
|
{
|
|
return float_format_;
|
|
}
|
|
|
|
int8_t precision() const
|
|
{
|
|
return precision_;
|
|
}
|
|
|
|
string_type line_delimiter() const
|
|
{
|
|
return line_delimiter_;
|
|
}
|
|
};
|
|
|
|
template <class CharT>
|
|
class basic_csv_options final : public basic_csv_decode_options<CharT>, public basic_csv_encode_options<CharT>
|
|
{
|
|
using char_type = CharT;
|
|
using string_type = std::basic_string<CharT>;
|
|
|
|
public:
|
|
using basic_csv_decode_options<CharT>::enable_str_to_nan;
|
|
using basic_csv_decode_options<CharT>::enable_str_to_inf;
|
|
using basic_csv_decode_options<CharT>::enable_str_to_neginf;
|
|
using basic_csv_decode_options<CharT>::nan_to_str;
|
|
using basic_csv_decode_options<CharT>::inf_to_str;
|
|
using basic_csv_decode_options<CharT>::neginf_to_str;
|
|
using basic_csv_decode_options<CharT>::nan_to_num;
|
|
using basic_csv_decode_options<CharT>::inf_to_num;
|
|
using basic_csv_decode_options<CharT>::neginf_to_num;
|
|
using basic_csv_decode_options<CharT>::field_delimiter;
|
|
using basic_csv_decode_options<CharT>::subfield_delimiter;
|
|
using basic_csv_decode_options<CharT>::quote_char;
|
|
using basic_csv_decode_options<CharT>::quote_escape_char;
|
|
using basic_csv_decode_options<CharT>::column_names;
|
|
using basic_csv_decode_options<CharT>::header_lines;
|
|
using basic_csv_decode_options<CharT>::assume_header;
|
|
using basic_csv_decode_options<CharT>::ignore_empty_values;
|
|
using basic_csv_decode_options<CharT>::ignore_empty_lines;
|
|
using basic_csv_decode_options<CharT>::trim_leading;
|
|
using basic_csv_decode_options<CharT>::trim_trailing;
|
|
using basic_csv_decode_options<CharT>::trim_leading_inside_quotes;
|
|
using basic_csv_decode_options<CharT>::trim_trailing_inside_quotes;
|
|
using basic_csv_decode_options<CharT>::trim;
|
|
using basic_csv_decode_options<CharT>::trim_inside_quotes;
|
|
using basic_csv_decode_options<CharT>::unquoted_empty_value_is_null;
|
|
using basic_csv_decode_options<CharT>::infer_types;
|
|
using basic_csv_decode_options<CharT>::lossless_number;
|
|
using basic_csv_decode_options<CharT>::comment_starter;
|
|
using basic_csv_decode_options<CharT>::mapping;
|
|
using basic_csv_decode_options<CharT>::max_lines;
|
|
using basic_csv_decode_options<CharT>::column_types;
|
|
using basic_csv_decode_options<CharT>::column_defaults;
|
|
using basic_csv_encode_options<CharT>::float_format;
|
|
using basic_csv_encode_options<CharT>::precision;
|
|
using basic_csv_encode_options<CharT>::line_delimiter;
|
|
using basic_csv_encode_options<CharT>::quote_style;
|
|
|
|
static constexpr size_t default_indent = 4;
|
|
|
|
// Constructors
|
|
|
|
basic_csv_options() = default;
|
|
basic_csv_options(const basic_csv_options&) = default;
|
|
basic_csv_options(basic_csv_options&&) = default;
|
|
basic_csv_options& operator=(const basic_csv_options&) = default;
|
|
basic_csv_options& operator=(basic_csv_options&&) = default;
|
|
|
|
basic_csv_options& float_format(float_chars_format value)
|
|
{
|
|
this->float_format_ = value;
|
|
return *this;
|
|
}
|
|
|
|
basic_csv_options& precision(int8_t value)
|
|
{
|
|
this->precision_ = value;
|
|
return *this;
|
|
}
|
|
|
|
basic_csv_options& header_lines(std::size_t value)
|
|
{
|
|
this->header_lines_ = value;
|
|
return *this;
|
|
}
|
|
|
|
basic_csv_options& assume_header(bool value)
|
|
{
|
|
this->assume_header_ = value;
|
|
return *this;
|
|
}
|
|
|
|
basic_csv_options& ignore_empty_values(bool value)
|
|
{
|
|
this->ignore_empty_values_ = value;
|
|
return *this;
|
|
}
|
|
|
|
basic_csv_options& ignore_empty_lines(bool value)
|
|
{
|
|
this->ignore_empty_lines_ = value;
|
|
return *this;
|
|
}
|
|
|
|
basic_csv_options& trim_leading(bool value)
|
|
{
|
|
this->trim_leading_ = value;
|
|
return *this;
|
|
}
|
|
|
|
basic_csv_options& trim_trailing(bool value)
|
|
{
|
|
this->trim_trailing_ = value;
|
|
return *this;
|
|
}
|
|
|
|
basic_csv_options& trim_leading_inside_quotes(bool value)
|
|
{
|
|
this->trim_leading_inside_quotes_ = value;
|
|
return *this;
|
|
}
|
|
|
|
basic_csv_options& trim_trailing_inside_quotes(bool value)
|
|
{
|
|
this->trim_trailing_inside_quotes_ = value;
|
|
return *this;
|
|
}
|
|
|
|
basic_csv_options& trim(bool value)
|
|
{
|
|
this->trim_leading_ = value;
|
|
this->trim_trailing_ = value;
|
|
return *this;
|
|
}
|
|
|
|
basic_csv_options& trim_inside_quotes(bool value)
|
|
{
|
|
this->trim_leading_inside_quotes_ = value;
|
|
this->trim_trailing_inside_quotes_ = value;
|
|
return *this;
|
|
}
|
|
|
|
basic_csv_options& unquoted_empty_value_is_null(bool value)
|
|
{
|
|
this->unquoted_empty_value_is_null_ = value;
|
|
return *this;
|
|
}
|
|
|
|
basic_csv_options& column_names(const string_type& value)
|
|
{
|
|
this->column_names_ = value;
|
|
return *this;
|
|
}
|
|
|
|
basic_csv_options& column_types(const string_type& value)
|
|
{
|
|
this->column_types_ = value;
|
|
return *this;
|
|
}
|
|
|
|
basic_csv_options& column_defaults(const string_type& value)
|
|
{
|
|
this->column_defaults_ = value;
|
|
return *this;
|
|
}
|
|
|
|
basic_csv_options& field_delimiter(char_type value)
|
|
{
|
|
this->field_delimiter_ = value;
|
|
return *this;
|
|
}
|
|
|
|
basic_csv_options& subfield_delimiter(char_type value)
|
|
{
|
|
this->subfield_delimiter_ = value;
|
|
return *this;
|
|
}
|
|
|
|
basic_csv_options& line_delimiter(const string_type& value)
|
|
{
|
|
this->line_delimiter_ = value;
|
|
return *this;
|
|
}
|
|
|
|
basic_csv_options& quote_char(char_type value)
|
|
{
|
|
this->quote_char_ = value;
|
|
return *this;
|
|
}
|
|
|
|
basic_csv_options& infer_types(bool value)
|
|
{
|
|
this->infer_types_ = value;
|
|
return *this;
|
|
}
|
|
|
|
basic_csv_options& lossless_number(bool value)
|
|
{
|
|
this->lossless_number_ = value;
|
|
return *this;
|
|
}
|
|
|
|
basic_csv_options& quote_escape_char(char_type value)
|
|
{
|
|
this->quote_escape_char_ = value;
|
|
return *this;
|
|
}
|
|
|
|
basic_csv_options& comment_starter(char_type value)
|
|
{
|
|
this->comment_starter_ = value;
|
|
return *this;
|
|
}
|
|
|
|
basic_csv_options& quote_style(quote_style_kind value)
|
|
{
|
|
this->quote_style_ = value;
|
|
return *this;
|
|
}
|
|
|
|
//#if !defined(JSONCONS_NO_DEPRECATED)
|
|
basic_csv_options& mapping(csv_mapping_kind value)
|
|
{
|
|
this->mapping_ = value;
|
|
return *this;
|
|
}
|
|
//#endif
|
|
|
|
basic_csv_options& mapping_kind(csv_mapping_kind value)
|
|
{
|
|
this->mapping_ = value;
|
|
return *this;
|
|
}
|
|
|
|
basic_csv_options& max_lines(std::size_t value)
|
|
{
|
|
this->max_lines_ = value;
|
|
return *this;
|
|
}
|
|
|
|
basic_csv_options& nan_to_num(const string_type& value)
|
|
{
|
|
this->enable_nan_to_num_ = true;
|
|
this->nan_to_str_.clear();
|
|
this->nan_to_num_ = value;
|
|
return *this;
|
|
}
|
|
|
|
basic_csv_options& inf_to_num(const string_type& value)
|
|
{
|
|
this->enable_inf_to_num_ = true;
|
|
this->inf_to_str_.clear();
|
|
this->inf_to_num_ = value;
|
|
return *this;
|
|
}
|
|
|
|
basic_csv_options& neginf_to_num(const string_type& value)
|
|
{
|
|
this->enable_neginf_to_num_ = true;
|
|
this->neginf_to_str_.clear();
|
|
this->neginf_to_num_ = value;
|
|
return *this;
|
|
}
|
|
|
|
basic_csv_options& nan_to_str(const string_type& value, bool enable_inverse = true)
|
|
{
|
|
this->enable_nan_to_str_ = true;
|
|
this->enable_str_to_nan_ = enable_inverse;
|
|
this->nan_to_num_.clear();
|
|
this->nan_to_str_ = value;
|
|
return *this;
|
|
}
|
|
|
|
basic_csv_options& inf_to_str(const string_type& value, bool enable_inverse = true)
|
|
{
|
|
this->enable_inf_to_str_ = true;
|
|
this->enable_inf_to_str_ = enable_inverse;
|
|
this->inf_to_num_.clear();
|
|
this->inf_to_str_ = value;
|
|
return *this;
|
|
}
|
|
|
|
basic_csv_options& neginf_to_str(const string_type& value, bool enable_inverse = true)
|
|
{
|
|
this->enable_neginf_to_str_ = true;
|
|
this->enable_neginf_to_str_ = enable_inverse;
|
|
this->neginf_to_num_.clear();
|
|
this->neginf_to_str_ = value;
|
|
return *this;
|
|
}
|
|
|
|
#if !defined(JSONCONS_NO_DEPRECATED)
|
|
|
|
JSONCONS_DEPRECATED_MSG("Instead, use float_format(float_chars_format)")
|
|
basic_csv_options& floating_point_format(float_chars_format value)
|
|
{
|
|
this->float_format_ = value;
|
|
return *this;
|
|
}
|
|
#endif
|
|
|
|
};
|
|
|
|
using csv_options = basic_csv_options<char>;
|
|
using wcsv_options = basic_csv_options<wchar_t>;
|
|
|
|
#if !defined(JSONCONS_NO_DEPRECATED)
|
|
JSONCONS_DEPRECATED_MSG("Instead, use csv_options") typedef csv_options csv_parameters;
|
|
JSONCONS_DEPRECATED_MSG("Instead, use wcsv_options") typedef wcsv_options wcsv_parameters;
|
|
JSONCONS_DEPRECATED_MSG("Instead, use csv_options") typedef csv_options csv_serializing_options;
|
|
JSONCONS_DEPRECATED_MSG("Instead, use wcsv_options") typedef wcsv_options wcsv_serializing_options;
|
|
#endif
|
|
|
|
|
|
}}
|
|
#endif
|