Add error handling to yyjson

This commit is contained in:
John Keiser 2021-01-04 13:05:08 -08:00
parent 25d1c7e622
commit 5583a3c89b
5 changed files with 33 additions and 5 deletions

View File

@ -13,21 +13,28 @@ public:
yyjson_doc *doc = yyjson_read(json.data(), json.size(), 0);
if (!doc) { return false; }
yyjson_val *root = yyjson_doc_get_root(doc);
if (!yyjson_is_obj(root)) { return false; }
yyjson_val *statuses = yyjson_obj_get(root, "statuses");
if (!yyjson_is_arr(statuses)) { return "Statuses is not an array!"; }
size_t tweet_idx, tweets_max;
yyjson_val *tweet;
yyjson_arr_foreach(statuses, tweet_idx, tweets_max, tweet) {
auto user = yyjson_obj_get(tweet, "user");
if (!yyjson_is_obj(user)) { return false; }
auto id = yyjson_obj_get(user, "id");
ids.push_back(yyjson_get_sint(id));
if (!yyjson_is_uint(id)) { return false; }
ids.push_back(yyjson_get_uint(id));
// Not all tweets have a "retweeted_status", but when they do
// we want to go and find the user within.
auto retweet = yyjson_obj_get(tweet, "retweeted_status");
if (retweet) {
if (!yyjson_is_obj(retweet)) { return false; }
user = yyjson_obj_get(retweet, "user");
if (!yyjson_is_obj(user)) { return false; }
id = yyjson_obj_get(user, "id");
if (!yyjson_is_uint(id)) { return false; }
ids.push_back(yyjson_get_sint(id));
}
}

View File

