View | Details | Raw Unified | Return to bug 2952
Collapse All | Expand All

(-)a/src/network/test/bit-serializer-test.cc (+124 lines)
Line 0    Link Here 
1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2
/*
3
 * Copyright (c) 2006,2007 INRIA
4
 *
5
 * This program is free software; you can redistribute it and/or modify
6
 * it under the terms of the GNU General Public License version 2 as
7
 * published by the Free Software Foundation;
8
 *
9
 * This program is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 * GNU General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU General Public License
15
 * along with this program; if not, write to the Free Software
16
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17
 *
18
 * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
19
 */
20
#include <cstdarg>
21
#include <iostream>
22
#include <sstream>
23
#include "ns3/test.h"
24
#include "ns3/bit-serializer.h"
25
#include "ns3/bit-deserializer.h"
26
27
using namespace ns3;
28
29
/**
30
 * \ingroup network-test
31
 * \ingroup tests
32
 *
33
 * \brief Bit serialization test
34
 */
35
class BitSerializerTest : public TestCase {
36
public:
37
  virtual void DoRun (void);
38
  BitSerializerTest ();
39
};
40
41
BitSerializerTest::BitSerializerTest ()
42
  : TestCase ("BitSerializer") {
43
}
44
45
void BitSerializerTest::DoRun ()
46
{
47
  BitSerializer testBitSerializer1;
48
49
  testBitSerializer1.PushBits (0x55, 7);
50
  testBitSerializer1.PushBits (0x7, 3);
51
  testBitSerializer1.PushBits (0x0, 2);
52
53
  std::vector<uint8_t> result = testBitSerializer1.GetBytes ();
54
  NS_TEST_EXPECT_MSG_EQ ((result[0] == 0xab) && (result[1] == 0xc0), true,
55
                         "Incorrect serialization " << result[0] << result[1] << " instead of " << int(0xab) << " " << int(0xc0));
56
57
  BitSerializer testBitSerializer2;
58
59
  testBitSerializer2.PushBits (0x55, 7);
60
  testBitSerializer2.PushBits (0x7, 3);
61
  testBitSerializer2.PushBits (0x0, 2);
62
63
  testBitSerializer2.InsertPaddingAtEnd (false);
64
65
  result = testBitSerializer2.GetBytes ();
66
  NS_TEST_EXPECT_MSG_EQ ((result[0] == 0x0a) && (result[1] == 0xbc), true,
67
                         "Incorrect serialization " << result[0] << result[1] << " instead of " << int(0x0a) << " " << int(0xbc));
68
}
69
70
/**
71
 * \ingroup network-test
72
 * \ingroup tests
73
 *
74
 * \brief Bit deserialization test
75
 */
76
class BitDeserializerTest : public TestCase {
77
public:
78
  virtual void DoRun (void);
79
  BitDeserializerTest ();
80
};
81
82
BitDeserializerTest::BitDeserializerTest ()
83
  : TestCase ("BitDeserializer") {
84
}
85
86
void BitDeserializerTest::DoRun ()
87
{
88
  BitDeserializer testBitDeserializer;
89
  uint8_t test[2];
90
  test[0] = 0xab;
91
  test[1] = 0xc0;
92
93
  testBitDeserializer.PushBytes (test,2);
94
  uint16_t nibble1 = testBitDeserializer.GetBits (7);
95
  uint16_t nibble2 = testBitDeserializer.GetBits (3);
96
  uint16_t nibble3 = testBitDeserializer.GetBits (2);
97
98
  bool result = (nibble1 == 0x55) && (nibble2 == 0x7) && (nibble3 == 0x0);
99
  NS_TEST_EXPECT_MSG_EQ (result, true,
100
                         "Incorrect deserialization " << nibble1 << " " << nibble2 << " " << nibble3 <<
101
                         " << instead of " << " " << int(0x55) << " " << int(0x7) << " " << int(0x0));
102
}
103
104
/**
105
 * \ingroup network-test
106
 * \ingroup tests
107
 *
108
 * \brief Packet Metadata TestSuite
109
 */
