Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
LEFEBVREJP email
radix
Commits
e4e97de8
Commit
e4e97de8
authored
Apr 02, 2020
by
Norby, Tom
Browse files
Template and test updates.
parent
c56b5004
Pipeline
#95949
passed with stages
in 20 minutes and 22 seconds
Changes
2
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
radixcore/json.hh
View file @
e4e97de8
...
...
@@ -8,18 +8,19 @@
#include <sstream>
#include <vector>
#include "radixcore/value.hh"
#include "radixcore/visibility.hh"
//-----------------------------------------------------------------------------
// see www.json.org for parsing grammar
namespace
radix
{
template
<
class
JsonT
ype
>
class
RADIX_PUBLIC
JSONParser
template
<
class
value_type
,
class
array_type
,
class
object_t
ype
>
class
RADIX_PUBLIC
JSONParser
Impl
{
public:
//-------------------------------------------------------------------------
JSONParser
()
JSONParser
Impl
()
{
literals
[
0
]
=
"false"
;
literals
[
1
]
=
"null"
;
...
...
@@ -29,7 +30,7 @@ class RADIX_PUBLIC JSONParser
}
//-------------------------------------------------------------------------
JsonT
ype
&
root
()
{
return
m_root
;
}
value_t
ype
&
root
()
{
return
m_root
;
}
//-------------------------------------------------------------------------
std
::
string
last_error
()
...
...
@@ -136,7 +137,7 @@ class RADIX_PUBLIC JSONParser
}
//-------------------------------------------------------------------------
JsonT
ype
parse_array
()
value_t
ype
parse_array
()
{
if
(
m_po
>=
m_text
.
size
())
return
nullptr
;
if
(
m_text
[
m_po
]
!=
'['
)
return
nullptr
;
...
...
@@ -146,11 +147,11 @@ class RADIX_PUBLIC JSONParser
size_t
col_prev
=
m_col
;
bool
trailing_comma
=
false
;
JsonT
ype
parent
=
JsonType
(
DataArray
()
);
value_t
ype
parent
=
array_type
(
);
for
(;
m_po
<
m_text
.
size
();
m_po
++
,
m_col
++
)
{
skip_whitespace
();
JsonT
ype
child
=
parse_value
();
value_t
ype
child
=
parse_value
();
if
(
child
.
is_null
())
{
if
(
m_last_error
!=
""
)
...
...
@@ -168,7 +169,7 @@ class RADIX_PUBLIC JSONParser
}
else
if
(
m_text
[
m_po
]
==
']'
)
break
;
return
JsonT
ype
();
return
value_t
ype
();
}
else
{
...
...
@@ -191,13 +192,13 @@ class RADIX_PUBLIC JSONParser
m_last_error
=
"invalid character '"
;
m_last_error
+=
ch
;
m_last_error
+=
"' in array"
;
return
JsonT
ype
();
return
value_t
ype
();
}
}
if
(
m_po
>=
m_text
.
size
()
||
m_text
[
m_po
]
!=
']'
)
{
m_last_error
=
"no closing bracket ']' for array"
;
return
JsonT
ype
();
return
value_t
ype
();
}
m_po
++
;
m_col
++
;
...
...
@@ -211,9 +212,9 @@ class RADIX_PUBLIC JSONParser
// (0|([1-9][0-9]*))
// (\.[0-9]+)?
// ([Ee][+-]?[0-9]+)?
JsonT
ype
parse_number
()
value_t
ype
parse_number
()
{
if
(
m_po
>=
m_text
.
size
())
return
JsonT
ype
();
if
(
m_po
>=
m_text
.
size
())
return
value_t
ype
();
size_t
len
=
0
;
...
...
@@ -226,7 +227,7 @@ class RADIX_PUBLIC JSONParser
if
(
m_po
>=
m_text
.
size
())
{
m_last_error
=
"invalid number (no digits after -)"
;
return
JsonT
ype
();
return
value_t
ype
();
}
}
...
...
@@ -235,7 +236,7 @@ class RADIX_PUBLIC JSONParser
if
(
m_po
>=
m_text
.
size
()
||
!
(
ch
>=
'0'
&&
m_text
[
m_po
]
<=
'9'
))
{
m_last_error
=
"invalid number (no digits)"
;
return
JsonT
ype
();
return
value_t
ype
();
}
m_po
++
;
m_col
++
;
...
...
@@ -254,13 +255,13 @@ class RADIX_PUBLIC JSONParser
{
try
{
JsonT
ype
node
=
JsonT
ype
(
std
::
stod
(
std
::
string
(
&
m_text
[
m_po
-
len
],
len
)));
value_t
ype
node
=
value_t
ype
(
std
::
stod
(
std
::
string
(
&
m_text
[
m_po
-
len
],
len
)));
return
node
;
}
catch
(...)
{
return
JsonT
ype
();
return
value_t
ype
();
}
}
ch
=
m_text
[
m_po
];
...
...
@@ -274,7 +275,7 @@ class RADIX_PUBLIC JSONParser
if
(
m_po
>=
m_text
.
size
())
{
m_last_error
=
"invalid number (no digits after decimal)"
;
return
JsonT
ype
();
return
value_t
ype
();
}
ch
=
m_text
[
m_po
];
size_t
n_digits
=
0
;
...
...
@@ -287,7 +288,7 @@ class RADIX_PUBLIC JSONParser
if
(
n_digits
==
0
)
{
m_last_error
=
"invalid number (no digits after decimal)"
;
return
JsonT
ype
();
return
value_t
ype
();
}
}
...
...
@@ -300,7 +301,7 @@ class RADIX_PUBLIC JSONParser
if
(
m_po
>=
m_text
.
size
())
{
m_last_error
=
"invalid number (no digits for exponent)"
;
return
JsonT
ype
();
return
value_t
ype
();
}
ch
=
m_text
[
m_po
];
// [+-]?
...
...
@@ -313,7 +314,7 @@ class RADIX_PUBLIC JSONParser
if
(
m_po
>=
m_text
.
size
())
{
m_last_error
=
"invalid number (no digits for exponent)"
;
return
JsonT
ype
();
return
value_t
ype
();
}
size_t
n_digits
=
0
;
...
...
@@ -326,19 +327,19 @@ class RADIX_PUBLIC JSONParser
if
(
n_digits
==
0
)
{
m_last_error
=
"invalid number (no digits after decimal)"
;
return
JsonT
ype
();
return
value_t
ype
();
}
}
try
{
JsonT
ype
node
=
JsonT
ype
(
std
::
stod
(
std
::
string
(
&
m_text
[
m_po
-
len
],
len
)));
value_t
ype
node
=
value_t
ype
(
std
::
stod
(
std
::
string
(
&
m_text
[
m_po
-
len
],
len
)));
return
node
;
}
catch
(...)
{
return
JsonT
ype
();
return
value_t
ype
();
}
}
...
...
@@ -359,7 +360,7 @@ class RADIX_PUBLIC JSONParser
// only 3 valid literals all in lower case: false, null, true
// TODO: need to refactor code to support null return (currently it is
// treated as an error)
JsonT
ype
parse_literal
()
value_t
ype
parse_literal
()
{
size_t
len
=
0
;
for
(;
m_po
+
len
<
m_text
.
size
();
len
++
)
...
...
@@ -375,32 +376,32 @@ class RADIX_PUBLIC JSONParser
m_col
+=
len
;
if
(
std
::
string
(
"true"
)
==
literals
[
i
])
{
return
JsonT
ype
(
true
);
return
value_t
ype
(
true
);
}
else
if
(
std
::
string
(
"false"
)
==
literals
[
i
])
{
return
JsonT
ype
(
false
);
return
value_t
ype
(
false
);
}
// default to null
return
JsonT
ype
();
return
value_t
ype
();
}
}
m_last_error
=
"invalid literal"
;
return
JsonT
ype
();
return
value_t
ype
();
}
//-------------------------------------------------------------------------
JsonT
ype
parse_object
()
value_t
ype
parse_object
()
{
if
(
m_po
>=
m_text
.
size
())
return
JsonT
ype
();
if
(
m_text
[
m_po
]
!=
'{'
)
return
JsonT
ype
();
if
(
m_po
>=
m_text
.
size
())
return
value_t
ype
();
if
(
m_text
[
m_po
]
!=
'{'
)
return
value_t
ype
();
m_po
++
;
m_col
++
;
size_t
line_prev
=
m_line
;
size_t
col_prev
=
m_col
;
bool
trailing_comma
=
false
;
JsonT
ype
parent
=
JsonType
(
DataObject
()
);
value_t
ype
parent
=
object_type
(
);
for
(;
m_po
<
m_text
.
size
();
m_po
++
,
m_col
++
)
{
skip_whitespace
();
...
...
@@ -412,7 +413,7 @@ class RADIX_PUBLIC JSONParser
m_last_error
=
"trailing comma in object"
;
m_line
=
line_prev
;
m_col
=
col_prev
;
return
JsonT
ype
();
return
value_t
ype
();
}
break
;
}
...
...
@@ -427,7 +428,7 @@ class RADIX_PUBLIC JSONParser
m_line
=
line_prev
;
m_col
=
col_prev
;
}
return
JsonT
ype
();
return
value_t
ype
();
}
skip_whitespace
();
...
...
@@ -435,13 +436,13 @@ class RADIX_PUBLIC JSONParser
if
(
m_po
>=
m_text
.
size
()
||
m_text
[
m_po
]
!=
':'
)
{
m_last_error
=
"no ':' following key in object"
;
return
JsonT
ype
();
return
value_t
ype
();
}
m_po
++
;
m_col
++
;
// parse value
JsonT
ype
child
=
parse_value
();
value_t
ype
child
=
parse_value
();
if
(
child
.
is_null
())
{
if
(
m_last_error
==
""
)
...
...
@@ -454,7 +455,7 @@ class RADIX_PUBLIC JSONParser
m_line
=
line_prev
;
m_col
=
col_prev
;
}
return
JsonT
ype
();
return
value_t
ype
();
}
else
{
...
...
@@ -476,13 +477,13 @@ class RADIX_PUBLIC JSONParser
else
{
m_last_error
=
"invalid character in object"
;
return
JsonT
ype
();
return
value_t
ype
();
}
}
if
(
m_po
>=
m_text
.
size
()
||
m_text
[
m_po
]
!=
'}'
)
{
m_last_error
=
"no closing curly bracket '}' for object"
;
return
JsonT
ype
();
return
value_t
ype
();
}
m_po
++
;
m_col
++
;
...
...
@@ -586,19 +587,19 @@ class RADIX_PUBLIC JSONParser
}
//-------------------------------------------------------------------------
JsonT
ype
parse_string
()
value_t
ype
parse_string
()
{
std
::
string
str
=
parse_string_contents
();
if
(
m_last_error
!=
""
)
return
JsonT
ype
();
return
JsonT
ype
(
str
);
if
(
m_last_error
!=
""
)
return
value_t
ype
();
return
value_t
ype
(
str
);
}
//-------------------------------------------------------------------------
JsonT
ype
parse_value
()
value_t
ype
parse_value
()
{
skip_whitespace
();
char
ch
=
m_text
[
m_po
];
JsonT
ype
node
;
value_t
ype
node
;
if
(
ch
==
'"'
)
node
=
parse_string
();
else
if
(
ch
==
'['
)
...
...
@@ -619,7 +620,7 @@ class RADIX_PUBLIC JSONParser
const
char
*
literals
[
N_LITERALS
];
size_t
literal_lens
[
N_LITERALS
];
JsonT
ype
m_root
;
value_t
ype
m_root
;
std
::
string
m_text
=
""
;
...
...
@@ -630,5 +631,8 @@ class RADIX_PUBLIC JSONParser
std
::
string
m_last_error
=
""
;
};
typedef
JSONParserImpl
<
Value
,
DataArray
,
DataObject
>
JSONParser
;
}
// namespace radix
#endif
/** RADIX_RADIXCORE_JSON_HH_ */
radixcore/tests/tstJson.cc
View file @
e4e97de8
#include "gtest/gtest.h"
#include "radixcore/json.hh"
#include "radixcore/value.hh"
#include <QDir>
using
namespace
radix
;
...
...
@@ -15,12 +12,10 @@ using namespace radix;
TEST
(
JSONParser
,
parse_from_file
)
{
QDir
workingDir
(
"."
);
{
JSONParser
<
Value
>
sunnyDay
;
std
::
string
filename
=
workingDir
.
absoluteFilePath
(
"testfiles/wellformed.json"
).
toStdString
();
bool
success
=
sunnyDay
.
parse_from_file
(
filename
);
JSONParser
sunnyDay
;
std
::
string
filename
=
"testfiles/wellformed.json"
;
bool
success
=
sunnyDay
.
parse_from_file
(
filename
);
EXPECT_TRUE
(
success
);
// not really an error just the null terminating at eof
...
...
@@ -53,11 +48,9 @@ TEST(JSONParser, parse_from_file)
EXPECT_TRUE
(
array
.
at
(
3
).
to_bool
());
}
{
JSONParser
<
Value
>
noFile
;
std
::
string
filename
=
workingDir
.
absoluteFilePath
(
"wrong_path/file_doesn't_exist.json"
)
.
toStdString
();
bool
success
=
noFile
.
parse_from_file
(
filename
);
JSONParser
noFile
;
std
::
string
filename
=
"wrong_path/file_doesn't_exist.json"
;
bool
success
=
noFile
.
parse_from_file
(
filename
);
EXPECT_FALSE
(
success
);
std
::
string
errorMsg
=
noFile
.
last_error
();
EXPECT_EQ
(
"could not open file at line 1 column 1"
,
errorMsg
);
...
...
@@ -68,7 +61,7 @@ TEST(JSONParser, parse_from_stream)
{
// check code paths in JSONParser class
{
JSONParser
<
Value
>
jp
;
JSONParser
jp
;
std
::
string
errorMsg
=
""
;
// trailing junk
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment