package utils

import (
	
)

// IsIPv4 works the same way as net.ParseIP,
// but without check for IPv6 case and without returning net.IP slice, whereby IsIPv4 makes no allocations.
func ( string) bool {
	for  := 0;  < net.IPv4len; ++ {
		if len() == 0 {
			return false
		}

		if  > 0 {
			if [0] != '.' {
				return false
			}
			 = [1:]
		}

		,  := 0, 0

		for  = 0;  < len() && '0' <= [] && [] <= '9'; ++ {
			 = *10 + int([]-'0')
			if  >= 0xFF {
				return false
			}
		}

		if  == 0 || ( > 1 && [0] == '0') {
			return false
		}

		 = [:]
	}

	return len() == 0
}

// IsIPv6 works the same way as net.ParseIP,
// but without check for IPv4 case and without returning net.IP slice, whereby IsIPv6 makes no allocations.
func ( string) bool {
	 := -1 // position of ellipsis in ip

	// Might have leading ellipsis
	if len() >= 2 && [0] == ':' && [1] == ':' {
		 = 0
		 = [2:]
		// Might be only ellipsis
		if len() == 0 {
			return true
		}
	}

	// Loop, parsing hex numbers followed by colon.
	 := 0
	for  < net.IPv6len {
		// Hex number.
		,  := 0, 0

		for  = 0;  < len(); ++ {
			if '0' <= [] && [] <= '9' {
				 *= 16
				 += int([] - '0')
			} else if 'a' <= [] && [] <= 'f' {
				 *= 16
				 += int([]-'a') + 10
			} else if 'A' <= [] && [] <= 'F' {
				 *= 16
				 += int([]-'A') + 10
			} else {
				break
			}
			if  > 0xFFFF {
				return false
			}
		}
		if  == 0 ||  > 0xFFFF {
			return false
		}

		if  < len() && [] == '.' {
			if  < 0 &&  != net.IPv6len-net.IPv4len {
				return false
			}
			if +net.IPv4len > net.IPv6len {
				return false
			}

			if !IsIPv4() {
				return false
			}

			 = ""
			 += net.IPv4len
			break
		}

		// Save this 16-bit chunk.
		 += 2

		// Stop at end of string.
		 = [:]
		if len() == 0 {
			break
		}

		// Otherwise must be followed by colon and more.
		if [0] != ':' || len() == 1 {
			return false
		}
		 = [1:]

		// Look for ellipsis.
		if [0] == ':' {
			if  >= 0 { // already have one
				return false
			}
			 = 
			 = [1:]
			if len() == 0 { // can be at end
				break
			}
		}
	}

	// Must have used entire string.
	if len() != 0 {
		return false
	}

	// If didn't parse enough, expand ellipsis.
	if  < net.IPv6len {
		if  < 0 {
			return false
		}
	} else if  >= 0 {
		// Ellipsis must represent at least one 0 group.
		return false
	}
	return true
}