110
class BitSerializerTestSuite : public TestSuite
111
{
112
public:
113
  BitSerializerTestSuite ();
114
};
115
116
117
BitSerializerTestSuite::BitSerializerTestSuite ()
118
  : TestSuite ("bit-serializer", UNIT)
119
{
120
  AddTestCase (new BitSerializerTest, TestCase::QUICK);
121
  AddTestCase (new BitDeserializerTest, TestCase::QUICK);
122
}
123
124
static BitSerializerTestSuite g_bitSerializerTest; //!< Static variable for test initialization
(-)a/src/network/utils/bit-deserializer.cc (+92 lines)
Line 0    Link Here 
1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2
/*
3
 * Copyright (c) 2018 Universita' di Firenze, Italy
4
 *
5
 * This program is free software; you can redistribute it and/or modify
6
 * it under the terms of the GNU General Public License version 2 as
7
 * published by the Free Software Foundation;
8
 *
9
 * This program is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 * GNU General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU General Public License
15
 * along with this program; if not, write to the Free Software
16
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17
 *
18
 * Author: Tommaso Pecorella <tommaso.pecorella@unifi.it>
19
 */
20
21
#include <iostream>
22
#include "bit-deserializer.h"
23
#include "ns3/log.h"
24
#include "ns3/assert.h"
25
26
namespace ns3 {
27
28
NS_LOG_COMPONENT_DEFINE ("BitDeserializer");
29
30
BitDeserializer::BitDeserializer ()
31
{
32
  m_deserializing = false;
33
}
34
35
void BitDeserializer::PushBytes (std::vector<uint8_t> bytes)
36
{
37
  NS_ASSERT_MSG (!m_deserializing, "Can't add bytes after deserialization started");
38
  m_bytesBlob.insert (m_bytesBlob.end (), bytes.begin (), bytes.end ());
39
}
40
41
void BitDeserializer::PushBytes (uint8_t* bytes, uint32_t size)
42
{
43
  NS_ASSERT_MSG (!m_deserializing, "Can't add bytes after deserialization started");
44
  for (uint32_t index = 0; index < size; index++)
45
    {
46
      m_bytesBlob.push_back (bytes[index]);
47
    }
48
}
49
50
void BitDeserializer::PushByte (uint8_t byte)
51
{
52
  NS_ASSERT_MSG (!m_deserializing, "Can't add bytes after deserialization started");
53
  m_bytesBlob.push_back (byte);
54
}
55
56
uint64_t BitDeserializer::GetBits (uint8_t size)
57
{
58
  uint8_t result = 0;
59
  PrepareDeserialization ();
60
61
  NS_ASSERT_MSG (size <= 64, "Number of requested bits exceeds 64");
62
  NS_ASSERT_MSG (size <= m_blob.size (), "Number of requested bits exceeds blob size");
63
64
  for (uint8_t i = 0; i < size; i++)
65
    {
66
      result <<= 1;
67
      result |= m_blob.front ();
68
      m_blob.pop_front ();
69
    }
70
  return result;
71
}
72
73
void BitDeserializer::PrepareDeserialization ()
74
{
75
  if (m_deserializing == false)
76
    {
77
      m_deserializing = true;
78
      for (auto index = m_bytesBlob.begin (); index != m_bytesBlob.end (); index++)
79
        {
80
          m_blob.push_back (*index & 0x80);
81
          m_blob.push_back (*index & 0x40);
82
          m_blob.push_back (*index & 0x20);
83
          m_blob.push_back (*index & 0x10);
84
          m_blob.push_back (*index & 0x8);
85
          m_blob.push_back (*index & 0x4);
86
          m_blob.push_back (*index & 0x2);
87
          m_blob.push_back (*index & 0x1);
88
        }
89
    }
90
}
91
92
} // namespace ns3
(-)a/src/network/utils/bit-deserializer.h (+85 lines)
Line 0    Link Here 
1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2
/*
3
 * Copyright (c) 2018 Universita' di Firenze, Italy
4
 *
5
 * This program is free software; you can redistribute it and/or modify
6
 * it under the terms of the GNU General Public License version 2 as
7
 * published by the Free Software Foundation;
8
 *
9
 * This program is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 * GNU General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU General Public License
15
 * along with this program; if not, write to the Free Software
16
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17
 *
18
 * Author: Tommaso Pecorella <tommaso.pecorella@unifi.it>
19
 */
