2020#include " NMEA.h"
2121#include " JSONAIS.h"
2222#include " Helper.h"
23+ #include " JSONBuilder.h"
2324
2425IO::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