Skip to content

Commit 437a45d

Browse files
committed
Binary string support
1 parent b237b1c commit 437a45d

File tree

10 files changed

+727
-110
lines changed

10 files changed

+727
-110
lines changed

ByteBuffer.js

Lines changed: 73 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@
110110
* @const
111111
* @expose
112112
*/
113-
ByteBuffer.VERSION = "2.2.0";
113+
ByteBuffer.VERSION = "2.3.0";
114114

115115
/**
116116
* Default buffer capacity of `16`. The ByteBuffer will be automatically resized by a factor of 2 if required.
@@ -195,7 +195,7 @@
195195
* ByteBuffer's offset to 0 and its length to the wrapped object's byte length.
196196
* @param {!ArrayBuffer|!Buffer|!{array: !ArrayBuffer}|!{buffer: !ArrayBuffer}|string} buffer Anything that can
197197
* be wrapped
198-
* @param {(string|boolean)=} enc String encoding if a string is provided (hex, utf8, defaults to base64)
198+
* @param {(string|boolean)=} enc String encoding if a string is provided (hex, utf8, binary, defaults to base64)
199199
* @param {boolean=} littleEndian `true` to use little endian multi byte values, defaults to `false` for big
200200
* endian.
201201
* @returns {!ByteBuffer}
@@ -210,10 +210,12 @@
210210
// Wrap a string
211211
if (typeof buffer === 'string') {
212212
switch (enc) {
213-
case "hex":
214-
return ByteBuffer.decodeHex(buffer, littleEndian);
215213
case "base64":
216214
return ByteBuffer.decode64(buffer, littleEndian);
215+
case "hex":
216+
return ByteBuffer.decodeHex(buffer, littleEndian);
217+
case "binary":
218+
return ByteBuffer.decodeBinary(buffer, littleEndian);
217219
default:
218220
return new ByteBuffer(ByteBuffer.DEFAULT_CAPACITY, littleEndian).writeUTF8String(buffer).flip();
219221
}
@@ -1615,7 +1617,7 @@
16151617
ByteBuffer.calculateUTF8String = function(str) {
16161618
str = ""+str;
16171619
var bytes = 0;
1618-
for (var i=0, k=str.length; i<k; i++) {
1620+
for (var i=0, k=str.length; i<k; ++i) {
16191621
// Does not throw since JS strings are already UTF8 encoded
16201622
bytes += ByteBuffer.calculateUTF8Char(str.charCodeAt(i));
16211623
}
@@ -1719,7 +1721,7 @@
17191721
}
17201722
if (bb.array === null) return "";
17211723
var val, out = [];
1722-
for (var i=bb.offset, k=bb.length; i<k; i++) {
1724+
for (var i=bb.offset, k=bb.length; i<k; ++i) {
17231725
val = bb.view.getUint8(i).toString(16).toUpperCase();
17241726
if (val.length < 2) val = "0"+val;
17251727
out.push(val);
@@ -1750,6 +1752,50 @@
17501752
return out.flip();
17511753
};
17521754

1755+
/**
1756+
* Encodes a ByteBuffer to a binary string. A binary string in this case is a string composed of 8bit values
1757+
* as characters with a char code between 0 and 255 inclusive.
1758+
* @param {!ByteBuffer} bb ByteBuffer to encode. Will be cloned and flipped if length < offset.
1759+
* @returns {string} Binary string
1760+
* @throws {Error} If the argument is not a valid ByteBuffer
1761+
* @expose
1762+
*/
1763+
ByteBuffer.encodeBinary = function(bb) {
1764+
if (!(bb instanceof ByteBuffer)) {
1765+
bb = ByteBuffer.wrap(bb);
1766+
} else if (bb.length < bb.offset) {
1767+
bb = bb.clone().flip();
1768+
}
1769+
var out = [], view = bb.view;
1770+
for (var i=bb.offset, k=bb.length; i<k; ++i) {
1771+
out.push(String.fromCharCode(view.getUint8(i)));
1772+
}
1773+
return out.join('');
1774+
};
1775+
1776+
/**
1777+
* Decodes a binary string to a ByteBuffer.A binary string in this case is a string composed of 8bit values
1778+
* as characters with a char code between 0 and 255 inclusive.
1779+
* @param {string} str Binary string
1780+
* @param {boolean=} littleEndian `true` to use little endian byte order, defaults to `false` for big endian.
1781+
* @returns {!ByteBuffer} ByteBuffer
1782+
* @throws {Error} If the argument is not a valid binary string
1783+
* @expose
1784+
*/
1785+
ByteBuffer.decodeBinary = function(str, littleEndian) {
1786+
if (typeof str !== 'string') {
1787+
throw(new Error("Illegal argument: Not a string"));
1788+
}
1789+
var k=str.length,
1790+
dst = new ArrayBuffer(k),
1791+
view = new DataView(dst),
1792+
val;
1793+
for (var i=0; i<k; ++i) {
1794+
if ((val = str.charCodeAt(i)) > 255) throw(new Error("Illegal argument: Not a binary string (char code "+val+")"));
1795+
view.setUint8(i, val);
1796+
}
1797+
return ByteBuffer.wrap(dst, littleEndian);
1798+
};
17531799

