Binary/Lite
Contents
Philosophy
There are already numerous proposals for Binary datatype out there (Binary/[A-E]). I personally find all of these too complex and cumbersome; aimed at ducktyping and multi-argument-type methods. The Binary/Lite proposal aims to provide a simplified data type which maintains the core functionality.
There is only one object specified in this proposal: the Binary
function. It is essentialy a (mutable) array of Numbers
. However, when compared with native Array
, this object offers these advantages:
- automatic conversion to
Number
and masking by 0xFF, - flat structure,
- built-in transcoding methods.
Specification
Construction
The Binary
object has only one constructor form.
/** * @param {int} length Initial length of this binary */ var Binary = exports.Binary = function(length = 0) {};
Correspondence with Array
There is a strong similarity with Array
.
Binary.prototype = [];
This way, we automatically have all those iterative methods, such as forEach
, reduce
etc. On client side, this is achieved by
var Binary = exports.Binary = Array;
Cooperation with other data types
To create Binary
from other data types, we use factory methods.
var b1 = Binary.fromArray([1, 2, 3]); var b2 = Binary.fromString("hello ondřej", "utf-8");
Converting back to standard types is very similar. Note that there are no monkey-patching efforts.
var array = b1.toArray(); var string = b1.decodeToString(charset);
The default "toString" is reserved for debugging purposes.
Binary.prototype.toString = function() { return "[Binary " + this.length + "]"; }
Basic usage
The length
property specifies the size. It is possible to resize the binary object by assigning to length
. Newly created values are zero-filled.
var b1 = Binary.fromArray([1, 2, 3]); var length = b1.length; /* 3 */ b1.length = 10;
The [] operator is used to retrieve byte values (as Number
s) as well as modify the binary object. One can freely modify non-existant index - in this case, the object is first resized accordingly.
var b1 = Binary.fromArray([1, 2, 3]); b1[3] = 123; /* b1 == [1, 2, 3, 123] */
Array methods
These methods return a Number
and resize the buffer accordingly:
-
pop
-
shift
These methods accept a variadic list of Number
s and resize the buffer accordingly:
-
push
-
unshift
These methods return a Binary
:
-
slice
-
splice
Miscellaneous
/** * Appends contents of other variadic Binary instance(s) to the end of this one. */ Binary.prototype.extendRight = function() {};
/** * Appends contents of other variadic Binary instance(s) to the beginning of this one. */ Binary.prototype.extendLeft = function() {};
/** * Converts contents from one encoding to another */ Binary.prototype.transcode = function(fromCharset, toCharset) {};
/** * Returns a copy of this Binary */ Binary.prototype.clone = function() {};
Place for improvements
Naming
Current naming scheme does not anticipate the existency of an immutable binary data type. If we decide that an immutable binary is a must, I suggest picking one of these approaches:
- leaving Binary as is, creating an ImmutableBinary type. The awkward name corresponds to the fact that in most situations, a mutable Binary is sufficient.
- switching back to ByteString and ByteArray variants. I am still unsure what is the overall attitude regarding the number of Binary data types we really want.
Transcoding
As mentioned by MisterN, everything related to transcoding might get separated into a different module. This clearly makes sense, as the set of tasks related to transcoding might get larger in the future. On the other hand, converting Strings to Binary has little sense without specifying a charset to be used.