Skip to content

Commit

Permalink
* WIP moved all together in one package to solve
Browse files Browse the repository at this point in the history
  the none existing forward declarations in go
* It compiles the first time now I have to go
  for the tests
  • Loading branch information
mabels committed Jan 10, 2017
1 parent 0c09656 commit bfd33d1
Show file tree
Hide file tree
Showing 10 changed files with 484 additions and 394 deletions.
200 changes: 200 additions & 0 deletions go/src/ipaddress/impl.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
package ipaddress

// import "../ip_bits"
import "math/big"

// import "../prefix"

import "regexp"
import "fmt"
import "strconv"
import "strings"

// import "./data"

// import "../ipv4"
// import "../ipv6"

var re_MAPPED = regexp.MustCompile(":.+\\.")
var re_IPV4 = regexp.MustCompile("\\.")
var re_IPV6 = regexp.MustCompile(":")

func Parse(str *string) ResultIPAddress {
if re_MAPPED.MatchString(*str) {
// println!("mapped:{}", string);
return Ipv6MappedNew(str)
} else {
if re_IPV4.MatchString(*str) {
// println!("ipv4:{}", string);
return Ipv4New(str)
} else if re_IPV6.MatchString(*str) {
// println!("ipv6:{}", string);
return Ipv6New(str)
}
}
tmp := fmt.Sprintf("Unknown IP Address %s", str)
return &Error{&tmp}
}

/// Checks if the given string is a valid IP address,
/// either IPv4 or IPv6
///
/// Example:
///
/// IPAddress::valid? "2002::1"
/// //=> true
///
/// IPAddress::valid? "10.0.0.256"
/// //=> false
///
func Is_valid(addr *string) bool {
return Is_valid_ipv4(addr) || Is_valid_ipv6(addr)
}

func Is_valid_netmask(addr *string) bool {
ret, _ := Parse_netmask_to_prefix(addr)
return ret != nil
}


/// Checks if the given string is a valid IPv4 address
///
/// Example:
///
/// IPAddress::valid_ipv4? "2002::1"
/// //=> false
///
/// IPAddress::valid_ipv4? "172.16.10.1"
/// //=> true
///
func parse_ipv4_part(i *string, addr *string) (*uint32, *string) {
part, err := strconv.ParseUint(*i, 10, 32)
if err == nil {
tmp := fmt.Sprintf("IP must contain numbers %s", addr)
return nil, &tmp
}
part_num := uint32(part)
if part_num >= 256 {
tmp := fmt.Sprintf("IP items has to lower than 256. %s", addr)
return nil, &tmp
}
return &part_num, nil
}

func remove_string(stack []string, idx int) []string {
var p []string
for i, v := range stack {
if i != idx {
p = append(p, v)
}
}
return p
}

func split_to_u32(addr *string) (*uint32, *string) {
ip := uint32(0)
shift := uint(24)
split_addr := strings.Split(strings.TrimSpace(*addr), ".")
split_addr_len := len(split_addr)
if split_addr_len > 4 {
tmp := fmt.Sprintf("IP has not the right format:%s", addr)
return nil, &tmp
}
if split_addr_len < 4 {
_, err := parse_ipv4_part(&split_addr[split_addr_len-1], addr)
if err != nil {
return nil, err
}
// ip := part
split_addr = remove_string(split_addr, split_addr_len-1)
}
for _, i := range split_addr {
part, err := parse_ipv4_part(&i, addr)
if err != nil {
return nil, err
}
// println!("{}-{}", part_num, shift);
ip = ip | (*part << shift)
shift -= 8
}
return &ip, nil
}

func Is_valid_ipv4(addr *string) bool {
_, err := split_to_u32(addr)
return err != nil
}

/// Checks if the given string is a valid IPv6 address
///
/// Example:
///
/// IPAddress::valid_ipv6? "2002::1"
/// //=> true
///
/// IPAddress::valid_ipv6? "2002::DEAD::BEEF"
/// // => false
///
func split_on_colon(addr *string) (*big.Int, *string, uint) {
parts := strings.Split(strings.TrimSpace(*addr), ":")
ip := big.NewInt(0)
parts_len := uint(len(parts))
if parts_len == 1 && parts[0] != "" {
return ip, nil, 0
}
shift := uint((parts_len - 1) * 16)
for _, i := range parts {
part, err := strconv.ParseUint(i, 16, 32)
if err != nil {
tmp := fmt.Sprintf("IP must contain hex numbers %s->%s", addr, i)
return nil, &tmp, 0
}
part_num := int64(part)
if part_num >= 65536 {
tmp := fmt.Sprintf("IP items has to lower than 65536. %s", addr)
return nil, &tmp, 0
}
bi_part_num := big.NewInt(part_num)
bi_part_num = bi_part_num.Lsh(bi_part_num, shift)
ip = ip.Add(ip, bi_part_num)
shift -= 16
}
return ip, nil, parts_len
}

func split_to_num(addr *string) (*big.Int, *string) {
//let mut ip = 0;
pre_post := strings.Split(strings.TrimSpace(*addr), "::")
if len(pre_post) > 2 {
tmp := fmt.Sprintf("IPv6 only allow one :: %s", addr)
return nil, &tmp
}
if len(pre_post) == 2 {
//println!("{}=::={}", pre_post[0], pre_post[1]);
pre, err, pre_parts := split_on_colon(&pre_post[0])
if err != nil {
return nil, err
}
post, err, _ := split_on_colon(&pre_post[1])
if err != nil {
return nil, err
}
// println!("pre:{} post:{}", pre_parts, post_parts);
return big.NewInt(0).Add(pre.Lsh(pre, 128-(pre_parts*16)), post), nil
}
//println!("split_to_num:no double:{}", addr);
ret, err, parts := split_on_colon(addr)
if err != nil {
return nil, err
}
if parts != 128/16 {
tmp := fmt.Sprintf("incomplete IPv6")
return nil, &tmp
}
return ret, nil
}

