@@ -152,44 +152,53 @@ func (err parseAddrError) Error() string {
152
152
return "ParseAddr(" + q (err .in ) + "): " + err .msg
153
153
}
154
154
155
- // parseIPv4 parses s as an IPv4 address (in form "192.168.0.1").
156
- func parseIPv4 (s string ) (ip Addr , err error ) {
157
- var fields [4 ]uint8
155
+ func parseIPv4Fields (in string , off , end int , fields []uint8 ) error {
158
156
var val , pos int
159
157
var digLen int // number of digits in current octet
158
+ s := in [off :end ]
160
159
for i := 0 ; i < len (s ); i ++ {
161
160
if s [i ] >= '0' && s [i ] <= '9' {
162
161
if digLen == 1 && val == 0 {
163
- return Addr {}, parseAddrError {in : s , msg : "IPv4 field has octet with leading zero" }
162
+ return parseAddrError {in : in , msg : "IPv4 field has octet with leading zero" }
164
163
}
165
164
val = val * 10 + int (s [i ]) - '0'
166
165
digLen ++
167
166
if val > 255 {
168
- return Addr {}, parseAddrError {in : s , msg : "IPv4 field has value >255" }
167
+ return parseAddrError {in : in , msg : "IPv4 field has value >255" }
169
168
}
170
169
} else if s [i ] == '.' {
171
170
// .1.2.3
172
171
// 1.2.3.
173
172
// 1..2.3
174
173
if i == 0 || i == len (s )- 1 || s [i - 1 ] == '.' {
175
- return Addr {}, parseAddrError {in : s , msg : "IPv4 field must have at least one digit" , at : s [i :]}
174
+ return parseAddrError {in : in , msg : "IPv4 field must have at least one digit" , at : s [i :]}
176
175
}
177
176
// 1.2.3.4.5
178
177
if pos == 3 {
179
- return Addr {}, parseAddrError {in : s , msg : "IPv4 address too long" }
178
+ return parseAddrError {in : in , msg : "IPv4 address too long" }
180
179
}
181
180
fields [pos ] = uint8 (val )
182
181
pos ++
183
182
val = 0
184
183
digLen = 0
185
184
} else {
186
- return Addr {}, parseAddrError {in : s , msg : "unexpected character" , at : s [i :]}
185
+ return parseAddrError {in : in , msg : "unexpected character" , at : s [i :]}
187
186
}
188
187
}
189
188
if pos < 3 {
190
- return Addr {}, parseAddrError {in : s , msg : "IPv4 address too short" }
189
+ return parseAddrError {in : in , msg : "IPv4 address too short" }
191
190
}
192
191
fields [3 ] = uint8 (val )
192
+ return nil
193
+ }
194
+
195
+ // parseIPv4 parses s as an IPv4 address (in form "192.168.0.1").
196
+ func parseIPv4 (s string ) (ip Addr , err error ) {
197
+ var fields [4 ]uint8
198
+ err = parseIPv4Fields (s , 0 , len (s ), fields [:])
199
+ if err != nil {
200
+ return Addr {}, err
201
+ }
193
202
return AddrFrom4 (fields ), nil
194
203
}
195
204
@@ -262,17 +271,15 @@ func parseIPv6(in string) (Addr, error) {
262
271
// Not enough room.
263
272
return Addr {}, parseAddrError {in : in , msg : "too many hex fields to fit an embedded IPv4 at the end of the address" , at : s }
264
273
}
265
- // TODO: could make this a bit faster by having a helper
266
- // that parses to a [4]byte, and have both parseIPv4 and
267
- // parseIPv6 use it.
268
- ip4 , err := parseIPv4 (s )
274
+
275
+ end := len (in )
276
+ if len (zone ) > 0 {
277
+ end -= len (zone ) + 1
278
+ }
279
+ err := parseIPv4Fields (in , end - len (s ), end , ip [i :i + 4 ])
269
280
if err != nil {
270
- return Addr {}, parseAddrError { in : in , msg : err . Error (), at : s }
281
+ return Addr {}, err
271
282
}
272
- ip [i ] = ip4 .v4 (0 )
273
- ip [i + 1 ] = ip4 .v4 (1 )
274
- ip [i + 2 ] = ip4 .v4 (2 )
275
- ip [i + 3 ] = ip4 .v4 (3 )
276
283
s = ""
277
284
i += 4
278
285
break
0 commit comments