A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
address.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2007 INRIA
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
7 */
8
9#include "address.h"
10
11#include "ns3/assert.h"
12#include "ns3/log.h"
13
14#include <cstring>
15#include <iomanip>
16#include <iostream>
17
18namespace ns3
19{
20
22
24
27 m_len(0)
28{
29 // Buffer left uninitialized
30 NS_LOG_FUNCTION(this);
31}
32
33Address::Address(uint8_t type, const uint8_t* buffer, uint8_t len)
34 : m_type(type),
35 m_len(len)
36{
37 NS_LOG_FUNCTION(this << static_cast<uint32_t>(type) << &buffer << static_cast<uint32_t>(len));
38 NS_ASSERT_MSG(m_len <= MAX_SIZE, "Address length too large");
39 NS_ASSERT_MSG(type != UNASSIGNED_TYPE, "Type 0 is reserved for uninitialized addresses.");
40 std::memcpy(m_data, buffer, m_len);
41}
42
44 : m_type(address.m_type),
45 m_len(address.m_len)
46{
48 std::memcpy(m_data, address.m_data, m_len);
49}
50
53{
55 m_type = address.m_type;
56 m_len = address.m_len;
58 std::memcpy(m_data, address.m_data, m_len);
59 return *this;
60}
61
62void
63Address::SetType(const std::string& kind, uint8_t length)
64{
65 NS_LOG_FUNCTION(this << kind << static_cast<uint32_t>(length));
66 auto search = m_typeRegistry.find({kind, length});
67 NS_ASSERT_MSG(search != m_typeRegistry.end(),
68 "No address with the given kind and length is registered.");
69
70 if (m_type != search->second)
71 {
73 "You can only change the type of a type-0 address."
74 << static_cast<uint32_t>(m_type));
75
76 m_type = search->second;
77 }
78}
79
80bool
82{
83 NS_LOG_FUNCTION(this);
84 return m_len == 0 && m_type == UNASSIGNED_TYPE;
85}
86
87uint8_t
89{
90 NS_LOG_FUNCTION(this);
92 return m_len;
93}
94
96Address::CopyTo(uint8_t buffer[MAX_SIZE]) const
97{
98 NS_LOG_FUNCTION(this << &buffer);
100 std::memcpy(buffer, m_data, m_len);
101 return m_len;
102}
103
105Address::CopyAllTo(uint8_t* buffer, uint8_t len) const
106{
107 NS_LOG_FUNCTION(this << &buffer << static_cast<uint32_t>(len));
108 NS_ASSERT(len - m_len > 1);
109 buffer[0] = m_type;
110 buffer[1] = m_len;
111 std::memcpy(buffer + 2, m_data, m_len);
112 return m_len + 2;
113}
114
116Address::CopyFrom(const uint8_t* buffer, uint8_t len)
117{
118 NS_LOG_FUNCTION(this << &buffer << static_cast<uint32_t>(len));
119 NS_ASSERT_MSG(m_len <= MAX_SIZE, "Address length too large");
121 "Type-0 addresses are reserved. Please use SetType before using CopyFrom.");
122 std::memcpy(m_data, buffer, len);
123 m_len = len;
124 return m_len;
125}
126
128Address::CopyAllFrom(const uint8_t* buffer, uint8_t len)
129{
130 NS_LOG_FUNCTION(this << &buffer << static_cast<uint32_t>(len));
131 NS_ASSERT(len >= 2);
132 m_type = buffer[0];
133 m_len = buffer[1];
134
135 NS_ASSERT(len - m_len > 1);
136 std::memcpy(m_data, buffer + 2, m_len);
137 return m_len + 2;
138}
139
140bool
141Address::CheckCompatible(uint8_t type, uint8_t len) const
142{
143 NS_LOG_FUNCTION(this << static_cast<uint32_t>(type) << static_cast<uint32_t>(len));
144 NS_ASSERT(len <= MAX_SIZE);
145 return (m_len == len && m_type == type);
146}
147
148bool
149Address::IsMatchingType(uint8_t type) const
150{
151 NS_LOG_FUNCTION(this << static_cast<uint32_t>(type));
152 return m_type == type;
153}
154
155uint8_t
156Address::Register(const std::string& kind, uint8_t length)
157{
158 NS_LOG_FUNCTION(kind << length);
159 static uint8_t lastRegisteredType = UNASSIGNED_TYPE;
160 NS_ASSERT_MSG(m_typeRegistry.find({kind, length}) == m_typeRegistry.end(),
161 "An address of the same kind and length is already registered.");
162 lastRegisteredType++;
163 m_typeRegistry[{kind, length}] = lastRegisteredType;
164 return lastRegisteredType;
165}
166
169{
170 NS_LOG_FUNCTION(this);
171 return 1 + 1 + m_len;
172}
173
174void
176{
177 NS_LOG_FUNCTION(this << &buffer);
178 buffer.WriteU8(m_type);
179 buffer.WriteU8(m_len);
180 buffer.Write(m_data, m_len);
181}
182
183void
185{
186 NS_LOG_FUNCTION(this << &buffer);
187 m_type = buffer.ReadU8();
188 m_len = buffer.ReadU8();
190 buffer.Read(m_data, m_len);
191}
192
194
195bool
196operator==(const Address& a, const Address& b)
197{
198 if (a.m_type != b.m_type)
199 {
200 return false;
201 }
202 if (a.m_len != b.m_len)
203 {
204 return false;
205 }
206 return std::memcmp(a.m_data, b.m_data, a.m_len) == 0;
207}
208
209bool
210operator!=(const Address& a, const Address& b)
211{
212 return !(a == b);
213}
214
215bool
216operator<(const Address& a, const Address& b)
217{
218 if (a.m_type < b.m_type)
219 {
220 return true;
221 }
222 else if (a.m_type > b.m_type)
223 {
224 return false;
225 }
226 if (a.m_len < b.m_len)
227 {
228 return true;
229 }
230 else if (a.m_len > b.m_len)
231 {
232 return false;
233 }
234 NS_ASSERT(a.GetLength() == b.GetLength());
235 for (uint8_t i = 0; i < a.GetLength(); i++)
236 {
237 if (a.m_data[i] < b.m_data[i])
238 {
239 return true;
240 }
241 else if (a.m_data[i] > b.m_data[i])
242 {
243 return false;
244 }
245 }
246 return false;
247}
248
249std::ostream&
250operator<<(std::ostream& os, const Address& address)
251{
252 if (address.m_len == 0)
253 {
254 return os;
255 }
256 std::ios_base::fmtflags ff = os.flags();
257 auto fill = os.fill('0');
258 os.setf(std::ios::hex, std::ios::basefield);
259 os << std::setw(2) << (uint32_t)address.m_type << "-" << std::setw(2) << (uint32_t)address.m_len
260 << "-";
261 for (uint8_t i = 0; i < (address.m_len - 1); ++i)
262 {
263 os << std::setw(2) << (uint32_t)address.m_data[i] << ":";
264 }
265 // Final byte not suffixed by ":"
266 os << std::setw(2) << (uint32_t)address.m_data[address.m_len - 1];
267 os.flags(ff); // Restore stream flags
268 os.fill(fill);
269 return os;
270}
271
272std::istream&
273operator>>(std::istream& is, Address& address)
274{
275 std::string v;
276 is >> v;
277 std::string::size_type firstDash;
278 std::string::size_type secondDash;
279 firstDash = v.find('-');
280 secondDash = v.find('-', firstDash + 1);
281 std::string type = v.substr(0, firstDash);
282 std::string len = v.substr(firstDash + 1, secondDash - (firstDash + 1));
283
284 address.m_type = std::stoul(type, nullptr, 16);
285 address.m_len = std::stoul(len, nullptr, 16);
286 NS_ASSERT(address.m_len <= Address::MAX_SIZE);
287
288 std::string::size_type col = secondDash + 1;
289 for (uint8_t i = 0; i < address.m_len; ++i)
290 {
291 std::string tmp;
292 std::string::size_type next;
293 next = v.find(':', col);
294 if (next == std::string::npos)
295 {
296 tmp = v.substr(col, v.size() - col);
297 address.m_data[i] = std::stoul(tmp, nullptr, 16);
298 break;
299 }
300 else
301 {
302 tmp = v.substr(col, next - col);
303 address.m_data[i] = std::stoul(tmp, nullptr, 16);
304 col = next + 1;
305 }
306 }
307 return is;
308}
309
310} // namespace ns3
uint32_t v
a polymophic address class
Definition address.h:111
uint32_t GetSerializedSize() const
Get the number of bytes needed to serialize the underlying Address Typically, this is GetLength () + ...
Definition address.cc:168
void Serialize(TagBuffer buffer) const
Serialize this address in host byte order to a byte buffer.
Definition address.cc:175
static constexpr uint8_t UNASSIGNED_TYPE
Unassigned Address type is reserved. Defined for clarity.
Definition address.h:147
uint32_t CopyFrom(const uint8_t *buffer, uint8_t len)
Definition address.cc:116
static constexpr uint32_t MAX_SIZE
The maximum size of a byte buffer which can be stored in an Address instance.
Definition address.h:154
bool IsInvalid() const
Definition address.cc:81
uint8_t m_len
Length of the address.
Definition address.h:353
uint8_t m_data[MAX_SIZE]
The address value.
Definition address.h:354
void SetType(const std::string &kind, uint8_t length)
Set the address type.
Definition address.cc:63
uint8_t m_type
Type of the address.
Definition address.h:352
Address & operator=(const Address &address)
Basic assignment operator.
Definition address.cc:52
std::unordered_map< KindType, uint8_t, Address::KeyHash > KindTypeRegistry
Type of the address registry.
Definition address.h:137
static KindTypeRegistry m_typeRegistry
Container of allocated address types.
Definition address.h:144
Address()
Create an invalid address.
Definition address.cc:25
uint32_t CopyAllFrom(const uint8_t *buffer, uint8_t len)
Definition address.cc:128
bool CheckCompatible(uint8_t type, uint8_t len) const
Definition address.cc:141
uint8_t GetLength() const
Get the length of the underlying address.
Definition address.cc:88
uint32_t CopyTo(uint8_t buffer[MAX_SIZE]) const
Copy the address bytes into a buffer.
Definition address.cc:96
void Deserialize(TagBuffer buffer)
Definition address.cc:184
static uint8_t Register(const std::string &kind, uint8_t length)
Allocate a new type id for a new type of address.
Definition address.cc:156
bool IsMatchingType(uint8_t type) const
Definition address.cc:149
uint32_t CopyAllTo(uint8_t *buffer, uint8_t len) const
Definition address.cc:105
read and write tag data
Definition tag-buffer.h:41
void Read(uint8_t *buffer, uint32_t size)
TAG_BUFFER_INLINE void WriteU8(uint8_t v)
Definition tag-buffer.h:161
TAG_BUFFER_INLINE uint8_t ReadU8()
Definition tag-buffer.h:185
void Write(const uint8_t *buffer, uint32_t size)
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition assert.h:55
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition assert.h:75
#define ATTRIBUTE_HELPER_CPP(type)
Define the attribute value, accessor and checkers for class type.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
Every class exported by the ns3 library is enclosed in the ns3 namespace.
bool operator!=(Callback< R, Args... > a, Callback< R, Args... > b)
Inequality test.
Definition callback.h:658
bool operator==(const EventId &a, const EventId &b)
Definition event-id.h:146
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition angles.cc:148
std::istream & operator>>(std::istream &is, Angles &a)
Definition angles.cc:172
bool operator<(const EventId &a, const EventId &b)
Definition event-id.h:159