20
21
#ifndef BITDESERIALIZER_H_
22
#define BITDESERIALIZER_H_
23
24
#include <vector>
25
#include <deque>
26
27
namespace ns3 {
28
29
/**
30
 * \ingroup packet
31
 *
32
 * \brief Bit deserializer. See also \sa ns3::BitSerializer
33
 *
34
 * This class helps converting a variable number, variable sized
35
 * number of bit-boundary fields stored as byte array representation
36
 * and extract the original bit-fields.
37
 *
38
 * Note that once the Deserialization starts, it's not anymore
39
 * possible to add more data to the `packet' to deserialize.
40
 */
41
42
class BitDeserializer
43
{
44
public:
45
  BitDeserializer ();
46
47
  /**
48
   * Pushes some bytes into the blob to be deserialized.
49
   * \param bytes The bytes to add.
50
   */
51
  void PushBytes (std::vector<uint8_t> bytes);
52
53
  /**
54
   * Pushes some bytes into the blob to be deserialized.
55
   * \param bytes The bytes to add.
56
   * \param size The length of the array.
57
   */
58
  void PushBytes (uint8_t* bytes, uint32_t size);
59
60
  /**
61
   * Pushes one byte into the blob to be deserialized.
62
   * \param byte The byte to add.
63
   */
64
  void PushByte (uint8_t byte);
65
66
  /**
67
   * Pops a given number of bits from the blob front.
68
   * \param size The number of bits to pop.
69
   */
70
  uint64_t GetBits (uint8_t size);
71
72
private:
73
  /**
74
   * Prepare the byte array to the deserialization.
75
   */
76
  void PrepareDeserialization ();
77
78
  std::deque<bool> m_blob; //!< Blob of bits ready to be deserialized.
79
  std::vector<uint8_t> m_bytesBlob;  //!< Blob of bytes to be deserialized.
80
  bool m_deserializing; //!< True if the deserialization did start alredy.
81
};
82
83
} // namespace ns3
84
85
#endif /* BITDESERIALIZER_H_ */
(-)a/src/network/utils/bit-serializer.cc (+119 lines)
Line 0    Link Here 
1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2
/*
3
 * Copyright (c) 2018 Universita' di Firenze, Italy
4
 *
5
 * This program is free software; you can redistribute it and/or modify
6
 * it under the terms of the GNU General Public License version 2 as
7
 * published by the Free Software Foundation;
8
 *
9
 * This program is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 * GNU General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU General Public License
15
 * along with this program; if not, write to the Free Software
16
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17
 *
18
 * Author: Tommaso Pecorella <tommaso.pecorella@unifi.it>
19
 */