17541800
/**
17551801
* Writes an UTF8 string.
@@ -1764,7 +1810,7 @@
17641810
var start = offset;
17651811
var encLen = ByteBuffer.calculateUTF8String(str); // See [1]
17661812
this.ensureCapacity(offset+encLen);
1767-
for (var i=0, j=str.length; i<j; i++) {
1813+
for (var i=0, j=str.length; i<j; ++i) {
17681814
// [1] Does not throw since JS strings are already UTF8 encoded
17691815
offset += ByteBuffer.encodeUTF8Char(str.charCodeAt(i), this, offset);
17701816
}
@@ -1789,7 +1835,7 @@
17891835
var advance = typeof offset === 'undefined';
17901836
offset = typeof offset !== 'undefined' ? offset : this.offset;
17911837
var dec, result = "", start = offset;
1792-
for (var i=0; i<chars; i++) {
1838+
for (var i=0; i<chars; ++i) {
17931839
dec = ByteBuffer.decodeUTF8Char(this, offset);
17941840
offset += dec["length"];
17951841
result += String.fromCharCode(dec["char"]);
@@ -2042,7 +2088,7 @@
20422088
} else {
20432089
out += " ";
20442090
}
2045-
for (var i=0, k=this.array.byteLength; i<k; i++) {
2091+
for (var i=0, k=this.array.byteLength; i<k; ++i) {
20462092
if (i>0 && i%wrap == 0) {
20472093
while (out.length < 3*wrap+1) out += " "; // Make it equal to maybe show something on the right
20482094
lines.push(out);
@@ -2065,14 +2111,14 @@
20652111
lines.push(out);
20662112
}
20672113
// Make it equal
2068-
for (i=0, k=lines.length; i<k; i++) {
2114+
for (i=0, k=lines.length; i<k; ++i) {
20692115
while (lines[i].length < 3*wrap+1) lines[i] += " "; // Make it equal to maybe show something on the right
20702116
}
20712117

20722118
// Right column: ASCII, using dots for (usually) non-printable characters
20732119
var n = 0;
20742120
out = "";
2075-
for (i=0, k=this.array.byteLength; i<k; i++) {
2121+
for (i=0, k=this.array.byteLength; i<k; ++i) {
20762122
if (i>0 && i%wrap == 0) {
20772123
lines[n] += " "+out;
20782124
out = ""; n++;
@@ -2112,13 +2158,7 @@
21122158
view = this.view,
21132159
i, k;
21142160
if (!debug) {
2115-
if (this.array === null) return "";
2116-
for (i=this.offset, k=this.length; i<k; i++) {
2117-
val = view.getUint8(i).toString(16).toUpperCase();
2118-
if (val.length < 2) val = "0"+val;
2119-
out += val;
2120-
}
2121-
return out;
2161+
return ByteBuffer.encodeHex(this);
21222162
} else {
21232163
if (this.array === null) return "DESTROYED";
21242164
if (this.offset == 0 && this.length == 0) {
@@ -2130,7 +2170,7 @@
21302170
} else {
21312171
out += " ";
21322172
}
2133-
for (i=0, k=this.array.byteLength; i<k; i++) {
2173+
for (i=0, k=this.array.byteLength; i<k; ++i) {
21342174
val = view.getUint8(i).toString(16).toUpperCase();
21352175
if (val.length < 2) val = "0"+val;
21362176
out += val;
@@ -2148,6 +2188,16 @@
21482188
}
21492189
};
21502190

2191+
/**
2192+
* Returns the ByteBuffer's contents between offset and length as a binary string. A binary string in this case
2193+
* is a string composed of 8bit values as characters with a char code between 0 and 255 inclusive.
2194+
* @returns {string} Binary string
2195+
* @expose
2196+
*/
2197+
ByteBuffer.prototype.toBinary = function() {
2198+
return ByteBuffer.encodeBinary(this);
2199+
};
2200+
21512201
/**
21522202
* Returns the base64 encoded representation of the ByteBuffer's contents.
21532203
* @returns {string} Base 64 encoded string
@@ -2171,8 +2221,8 @@
21712221
/**
21722222
* Converts the ByteBuffer to a string.
21732223
* @param {string=} enc Output encoding. Returns an informative string representation by default but also allows
2174-
* direct conversion to "utf8", "hex" and "base64" encoding. "debug" returns a hex representation with marked
2175-
* offsets.
2224+
* direct conversion to "utf8", "hex", "base64" and "binary" encoding. "debug" returns a hex representation with
2225+
* marked offsets.
21762226
* @returns {string} String representation
21772227
* @expose
21782228
*/
@@ -2185,6 +2235,8 @@
21852235
return this.toBase64();
21862236
case "hex":
21872237
return this.toHex();
2238+
case "binary":
2239+
return this.toBinary();
21882240
case "debug":
21892241
return this.toHex(true);
21902242
default:

0 commit comments

Comments
 (0)