Class: ScanBeacon::Beacon::Field

Inherits:
Object
  • Object
show all
Includes:
Comparable
Defined in:
lib/scan_beacon/beacon/field.rb

Constant Summary collapse

ENCODING =
"ASCII-8BIT".freeze
NULL_BYTE =
"\x00".force_encoding(ENCODING).freeze

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(opts = {}) ⇒ Field

Returns a new instance of Field.



8
9
10
# File 'lib/scan_beacon/beacon/field.rb', line 8

def initialize(opts = {})
  self.set_data(opts)
end

Class Method Details

.field_with_length(id, length) ⇒ Object



12
13
14
15
16
17
18
19
# File 'lib/scan_beacon/beacon/field.rb', line 12

def self.field_with_length(id, length)
  return id if id.is_a? self
  if id.is_a? String
    self.new hex: id, length: length
  elsif id.is_a? Integer
    self.new number: id, length: length
  end
end

Instance Method Details

#<=>(other) ⇒ Object



96
97
98
99
100
101
102
# File 'lib/scan_beacon/beacon/field.rb', line 96

def <=> (other)
  if other.is_a? self.class
    self.bytes <=> other.bytes
  else
    self.value <=> other
  end
end

#bytesObject



55
56
57
# File 'lib/scan_beacon/beacon/field.rb', line 55

def bytes
  @data
end

#hashObject



106
107
108
# File 'lib/scan_beacon/beacon/field.rb', line 106

def hash
  @data.hash
end

#inspectObject



51
52
53
# File 'lib/scan_beacon/beacon/field.rb', line 51

def inspect
  "<Beacon::Field value=#{self.value.inspect}>"
end

#set_data(opts = {}) ⇒ Object



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/scan_beacon/beacon/field.rb', line 21

def set_data(opts = {})
  bytes = opts[:bytes]
  hex = opts[:hex]
  number = opts[:number]
  length = opts[:length]
  if bytes
    @data = bytes.force_encoding(ENCODING)
  elsif hex
    # zero pad hex if needed
    hex = "0"*(length*2-hex.size) + hex if length and hex.size < length*2
    hex.gsub!("-","")
    @data = [hex].pack("H*")
  elsif number
    raise ArgumentError.new("Must also give a field length when you give a number") if length.nil?
    set_data(hex: number.to_s(16), length: length)
  end
end

#to_fObject



81
82
83
84
85
86
87
88
89
90
# File 'lib/scan_beacon/beacon/field.rb', line 81

def to_f
  case @data.size
  when 2
    # 8:8 format
    integer_part, decimal_part = @data.unpack("cC")
    integer_part + (decimal_part / 256.0)
  else
    nil
  end
end

#to_hexObject



92
93
94
# File 'lib/scan_beacon/beacon/field.rb', line 92

def to_hex
  @data.unpack("H*")[0]
end

#to_iObject



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/scan_beacon/beacon/field.rb', line 59

def to_i
  size = @data.size
  case size
  when 0
    nil
  when 1
    @data.unpack("C")[0]
  when 2
    @data.unpack("S>")[0]
  when 3
    (NULL_BYTE + @data).unpack("L>")[0]
  when 4
    @data.unpack("L>")[0]
  when 5,6,7
    (NULL_BYTE*(8-size) + @data).unpack("Q>")[0]
  when 8
    @data.unpack("Q>")[0]
  else
    @data[-8..-1].unpack("Q>")[0]
  end
end

#to_sObject



47
48
49
# File 'lib/scan_beacon/beacon/field.rb', line 47

def to_s
  value.to_s
end

#valueObject



39
40
41
42
43
44
45
# File 'lib/scan_beacon/beacon/field.rb', line 39

def value
  if @data.size < 6
    self.to_i
  else
    self.to_hex
  end
end