ref: b7267a73ef2d703263173152bb219955aaffa76e
dir: /libstd/ipparse.myr/
use "die.use"
use "intparse.use"
use "option.use"
use "strfind.use"
use "types.use"
use "chartype.use"
/* FIXME: needed for decls which should be pulled in as hidden */
use "hasprefix.use"
use "utf.use"
pkg std =
type netaddr = union
`Ipv4 byte[4]
`Ipv6 byte[16]
;;
const ipparse : (ip : byte[:] -> option(netaddr))
const ip4parse : (ip : byte[:] -> option(netaddr))
const ip6parse : (ip : byte[:] -> option(netaddr))
;;
const ipparse = {ip
match strfind(ip, ":")
| `Some _: -> ip6parse(ip)
| `None: -> ip4parse(ip)
;;
}
const ip4parse = {ip
var a, b, c, d
var ok
/*
var addr
var last : size
var x : option(int32)
var val : int32 /* need int32 to check for overflow */
var i
var j : size
*/
(a, ip, ok) = octet(ip, 10, true)
(ip, ok) = dot(ip, ok)
(b, ip, ok) = octet(ip, 10, ok)
(ip, ok) = dot(ip, ok)
(c, ip, ok) = octet(ip, 10, ok)
(ip, ok) = dot(ip, ok)
(d, ip, ok) = octet(ip, 10, ok)
if ok && ip.len == 0
-> `Some (`Ipv4 [a, b,c,d])
else
-> `None
;;
}
const ip6parse = {ip
-> `None
}
const dot = {ip, ok
if ip.len > 0 && ip[0] == '.' castto(byte)
-> (ip[1:], ok)
else
-> ("", false)
;;
}
const octet = {ip, base, ok
var len
if !ok
-> (0, "", false)
;;
for len = 0; len < ip.len; len++
if ip[len] == '.' castto(byte)
break
;;
;;
match intparsebase(ip[:len], base)
| `std.Some v:
if v < 0 || v > 255
-> (0, "", false)
;;
-> (v castto(byte), ip[len:], true)
| `std.None:
-> (0, "", false)
;;
}