TypeArray - Ruby implementation of the ECMAScript spec ( wiki.ecmascript.org/doku.php?id=strawman:typed_arrays ) <img src=“https://secure.travis-ci.org/methodmissing/type_array.png” alt=“Build Status” />¶ ↑
© 2012 Lourens Naudé (methodmissing)
http://github.com/methodmissing/type_array
This library provides portable, high performance and memory-safe access to native-typed binary data. It defines a generic fixed length buffer type as well as accessor types (views) for accessing data stored within the buffer.
Where binary data has needed to be manipulated, it is often stored as a String or Array. Both of these methods are slow and error-prone. Several protocol implementations would benefit from being able to read and write binary data directly to it’s native form.
Supported numeric types :
-
an unsigned-integer: one of uint8, uint16, uint32
-
a signed-integer: one of int8, int16, int32
-
a floating-point: one of float32 or float64
There’s a few different kinds of typed arrays defined :
-
Int8Array - 8-bit 2’s complement signed integer
-
UInt8Array - 8-bit unsigned integer
-
Int16Array - 16-bit 2’s complement signed integer
-
UInt16Array - 16-bit unsigned integer
-
Int32Array - 32-bit 2’s complement signed integer
-
Uint32Array - 32-bit unsigned integer
-
Float32Array - 32-bit IEEE floating point
-
Float64Array - 64-bit IEEE floating point
Type Conversion¶ ↑
Type Size Description Equivalent C Type Ruby Type -------------------------------------------------------------------------------------------------- Int8Array 1 8-bit 2's complement signed integer signed char Fixnum Uint8Array 1 8-bit unsigned integer unsigned char Fixnum Int16Array 2 16-bit 2's complement signed integer short Fixnum Uint16Array 2 16-bit unsigned integer unsigned short Fixnum Int32Array 4 32-bit 2's complement signed integer int Fixnum / Bignum Uint32Array 4 32-bit unsigned integer unsigned int Fixnum / Bignum Float32Array 4 32-bit IEEE floating point float Float Float64Array 8 64-bit IEEE floating point double Float
Array Buffers¶ ↑
An opaque buffer with an explicit and fixed length. ArrayBuffer contents cannot be accessed directly - there’s no Ruby API exposed to manipulate it.
buf = ArrayBuffer.new(8) => ArrayBuffer buf.byte_length => 8 buf = ArrayBuffer.new("buffer") => ArrayBuffer buf.byte_length => 6 buf.to_s => "buffer"
Type Arrays¶ ↑
A group of types are used to create views of the ArrayBuffer. For example, to access the buffer as an array of 32-bit signed integers, an Int32Array would be created that refers to the ArrayBuffer.
A number of types are introduced that describe how to interpret the bytes in an ArrayBuffer. For example, an Int32Array views the bytes in an ArrayBuffer (or a subregion of an ArrayBuffer) as 32-bit signed integers. Elements of the array are accessible by getting or setting their index.
buf = ArrayBuffer.new("buffer") => ArrayBuffer ary = Int32Array.new(buf) => Int32Array ary.to_s => "buffer" ary = Int32Array.new("01234567") => Int32Array ary[1] = 23 => nil ary[1] => 23 buf = ArrayBuffer.new(100) => ArrayBuffer ary = Int32Array.new(buf, 20) => Int32Array ary.length => 20 ary.byte_length => 80 ary.byte_offset => 20 ary = Int32Array.new(buf, 0, 20) => Int32Array ary.length => 20 ary.byte_length => 80 ary.byte_offset => 0 ary = Int32Array.new(buf, 20, 20) => Int32Array ary.length => 20 ary.byte_length => 80 ary.byte_offset => 20 ary = Int32Array.new("01234567") => Int32Array ary.byte_length => 8 ary.to_s => "01234567" ary = Int32Array.new(100) => Int32Array ary.length => 100 ary.byte_length => 400
Data Views¶ ↑
Multiple views can exist for the same ArrayBuffer, allowing for complex data structures to be built up, albeit with some difficulty. A DataView type is introduced which allows arbitrary indexed reads and writes of basic types from the bytes in the underlying ArrayBuffer. The goal is to allow as close to the native byte access as possible with very few performance penalties, while still retaining safety.
buf = ArrayBuffer.new(100) => ArrayBuffer view = DataView.new(buf) => DataView view.set_float64(2, 77.643) => nil view.get_float64(2) => 758 buf = ArrayBuffer.new(100) => ArrayBuffer view = DataView.new(buf) => DataView view.set_uint32(2, 758) => nil view.get_uint32(2) => 758 buf = ArrayBuffer.new(100) => ArrayBuffer view = DataView.new(buf) => DataView view.set_int16(2, 20) => nil view.get_int16(2) => 20
Requirements¶ ↑
-
Known to work well on Linux, BSD variants and Mac OS X (not tested on Windows)
-
A C compiler
-
Ruby MRI 1.8 or 1.9, Rubinius or JRuby (versions 1.6 and up, C API is deprecated though)
Installation¶ ↑
Rubygems installation
gem install type_array
Building from source
git clone git@github.com:methodmissing/type_array.git rake
Running tests
rake test
Todo¶ ↑
-
Support structs / records
-
Handle edges where coercion to and from Bignum is more appropriate
Contact, feedback and bugs¶ ↑
This project is still work in progress. Please log bugs and suggestions at github.com/methodmissing/type_array/issues