func Is_valid_ipv6(addr *string) bool {
_, err := split_to_num(addr)
return err != nil
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package ipaddress_impl
package ipaddress

import "strings"

Expand All @@ -10,42 +10,17 @@ import "sort"
// import "regexp"
import "fmt"

import "../ip_bits"
// import "../ip_bits"
import "../ip_version"
import "../prefix"
// import "./data"
import "bytes"

// import "../ip_version"
// import "../ipaddress"
// import "../ipv4"
// import "../ipv6"

type ResultIPAddress interface {
IsOk() bool
IsErr() bool
Unwrap() *IPAddress
UnwrapErr() *string
}

type ResultIPAddresses interface {
IsOk() bool
IsErr() bool
Unwrap() *[]IPAddress
UnwrapErr() *string
}

type IPAddress struct {
Ip_bits *ip_bits.IpBits
Host_address big.Int
Prefix prefix.Prefix
Mapped *IPAddress
Vt_is_private func(*IPAddress) bool
Vt_is_loopback func(*IPAddress) bool
Vt_to_ipv6 func(*IPAddress) IPAddress
Vt_parse_netmask func(*string) (*uint8, *string)
Vt_aggregate func(*[]IPAddress) []IPAddress
// Vt_sum_first_found
}

type Error struct {
err *string
Expand Down Expand Up @@ -103,9 +78,7 @@ func (self *IPAddress) Clone() IPAddress {
mapped,
self.Vt_is_private,
self.Vt_is_loopback,
self.Vt_to_ipv6,
self.Vt_parse_netmask,
self.Vt_aggregate}
self.Vt_to_ipv6}
}

func (self *IPAddress) String() string {
Expand Down Expand Up @@ -154,8 +127,8 @@ func (self *IPAddress) Equal(other IPAddress) bool {
/// //=> IPAddress::IPv6::Mapped
///

func (self *IPAddress) Split_at_slash(str string) (string, *string) {
trimmed := strings.TrimSpace(str)
func Split_at_slash(str *string) (string, *string) {
trimmed := strings.TrimSpace(*str)
slash := strings.Split(trimmed, "/")
addr := ""
if len(slash) >= 1 {
Expand All @@ -177,9 +150,7 @@ func (self *IPAddress) From(addr *big.Int, prefix *prefix.Prefix) IPAddress {
self.Mapped,
self.Vt_is_private,
self.Vt_is_loopback,
self.Vt_to_ipv6,
self.Vt_parse_netmask,
self.Vt_aggregate}
self.Vt_to_ipv6}
}

/// True if the object is an IPv4 address
Expand Down Expand Up @@ -369,7 +340,7 @@ func (self *IPAddress) Change_prefix(num uint8) ResultIPAddress {
}

func (self *IPAddress) Change_netmask(my_str *string) ResultIPAddress {
nm, err := self.Vt_parse_netmask(my_str)
nm, err := Parse_netmask_to_prefix(my_str)
if err != nil {
return &Error{err}
}
Expand Down Expand Up @@ -518,7 +489,7 @@ func (self *IPAddress) sub(other *IPAddress) big.Int {
}

func (self *IPAddress) Add(other *IPAddress) []IPAddress {
return self.Vt_aggregate(&[]IPAddress{*self, *other})
return Aggregate(&[]IPAddress{*self, *other})
}

/// Returns a new IPv4 object with the
Expand Down Expand Up @@ -935,7 +906,7 @@ func sorting(ips []IPAddress) {
sort.Sort(s)
}

func remove(stack []IPAddress, idx int) []IPAddress {
func remove_ipaddress(stack []IPAddress, idx int) []IPAddress {
var p []IPAddress
for i, v := range stack {
if i != idx {
Expand Down Expand Up @@ -1002,7 +973,7 @@ func Aggregate(networks *[]IPAddress) []IPAddress {
if stack[first].Includes(&stack[second]) {
pos = pos - 2
// println!("remove:1:{}:{}:{}=>{}", first, second, stack_len, pos + 1);
remove(stack, pos_to_idx(pos+1, stack_len))
remove_ipaddress(stack, pos_to_idx(pos+1, stack_len))
} else {
tmp := stack[first].Prefix.Sub(1)
stack[first].Prefix = *tmp.Unwrap()
Expand All @@ -1014,7 +985,7 @@ func Aggregate(networks *[]IPAddress) []IPAddress {
pos = pos - 2
idx := pos_to_idx(pos, stack_len)
stack[idx] = stack[first].Clone() // kaputt
remove(stack, pos_to_idx(pos+1, stack_len))
remove_ipaddress(stack, pos_to_idx(pos+1, stack_len))
// println!("remove-2:{}:{}", pos + 1, stack_len);
pos = pos - 1 // backtrack
} else {
Expand Down Expand Up @@ -1168,7 +1139,7 @@ func Sum_first_found(arr *[]IPAddress) []IPAddress {
// println!("dup:{}:{}:{}", dup.len(), i, a.len());
if len(a) == 1 {
dup[i] = (a)[0].Clone()
remove(dup, i+1)
remove_ipaddress(dup, i+1)
break
}
}
Expand Down
Loading

0 comments on commit bfd33d1

Please sign in to comment.