/* * This file is a part of PikoTools * and is distributed under the (new) BSD licence. * Author: Tomasz Sowa */ /* * Copyright (c) 2008-2021, 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: * * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * * 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. * * * Neither the name Tomasz Sowa nor the names of contributors to this * project may be used to endorse or promote products derived * from this software without specific prior written permission. * * 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 OWNER 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. */ #include #include "space.h" #include "utf8/utf8.h" #include "convert/convert.h" namespace pt { Space::Space() { initialize(); } Space::Space(const Space & space) { initialize(); copy_from(space); } Space::Space(Space && space) { initialize(); move_from(std::move(space)); } Space & Space::operator=(const Space & space) { copy_from(space); return *this; } Space & Space::operator=(Space && space) { move_from(std::move(space)); return *this; } Space::~Space() { remove_value(); } Space::Space(bool val) { initialize(); set(val); } Space::Space(short val) { initialize(); set(val); } Space::Space(int val) { initialize(); set(val); } Space::Space(long val) { initialize(); set(val); } Space::Space(long long val) { initialize(); set(val); } Space::Space(unsigned short val) { initialize(); set(val); } Space::Space(unsigned int val) { initialize(); set(val); } Space::Space(unsigned long val) { initialize(); set(val); } Space::Space(unsigned long long val) { initialize(); set(val); } Space::Space(float val) { initialize(); set(val); } Space::Space(double val) { initialize(); set(val); } Space::Space(long double val) { initialize(); set(val); } Space::Space(const char * str) { initialize(); set(str); } Space::Space(const wchar_t * str) { initialize(); set(str); } Space::Space(const std::string & str) { initialize(); set(str); } Space::Space(const std::wstring & str) { initialize(); set(str); } Space::Space(const Space * space) { initialize(); set(space); } void Space::clear() { set_null(); } size_t Space::str_size() const { if( is_str() ) { return value.value_string.size(); } return 0; } size_t Space::wstr_size() const { if( is_wstr() ) { return value.value_wstring.size(); } return 0; } size_t Space::object_size() const { if( is_object() ) { return value.value_object.size(); } return 0; } size_t Space::table_size() const { if( is_table() ) { return value.value_table.size(); } return 0; } void Space::set_null() { initialize_value_null_if_needed(); } void Space::set_empty_string() { if( type == type_string ) { value.value_string.clear(); } else { initialize_value_string_if_needed(); } } void Space::set_empty_wstring() { if( type == type_wstring ) { value.value_wstring.clear(); } else { initialize_value_wstring_if_needed(); } } void Space::set_empty_table() { if( type == type_table ) { remove_value_table(true); } else { initialize_value_table_if_needed(); } } void Space::set_empty_object() { if( type == type_object ) { remove_value_object(true); } else { initialize_value_object_if_needed(); } } void Space::set(bool val) { initialize_value_bool_if_needed(); value.value_bool = val; } void Space::set(short val) { set(static_cast(val)); } void Space::set(int val) { set(static_cast(val)); } void Space::set(long val) { set(static_cast(val)); } void Space::set(long long val) { initialize_value_long_if_needed(); value.value_long = val; } void Space::set(unsigned short val) { set(static_cast(val)); } void Space::set(unsigned int val) { set(static_cast(val)); } void Space::set(unsigned long val) { set(static_cast(val)); } void Space::set(unsigned long long val) { set(static_cast(val)); } void Space::set(float val) { initialize_value_float_if_needed(); value.value_float = val; } void Space::set(double val) { initialize_value_double_if_needed(); value.value_double = val; } void Space::set(long double val) { initialize_value_long_double_if_needed(); value.value_long_double = val; } void Space::set(const char * str) { if( str == nullptr ) { initialize_value_null_if_needed(); } else { initialize_value_string_if_needed(); value.value_string = str; } } void Space::set(const wchar_t * str) { if( str == nullptr ) { initialize_value_null_if_needed(); } else { initialize_value_wstring_if_needed(); value.value_wstring = str; } } void Space::set(const std::string & str) { initialize_value_string_if_needed(); value.value_string = str; } void Space::set(const std::wstring & str) { initialize_value_wstring_if_needed(); value.value_wstring = str; } void Space::set(const Space & space) { copy_from(space); } void Space::set(const Space * space) { if( space == nullptr ) { initialize_value_null_if_needed(); } else { copy_from(*space); } } void Space::set(Space && space) { move_from(std::move(space)); } Space & Space::add(bool val) { return add_generic(val); } Space & Space::add(short val) { return add_generic(val); } Space & Space::add(int val) { return add_generic(val); } Space & Space::add(long val) { return add_generic(val); } Space & Space::add(long long val) { return add_generic(val); } Space & Space::add(unsigned short val) { return add_generic(val); } Space & Space::add(unsigned int val) { return add_generic(val); } Space & Space::add(unsigned long val) { return add_generic(val); } Space & Space::add(unsigned long long val) { return add_generic(val); } Space & Space::add(float val) { return add_generic(val); } Space & Space::add(double val) { return add_generic(val); } Space & Space::add(long double val) { return add_generic(val); } Space & Space::add(const char * val) { return add_generic(val); } Space & Space::add(const wchar_t * val) { return add_generic(val); } Space & Space::add(const std::string & val) { return add_generic(val); } Space & Space::add(const std::wstring & val) { return add_generic(val); } Space & Space::add(const Space & space) { return add_generic(space); } Space & Space::add(const Space * space) { return add_generic(space); } Space & Space::add(Space && space) { initialize_value_table_if_needed(); Space * new_space = new Space(std::move(space)); value.value_table.push_back(new_space); return *value.value_table.back(); } Space & Space::add_empty_space() { return add_generic(static_cast(nullptr)); } Space & Space::add(const wchar_t * field, bool val) { return add_generic(field, val); } Space & Space::add(const wchar_t * field, short val) { return add_generic(field, val); } Space & Space::add(const wchar_t * field, int val) { return add_generic(field, val); } Space & Space::add(const wchar_t * field, long val) { return add_generic(field, val); } Space & Space::add(const wchar_t * field, long long val) { return add_generic(field, val); } Space & Space::add(const wchar_t * field, unsigned short val) { return add_generic(field, val); } Space & Space::add(const wchar_t * field, unsigned int val) { return add_generic(field, val); } Space & Space::add(const wchar_t * field, unsigned long val) { return add_generic(field, val); } Space & Space::add(const wchar_t * field, unsigned long long val) { return add_generic(field, val); } Space & Space::add(const wchar_t * field, float val) { return add_generic(field, val); } Space & Space::add(const wchar_t * field, double val) { return add_generic(field, val); } Space & Space::add(const wchar_t * field, long double val) { return add_generic(field, val); } Space & Space::add(const wchar_t * field, const char * val) { return add_generic(field, val); } Space & Space::add(const wchar_t * field, const wchar_t * val) { return add_generic(field, val); } Space & Space::add(const wchar_t * field, const std::string & val) { return add_generic(field, val); } Space & Space::add(const wchar_t * field, const std::wstring & val) { return add_generic(field, val); } Space & Space::add(const wchar_t * field, const Space & space) { return add_generic(field, space); } Space & Space::add(const wchar_t * field, const Space * space) { return add_generic(field, space); } Space & Space::add(const wchar_t * field, Space && space) { initialize_value_object_if_needed(); auto insert_res = value.value_object.insert(std::make_pair(field, nullptr)); if( insert_res.second ) { insert_res.first->second = new Space(std::move(space)); } else { insert_res.first->second->set(std::move(space)); } return *(insert_res.first->second); } Space & Space::add_empty_space(const wchar_t * field) { return add_generic(field, static_cast(nullptr)); } Space & Space::add(const std::wstring & field, bool val) { return add_generic(field, val); } Space & Space::add(const std::wstring & field, short val) { return add_generic(field, val); } Space & Space::add(const std::wstring & field, int val) { return add_generic(field, val); } Space & Space::add(const std::wstring & field, long val) { return add_generic(field, val); } Space & Space::add(const std::wstring & field, long long val) { return add_generic(field, val); } Space & Space::add(const std::wstring & field, unsigned short val) { return add_generic(field, val); } Space & Space::add(const std::wstring & field, unsigned int val) { return add_generic(field, val); } Space & Space::add(const std::wstring & field, unsigned long val) { return add_generic(field, val); } Space & Space::add(const std::wstring & field, unsigned long long val) { return add_generic(field, val); } Space & Space::add(const std::wstring & field, float val) { return add_generic(field, val); } Space & Space::add(const std::wstring & field, double val) { return add_generic(field, val); } Space & Space::add(const std::wstring & field, long double val) { return add_generic(field, val); } Space & Space::add(const std::wstring & field, const char * val) { return add_generic(field, val); } Space & Space::add(const std::wstring & field, const wchar_t * val) { return add_generic(field, val); } Space & Space::add(const std::wstring & field, const std::string & val) { return add_generic(field, val); } Space & Space::add(const std::wstring & field, const std::wstring & val) { return add_generic(field, val); } Space & Space::add(const std::wstring & field, const Space & space) { return add_generic(field, space); } Space & Space::add(const std::wstring & field, const Space * space) { return add_generic(field, space); } Space & Space::add(const std::wstring & field, Space && space) { return add(field.c_str(), std::move(space)); } Space & Space::add_empty_space(const std::wstring & field) { return add_generic(field, static_cast(nullptr)); } bool Space::is_null() const { return type == type_null; } bool Space::is_bool() const { return type == type_bool; } bool Space::is_llong() const { return is_long_long(); } bool Space::is_long_long() const { return type == type_long; } bool Space::is_float() const { return type == type_float; } bool Space::is_double() const { return type == type_double; } bool Space::is_long_double() const { return type == type_long_double; } bool Space::is_numeric() const { return is_long_long() || is_float() || is_double() || is_long_double(); } bool Space::is_str() const { return type == type_string; } bool Space::is_wstr() const { return type == type_wstring; } bool Space::is_text() const { return is_str() || is_wstr(); } bool Space::is_object() const { return type == type_object; } bool Space::is_table() const { return type == type_table; } bool Space::to_bool() const { if( type == type_bool ) return value.value_bool; if( type == type_long ) return value.value_long != 0; if( type == type_float ) return value.value_float != 0.0f; if( type == type_double ) return value.value_double != 0.0; if( type == type_long_double ) return value.value_long_double != 0.0L; if( type == type_string ) return !value.value_string.empty(); if( type == type_wstring ) return !value.value_wstring.empty(); if( type == type_table ) return !value.value_table.empty(); if( type == type_object ) return !value.value_object.empty(); return false; } short Space::to_short() const { return to_generic_numeric_signed_value(); } int Space::to_int() const { return to_generic_numeric_signed_value(); } long Space::to_long() const { return to_generic_numeric_signed_value(); } long long Space::to_llong() const { return to_long_long(); } long long Space::to_long_long() const { switch(type) { case type_null: case type_object: case type_table: return 0; case type_bool: return value.value_bool ? 1 : 0; case type_long: return value.value_long; case type_float: return static_cast(value.value_float); case type_double: return static_cast(value.value_double); case type_long_double: return static_cast(value.value_long_double); case type_string: return convert_string_to_long_long(); case type_wstring: return convert_wstring_to_long_long(); } return 0; } unsigned long long Space::to_ullong() const { return to_ulong_long(); } long long Space::convert_string_to_long_long() const { bool was_overflow = false; const char * after_str; long long val = Toll(value.value_string.c_str(), 10, &after_str, &was_overflow, true); return was_overflow ? 0 : val; } long long Space::convert_wstring_to_long_long() const { bool was_overflow = false; const wchar_t * after_str; long long val = Toll(value.value_wstring.c_str(), 10, &after_str, &was_overflow, true); return was_overflow ? 0 : val; } unsigned long long Space::convert_string_to_ulong_long() const { bool was_overflow = false; const char * after_str; unsigned long long val = Toull(value.value_string.c_str(), 10, &after_str, &was_overflow, true); return was_overflow ? 0 : val; } unsigned long long Space::convert_wstring_to_ulong_long() const { bool was_overflow = false; const wchar_t * after_str; unsigned long long val = Toull(value.value_wstring.c_str(), 10, &after_str, &was_overflow, true); return was_overflow ? 0 : val; } unsigned short Space::to_ushort() const { return to_generic_numeric_unsigned_value(); } unsigned int Space::to_uint() const { return to_generic_numeric_unsigned_value(); } unsigned long Space::to_ulong() const { return to_generic_numeric_unsigned_value(); } unsigned long long Space::to_ulong_long() const { switch(type) { case type_null: case type_object: case type_table: return 0; case type_bool: return value.value_bool ? 1 : 0; case type_long: return static_cast(value.value_long); case type_float: return static_cast(value.value_float); case type_double: return static_cast(value.value_double); case type_long_double: return static_cast(value.value_long_double); case type_string: return convert_string_to_ulong_long(); case type_wstring: return convert_wstring_to_ulong_long(); } return 0; } float Space::to_float() const { switch(type) { case type_null: case type_object: case type_table: return 0; case type_bool: return value.value_bool ? 1.0f : 0.0f; case type_long: return static_cast(value.value_long); case type_float: return value.value_float; case type_double: return static_cast(value.value_double); case type_long_double: return static_cast(value.value_long_double); case type_string: return pt::to_float(value.value_string); case type_wstring: return pt::to_float(value.value_wstring); } return 0; } double Space::to_double() const { switch(type) { case type_null: case type_object: case type_table: return 0; case type_bool: return value.value_bool ? 1.0 : 0.0; case type_long: return static_cast(value.value_long); case type_float: return static_cast(value.value_float); case type_double: return value.value_double; case type_long_double: return static_cast(value.value_long_double); case type_string: return pt::to_double(value.value_string); case type_wstring: return pt::to_double(value.value_wstring); } return 0; } long double Space::to_long_double() const { switch(type) { case type_null: case type_object: case type_table: return 0; case type_bool: return value.value_bool ? 1.0 : 0.0; case type_long: return static_cast(value.value_long); case type_float: return static_cast(value.value_float); case type_double: return static_cast(value.value_double); case type_long_double: return value.value_long_double; case type_string: return pt::to_long_double(value.value_string); case type_wstring: return pt::to_long_double(value.value_wstring); } return 0; } std::string Space::to_str() const { if( type == type_string ) return value.value_string; std::string str; if( type == type_wstring ) { TextStream stream; serialize_string_buffer(value.value_wstring.c_str(), value.value_wstring.size(), stream, Escape::no_escape); stream.to_str(str); return str; } serialize_to_json_to(str); return str; } std::wstring Space::to_wstr() const { if( type == type_wstring ) return value.value_wstring; std::wstring str; if( type == type_string ) { utf8_to_wide(value.value_string, str); return str; } serialize_to_json_to(str); return str; } void Space::to_list(std::list & output_list, bool clear_list) const { to_list_str_generic(output_list, clear_list); } void Space::to_list(std::list & output_list, bool clear_list) const { to_list_wstr_generic(output_list, clear_list); } void Space::to_list(std::vector & output_list, bool clear_list) const { to_list_str_generic(output_list, clear_list); } void Space::to_list(std::vector & output_list, bool clear_list) const { to_list_wstr_generic(output_list, clear_list); } bool Space::to_bool(const wchar_t * field, bool default_value) const { const Space * space = get_space(field); return space ? space->to_bool() : default_value; } short Space::to_short(const wchar_t * field, short default_value) const { const Space * space = get_space(field); return space ? space->to_short() : default_value; } int Space::to_int(const wchar_t * field, int default_value) const { const Space * space = get_space(field); return space ? space->to_int() : default_value; } long Space::to_long(const wchar_t * field, long default_value) const { const Space * space = get_space(field); return space ? space->to_long() : default_value; } long long Space::to_llong(const wchar_t * field, long long default_value) const { const Space * space = get_space(field); return space ? space->to_llong() : default_value; } long long Space::to_long_long(const wchar_t * field, long long default_value) const { const Space * space = get_space(field); return space ? space->to_long_long() : default_value; } unsigned short Space::to_ushort(const wchar_t * field, unsigned short default_value) const { const Space * space = get_space(field); return space ? space->to_ushort() : default_value; } unsigned int Space::to_uint(const wchar_t * field, unsigned int default_value) const { const Space * space = get_space(field); return space ? space->to_uint() : default_value; } unsigned long Space::to_ulong(const wchar_t * field, unsigned long default_value) const { const Space * space = get_space(field); return space ? space->to_ulong() : default_value; } unsigned long long Space::to_ullong(const wchar_t * field, unsigned long long default_value) const { const Space * space = get_space(field); return space ? space->to_ullong() : default_value; } unsigned long long Space::to_ulong_long(const wchar_t * field, unsigned long long default_value) const { const Space * space = get_space(field); return space ? space->to_ulong_long() : default_value; } std::string Space::to_str(const wchar_t * field, const char * default_value) const { const Space * space = get_space(field); if( space ) { return space->to_str(); } if( default_value ) { return std::string(default_value); } return std::string(); } std::string Space::to_str(const wchar_t * field, const std::string & default_value) const { const Space * space = get_space(field); return space ? space->to_str() : default_value; } std::wstring Space::to_wstr(const wchar_t * field, const wchar_t * default_value) const { const Space * space = get_space(field); if( space ) { return space->to_wstr(); } if( default_value ) { return std::wstring(default_value); } return std::wstring(); } std::wstring Space::to_wstr(const wchar_t * field, const std::wstring & default_value) const { const Space * space = get_space(field); return space ? space->to_wstr() : default_value; } bool Space::to_list(const wchar_t * field, std::list & output_list, bool clear_list) const { return to_list_generic(field, output_list, clear_list); } bool Space::to_list(const wchar_t * field, std::list & output_list, bool clear_list) const { return to_list_generic(field, output_list, clear_list); } bool Space::to_list(const std::wstring & field, std::list & output_list, bool clear_list) const { return to_list_generic(field, output_list, clear_list); } bool Space::to_list(const std::wstring & field, std::list & output_list, bool clear_list) const { return to_list_generic(field, output_list, clear_list); } bool Space::to_list(const wchar_t * field, std::vector & output_list, bool clear_list) const { return to_list_generic(field, output_list, clear_list); } bool Space::to_list(const wchar_t * field, std::vector & output_list, bool clear_list) const { return to_list_generic(field, output_list, clear_list); } bool Space::to_list(const std::wstring & field, std::vector & output_list, bool clear_list) const { return to_list_generic(field, output_list, clear_list); } bool Space::to_list(const std::wstring & field, std::vector & output_list, bool clear_list) const { return to_list_generic(field, output_list, clear_list); } bool Space::to_bool(const std::wstring & field, bool default_value) const { const Space * space = get_space(field); return space ? space->to_bool() : default_value; } short Space::to_short(const std::wstring & field, short default_value) const { const Space * space = get_space(field); return space ? space->to_short() : default_value; } int Space::to_int(const std::wstring & field, int default_value) const { const Space * space = get_space(field); return space ? space->to_int() : default_value; } long Space::to_long(const std::wstring & field, long default_value) const { const Space * space = get_space(field); return space ? space->to_long() : default_value; } long long Space::to_llong(const std::wstring & field, long long default_value) const { const Space * space = get_space(field); return space ? space->to_llong() : default_value; } long long Space::to_long_long(const std::wstring & field, long long default_value) const { const Space * space = get_space(field); return space ? space->to_long_long() : default_value; } unsigned short Space::to_ushort(const std::wstring & field, unsigned short default_value) const { const Space * space = get_space(field); return space ? space->to_ushort() : default_value; } unsigned int Space::to_uint(const std::wstring & field, unsigned int default_value) const { const Space * space = get_space(field); return space ? space->to_uint() : default_value; } unsigned long Space::to_ulong(const std::wstring & field, unsigned long default_value) const { const Space * space = get_space(field); return space ? space->to_ulong() : default_value; } unsigned long long Space::to_ullong(const std::wstring & field, unsigned long long default_value) const { const Space * space = get_space(field); return space ? space->to_ullong() : default_value; } unsigned long long Space::to_ulong_long(const std::wstring & field, unsigned long long default_value) const { const Space * space = get_space(field); return space ? space->to_ulong_long() : default_value; } std::string Space::to_str(const std::wstring & field, const char * default_value) const { const Space * space = get_space(field); if( space ) { return space->to_str(); } if( default_value ) { return std::string(default_value); } return std::string(); } std::string Space::to_str(const std::wstring & field, const std::string & default_value) const { const Space * space = get_space(field); return space ? space->to_str() : default_value; } std::wstring Space::to_wstr(const std::wstring & field, const wchar_t * default_value) const { const Space * space = get_space(field); if( space ) { return space->to_wstr(); } if( default_value ) { return std::wstring(default_value); } return std::wstring(); } std::wstring Space::to_wstr(const std::wstring & field, const std::wstring & default_value) const { const Space * space = get_space(field); return space ? space->to_wstr() : default_value; } std::string Space::serialize_to_space_str(bool pretty_print) const { std::string str; serialize_to_space_to(str, pretty_print); return str; } std::wstring Space::serialize_to_space_wstr(bool pretty_print) const { std::wstring str; serialize_to_space_to(str, pretty_print); return str; } void Space::serialize_to_space_to(std::string & str, bool pretty_print) const { TextStream stream; serialize_to_space_stream(stream, pretty_print); stream.to_str(str); } void Space::serialize_to_space_to(std::wstring & str, bool pretty_print) const { WTextStream stream; serialize_to_space_stream(stream, pretty_print); stream.to_str(str); } std::string Space::serialize_to_json_str(bool pretty_print) const { std::string str; serialize_to_json_to(str, pretty_print); return str; } std::wstring Space::serialize_to_json_wstr(bool pretty_print) const { std::wstring str; serialize_to_json_to(str, pretty_print); return str; } void Space::serialize_to_json_to(std::string & str, bool pretty_print) const { TextStream stream; serialize_to_json_stream(stream, pretty_print); stream.to_str(str); } void Space::serialize_to_json_to(std::wstring & str, bool pretty_print) const { WTextStream stream; serialize_to_json_stream(stream, pretty_print); stream.to_str(str); } bool * Space::get_bool() { return type == type_bool ? &value.value_bool : nullptr; } long long * Space::get_llong() { return get_long_long(); } long long * Space::get_long_long() { return type == type_long ? &value.value_long : nullptr; } float * Space::get_float() { return type == type_float ? &value.value_float : nullptr; } double * Space::get_double() { return type == type_double ? &value.value_double : nullptr; } long double * Space::get_long_double() { return type == type_long_double ? &value.value_long_double : nullptr; } std::string * Space::get_str() { return type == type_string ? &value.value_string : nullptr; } std::wstring * Space::get_wstr() { return type == type_wstring ? &value.value_wstring : nullptr; } Space::ObjectType * Space::get_object() { return type == type_object ? &value.value_object : nullptr; } Space::TableType * Space::get_table() { return type == type_table ? &value.value_table : nullptr; } bool Space::is_equal(const char * val) const { if( type == type_string ) { return value.value_string == val; } return false; } bool Space::is_equal(const std::string & val) const { if( type == type_string ) { return value.value_string == val; } return false; } bool Space::is_equal(const wchar_t * val) const { if( type == type_wstring ) { return value.value_wstring == val; } return false; } bool Space::is_equal(const std::wstring & val) const { if( type == type_wstring ) { return value.value_wstring == val; } return false; } bool Space::has_value(const char * val) const { if( type == type_string ) { return value.value_string == val; } if( type == type_table ) { for(size_t i=0 ; i < value.value_table.size() ; ++i) { Space * table_item = value.value_table[i]; if( table_item->type == type_string ) { if( table_item->value.value_string == val ) return true; } } } return false; } bool Space::has_value(const std::string & val) const { return has_value(val.c_str()); } bool Space::has_value(const wchar_t * val) const { if( type == type_wstring ) { return value.value_wstring == val; } if( type == type_table ) { for(size_t i=0 ; i < value.value_table.size() ; ++i) { Space * table_item = value.value_table[i]; if( table_item->type == type_wstring ) { if( table_item->value.value_wstring == val ) return true; } } } return false; } bool Space::has_value(const std::wstring & val) const { return has_value(val.c_str()); } Space * Space::get_space(const wchar_t * field) { if( is_object() ) { ObjectType::iterator i = value.value_object.find(field); if( i != value.value_object.end() ) { return i->second; } } return nullptr; } Space * Space::get_space(const std::wstring & field) { return get_space(field.c_str()); } Space & Space::get_add_space(const wchar_t * field) { pt::Space * space = get_space(field); if( !space ) { return add_empty_space(field); } return *space; } Space & Space::get_add_space(const std::wstring & field) { return get_add_space(field.c_str()); } bool * Space::get_bool(const wchar_t * field) { Space * space = get_space(field); return space ? space->get_bool() : nullptr; } long long * Space::get_llong(const wchar_t * field) { Space * space = get_space(field); return space ? space->get_llong() : nullptr; } long long * Space::get_long_long(const wchar_t * field) { Space * space = get_space(field); return space ? space->get_long_long() : nullptr; } float * Space::get_float(const wchar_t * field) { Space * space = get_space(field); return space ? space->get_float() : nullptr; } double * Space::get_double(const wchar_t * field) { Space * space = get_space(field); return space ? space->get_double() : nullptr; } long double * Space::get_long_double(const wchar_t * field) { Space * space = get_space(field); return space ? space->get_long_double() : nullptr; } std::string * Space::get_str(const wchar_t * field) { Space * space = get_space(field); return space ? space->get_str() : nullptr; } std::wstring * Space::get_wstr(const wchar_t * field) { Space * space = get_space(field); return space ? space->get_wstr() : nullptr; } Space::ObjectType * Space::get_object(const wchar_t * field) { Space * space = get_space(field); return space ? space->get_object() : nullptr; } Space::TableType * Space::get_table(const wchar_t * field) { Space * space = get_space(field); return space ? space->get_table() : nullptr; } const bool * Space::get_bool() const { return type == type_bool ? &value.value_bool : nullptr; } const long long * Space::get_llong() const { return get_long_long(); } const long long * Space::get_long_long() const { return type == type_long ? &value.value_long : nullptr; } const float * Space::get_float() const { return type == type_float ? &value.value_float : nullptr; } const double * Space::get_double() const { return type == type_double ? &value.value_double : nullptr; } const long double * Space::get_long_double() const { return type == type_long_double ? &value.value_long_double : nullptr; } const std::string * Space::get_str() const { return type == type_string ? &value.value_string : nullptr; } const std::wstring * Space::get_wstr() const { return type == type_wstring ? &value.value_wstring : nullptr; } const Space::ObjectType * Space::get_object() const { return type == type_object ? &value.value_object : nullptr; } const Space::TableType * Space::get_table() const { return type == type_table ? &value.value_table : nullptr; } bool Space::has_key(const wchar_t * field) const { return get_space(field) != nullptr; } bool Space::has_key(const std::wstring & field) const { return get_space(field) != nullptr; } const Space * Space::get_space(const wchar_t * field) const { if( is_object() ) { ObjectType::const_iterator i = value.value_object.find(field); if( i != value.value_object.end() ) { return i->second; } } return nullptr; } const Space * Space::get_space(const std::wstring & field) const { return get_space(field.c_str()); } const bool * Space::get_bool(const wchar_t * field) const { const Space * space = get_space(field); return space ? space->get_bool() : nullptr; } const long long * Space::get_llong(const wchar_t * field) const { const Space * space = get_space(field); return space ? space->get_llong() : nullptr; } const long long * Space::get_long_long(const wchar_t * field) const { const Space * space = get_space(field); return space ? space->get_long_long() : nullptr; } const float * Space::get_float(const wchar_t * field) const { const Space * space = get_space(field); return space ? space->get_float() : nullptr; } const double * Space::get_double(const wchar_t * field) const { const Space * space = get_space(field); return space ? space->get_double() : nullptr; } const long double * Space::get_long_double(const wchar_t * field) const { const Space * space = get_space(field); return space ? space->get_long_double() : nullptr; } const std::string * Space::get_str(const wchar_t * field) const { const Space * space = get_space(field); return space ? space->get_str() : nullptr; } const std::wstring * Space::get_wstr(const wchar_t * field) const { const Space * space = get_space(field); return space ? space->get_wstr() : nullptr; } const Space::ObjectType * Space::get_object(const wchar_t * field) const { const Space * space = get_space(field); return space ? space->get_object() : nullptr; } const Space::TableType * Space::get_table(const wchar_t * field) const { const Space * space = get_space(field); return space ? space->get_table() : nullptr; } Space * Space::get_space_nc(const wchar_t * field) { if( is_object() ) { ObjectType::iterator i = value.value_object.begin(); while( i != value.value_object.end() ) { if( is_equal_nc(field, i->first.c_str()) ) { return i->second; } } } return nullptr; } Space * Space::get_space_nc(const std::wstring & field) { return get_space_nc(field.c_str()); } const Space * Space::get_space_nc(const wchar_t * field) const { if( is_object() ) { ObjectType::const_iterator i = value.value_object.cbegin(); while( i != value.value_object.cend() ) { if( is_equal_nc(field, i->first.c_str()) ) { return i->second; } } } return nullptr; } const Space * Space::get_space_nc(const std::wstring & field) const { return get_space_nc(field.c_str()); } void Space::remove(const wchar_t * field) { remove(std::wstring(field)); } void Space::remove(const std::wstring & field) { if( type == type_object ) { ObjectType::iterator i = value.value_object.find(field); if( i != value.value_object.end() ) { delete i->second; i->second = nullptr; value.value_object.erase(i); } } } void Space::remove(size_t table_index) { if( type == type_table && table_index < value.value_table.size() ) { delete value.value_table[table_index]; value.value_table[table_index] = nullptr; value.value_table.erase(value.value_table.begin() + table_index); } } bool Space::is_equal(const wchar_t * field, const char * val) const { const Space * space = get_space(field); if( space ) { return space->is_equal(val); } return false; } bool Space::is_equal(const wchar_t * field, const std::string & val) const { const Space * space = get_space(field); if( space ) { return space->is_equal(val); } return false; } bool Space::is_equal(const wchar_t * field, const wchar_t * val) const { const Space * space = get_space(field); if( space ) { return space->is_equal(val); } return false; } bool Space::is_equal(const wchar_t * field, const std::wstring & val) const { const Space * space = get_space(field); if( space ) { return space->is_equal(val); } return false; } bool Space::has_value(const wchar_t * field, const char * val) const { const Space * space = get_space(field); if( space ) { return space->has_value(val); } return false; } bool Space::has_value(const wchar_t * field, const std::string & val) const { const Space * space = get_space(field); if( space ) { return space->has_value(val); } return false; } bool Space::has_value(const wchar_t * field, const wchar_t * val) const { const Space * space = get_space(field); if( space ) { return space->has_value(val); } return false; } bool Space::has_value(const wchar_t * field, const std::wstring & val) const { const Space * space = get_space(field); if( space ) { return space->has_value(val); } return false; } void Space::copy_from(const Space & space) { switch(space.type) { case type_null: initialize_value_null_if_needed(); break; case type_bool: initialize_value_bool_if_needed(); value.value_bool = space.value.value_bool; break; case type_long: initialize_value_long_if_needed(); value.value_long = space.value.value_long; break; case type_float: initialize_value_float_if_needed(); value.value_float = space.value.value_float; break; case type_double: initialize_value_double_if_needed(); value.value_double = space.value.value_double; break; case type_long_double: initialize_value_long_double_if_needed(); value.value_long_double = space.value.value_long_double; break; case type_string: initialize_value_string_if_needed(); value.value_string = space.value.value_string; break; case type_wstring: initialize_value_wstring_if_needed(); value.value_wstring = space.value.value_wstring; break; case type_object: copy_value_object(space.value); break; case type_table: copy_value_table(space.value); break; } } void Space::copy_value_object(const Value & value_from) { if( type == type_object ) { remove_value_object(true); } else { initialize_value_object_if_needed(); } for(auto map_item : value_from.value_object) { Space * new_space = new Space(*map_item.second); value.value_object.insert(std::make_pair(map_item.first, new_space)); } } void Space::copy_value_table(const Value & value_from) { if( type == type_table ) { remove_value_table(true); } else { initialize_value_table_if_needed(); } for(Space * space : value_from.value_table) { Space * new_space = new Space(*space); value.value_table.push_back(new_space); } } void Space::move_value_from(Space && space) { switch(space.type) { case type_string: initialize_value_string_if_needed(std::move(space.value.value_string)); break; case type_wstring: initialize_value_wstring_if_needed(std::move(space.value.value_wstring)); break; case type_object: initialize_value_object_if_needed(std::move(space.value.value_object)); break; case type_table: initialize_value_table_if_needed(std::move(space.value.value_table)); break; default: copy_from(space); break; } } void Space::move_from(Space && space) { move_value_from(std::move(space)); space.type = Type::type_null; } void Space::initialize() { type = type_null; } void Space::initialize_value_null_if_needed() { if( type != type_null ) { remove_value(); type = type_null; } } void Space::initialize_value_bool_if_needed() { if( type != type_bool ) { remove_value(); new (&value) bool; type = type_bool; } } void Space::initialize_value_long_if_needed() { if( type != type_long ) { remove_value(); new (&value) long long; type = type_long; } } void Space::initialize_value_float_if_needed() { if( type != type_float ) { remove_value(); new (&value) float; type = type_float; } } void Space::initialize_value_double_if_needed() { if( type != type_double ) { remove_value(); new (&value) double; type = type_double; } } void Space::initialize_value_long_double_if_needed() { if( type != type_long_double ) { remove_value(); new (&value) long double; type = type_long_double; } } void Space::initialize_value_string_if_needed() { if( type != type_string ) { remove_value(); new (&value) std::string; type = type_string; } } void Space::initialize_value_string_if_needed(std::string && str) { if( type != type_string ) { remove_value(); new (&value) std::string(std::move(str)); type = type_string; } else { value.value_string = std::move(str); } } void Space::initialize_value_wstring_if_needed() { if( type != type_wstring ) { remove_value(); new (&value) std::wstring; type = type_wstring; } } void Space::initialize_value_wstring_if_needed(std::wstring && str) { if( type != type_wstring ) { remove_value(); new (&value) std::wstring(std::move(str)); type = type_wstring; } else { value.value_wstring = std::move(str); } } void Space::initialize_value_object_if_needed() { if( type != type_object ) { remove_value(); new (&value) ObjectType; type = type_object; } } void Space::initialize_value_object_if_needed(ObjectType && obj) { if( type != type_object ) { remove_value(); new (&value) ObjectType(std::move(obj)); type = type_object; } else { remove_value_object(true); value.value_object = std::move(obj); } } void Space::initialize_value_table_if_needed() { if( type != type_table ) { remove_value(); new (&value) TableType; type = type_table; } } void Space::initialize_value_table_if_needed(TableType && tab) { if( type != type_table ) { remove_value(); new (&value) TableType(std::move(tab)); type = type_table; } else { remove_value_table(true); value.value_table = std::move(tab); } } void Space::remove_value() { switch(type) { case type_null: break; case type_bool: case type_long: case type_float: case type_double: case type_long_double: type = type_null; break; case type_string: { remove_value_string(); break; } case type_wstring: { remove_value_wstring(); break; } case type_object: { remove_value_object(); break; } case type_table: remove_value_table(); break; } } void Space::remove_value_string() { value.value_string.~basic_string(); type = type_null; } void Space::remove_value_wstring() { value.value_wstring.~basic_string(); type = type_null; } void Space::remove_value_object(bool only_clear) { for(auto map_item : value.value_object) { delete map_item.second; map_item.second = nullptr; } if( only_clear ) { value.value_object.clear(); } else { value.value_object.~ObjectType(); type = type_null; } } void Space::remove_value_table(bool only_clear) { for(size_t i = 0 ; i < value.value_table.size() ; ++i) { delete value.value_table[i]; value.value_table[i] = nullptr; } if( only_clear ) { value.value_table.clear(); } else { value.value_table.~TableType(); type = type_null; } } } // namespace