~cmiller/ubuntu/quantal/deluge/fix-parameter-move-storage

« back to all changes in this revision

Viewing changes to libtorrent/include/asio/ip/address_v6.hpp

  • Committer: Bazaar Package Importer
  • Author(s): Cristian Greco
  • Date: 2009-11-13 02:39:45 UTC
  • mfrom: (4.1.7 squeeze)
  • Revision ID: james.westby@ubuntu.com-20091113023945-te1bybo2912ejzuc
Tags: 1.2.0~rc3-4
* debian/control: bump build-dep on python-setuptools to (>= 0.6c9).
* debian/patches:
  - 25_r5921_fastresume_files.patch
    new, should fix problems with fresh configs;
  - 30_r5931_ipc_lockfile.patch:
    new, should fix an issue where Deluge will fail to start if there is a
    stale ipc lockfile. (Closes: #555849)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
//
2
 
// address_v6.hpp
3
 
// ~~~~~~~~~~~~~~
4
 
//
5
 
// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com)
6
 
//
7
 
// Distributed under the Boost Software License, Version 1.0. (See accompanying
8
 
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9
 
//
10
 
 
11
 
#ifndef ASIO_IP_ADDRESS_V6_HPP
12
 
#define ASIO_IP_ADDRESS_V6_HPP
13
 
 
14
 
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
15
 
# pragma once
16
 
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
17
 
 
18
 
#include "asio/detail/push_options.hpp"
19
 
 
20
 
#include "asio/detail/push_options.hpp"
21
 
#include <cstring>
22
 
#include <string>
23
 
#include <stdexcept>
24
 
#include <typeinfo>
25
 
#include <boost/array.hpp>
26
 
#include <boost/throw_exception.hpp>
27
 
#include "asio/detail/pop_options.hpp"
28
 
 
29
 
#include "asio/error.hpp"
30
 
#include "asio/detail/socket_ops.hpp"
31
 
#include "asio/detail/socket_types.hpp"
32
 
#include "asio/detail/throw_error.hpp"
33
 
#include "asio/ip/address_v4.hpp"
34
 
 
35
 
namespace asio {
36
 
namespace ip {
37
 
 
38
 
/// Implements IP version 6 style addresses.
39
 
/**
40
 
 * The asio::ip::address_v6 class provides the ability to use and
41
 
 * manipulate IP version 6 addresses.
42
 
 *
43
 
 * @par Thread Safety
44
 
 * @e Distinct @e objects: Safe.@n
45
 
 * @e Shared @e objects: Unsafe.
46
 
 */
47
 
class address_v6
48
 
{
49
 
public:
50
 
  /// The type used to represent an address as an array of bytes.
51
 
  typedef boost::array<unsigned char, 16> bytes_type;
52
 
 
53
 
  /// Default constructor.
54
 
  address_v6()
55
 
    : scope_id_(0)
56
 
  {
57
 
    asio::detail::in6_addr_type tmp_addr = IN6ADDR_ANY_INIT;
58
 
    addr_ = tmp_addr;
59
 
  }
60
 
 
61
 
  /// Construct an address from raw bytes and scope ID.
62
 
  explicit address_v6(const bytes_type& bytes, unsigned long scope_id = 0)
63
 
    : scope_id_(scope_id)
64
 
  {
65
 
#if UCHAR_MAX > 0xFF
66
 
    for (std::size_t i = 0; i < bytes.size(); ++i)
67
 
    {
68
 
      if (bytes[i] > 0xFF)
69
 
      {
70
 
        std::out_of_range ex("address_v6 from bytes_type");
71
 
        boost::throw_exception(ex);
72
 
      }
73
 
    }
74
 
#endif // UCHAR_MAX > 0xFF
75
 
 
76
 
    using namespace std; // For memcpy.
77
 
    memcpy(addr_.s6_addr, bytes.elems, 16);
78
 
  }
79
 
 
80
 
  /// Copy constructor.
81
 
  address_v6(const address_v6& other)
82
 
    : addr_(other.addr_),
83
 
      scope_id_(other.scope_id_)
84
 
  {
85
 
  }
86
 
 
87
 
  /// Assign from another address.
88
 
  address_v6& operator=(const address_v6& other)
89
 
  {
90
 
    addr_ = other.addr_;
91
 
    scope_id_ = other.scope_id_;
92
 
    return *this;
93
 
  }
94
 
 
95
 
  /// The scope ID of the address.
96
 
  /**
97
 
   * Returns the scope ID associated with the IPv6 address.
98
 
   */
99
 
  unsigned long scope_id() const
100
 
  {
101
 
    return scope_id_;
102
 
  }
103
 
 
104
 
  /// The scope ID of the address.
105
 
  /**
106
 
   * Modifies the scope ID associated with the IPv6 address.
107
 
   */
108
 
  void scope_id(unsigned long id)
109
 
  {
110
 
    scope_id_ = id;
111
 
  }
112
 
 
113
 
  /// Get the address in bytes.
114
 
  bytes_type to_bytes() const
115
 
  {
116
 
    using namespace std; // For memcpy.
117
 
    bytes_type bytes;
118
 
    memcpy(bytes.elems, addr_.s6_addr, 16);
119
 
    return bytes;
120
 
  }
121
 
 
122
 
  /// Get the address as a string.
123
 
  std::string to_string() const
124
 
  {
125
 
    asio::error_code ec;
126
 
    std::string addr = to_string(ec);
127
 
    asio::detail::throw_error(ec);
128
 
    return addr;
129
 
  }
130
 
 
131
 
  /// Get the address as a string.
132
 
  std::string to_string(asio::error_code& ec) const
133
 
  {
134
 
    char addr_str[asio::detail::max_addr_v6_str_len];
135
 
    const char* addr =
136
 
      asio::detail::socket_ops::inet_ntop(AF_INET6, &addr_, addr_str,
137
 
          asio::detail::max_addr_v6_str_len, scope_id_, ec);
138
 
    if (addr == 0)
139
 
      return std::string();
140
 
    return addr;
141
 
  }
142
 
 
143
 
  /// Create an address from an IP address string.
144
 
  static address_v6 from_string(const char* str)
145
 
  {
146
 
    asio::error_code ec;
147
 
    address_v6 addr = from_string(str, ec);
148
 
    asio::detail::throw_error(ec);
149
 
    return addr;
150
 
  }
151
 
 
152
 
  /// Create an address from an IP address string.
153
 
  static address_v6 from_string(const char* str, asio::error_code& ec)
154
 
  {
155
 
    address_v6 tmp;
156
 
    if (asio::detail::socket_ops::inet_pton(
157
 
          AF_INET6, str, &tmp.addr_, &tmp.scope_id_, ec) <= 0)
158
 
      return address_v6();
159
 
    return tmp;
160
 
  }
161
 
 
162
 
  /// Create an address from an IP address string.
163
 
  static address_v6 from_string(const std::string& str)
164
 
  {
165
 
    return from_string(str.c_str());
166
 
  }
167
 
 
168
 
  /// Create an address from an IP address string.
169
 
  static address_v6 from_string(const std::string& str,
170
 
      asio::error_code& ec)
171
 
  {
172
 
    return from_string(str.c_str(), ec);
173
 
  }
174
 
 
175
 
  /// Converts an IPv4-mapped or IPv4-compatible address to an IPv4 address.
176
 
  address_v4 to_v4() const
177
 
  {
178
 
    if (!is_v4_mapped() && !is_v4_compatible())
179
 
    {
180
 
      std::bad_cast ex;
181
 
      boost::throw_exception(ex);
182
 
    }
183
 
 
184
 
    address_v4::bytes_type v4_bytes = { { addr_.s6_addr[12],
185
 
      addr_.s6_addr[13], addr_.s6_addr[14], addr_.s6_addr[15] } };
186
 
    return address_v4(v4_bytes);
187
 
  }
188
 
 
189
 
  /// Determine whether the address is a loopback address.
190
 
  bool is_loopback() const
191
 
  {
192
 
#if defined(__BORLANDC__)
193
 
    return ((addr_.s6_addr[0] == 0) && (addr_.s6_addr[1] == 0)
194
 
        && (addr_.s6_addr[2] == 0) && (addr_.s6_addr[3] == 0)
195
 
        && (addr_.s6_addr[4] == 0) && (addr_.s6_addr[5] == 0)
196
 
        && (addr_.s6_addr[6] == 0) && (addr_.s6_addr[7] == 0)
197
 
        && (addr_.s6_addr[8] == 0) && (addr_.s6_addr[9] == 0)
198
 
        && (addr_.s6_addr[10] == 0) && (addr_.s6_addr[11] == 0)
199
 
        && (addr_.s6_addr[12] == 0) && (addr_.s6_addr[13] == 0)
200
 
        && (addr_.s6_addr[14] == 0) && (addr_.s6_addr[15] == 1));
201
 
#else
202
 
    using namespace asio::detail;
203
 
    return IN6_IS_ADDR_LOOPBACK(&addr_) != 0;
204
 
#endif
205
 
  }
206
 
 
207
 
  /// Determine whether the address is unspecified.
208
 
  bool is_unspecified() const
209
 
  {
210
 
#if defined(__BORLANDC__)
211
 
    return ((addr_.s6_addr[0] == 0) && (addr_.s6_addr[1] == 0)
212
 
        && (addr_.s6_addr[2] == 0) && (addr_.s6_addr[3] == 0)
213
 
        && (addr_.s6_addr[4] == 0) && (addr_.s6_addr[5] == 0)
214
 
        && (addr_.s6_addr[6] == 0) && (addr_.s6_addr[7] == 0)
215
 
        && (addr_.s6_addr[8] == 0) && (addr_.s6_addr[9] == 0)
216
 
        && (addr_.s6_addr[10] == 0) && (addr_.s6_addr[11] == 0)
217
 
        && (addr_.s6_addr[12] == 0) && (addr_.s6_addr[13] == 0)
218
 
        && (addr_.s6_addr[14] == 0) && (addr_.s6_addr[15] == 0));
219
 
#else
220
 
    using namespace asio::detail;
221
 
    return IN6_IS_ADDR_UNSPECIFIED(&addr_) != 0;
222
 
#endif
223
 
  }
224
 
 
225
 
  /// Determine whether the address is link local.
226
 
  bool is_link_local() const
227
 
  {
228
 
    using namespace asio::detail;
229
 
    return IN6_IS_ADDR_LINKLOCAL(&addr_) != 0;
230
 
  }
231
 
 
232
 
  /// Determine whether the address is site local.
233
 
  bool is_site_local() const
234
 
  {
235
 
    using namespace asio::detail;
236
 
    return IN6_IS_ADDR_SITELOCAL(&addr_) != 0;
237
 
  }
238
 
 
239
 
  /// Determine whether the address is a mapped IPv4 address.
240
 
  bool is_v4_mapped() const
241
 
  {
242
 
    using namespace asio::detail;
243
 
    return IN6_IS_ADDR_V4MAPPED(&addr_) != 0;
244
 
  }
245
 
 
246
 
  /// Determine whether the address is an IPv4-compatible address.
247
 
  bool is_v4_compatible() const
248
 
  {
249
 
    using namespace asio::detail;
250
 
    return IN6_IS_ADDR_V4COMPAT(&addr_) != 0;
251
 
  }
252
 
 
253
 
  /// Determine whether the address is a multicast address.
254
 
  bool is_multicast() const
255
 
  {
256
 
    using namespace asio::detail;
257
 
    return IN6_IS_ADDR_MULTICAST(&addr_) != 0;
258
 
  }
259
 
 
260
 
  /// Determine whether the address is a global multicast address.
261
 
  bool is_multicast_global() const
262
 
  {
263
 
    using namespace asio::detail;
264
 
    return IN6_IS_ADDR_MC_GLOBAL(&addr_) != 0;
265
 
  }
266
 
 
267
 
  /// Determine whether the address is a link-local multicast address.
268
 
  bool is_multicast_link_local() const
269
 
  {
270
 
    using namespace asio::detail;
271
 
    return IN6_IS_ADDR_MC_LINKLOCAL(&addr_) != 0;
272
 
  }
273
 
 
274
 
  /// Determine whether the address is a node-local multicast address.
275
 
  bool is_multicast_node_local() const
276
 
  {
277
 
    using namespace asio::detail;
278
 
    return IN6_IS_ADDR_MC_NODELOCAL(&addr_) != 0;
279
 
  }
280
 
 
281
 
  /// Determine whether the address is a org-local multicast address.
282
 
  bool is_multicast_org_local() const
283
 
  {
284
 
    using namespace asio::detail;
285
 
    return IN6_IS_ADDR_MC_ORGLOCAL(&addr_) != 0;
286
 
  }
287
 
 
288
 
  /// Determine whether the address is a site-local multicast address.
289
 
  bool is_multicast_site_local() const
290
 
  {
291
 
    using namespace asio::detail;
292
 
    return IN6_IS_ADDR_MC_SITELOCAL(&addr_) != 0;
293
 
  }
294
 
 
295
 
  /// Compare two addresses for equality.
296
 
  friend bool operator==(const address_v6& a1, const address_v6& a2)
297
 
  {
298
 
    using namespace std; // For memcmp.
299
 
    return memcmp(&a1.addr_, &a2.addr_,
300
 
        sizeof(asio::detail::in6_addr_type)) == 0
301
 
      && a1.scope_id_ == a2.scope_id_;
302
 
  }
303
 
 
304
 
  /// Compare two addresses for inequality.
305
 
  friend bool operator!=(const address_v6& a1, const address_v6& a2)
306
 
  {
307
 
    using namespace std; // For memcmp.
308
 
    return memcmp(&a1.addr_, &a2.addr_,
309
 
        sizeof(asio::detail::in6_addr_type)) != 0
310
 
      || a1.scope_id_ != a2.scope_id_;
311
 
  }
312
 
 
313
 
  /// Compare addresses for ordering.
314
 
  friend bool operator<(const address_v6& a1, const address_v6& a2)
315
 
  {
316
 
    using namespace std; // For memcmp.
317
 
    int memcmp_result = memcmp(&a1.addr_, &a2.addr_,
318
 
        sizeof(asio::detail::in6_addr_type));
319
 
    if (memcmp_result < 0)
320
 
      return true;
321
 
    if (memcmp_result > 0)
322
 
      return false;
323
 
    return a1.scope_id_ < a2.scope_id_;
324
 
  }
325
 
 
326
 
  /// Compare addresses for ordering.
327
 
  friend bool operator>(const address_v6& a1, const address_v6& a2)
328
 
  {
329
 
    return a2 < a1;
330
 
  }
331
 
 
332
 
  /// Compare addresses for ordering.
333
 
  friend bool operator<=(const address_v6& a1, const address_v6& a2)
334
 
  {
335
 
    return !(a2 < a1);
336
 
  }
337
 
 
338
 
  /// Compare addresses for ordering.
339
 
  friend bool operator>=(const address_v6& a1, const address_v6& a2)
340
 
  {
341
 
    return !(a1 < a2);
342
 
  }
343
 
 
344
 
  /// Obtain an address object that represents any address.
345
 
  static address_v6 any()
346
 
  {
347
 
    return address_v6();
348
 
  }
349
 
 
350
 
  /// Obtain an address object that represents the loopback address.
351
 
  static address_v6 loopback()
352
 
  {
353
 
    address_v6 tmp;
354
 
    asio::detail::in6_addr_type tmp_addr = IN6ADDR_LOOPBACK_INIT;
355
 
    tmp.addr_ = tmp_addr;
356
 
    return tmp;
357
 
  }
358
 
 
359
 
  /// Create an IPv4-mapped IPv6 address.
360
 
  static address_v6 v4_mapped(const address_v4& addr)
361
 
  {
362
 
    address_v4::bytes_type v4_bytes = addr.to_bytes();
363
 
    bytes_type v6_bytes = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF,
364
 
      v4_bytes[0], v4_bytes[1], v4_bytes[2], v4_bytes[3] } };
365
 
    return address_v6(v6_bytes);
366
 
  }
367
 
 
368
 
  /// Create an IPv4-compatible IPv6 address.
369
 
  static address_v6 v4_compatible(const address_v4& addr)
370
 
  {
371
 
    address_v4::bytes_type v4_bytes = addr.to_bytes();
372
 
    bytes_type v6_bytes = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
373
 
      v4_bytes[0], v4_bytes[1], v4_bytes[2], v4_bytes[3] } };
374
 
    return address_v6(v6_bytes);
375
 
  }
