Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2001-2025 German Aerospace Center (DLR) and others.
4 : // This program and the accompanying materials are made available under the
5 : // terms of the Eclipse Public License 2.0 which is available at
6 : // https://www.eclipse.org/legal/epl-2.0/
7 : // This Source Code may also be made available under the following Secondary
8 : // Licenses when the conditions for such availability set forth in the Eclipse
9 : // Public License 2.0 are satisfied: GNU General Public License, version 2
10 : // or later which is available at
11 : // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12 : // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13 : /****************************************************************************/
14 : /// @file StorageHelper.h
15 : /// @author Michael Behrisch
16 : /// @date 2020-12-17
17 : ///
18 : // Functions for reading, writing and converting TraCIResults to tcpip::Storage
19 : /****************************************************************************/
20 : #pragma once
21 : #include <config.h>
22 : #include <foreign/tcpip/storage.h>
23 : #include <libsumo/TraCIDefs.h>
24 : #include <utils/common/ToString.h>
25 :
26 :
27 : // ===========================================================================
28 : // class definitions
29 : // ===========================================================================
30 : namespace libsumo {
31 :
32 : class StorageHelper {
33 : public:
34 333 : static inline std::shared_ptr<tcpip::Storage> toStorage(const TraCIResult& v) {
35 : std::shared_ptr<tcpip::Storage> result = std::make_shared<tcpip::Storage>();
36 333 : if (v.getType() == POSITION_ROADMAP || v.getType() == POSITION_2D || v.getType() == POSITION_3D) {
37 : writeCompound(*result, 2);
38 : }
39 333 : if (v.getType() != -1) {
40 315 : result->writeUnsignedByte(v.getType());
41 : }
42 333 : switch (v.getType()) {
43 : case TYPE_STRING:
44 189 : result->writeString(v.getString());
45 189 : break;
46 : case TYPE_DOUBLE:
47 78 : result->writeDouble(((const TraCIDouble&)v).value);
48 : break;
49 : case TYPE_INTEGER:
50 30 : result->writeInt(((const TraCIInt&)v).value);
51 : break;
52 : case TYPE_BYTE:
53 3 : result->writeByte(((const TraCIInt&)v).value);
54 : break;
55 : case TYPE_UBYTE:
56 3 : result->writeUnsignedByte(((const TraCIInt&)v).value);
57 : break;
58 : case POSITION_ROADMAP:
59 6 : result->writeString(((const TraCIRoadPosition&)v).edgeID);
60 6 : result->writeDouble(((const TraCIRoadPosition&)v).pos);
61 6 : result->writeUnsignedByte(((const TraCIRoadPosition&)v).laneIndex);
62 : break;
63 : case POSITION_2D:
64 6 : result->writeDouble(((const TraCIPosition&)v).x);
65 6 : result->writeDouble(((const TraCIPosition&)v).y);
66 : break;
67 : case POSITION_3D:
68 0 : result->writeDouble(((const TraCIPosition&)v).x);
69 0 : result->writeDouble(((const TraCIPosition&)v).y);
70 0 : result->writeDouble(((const TraCIPosition&)v).z);
71 : break;
72 18 : case -1: {
73 : // a hack for transfering multiple values
74 : const auto& pl = ((const TraCIStringDoublePairList&)v).value;
75 18 : const bool tisb = pl.size() == 2 && pl[0].first != "";
76 18 : writeCompound(*result, pl.size() == 2 && !tisb ? 2 : (int)pl.size() + 1);
77 18 : if (pl.size() == 1) {
78 6 : writeTypedDouble(*result, pl.front().second);
79 6 : writeTypedString(*result, pl.front().first);
80 12 : } else if (pl.size() == 2) {
81 6 : if (tisb) {
82 3 : writeTypedInt(*result, (int)(pl.front().second + 0.5));
83 3 : writeTypedString(*result, pl.front().first);
84 3 : writeTypedByte(*result, (int)(pl.back().second + 0.5));
85 : } else {
86 3 : writeTypedDouble(*result, pl.front().second);
87 3 : writeTypedDouble(*result, pl.back().second);
88 : }
89 6 : } else if (pl.size() == 3) {
90 3 : writeTypedDouble(*result, pl[0].second);
91 3 : writeTypedDouble(*result, pl[1].second);
92 3 : writeTypedDouble(*result, pl[2].second);
93 3 : writeTypedString(*result, pl[2].first);
94 3 : } else if (pl.size() == 4) {
95 3 : writeTypedDouble(*result, pl[0].second);
96 3 : writeTypedDouble(*result, pl[1].second);
97 3 : writeTypedDouble(*result, pl[2].second);
98 3 : writeTypedDouble(*result, pl[3].second);
99 3 : writeTypedString(*result, pl[3].first);
100 : }
101 : break;
102 : }
103 0 : default:
104 0 : throw TraCIException("Unknown type " + toHex(v.getType()));
105 : }
106 333 : if (v.getType() == POSITION_ROADMAP || v.getType() == POSITION_2D || v.getType() == POSITION_3D) {
107 12 : result->writeUnsignedByte(REQUEST_DRIVINGDIST);
108 : }
109 333 : return result;
110 : }
111 :
112 111978 : static inline int readTypedInt(tcpip::Storage& ret, const std::string& error = "") {
113 111978 : if (ret.readUnsignedByte() != libsumo::TYPE_INTEGER && error != "") {
114 8 : throw TraCIException(error);
115 : }
116 111974 : return ret.readInt();
117 : }
118 :
119 3678 : static inline int readTypedByte(tcpip::Storage& ret, const std::string& error = "") {
120 3678 : if (ret.readUnsignedByte() != libsumo::TYPE_BYTE && error != "") {
121 0 : throw TraCIException(error);
122 : }
123 3678 : return ret.readByte();
124 : }
125 :
126 18 : static inline int readTypedUnsignedByte(tcpip::Storage& ret, const std::string& error = "") {
127 18 : if (ret.readUnsignedByte() != libsumo::TYPE_UBYTE && error != "") {
128 0 : throw TraCIException(error);
129 : }
130 18 : return ret.readUnsignedByte();
131 : }
132 :
133 61192 : static inline double readTypedDouble(tcpip::Storage& ret, const std::string& error = "") {
134 61192 : if (ret.readUnsignedByte() != libsumo::TYPE_DOUBLE && error != "") {
135 4 : throw TraCIException(error);
136 : }
137 61190 : return ret.readDouble();
138 : }
139 :
140 79333 : static inline std::string readTypedString(tcpip::Storage& ret, const std::string& error = "") {
141 79333 : if (ret.readUnsignedByte() != libsumo::TYPE_STRING && error != "") {
142 0 : throw TraCIException(error);
143 : }
144 79333 : return ret.readString();
145 : }
146 :
147 2301 : static inline std::vector<std::string> readTypedStringList(tcpip::Storage& ret, const std::string& error = "") {
148 2301 : if (ret.readUnsignedByte() != libsumo::TYPE_STRINGLIST && error != "") {
149 4 : throw TraCIException(error);
150 : }
151 2297 : return ret.readStringList();
152 : }
153 :
154 5096 : static inline int readCompound(tcpip::Storage& ret, int expectedSize = -1, const std::string& error = "") {
155 5096 : const int type = ret.readUnsignedByte();
156 5096 : const int size = ret.readInt();
157 5096 : if (error != "") {
158 2106 : if (type != libsumo::TYPE_COMPOUND || (expectedSize != -1 && size != expectedSize)) {
159 0 : throw TraCIException(error);
160 : }
161 : }
162 5096 : return size;
163 : }
164 :
165 6044 : static inline void readPolygon(tcpip::Storage& ret, libsumo::TraCIPositionVector& poly) {
166 6044 : int size = ret.readUnsignedByte();
167 6044 : if (size == 0) {
168 1 : size = ret.readInt();
169 : }
170 21104 : for (int i = 0; i < size; ++i) {
171 15060 : libsumo::TraCIPosition p;
172 15060 : p.x = ret.readDouble();
173 15060 : p.y = ret.readDouble();
174 15060 : p.z = 0.;
175 15060 : poly.value.emplace_back(p);
176 : }
177 6044 : }
178 :
179 207 : static inline bool readBool(tcpip::Storage& ret, const std::string& error = "") {
180 207 : if (ret.readUnsignedByte() != libsumo::TYPE_UBYTE && error != "") {
181 0 : throw TraCIException(error);
182 : }
183 207 : return ret.readUnsignedByte() != 0;
184 : }
185 :
186 30 : static inline void readStage(tcpip::Storage& inputStorage, libsumo::TraCIStage& stage, const std::string& error = "") {
187 30 : stage.type = readTypedInt(inputStorage, error);
188 30 : stage.vType = readTypedString(inputStorage, error);
189 30 : stage.line = readTypedString(inputStorage, error);
190 30 : stage.destStop = readTypedString(inputStorage, error);
191 30 : stage.edges = readTypedStringList(inputStorage, error);
192 30 : stage.travelTime = readTypedDouble(inputStorage, error);
193 30 : stage.cost = readTypedDouble(inputStorage, error);
194 30 : stage.length = readTypedDouble(inputStorage, error);
195 30 : stage.intended = readTypedString(inputStorage, error);
196 30 : stage.depart = readTypedDouble(inputStorage, error);
197 30 : stage.departPos = readTypedDouble(inputStorage, error);
198 30 : stage.arrivalPos = readTypedDouble(inputStorage, error);
199 30 : stage.description = readTypedString(inputStorage, error);
200 30 : }
201 :
202 33 : static inline void readConnection(tcpip::Storage& inputStorage, libsumo::TraCIConnection& connection, const std::string& error = "") {
203 33 : connection.approachedLane = readTypedString(inputStorage, error);
204 33 : connection.approachedInternal = readTypedString(inputStorage, error);
205 33 : connection.hasPrio = readBool(inputStorage, error);
206 33 : connection.isOpen = readBool(inputStorage, error);
207 33 : connection.hasFoe = readBool(inputStorage, error);
208 33 : connection.state = readTypedString(inputStorage, error);
209 33 : connection.direction = readTypedString(inputStorage, error);
210 33 : connection.length = readTypedDouble(inputStorage, error);
211 33 : }
212 :
213 17426 : static inline void readVehicleDataVector(tcpip::Storage& inputStorage, std::vector<libsumo::TraCIVehicleData>& result, const std::string& error = "") {
214 17426 : const int n = readTypedInt(inputStorage, error);
215 19564 : for (int i = 0; i < n; ++i) {
216 : libsumo::TraCIVehicleData vd;
217 2138 : vd.id = readTypedString(inputStorage, error);
218 2138 : vd.length = readTypedDouble(inputStorage, error);
219 2138 : vd.entryTime = readTypedDouble(inputStorage, error);
220 2138 : vd.leaveTime = readTypedDouble(inputStorage, error);
221 2138 : vd.typeID = readTypedString(inputStorage, error);
222 2138 : result.emplace_back(vd);
223 : }
224 17426 : }
225 :
226 1441 : static inline void readReservation(tcpip::Storage& inputStorage, libsumo::TraCIReservation& result, const std::string& error = "") {
227 1441 : readCompound(inputStorage, 10, error);
228 1441 : result.id = readTypedString(inputStorage, error);
229 1441 : result.persons = readTypedStringList(inputStorage, error);
230 1441 : result.group = readTypedString(inputStorage, error);
231 1441 : result.fromEdge = readTypedString(inputStorage, error);
232 1441 : result.toEdge = readTypedString(inputStorage, error);
233 1441 : result.departPos = readTypedDouble(inputStorage, error);
234 1441 : result.arrivalPos = readTypedDouble(inputStorage, error);
235 1441 : result.depart = readTypedDouble(inputStorage, error);
236 1441 : result.reservationTime = readTypedDouble(inputStorage, error);
237 1441 : result.state = readTypedInt(inputStorage, error);
238 1441 : }
239 :
240 36 : static inline void readLogic(tcpip::Storage& inputStorage, libsumo::TraCILogic& logic, const std::string& error = "") {
241 36 : readCompound(inputStorage, 5, error);
242 36 : logic.programID = readTypedString(inputStorage);
243 36 : logic.type = readTypedInt(inputStorage);
244 36 : logic.currentPhaseIndex = readTypedInt(inputStorage);
245 36 : int numPhases = readCompound(inputStorage);
246 276 : while (numPhases-- > 0) {
247 240 : readCompound(inputStorage, 6);
248 240 : libsumo::TraCIPhase* phase = new libsumo::TraCIPhase();
249 240 : phase->duration = readTypedDouble(inputStorage);
250 240 : phase->state = readTypedString(inputStorage);
251 240 : phase->minDur = readTypedDouble(inputStorage);
252 240 : phase->maxDur = readTypedDouble(inputStorage);
253 240 : int numNext = readCompound(inputStorage);
254 285 : while (numNext-- > 0) {
255 90 : phase->next.push_back(readTypedInt(inputStorage));
256 : }
257 240 : phase->name = readTypedString(inputStorage);
258 240 : logic.phases.emplace_back(phase);
259 : }
260 36 : int numParams = readCompound(inputStorage);
261 39 : while (numParams-- > 0) {
262 6 : const std::vector<std::string> key_value = readTypedStringList(inputStorage);
263 3 : logic.subParameter[key_value[0]] = key_value[1];
264 3 : }
265 36 : }
266 :
267 253 : static inline void readConstraintVector(tcpip::Storage& inputStorage, std::vector<libsumo::TraCISignalConstraint>& result, const std::string& error = "") {
268 253 : const int n = readTypedInt(inputStorage, error);
269 457 : for (int i = 0; i < n; ++i) {
270 : libsumo::TraCISignalConstraint c;
271 204 : c.signalId = readTypedString(inputStorage);
272 204 : c.tripId = readTypedString(inputStorage);
273 204 : c.foeId = readTypedString(inputStorage);
274 204 : c.foeSignal = readTypedString(inputStorage);
275 204 : c.limit = readTypedInt(inputStorage);
276 204 : c.type = readTypedInt(inputStorage);
277 204 : c.mustWait = readTypedByte(inputStorage) != 0;
278 204 : c.active = readTypedByte(inputStorage) != 0;
279 204 : const std::vector<std::string> paramItems = readTypedStringList(inputStorage);
280 300 : for (int j = 0; j < (int)paramItems.size(); j += 2) {
281 96 : c.param[paramItems[j]] = paramItems[j + 1];
282 : }
283 204 : result.emplace_back(c);
284 204 : }
285 253 : }
286 :
287 11 : static inline void readLinkVectorVector(tcpip::Storage& inputStorage, std::vector< std::vector<libsumo::TraCILink> >& result, const std::string& error = "") {
288 11 : const int n = readTypedInt(inputStorage, error);
289 195 : for (int i = 0; i < n; ++i) {
290 : std::vector<libsumo::TraCILink> controlledLinks;
291 184 : int numLinks = readTypedInt(inputStorage);
292 368 : while (numLinks-- > 0) {
293 368 : std::vector<std::string> link = readTypedStringList(inputStorage);
294 184 : controlledLinks.emplace_back(link[0], link[2], link[1]);
295 184 : }
296 184 : result.emplace_back(controlledLinks);
297 184 : }
298 11 : }
299 :
300 :
301 20 : static inline void readBestLanesVector(tcpip::Storage& inputStorage, std::vector<libsumo::TraCIBestLanesData>& result, const std::string& error = "") {
302 20 : const int n = readTypedInt(inputStorage, error);
303 38 : for (int i = 0; i < n; ++i) {
304 : libsumo::TraCIBestLanesData info;
305 18 : info.laneID = readTypedString(inputStorage);
306 18 : info.length = readTypedDouble(inputStorage);
307 18 : info.occupation = readTypedDouble(inputStorage);
308 18 : info.bestLaneOffset = readTypedUnsignedByte(inputStorage);
309 18 : info.allowsContinuation = readBool(inputStorage);
310 18 : info.continuationLanes = readTypedStringList(inputStorage, error);
311 18 : result.emplace_back(info);
312 : }
313 20 : }
314 :
315 70 : static inline void readCollisionVector(tcpip::Storage& inputStorage, std::vector<libsumo::TraCICollision>& result, const std::string& error = "") {
316 70 : int numCollisions = readTypedInt(inputStorage, error);
317 75 : while (numCollisions-- > 0) {
318 : libsumo::TraCICollision c;
319 5 : c.collider = readTypedString(inputStorage);
320 5 : c.victim = readTypedString(inputStorage);
321 5 : c.colliderType = readTypedString(inputStorage);
322 5 : c.victimType = readTypedString(inputStorage);
323 5 : c.colliderSpeed = readTypedDouble(inputStorage);
324 5 : c.victimSpeed = readTypedDouble(inputStorage);
325 5 : c.type = readTypedString(inputStorage);
326 5 : c.lane = readTypedString(inputStorage);
327 5 : c.pos = readTypedDouble(inputStorage);
328 5 : result.emplace_back(c);
329 5 : }
330 70 : }
331 :
332 32 : static inline void readJunctionFoeVector(tcpip::Storage& inputStorage, std::vector<libsumo::TraCIJunctionFoe>& result, const std::string& error = "") {
333 32 : const int n = readTypedInt(inputStorage, error);
334 77 : for (int i = 0; i < n; ++i) {
335 : libsumo::TraCIJunctionFoe info;
336 45 : info.foeId = readTypedString(inputStorage);
337 45 : info.egoDist = readTypedDouble(inputStorage);
338 45 : info.foeDist = readTypedDouble(inputStorage);
339 45 : info.egoExitDist = readTypedDouble(inputStorage);
340 45 : info.foeExitDist = readTypedDouble(inputStorage);
341 45 : info.egoLane = readTypedString(inputStorage);
342 45 : info.foeLane = readTypedString(inputStorage);
343 45 : info.egoResponse = readBool(inputStorage);
344 45 : info.foeResponse = readBool(inputStorage);
345 45 : result.emplace_back(info);
346 45 : }
347 32 : }
348 :
349 630 : static inline void readStopVector(tcpip::Storage& inputStorage, std::vector<libsumo::TraCINextStopData>& result, const std::string& error = "") {
350 630 : const int n = readTypedInt(inputStorage, error);
351 2103 : for (int i = 0; i < n; ++i) {
352 2946 : libsumo::TraCINextStopData s;
353 1473 : s.lane = readTypedString(inputStorage);
354 1473 : s.endPos = readTypedDouble(inputStorage);
355 1473 : s.stoppingPlaceID = readTypedString(inputStorage);
356 1473 : s.stopFlags = readTypedInt(inputStorage);
357 1473 : s.duration = readTypedDouble(inputStorage);
358 1473 : s.until = readTypedDouble(inputStorage);
359 1473 : s.startPos = readTypedDouble(inputStorage);
360 1473 : s.intendedArrival = readTypedDouble(inputStorage);
361 1473 : s.arrival = readTypedDouble(inputStorage);
362 1473 : s.depart = readTypedDouble(inputStorage);
363 1473 : s.split = readTypedString(inputStorage);
364 1473 : s.join = readTypedString(inputStorage);
365 1473 : s.actType = readTypedString(inputStorage);
366 1473 : s.tripId = readTypedString(inputStorage);
367 1473 : s.line = readTypedString(inputStorage);
368 1473 : s.speed = readTypedDouble(inputStorage);
369 1473 : result.emplace_back(s);
370 1473 : }
371 630 : }
372 :
373 275 : static inline void readTLSDataVector(tcpip::Storage& inputStorage, std::vector<libsumo::TraCINextTLSData>& result, const std::string& error = "") {
374 275 : const int n = readTypedInt(inputStorage, error);
375 626 : for (int i = 0; i < n; ++i) {
376 : libsumo::TraCINextTLSData tls;
377 351 : tls.id = readTypedString(inputStorage);
378 351 : tls.tlIndex = readTypedInt(inputStorage);
379 351 : tls.dist = readTypedDouble(inputStorage);
380 351 : tls.state = (char)readTypedByte(inputStorage);
381 351 : result.emplace_back(tls);
382 : }
383 275 : }
384 :
385 :
386 : static inline void writeTypedByte(tcpip::Storage& content, int value) {
387 4488 : content.writeUnsignedByte(libsumo::TYPE_BYTE);
388 5820 : content.writeByte(value);
389 3714 : }
390 :
391 : static inline void writeTypedUnsignedByte(tcpip::Storage& content, int value) {
392 499 : content.writeUnsignedByte(libsumo::TYPE_UBYTE);
393 499 : content.writeUnsignedByte(value);
394 : }
395 :
396 : static inline void writeTypedInt(tcpip::Storage& content, int value) {
397 83210 : content.writeUnsignedByte(libsumo::TYPE_INTEGER);
398 84542 : content.writeInt(value);
399 23582 : }
400 :
401 : static inline void writeTypedDouble(tcpip::Storage& content, double value) {
402 118741 : content.writeUnsignedByte(libsumo::TYPE_DOUBLE);
403 156439 : content.writeDouble(value);
404 21345 : }
405 :
406 : static inline void writeTypedString(tcpip::Storage& content, const std::string& value) {
407 185958 : content.writeUnsignedByte(libsumo::TYPE_STRING);
408 219992 : content.writeString(value);
409 92645 : }
410 :
411 : static inline void writeTypedStringList(tcpip::Storage& content, const std::vector<std::string>& value) {
412 6059 : content.writeUnsignedByte(libsumo::TYPE_STRINGLIST);
413 12342 : content.writeStringList(value);
414 1202 : }
415 :
416 : static inline void writeCompound(tcpip::Storage& content, int size) {
417 85861 : content.writeUnsignedByte(libsumo::TYPE_COMPOUND);
418 92144 : content.writeInt(size);
419 12907 : }
420 :
421 38 : static inline void writePolygon(tcpip::Storage& content, const libsumo::TraCIPositionVector& shape) {
422 38 : content.writeUnsignedByte(libsumo::TYPE_POLYGON);
423 38 : if (shape.value.size() <= 255) {
424 37 : content.writeUnsignedByte((int)shape.value.size());
425 : } else {
426 1 : content.writeUnsignedByte(0);
427 1 : content.writeInt((int)shape.value.size());
428 : }
429 465 : for (const libsumo::TraCIPosition& pos : shape.value) {
430 427 : content.writeDouble(pos.x);
431 427 : content.writeDouble(pos.y);
432 : }
433 38 : }
434 :
435 6283 : static inline void writeStage(tcpip::Storage& content, const libsumo::TraCIStage& stage) {
436 : writeCompound(content, 13);
437 6283 : content.writeUnsignedByte(libsumo::TYPE_INTEGER);
438 6283 : content.writeInt(stage.type);
439 6283 : writeTypedString(content, stage.vType);
440 6283 : writeTypedString(content, stage.line);
441 6283 : writeTypedString(content, stage.destStop);
442 6283 : writeTypedStringList(content, stage.edges);
443 6283 : writeTypedDouble(content, stage.travelTime);
444 6283 : writeTypedDouble(content, stage.cost);
445 6283 : writeTypedDouble(content, stage.length);
446 6283 : writeTypedString(content, stage.intended);
447 6283 : writeTypedDouble(content, stage.depart);
448 6283 : writeTypedDouble(content, stage.departPos);
449 6283 : writeTypedDouble(content, stage.arrivalPos);
450 6283 : writeTypedString(content, stage.description);
451 6283 : }
452 :
453 666 : static inline void writeConstraint(tcpip::Storage& content, const libsumo::TraCISignalConstraint& c) {
454 666 : writeTypedString(content, c.signalId);
455 666 : writeTypedString(content, c.tripId);
456 666 : writeTypedString(content, c.foeId);
457 666 : writeTypedString(content, c.foeSignal);
458 666 : writeTypedInt(content, c.limit);
459 666 : writeTypedInt(content, c.type);
460 666 : writeTypedByte(content, c.mustWait);
461 666 : writeTypedByte(content, c.active);
462 : std::vector<std::string> paramItems;
463 1002 : for (const auto& item : c.param) {
464 336 : paramItems.push_back(item.first);
465 336 : paramItems.push_back(item.second);
466 : }
467 : writeTypedStringList(content, paramItems);
468 666 : }
469 :
470 : };
471 :
472 :
473 : }
474 :
475 : typedef libsumo::StorageHelper StoHelp;
|