@ -20,14 +20,19 @@ public:
yyjson_doc *doc = yyjson_read(json.data(), json.size(), 0);
if (!doc) { return false; }
yyjson_val *root = yyjson_doc_get_root(doc);
if (!yyjson_is_obj(root)) { return false; }
yyjson_val *statuses = yyjson_obj_get(root, "statuses");
if (!yyjson_is_arr(statuses)) { return "Statuses is not an array!"; }
size_t tweet_idx, tweets_max;
yyjson_val *tweet;
yyjson_arr_foreach(statuses, tweet_idx, tweets_max, tweet) {
if (!yyjson_is_obj(tweet)) { return false; }
auto id = yyjson_obj_get(tweet, "id");
if (!yyjson_is_uint(id)) { return false; }
if (yyjson_get_uint(id) == find_id) {
auto _text = yyjson_obj_get(tweet, "text");
if (yyjson_is_str(id)) { return false; }
text = yyjson_get_str(_text);
return true;
}

View File

@ -9,7 +9,8 @@ namespace kostya {
class yyjson {
simdjson_really_inline double get_double(yyjson_val *obj, std::string_view key) {
yyjson_val *val = yyjson_obj_getn(obj, key.data(), key.length());
if (yyjson_get_type(val) != YYJSON_TYPE_NUM) { return 0; }
if (!val){ throw "missing point field!"; }
if (yyjson_get_type(val) != YYJSON_TYPE_NUM) { throw "Number is not a type!"; }
switch (yyjson_get_subtype(val)) {
case YYJSON_SUBTYPE_UINT:
@ -19,7 +20,7 @@ class yyjson {
case YYJSON_SUBTYPE_REAL:
return yyjson_get_real(val);
default:
return 0;
SIMDJSON_UNREACHABLE();
}
}
@ -28,11 +29,14 @@ public:
yyjson_doc *doc = yyjson_read(json.data(), json.size(), 0);
if (!doc) { return false; }
yyjson_val *root = yyjson_doc_get_root(doc);
if (!yyjson_is_obj(root)) { return false; }
yyjson_val *coords = yyjson_obj_get(root, "coordinates");
if (!yyjson_is_obj(coords)) { return false; }
size_t idx, max;
yyjson_val *coord;
yyjson_arr_foreach(coords, idx, max, coord) {
if (!yyjson_is_obj(coord)) { return false; }
points.emplace_back(point{get_double(coord, "x"), get_double(coord, "y"), get_double(coord, "z")});
}

View File

@ -11,7 +11,8 @@ class yyjson {
simdjson_really_inline double get_double(yyjson_val *obj, std::string_view key) {
yyjson_val *val = yyjson_obj_getn(obj, key.data(), key.length());
if (yyjson_get_type(val) != YYJSON_TYPE_NUM) { return 0; }
if (!val){ throw "missing point field!"; }
if (yyjson_get_type(val) != YYJSON_TYPE_NUM) { throw "Number is not a type!"; }
switch (yyjson_get_subtype(val)) {
case YYJSON_SUBTYPE_UINT:
@ -21,7 +22,7 @@ class yyjson {
case YYJSON_SUBTYPE_REAL:
return yyjson_get_real(val);
default:
return 0;
SIMDJSON_UNREACHABLE();
}
}
@ -31,10 +32,12 @@ public:
yyjson_doc *doc = yyjson_read(json.data(), json.size(), 0);
if (!doc) { return false; }
yyjson_val *coords = yyjson_doc_get_root(doc);
if (!yyjson_is_arr(coords)) { return false; }
size_t idx, max;
yyjson_val *coord;
yyjson_arr_foreach(coords, idx, max, coord) {
if (!yyjson_is_obj(coord)) { return false; }
points.emplace_back(point{get_double(coord, "x"), get_double(coord, "y"), get_double(coord, "z")});
}
return true;

View File

@ -11,18 +11,24 @@ class yyjson {
simdjson_really_inline std::string_view get_string_view(yyjson_val *obj, std::string_view key) {
auto val = yyjson_obj_getn(obj, key.data(), key.length());
if (!yyjson_is_str(val)) { throw "field is not uint64 or null!"; }
return { yyjson_get_str(val), yyjson_get_len(val) };
}
simdjson_really_inline uint64_t get_uint64(yyjson_val *obj, std::string_view key) {
auto val = yyjson_obj_getn(obj, key.data(), key.length());
if (!yyjson_is_uint(val)) { throw "field is not uint64 or null!"; }
return yyjson_get_uint(val);
}
simdjson_really_inline uint64_t get_nullable_uint64(yyjson_val *obj, std::string_view key) {
auto val = yyjson_obj_getn(obj, key.data(), key.length());
if (!yyjson_is_uint(val)) { }
auto type = yyjson_get_type(val);
if (type != YYJSON_TYPE_NUM && type != YYJSON_TYPE_NULL ) { throw "field is not uint64 or null!"; }
return yyjson_get_uint(val);
}
simdjson_really_inline partial_tweets::twitter_user get_user(yyjson_val *obj, std::string_view key) {
auto user = yyjson_obj_getn(obj, key.data(), key.length());
if (!yyjson_is_obj(user)) { throw "missing twitter user field!"; }
return { get_uint64(user, "id"), get_string_view(user, "screen_name") };
}
@ -32,11 +38,14 @@ public:
yyjson_doc *doc = yyjson_read(json.data(), json.size(), 0);
if (!doc) { return false; }
yyjson_val *root = yyjson_doc_get_root(doc);
if (!yyjson_is_obj(root)) { return false; }
yyjson_val *statuses = yyjson_obj_get(root, "statuses");
if (!yyjson_is_arr(statuses)) { return "Statuses is not an array!"; }
size_t tweet_idx, tweets_max;
yyjson_val *tweet;
yyjson_arr_foreach(statuses, tweet_idx, tweets_max, tweet) {
if (!yyjson_is_obj(tweet)) { return false; }
// TODO these can't actually handle errors
tweets.emplace_back(partial_tweets::tweet{
get_string_view(tweet, "created_at"),