Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/src/foreign/tcpip/storage.cpp
169678 views
1
/************************************************************************
2
** This file is part of the network simulator Shawn. **
3
** Copyright (C) 2004-2007 by the SwarmNet (www.swarmnet.de) project **
4
** Shawn is free software; you can redistribute it and/or modify it **
5
** under the terms of the BSD License. Refer to the shawn-licence.txt **
6
** file in the root of the Shawn source tree for further details. **
7
************************************************************************
8
** **
9
** \author Axel Wegener <[email protected]> **
10
** \author Bjoern Hendriks <[email protected]> **
11
** **
12
************************************************************************/
13
14
#include "storage.h"
15
16
#ifdef BUILD_TCPIP
17
18
#include <iostream>
19
#include <iterator>
20
#include <sstream>
21
#include <cassert>
22
#include <algorithm>
23
#include <iomanip>
24
25
26
//#define NULLITER static_cast<list<unsigned char>::iterator>(0)
27
28
namespace tcpip
29
{
30
31
// ----------------------------------------------------------------------
32
Storage::Storage()
33
{
34
init();
35
}
36
37
38
// ----------------------------------------------------------------------
39
Storage::Storage(const unsigned char packet[], int length)
40
{
41
assert(length >= 0); // fixed MB, 2015-04-21
42
43
store.reserve(length);
44
// Get the content
45
for(int i = 0; i < length; ++i) store.push_back(packet[i]);
46
47
init();
48
}
49
50
51
// ----------------------------------------------------------------------
52
void Storage::init()
53
{
54
// Initialize local variables
55
iter_ = store.begin();
56
57
short a = 0x0102;
58
unsigned char *p_a = reinterpret_cast<unsigned char*>(&a);
59
bigEndian_ = (p_a[0] == 0x01); // big endian?
60
}
61
62
63
// ----------------------------------------------------------------------
64
Storage::~Storage()
65
{}
66
67
68
// ----------------------------------------------------------------------
69
bool Storage::valid_pos()
70
{
71
return (iter_ != store.end()); // this implies !store.empty()
72
}
73
74
75
// ----------------------------------------------------------------------
76
unsigned int Storage::position() const
77
{
78
// According to C++ standard std::distance will simply compute the iterators
79
// difference for random access iterators as std::vector provides.
80
return static_cast<unsigned int>(std::distance(store.begin(), iter_));
81
}
82
83
84
// ----------------------------------------------------------------------
85
void Storage::reset() {
86
store.clear();
87
iter_ = store.begin();
88
}
89
90
91
// ----------------------------------------------------------------------
92
void Storage::resetPos() {
93
iter_ = store.begin();
94
}
95
96
97
// ----------------------------------------------------------------------
98
/**
99
* Reads a char form the array
100
* @return The read char (between 0 and 255)
101
*/
102
unsigned char Storage::readChar()
103
{
104
if ( !valid_pos() )
105
{
106
throw std::invalid_argument("Storage::readChar(): invalid position");
107
}
108
return readCharUnsafe();
109
}
110
111
112
// ----------------------------------------------------------------------
113
/**
114
*
115
*/
116
void Storage::writeChar(unsigned char value)
117
{
118
store.push_back(value);
119
iter_ = store.begin();
120
}
121
122
123
// ----------------------------------------------------------------------
124
/**
125
* Reads a byte form the array
126
* @return The read byte (between -128 and 127)
127
*/
128
int Storage::readByte()
129
{
130
int i = static_cast<int>(readChar());
131
if (i < 128) return i;
132
else return (i - 256);
133
}
134
135
136
// ----------------------------------------------------------------------
137
/**
138
*
139
*/
140
void Storage::writeByte(int value)
141
{
142
if (value < -128 || value > 127)
143
{
144
throw std::invalid_argument("Storage::writeByte(): Invalid value, not in [-128, 127]");
145
}
146
writeChar( static_cast<unsigned char>( (value+256) % 256 ) );
147
}
148
149
150
// ----------------------------------------------------------------------
151
/**
152
* Reads an unsigned byte form the array
153
* @return The read byte (between 0 and 255)
154
*/
155
int Storage::readUnsignedByte()
156
{
157
return static_cast<int>(readChar());
158
}
159
160
161
// ----------------------------------------------------------------------
162
/**
163
*
164
*/
165
void Storage::writeUnsignedByte(int value)
166
{
167
if (value < 0 || value > 255)
168
{
169
throw std::invalid_argument("Storage::writeUnsignedByte(): Invalid value, not in [0, 255]");
170
}
171
writeChar( static_cast<unsigned char>( value ));
172
}
173
174
175
// -----------------------------------------------------------------------
176
/**
177
* Reads a string form the array
178
* @return The read string
179
*/
180
std::string Storage::readString()
181
{
182
int len = readInt();
183
checkReadSafe(len);
184
StorageType::const_iterator end = iter_;
185
std::advance(end, len);
186
const std::string tmp(iter_, end);
187
iter_ = end;
188
return tmp;
189
}
190
191
192
// ----------------------------------------------------------------------
193
/**
194
* Writes a string into the array;
195
* @param s The string to be written
196
*/
197
void Storage::writeString(const std::string &s)
198
{
199
writeInt(static_cast<int>(s.length()));
200
201
store.insert(store.end(), s.begin(), s.end());
202
iter_ = store.begin();
203
}
204
205
206
// -----------------------------------------------------------------------
207
/**
208
* Reads a string list form the array
209
* @return The read string
210
*/
211
std::vector<std::string> Storage::readStringList()
212
{
213
std::vector<std::string> tmp;
214
const int len = readInt();
215
tmp.reserve(len);
216
for (int i = 0; i < len; i++)
217
{
218
tmp.push_back(readString());
219
}
220
return tmp;
221
}
222
223
224
// -----------------------------------------------------------------------
225
/**
226
* Reads a double list from the array
227
* @return The read double list
228
*/
229
std::vector<double> Storage::readDoubleList()
230
{
231
std::vector<double> tmp;
232
const int len = readInt();
233
tmp.reserve(len);
234
for (int i = 0; i < len; i++)
235
{
236
tmp.push_back(readDouble());
237
}
238
return tmp;
239
}
240
241
242
// ----------------------------------------------------------------------
243
/**
244
* Writes a string into the array;
245
* @param s The string to be written
246
*/
247
void Storage::writeStringList(const std::vector<std::string> &s)
248
{
249
writeInt(static_cast<int>(s.size()));
250
for (std::vector<std::string>::const_iterator it = s.begin(); it!=s.end() ; it++)
251
{
252
writeString(*it);
253
}
254
}
255
256
257
// ----------------------------------------------------------------------
258
/**
259
* Writes a double list into the array;
260
* @param s The double list to be written
261
*/
262
void Storage::writeDoubleList(const std::vector<double> &s)
263
{
264
writeInt(static_cast<int>(s.size()));
265
for (std::vector<double>::const_iterator it = s.begin(); it!=s.end() ; it++)
266
{
267
writeDouble(*it);
268
}
269
}
270
271
272
// ----------------------------------------------------------------------
273
/**
274
* Restores an integer, which was split up in two bytes according to the
275
* specification, it must have been split by its row byte representation
276
* with MSBF-order
277
*
278
* @return the unspoiled integer value (between -32768 and 32767)
279
*/
280
int Storage::readShort()
281
{
282
short value = 0;
283
unsigned char *p_value = reinterpret_cast<unsigned char*>(&value);
284
readByEndianess(p_value, 2);
285
return value;
286
}
287
288
289
// ----------------------------------------------------------------------
290
void Storage::writeShort( int value )
291
{
292
if (value < -32768 || value > 32767)
293
{
294
throw std::invalid_argument("Storage::writeShort(): Invalid value, not in [-32768, 32767]");
295
}
296
297
short svalue = static_cast<short>(value);
298
unsigned char *p_svalue = reinterpret_cast<unsigned char*>(&svalue);
299
writeByEndianess(p_svalue, 2);
300
}
301
302
303
// ----------------------------------------------------------------------
304
/**
305
* restores an integer, which was split up in four bytes acording to the
306
* specification, it must have been split by its row byte representation
307
* with MSBF-order
308
*
309
* @return the unspoiled integer value (between -2.147.483.648 and 2.147.483.647)
310
*/
311
int Storage::readInt()
312
{
313
int value = 0;
314
unsigned char *p_value = reinterpret_cast<unsigned char*>(&value);
315
readByEndianess(p_value, 4);
316
return value;
317
}
318
319
320
// ----------------------------------------------------------------------
321
void Storage::writeInt( int value )
322
{
323
unsigned char *p_value = reinterpret_cast<unsigned char*>(&value);
324
writeByEndianess(p_value, 4);
325
}
326
327
328
// ----------------------------------------------------------------------
329
/**
330
* restores a float , which was split up in four bytes acording to the
331
* specification, it must have been split by its row byte representation
332
* with MSBF-order
333
*
334
* @return the unspoiled float value
335
*/
336
float Storage::readFloat()
337
{
338
float value = 0;
339
unsigned char *p_value = reinterpret_cast<unsigned char*>(&value);
340
readByEndianess(p_value, 4);
341
return value;
342
}
343
344
345
// ----------------------------------------------------------------------
346
void Storage::writeFloat( float value )
347
{
348
unsigned char *p_value = reinterpret_cast<unsigned char*>(&value);
349
writeByEndianess(p_value, 4);
350
}
351
352
353
// ----------------------------------------------------------------------
354
void Storage::writeDouble( double value )
355
{
356
unsigned char *p_value = reinterpret_cast<unsigned char*>(&value);
357
writeByEndianess(p_value, 8);
358
}
359
360
361
// ----------------------------------------------------------------------
362
double Storage::readDouble( )
363
{
364
double value = 0;
365
unsigned char *p_value = reinterpret_cast<unsigned char*>(&value);
366
readByEndianess(p_value, 8);
367
return value;
368
}
369
370
371
// ----------------------------------------------------------------------
372
void Storage::writePacket(unsigned char* packet, int length)
373
{
374
store.insert(store.end(), &(packet[0]), &(packet[length]));
375
iter_ = store.begin(); // reserve() invalidates iterators
376
}
377
378
379
// ----------------------------------------------------------------------
380
void Storage::writePacket(const std::vector<unsigned char> &packet)
381
{
382
std::copy(packet.begin(), packet.end(), std::back_inserter(store));
383
iter_ = store.begin();
384
}
385
386
387
// ----------------------------------------------------------------------
388
void Storage::writeStorage(tcpip::Storage& other)
389
{
390
// the compiler cannot deduce to use a const_iterator as source
391
store.insert<StorageType::const_iterator>(store.end(), other.iter_, other.store.end());
392
iter_ = store.begin();
393
}
394
395
396
// ----------------------------------------------------------------------
397
void Storage::checkReadSafe(unsigned int num) const
398
{
399
if (std::distance(iter_, store.end()) < static_cast<int>(num))
400
{
401
std::ostringstream msg;
402
msg << "tcpip::Storage::readIsSafe: want to read " << num << " bytes from Storage, "
403
<< "but only " << std::distance(iter_, store.end()) << " remaining";
404
throw std::invalid_argument(msg.str());
405
}
406
}
407
408
409
// ----------------------------------------------------------------------
410
unsigned char Storage::readCharUnsafe()
411
{
412
const unsigned char hb = *iter_;
413
++iter_;
414
return hb;
415
}
416
417
418
// ----------------------------------------------------------------------
419
void Storage::writeByEndianess(const unsigned char * begin, unsigned int size)
420
{
421
const unsigned char * end = &(begin[size]);
422
if (bigEndian_)
423
store.insert(store.end(), begin, end);
424
else
425
store.insert(store.end(), std::reverse_iterator<const unsigned char *>(end), std::reverse_iterator<const unsigned char *>(begin));
426
iter_ = store.begin();
427
}
428
429
430
// ----------------------------------------------------------------------
431
void Storage::readByEndianess(unsigned char * array, int size)
432
{
433
checkReadSafe(size);
434
if (bigEndian_)
435
{
436
for (int i = 0; i < size; ++i)
437
array[i] = readCharUnsafe();
438
}
439
else
440
{
441
for (int i = size - 1; i >= 0; --i)
442
array[i] = readCharUnsafe();
443
}
444
}
445
446
447
// ----------------------------------------------------------------------
448
std::string Storage::hexDump() const
449
{
450
std::ostringstream dump;
451
for(StorageType::const_iterator it = store.begin(); it != store.end(); ++it)
452
{
453
// insert spaces between values
454
if (it != store.begin())
455
dump << " ";
456
dump << std::setfill('0') << std::setw(2) << std::hex << static_cast<int>(*it);
457
}
458
459
return dump.str();
460
}
461
462
}
463
464
#endif // BUILD_TCPIP
465
466
/*-----------------------------------------------------------------------
467
* Source $Source: $
468
* Version $Revision: 620 $
469
* Date $Date: 2011-07-08 17:39:10 +0200 (Fri, 08 Jul 2011) $
470
*-----------------------------------------------------------------------
471
* $Log: $
472
*-----------------------------------------------------------------------*/
473
474