Class: Innodb::Cursor
- Inherits:
-
Object
- Object
- Innodb::Cursor
- Defined in:
- lib/innodb/cursor.rb
Overview
A cursor to walk through InnoDB data structures to read fields.
Instance Method Summary collapse
-
#adjust(relative_offset) ⇒ Object
Adjust the current cursor to a new relative position.
-
#backward ⇒ Object
Set the direction of the cursor to “backward”.
-
#forward ⇒ Object
Set the direction of the cursor to “forward”.
-
#get_bit_array(num_bits) ⇒ Object
Read an array of 1-bit integers.
-
#get_bytes(length) ⇒ Object
Return raw bytes.
-
#get_hex(length) ⇒ Object
Return raw bytes as hex.
-
#get_i_sint16 ⇒ Object
Read an InnoDB-munged signed 16-bit integer.
-
#get_i_sint24 ⇒ Object
Read an InnoDB-munged signed 24-bit integer.
-
#get_i_sint32 ⇒ Object
Read an InnoDB-munged signed 32-bit integer.
-
#get_i_sint64 ⇒ Object
Read an InnoDB-munged signed 64-bit integer.
-
#get_i_sint8 ⇒ Object
Read an InnoDB-munged signed 8-bit integer.
-
#get_i_sint_by_size(size) ⇒ Object
Read an InnoDB-munged signed integer given its size in bytes.
-
#get_ic_uint32 ⇒ Object
Read an InnoDB-compressed unsigned 32-bit integer.
-
#get_sint16(offset = nil) ⇒ Object
Read a big-endian signed 16-bit integer.
-
#get_uint16(offset = nil) ⇒ Object
Read a big-endian unsigned 16-bit integer.
-
#get_uint24(offset = nil) ⇒ Object
Read a big-endian unsigned 24-bit integer.
-
#get_uint32(offset = nil) ⇒ Object
Read a big-endian unsigned 32-bit integer.
-
#get_uint64(offset = nil) ⇒ Object
Read a big-endian unsigned 64-bit integer.
-
#get_uint8(offset = nil) ⇒ Object
Read an unsigned 8-bit integer.
-
#get_uint_by_size(size) ⇒ Object
Read a big-endian unsigned integer given its size in bytes.
-
#initialize(buffer, offset) ⇒ Cursor
constructor
A new instance of Cursor.
-
#peek ⇒ Object
Execute a block and restore the cursor to the previous position after the block returns.
-
#pop ⇒ Object
Restore the last cursor position.
-
#position ⇒ Object
Return the position of the current cursor.
-
#push(offset = nil) ⇒ Object
Save the current cursor position and start a new (nested, stacked) cursor.
-
#read_and_advance(length) ⇒ Object
Read a number of bytes forwards or backwards from the current cursor position and adjust the cursor position by that amount.
-
#seek(offset) ⇒ Object
Move the current cursor to a new absolute position.
Constructor Details
#initialize(buffer, offset) ⇒ Cursor
Returns a new instance of Cursor.
5 6 7 8 9 |
# File 'lib/innodb/cursor.rb', line 5 def initialize(buffer, offset) @buffer = buffer @cursor = [ offset ] @direction = :forward end |
Instance Method Details
#adjust(relative_offset) ⇒ Object
Adjust the current cursor to a new relative position.
35 36 37 38 |
# File 'lib/innodb/cursor.rb', line 35 def adjust(relative_offset) @cursor[0] += relative_offset self end |
#backward ⇒ Object
Set the direction of the cursor to “backward”.
18 19 20 21 |
# File 'lib/innodb/cursor.rb', line 18 def backward @direction = :backward self end |
#forward ⇒ Object
Set the direction of the cursor to “forward”.
12 13 14 15 |
# File 'lib/innodb/cursor.rb', line 12 def forward @direction = :forward self end |
#get_bit_array(num_bits) ⇒ Object
Read an array of 1-bit integers.
221 222 223 224 225 226 |
# File 'lib/innodb/cursor.rb', line 221 def get_bit_array(num_bits) size = (num_bits + 7) / 8 data = read_and_advance(size) bit_array = BinData::Array.new(:type => :bit1, :initial_length => size * 8) bit_array.read(data).to_ary end |
#get_bytes(length) ⇒ Object
Return raw bytes.
82 83 84 |
# File 'lib/innodb/cursor.rb', line 82 def get_bytes(length) read_and_advance(length) end |
#get_hex(length) ⇒ Object
Return raw bytes as hex.
87 88 89 |
# File 'lib/innodb/cursor.rb', line 87 def get_hex(length) read_and_advance(length).bytes.map { |c| "%02x" % c }.join end |
#get_i_sint16 ⇒ Object
Read an InnoDB-munged signed 16-bit integer.
179 180 181 182 |
# File 'lib/innodb/cursor.rb', line 179 def get_i_sint16 data = read_and_advance(2) BinData::Int16be.read(data) ^ (-1 << 15) end |
#get_i_sint24 ⇒ Object
Read an InnoDB-munged signed 24-bit integer.
185 186 187 188 |
# File 'lib/innodb/cursor.rb', line 185 def get_i_sint24 data = read_and_advance(3) BinData::Int24be.read(data) ^ (-1 << 23) end |
#get_i_sint32 ⇒ Object
Read an InnoDB-munged signed 32-bit integer.
191 192 193 194 |
# File 'lib/innodb/cursor.rb', line 191 def get_i_sint32 data = read_and_advance(4) BinData::Int32be.read(data) ^ (-1 << 31) end |
#get_i_sint64 ⇒ Object
Read an InnoDB-munged signed 64-bit integer.
197 198 199 200 |
# File 'lib/innodb/cursor.rb', line 197 def get_i_sint64 data = read_and_advance(8) BinData::Int64be.read(data) ^ (-1 << 63) end |
#get_i_sint8 ⇒ Object
Read an InnoDB-munged signed 8-bit integer.
173 174 175 176 |
# File 'lib/innodb/cursor.rb', line 173 def get_i_sint8 data = read_and_advance(1) BinData::Int8.read(data) ^ (-1 << 7) end |
#get_i_sint_by_size(size) ⇒ Object
Read an InnoDB-munged signed integer given its size in bytes.
203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 |
# File 'lib/innodb/cursor.rb', line 203 def get_i_sint_by_size(size) case size when 1 get_i_sint8 when 2 get_i_sint16 when 3 get_i_sint24 when 4 get_i_sint32 when 8 get_i_sint64 else raise "Not implemented" end end |
#get_ic_uint32 ⇒ Object
Read an InnoDB-compressed unsigned 32-bit integer.
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 |
# File 'lib/innodb/cursor.rb', line 152 def get_ic_uint32 flag = peek { get_uint8 } case when flag < 0x80 get_uint8 when flag < 0xc0 get_uint16 & 0x7fff when flag < 0xe0 get_uint24 & 0x3fffff when flag < 0xf0 get_uint32 & 0x1fffffff when flag == 0xf0 adjust(+1) # Skip the flag. get_uint32 else raise "Invalid flag #{flag.to_s(16)} seen" end end |
#get_sint16(offset = nil) ⇒ Object
Read a big-endian signed 16-bit integer.
106 107 108 109 110 |
# File 'lib/innodb/cursor.rb', line 106 def get_sint16(offset=nil) seek(offset) data = read_and_advance(2) BinData::Int16be.read(data) end |
#get_uint16(offset = nil) ⇒ Object
Read a big-endian unsigned 16-bit integer.
99 100 101 102 103 |
# File 'lib/innodb/cursor.rb', line 99 def get_uint16(offset=nil) seek(offset) data = read_and_advance(2) BinData::Uint16be.read(data) end |
#get_uint24(offset = nil) ⇒ Object
Read a big-endian unsigned 24-bit integer.
113 114 115 116 117 |
# File 'lib/innodb/cursor.rb', line 113 def get_uint24(offset=nil) seek(offset) data = read_and_advance(3) BinData::Uint24be.read(data) end |
#get_uint32(offset = nil) ⇒ Object
Read a big-endian unsigned 32-bit integer.
120 121 122 123 124 |
# File 'lib/innodb/cursor.rb', line 120 def get_uint32(offset=nil) seek(offset) data = read_and_advance(4) BinData::Uint32be.read(data) end |
#get_uint64(offset = nil) ⇒ Object
Read a big-endian unsigned 64-bit integer.
127 128 129 130 131 |
# File 'lib/innodb/cursor.rb', line 127 def get_uint64(offset=nil) seek(offset) data = read_and_advance(8) BinData::Uint64be.read(data) end |
#get_uint8(offset = nil) ⇒ Object
Read an unsigned 8-bit integer.
92 93 94 95 96 |
# File 'lib/innodb/cursor.rb', line 92 def get_uint8(offset=nil) seek(offset) data = read_and_advance(1) BinData::Uint8.read(data) end |
#get_uint_by_size(size) ⇒ Object
Read a big-endian unsigned integer given its size in bytes.
134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 |
# File 'lib/innodb/cursor.rb', line 134 def get_uint_by_size(size) case size when 1 get_uint8 when 2 get_uint16 when 3 get_uint24 when 4 get_uint32 when 8 get_uint64 else raise "Not implemented" end end |
#peek ⇒ Object
Execute a block and restore the cursor to the previous position after the block returns. Return the block’s return value after restoring the cursor.
56 57 58 59 60 61 62 |
# File 'lib/innodb/cursor.rb', line 56 def peek raise "No block given" unless block_given? push result = yield pop result end |
#pop ⇒ Object
Restore the last cursor position.
47 48 49 50 51 |
# File 'lib/innodb/cursor.rb', line 47 def pop raise "No cursors to pop" unless @cursor.size > 1 @cursor.shift self end |
#position ⇒ Object
Return the position of the current cursor.
24 25 26 |
# File 'lib/innodb/cursor.rb', line 24 def position @cursor[0] end |
#push(offset = nil) ⇒ Object
Save the current cursor position and start a new (nested, stacked) cursor.
41 42 43 44 |
# File 'lib/innodb/cursor.rb', line 41 def push(offset=nil) @cursor.unshift(offset.nil? ? @cursor[0] : offset) self end |
#read_and_advance(length) ⇒ Object
Read a number of bytes forwards or backwards from the current cursor position and adjust the cursor position by that amount.
66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/innodb/cursor.rb', line 66 def read_and_advance(length) data = nil #print "data(#{@cursor[0]}..." case @direction when :forward data = @buffer.data(@cursor[0], length) adjust(length) when :backward adjust(-length) data = @buffer.data(@cursor[0], length) end #puts "#{@cursor[0]}) = #{data.bytes.map { |n| "%02x" % n }.join}" data end |
#seek(offset) ⇒ Object
Move the current cursor to a new absolute position.
29 30 31 32 |
# File 'lib/innodb/cursor.rb', line 29 def seek(offset) @cursor[0] = offset if offset self end |