|
2 | 2 |
|
3 | 3 | #include "ncei/models/common.hpp" |
4 | 4 |
|
| 5 | +#include <format> |
| 6 | +#include <iterator> |
5 | 7 | #include <nlohmann/json.hpp> |
6 | | -#include <sstream> |
7 | 8 | #include <utility> |
8 | 9 |
|
9 | 10 | namespace ncei { |
@@ -56,98 +57,55 @@ Result<HttpResponse> CDOClient::do_get(std::string_view path) { |
56 | 57 | } |
57 | 58 |
|
58 | 59 | std::string CDOClient::build_list_query(std::string_view base, const CDOListParams& params) { |
59 | | - std::ostringstream oss; |
60 | | - oss << base; |
| 60 | + std::string url(base); |
| 61 | + url.reserve(url.size() + 256); |
| 62 | + std::back_insert_iterator<std::string> out(url); |
61 | 63 | char sep = '?'; |
62 | 64 |
|
63 | | - if (params.dataset_id) { |
64 | | - oss << sep << "datasetid=" << *params.dataset_id; |
| 65 | + auto append = [&](std::string_view key, const auto& value) { |
| 66 | + std::format_to(out, "{}{}={}", sep, key, value); |
65 | 67 | sep = '&'; |
66 | | - } |
67 | | - if (params.location_id) { |
68 | | - oss << sep << "locationid=" << *params.location_id; |
69 | | - sep = '&'; |
70 | | - } |
71 | | - if (params.station_id) { |
72 | | - oss << sep << "stationid=" << *params.station_id; |
73 | | - sep = '&'; |
74 | | - } |
75 | | - if (params.data_type_id) { |
76 | | - oss << sep << "datatypeid=" << *params.data_type_id; |
77 | | - sep = '&'; |
78 | | - } |
79 | | - if (params.data_category_id) { |
80 | | - oss << sep << "datacategoryid=" << *params.data_category_id; |
81 | | - sep = '&'; |
82 | | - } |
83 | | - if (params.location_category_id) { |
84 | | - oss << sep << "locationcategoryid=" << *params.location_category_id; |
85 | | - sep = '&'; |
86 | | - } |
87 | | - if (params.start_date) { |
88 | | - oss << sep << "startdate=" << *params.start_date; |
89 | | - sep = '&'; |
90 | | - } |
91 | | - if (params.end_date) { |
92 | | - oss << sep << "enddate=" << *params.end_date; |
93 | | - sep = '&'; |
94 | | - } |
95 | | - if (params.sort_field) { |
96 | | - oss << sep << "sortfield=" << *params.sort_field; |
97 | | - sep = '&'; |
98 | | - } |
99 | | - if (params.sort_order) { |
100 | | - oss << sep << "sortorder=" << *params.sort_order; |
101 | | - sep = '&'; |
102 | | - } |
103 | | - if (params.limit) { |
104 | | - oss << sep << "limit=" << *params.limit; |
105 | | - sep = '&'; |
106 | | - } |
107 | | - if (params.offset) { |
108 | | - oss << sep << "offset=" << *params.offset; |
109 | | - sep = '&'; |
110 | | - } |
111 | | - |
112 | | - return oss.str(); |
| 68 | + }; |
| 69 | + |
| 70 | + if (params.dataset_id) append("datasetid", *params.dataset_id); |
| 71 | + if (params.location_id) append("locationid", *params.location_id); |
| 72 | + if (params.station_id) append("stationid", *params.station_id); |
| 73 | + if (params.data_type_id) append("datatypeid", *params.data_type_id); |
| 74 | + if (params.data_category_id) append("datacategoryid", *params.data_category_id); |
| 75 | + if (params.location_category_id) append("locationcategoryid", *params.location_category_id); |
| 76 | + if (params.start_date) append("startdate", *params.start_date); |
| 77 | + if (params.end_date) append("enddate", *params.end_date); |
| 78 | + if (params.sort_field) append("sortfield", *params.sort_field); |
| 79 | + if (params.sort_order) append("sortorder", *params.sort_order); |
| 80 | + if (params.limit) append("limit", *params.limit); |
| 81 | + if (params.offset) append("offset", *params.offset); |
| 82 | + |
| 83 | + return url; |
113 | 84 | } |
114 | 85 |
|
115 | 86 | std::string CDOClient::build_data_query(const GetDataParams& params) { |
116 | | - std::ostringstream oss; |
117 | | - oss << "/data?datasetid=" << params.dataset_id << "&startdate=" << params.start_date |
118 | | - << "&enddate=" << params.end_date; |
| 87 | + std::string url = std::format("/data?datasetid={}&startdate={}&enddate={}", |
| 88 | + params.dataset_id, params.start_date, params.end_date); |
| 89 | + std::back_insert_iterator<std::string> out(url); |
119 | 90 |
|
120 | 91 | if (params.data_type_ids) { |
121 | 92 | for (const std::string& dt : *params.data_type_ids) { |
122 | | - oss << "&datatypeid=" << dt; |
| 93 | + std::format_to(out, "&datatypeid={}", dt); |
123 | 94 | } |
124 | 95 | } |
125 | | - if (params.location_id) { |
126 | | - oss << "&locationid=" << *params.location_id; |
127 | | - } |
128 | | - if (params.station_id) { |
129 | | - oss << "&stationid=" << *params.station_id; |
130 | | - } |
131 | | - if (params.sort_field) { |
132 | | - oss << "&sortfield=" << *params.sort_field; |
133 | | - } |
134 | | - if (params.sort_order) { |
135 | | - oss << "&sortorder=" << *params.sort_order; |
136 | | - } |
137 | | - if (params.limit) { |
138 | | - oss << "&limit=" << *params.limit; |
139 | | - } |
140 | | - if (params.offset) { |
141 | | - oss << "&offset=" << *params.offset; |
142 | | - } |
143 | | - if (params.units) { |
144 | | - oss << "&units=" << *params.units; |
145 | | - } |
| 96 | + if (params.location_id) std::format_to(out, "&locationid={}", *params.location_id); |
| 97 | + if (params.station_id) std::format_to(out, "&stationid={}", *params.station_id); |
| 98 | + if (params.sort_field) std::format_to(out, "&sortfield={}", *params.sort_field); |
| 99 | + if (params.sort_order) std::format_to(out, "&sortorder={}", *params.sort_order); |
| 100 | + if (params.limit) std::format_to(out, "&limit={}", *params.limit); |
| 101 | + if (params.offset) std::format_to(out, "&offset={}", *params.offset); |
| 102 | + if (params.units) std::format_to(out, "&units={}", *params.units); |
146 | 103 | if (params.include_metadata) { |
147 | | - oss << "&includemetadata=" << (*params.include_metadata ? "true" : "false"); |
| 104 | + std::format_to(out, "&includemetadata={}", |
| 105 | + *params.include_metadata ? "true" : "false"); |
148 | 106 | } |
149 | 107 |
|
150 | | - return oss.str(); |
| 108 | + return url; |
151 | 109 | } |
152 | 110 |
|
153 | 111 | namespace { |
|
0 commit comments