Skip to content

Commit cc62dda

Browse files
committed
Use JSONBuilder in WebViewer.cpp for JSON generation
1 parent 36f93bc commit cc62dda

File tree

1 file changed

+91
-68
lines changed

1 file changed

+91
-68
lines changed

Source/Application/WebViewer.cpp

Lines changed: 91 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "NMEA.h"
2121
#include "JSONAIS.h"
2222
#include "Helper.h"
23+
#include "JSONBuilder.h"
2324

2425
IO::OutputMessage *commm_feed = nullptr;
2526

@@ -32,8 +33,8 @@ void SSEStreamer::Receive(const JSON::JSON *data, int len, TAG &tag)
3233

3334
if (!m->NMEA.empty())
3435
{
35-
std::string nmea_array = "[";
36-
bool first = true;
36+
JSON::JSONBuilder nmeaArray;
37+
nmeaArray.startArray();
3738

3839
for (const auto &s : m->NMEA)
3940
{
@@ -61,30 +62,34 @@ void SSEStreamer::Receive(const JSON::JSON *data, int len, TAG &tag)
6162
}
6263
}
6364

64-
if (!first)
65-
nmea_array += ",";
66-
nmea_array += "\"" + nmea + "\"";
67-
first = false;
65+
nmeaArray.value(nmea);
6866
}
69-
nmea_array += "]";
70-
71-
std::string shipname_str;
72-
std::string shipname_escaped(tag.shipname);
73-
JSON::StringBuilder::stringify(shipname_escaped, shipname_str);
74-
75-
std::string json = "{\"mmsi\":" + std::to_string(m->mmsi()) +
76-
",\"timestamp\":" + std::to_string(now) +
77-
",\"channel\":\"" + m->getChannel() +
78-
"\",\"type\":" + std::to_string(m->type()) +
79-
",\"shipname\":" + shipname_str +
80-
",\"nmea\":" + nmea_array + "}";
81-
server->sendSSE(1, "nmea", json);
67+
nmeaArray.endArray();
68+
69+
JSON::JSONBuilder json;
70+
json.start();
71+
json.add("mmsi", m->mmsi());
72+
json.add("timestamp", (long long)now);
73+
json.addString("channel", std::string(1, m->getChannel()));
74+
json.add("type", m->type());
75+
json.addString("shipname", tag.shipname);
76+
json.key("nmea");
77+
json.valueRaw(nmeaArray.take());
78+
json.end();
79+
80+
server->sendSSE(1, "nmea", json.str());
8281
}
8382