20
21
#include <iostream>
22
#include "bit-serializer.h"
23
#include "ns3/log.h"
24
#include "ns3/assert.h"
25
26
namespace ns3 {
27
28
NS_LOG_COMPONENT_DEFINE ("BitSerializer");
29
30
BitSerializer::BitSerializer ()
31
{
32
  m_padAtEnd = true;
33
}
34
35
void BitSerializer::InsertPaddingAtEnd (bool padAtEnd)
36
{
37
  m_padAtEnd = padAtEnd;
38
}
39
40
void BitSerializer::PadAtStart ()
41
{
42
  uint8_t padding = 8 - (m_blob.size () % 8);
43
44
  m_blob.insert (m_blob.begin (), padding, false);
45
}
46
47
void BitSerializer::PadAtEnd ()
48
{
49
  uint8_t padding = 8 - (m_blob.size () % 8);
50
51
  m_blob.insert (m_blob.end (), padding, false);
52
}
53
54
void BitSerializer::PushBits (uint64_t value, uint8_t significantBits)
55
{
56
  uint64_t mask = 1;
57
  mask <<= significantBits - 1;
58
59
  for (uint8_t i = 0; i < significantBits; i++)
60
    {
61
      if (value & mask)
62
        {
63
          m_blob.push_back (true);
64
        }
65
      else
66
        {
67
          m_blob.push_back (false);
68
        }
69
      mask >>= 1;
70
    }
71
}
72
73
std::vector<uint8_t> BitSerializer::GetBytes ()
74
{
75
  std::vector<uint8_t> result;
76
77
  m_padAtEnd ? PadAtEnd () : PadAtStart ();
78
79
  for (auto it = m_blob.begin (); it != m_blob.end ();)
80
    {
81
      uint8_t tmp = 0;
82
      for (uint8_t i = 0; i < 8; ++i)
83
        {
84
          tmp <<= 1;
85
          tmp |= (*it & 1);
86
          it++;
87
        }
88
      result.push_back (tmp);
89
    }
90
  m_blob.clear ();
91
  return result;
92
}
93
94
uint8_t BitSerializer::GetBytes (uint8_t *buffer, uint32_t size)
95
{
96
  uint8_t resultLen = 0;
97
98
  m_padAtEnd ? PadAtEnd () : PadAtStart ();
99
100
  NS_ASSERT_MSG (m_blob.size () <= 8 * size, "Target buffer is too short, " << m_blob.size () / 8 << " bytes needed" );
101
102
  for (auto it = m_blob.begin (); it != m_blob.end ();)
103
    {
104
      uint8_t tmp = 0;
105
      for (uint8_t i = 0; i < 8; ++i)
106
        {
107
          tmp <<= 1;
108
          tmp |= (*it & 1);
109
          it++;
110
        }
111
      buffer[resultLen] = tmp;
112
      resultLen++;
113
114
    }
115
  m_blob.clear ();
116
  return resultLen;
117
}
118
119
} // namespace ns3
(-)a/src/network/utils/bit-serializer.h (+116 lines)
Line 0    Link Here 
1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2
/*
3
 * Copyright (c) 2018 Universita' di Firenze, Italy
4
 *
5
 * This program is free software; you can redistribute it and/or modify
6
 * it under the terms of the GNU General Public License version 2 as
7
 * published by the Free Software Foundation;
8
 *
9
 * This program is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 * GNU General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU General Public License
15
 * along with this program; if not, write to the Free Software
16
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17
 *
18
 * Author: Tommaso Pecorella <tommaso.pecorella@unifi.it>
19
 */
