Class: CryptoconditionsRuby::Utils::Reader

Inherits:
Object
  • Object
show all
Defined in:
lib/cryptoconditions_ruby/utils/reader.rb

Constant Summary collapse

HIGH_BIT =
0x80
LOWER_SEVEN_BITS =
0x7F
MAX_INT_BYTES =
6

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(buffer) ⇒ Reader

Returns a new instance of Reader.



7
8
9
10
11
# File 'lib/cryptoconditions_ruby/utils/reader.rb', line 7

def initialize(buffer)
  @buffer = buffer
  @cursor = 0
  @bookmarks = []
end

Instance Attribute Details

#bookmarksObject

Returns the value of attribute bookmarks.



6
7
8
# File 'lib/cryptoconditions_ruby/utils/reader.rb', line 6

def bookmarks
  @bookmarks
end

#bufferObject

Returns the value of attribute buffer.



6
7
8
# File 'lib/cryptoconditions_ruby/utils/reader.rb', line 6

def buffer
  @buffer
end

#cursorObject

Returns the value of attribute cursor.



6
7
8
# File 'lib/cryptoconditions_ruby/utils/reader.rb', line 6

def cursor
  @cursor
end

Class Method Details

.from_source(source) ⇒ Object



13
14
15
# File 'lib/cryptoconditions_ruby/utils/reader.rb', line 13

def self.from_source(source)
  source.is_a?(self) ? source : new(source)
end

Instance Method Details

#bookmarkObject



17
18
19
# File 'lib/cryptoconditions_ruby/utils/reader.rb', line 17

def bookmark
  self.bookmarks << cursor
end

#ensure_available(num_bytes) ⇒ Object



25
26
27
28
29
# File 'lib/cryptoconditions_ruby/utils/reader.rb', line 25

def ensure_available(num_bytes)
  if buffer.length < cursor + num_bytes
    raise RangeError.new("Tried to read #{num_bytes} bytes, but only #{buffer.length - cursor} bytes available")
  end
end

#peek(num_bytes) ⇒ Object



111
112
113
# File 'lib/cryptoconditions_ruby/utils/reader.rb', line 111

def peek(num_bytes)
  read(num_bytes, peek: true)
end

#peek_octet_string(length) ⇒ Object



71
72
73
# File 'lib/cryptoconditions_ruby/utils/reader.rb', line 71

def peek_octet_string(length)
  peek(length)
end

#peek_uint(length) ⇒ Object



41
42
43
# File 'lib/cryptoconditions_ruby/utils/reader.rb', line 41

def peek_uint(length)
  read_uint(length, peek: true)
end

#peek_uint16Object



140
141
142
# File 'lib/cryptoconditions_ruby/utils/reader.rb', line 140

def peek_uint16
  peek_uint(2)
end

#peek_uint32Object



144
145
146
# File 'lib/cryptoconditions_ruby/utils/reader.rb', line 144

def peek_uint32
  peek_uint(4)
end

#peek_uint64Object



148
149
150
# File 'lib/cryptoconditions_ruby/utils/reader.rb', line 148

def peek_uint64
  peek_uint(8)
end

#peek_uint8Object



136
137
138
# File 'lib/cryptoconditions_ruby/utils/reader.rb', line 136

def peek_uint8
  peek_uint(1)
end

#peek_var_octet_stringObject



93
94
95
96
# File 'lib/cryptoconditions_ruby/utils/reader.rb', line 93

def peek_var_octet_string
  bookmark
  read_var_octet_string.tap { restore }
end

#peek_var_uintObject



58
59
60
61
# File 'lib/cryptoconditions_ruby/utils/reader.rb', line 58

def peek_var_uint
  bookmark
  read_var_uint.tap { restore }
end

#read(num_bytes, peek: false) ⇒ Object



103
104
105
106
107
108
109
# File 'lib/cryptoconditions_ruby/utils/reader.rb', line 103

def read(num_bytes, peek: false)
  ensure_available(num_bytes)

  value = buffer[cursor...(cursor + num_bytes)]
  self.cursor += num_bytes unless peek
  value
end

#read_length_prefixObject



79
80
81
82
83
84
85
86
# File 'lib/cryptoconditions_ruby/utils/reader.rb', line 79