8483
if (tag.lat != 0 && tag.lon != 0)
8584
{
86-
std::string json = "{\"mmsi\":" + std::to_string(m->mmsi()) + ",\"channel\":\"" + m->getChannel() + "\",\"lat\":" + std::to_string(tag.lat) + ",\"lon\":" + std::to_string(tag.lon) + "}";
87-
server->sendSSE(2, "nmea", json);
85+
JSON::JSONBuilder json;
86+
json.start();
87+
json.add("mmsi", m->mmsi());
88+
json.addString("channel", std::string(1, m->getChannel()));
89+
json.add("lat", tag.lat);
90+
json.add("lon", tag.lon);
91+
json.end();
92+
server->sendSSE(2, "nmea", json.str());
8893
}
8994
}
9095
}
@@ -632,37 +637,51 @@ void WebViewer::Request(IO::TCPServerConnection &c, const std::string &response,
632637
else if (r == "/api/stat.json" || r == "/stat.json")
633638
{
634639

635-
std::string content;
640+
JSON::JSONBuilder json;
641+
json.start();
642+
643+
json.key("total");
644+
json.valueRaw(counter.toJSON());
645+
json.key("session");
646+
json.valueRaw(counter_session.toJSON());
647+
json.key("last_day");
648+
json.valueRaw(hist_day.lastStatToJSON());
649+
json.key("last_hour");
650+
json.valueRaw(hist_hour.lastStatToJSON());
651+
json.key("last_minute");
652+
json.valueRaw(hist_minute.lastStatToJSON());
653+
json.add("tcp_clients", numberOfClients());
654+
json.addRaw("sharing", commm_feed ? "true" : "false");
636655

637-
content += "{\"total\":" + counter.toJSON() + ",";
638-
content += "\"session\":" + counter_session.toJSON() + ",";
639-
content += "\"last_day\":" + hist_day.lastStatToJSON() + ",";
640-
content += "\"last_hour\":" + hist_hour.lastStatToJSON() + ",";
641-
content += "\"last_minute\":" + hist_minute.lastStatToJSON() + ",";
642-
content += "\"tcp_clients\":" + std::to_string(numberOfClients()) + ",";
643-
content += "\"sharing\":" + std::string(commm_feed ? "true" : "false") + ",";
644656
if (ships.getShareLatLon() && ships.getLat() != LAT_UNDEFINED && ships.getLon() != LON_UNDEFINED)
645-
content += "\"sharing_link\":\"https://www.aiscatcher.org/?&zoom=10&lat=" + std::to_string(ships.getLat()) + "&lon=" + std::to_string(ships.getLon()) + "\",";
657+
{
658+
std::string link = "https://www.aiscatcher.org/?&zoom=10&lat=" + std::to_string(ships.getLat()) + "&lon=" + std::to_string(ships.getLon());
659+
json.addString("sharing_link", link);
660+
}
646661
else
647-
content += "\"sharing_link\":\"https://www.aiscatcher.org\",";
648-
649-
content += "\"station\":" + station + ",";
650-
content += "\"station_link\":" + station_link + ",";
651-
content += "\"sample_rate\":\"" + sample_rate + "\",";
652-
content += "\"msg_rate\":" + std::to_string(hist_second.getAverage()) + ",";
653-
content += "\"vessel_count\":" + std::to_string(ships.getCount()) + ",";
654-
content += "\"vessel_max\":" + std::to_string(ships.getMaxCount()) + ",";
655-
content += "\"product\":\"" + product + "\",";
656-
content += "\"vendor\":\"" + vendor + "\",";
657-
content += "\"serial\":\"" + serial + "\",";
658-
content += "\"model\":\"" + model + "\",";
659-
content += "\"build_date\":\"" + std::string(__DATE__) + "\",";
660-
content += "\"build_version\":\"" + std::string(VERSION) + "\",";
661-
content += "\"build_describe\":\"" + std::string(VERSION_DESCRIBE) + "\",";
662-
content += "\"run_time\":\"" + std::to_string((long int)time(nullptr) - (long int)time_start) + "\",";
663-
content += "\"memory\":" + std::to_string(Util::Helper::getMemoryConsumption()) + ",";
664-
content += "\"os\":" + os + ",";
665-
content += "\"hardware\":" + hardware + ",";
662+
json.addString("sharing_link", "https://www.aiscatcher.org");
663+
664+
json.key("station");
665+
json.valueRaw(station);
666+
json.key("station_link");
667+
json.valueRaw(station_link);
668+
json.addString("sample_rate", sample_rate);
669+
json.add("msg_rate", hist_second.getAverage());
670+
json.add("vessel_count", ships.getCount());
671+
json.add("vessel_max", ships.getMaxCount());
672+
json.addString("product", product);
673+
json.addString("vendor", vendor);
674+
json.addString("serial", serial);
675+
json.addString("model", model);
676+
json.addString("build_date", __DATE__);
677+
json.addString("build_version", VERSION);
678+
json.addString("build_describe", VERSION_DESCRIBE);
679+
json.addString("run_time", std::to_string((long int)time(nullptr) - (long int)time_start));
680+
json.add("memory", Util::Helper::getMemoryConsumption());
681+
json.key("os");
682+
json.valueRaw(os);
683+
json.key("hardware");
684+
json.valueRaw(hardware);
666685

667686
std::string unit;
668687
const uint64_t GB = 1000000000;
@@ -683,9 +702,11 @@ void WebViewer::Request(IO::TCPServerConnection &c, const std::string &response,
683702
int d1 = norm / 10;
684703
int d2 = norm % 10;
685704

686-
content += "\"received\":\"" + std::to_string(d1) + "." + std::to_string(d2) + unit + "\"}";
705+
std::string received = std::to_string(d1) + "." + std::to_string(d2) + unit;
706+
json.addString("received", received);
707+
json.end();
687708

688-
Response(c, "application/json", content, use_zlib & gzip);
709+
Response(c, "application/json", json.str(), use_zlib & gzip);
689710
}
690711
else if (r == "/api/ships.json" || r == "/ships.json")
691712
{
@@ -751,7 +772,8 @@ void WebViewer::Request(IO::TCPServerConnection &c, const std::string &response,
751772
{
752773
std::stringstream ss(a);
753774
std::string mmsi_str;
754-
std::string content = "{";
775+
JSON::JSONBuilder json;
776+
json.start();
755777
int count = 0;
756778
const int MAX_MMSI_COUNT = 100; // Limit number of MMSIs to prevent DoS
757779

@@ -768,9 +790,9 @@ void WebViewer::Request(IO::TCPServerConnection &c, const std::string &response,
768790
int mmsi = std::stoi(mmsi_str);
769791
if (mmsi >= 1 && mmsi <= 999999999)
770792
{
771-
if (content.length() > 1)
772-
content += ",";
773-
content += "\"" + std::to_string(mmsi) + "\":" + ships.getPathJSON(mmsi);
793+
std::string mmsiKey = std::to_string(mmsi);
794+
json.key(mmsiKey);
795+
json.valueRaw(ships.getPathJSON(mmsi));
774796
}
775797
}
776798
catch (const std::invalid_argument &)
@@ -782,8 +804,8 @@ void WebViewer::Request(IO::TCPServerConnection &c, const std::string &response,
782804
Error() << "Server - path MMSI out of range: " << mmsi_str;
783805
}
784806
}
785-
content += "}";
786-
Response(c, "application/json", content, use_zlib & gzip);
807+
json.end();
808+
Response(c, "application/json", json.str(), use_zlib & gzip);
787809
}
788810
else if (r == "/api/allpath.json")
789811
{
@@ -902,18 +924,19 @@ void WebViewer::Request(IO::TCPServerConnection &c, const std::string &response,
902924
else if (r == "/api/history_full.json")
903925
{
904926

905-
std::string content = "{";
906-
content += "\"second\":";
907-
content += hist_second.toJSON();
908-
content += ",\"minute\":";
909-
content += hist_minute.toJSON();
910-
content += ",\"hour\":";
911-
content += hist_hour.toJSON();
912-
content += ",\"day\":";
913-
content += hist_day.toJSON();
914-
content += "}\n\n";
927+
JSON::JSONBuilder json;
928+
json.start();
929+
json.key("second");
930+
json.valueRaw(hist_second.toJSON());
931+
json.key("minute");
932+
json.valueRaw(hist_minute.toJSON());
933+
json.key("hour");
934+
json.valueRaw(hist_hour.toJSON());
935+
json.key("day");
936+
json.valueRaw(hist_day.toJSON());
937+
json.end();
915938

916-
Response(c, "application/json", content, use_zlib & gzip);
939+
Response(c, "application/json", json.str() + "\n\n", use_zlib & gzip);
917940
}
918941
else if (r.substr(0, 6) == "/tiles")
919942
{

0 commit comments

Comments
 (0)