You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

2429 lines
42 KiB

/*
* This file is a part of PikoTools
* and is distributed under the (new) BSD licence.
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
* 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 <wchar.h>
#include <utility>
#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();
remove_child_spaces();
remove_space_name();
}
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(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();
}
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 )
{
value.value_table.clear();
}
else
{
initialize_value_table_if_needed();
}
}
void Space::set_empty_object()
{
if( type == type_object )
{
value.value_object.clear();
}
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<long long>(val));
}
void Space::set(int val)
{
set(static_cast<long long>(val));
}
void Space::set(long val)
{
set(static_cast<long long>(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<long long>(val));
}
void Space::set(unsigned int val)
{
set(static_cast<long long>(val));
}
void Space::set(unsigned long val)
{
set(static_cast<long long>(val));
}
void Space::set(unsigned long long val)
{
set(static_cast<long long>(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(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(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<Space*>(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, 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));
insert_res.first->second = new Space(std::move(space));
return *(insert_res.first->second);
}
Space & Space::add_empty_space(const wchar_t * field)
{
return add_generic(field, static_cast<Space*>(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, 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<Space*>(nullptr));
}
Space & Space::add_child_space(const wchar_t * space_name)
{
initialize_child_spaces_if_needed();
child_spaces->push_back(new Space());
Space * last_space = child_spaces->back();
last_space->initialize_space_name_if_needed();
last_space->name->append(space_name);
return *last_space;
}
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_numeric() const
{
return is_long_long() || is_float() || is_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;
long long val = to_long_long();
return (val != 0) ? true : false;
}
short Space::to_short() const
{
return to_generic_numeric_signed_value<short>();
}
int Space::to_int() const
{
return to_generic_numeric_signed_value<int>();
}
long Space::to_long() const
{
return to_generic_numeric_signed_value<long>();
}
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<long long>(value.value_float);
case type_double:
return static_cast<long long>(value.value_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 short>();
}
unsigned int Space::to_uint() const
{
return to_generic_numeric_unsigned_value<unsigned int>();
}
unsigned long Space::to_ulong() const
{
return to_generic_numeric_unsigned_value<unsigned long>();
}
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<unsigned long long>(value.value_long);
case type_float:
return static_cast<unsigned long long>(value.value_float);
case type_double:
return static_cast<unsigned long long>(value.value_double);
case type_string:
return convert_string_to_ulong_long();
case type_wstring:
return convert_wstring_to_ulong_long();
}
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(), stream, Escape::no_escape);
stream.to_string(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 )
{
UTF8ToWide(value.value_string, str);
return str;
}
serialize_to_json_to(str);
return str;
}
void Space::to_list(std::list<std::string> & output_list, bool clear_list) const
{
to_list_str_generic(output_list, clear_list);
}
void Space::to_list(std::list<std::wstring> & output_list, bool clear_list) const
{
to_list_wstr_generic(output_list, clear_list);
}
void Space::to_list(std::vector<std::string> & output_list, bool clear_list) const
{
to_list_str_generic(output_list, clear_list);
}
void Space::to_list(std::vector<std::wstring> & 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_object_field(field);
return space ? space->to_bool() : default_value;
}
short Space::to_short(const wchar_t * field, short default_value) const
{
const Space * space = get_object_field(field);
return space ? space->to_short() : default_value;
}
int Space::to_int(const wchar_t * field, int default_value) const
{
const Space * space = get_object_field(field);
return space ? space->to_int() : default_value;
}
long Space::to_long(const wchar_t * field, long default_value) const
{
const Space * space = get_object_field(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_object_field(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_object_field(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_object_field(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_object_field(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_object_field(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_object_field(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_object_field(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_object_field(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_object_field(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_object_field(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_object_field(field);
return space ? space->to_wstr() : default_value;
}
bool Space::to_list(const wchar_t * field, std::list<std::string> & 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<std::wstring> & 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<std::string> & 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<std::wstring> & 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<std::string> & 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<std::wstring> & 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<std::string> & 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<std::wstring> & 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_object_field(field);
return space ? space->to_bool() : default_value;
}
short Space::to_short(const std::wstring & field, short default_value) const
{
const Space * space = get_object_field(field);
return space ? space->to_short() : default_value;
}
int Space::to_int(const std::wstring & field, int default_value) const
{
const Space * space = get_object_field(field);
return space ? space->to_int() : default_value;
}
long Space::to_long(const std::wstring & field, long default_value) const
{
const Space * space = get_object_field(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_object_field(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_object_field(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_object_field(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_object_field(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_object_field(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_object_field(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_object_field(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_object_field(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_object_field(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_object_field(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_object_field(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_string(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_string(str);
}
std::string Space::serialize_to_json_str() const
{
std::string str;
serialize_to_json_to(str);
return str;
}
std::wstring Space::serialize_to_json_wstr() const
{
std::wstring str;
serialize_to_json_to(str);
return str;
}
void Space::serialize_to_json_to(std::string & str) const
{
TextStream stream;
serialize_to_json_stream(stream);
stream.to_string(str);
}
void Space::serialize_to_json_to(std::wstring & str) const
{
WTextStream stream;
serialize_to_json_stream(stream);
stream.to_string(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;
}
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_object_field(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;
}
bool * Space::get_bool(const wchar_t * field)
{
Space * space = get_object_field(field);
return space ? space->get_bool() : nullptr;
}
long long * Space::get_llong(const wchar_t * field)
{
Space * space = get_object_field(field);
return space ? space->get_llong() : nullptr;
}
long long * Space::get_long_long(const wchar_t * field)
{
Space * space = get_object_field(field);
return space ? space->get_long_long() : nullptr;
}
float * Space::get_float(const wchar_t * field)
{
Space * space = get_object_field(field);
return space ? space->get_float() : nullptr;
}
double * Space::get_double(const wchar_t * field)
{
Space * space = get_object_field(field);
return space ? space->get_double() : nullptr;
}
std::string * Space::get_str(const wchar_t * field)
{
Space * space = get_object_field(field);
return space ? space->get_str() : nullptr;
}
std::wstring * Space::get_wstr(const wchar_t * field)
{
Space * space = get_object_field(field);
return space ? space->get_wstr() : nullptr;
}
Space::ObjectType * Space::get_object(const wchar_t * field)
{
Space * space = get_object_field(field);
return space ? space->get_object() : nullptr;
}
Space::TableType * Space::get_table(const wchar_t * field)
{
Space * space = get_object_field(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 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_object_field(field) != nullptr;
}
bool Space::has_key(const std::wstring & field) const
{
return get_object_field(field) != nullptr;
}
const Space * Space::get_object_field(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;
}
Space * Space::get_object_field(const std::wstring & field)
{
return get_object_field(field.c_str());
}
const Space * Space::get_object_field(const std::wstring & field) const
{
return get_object_field(field.c_str());
}
const bool * Space::get_bool(const wchar_t * field) const
{
const Space * space = get_object_field(field);
return space ? space->get_bool() : nullptr;
}
const long long * Space::get_llong(const wchar_t * field) const
{
const Space * space = get_object_field(field);
return space ? space->get_llong() : nullptr;
}
const long long * Space::get_long_long(const wchar_t * field) const
{
const Space * space = get_object_field(field);
return space ? space->get_long_long() : nullptr;
}
const float * Space::get_float(const wchar_t * field) const
{
const Space * space = get_object_field(field);
return space ? space->get_float() : nullptr;
}
const double * Space::get_double(const wchar_t * field) const
{
const Space * space = get_object_field(field);
return space ? space->get_double() : nullptr;
}
const std::string * Space::get_str(const wchar_t * field) const
{
const Space * space = get_object_field(field);
return space ? space->get_str() : nullptr;
}
const std::wstring * Space::get_wstr(const wchar_t * field) const
{
const Space * space = get_object_field(field);
return space ? space->get_wstr() : nullptr;
}
const Space::ObjectType * Space::get_object(const wchar_t * field) const
{
const Space * space = get_object_field(field);
return space ? space->get_object() : nullptr;
}
const Space::TableType * Space::get_table(const wchar_t * field) const
{
const Space * space = get_object_field(field);
return space ? space->get_table() : nullptr;
}
Space * Space::get_object_field_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_object_field_nc(const std::wstring & field)
{
return get_object_field_nc(field.c_str());
}
const Space * Space::get_object_field_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_object_field_nc(const std::wstring & field) const
{
return get_object_field_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);
}
}
}
bool Space::is_equal(const wchar_t * field, const char * val) const
{
const Space * space = get_object_field(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_object_field(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_object_field(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_object_field(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_object_field(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_object_field(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_object_field(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_object_field(field);
if( space )
{
return space->has_value(val);
}
return false;
}
Space * Space::find_child_space(const wchar_t * name)
{
return find_child_space_generic(name);
}
Space * Space::find_child_space(const std::wstring & name)
{
return find_child_space_generic(name);
}
const Space * Space::find_child_space(const wchar_t * name) const
{
return find_child_space_generic(name);
}
const Space * Space::find_child_space(const std::wstring & name) const
{
return find_child_space_generic(name);
}
Space & Space::find_add_child_space(const wchar_t * name)
{
Space * space = find_child_space(name);
if( !space )
{
return add_child_space(name);
}
return *space;
}
Space & Space::find_add_child_space(const std::wstring & name)
{
return find_add_child_space(name.c_str());
}
void Space::remove_child_space(const wchar_t * name)
{
if( child_spaces )
{
for(size_t i=0 ; i<child_spaces->size() ; )
{
Space * child = (*child_spaces)[i];
if( child->name && (*child->name) == name )
{
delete child;
child = nullptr;
child_spaces->erase(child_spaces->begin() + i);
}
else
{
++i;
}
}
}
}
void Space::remove_child_space(const std::wstring & name)
{
return remove_child_space(name.c_str());
}
void Space::remove_child_space(size_t index)
{
if( child_spaces && index < child_spaces->size() )
{
Space * child = (*child_spaces)[index];
delete child;
child = nullptr;
child_spaces->erase(child_spaces->begin() + index);
}
}
void Space::copy_value_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_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_child_spaces_from(const Space & space)
{
if( space.child_spaces )
{
initialize_child_spaces_if_needed();
child_spaces->clear();
for(size_t i = 0 ; i < space.child_spaces->size() ; ++i)
{
child_spaces->push_back(new Space((*space.child_spaces)[i]));
}
}
else
if( child_spaces )
{
remove_child_spaces();
}
}
void Space::copy_space_name_from(const Space & space)
{
if( space.name )
{
initialize_space_name_if_needed();
*name = *space.name;
}
else
if( name )
{
remove_space_name();
}
}
void Space::copy_from(const Space & space)
{
copy_value_from(space);
copy_child_spaces_from(space);
copy_space_name_from(space);
}
void Space::copy_value_object(const Value & value_from)
{
initialize_value_object_if_needed();
value.value_object.clear();
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)
{
initialize_value_table_if_needed();
value.value_table.clear();
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_value_from(space);
break;
}
}
void Space::move_from(Space && space)
{
move_value_from(std::move(space));
space.type = Type::type_null;
std::swap(child_spaces, space.child_spaces);
std::swap(name, space.name);
}
void Space::initialize()
{
type = type_null;
child_spaces = nullptr;
name = nullptr;
}
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_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
{
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
{
value.value_table = std::move(tab);
}
}
void Space::initialize_child_spaces_if_needed()
{
if( child_spaces == nullptr )
{
child_spaces = new TableType();
}
}
void Space::initialize_space_name_if_needed()
{
if( name == nullptr )
{
name = new std::wstring();
}
}
void Space::remove_value()
{
switch(type)
{
case type_null:
break;
case type_bool:
case type_long:
case type_float:
case type_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()
{
for(auto map_item : value.value_object)
{
delete map_item.second;
map_item.second = nullptr;
}
value.value_object.~ObjectType();
type = type_null;
}
void Space::remove_value_table()
{
for(size_t i = 0 ; i < value.value_table.size() ; ++i)
{
delete value.value_table[i];
value.value_table[i] = nullptr;
}
value.value_table.~TableType();
type = type_null;
}
void Space::remove_child_spaces()
{
if( child_spaces )
{
for(size_t i = 0 ; i < child_spaces->size() ; ++i)
{
delete (*child_spaces)[i];
(*child_spaces)[i] = nullptr;
}
delete child_spaces;
child_spaces = nullptr;
}
}
void Space::remove_space_name()
{
if( name )
{
delete name;
name = nullptr;
}
}
} // namespace