376
 
 
377
 
private:
378
 
  // The underlying IPv6 address.
379
 
  asio::detail::in6_addr_type addr_;
380
 
 
381
 
  // The scope ID associated with the address.
382
 
  unsigned long scope_id_;
383
 
};
384
 
 
385
 
/// Output an address as a string.
386
 
/**
387
 
 * Used to output a human-readable string for a specified address.
388
 
 *
389
 
 * @param os The output stream to which the string will be written.
390
 
 *
391
 
 * @param addr The address to be written.
392
 
 *
393
 
 * @return The output stream.
394
 
 *
395
 
 * @relates asio::ip::address_v6
396
 
 */
397
 
template <typename Elem, typename Traits>
398
 
std::basic_ostream<Elem, Traits>& operator<<(
399
 
    std::basic_ostream<Elem, Traits>& os, const address_v6& addr)
400
 
{
401
 
  asio::error_code ec;
402
 
  std::string s = addr.to_string(ec);
403
 
  if (ec)
404
 
  {
405
 
    if (os.exceptions() & std::ios::failbit)
406
 
      asio::detail::throw_error(ec);
407
 
    else
408
 
      os.setstate(std::ios_base::failbit);
409
 
  }
410
 
  else
411
 
    for (std::string::iterator i = s.begin(); i != s.end(); ++i)
412
 
      os << os.widen(*i);
413
 
  return os;
414
 
}
415
 
 
416
 
} // namespace ip
417
 
} // namespace asio
418
 
 
419
 
#include "asio/detail/pop_options.hpp"
420
 
 
421
 
#endif // ASIO_IP_ADDRESS_V6_HPP