summaryrefslogtreecommitdiffstats
path: root/core/codecArrayBuffer.js
diff options
context:
space:
mode:
Diffstat (limited to 'core/codecArrayBuffer.js')
-rw-r--r--core/codecArrayBuffer.js113
1 files changed, 113 insertions, 0 deletions
diff --git a/core/codecArrayBuffer.js b/core/codecArrayBuffer.js
new file mode 100644
index 0000000..c2be4ca
--- /dev/null
+++ b/core/codecArrayBuffer.js
@@ -0,0 +1,113 @@
+/** @fileOverview Bit array codec implementations.
+ *
+ * @author Marco Munizaga
+ */
+
+//patch arraybuffers if they don't exist
+if (typeof(ArrayBuffer) === 'undefined') {
+ (function(globals){
+ "use strict";
+ globals.ArrayBuffer = function(){};
+ globals.DataView = function(){};
+ }(this));
+}
+
+/** @namespace ArrayBuffer */
+sjcl.codec.arrayBuffer = {
+ /** Convert from a bitArray to an ArrayBuffer.
+ * Will default to 8byte padding if padding is undefined*/
+ fromBits: function (arr, padding, padding_count) {
+ var out, i, ol, tmp, smallest;
+ padding = padding==undefined ? true : padding
+ padding_count = padding_count || 8
+
+ if (arr.length === 0) {
+ return new ArrayBuffer(0);
+ }
+
+ ol = sjcl.bitArray.bitLength(arr)/8;
+
+ //check to make sure the bitLength is divisible by 8, if it isn't
+ //we can't do anything since arraybuffers work with bytes, not bits
+ if ( sjcl.bitArray.bitLength(arr)%8 !== 0 ) {
+ throw new sjcl.exception.invalid("Invalid bit size, must be divisble by 8 to fit in an arraybuffer correctly")
+ }
+
+ if (padding && ol%padding_count !== 0){
+ ol += padding_count - (ol%padding_count);
+ }
+
+
+ //padded temp for easy copying
+ tmp = new DataView(new ArrayBuffer(arr.length*4));
+ for (i=0; i<arr.length; i++) {
+ tmp.setUint32(i*4, (arr[i]<<32)); //get rid of the higher bits
+ }
+
+ //now copy the final message if we are not going to 0 pad
+ out = new DataView(new ArrayBuffer(ol));
+
+ //save a step when the tmp and out bytelength are ===
+ if (out.byteLength === tmp.byteLength){
+ return tmp.buffer;
+ }
+
+ smallest = tmp.byteLength < out.byteLength ? tmp.byteLength : out.byteLength;
+ for(i=0; i<smallest; i++){
+ out.setUint8(i,tmp.getUint8(i));
+ }
+
+
+ return out.buffer
+ },
+
+ toBits: function (buffer) {
+ var i, out=[], len, inView, tmp;
+
+ if (buffer.byteLength === 0) {
+ return [];
+ }
+
+ inView = new DataView(buffer);
+ len = inView.byteLength - inView.byteLength%4;
+
+ for (var i = 0; i < len; i+=4) {
+ out.push(inView.getUint32(i));
+ }
+
+ if (inView.byteLength%4 != 0) {
+ tmp = new DataView(new ArrayBuffer(4));
+ for (var i = 0, l = inView.byteLength%4; i < l; i++) {
+ //we want the data to the right, because partial slices off the starting bits
+ tmp.setUint8(i+4-l, inView.getUint8(len+i)); // big-endian,
+ }
+ out.push(
+ sjcl.bitArray.partial( (inView.byteLength%4)*8, tmp.getUint32(0) )
+ );
+ }
+ return out;
+ },
+
+
+
+ /** Prints a hex output of the buffer contents, akin to hexdump **/
+ hexDumpBuffer: function(buffer){
+ var stringBufferView = new DataView(buffer)
+ var string = ''
+ var pad = function (n, width) {
+ n = n + '';
+ return n.length >= width ? n : new Array(width - n.length + 1).join('0') + n;
+ }
+
+ for (var i = 0; i < stringBufferView.byteLength; i+=2) {
+ if (i%16 == 0) string += ('\n'+(i).toString(16)+'\t')
+ string += ( pad(stringBufferView.getUint16(i).toString(16),4) + ' ')
+ }
+
+ if ( typeof console === undefined ){
+ console = console || {log:function(){}} //fix for IE
+ }
+ console.log(string.toUpperCase())
+ }
+};
+