Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/src/libsumo/StorageHelper.h
169666 views
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
static inline std::shared_ptr<tcpip::Storage> toStorage(const TraCIResult& v) {
35
std::shared_ptr<tcpip::Storage> result = std::make_shared<tcpip::Storage>();
36
if (v.getType() == POSITION_ROADMAP || v.getType() == POSITION_2D || v.getType() == POSITION_3D) {
37
writeCompound(*result, 2);
38
}
39
if (v.getType() != -1) {
40
result->writeUnsignedByte(v.getType());
41
}
42
switch (v.getType()) {
43
case TYPE_STRING:
44
result->writeString(v.getString());
45
break;
46
case TYPE_DOUBLE:
47
result->writeDouble(((const TraCIDouble&)v).value);
48
break;
49
case TYPE_INTEGER:
50
result->writeInt(((const TraCIInt&)v).value);
51
break;
52
case TYPE_BYTE:
53
result->writeByte(((const TraCIInt&)v).value);
54
break;
55
case TYPE_UBYTE:
56
result->writeUnsignedByte(((const TraCIInt&)v).value);
57
break;
58
case POSITION_ROADMAP:
59
result->writeString(((const TraCIRoadPosition&)v).edgeID);
60
result->writeDouble(((const TraCIRoadPosition&)v).pos);
61
result->writeUnsignedByte(((const TraCIRoadPosition&)v).laneIndex);
62
break;
63
case POSITION_2D:
64
result->writeDouble(((const TraCIPosition&)v).x);
65
result->writeDouble(((const TraCIPosition&)v).y);
66
break;
67
case POSITION_3D:
68
result->writeDouble(((const TraCIPosition&)v).x);
69
result->writeDouble(((const TraCIPosition&)v).y);
70
result->writeDouble(((const TraCIPosition&)v).z);
71
break;
72
case -1: {
73
// a hack for transfering multiple values
74
const auto& pl = ((const TraCIStringDoublePairList&)v).value;
75
const bool tisb = pl.size() == 2 && pl[0].first != "";
76
writeCompound(*result, pl.size() == 2 && !tisb ? 2 : (int)pl.size() + 1);
77
if (pl.size() == 1) {
78
writeTypedDouble(*result, pl.front().second);
79
writeTypedString(*result, pl.front().first);
80
} else if (pl.size() == 2) {
81
if (tisb) {
82
writeTypedInt(*result, (int)(pl.front().second + 0.5));
83
writeTypedString(*result, pl.front().first);
84
writeTypedByte(*result, (int)(pl.back().second + 0.5));
85
} else {
86
writeTypedDouble(*result, pl.front().second);
87
writeTypedDouble(*result, pl.back().second);
88
}
89
} else if (pl.size() == 3) {
90
writeTypedDouble(*result, pl[0].second);
91
writeTypedDouble(*result, pl[1].second);
92
writeTypedDouble(*result, pl[2].second);
93
writeTypedString(*result, pl[2].first);
94
} else if (pl.size() == 4) {
95
writeTypedDouble(*result, pl[0].second);
96
writeTypedDouble(*result, pl[1].second);
97
writeTypedDouble(*result, pl[2].second);
98
writeTypedDouble(*result, pl[3].second);
99
writeTypedString(*result, pl[3].first);
100
}
101
break;
102
}
103
default:
104
throw TraCIException("Unknown type " + toHex(v.getType()));
105
}
106
if (v.getType() == POSITION_ROADMAP || v.getType() == POSITION_2D || v.getType() == POSITION_3D) {
107
result->writeUnsignedByte(REQUEST_DRIVINGDIST);
108
}
109
return result;
110
}
111
112
static inline int readTypedInt(tcpip::Storage& ret, const std::string& error = "") {
113
if (ret.readUnsignedByte() != libsumo::TYPE_INTEGER && error != "") {
114
throw TraCIException(error);
115
}
116
return ret.readInt();
117
}
118
119
static inline int readTypedByte(tcpip::Storage& ret, const std::string& error = "") {
120
if (ret.readUnsignedByte() != libsumo::TYPE_BYTE && error != "") {
121
throw TraCIException(error);
122
}
123
return ret.readByte();
124
}
125
126
static inline int readTypedUnsignedByte(tcpip::Storage& ret, const std::string& error = "") {
127
if (ret.readUnsignedByte() != libsumo::TYPE_UBYTE && error != "") {
128
throw TraCIException(error);
129
}
130
return ret.readUnsignedByte();
131
}
132
133
static inline double readTypedDouble(tcpip::Storage& ret, const std::string& error = "") {
134
if (ret.readUnsignedByte() != libsumo::TYPE_DOUBLE && error != "") {
135
throw TraCIException(error);
136
}
137
return ret.readDouble();
138
}
139
140
static inline std::string readTypedString(tcpip::Storage& ret, const std::string& error = "") {
141
if (ret.readUnsignedByte() != libsumo::TYPE_STRING && error != "") {
142
throw TraCIException(error);
143
}
144
return ret.readString();
145
}
146
147
static inline std::vector<std::string> readTypedStringList(tcpip::Storage& ret, const std::string& error = "") {
148
if (ret.readUnsignedByte() != libsumo::TYPE_STRINGLIST && error != "") {
149
throw TraCIException(error);
150
}
151
return ret.readStringList();
152
}
153
154
static inline int readCompound(tcpip::Storage& ret, int expectedSize = -1, const std::string& error = "") {
155
const int type = ret.readUnsignedByte();
156
const int size = ret.readInt();
157
if (error != "") {
158
if (type != libsumo::TYPE_COMPOUND || (expectedSize != -1 && size != expectedSize)) {
159
throw TraCIException(error);
160
}
161
}
162
return size;
163
}
164
165
static inline void readPolygon(tcpip::Storage& ret, libsumo::TraCIPositionVector& poly) {
166
int size = ret.readUnsignedByte();
167
if (size == 0) {
168
size = ret.readInt();
169
}
170
for (int i = 0; i < size; ++i) {
171
libsumo::TraCIPosition p;
172
p.x = ret.readDouble();
173
p.y = ret.readDouble();
174
p.z = 0.;
175
poly.value.emplace_back(p);
176
}
177
}
178
179
static inline bool readBool(tcpip::Storage& ret, const std::string& error = "") {
180
if (ret.readUnsignedByte() != libsumo::TYPE_UBYTE && error != "") {
181
throw TraCIException(error);
182
}
183
return ret.readUnsignedByte() != 0;
184
}
185
186
static inline void readStage(tcpip::Storage& inputStorage, libsumo::TraCIStage& stage, const std::string& error = "") {
187
stage.type = readTypedInt(inputStorage, error);
188
stage.vType = readTypedString(inputStorage, error);
189
stage.line = readTypedString(inputStorage, error);
190
stage.destStop = readTypedString(inputStorage, error);
191
stage.edges = readTypedStringList(inputStorage, error);
192
stage.travelTime = readTypedDouble(inputStorage, error);
193
stage.cost = readTypedDouble(inputStorage, error);
194
stage.length = readTypedDouble(inputStorage, error);
195
stage.intended = readTypedString(inputStorage, error);
196
stage.depart = readTypedDouble(inputStorage, error);
197
stage.departPos = readTypedDouble(inputStorage, error);
198
stage.arrivalPos = readTypedDouble(inputStorage, error);
199
stage.description = readTypedString(inputStorage, error);
200
}
201
202
static inline void readConnection(tcpip::Storage& inputStorage, libsumo::TraCIConnection& connection, const std::string& error = "") {
203
connection.approachedLane = readTypedString(inputStorage, error);
204
connection.approachedInternal = readTypedString(inputStorage, error);
205
connection.hasPrio = readBool(inputStorage, error);
206
connection.isOpen = readBool(inputStorage, error);
207
connection.hasFoe = readBool(inputStorage, error);
208
connection.state = readTypedString(inputStorage, error);
209
connection.direction = readTypedString(inputStorage, error);
210
connection.length = readTypedDouble(inputStorage, error);
211
}
212
213
static inline void readVehicleDataVector(tcpip::Storage& inputStorage, std::vector<libsumo::TraCIVehicleData>& result, const std::string& error = "") {
214
const int n = readTypedInt(inputStorage, error);
215
for (int i = 0; i < n; ++i) {
216
libsumo::TraCIVehicleData vd;
217
vd.id = readTypedString(inputStorage, error);
218
vd.length = readTypedDouble(inputStorage, error);
219
vd.entryTime = readTypedDouble(inputStorage, error);
220
vd.leaveTime = readTypedDouble(inputStorage, error);
221
vd.typeID = readTypedString(inputStorage, error);
222
result.emplace_back(vd);
223
}
224
}
225
226
static inline void readReservation(tcpip::Storage& inputStorage, libsumo::TraCIReservation& result, const std::string& error = "") {
227
readCompound(inputStorage, 10, error);
228
result.id = readTypedString(inputStorage, error);
229
result.persons = readTypedStringList(inputStorage, error);
230
result.group = readTypedString(inputStorage, error);
231
result.fromEdge = readTypedString(inputStorage, error);
232
result.toEdge = readTypedString(inputStorage, error);
233
result.departPos = readTypedDouble(inputStorage, error);
234
result.arrivalPos = readTypedDouble(inputStorage, error);
235
result.depart = readTypedDouble(inputStorage, error);
236
result.reservationTime = readTypedDouble(inputStorage, error);
237
result.state = readTypedInt(inputStorage, error);
238
}
239
240
static inline void readLogic(tcpip::Storage& inputStorage, libsumo::TraCILogic& logic, const std::string& error = "") {
241
readCompound(inputStorage, 5, error);
242
logic.programID = readTypedString(inputStorage);
243
logic.type = readTypedInt(inputStorage);
244
logic.currentPhaseIndex = readTypedInt(inputStorage);
245
int numPhases = readCompound(inputStorage);
246
while (numPhases-- > 0) {
247
readCompound(inputStorage, 6);
248
libsumo::TraCIPhase* phase = new libsumo::TraCIPhase();
249
phase->duration = readTypedDouble(inputStorage);
250
phase->state = readTypedString(inputStorage);
251
phase->minDur = readTypedDouble(inputStorage);
252
phase->maxDur = readTypedDouble(inputStorage);
253
int numNext = readCompound(inputStorage);
254
while (numNext-- > 0) {
255
phase->next.push_back(readTypedInt(inputStorage));
256
}
257
phase->name = readTypedString(inputStorage);
258
logic.phases.emplace_back(phase);
259
}
260
int numParams = readCompound(inputStorage);
261
while (numParams-- > 0) {
262
const std::vector<std::string> key_value = readTypedStringList(inputStorage);
263
logic.subParameter[key_value[0]] = key_value[1];
264
}
265
}
266
267
static inline void readConstraintVector(tcpip::Storage& inputStorage, std::vector<libsumo::TraCISignalConstraint>& result, const std::string& error = "") {
268
const int n = readTypedInt(inputStorage, error);
269
for (int i = 0; i < n; ++i) {
270
libsumo::TraCISignalConstraint c;
271
c.signalId = readTypedString(inputStorage);
272
c.tripId = readTypedString(inputStorage);
273
c.foeId = readTypedString(inputStorage);
274
c.foeSignal = readTypedString(inputStorage);
275
c.limit = readTypedInt(inputStorage);
276
c.type = readTypedInt(inputStorage);
277
c.mustWait = readTypedByte(inputStorage) != 0;
278
c.active = readTypedByte(inputStorage) != 0;
279
const std::vector<std::string> paramItems = readTypedStringList(inputStorage);
280
for (int j = 0; j < (int)paramItems.size(); j += 2) {
281
c.param[paramItems[j]] = paramItems[j + 1];
282
}
283
result.emplace_back(c);
284
}
285
}
286
287
static inline void readLinkVectorVector(tcpip::Storage& inputStorage, std::vector< std::vector<libsumo::TraCILink> >& result, const std::string& error = "") {
288
const int n = readTypedInt(inputStorage, error);
289
for (int i = 0; i < n; ++i) {
290
std::vector<libsumo::TraCILink> controlledLinks;
291
int numLinks = readTypedInt(inputStorage);
292
while (numLinks-- > 0) {
293
std::vector<std::string> link = readTypedStringList(inputStorage);
294
controlledLinks.emplace_back(link[0], link[2], link[1]);
295
}
296
result.emplace_back(controlledLinks);
297
}
298
}
299
300
301
static inline void readBestLanesVector(tcpip::Storage& inputStorage, std::vector<libsumo::TraCIBestLanesData>& result, const std::string& error = "") {
302
const int n = readTypedInt(inputStorage, error);
303
for (int i = 0; i < n; ++i) {
304
libsumo::TraCIBestLanesData info;
305
info.laneID = readTypedString(inputStorage);
306
info.length = readTypedDouble(inputStorage);
307
info.occupation = readTypedDouble(inputStorage);
308
info.bestLaneOffset = readTypedUnsignedByte(inputStorage);
309
info.allowsContinuation = readBool(inputStorage);
310
info.continuationLanes = readTypedStringList(inputStorage, error);
311
result.emplace_back(info);
312
}
313
}
314
315
static inline void readCollisionVector(tcpip::Storage& inputStorage, std::vector<libsumo::TraCICollision>& result, const std::string& error = "") {
316
int numCollisions = readTypedInt(inputStorage, error);
317
while (numCollisions-- > 0) {
318
libsumo::TraCICollision c;
319
c.collider = readTypedString(inputStorage);
320
c.victim = readTypedString(inputStorage);
321
c.colliderType = readTypedString(inputStorage);
322
c.victimType = readTypedString(inputStorage);
323
c.colliderSpeed = readTypedDouble(inputStorage);
324
c.victimSpeed = readTypedDouble(inputStorage);
325
c.type = readTypedString(inputStorage);
326
c.lane = readTypedString(inputStorage);
327
c.pos = readTypedDouble(inputStorage);
328
result.emplace_back(c);
329
}
330
}
331
332
static inline void readJunctionFoeVector(tcpip::Storage& inputStorage, std::vector<libsumo::TraCIJunctionFoe>& result, const std::string& error = "") {
333
const int n = readTypedInt(inputStorage, error);
334
for (int i = 0; i < n; ++i) {
335
libsumo::TraCIJunctionFoe info;
336
info.foeId = readTypedString(inputStorage);
337
info.egoDist = readTypedDouble(inputStorage);
338
info.foeDist = readTypedDouble(inputStorage);
339
info.egoExitDist = readTypedDouble(inputStorage);
340
info.foeExitDist = readTypedDouble(inputStorage);
341
info.egoLane = readTypedString(inputStorage);
342
info.foeLane = readTypedString(inputStorage);
343
info.egoResponse = readBool(inputStorage);
344
info.foeResponse = readBool(inputStorage);
345
result.emplace_back(info);
346
}
347
}
348
349
static inline void readStopVector(tcpip::Storage& inputStorage, std::vector<libsumo::TraCINextStopData>& result, const std::string& error = "") {
350
const int n = readTypedInt(inputStorage, error);
351
for (int i = 0; i < n; ++i) {
352
libsumo::TraCINextStopData s;
353
s.lane = readTypedString(inputStorage);
354
s.endPos = readTypedDouble(inputStorage);
355
s.stoppingPlaceID = readTypedString(inputStorage);
356
s.stopFlags = readTypedInt(inputStorage);
357
s.duration = readTypedDouble(inputStorage);
358
s.until = readTypedDouble(inputStorage);
359
s.startPos = readTypedDouble(inputStorage);
360
s.intendedArrival = readTypedDouble(inputStorage);
361
s.arrival = readTypedDouble(inputStorage);
362
s.depart = readTypedDouble(inputStorage);
363
s.split = readTypedString(inputStorage);
364
s.join = readTypedString(inputStorage);
365
s.actType = readTypedString(inputStorage);
366
s.tripId = readTypedString(inputStorage);
367
s.line = readTypedString(inputStorage);
368
s.speed = readTypedDouble(inputStorage);
369
result.emplace_back(s);
370
}
371
}
372
373
static inline void readTLSDataVector(tcpip::Storage& inputStorage, std::vector<libsumo::TraCINextTLSData>& result, const std::string& error = "") {
374
const int n = readTypedInt(inputStorage, error);
375
for (int i = 0; i < n; ++i) {
376
libsumo::TraCINextTLSData tls;
377
tls.id = readTypedString(inputStorage);
378
tls.tlIndex = readTypedInt(inputStorage);
379
tls.dist = readTypedDouble(inputStorage);
380
tls.state = (char)readTypedByte(inputStorage);
381
result.emplace_back(tls);
382
}
383
}
384
385
386
static inline void writeTypedByte(tcpip::Storage& content, int value) {
387
content.writeUnsignedByte(libsumo::TYPE_BYTE);
388
content.writeByte(value);
389
}
390
391
static inline void writeTypedUnsignedByte(tcpip::Storage& content, int value) {
392
content.writeUnsignedByte(libsumo::TYPE_UBYTE);
393
content.writeUnsignedByte(value);
394
}
395
396
static inline void writeTypedInt(tcpip::Storage& content, int value) {
397
content.writeUnsignedByte(libsumo::TYPE_INTEGER);
398
content.writeInt(value);
399
}
400
401
static inline void writeTypedDouble(tcpip::Storage& content, double value) {
402
content.writeUnsignedByte(libsumo::TYPE_DOUBLE);
403
content.writeDouble(value);
404
}
405
406
static inline void writeTypedString(tcpip::Storage& content, const std::string& value) {
407
content.writeUnsignedByte(libsumo::TYPE_STRING);
408
content.writeString(value);
409
}
410
411
static inline void writeTypedStringList(tcpip::Storage& content, const std::vector<std::string>& value) {
412
content.writeUnsignedByte(libsumo::TYPE_STRINGLIST);
413
content.writeStringList(value);
414
}
415
416
static inline void writeCompound(tcpip::Storage& content, int size) {
417
content.writeUnsignedByte(libsumo::TYPE_COMPOUND);
418
content.writeInt(size);
419
}
420
421
static inline void writePolygon(tcpip::Storage& content, const libsumo::TraCIPositionVector& shape) {
422
content.writeUnsignedByte(libsumo::TYPE_POLYGON);
423
if (shape.value.size() <= 255) {
424
content.writeUnsignedByte((int)shape.value.size());
425
} else {
426
content.writeUnsignedByte(0);
427
content.writeInt((int)shape.value.size());
428
}
429
for (const libsumo::TraCIPosition& pos : shape.value) {
430
content.writeDouble(pos.x);
431
content.writeDouble(pos.y);
432
}
433
}
434
435
static inline void writeStage(tcpip::Storage& content, const libsumo::TraCIStage& stage) {
436
writeCompound(content, 13);
437
content.writeUnsignedByte(libsumo::TYPE_INTEGER);
438
content.writeInt(stage.type);
439
writeTypedString(content, stage.vType);
440
writeTypedString(content, stage.line);
441
writeTypedString(content, stage.destStop);
442
writeTypedStringList(content, stage.edges);
443
writeTypedDouble(content, stage.travelTime);
444
writeTypedDouble(content, stage.cost);
445
writeTypedDouble(content, stage.length);
446
writeTypedString(content, stage.intended);
447
writeTypedDouble(content, stage.depart);
448
writeTypedDouble(content, stage.departPos);
449
writeTypedDouble(content, stage.arrivalPos);
450
writeTypedString(content, stage.description);
451
}
452
453
static inline void writeConstraint(tcpip::Storage& content, const libsumo::TraCISignalConstraint& c) {
454
writeTypedString(content, c.signalId);
455
writeTypedString(content, c.tripId);
456
writeTypedString(content, c.foeId);
457
writeTypedString(content, c.foeSignal);
458
writeTypedInt(content, c.limit);
459
writeTypedInt(content, c.type);
460
writeTypedByte(content, c.mustWait);
461
writeTypedByte(content, c.active);
462
std::vector<std::string> paramItems;
463
for (const auto& item : c.param) {
464
paramItems.push_back(item.first);
465
paramItems.push_back(item.second);
466
}
467
writeTypedStringList(content, paramItems);
468
}
469
470
};
471
472
473
}
474
475
typedef libsumo::StorageHelper StoHelp;
476
477