Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(178)

Side by Side Diff: net/base/ip_address.h

Issue 2881673002: Avoid heap allocations in IPAddress (Closed)
Patch Set: More fixes Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2015 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef NET_BASE_IP_ADDRESS_H_ 5 #ifndef NET_BASE_IP_ADDRESS_H_
6 #define NET_BASE_IP_ADDRESS_H_ 6 #define NET_BASE_IP_ADDRESS_H_
7 7
8 #include <stddef.h> 8 #include <stddef.h>
9 #include <stdint.h> 9 #include <stdint.h>
10 10
11 #include <array>
11 #include <string> 12 #include <string>
12 #include <vector> 13 #include <vector>
13 14
14 #include "base/compiler_specific.h" 15 #include "base/compiler_specific.h"
15 #include "base/strings/string_piece.h" 16 #include "base/strings/string_piece.h"
16 #include "net/base/net_export.h" 17 #include "net/base/net_export.h"
17 18
18 namespace net { 19 namespace net {
19 20
20 class NET_EXPORT IPAddress { 21 class NET_EXPORT IPAddress {
21 public: 22 public:
22 enum : size_t { kIPv4AddressSize = 4, kIPv6AddressSize = 16 }; 23 enum : size_t { kIPv4AddressSize = 4, kIPv6AddressSize = 16 };
23 24
25 // Helper class to represent the sequence of bytes in an IP address.
26 // A vector<uint8_t> would be simpler but incurs heap allocation, so
27 // IPAddressBytes uses a fixed size array
28 class IPAddressBytes {
29 public:
30 IPAddressBytes();
31 IPAddressBytes(const IPAddressBytes& other);
32 ~IPAddressBytes();
33
34 // Returns the number of elements in the underlying array.
35 size_t size() const { return size_; }
36
37 // Sets the size to be |size|. Does not actually change the size
38 // of the underlying array.
39 void resize(size_t size) {
40 DCHECK_GT(16u, size);
eroman 2017/05/12 23:27:02 DCHECK_LE(size, 16); Either way, need equality in
Ryan Hamilton 2017/05/13 13:20:47 Done.
41 size_ = static_cast<uint8_t>(size);
42 }
43
44 // Returns true if the underlying array is empty.
45 bool empty() const { return size_ == 0; }
46
47 // Returns a pointer to the underlying array of bytes.
48 const uint8_t* data() const { return bytes_.data(); }
49 uint8_t* data() { return bytes_.data(); }
50
51 // Returns a pointer to the first element.
52 const uint8_t* begin() const { return data(); }
53
54 // Returns a pointer past the last element.
55 const uint8_t* end() const { return &(data()[size_]); }
eroman 2017/05/12 23:25:05 return data() + size;
Ryan Hamilton 2017/05/13 13:20:47 Done.
56
57 // Returns a reference to the last element.
58 uint8_t& back() { return bytes_[size_ - 1]; }
eroman 2017/05/12 23:25:05 DCHECK(!empty()) ?
Ryan Hamilton 2017/05/13 13:20:47 Done.
59 const uint8_t& back() const { return bytes_[size_ - 1]; }
eroman 2017/05/12 23:25:05 ditto.
Ryan Hamilton 2017/05/13 13:20:47 Done.
60
61 // Appends |val| to the end and increments the size.
62 void push_back(uint8_t val) {
63 DCHECK_GT(16, size_);
64 bytes_[size_++] = val;
65 }
66
67 // Returns a reference to the byte at index |pos|.
68 uint8_t& operator[](size_t pos) { return bytes_[pos]; }
eroman 2017/05/12 23:25:05 DCHECK that it is in range?
Ryan Hamilton 2017/05/13 13:20:47 Done.
69 const uint8_t& operator[](size_t pos) const { return bytes_[pos]; }
70
71 private:
72 friend bool operator>(IPAddressBytes lhs, IPAddressBytes rhs);
eroman 2017/05/12 23:25:05 const IPAddressBytes&
Ryan Hamilton 2017/05/13 13:20:47 Done.
73 friend bool operator<(IPAddressBytes lhs, IPAddressBytes rhs);
74 friend bool operator!=(IPAddressBytes lhs, IPAddressBytes rhs);
75 friend bool operator==(IPAddressBytes lhs, IPAddressBytes rhs);
76
77 // Number of elements in |bytes_|. Should be either kIPv4AddressSize
78 // or kIPv6AddressSize.
eroman 2017/05/12 23:25:05 or 0.
Ryan Hamilton 2017/05/13 13:20:47 Good point!
79 uint8_t size_;
eroman 2017/05/12 23:25:05 [optional] I suggest putting this after |bytes_|.
Ryan Hamilton 2017/05/13 13:20:47 Ooh, clever.
80
81 // Underlying sequence of bytes
82 std::array<uint8_t, kIPv6AddressSize> bytes_;
83 };
84
24 // Creates a zero-sized, invalid address. 85 // Creates a zero-sized, invalid address.
25 IPAddress(); 86 IPAddress();
26 87
27 // Copies the input address to |ip_address_|. The input is expected to be in 88 // Copies the input address to |ip_address_|. The input is expected to be in
28 // network byte order. 89 // network byte order.
29 explicit IPAddress(const std::vector<uint8_t>& address); 90 explicit IPAddress(const std::vector<uint8_t>& address);
30 91
31 IPAddress(const IPAddress& other); 92 IPAddress(const IPAddress& other);
32 93
33 // Copies the input address to |ip_address_|. The input is expected to be in 94 // Copies the input address to |ip_address_|. The input is expected to be in
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
95 // Returns the canonical string representation of an IP address. 156 // Returns the canonical string representation of an IP address.
96 // For example: "192.168.0.1" or "::1". Returns the empty string when 157 // For example: "192.168.0.1" or "::1". Returns the empty string when
97 // |ip_address_| is invalid. 158 // |ip_address_| is invalid.
98 std::string ToString() const; 159 std::string ToString() const;
99 160
100 // Parses an IP address literal (either IPv4 or IPv6) to its numeric value. 161 // Parses an IP address literal (either IPv4 or IPv6) to its numeric value.
101 // Returns true on success and fills |ip_address_| with the numeric value. 162 // Returns true on success and fills |ip_address_| with the numeric value.
102 bool AssignFromIPLiteral(const base::StringPiece& ip_literal) 163 bool AssignFromIPLiteral(const base::StringPiece& ip_literal)
103 WARN_UNUSED_RESULT; 164 WARN_UNUSED_RESULT;
104 165
105 // Returns the underlying byte vector. 166 // Returns the underlying bytes.
106 const std::vector<uint8_t>& bytes() const { return ip_address_; }; 167 const IPAddressBytes& bytes() const { return ip_address_; };
168
169 // Returns the underlying bytes as a vector.
170 std::vector<uint8_t> BytesAsVector() const;
107 171
108 // Returns an IPAddress instance representing the 127.0.0.1 address. 172 // Returns an IPAddress instance representing the 127.0.0.1 address.
109 static IPAddress IPv4Localhost(); 173 static IPAddress IPv4Localhost();
110 174
111 // Returns an IPAddress instance representing the ::1 address. 175 // Returns an IPAddress instance representing the ::1 address.
112 static IPAddress IPv6Localhost(); 176 static IPAddress IPv6Localhost();
113 177
114 // Returns an IPAddress made up of |num_zero_bytes| zeros. 178 // Returns an IPAddress made up of |num_zero_bytes| zeros.
115 static IPAddress AllZeros(size_t num_zero_bytes); 179 static IPAddress AllZeros(size_t num_zero_bytes);
116 180
117 // Returns an IPAddress instance representing the 0.0.0.0 address. 181 // Returns an IPAddress instance representing the 0.0.0.0 address.
118 static IPAddress IPv4AllZeros(); 182 static IPAddress IPv4AllZeros();
119 183
120 // Returns an IPAddress instance representing the :: address. 184 // Returns an IPAddress instance representing the :: address.
121 static IPAddress IPv6AllZeros(); 185 static IPAddress IPv6AllZeros();
122 186
123 bool operator==(const IPAddress& that) const; 187 bool operator==(const IPAddress& that) const;
124 bool operator!=(const IPAddress& that) const; 188 bool operator!=(const IPAddress& that) const;
125 bool operator<(const IPAddress& that) const; 189 bool operator<(const IPAddress& that) const;
126 190
127 private: 191 private:
128 // IPv4 addresses will have length kIPv4AddressSize, whereas IPv6 address 192 // IPv4 addresses will have length kIPv4AddressSize, whereas IPv6 address
129 // will have length kIPv6AddressSize. 193 // will have length kIPv6AddressSize.
130 std::vector<uint8_t> ip_address_; 194 IPAddressBytes ip_address_;
eroman 2017/05/12 23:25:05 Was IPAddressBytes made a separate class (as oppos
Ryan Hamilton 2017/05/13 13:20:47 The mutability was part of it. I also wanted to, a
131 195
132 // This class is copyable and assignable. 196 // This class is copyable and assignable.
133 }; 197 };
134 198
199 bool operator>(IPAddress::IPAddressBytes lhs, IPAddress::IPAddressBytes rhs);
eroman 2017/05/12 23:25:05 const IPAddressBytes&, or we will create unnecessa
Ryan Hamilton 2017/05/13 13:20:47 Done.
200 bool operator<(IPAddress::IPAddressBytes lhs, IPAddress::IPAddressBytes rhs);
201 bool operator!=(IPAddress::IPAddressBytes lhs, IPAddress::IPAddressBytes rhs);
202 bool operator==(IPAddress::IPAddressBytes lhs, IPAddress::IPAddressBytes rhs);
203
135 using IPAddressList = std::vector<IPAddress>; 204 using IPAddressList = std::vector<IPAddress>;
136 205
137 // Returns the canonical string representation of an IP address along with its 206 // Returns the canonical string representation of an IP address along with its
138 // port. For example: "192.168.0.1:99" or "[::1]:80". 207 // port. For example: "192.168.0.1:99" or "[::1]:80".
139 NET_EXPORT std::string IPAddressToStringWithPort(const IPAddress& address, 208 NET_EXPORT std::string IPAddressToStringWithPort(const IPAddress& address,
140 uint16_t port); 209 uint16_t port);
141 210
142 // Returns the address as a sequence of bytes in network-byte-order. 211 // Returns the address as a sequence of bytes in network-byte-order.
143 NET_EXPORT std::string IPAddressToPackedString(const IPAddress& address); 212 NET_EXPORT std::string IPAddressToPackedString(const IPAddress& address);
144 213
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
199 template <size_t N> 268 template <size_t N>
200 bool IPAddressStartsWith(const IPAddress& address, const uint8_t (&prefix)[N]) { 269 bool IPAddressStartsWith(const IPAddress& address, const uint8_t (&prefix)[N]) {
201 if (address.size() < N) 270 if (address.size() < N)
202 return false; 271 return false;
203 return std::equal(prefix, prefix + N, address.bytes().begin()); 272 return std::equal(prefix, prefix + N, address.bytes().begin());
204 } 273 }
205 274
206 } // namespace net 275 } // namespace net
207 276
208 #endif // NET_BASE_IP_ADDRESS_H_ 277 #endif // NET_BASE_IP_ADDRESS_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698