/* * This file is a part of PikoTools * and is distributed under the 2-Clause BSD licence. * Author: Tomasz Sowa */ /* * Copyright (c) 2012-2022, Tomasz Sowa * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * */ #ifndef headerfile_pikotools_src_space_spaceparser #define headerfile_pikotools_src_space_spaceparser #include #include "space.h" #include "convert/baseparser.h" namespace pt { class SpaceParser : public BaseParser { public: /* ctor -- setting default values (SetDefault() method) */ SpaceParser(); /* status of parsing ok - input stream has been parsed correctly cant_open_file - I cannot open the file (returns only in a case when parsing a file) syntax_error - a syntax error in the input stream limit_object_items_exceeded - limit of object items has been exceeded limit_table_items_exceeded - limit of table items has been exceeded limit_all_items_exceeded - limit of items (key/value pairs of objects or table items) throughout the whole tree has been exceeded limit_nested_level_exceeded - limit of nested objects/tables has been exceeded */ enum Status { ok, cant_open_file, syntax_error, limit_object_items_exceeded, limit_table_items_exceeded, limit_all_items_exceeded, limit_nested_level_exceeded }; /* the last status of parsing, set by parse() methods */ Status status; /* main methods used to parse a JSON file file_name is the path to a file */ Status parse_json_file(const char * file_name, Space & out_space, bool clear_space = true); Status parse_json_file(const std::string & file_name, Space & out_space, bool clear_space = true); Status parse_json_file(const wchar_t * file_name, Space & out_space, bool clear_space = true); Status parse_json_file(const std::wstring & file_name, Space & out_space, bool clear_space = true); /* main methods used to parse a Space file file_name is the path to a file */ Status parse_space_file(const char * file_name, Space & out_space, bool clear_space = true); Status parse_space_file(const std::string & file_name, Space & out_space, bool clear_space = true); Status parse_space_file(const wchar_t * file_name, Space & out_space, bool clear_space = true); Status parse_space_file(const std::wstring & file_name, Space & out_space, bool clear_space = true); /* main methods used to parse str - input string (either 8bit ascii or UTF-8 -- see UTF8() method) */ Status parse_json(const char * str, Space & out_space, bool clear_space = true); Status parse_json(const std::string & str, Space & out_space, bool clear_space = true); /* main methods used to parse here input string is always in unicode (wide characters) */ Status parse_json(const wchar_t * str, Space & out_space, bool clear_space = true); Status parse_json(const std::wstring & str, Space & out_space, bool clear_space = true); Status parse_json(const pt::TextStream & str, Space & out_space, bool clear_space = true); Status parse_json(const pt::WTextStream & str, Space & out_space, bool clear_space = true); Status parse_space(const char * str, Space & out_space, bool clear_space = true); Status parse_space(const std::string & str, Space & out_space, bool clear_space = true); Status parse_space(const wchar_t * str, Space & out_space, bool clear_space = true); Status parse_space(const std::wstring & str, Space & out_space, bool clear_space = true); Status parse_space(const pt::TextStream & str, Space & out_space, bool clear_space = true); Status parse_space(const pt::WTextStream & str, Space & out_space, bool clear_space = true); /* * add two args parse method * Status parse(const char * str, Space & output_space); * */ /* * if true then the input file or string (char* or std::string) is treated as UTF-8 * default true * * the internal storage for strings is std::wstring so if you call set_utf8(false) then * the characters of input string will be simple static_cast<> from char to wchar_t * */ void use_utf8(bool utf); /* * * returns a number of a last parsed line * can be used to obtain the line in which there was a syntax error * */ int get_last_parsed_line(); int get_last_parsed_column(); /* * get/set limit of object items in one object * default: 0 (disabled) */ void set_object_items_limit(size_t val); size_t get_object_items_limit(); /* * get/set limit of items in one table * default: 0 (disabled) * */ void set_table_items_limit(size_t val); size_t get_table_items_limit(); /* * get/set limit of all items (objects items and table items) througout the whole tree * default: 0 (disabled) * */ void set_all_items_limit(size_t val); size_t get_all_items_limit(); /* * get/set nested level limit * limit of nested objects and tables * default: 0 (disabled) * */ void set_nested_level_limit(size_t val); size_t get_nested_level_limit(); private: /* current space set by SetSpace(); */ Space * root_space; /* last read token */ std::wstring token; /* separator between a variable and a value, default: '=' */ int separator; /* space starting character, default: '{' */ int space_start; /* space ending character, default: '}' */ int space_end; /* table starting character, default: '[' */ int table_start; /* table ending character, default: ']' */ int table_end; /* option delimiter, default: ',' */ int option_delimiter; /* true if the lastc was escaped (with a backslash) we have to know if the last sequence was \" or just " */ bool char_was_escaped; /* * if parsing_space is false then it means we are parsing JSON format * */ bool parsing_space; /* * object_items_limit - limit of key/value pairs of one object * table_items_limit - limit of items of one table * all_items_limit - limit of all items of all objects and all tables * nested_levels_limit - limit of nested objects/tables */ size_t object_items_limit; size_t table_items_limit; size_t all_items_limit; size_t nested_levels_limit; /* * current_items_counter - how many items (key/value pairs of objects or table items) throughout the whole tree * current_nested_level - current nested level of objects and tables */ size_t current_items_counter; size_t current_nested_level; void parse_root_space(bool clear_root_space); void parse(Space * space, bool is_object_value, bool is_table_value); void parse_space(Space * space); void parse_table(Space * space); void parse_key_value_pairs(Space * space); void parse_values_list(Space * space); void read_key(); void parse_text_value(Space * space); void parse_integer_value(Space * space); void parse_floating_point_value(Space * space); bool is_alfa_numeric_char(int c); void read_token_until_delimiter(std::wstring & token, int delimiter1, int delimiter2); void read_alfa_numeric_token(std::wstring & token); void read_string_value(std::wstring & token, bool is_object_value, bool is_table_value); bool is_integer_token(); bool is_floating_point_token(); void read_space_field_token(std::wstring & token); void read_token_quoted(std::wstring & token); void read_multiline_token_quoted(std::wstring & token); int read_char(); bool is_white(int c); void skip_line(); void skip_white(); void trim_last_white(std::wstring & s); bool is_hex_digit(wchar_t c); int hex_to_int(wchar_t c); bool read_unicode_four_digit_format(bool has_first_byte, int first_byte); void read_unicode_json_format(bool has_first_byte, int first_byte); void read_unicode_floating_format(); void read_unicode_code_point(); void prepare_to_parsing(); }; } // namespace #endif