Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/src/libsumo/StorageHelper.h
193906 views
1
/****************************************************************************/
2
// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3
// Copyright (C) 2001-2026 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::vector<double> readTypedDoubleList(tcpip::Storage& ret, const std::string& error = "") {
141
if (ret.readUnsignedByte() != libsumo::TYPE_DOUBLELIST && error != "") {
142
throw TraCIException(error);
143
}
144
return ret.readDoubleList();
145
}
146
147
static inline std::string readTypedString(tcpip::Storage& ret, const std::string& error = "") {
148
if (ret.readUnsignedByte() != libsumo::TYPE_STRING && error != "") {
149
throw TraCIException(error);
150
}
151
return ret.readString();
152
}
153
154
static inline std::vector<std::string> readTypedStringList(tcpip::Storage& ret, const std::string& error = "") {
155
if (ret.readUnsignedByte() != libsumo::TYPE_STRINGLIST && error != "") {
156
throw TraCIException(error);
157
}
158
return ret.readStringList();
159
}
160
161
static inline const libsumo::TraCIColor readTypedColor(tcpip::Storage& ret, const std::string& error = "") {
162
if (ret.readUnsignedByte() != libsumo::TYPE_COLOR && error != "") {
163
throw TraCIException(error);
164
}
165
libsumo::TraCIColor into;
166
into.r = static_cast<unsigned char>(ret.readUnsignedByte());
167
into.g = static_cast<unsigned char>(ret.readUnsignedByte());
168
into.b = static_cast<unsigned char>(ret.readUnsignedByte());
169
into.a = static_cast<unsigned char>(ret.readUnsignedByte());
170
return into;
171
}
172
173
static inline const libsumo::TraCIPosition readTypedPosition2D(tcpip::Storage& ret, const std::string& error = "") {
174
if (ret.readUnsignedByte() != libsumo::POSITION_2D && error != "") {
175
throw TraCIException(error);
176
}
177
libsumo::TraCIPosition p;
178
p.x = ret.readDouble();
179
p.y = ret.readDouble();
180
return p;
181
}
182
183
static inline const libsumo::TraCIPositionVector readTypedPolygon(tcpip::Storage& ret, const std::string& error = "") {
184
if (ret.readUnsignedByte() != libsumo::TYPE_POLYGON && error != "") {
185
throw TraCIException(error);
186
}
187
libsumo::TraCIPositionVector poly;
188
readPolygon(ret, poly);
189
return poly;
190
}
191
192
static inline int readCompound(tcpip::Storage& ret, int expectedSize = -1, const std::string& error = "") {
193
const int type = ret.readUnsignedByte();
194
const int size = ret.readInt();
195
if (error != "") {
196
if (type != libsumo::TYPE_COMPOUND || (expectedSize != -1 && size != expectedSize)) {
197
throw TraCIException(error);
198
}
199
}
200
return size;
201
}
202
203
static inline void readPolygon(tcpip::Storage& ret, libsumo::TraCIPositionVector& poly) {
204
int size = ret.readUnsignedByte();
205
if (size == 0) {
206
size = ret.readInt();
207
}
208
for (int i = 0; i < size; ++i) {
209
libsumo::TraCIPosition p;
210
p.x = ret.readDouble();
211
p.y = ret.readDouble();
212
p.z = 0.;
213
poly.value.emplace_back(p);
214
}
215
}
216
217
static inline bool readBool(tcpip::Storage& ret, const std::string& error = "") {
218
if (ret.readUnsignedByte() != libsumo::TYPE_UBYTE && error != "") {
219
throw TraCIException(error);
220
}
221
return ret.readUnsignedByte() != 0;
222
}
223
224
static inline void readStage(tcpip::Storage& inputStorage, libsumo::TraCIStage& stage, const std::string& error = "") {
225
stage.type = readTypedInt(inputStorage, error);
226
stage.vType = readTypedString(inputStorage, error);
227
stage.line = readTypedString(inputStorage, error);
228
stage.destStop = readTypedString(inputStorage, error);
229
stage.edges = readTypedStringList(inputStorage, error);
230
stage.travelTime = readTypedDouble(inputStorage, error);
231
stage.cost = readTypedDouble(inputStorage, error);
232
stage.length = readTypedDouble(inputStorage, error);
233
stage.intended = readTypedString(inputStorage, error);
234
stage.depart = readTypedDouble(inputStorage, error);
235
stage.departPos = readTypedDouble(inputStorage, error);
236
stage.arrivalPos = readTypedDouble(inputStorage, error);
237
stage.description = readTypedString(inputStorage, error);
238
}
239
240
static inline void readConnection(tcpip::Storage& inputStorage, libsumo::TraCIConnection& connection, const std::string& error = "") {
241
connection.approachedLane = readTypedString(inputStorage, error);
242
connection.approachedInternal = readTypedString(inputStorage, error);
243
connection.hasPrio = readBool(inputStorage, error);
244
connection.isOpen = readBool(inputStorage, error);
245
connection.hasFoe = readBool(inputStorage, error);
246
connection.state = readTypedString(inputStorage, error);
247
connection.direction = readTypedString(inputStorage, error);
248
connection.length = readTypedDouble(inputStorage, error);
249
}
250
251
static inline void readVehicleDataVector(tcpip::Storage& inputStorage, std::vector<libsumo::TraCIVehicleData>& result, const std::string& error = "") {
252
const int n = readTypedInt(inputStorage, error);
253
for (int i = 0; i < n; ++i) {
254
libsumo::TraCIVehicleData vd;
255
vd.id = readTypedString(inputStorage, error);
256
vd.length = readTypedDouble(inputStorage, error);
257
vd.entryTime = readTypedDouble(inputStorage, error);
258
vd.leaveTime = readTypedDouble(inputStorage, error);
259
vd.typeID = readTypedString(inputStorage, error);
260
result.emplace_back(vd);
261
}
262
}
263
264
static inline void readReservation(tcpip::Storage& inputStorage, libsumo::TraCIReservation& result, const std::string& error = "") {
265
readCompound(inputStorage, 10, error);
266
result.id = readTypedString(inputStorage, error);
267
result.persons = readTypedStringList(inputStorage, error);
268
result.group = readTypedString(inputStorage, error);
269
result.fromEdge = readTypedString(inputStorage, error);
270
result.toEdge = readTypedString(inputStorage, error);
271
result.departPos = readTypedDouble(inputStorage, error);
272
result.arrivalPos = readTypedDouble(inputStorage, error);
273
result.depart = readTypedDouble(inputStorage, error);
274
result.reservationTime = readTypedDouble(inputStorage, error);
275
result.state = readTypedInt(inputStorage, error);
276
}
277
278
static inline void readLogic(tcpip::Storage& inputStorage, libsumo::TraCILogic& logic, const std::string& error = "") {
279
readCompound(inputStorage, 5, error);
280
logic.programID = readTypedString(inputStorage);
281
logic.type = readTypedInt(inputStorage);
282
logic.currentPhaseIndex = readTypedInt(inputStorage);
283
int numPhases = readCompound(inputStorage);
284
while (numPhases-- > 0) {
285
readCompound(inputStorage, 6);
286
libsumo::TraCIPhase* phase = new libsumo::TraCIPhase();
287
phase->duration = readTypedDouble(inputStorage);
288
phase->state = readTypedString(inputStorage);
289
phase->minDur = readTypedDouble(inputStorage);
290
phase->maxDur = readTypedDouble(inputStorage);
291
int numNext = readCompound(inputStorage);
292
while (numNext-- > 0) {
293
phase->next.push_back(readTypedInt(inputStorage));
294
}
295
phase->name = readTypedString(inputStorage);
296
logic.phases.emplace_back(phase);
297
}
298
int numParams = readCompound(inputStorage);
299
while (numParams-- > 0) {
300
const std::vector<std::string> key_value = readTypedStringList(inputStorage);
301
logic.subParameter[key_value[0]] = key_value[1];
302
}
303
}
304
305
static inline void readConstraintVector(tcpip::Storage& inputStorage, std::vector<libsumo::TraCISignalConstraint>& result, const std::string& error = "") {
306
const int n = readTypedInt(inputStorage, error);
307
for (int i = 0; i < n; ++i) {
308
libsumo::TraCISignalConstraint c;
309
c.signalId = readTypedString(inputStorage);
310
c.tripId = readTypedString(inputStorage);
311
c.foeId = readTypedString(inputStorage);
312
c.foeSignal = readTypedString(inputStorage);
313
c.limit = readTypedInt(inputStorage);
314
c.type = readTypedInt(inputStorage);
315
c.mustWait = readTypedByte(inputStorage) != 0;
316
c.active = readTypedByte(inputStorage) != 0;
317
const std::vector<std::string> paramItems = readTypedStringList(inputStorage);
318
for (int j = 0; j < (int)paramItems.size(); j += 2) {
319
c.param[paramItems[j]] = paramItems[j + 1];
320
}
321
result.emplace_back(c);
322
}
323
}
324
325
static inline void readLinkVectorVector(tcpip::Storage& inputStorage, std::vector< std::vector<libsumo::TraCILink> >& result, const std::string& error = "") {
326
const int n = readTypedInt(inputStorage, error);
327
for (int i = 0; i < n; ++i) {
328
std::vector<libsumo::TraCILink> controlledLinks;
329
int numLinks = readTypedInt(inputStorage);
330
while (numLinks-- > 0) {
331
std::vector<std::string> link = readTypedStringList(inputStorage);
332
controlledLinks.emplace_back(link[0], link[2], link[1]);
333
}
334
result.emplace_back(controlledLinks);
335
}
336
}
337
338
339
static inline void readBestLanesVector(tcpip::Storage& inputStorage, std::vector<libsumo::TraCIBestLanesData>& result, const std::string& error = "") {
340
const int n = readTypedInt(inputStorage, error);
341
for (int i = 0; i < n; ++i) {
342
libsumo::TraCIBestLanesData info;
343
info.laneID = readTypedString(inputStorage);
344
info.length = readTypedDouble(inputStorage);
345
info.occupation = readTypedDouble(inputStorage);
346
info.bestLaneOffset = readTypedUnsignedByte(inputStorage);
347
info.allowsContinuation = readBool(inputStorage);
348
info.continuationLanes = readTypedStringList(inputStorage, error);
349
result.emplace_back(info);
350
}
351
}
352
353
static inline void readCollisionVector(tcpip::Storage& inputStorage, std::vector<libsumo::TraCICollision>& result, const std::string& error = "") {
354
int numCollisions = readTypedInt(inputStorage, error);
355
while (numCollisions-- > 0) {
356
libsumo::TraCICollision c;
357
c.collider = readTypedString(inputStorage);
358
c.victim = readTypedString(inputStorage);
359
c.colliderType = readTypedString(inputStorage);
360
c.victimType = readTypedString(inputStorage);
361
c.colliderSpeed = readTypedDouble(inputStorage);
362
c.victimSpeed = readTypedDouble(inputStorage);
363
c.type = readTypedString(inputStorage);
364
c.lane = readTypedString(inputStorage);
365
c.pos = readTypedDouble(inputStorage);
366
result.emplace_back(c);
367
}
368
}
369
370
static inline void readJunctionFoeVector(tcpip::Storage& inputStorage, std::vector<libsumo::TraCIJunctionFoe>& result, const std::string& error = "") {
371
const int n = readTypedInt(inputStorage, error);
372
for (int i = 0; i < n; ++i) {
373
libsumo::TraCIJunctionFoe info;
374
info.foeId = readTypedString(inputStorage);
375
info.egoDist = readTypedDouble(inputStorage);
376
info.foeDist = readTypedDouble(inputStorage);
377
info.egoExitDist = readTypedDouble(inputStorage);
378
info.foeExitDist = readTypedDouble(inputStorage);
379
info.egoLane = readTypedString(inputStorage);
380
info.foeLane = readTypedString(inputStorage);
381
info.egoResponse = readBool(inputStorage);
382
info.foeResponse = readBool(inputStorage);
383
result.emplace_back(info);
384
}
385
}
386
387
static inline void readStopVector(tcpip::Storage& inputStorage, std::vector<libsumo::TraCINextStopData>& result, const std::string& error = "") {
388
const int n = readTypedInt(inputStorage, error);
389
for (int i = 0; i < n; ++i) {
390
libsumo::TraCINextStopData s;
391
s.lane = readTypedString(inputStorage);
392
s.endPos = readTypedDouble(inputStorage);
393
s.stoppingPlaceID = readTypedString(inputStorage);
394
s.stopFlags = readTypedInt(inputStorage);
395
s.duration = readTypedDouble(inputStorage);
396
s.until = readTypedDouble(inputStorage);
397
s.startPos = readTypedDouble(inputStorage);
398
s.intendedArrival = readTypedDouble(inputStorage);
399
s.arrival = readTypedDouble(inputStorage);
400
s.depart = readTypedDouble(inputStorage);
401
s.split = readTypedString(inputStorage);
402
s.join = readTypedString(inputStorage);
403
s.actType = readTypedString(inputStorage);
404
s.tripId = readTypedString(inputStorage);
405
s.line = readTypedString(inputStorage);
406
s.speed = readTypedDouble(inputStorage);
407
result.emplace_back(s);
408
}
409
}
410
411
static inline void readTLSDataVector(tcpip::Storage& inputStorage, std::vector<libsumo::TraCINextTLSData>& result, const std::string& error = "") {
412
const int n = readTypedInt(inputStorage, error);
413
for (int i = 0; i < n; ++i) {
414
libsumo::TraCINextTLSData tls;
415
tls.id = readTypedString(inputStorage);
416
tls.tlIndex = readTypedInt(inputStorage);
417
tls.dist = readTypedDouble(inputStorage);
418
tls.state = (char)readTypedByte(inputStorage);
419
result.emplace_back(tls);
420
}
421
}
422
423
424
static inline void writeTypedByte(tcpip::Storage& content, int value) {
425
content.writeUnsignedByte(libsumo::TYPE_BYTE);
426
content.writeByte(value);
427
}
428
429
static inline void writeTypedUnsignedByte(tcpip::Storage& content, int value) {
430
content.writeUnsignedByte(libsumo::TYPE_UBYTE);
431
content.writeUnsignedByte(value);
432
}
433
434
static inline void writeTypedInt(tcpip::Storage& content, int value) {
435
content.writeUnsignedByte(libsumo::TYPE_INTEGER);
436
content.writeInt(value);
437
}
438
439
static inline void writeTypedDouble(tcpip::Storage& content, double value) {
440
content.writeUnsignedByte(libsumo::TYPE_DOUBLE);
441
content.writeDouble(value);
442
}
443
444
static inline void writeTypedString(tcpip::Storage& content, const std::string& value) {
445
content.writeUnsignedByte(libsumo::TYPE_STRING);
446
content.writeString(value);
447
}
448
449
static inline void writeTypedStringList(tcpip::Storage& content, const std::vector<std::string>& value) {
450
content.writeUnsignedByte(libsumo::TYPE_STRINGLIST);
451
content.writeStringList(value);
452
}
453
454
static inline void writeCompound(tcpip::Storage& content, int size) {
455
content.writeUnsignedByte(libsumo::TYPE_COMPOUND);
456
content.writeInt(size);
457
}
458
459
static inline void writePolygon(tcpip::Storage& content, const libsumo::TraCIPositionVector& shape) {
460
content.writeUnsignedByte(libsumo::TYPE_POLYGON);
461
if (shape.value.size() <= 255) {
462
content.writeUnsignedByte((int)shape.value.size());
463
} else {
464
content.writeUnsignedByte(0);
465
content.writeInt((int)shape.value.size());
466
}
467
for (const libsumo::TraCIPosition& pos : shape.value) {
468
content.writeDouble(pos.x);
469
content.writeDouble(pos.y);
470
}
471
}
472
473
static inline void writeStage(tcpip::Storage& content, const libsumo::TraCIStage& stage) {
474
writeCompound(content, 13);
475
content.writeUnsignedByte(libsumo::TYPE_INTEGER);
476
content.writeInt(stage.type);
477
writeTypedString(content, stage.vType);
478
writeTypedString(content, stage.line);
479
writeTypedString(content, stage.destStop);
480
writeTypedStringList(content, stage.edges);
481
writeTypedDouble(content, stage.travelTime);
482
writeTypedDouble(content, stage.cost);
483
writeTypedDouble(content, stage.length);
484
writeTypedString(content, stage.intended);
485
writeTypedDouble(content, stage.depart);
486
writeTypedDouble(content, stage.departPos);
487
writeTypedDouble(content, stage.arrivalPos);
488
writeTypedString(content, stage.description);
489
}
490
491
static inline void writeConstraint(tcpip::Storage& content, const libsumo::TraCISignalConstraint& c) {
492
writeTypedString(content, c.signalId);
493
writeTypedString(content, c.tripId);
494
writeTypedString(content, c.foeId);
495
writeTypedString(content, c.foeSignal);
496
writeTypedInt(content, c.limit);
497
writeTypedInt(content, c.type);
498
writeTypedByte(content, c.mustWait);
499
writeTypedByte(content, c.active);
500
std::vector<std::string> paramItems;
501
for (const auto& item : c.param) {
502
paramItems.push_back(item.first);
503
paramItems.push_back(item.second);
504
}
505
writeTypedStringList(content, paramItems);
506
}
507
508
};
509
510
511
}
512
513
typedef libsumo::StorageHelper StoHelp;
514
515