Skip to content

Commit 95dc689

Browse files
committed
Adding try_object_begins/ends.
Adding float reading support.
1 parent fc549e0 commit 95dc689

2 files changed

Lines changed: 83 additions & 5 deletions

File tree

includes/sjson/parser.h

Lines changed: 56 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,32 @@ namespace sjson
102102
bool object_begins(const char* having_name) { return read_key(having_name) && read_equal_sign() && object_begins(); }
103103
bool object_ends() { return read_closing_brace(); }
104104

105+
bool try_object_begins(const char* having_name)
106+
{
107+
ParserState s = save_state();
108+
109+
if (!object_begins(having_name))
110+
{
111+
restore_state(s);
112+
return false;
113+
}
114+
115+
return true;
116+
}
117+
118+
bool try_object_ends()
119+
{
120+
ParserState s = save_state();
121+
122+
if (!object_ends())
123+
{
124+
restore_state(s);
125+
return false;
126+
}
127+
128+
return true;
129+
}
130+
105131
bool array_begins() { return read_opening_bracket(); }
106132
bool array_begins(const char* having_name) { return read_key(having_name) && read_equal_sign() && read_opening_bracket(); }
107133
bool array_ends() { return read_closing_bracket(); }
@@ -147,7 +173,8 @@ namespace sjson
147173
// StringView start ^ end ^
148174
bool read(const char* key, StringView& value) { return read_key(key) && read_equal_sign() && read_string(value); }
149175
bool read(const char* key, bool& value) { return read_key(key) && read_equal_sign() && read_bool(value); }
150-
bool read(const char* key, double& value) { return read_key(key) && read_equal_sign() && read_double(value); }
176+
bool read(const char* key, double& value) { return read_key(key) && read_equal_sign() && read_double(&value, nullptr); }
177+
bool read(const char* key, float& value) { return read_key(key) && read_equal_sign() && read_double(nullptr, &value); }
151178
bool read(const char* key, int8_t& value) { return read_key(key) && read_equal_sign() && read_integer(value); }
152179
bool read(const char* key, uint8_t& value) { return read_key(key) && read_equal_sign() && read_integer(value); }
153180
bool read(const char* key, int16_t& value) { return read_key(key) && read_equal_sign() && read_integer(value); }
@@ -221,7 +248,28 @@ namespace sjson
221248
return false;
222249
}
223250

224-
if (read_double(value))
251+
if (read_double(&value, nullptr))
252+
return true;
253+
}
254+
255+
restore_state(s);
256+
value = default_value;
257+
return false;
258+
}
259+
260+
bool try_read(const char* key, float& value, float default_value)
261+
{
262+
ParserState s = save_state();
263+
264+
if (read_key(key) && read_equal_sign())
265+
{
266+
if (try_read_null())
267+
{
268+
value = default_value;
269+
return false;
270+
}
271+
272+
if (read_double(nullptr, &value))
225273
return true;
226274
}
227275

@@ -279,7 +327,7 @@ namespace sjson
279327

280328
for (uint32_t i = 0; i < num_elements; ++i)
281329
{
282-
if (!read_double(values[i]))
330+
if (!read_double(&values[i], nullptr))
283331
return false;
284332

285333
if (i < (num_elements - 1) && !read_comma())
@@ -632,7 +680,7 @@ namespace sjson
632680
return false;
633681
}
634682

635-
bool read_double(double& value)
683+
bool read_double(double* dbl_value, float* flt_value)
636684
{
637685
if (!skip_comments_and_whitespace_fail_if_eof())
638686
return false;
@@ -698,7 +746,10 @@ namespace sjson
698746
slice[length] = '\0';
699747

700748
char* last_used_symbol = nullptr;
701-
value = std::strtod(slice, &last_used_symbol);
749+
if (dbl_value != nullptr)
750+
*dbl_value = std::strtod(slice, &last_used_symbol);
751+
else
752+
*flt_value = std::strtof(slice, &last_used_symbol);
702753

703754
if (last_used_symbol != slice + length)
704755
{

tests/sources/test_parser.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,15 @@ TEST_CASE("Parser Number Reading", "[parser]")
247247
REQUIRE(parser.is_valid());
248248
}
249249

250+
{
251+
Parser parser = parser_from_c_str("key = 123.456789");
252+
float value;
253+
REQUIRE(parser.read("key", value));
254+
REQUIRE(value == 123.456789f);
255+
REQUIRE(parser.eof());
256+
REQUIRE(parser.is_valid());
257+
}
258+
250259
{
251260
Parser parser = parser_from_c_str("key = -123");
252261
int8_t value;
@@ -336,6 +345,24 @@ TEST_CASE("Parser Number Reading", "[parser]")
336345
REQUIRE(parser.eof());
337346
REQUIRE(parser.is_valid());
338347
}
348+
349+
{
350+
Parser parser = parser_from_c_str("bad_key = \"bad\"");
351+
float value = 0.0f;
352+
REQUIRE_FALSE(parser.try_read("key", value, 1.0f));
353+
REQUIRE(value == 1.0f);
354+
REQUIRE_FALSE(parser.eof());
355+
REQUIRE(parser.is_valid());
356+
}
357+
358+
{
359+
Parser parser = parser_from_c_str("key = 2.0");
360+
float value = 0.0f;
361+
REQUIRE(parser.try_read("key", value, 1.0f));
362+
REQUIRE(value == 2.0f);
363+
REQUIRE(parser.eof());
364+
REQUIRE(parser.is_valid());
365+
}
339366
}
340367

341368
TEST_CASE("Parser Array Reading", "[parser]")

0 commit comments

Comments
 (0)