20
21
#ifndef BITSERIALIZER_H_
22
#define BITSERIALIZER_H_
23
24
#include <vector>
25
26
namespace ns3 {
27
28
/**
29
 * \ingroup packet
30
 *
31
 * \brief Bit serializer. See also \sa ns3::BitDeserializer
32
 *
33
 * This class helps converting a variable number, variable sized
34
 * number of bit-boundary fields to its final byte array representation.
35
 *
36
 * The typical use-case is:
37
 * \verbatim
38
 * aaa: A field
39
 * bbb: B field
40
 * ccc: C field
41
 * ddd: D field
42
 * 000: padding
43
 *
44
 * |aaaa abbb bbcc cdd0|
45
 * \endverbatim
46
 *
47
 * Padding can be automatically added at the end or at the start
48
 * of the `packet' to reach a multiple of 8 bits. By default the
49
 * padding is added at the end of the `packet'.
50
 *
51
 * This class should be used in two cases:
52
 *   - When the number of fields is large.
53
 *   - When the number of fields is variable.
54
 * In the other cases it's more convenient to use a simple bitmask.
55
 */
56
57
class BitSerializer
58
{
59
public:
60
  BitSerializer ();
61
62
  /**
63
   * Toggles the padding insertion policy.
64
   * \param padAtEnd true if the padding have to be inserted at the end of the bit blob.
65
   */
66
  void InsertPaddingAtEnd (bool padAtEnd);
67
68
  /**
69
   * Pushes a number of bits in the blob.
70
   * \param value the bits to be inserted.
71
   * \param significantBits Number of bits to insert.
72
   */
73
  void PushBits (uint64_t value, uint8_t significantBits);
74
75
  /**
76
   * Get the bytes representation of the blob.
77
   * Not that this operation  \b automatically add the
78
   * needed padding at the end (or start) of the blob.
79
   *
80
   * \warning {This operation clears the stored data.}
81
   *
82
   * \returns The byte representation of the blob.
83
   */
84
  std::vector<uint8_t> GetBytes ();
85
86
  /**
87
   * Get the bytes representation of the blob.
88
   * Not that this operation  \b automatically add the
89
   * needed padding at the end (or start) of the blob.
90
   *
91
   * \warning {This operation clears the stored data.}
92
   *
93
   * \param [out] buffer The buffer where to store the return data.
94
   * \param [in] size The size of the buffer.
95
   * \returns The number of bytes actually used in the buffer.
96
   */
97
  uint8_t GetBytes (uint8_t *buffer, uint32_t size);
98
99
private:
100
  /**
101
   * Add the padding at the start of the blob.
102
   */
103
  void PadAtStart ();
104
105
  /**
106
   * Add the padding at the end of the blob.
107
   */
108
  void PadAtEnd ();
109
110
  std::vector<bool> m_blob; //!< Blob of serialized bits.
111
  bool m_padAtEnd; //!< True if the padding must be added at the end of the blob.
112
};
113
114
} // namespace ns3
115
116
#endif /* BITSERIALIZER_H_ */
(-)a/src/network/wscript (+5 lines)
 Lines 25-30    Link Here 
25
        'model/trailer.cc',
25
        'model/trailer.cc',
26
        'utils/address-utils.cc',
26
        'utils/address-utils.cc',
27
        'utils/ascii-file.cc',
27
        'utils/ascii-file.cc',
28
        'utils/bit-deserializer.cc',
29
        'utils/bit-serializer.cc',
28
        'utils/crc32.cc',
30
        'utils/crc32.cc',
29
        'utils/data-rate.cc',
31
        'utils/data-rate.cc',
30
        'utils/drop-tail-queue.cc',
32
        'utils/drop-tail-queue.cc',
 Lines 75-80    Link Here 
75
77
76
    network_test = bld.create_ns3_module_test_library('network')
78
    network_test = bld.create_ns3_module_test_library('network')
77
    network_test.source = [
79
    network_test.source = [
80
        'test/bit-serializer-test.cc',
78
        'test/buffer-test.cc',
81
        'test/buffer-test.cc',
79
        'test/drop-tail-queue-test-suite.cc',
82
        'test/drop-tail-queue-test-suite.cc',
80
        'test/error-model-test-suite.cc',
83
        'test/error-model-test-suite.cc',
 Lines 113-118    Link Here 
113
        'utils/address-utils.h',
116
        'utils/address-utils.h',
114
        'utils/ascii-file.h',
117
        'utils/ascii-file.h',
115
        'utils/ascii-test.h',
118
        'utils/ascii-test.h',
119
        'utils/bit-deserializer.h',
120
        'utils/bit-serializer.h',
116
        'utils/crc32.h',
121
        'utils/crc32.h',
117
        'utils/data-rate.h',
122
        'utils/data-rate.h',
118
        'utils/drop-tail-queue.h',
123
        'utils/drop-tail-queue.h',

Return to bug 2952