From ef60ec40c3d2bb8dd847c0d6cc0218cfb9955262 Mon Sep 17 00:00:00 2001 From: Chris Marsh Date: Fri, 28 Jul 2017 10:03:05 -0700 Subject: [PATCH] Do/wrap error checking around json reading --- src/discord-rpc.cpp | 36 ++++++++++++++++++------------------ src/rpc_connection.cpp | 5 ++--- src/serialization.h | 37 +++++++++++++++++++++++++++++++++++++ 3 files changed, 57 insertions(+), 21 deletions(-) diff --git a/src/discord-rpc.cpp b/src/discord-rpc.cpp index a91123f..d667cf8 100644 --- a/src/discord-rpc.cpp +++ b/src/discord-rpc.cpp @@ -100,20 +100,16 @@ extern "C" void Discord_UpdateConnection() break; } - const char* evtName = nullptr; - auto evt = message.FindMember("evt"); - if (evt != message.MemberEnd() && evt->value.IsString()) { - evtName = evt->value.GetString(); - } + const char* evtName = GetStrMember(&message, "evt"); + const char* nonce = GetStrMember(&message, "nonce"); - auto nonce = message.FindMember("nonce"); - if (nonce != message.MemberEnd() && nonce->value.IsString()) { + if (nonce) { // in responses only -- should use to match up response when needed. if (evtName && strcmp(evtName, "ERROR") == 0) { - auto data = message.FindMember("data"); - LastErrorCode = data->value["code"].GetInt(); - StringCopy(LastErrorMessage, data->value["message"].GetString()); + auto data = GetObjMember(&message, "data"); + LastErrorCode = GetIntMember(data, "code"); + StringCopy(LastErrorMessage, GetStrMember(data, "message", "")); GotErrorMessage.store(true); } } @@ -124,16 +120,20 @@ extern "C" void Discord_UpdateConnection() } if (strcmp(evtName, "GAME_JOIN") == 0) { - auto data = message.FindMember("data"); - auto secret = data->value["secret"].GetString(); - StringCopy(JoinGameSecret, secret); - WasJoinGame.store(true); + auto data = GetObjMember(&message, "data"); + auto secret = GetStrMember(data, "secret"); + if (secret) { + StringCopy(JoinGameSecret, secret); + WasJoinGame.store(true); + } } else if (strcmp(evtName, "GAME_SPECTATE") == 0) { - auto data = message.FindMember("data"); - auto secret = data->value["secret"].GetString(); - StringCopy(SpectateGameSecret, secret); - WasSpectateGame.store(true); + auto data = GetObjMember(&message, "data"); + auto secret = GetStrMember(data, "secret"); + if (secret) { + StringCopy(SpectateGameSecret, secret); + WasSpectateGame.store(true); + } } } } diff --git a/src/rpc_connection.cpp b/src/rpc_connection.cpp index b10269b..1ff2d3b 100644 --- a/src/rpc_connection.cpp +++ b/src/rpc_connection.cpp @@ -114,9 +114,8 @@ bool RpcConnection::Read(JsonDocument& message) switch (readFrame.opcode) { case Opcode::Close: { message.ParseInsitu(readFrame.message); - lastErrorCode = message["code"].GetInt(); - const auto& m = message["message"]; - StringCopy(lastErrorMessage, m.GetString()); + lastErrorCode = GetIntMember(&message, "code"); + StringCopy(lastErrorMessage, GetStrMember(&message, "message", "")); Close(); return false; } diff --git a/src/serialization.h b/src/serialization.h index f155b66..172b67b 100644 --- a/src/serialization.h +++ b/src/serialization.h @@ -142,3 +142,40 @@ public: { } }; + +using JsonValue = rapidjson::GenericValue; + +inline JsonValue* GetObjMember(JsonValue* obj, const char* name) +{ + if (obj) { + auto member = obj->FindMember(name); + if (member != obj->MemberEnd() && member->value.IsObject()) { + return &member->value; + } + } + return nullptr; +} + +inline int GetIntMember(JsonValue* obj, const char* name, int notFoundDefault = 0) +{ + if (obj) { + auto member = obj->FindMember(name); + if (member != obj->MemberEnd() && member->value.IsInt()) { + return member->value.GetInt(); + } + } + return notFoundDefault; +} + +inline const char* GetStrMember(JsonValue* obj, + const char* name, + const char* notFoundDefault = nullptr) +{ + if (obj) { + auto member = obj->FindMember(name); + if (member != obj->MemberEnd() && member->value.IsString()) { + return member->value.GetString(); + } + } + return notFoundDefault; +}