def read_length_prefix
  length = read_uint8

  if length & HIGH_BIT > 0
    return read_uint(length & LOWER_SEVEN_BITS)
  end
  length
end

#read_octet_string(length) ⇒ Object



67
68
69
# File 'lib/cryptoconditions_ruby/utils/reader.rb', line 67

def read_octet_string(length)
  read(length)
end

#read_uint(length, peek: false) ⇒ Object



31
32
33
34
35
36
37
38
39
# File 'lib/cryptoconditions_ruby/utils/reader.rb', line 31

def read_uint(length, peek: false)
  if length > MAX_INT_BYTES
    raise RangeError.new("Tried to read too large integer (requested: #{length}, max: #{MAX_INT_BYTES})")
  end
  ensure_available(length)
  value = buffer[cursor...(cursor + length)]
  self.cursor += length unless peek
  CryptoconditionsRuby::Utils::Bytes.new(value).to_i(16)
end

#read_uint16Object



124
125
126
# File 'lib/cryptoconditions_ruby/utils/reader.rb', line 124

def read_uint16
  read_uint(2)
end

#read_uint32Object



128
129
130
# File 'lib/cryptoconditions_ruby/utils/reader.rb', line 128

def read_uint32
  read_uint(4)
end

#read_uint64Object



132
133
134
# File 'lib/cryptoconditions_ruby/utils/reader.rb', line 132

def read_uint64
  read_uint(8)
end

#read_uint8Object



120
121
122
# File 'lib/cryptoconditions_ruby/utils/reader.rb', line 120

def read_uint8
  read_uint(1)
end

#read_var_octet_stringObject



88
89
90
91
# File 'lib/cryptoconditions_ruby/utils/reader.rb', line 88

def read_var_octet_string
  length = read_length_prefix
  read(length)
end

#read_var_uintObject



49
50
51
52
53
54
55
56
# File 'lib/cryptoconditions_ruby/utils/reader.rb', line 49

def read_var_uint
  buffer = read_var_octet_string
  if buffer.length > MAX_INT_BYTES
    raise RangeError.new("UInt of length #{butter.length} too large to parse as integer(#{MAX_INT_BYTES})")
  end
  value = buffer[0...buffer.length]
  CryptoconditionsRuby::Utils::Bytes.new(value).to_i(16)
end

#restoreObject



21
22
23
# File 'lib/cryptoconditions_ruby/utils/reader.rb', line 21

def restore
  self.cursor = bookmarks.pop
end

#skip(num_bytes) ⇒ Object



115
116
117
118
# File 'lib/cryptoconditions_ruby/utils/reader.rb', line 115

def skip(num_bytes)
  ensure_available(num_bytes)
  self.cursor += num_bytes
end

#skip_octet_string(length) ⇒ Object



75
76
77
# File 'lib/cryptoconditions_ruby/utils/reader.rb', line 75

def skip_octet_string(length)
  skip(length)
end

#skip_uint(length) ⇒ Object



45
46
47
# File 'lib/cryptoconditions_ruby/utils/reader.rb', line 45

def skip_uint(length)
  skip(length)
end

#skip_uint16Object



156
157
158
# File 'lib/cryptoconditions_ruby/utils/reader.rb', line 156

def skip_uint16
  skip_uint(2)
end

#skip_uint32Object



160
161
162
# File 'lib/cryptoconditions_ruby/utils/reader.rb', line 160

def skip_uint32
  skip_uint(4)
end

#skip_uint64Object



164
165
166
# File 'lib/cryptoconditions_ruby/utils/reader.rb', line 164

def skip_uint64
  skip_uint(8)
end

#skip_uint8Object



152
153
154
# File 'lib/cryptoconditions_ruby/utils/reader.rb', line 152

def skip_uint8
  skip_uint(1)
end

#skip_var_octet_stringObject



98
99
100
101
# File 'lib/cryptoconditions_ruby/utils/reader.rb', line 98

def skip_var_octet_string
  length = read_length_prefix
  skip(length)
end

#skip_var_uintObject



63
64
65
# File 'lib/cryptoconditions_ruby/utils/reader.rb', line 63

def skip_var_uint
  skip_var_octet_string
end