api2021 part I #4
|
@ -156,6 +156,39 @@ Space::Space(const Space * space)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Space::clear()
|
||||||
|
{
|
||||||
|
set_null();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void Space::set_null()
|
||||||
|
{
|
||||||
|
initialize_value_null_if_needed();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Space::set_empty_string()
|
||||||
|
{
|
||||||
|
initialize_value_string_if_needed();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Space::set_empty_wstring()
|
||||||
|
{
|
||||||
|
initialize_value_wstring_if_needed();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Space::set_empty_table()
|
||||||
|
{
|
||||||
|
initialize_value_table_if_needed();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Space::set_empty_object()
|
||||||
|
{
|
||||||
|
initialize_value_object_if_needed();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Space::set(bool val)
|
void Space::set(bool val)
|
||||||
|
@ -220,14 +253,28 @@ void Space::set(double val)
|
||||||
|
|
||||||
void Space::set(const char * str)
|
void Space::set(const char * str)
|
||||||
{
|
{
|
||||||
initialize_value_string_if_needed();
|
if( str == nullptr )
|
||||||
value.value_string = str;
|
{
|
||||||
|
initialize_value_null_if_needed();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
initialize_value_string_if_needed();
|
||||||
|
value.value_string = str;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Space::set(const wchar_t * str)
|
void Space::set(const wchar_t * str)
|
||||||
{
|
{
|
||||||
initialize_value_wstring_if_needed();
|
if( str == nullptr )
|
||||||
value.value_wstring = str;
|
{
|
||||||
|
initialize_value_null_if_needed();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
initialize_value_wstring_if_needed();
|
||||||
|
value.value_wstring = str;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Space::set(const std::string & str)
|
void Space::set(const std::string & str)
|
||||||
|
|
166
space/space.h
166
space/space.h
|
@ -55,110 +55,72 @@ namespace PT
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
A parser for parsing config files.
|
|
||||||
|
|
||||||
A config file can look like this:
|
Simple form:
|
||||||
variable1 = value 1
|
key = value
|
||||||
variable2 = " value 2 "
|
|
||||||
variable3 = (value 1, value 2)
|
|
||||||
variable4 = (" value 1 " , "value2", value 3)
|
|
||||||
|
|
||||||
sample of use:
|
If value is equal to 'null' then the internal representation is equal to Type::type_null, e.g:
|
||||||
SpaceParser parser;
|
key = null
|
||||||
parser.Parse("/path/to/config");
|
|
||||||
|
|
||||||
if( parser.status == SpaceParser::ok )
|
If value is either 'false' or 'true' then the internal representation is Type::type_bool, e.g:
|
||||||
{
|
key = false
|
||||||
// the whole config we have in parser.table
|
key = true
|
||||||
}
|
|
||||||
|
|
||||||
config syntax:
|
If value is an integer number and not an overflow has occured while parsing then type of the value
|
||||||
option = list
|
is Type::type_long (type is 'long long' internally):
|
||||||
|
key = 1000
|
||||||
|
|
||||||
list can consists of any number of items, if you're using more than one item you should
|
If value is a floating point number then type is Type::type_double (type is 'double' internally):
|
||||||
use brackets ()
|
key = 123.45
|
||||||
|
key = 123.45e+10
|
||||||
|
|
||||||
for one item the brackets can be ommited:
|
In other cases value has Type::type_wstring type.
|
||||||
option = value
|
|
||||||
white characters at the beginning of the value (and at the end) will be trimmed,
|
|
||||||
or you can use quotes:
|
|
||||||
option = "value"
|
|
||||||
option2 = "value with spaces at the end "
|
|
||||||
|
|
||||||
the form without quotes:
|
The form with quotation marks:
|
||||||
option = value
|
key = "value"
|
||||||
should be written in one line, so this is not allowed:
|
In such a case value has Type::type_wstring type and can be multiline e.g:
|
||||||
option =
|
key = "multiline
|
||||||
value
|
value"
|
||||||
you can use a new line characters only between brackets and quotes:
|
In this form you can have spaces around value, e.g.:
|
||||||
option = "this is
|
key = " value with spaces "
|
||||||
a multiline string"
|
|
||||||
option = ( value1,
|
|
||||||
value2 )
|
|
||||||
|
|
||||||
but there is one requirement: the first character " or ( should be in the same line,
|
|
||||||
so this is not allowed
|
|
||||||
option =
|
|
||||||
"this is wrong"
|
|
||||||
but this is ok:
|
|
||||||
option = "
|
|
||||||
that is ok"
|
|
||||||
|
|
||||||
empty lists:
|
The value can be a list:
|
||||||
option = ()
|
key = (value1,value2)
|
||||||
this creates an empty list: parser.table['option'].empty() == true
|
or the same written with spaces around:
|
||||||
|
key = ( value1 , value2 )
|
||||||
|
or written in multiline fashion:
|
||||||
|
key = (
|
||||||
|
value1,
|
||||||
|
value2,
|
||||||
|
)
|
||||||
|
a colon after value2 is optional.
|
||||||
|
|
||||||
option =
|
List can be written with quotation marks too:
|
||||||
this creates an empty list too (the same as previously)
|
key = (
|
||||||
|
"value1",
|
||||||
|
"value2",
|
||||||
|
"value3
|
||||||
|
with a new line character inside",
|
||||||
|
)
|
||||||
|
|
||||||
option = ""
|
List without value:
|
||||||
but this doesn't create an empty list, it creates a list with one (empty) item
|
key = ()
|
||||||
|
is equal to simple form without value, e.g.:
|
||||||
|
key =
|
||||||
|
|
||||||
commentaries:
|
|
||||||
# this is a commentary (until the end of the line)
|
|
||||||
option = value # this is a commentary too
|
|
||||||
|
|
||||||
commentaries are treated as white characters, other example:
|
|
||||||
option = ( # this is my list
|
|
||||||
"value 1" # this is a value one
|
|
||||||
value 2 # and this is a value two
|
|
||||||
) # end of my list
|
|
||||||
|
|
||||||
overwriting:
|
|
||||||
option1 = some value
|
|
||||||
option1 = other value
|
|
||||||
# always the last option is used so option1 is "other value"
|
|
||||||
|
|
||||||
list delimiter:
|
Difference between a simple form and a list is when parsing the colon, in simple form the colon is a part of the value, e.g.:
|
||||||
option1 = (value1, value2, value3)
|
key = value with , a colon inside
|
||||||
option2 = ("value1", "value2", "value3")
|
this is equal to:
|
||||||
above we're using a comma ',' as a list delimiter but when using quotes (second line)
|
key = "value with , a colon inside"
|
||||||
the commas can be omitted:
|
|
||||||
option2 = ("value1" "value2" "value3")
|
|
||||||
|
|
||||||
white characters:
|
and in a form of a list it would have two values:
|
||||||
the name of an option cannot consist of white characters
|
key = (value with , a colon inside)
|
||||||
some option = value # this is wrong
|
would be equal to:
|
||||||
some_option = value # this is ok
|
key = ("value with" , "a colon inside")
|
||||||
|
|
||||||
which characters are allowed in an option name is defined by IsVariableChar() method
|
|
||||||
|
|
||||||
you can use white characters in values
|
|
||||||
option = value with spaces or tabs
|
|
||||||
white characters at the beginning and at the end will be trimmed,
|
|
||||||
so if you want them use quotes:
|
|
||||||
option = " other value with spaces "
|
|
||||||
|
|
||||||
special characters in quoted strings:
|
|
||||||
option = "this is a string with \" a quote inside"
|
|
||||||
the option will be: this is a string with " a quote inside
|
|
||||||
\\ - means one \
|
|
||||||
basically: \char produces char
|
|
||||||
so:
|
|
||||||
"\a" gives "a"
|
|
||||||
"\\" gives "\"
|
|
||||||
"\Z" gives "Z" and so on
|
|
||||||
you can call UseEscapeChar(false) to turn this off
|
|
||||||
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
@ -242,7 +204,15 @@ public:
|
||||||
Space(const Space * space);
|
Space(const Space * space);
|
||||||
|
|
||||||
|
|
||||||
|
void clear();
|
||||||
|
|
||||||
// set a new value
|
// set a new value
|
||||||
|
void set_null();
|
||||||
|
void set_empty_string();
|
||||||
|
void set_empty_wstring();
|
||||||
|
void set_empty_table();
|
||||||
|
void set_empty_object();
|
||||||
|
|
||||||
void set(bool val);
|
void set(bool val);
|
||||||
void set(short val);
|
void set(short val);
|
||||||
void set(int val);
|
void set(int val);
|
||||||
|
@ -258,7 +228,7 @@ public:
|
||||||
void set(const wchar_t * str);
|
void set(const wchar_t * str);
|
||||||
void set(const std::string & str);
|
void set(const std::string & str);
|
||||||
void set(const std::wstring & str);
|
void set(const std::wstring & str);
|
||||||
void set(const Space * space = nullptr);
|
void set(const Space * space);
|
||||||
|
|
||||||
|
|
||||||
// add a value to the table, change to table if needed, return the reference to the new inserted item
|
// add a value to the table, change to table if needed, return the reference to the new inserted item
|
||||||
|
@ -652,20 +622,28 @@ protected:
|
||||||
template<typename StreamType>
|
template<typename StreamType>
|
||||||
void serialize_json_float(StreamType & str) const
|
void serialize_json_float(StreamType & str) const
|
||||||
{
|
{
|
||||||
wchar_t buffer[50];
|
wchar_t buffer[100];
|
||||||
size_t buffer_len = sizeof(buffer) / sizeof(char);
|
size_t buffer_len = sizeof(buffer) / sizeof(char);
|
||||||
|
|
||||||
std::swprintf(buffer, buffer_len, L"%f", value.value_float);
|
int chars_written = std::swprintf(buffer, buffer_len, L"%e", static_cast<double>(value.value_float));
|
||||||
|
|
||||||
|
if( errno == EOVERFLOW || chars_written < 0 )
|
||||||
|
buffer[0] = 0;
|
||||||
|
|
||||||
serialize_string_buffer(buffer, str, Escape::escape_json);
|
serialize_string_buffer(buffer, str, Escape::escape_json);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename StreamType>
|
template<typename StreamType>
|
||||||
void serialize_json_double(StreamType & str) const
|
void serialize_json_double(StreamType & str) const
|
||||||
{
|
{
|
||||||
wchar_t buffer[50];
|
wchar_t buffer[100];
|
||||||
size_t buffer_len = sizeof(buffer) / sizeof(char);
|
size_t buffer_len = sizeof(buffer) / sizeof(wchar_t);
|
||||||
|
|
||||||
|
int chars_written = std::swprintf(buffer, buffer_len, L"%e", value.value_double);
|
||||||
|
|
||||||
|
if( errno == EOVERFLOW || chars_written < 0 )
|
||||||
|
buffer[0] = 0;
|
||||||
|
|
||||||
std::swprintf(buffer, buffer_len, L"%f", value.value_double);
|
|
||||||
serialize_string_buffer(buffer, str, Escape::escape_json);
|
serialize_string_buffer(buffer, str, Escape::escape_json);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue