Class: SerialNumber

Inherits:
Object
  • Object
show all
Defined in:
lib/mock_dns_server/serial_number.rb

Overview

Handles serial values, adjusting correctly for wraparound.

From the DNS and Bind book, p. 139:

“The DNS serial number is a 32-bit unsigned integer whose value ranges from 0 to 4,294,967,295. The serial number uses sequence space arithmetic, which means that for any serial number, half the numbers in the number space (2,147,483,647 numbers) are less than the serial number, and half the numbers are larger.”“

Constant Summary collapse

MIN_VALUE =
0
MAX_VALUE =

(4_294_967_295)

0xFFFF_FFFF
MAX_DIFFERENCE =

(2_147_483_648)

0x8000_0000

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(value) ⇒ SerialNumber

Returns a new instance of SerialNumber.



20
21
22
23
# File 'lib/mock_dns_server/serial_number.rb', line 20

def initialize(value)
  self.class.validate(value)
  @value = value
end

Instance Attribute Details

#valueObject

Returns the value of attribute value.



18
19
20
# File 'lib/mock_dns_server/serial_number.rb', line 18

def value
  @value
end

Class Method Details

.compare(sss1, sss2) ⇒ Object



62
63
64
# File 'lib/mock_dns_server/serial_number.rb', line 62

def self.compare(sss1, sss2)
  compare_values(sss1.value, sss2.value)
end

.compare_values(value_1, value_2) ⇒ Object



47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/mock_dns_server/serial_number.rb', line 47

def self.compare_values(value_1, value_2)
  distance = (value_1 - value_2).abs

  if distance == 0
    0
  elsif distance < MAX_DIFFERENCE
    value_1 - value_2
  elsif distance > MAX_DIFFERENCE
    value_2 - value_1
  else # distance == MAX_DIFFERENCE
    raise "Cannot compare 2 numbers whose difference is exactly #{MAX_DIFFERENCE.to_s(16)} (#{value_1}, #{value_2})."
  end
end

.next_serial_value(value) ⇒ Object



67
68
69
70
# File 'lib/mock_dns_server/serial_number.rb', line 67

def self.next_serial_value(value)
  validate(value)
  value == MAX_VALUE ? 0 : value + 1
end

.object(thing) ⇒ Object

Call this when you have an object that may be either a SerialNumber or a Fixnum/Bignum, and you want to ensure that you have a SerialNumber.



29
30
31
32
33
34
35
36
37
# File 'lib/mock_dns_server/serial_number.rb', line 29

def self.object(thing)
  if thing.is_a?(SerialNumber)
    thing
  elsif thing.nil?
    nil
  else
    SerialNumber.new(thing)
  end
end

.validate(value) ⇒ Object



40
41
42
43
44
# File 'lib/mock_dns_server/serial_number.rb', line 40

def self.validate(value)
  if value < MIN_VALUE || value > MAX_VALUE
    raise "Invalid value (#{value}), must be between #{MIN_VALUE} and #{MAX_VALUE}."
  end
end

Instance Method Details

#<(other) ⇒ Object



88
89
90
# File 'lib/mock_dns_server/serial_number.rb', line 88

def <(other)
  self.<=>(other) < 0
end

#<=(other) ⇒ Object



98
99
100
# File 'lib/mock_dns_server/serial_number.rb', line 98

def <=(other)
  self.<=>(other) <= 0
end

#<=>(other) ⇒ Object



78
79
80
# File 'lib/mock_dns_server/serial_number.rb', line 78

def <=>(other)
  self.class.compare(self, other)
end

#==(other) ⇒ Object



103
104
105
106
# File 'lib/mock_dns_server/serial_number.rb', line 103

def ==(other)
  self.class == other.class &&
  self.value == other.value
end

#>(other) ⇒ Object



83
84
85
# File 'lib/mock_dns_server/serial_number.rb', line 83

def >(other)
  self.<=>(other) > 0
end

#>=(other) ⇒ Object



93
94
95
# File 'lib/mock_dns_server/serial_number.rb', line 93

def >=(other)
  self.<=>(other) >= 0
end

#eql?(other) ⇒ Boolean

Returns:

  • (Boolean)


113
114
115
# File 'lib/mock_dns_server/serial_number.rb', line 113

def eql?(other)
  self.==(other)
end

#hashObject



109
110
111
# File 'lib/mock_dns_server/serial_number.rb', line 109

def hash
  value.hash
end

#next_serialObject



73
74
75
# File 'lib/mock_dns_server/serial_number.rb', line 73

def next_serial
  self.class.new(self.class.next_serial_value(value))
end

#to_iObject

Can be used to normalize an object that may be a Fixnum or a SerialNumber to an int:



118
119
120
# File 'lib/mock_dns_server/serial_number.rb', line 118

def to_i
  value
end

#to_sObject



123
124
125
# File 'lib/mock_dns_server/serial_number.rb', line 123

def to_s
  "#{self.class}: value = #{value}"
end