Class: Flt::Bytes
- Inherits:
-
String
- Object
- String
- Flt::Bytes
- Defined in:
- lib/float-formats/bytes.rb
Class Method Summary collapse
-
.from_bitfields(lens, fields, byte_endianness = :little_endian, bits_little_endian = false) ⇒ Object
pack fixed-width bit-fields as integers into a byte string.
- .from_bits(bits, byte_endianness = :little_endian, bits_little_endian = false, nbits = nil) ⇒ Object
-
.from_hex(hex) ⇒ Object
generate a byte string from an hex representation.
-
.from_i(i, len = 0, byte_endianness = :little_endian, bits_little_endian = false) ⇒ Object
Convert an integer to a byte string.
Instance Method Summary collapse
- #+(b) ⇒ Object
- #[](*params) ⇒ Object
- #[]=(i, v) ⇒ Object
- #_get_str ⇒ Object
- #_set_str ⇒ Object
- #convert_endianness(from_endianness, to_endianness) ⇒ Object
-
#convert_endianness!(from_endianness, to_endianness) ⇒ Object
Supported endianness modes for byte strings are: [
:little_endian
] (Intel order): least significant bytes come first. - #dup ⇒ Object
-
#initialize(bytes) ⇒ Bytes
constructor
A new instance of Bytes.
- #reverse_byte_bits ⇒ Object
-
#reverse_byte_bits! ⇒ Object
Reverse the order of the bits in each byte.
- #reverse_byte_nibbles ⇒ Object
-
#reverse_byte_nibbles! ⇒ Object
Reverse the order of the nibbles in each byte.
- #reverse_byte_pairs ⇒ Object
-
#reverse_byte_pairs! ⇒ Object
reverse the order of bytes in 16-bit words.
- #size ⇒ Object
-
#to_bitfields(lens, byte_endianness = :little_endian, bits_little_endian = false) ⇒ Object
convert a byte string to separate fixed-width bit-fields as integers.
- #to_bits(byte_endianness = :little_endian, bits_little_endian = false, nbits = nil) ⇒ Object
-
#to_hex(sep_bytes = false) ⇒ Object
return an hex representation of a byte string.
-
#to_i(byte_endianness = :little_endian, bits_little_endian = false) ⇒ Object
Convert a byte string to an integer.
Constructor Details
#initialize(bytes) ⇒ Bytes
Returns a new instance of Bytes.
107 108 109 110 111 112 113 114 115 116 117 118 |
# File 'lib/float-formats/bytes.rb', line 107 def initialize(bytes) case bytes when Bytes @bytes = bytes.to_s when Array @bytes = bytes.pack("C*") else @bytes = bytes.to_str end @bytes.force_encoding(Encoding::BINARY) if RUBY_VERSION>="1.9.0" super @bytes end |
Class Method Details
.from_bitfields(lens, fields, byte_endianness = :little_endian, bits_little_endian = false) ⇒ Object
pack fixed-width bit-fields as integers into a byte string
292 293 294 295 296 297 298 299 300 301 302 303 304 305 |
# File 'lib/float-formats/bytes.rb', line 292 def Bytes.from_bitfields(lens,fields,byte_endianness=:little_endian, bits_little_endian=false) i = 0 lens = lens.reverse fields = fields.reverse bits = 0 (0...lens.size).each do |j| i <<= lens[j] i |= fields[j] bits += lens[j] end from_i i,(bits+7)/8,byte_endianness, bits_little_endian end |
.from_bits(bits, byte_endianness = :little_endian, bits_little_endian = false, nbits = nil) ⇒ Object
313 314 315 316 |
# File 'lib/float-formats/bytes.rb', line 313 def Bytes.from_bits(bits,byte_endianness=:little_endian, bits_little_endian=false,nbits=nil) nbits ||= (bits.size+7)/8 from_i bits.to_i, nbits, byte_endianness, bits_little_endian end |
.from_hex(hex) ⇒ Object
generate a byte string from an hex representation
170 171 172 |
# File 'lib/float-formats/bytes.rb', line 170 def Bytes.from_hex(hex) Bytes.new [hex.tr(' ','')].pack('H*') end |
.from_i(i, len = 0, byte_endianness = :little_endian, bits_little_endian = false) ⇒ Object
Convert an integer to a byte string
265 266 267 268 269 270 271 272 273 274 275 276 277 |
# File 'lib/float-formats/bytes.rb', line 265 def Bytes.from_i(i, len=0, byte_endianness=:little_endian, bits_little_endian=false) return nil if i<0 bytes = Bytes.new("") while i>0 b = (i&0xFF) bytes << b i >>= 8 end bytes << 0 while bytes.size<len bytes.reverse_byte_bits! if bits_little_endian bytes.convert_endianness!(:little_endian, byte_endianness) bytes end |
Instance Method Details
#+(b) ⇒ Object
151 152 153 |
# File 'lib/float-formats/bytes.rb', line 151 def +(b) Bytes.new(to_str + b.to_str) end |
#[](*params) ⇒ Object
130 131 132 133 134 135 136 |
# File 'lib/float-formats/bytes.rb', line 130 def [](*params) if params.size == 1 && !params.first.kind_of?(Range) _get_str(params.first).ord # bytes.to_a[params.first] else Bytes.new(_get_str(*params)) end end |
#[]=(i, v) ⇒ Object
137 138 139 |
# File 'lib/float-formats/bytes.rb', line 137 def []=(i,v) _set_str i, v.chr(Encoding::BINARY) end |
#_get_str ⇒ Object
128 129 130 131 132 133 134 |
# File 'lib/float-formats/bytes.rb', line 128 def [](*params) if params.size == 1 && !params.first.kind_of?(Range) _get_str(params.first).ord # bytes.to_a[params.first] else Bytes.new(_get_str(*params)) end end |
#_set_str ⇒ Object
129 |
# File 'lib/float-formats/bytes.rb', line 129 alias _set_str []= |
#convert_endianness(from_endianness, to_endianness) ⇒ Object
243 244 245 |
# File 'lib/float-formats/bytes.rb', line 243 def convert_endianness(from_endianness, to_endianness) dup.convert_endianness!(from_endianness, to_endianness) end |
#convert_endianness!(from_endianness, to_endianness) ⇒ Object
Supported endianness modes for byte strings are:
:little_endian
-
(Intel order): least significant bytes come first.
:big_endian
-
(Network order): most significant bytes come first.
:little_big_endian
or:middle_endian
-
(PDP-11 order): each pair of bytes (16-bit word) has the bytes in little endian order, but the words are stored in big endian order (we assume the number of bytes is even).
Note that the :big_little_endian
order which would logically complete the set is not currently supported as it has no known uses.
224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 |
# File 'lib/float-formats/bytes.rb', line 224 def convert_endianness!(from_endianness, to_endianness) if from_endianness!=to_endianness if ([:little_endian,:big_endian]+[from_endianness, to_endianness]).uniq.size==2 # no middle_endian order reverse! else # from or to is middle_endian if [:middle_endian, :little_big_endian].include?(to_endianness) # from little_big_endian convert_endianness!(from_endianness, :big_endian).reverse_byte_pairs! else # from little_big_endian reverse_byte_pairs!.convert_endianness!(:big_endian, to_endianness) end end end self end |
#dup ⇒ Object
120 121 122 |
# File 'lib/float-formats/bytes.rb', line 120 def dup Bytes.new @bytes.dup end |
#reverse_byte_bits ⇒ Object
182 183 184 |
# File 'lib/float-formats/bytes.rb', line 182 def reverse_byte_bits dup.reverse_byte_bits! end |
#reverse_byte_bits! ⇒ Object
Reverse the order of the bits in each byte.
176 177 178 179 180 |
# File 'lib/float-formats/bytes.rb', line 176 def reverse_byte_bits! @bytes = @bytes.unpack('b*').pack("B*")[0] __setobj__ @bytes self end |
#reverse_byte_nibbles ⇒ Object
196 197 198 |
# File 'lib/float-formats/bytes.rb', line 196 def reverse_byte_nibbles dup.reverse_byte_nibbles! end |
#reverse_byte_nibbles! ⇒ Object
Reverse the order of the nibbles in each byte.
187 188 189 190 191 192 193 194 195 |
# File 'lib/float-formats/bytes.rb', line 187 def reverse_byte_nibbles! w = "" @bytes.each_byte do |b| w << ((b >> 4)|((b&0xF)<<4)) end @bytes = w __setobj__ @bytes self end |
#reverse_byte_pairs ⇒ Object
212 213 214 |
# File 'lib/float-formats/bytes.rb', line 212 def reverse_byte_pairs dup.reverse_byte_pairs! end |
#reverse_byte_pairs! ⇒ Object
reverse the order of bytes in 16-bit words
201 202 203 204 205 206 207 208 209 210 |
# File 'lib/float-formats/bytes.rb', line 201 def reverse_byte_pairs! w = "" (0...@bytes.size).step(2) do |i| w << @bytes[i+1] w << @bytes[i] end @bytes = w __setobj__ @bytes self end |
#size ⇒ Object
125 126 127 |
# File 'lib/float-formats/bytes.rb', line 125 def size bytesize end |
#to_bitfields(lens, byte_endianness = :little_endian, bits_little_endian = false) ⇒ Object
convert a byte string to separate fixed-width bit-fields as integers
280 281 282 283 284 285 286 287 288 289 |
# File 'lib/float-formats/bytes.rb', line 280 def to_bitfields(lens,byte_endianness=:little_endian, bits_little_endian=false) fields = [] i = to_i(byte_endianness,bits_little_endian) for len in lens mask = (1<<len)-1 fields << (i&mask) i >>= len end fields end |
#to_bits(byte_endianness = :little_endian, bits_little_endian = false, nbits = nil) ⇒ Object
307 308 309 310 311 |
# File 'lib/float-formats/bytes.rb', line 307 def to_bits(byte_endianness=:little_endian, bits_little_endian=false,nbits=nil) i = to_i(byte_endianness, bits_little_endian) nbits ||= 8*size Bits.from_i(i,nbits) end |
#to_hex(sep_bytes = false) ⇒ Object
return an hex representation of a byte string
156 157 158 159 160 161 162 163 164 165 166 167 |
# File 'lib/float-formats/bytes.rb', line 156 def to_hex(sep_bytes=false) hx = @bytes.unpack('H*')[0].upcase if sep_bytes sep = "" (0...hx.size).step(2) do |i| sep << " " unless i==0 sep << hx[i,2] end hx = sep end hx end |
#to_i(byte_endianness = :little_endian, bits_little_endian = false) ⇒ Object
Convert a byte string to an integer
253 254 255 256 257 258 259 260 261 262 |
# File 'lib/float-formats/bytes.rb', line 253 def to_i(byte_endianness=:little_endian, bits_little_endian=false) i = 0 bytes = convert_endianness(byte_endianness, :big_endian) bytes = bytes.reverse_byte_bits if bits_little_endian bytes.each_byte do |b| i <<= 8 i |= b end i end |