implement getDefault for json::value, this helps correct a flaw in picojson that causes get to fail with an assertion;

pull/72/head
Bryan Biedenkapp 1 year ago
parent 304163ef8b
commit ab32e8c8be

@ -17,6 +17,7 @@
#define __JSON_H__ #define __JSON_H__
#include "common/Defines.h" #include "common/Defines.h"
#include "common/Log.h"
#include <algorithm> #include <algorithm>
#include <cstdio> #include <cstdio>
@ -171,6 +172,8 @@ namespace json
template <typename T> const T &get() const; template <typename T> const T &get() const;
template <typename T> T &get(); template <typename T> T &get();
template <typename T> const T getDefault(T def) const;
template <typename T> T getDefault(T def);
template <typename T> void set(const T &); template <typename T> void set(const T &);
#if PICOJSON_USE_RVALUE_REFERENCE #if PICOJSON_USE_RVALUE_REFERENCE
@ -376,12 +379,22 @@ namespace json
#define GET(ctype, var) \ #define GET(ctype, var) \
template <> inline const ctype &value::get<ctype>() const { \ template <> inline const ctype &value::get<ctype>() const { \
if (!is<ctype>()) ::LogError(LOG_HOST, "JSON ERROR: type mismatch! call is<type>() before get<type>(), type = %s, %s", to_type().c_str(), to_str().c_str()); \
PICOJSON_ASSERT("type mismatch! call is<type>() before get<type>()" && is<ctype>()); \ PICOJSON_ASSERT("type mismatch! call is<type>() before get<type>()" && is<ctype>()); \
return var; \ return var; \
} \ } \
template <> inline ctype &value::get<ctype>() { \ template <> inline ctype &value::get<ctype>() { \
if (!is<ctype>()) ::LogError(LOG_HOST, "JSON ERROR: type mismatch! call is<type>() before get<type>(), type = %s, %s", to_type().c_str(), to_str().c_str()); \
PICOJSON_ASSERT("type mismatch! call is<type>() before get<type>()" && is<ctype>()); \ PICOJSON_ASSERT("type mismatch! call is<type>() before get<type>()" && is<ctype>()); \
return var; \ return var; \
} \
template <> inline const ctype value::getDefault<ctype>(ctype def) const { \
if (!is<ctype>()) return def; \
return var; \
} \
template <> inline ctype value::getDefault<ctype>(ctype def) { \
if (!is<ctype>()) return def; \
return var; \
} }
GET(bool, u_.boolean_) GET(bool, u_.boolean_)

@ -111,12 +111,12 @@ public:
json::array fneAffils = rsp["affiliations"].get<json::array>(); json::array fneAffils = rsp["affiliations"].get<json::array>();
for (auto entry : fneAffils) { for (auto entry : fneAffils) {
json::object peerAffils = entry.get<json::object>(); json::object peerAffils = entry.get<json::object>();
uint32_t peerId = peerAffils["peerId"].get<uint32_t>(); uint32_t peerId = peerAffils["peerId"].getDefault<uint32_t>(0U);
json::array affils = peerAffils["affiliations"].get<json::array>(); json::array affils = peerAffils["affiliations"].get<json::array>();
for (auto pentry : affils) { for (auto pentry : affils) {
json::object peerEntry = pentry.get<json::object>(); json::object peerEntry = pentry.get<json::object>();
uint32_t dstId = peerEntry["dstId"].get<uint32_t>(); uint32_t dstId = peerEntry["dstId"].getDefault<uint32_t>(0U);
uint32_t srcId = peerEntry["srcId"].get<uint32_t>(); uint32_t srcId = peerEntry["srcId"].getDefault<uint32_t>(0U);
// pad peer IDs properly // pad peer IDs properly
std::ostringstream peerOss; std::ostringstream peerOss;

@ -111,11 +111,11 @@ public:
json::array fnePeers = rsp["peers"].get<json::array>(); json::array fnePeers = rsp["peers"].get<json::array>();
for (auto entry : fnePeers) { for (auto entry : fnePeers) {
json::object peerObj = entry.get<json::object>(); json::object peerObj = entry.get<json::object>();
uint32_t peerId = peerObj["peerId"].get<uint32_t>(); uint32_t peerId = peerObj["peerId"].getDefault<uint32_t>(0U);
std::string peerAddress = peerObj["address"].get<std::string>(); std::string peerAddress = peerObj["address"].getDefault<std::string>("");
uint16_t port = (uint16_t)peerObj["port"].get<uint32_t>(); uint16_t port = (uint16_t)peerObj["port"].getDefault<uint32_t>(0U);
bool connected = peerObj["connected"].get<bool>(); bool connected = peerObj["connected"].getDefault<bool>(false);
uint32_t connectionState = (uint32_t)peerObj["connectionState"].get<uint32_t>(); uint32_t connectionState = (uint32_t)peerObj["connectionState"].getDefault<uint32_t>(0U);
std::string strConnState = ""; std::string strConnState = "";
switch (connectionState) { switch (connectionState) {
case network::NET_CONN_STATUS::NET_STAT_RUNNING: case network::NET_CONN_STATUS::NET_STAT_RUNNING:
@ -135,25 +135,25 @@ public:
break; break;
} }
uint32_t pingsReceived = (uint32_t)peerObj["pingsReceived"].get<uint32_t>(); uint32_t pingsReceived = (uint32_t)peerObj["pingsReceived"].getDefault<uint32_t>(0U);
uint64_t lastPing = (uint64_t)peerObj["lastPing"].get<uint32_t>(); uint64_t lastPing = (uint64_t)peerObj["lastPing"].getDefault<uint32_t>(0U);
uint32_t ccPeerId = (uint32_t)peerObj["controlChannel"].get<uint32_t>(); uint32_t ccPeerId = (uint32_t)peerObj["controlChannel"].getDefault<uint32_t>(0U);
json::array voiceChannels = peerObj["voiceChannels"].get<json::array>(); json::array voiceChannels = peerObj["voiceChannels"].get<json::array>();
std::vector<uint32_t> voiceChannelPeers; std::vector<uint32_t> voiceChannelPeers;
for (auto vcEntry : voiceChannels) { for (auto vcEntry : voiceChannels) {
uint32_t vcPeerId = vcEntry.get<uint32_t>(); uint32_t vcPeerId = vcEntry.getDefault<uint32_t>(0U);
voiceChannelPeers.push_back(vcPeerId); voiceChannelPeers.push_back(vcPeerId);
} }
json::object peerConfig = peerObj["config"].get<json::object>(); json::object peerConfig = peerObj["config"].get<json::object>();
std::string identity = peerConfig["identity"].get<std::string>(); std::string identity = peerConfig["identity"].getDefault<std::string>("");
std::string software = peerConfig["software"].get<std::string>(); std::string software = peerConfig["software"].getDefault<std::string>("");
json::object channel = peerConfig["channel"].get<json::object>(); json::object channel = peerConfig["channel"].get<json::object>();
uint32_t chNo = (uint32_t)channel["channelNo"].get<int>(); uint32_t chNo = (uint32_t)channel["channelNo"].getDefault<int>(1);
uint8_t chId = channel["channelId"].get<uint8_t>(); uint8_t chId = channel["channelId"].getDefault<uint8_t>(0U);
g_peerIdentityNameMap[peerId] = std::string(identity); g_peerIdentityNameMap[peerId] = std::string(identity);

Loading…
Cancel
Save

Powered by TurnKey Linux.