Line data Source code
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 <wegener@itm.uni-luebeck.de> **
10 : ** \author Bjoern Hendriks <hendriks@ibr.cs.tu-bs.de> **
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 57742396 : Storage::Storage()
33 : {
34 57742396 : init();
35 57742396 : }
36 :
37 :
38 : // ----------------------------------------------------------------------
39 31859211 : Storage::Storage(const unsigned char packet[], int length)
40 : {
41 : assert(length >= 0); // fixed MB, 2015-04-21
42 :
43 31859211 : store.reserve(length);
44 : // Get the content
45 159296055 : for(int i = 0; i < length; ++i) store.push_back(packet[i]);
46 :
47 31859211 : init();
48 31859211 : }
49 :
50 :
51 : // ----------------------------------------------------------------------
52 89601607 : void Storage::init()
53 : {
54 : // Initialize local variables
55 89601607 : iter_ = store.begin();
56 :
57 : short a = 0x0102;
58 : unsigned char *p_a = reinterpret_cast<unsigned char*>(&a);
59 89601607 : bigEndian_ = (p_a[0] == 0x01); // big endian?
60 89601607 : }
61 :
62 :
63 : // ----------------------------------------------------------------------
64 89601599 : Storage::~Storage()
65 89601599 : {}
66 :
67 :
68 : // ----------------------------------------------------------------------
69 448181194 : bool Storage::valid_pos()
70 : {
71 448181194 : return (iter_ != store.end()); // this implies !store.empty()
72 : }
73 :
74 :
75 : // ----------------------------------------------------------------------
76 52988175 : 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 52988175 : return static_cast<unsigned int>(std::distance(store.begin(), iter_));
81 : }
82 :
83 :
84 : // ----------------------------------------------------------------------
85 132758332 : void Storage::reset() {
86 : store.clear();
87 132758332 : iter_ = store.begin();
88 132758332 : }
89 :
90 :
91 : // ----------------------------------------------------------------------
92 243755 : void Storage::resetPos() {
93 243755 : iter_ = store.begin();
94 243755 : }
95 :
96 :
97 : // ----------------------------------------------------------------------
98 : /**
99 : * Reads a char form the array
100 : * @return The read char (between 0 and 255)
101 : */
102 326388062 : unsigned char Storage::readChar()
103 : {
104 326388062 : if ( !valid_pos() )
105 : {
106 22 : throw std::invalid_argument("Storage::readChar(): invalid position");
107 : }
108 326388040 : return readCharUnsafe();
109 : }
110 :
111 :
112 : // ----------------------------------------------------------------------
113 : /**
114 : *
115 : */
116 394804478 : void Storage::writeChar(unsigned char value)
117 : {
118 394804478 : store.push_back(value);
119 394804478 : iter_ = store.begin();
120 394804478 : }
121 :
122 :
123 : // ----------------------------------------------------------------------
124 : /**
125 : * Reads a byte form the array
126 : * @return The read byte (between -128 and 127)
127 : */
128 30840263 : int Storage::readByte()
129 : {
130 30840263 : int i = static_cast<int>(readChar());
131 30840263 : if (i < 128) return i;
132 2321373 : else return (i - 256);
133 : }
134 :
135 :
136 : // ----------------------------------------------------------------------
137 : /**
138 : *
139 : */
140 28796929 : void Storage::writeByte(int value)
141 : {
142 28796929 : if (value < -128 || value > 127)
143 : {
144 0 : throw std::invalid_argument("Storage::writeByte(): Invalid value, not in [-128, 127]");
145 : }
146 28796929 : writeChar( static_cast<unsigned char>( (value+256) % 256 ) );
147 28796929 : }
148 :
149 :
150 : // ----------------------------------------------------------------------
151 : /**
152 : * Reads an unsigned byte form the array
153 : * @return The read byte (between 0 and 255)
154 : */
155 295546709 : int Storage::readUnsignedByte()
156 : {
157 295546709 : return static_cast<int>(readChar());
158 : }
159 :
160 :
161 : // ----------------------------------------------------------------------
162 : /**
163 : *
164 : */
165 365914171 : void Storage::writeUnsignedByte(int value)
166 : {
167 365914171 : if (value < 0 || value > 255)
168 : {
169 0 : throw std::invalid_argument("Storage::writeUnsignedByte(): Invalid value, not in [0, 255]");
170 : }
171 365914171 : writeChar( static_cast<unsigned char>( value ));
172 365914171 : }
173 :
174 :
175 : // -----------------------------------------------------------------------
176 : /**
177 : * Reads a string form the array
178 : * @return The read string
179 : */
180 41759669 : std::string Storage::readString()
181 : {
182 41759669 : int len = readInt();
183 41759669 : checkReadSafe(len);
184 41759669 : StorageType::const_iterator end = iter_;
185 : std::advance(end, len);
186 41759669 : const std::string tmp(iter_, end);
187 41759669 : iter_ = end;
188 41759669 : return tmp;
189 : }
190 :
191 :
192 : // ----------------------------------------------------------------------
193 : /**
194 : * Writes a string into the array;
195 : * @param s The string to be written
196 : */
197 89611890 : void Storage::writeString(const std::string &s)
198 : {
199 89611890 : writeInt(static_cast<int>(s.length()));
200 :
201 89611890 : store.insert(store.end(), s.begin(), s.end());
202 89611890 : iter_ = store.begin();
203 89611890 : }
204 :
205 :
206 : // -----------------------------------------------------------------------
207 : /**
208 : * Reads a string list form the array
209 : * @return The read string
210 : */
211 81352 : std::vector<std::string> Storage::readStringList()
212 : {
213 : std::vector<std::string> tmp;
214 81352 : const int len = readInt();
215 81352 : tmp.reserve(len);
216 516538 : for (int i = 0; i < len; i++)
217 : {
218 870372 : tmp.push_back(readString());
219 : }
220 81352 : return tmp;
221 0 : }
222 :
223 :
224 : // -----------------------------------------------------------------------
225 : /**
226 : * Reads a double list from the array
227 : * @return The read double list
228 : */
229 206 : std::vector<double> Storage::readDoubleList()
230 : {
231 : std::vector<double> tmp;
232 206 : const int len = readInt();
233 206 : tmp.reserve(len);
234 860 : for (int i = 0; i < len; i++)
235 : {
236 654 : tmp.push_back(readDouble());
237 : }
238 206 : return tmp;
239 0 : }
240 :
241 :
242 : // ----------------------------------------------------------------------
243 : /**
244 : * Writes a string into the array;
245 : * @param s The string to be written
246 : */
247 302092 : void Storage::writeStringList(const std::vector<std::string> &s)
248 : {
249 302092 : writeInt(static_cast<int>(s.size()));
250 1678535 : for (std::vector<std::string>::const_iterator it = s.begin(); it!=s.end() ; it++)
251 : {
252 1376443 : writeString(*it);
253 : }
254 302092 : }
255 :
256 :
257 : // ----------------------------------------------------------------------
258 : /**
259 : * Writes a double list into the array;
260 : * @param s The double list to be written
261 : */
262 18 : void Storage::writeDoubleList(const std::vector<double> &s)
263 : {
264 18 : writeInt(static_cast<int>(s.size()));
265 36 : for (std::vector<double>::const_iterator it = s.begin(); it!=s.end() ; it++)
266 : {
267 18 : writeDouble(*it);
268 : }
269 18 : }
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 0 : int Storage::readShort()
281 : {
282 0 : short value = 0;
283 : unsigned char *p_value = reinterpret_cast<unsigned char*>(&value);
284 0 : readByEndianess(p_value, 2);
285 0 : return value;
286 : }
287 :
288 :
289 : // ----------------------------------------------------------------------
290 0 : void Storage::writeShort( int value )
291 : {
292 0 : if (value < -32768 || value > 32767)
293 : {
294 0 : throw std::invalid_argument("Storage::writeShort(): Invalid value, not in [-32768, 32767]");
295 : }
296 :
297 0 : short svalue = static_cast<short>(value);
298 : unsigned char *p_svalue = reinterpret_cast<unsigned char*>(&svalue);
299 0 : writeByEndianess(p_svalue, 2);
300 0 : }
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 76282081 : int Storage::readInt()
312 : {
313 76282081 : int value = 0;
314 : unsigned char *p_value = reinterpret_cast<unsigned char*>(&value);
315 76282081 : readByEndianess(p_value, 4);
316 76282081 : return value;
317 : }
318 :
319 :
320 : // ----------------------------------------------------------------------
321 145697142 : void Storage::writeInt( int value )
322 : {
323 : unsigned char *p_value = reinterpret_cast<unsigned char*>(&value);
324 145697142 : writeByEndianess(p_value, 4);
325 145697142 : }
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 0 : float Storage::readFloat()
337 : {
338 0 : float value = 0;
339 : unsigned char *p_value = reinterpret_cast<unsigned char*>(&value);
340 0 : readByEndianess(p_value, 4);
341 0 : return value;
342 : }
343 :
344 :
345 : // ----------------------------------------------------------------------
346 0 : void Storage::writeFloat( float value )
347 : {
348 : unsigned char *p_value = reinterpret_cast<unsigned char*>(&value);
349 0 : writeByEndianess(p_value, 4);
350 0 : }
351 :
352 :
353 : // ----------------------------------------------------------------------
354 13211227 : void Storage::writeDouble( double value )
355 : {
356 : unsigned char *p_value = reinterpret_cast<unsigned char*>(&value);
357 13211227 : writeByEndianess(p_value, 8);
358 13211227 : }
359 :
360 :
361 : // ----------------------------------------------------------------------
362 19905636 : double Storage::readDouble( )
363 : {
364 19905636 : double value = 0;
365 : unsigned char *p_value = reinterpret_cast<unsigned char*>(&value);
366 19905636 : readByEndianess(p_value, 8);
367 19905636 : return value;
368 : }
369 :
370 :
371 : // ----------------------------------------------------------------------
372 31859211 : void Storage::writePacket(unsigned char* packet, int length)
373 : {
374 31859211 : store.insert(store.end(), &(packet[0]), &(packet[length]));
375 31859211 : iter_ = store.begin(); // reserve() invalidates iterators
376 31859211 : }
377 :
378 :
379 : // ----------------------------------------------------------------------
380 0 : void Storage::writePacket(const std::vector<unsigned char> &packet)
381 : {
382 0 : std::copy(packet.begin(), packet.end(), std::back_inserter(store));
383 0 : iter_ = store.begin();
384 0 : }
385 :
386 :
387 : // ----------------------------------------------------------------------
388 45970898 : void Storage::writeStorage(tcpip::Storage& other)
389 : {
390 : // the compiler cannot deduce to use a const_iterator as source
391 45970898 : store.insert<StorageType::const_iterator>(store.end(), other.iter_, other.store.end());
392 45970898 : iter_ = store.begin();
393 45970898 : }
394 :
395 :
396 : // ----------------------------------------------------------------------
397 137947386 : void Storage::checkReadSafe(unsigned int num) const
398 : {
399 137947386 : if (std::distance(iter_, store.end()) < static_cast<int>(num))
400 : {
401 0 : std::ostringstream msg;
402 : msg << "tcpip::Storage::readIsSafe: want to read " << num << " bytes from Storage, "
403 0 : << "but only " << std::distance(iter_, store.end()) << " remaining";
404 0 : throw std::invalid_argument(msg.str());
405 0 : }
406 137947386 : }
407 :
408 :
409 : // ----------------------------------------------------------------------
410 790761452 : unsigned char Storage::readCharUnsafe()
411 : {
412 790761452 : const unsigned char hb = *iter_;
413 : ++iter_;
414 790761452 : return hb;
415 : }
416 :
417 :
418 : // ----------------------------------------------------------------------
419 158908369 : void Storage::writeByEndianess(const unsigned char * begin, unsigned int size)
420 : {
421 158908369 : const unsigned char * end = &(begin[size]);
422 158908369 : if (bigEndian_)
423 0 : store.insert(store.end(), begin, end);
424 : else
425 158908369 : store.insert(store.end(), std::reverse_iterator<const unsigned char *>(end), std::reverse_iterator<const unsigned char *>(begin));
426 158908369 : iter_ = store.begin();
427 158908369 : }
428 :
429 :
430 : // ----------------------------------------------------------------------
431 96187717 : void Storage::readByEndianess(unsigned char * array, int size)
432 : {
433 96187717 : checkReadSafe(size);
434 96187717 : if (bigEndian_)
435 : {
436 0 : for (int i = 0; i < size; ++i)
437 0 : array[i] = readCharUnsafe();
438 : }
439 : else
440 : {
441 560561129 : for (int i = size - 1; i >= 0; --i)
442 464373412 : array[i] = readCharUnsafe();
443 : }
444 96187717 : }
445 :
446 :
447 : // ----------------------------------------------------------------------
448 0 : std::string Storage::hexDump() const
449 : {
450 0 : std::ostringstream dump;
451 0 : for(StorageType::const_iterator it = store.begin(); it != store.end(); ++it)
452 : {
453 : // insert spaces between values
454 0 : if (it != store.begin())
455 0 : dump << " ";
456 0 : dump << std::setfill('0') << std::setw(2) << std::hex << static_cast<int>(*it);
457 : }
458 :
459 0 : return dump.str();
460 0 : }
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 : *-----------------------------------------------------------------------*/
|