1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397
|
//
// Copyright 2020-2022 Sean C Foley
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
package ipaddr
import (
"math"
"math/big"
"strconv"
)
type boolSetting struct {
isSet, val bool
}
var (
falseVal = false
trueVal = true
)
// A PrefixLen indicates the length of the prefix for an address, section, division grouping, segment, or division.
// The zero value, which is nil, indicates that there is no prefix length.
type PrefixLen = *PrefixBitCount
// ToPrefixLen converts the given int to a prefix length
func ToPrefixLen(i int) PrefixLen {
res := PrefixBitCount(i)
return &res
}
// BitCount represents a count of bits in an address, section, grouping, segment, or division.
// Using signed integers allows for easier arithmetic, avoiding bugs.
// However, all methods adjust bit counts to match address size,
// so negative bit counts or bit counts larger than address size are meaningless.
type BitCount = int // using signed integers allows for easier arithmetic
const maxBitCountInternal, minBitCountInternal = math.MaxUint8, 0
// A PrefixBitCount is the count of bits in a non-nil PrefixLen.
// For arithmetic, you may wish to use the signed integer type BitCount instead, which you can get from a PrefixLen using the Len method.
type PrefixBitCount uint8
// Len returns the length of the prefix. If the receiver is nil, representing the absence of a prefix length, returns 0.
// It will also return 0 if the receiver is a prefix with length of 0. To distinguish the two, compare the receiver with nil.
func (prefixBitCount *PrefixBitCount) Len() BitCount {
if prefixBitCount == nil {
return 0
}
return prefixBitCount.bitCount()
}
// IsNil returns true if this is nil, meaning it represents having no prefix length, or the absence of a prefix length
func (prefixBitCount *PrefixBitCount) IsNil() bool {
return prefixBitCount == nil
}
func (prefixBitCount *PrefixBitCount) bitCount() BitCount {
return BitCount(*prefixBitCount)
}
func (prefixBitCount *PrefixBitCount) copy() PrefixLen {
if prefixBitCount == nil {
return nil
}
res := *prefixBitCount
return &res
}
// Equal compares two PrefixLen values for equality. This method is intended for the PrefixLen type. BitCount values should be compared with the == operator.
func (prefixBitCount *PrefixBitCount) Equal(other PrefixLen) bool {
if prefixBitCount == nil {
return other == nil
}
return other != nil && prefixBitCount.bitCount() == other.bitCount()
}
// Matches compares a PrefixLen value with a bit count
func (prefixBitCount *PrefixBitCount) Matches(other BitCount) bool {
return prefixBitCount != nil && prefixBitCount.bitCount() == other
}
// Compare compares PrefixLen values, returning -1, 0, or 1 if this prefix length is less than, equal to, or greater than the given prefix length.
// This method is intended for the PrefixLen type. BitCount values should be compared with ==, >, <, >= and <= operators.
func (prefixBitCount *PrefixBitCount) Compare(other PrefixLen) int {
if prefixBitCount == nil {
if other == nil {
return 0
}
return 1
} else if other == nil {
return -1
}
return prefixBitCount.bitCount() - other.bitCount()
}
// String returns the bit count as a base-10 positive integer string, or "<nil>" if the receiver is a nil pointer.
func (prefixBitCount *PrefixBitCount) String() string {
if prefixBitCount == nil {
return nilString()
}
return strconv.Itoa(prefixBitCount.bitCount())
}
// HostBitCount is the count of bits in a host.
// For arithmetic, you may wish to use the signed integer type BitCount instead, which you can get from a HostBitCount using the Len method.
type HostBitCount uint8
// BitsForCount returns the number of bits required outside the prefix length
// for a single prefix block to span at least as many addresses as the given count.
// Mathematically, it is the ceiling of the base 2 logarithm of the given count.
// A count of zero returns nil.
func BitsForCount(count uint64) (result *HostBitCount) {
if count != 0 {
var res HostBitCount
countMinusOne := count - 1
if (countMinusOne & (0xfff0000000000000)) != 0 { // conversion to float64 will fail
count = (countMinusOne >> 53) + 1
res = 53
}
res += HostBitCount(math.Ilogb(float64((count << 1) - 1)))
return &res
}
return nil
}
// BlockSize is the reverse of BitsForCount, giving the total number of values when ranging across the number of host bits.
// The nil *HostBitCount returns 0.
func (hostBitCount *HostBitCount) BlockSize() *big.Int {
if hostBitCount == nil {
return bigZero()
}
return new(big.Int).Lsh(bigOneConst(), uint(*hostBitCount))
}
// Len returns the length of the host. If the receiver is nil, representing the absence of a host length, returns 0.
// It will also return 0 if the receiver has a host length of 0. To distinguish the two, compare the receiver with nil.
func (hostBitCount *HostBitCount) Len() BitCount {
if hostBitCount == nil {
return 0
}
return BitCount(*hostBitCount)
}
// String returns the bit count as a base-10 positive integer string, or "<nil>" if the receiver is a nil pointer.
func (hostBitCount *HostBitCount) String() string {
if hostBitCount == nil {
return nilString()
}
return strconv.Itoa(hostBitCount.Len())
}
// IsNil returns true if this is nil, meaning it represents having no identified host length.
func (hostBitCount *HostBitCount) IsNil() bool {
return hostBitCount == nil
}
var cachedPrefixBitCounts, cachedPrefixLens = initPrefLens()
func initPrefLens() ([]PrefixBitCount, []PrefixLen) {
cachedPrefBitcounts := make([]PrefixBitCount, maxBitCountInternal)
cachedPrefLens := make([]PrefixLen, maxBitCountInternal)
for i := 0; i <= IPv6BitCount; i++ {
cachedPrefBitcounts[i] = PrefixBitCount(i)
cachedPrefLens[i] = &cachedPrefBitcounts[i]
}
return cachedPrefBitcounts, cachedPrefLens
}
func cacheBitCount(i BitCount) PrefixLen {
if i < minBitCountInternal {
i = minBitCountInternal
}
if i < len(cachedPrefixBitCounts) {
return &cachedPrefixBitCounts[i]
}
if i > maxBitCountInternal {
i = maxBitCountInternal
}
res := PrefixBitCount(i)
return &res
}
func cachePrefix(i BitCount) *PrefixLen {
if i < minBitCountInternal {
i = minBitCountInternal
}
if i < len(cachedPrefixLens) {
return &cachedPrefixLens[i]
}
if i > maxBitCountInternal {
i = maxBitCountInternal
}
val := PrefixBitCount(i)
res := &val
return &res
}
func cachePrefixLen(external PrefixLen) PrefixLen {
if external == nil {
return nil
}
return cacheBitCount(external.bitCount())
}
var p PrefixLen
func cacheNilPrefix() *PrefixLen {
return &p
}
const maxPortNumInternal, minPortNumInternal = math.MaxUint16, 0
// Port represents the port of a UDP or TCP address. A nil value indicates no port.
type Port = *PortNum
type PortInt = int // using signed integers allows for easier arithmetic
// PortNum is the port number for a non-nil Port. For arithmetic, you might wish to use the signed integer type PortInt instead.
type PortNum uint16
func (portNum *PortNum) portNum() PortInt {
return PortInt(*portNum)
}
func (portNum *PortNum) copy() Port {
if portNum == nil {
return nil
}
res := *portNum
return &res
}
// Num converts to a PortPortIntNum, returning 0 if the receiver is nil.
func (portNum *PortNum) Num() PortInt {
if portNum == nil {
return 0
}
return PortInt(*portNum)
}
// Port dereferences this PortNum, while returning 0 if the receiver is nil.
func (portNum *PortNum) Port() PortNum {
if portNum == nil {
return 0
}
return *portNum
}
// Equal compares two Port values for equality.
func (portNum *PortNum) Equal(other Port) bool {
if portNum == nil {
return other == nil
}
return other != nil && portNum.portNum() == other.portNum()
}
// Matches compares a Port value with a port number.
func (portNum *PortNum) Matches(other PortInt) bool {
return portNum != nil && portNum.portNum() == other
}
// Compare compares PrefixLen values, returning -1, 0, or 1 if the receiver is less than, equal to, or greater than the argument.
func (portNum *PortNum) Compare(other Port) int {
if portNum == nil {
if other == nil {
return 0
}
return -1
} else if other == nil {
return 1
}
return portNum.portNum() - other.portNum()
}
// String returns the bit count as a base-10 positive integer string, or "<nil>" if the receiver is a nil pointer.
func (portNum *PortNum) String() string {
if portNum == nil {
return nilString()
}
return strconv.Itoa(portNum.portNum())
}
func cachePorts(i PortInt) Port {
if i < minPortNumInternal {
i = minPortNumInternal
} else if i > maxPortNumInternal {
i = maxPortNumInternal
}
res := PortNum(i)
return &res
}
func bigOne() *big.Int {
return big.NewInt(1)
}
var one = bigOne()
func bigOneConst() *big.Int {
return one
}
func bigZero() *big.Int {
return new(big.Int)
}
var zero = bigZero()
func bigZeroConst() *big.Int {
return zero
}
var minusOne = big.NewInt(-1)
func bigMinusOneConst() *big.Int {
return minusOne
}
func bigSixteen() *big.Int {
return big.NewInt(16)
}
func bigIsZero(val *BigDivInt) bool {
return len(val.Bits()) == 0 // slightly faster than div.value.BitLen() == 0
}
func bigIsOne(val *BigDivInt) bool {
return bigAbsIsOne(val) && val.Sign() > 0
}
func bigAbsIsOne(val *BigDivInt) bool {
bits := val.Bits()
return len(bits) == 1 && bits[0] == 1
}
func checkSubnet(item BitItem, prefixLength BitCount) BitCount {
return checkBitCount(prefixLength, item.GetBitCount())
}
func checkDiv(div DivisionType, prefixLength BitCount) BitCount {
return checkBitCount(prefixLength, div.GetBitCount())
}
func checkBitCount(prefixLength, max BitCount) BitCount {
if prefixLength > max {
return max
} else if prefixLength < 0 {
return 0
}
return prefixLength
}
func checkPrefLen(prefixLength PrefixLen, max BitCount) PrefixLen {
if prefixLength != nil {
prefLen := prefixLength.bitCount()
if prefLen > max {
return cacheBitCount(max)
} else if prefLen < 0 {
return cacheBitCount(0)
}
}
return prefixLength
}
// wrapperIterator notifies the iterator to the right when wrapperIterator reaches its final value
type wrappedIterator struct {
iterator Iterator[*IPAddressSegment]
finalValue []bool
indexi int
}
func (wrapped *wrappedIterator) HasNext() bool {
return wrapped.iterator.HasNext()
}
func (wrapped *wrappedIterator) Next() *IPAddressSegment {
iter := wrapped.iterator
next := iter.Next()
if !iter.HasNext() {
wrapped.finalValue[wrapped.indexi+1] = true
}
return next
}
|