Home | History | Annotate | Download | only in js
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 define("mojo/public/js/buffer", function() {
      6 
      7   var kHostIsLittleEndian = (function () {
      8     var endianArrayBuffer = new ArrayBuffer(2);
      9     var endianUint8Array = new Uint8Array(endianArrayBuffer);
     10     var endianUint16Array = new Uint16Array(endianArrayBuffer);
     11     endianUint16Array[0] = 1;
     12     return endianUint8Array[0] == 1;
     13   })();
     14 
     15   var kHighWordMultiplier = 0x100000000;
     16 
     17   function Buffer(sizeOrArrayBuffer) {
     18     if (sizeOrArrayBuffer instanceof ArrayBuffer)
     19       this.arrayBuffer = sizeOrArrayBuffer;
     20     else
     21       this.arrayBuffer = new ArrayBuffer(sizeOrArrayBuffer);
     22 
     23     this.dataView = new DataView(this.arrayBuffer);
     24     this.next = 0;
     25   }
     26 
     27   Object.defineProperty(Buffer.prototype, "byteLength", {
     28     get: function() { return this.arrayBuffer.byteLength; }
     29   });
     30 
     31   Buffer.prototype.alloc = function(size) {
     32     var pointer = this.next;
     33     this.next += size;
     34     if (this.next > this.byteLength) {
     35       var newSize = (1.5 * (this.byteLength + size)) | 0;
     36       this.grow(newSize);
     37     }
     38     return pointer;
     39   };
     40 
     41   function copyArrayBuffer(dstArrayBuffer, srcArrayBuffer) {
     42     (new Uint8Array(dstArrayBuffer)).set(new Uint8Array(srcArrayBuffer));
     43   }
     44 
     45   Buffer.prototype.grow = function(size) {
     46     var newArrayBuffer = new ArrayBuffer(size);
     47     copyArrayBuffer(newArrayBuffer, this.arrayBuffer);
     48     this.arrayBuffer = newArrayBuffer;
     49     this.dataView = new DataView(this.arrayBuffer);
     50   };
     51 
     52   Buffer.prototype.trim = function() {
     53     this.arrayBuffer = this.arrayBuffer.slice(0, this.next);
     54     this.dataView = new DataView(this.arrayBuffer);
     55   };
     56 
     57   Buffer.prototype.getUint8 = function(offset) {
     58     return this.dataView.getUint8(offset);
     59   }
     60   Buffer.prototype.getUint16 = function(offset) {
     61     return this.dataView.getUint16(offset, kHostIsLittleEndian);
     62   }
     63   Buffer.prototype.getUint32 = function(offset) {
     64     return this.dataView.getUint32(offset, kHostIsLittleEndian);
     65   }
     66   Buffer.prototype.getUint64 = function(offset) {
     67     var lo, hi;
     68     if (kHostIsLittleEndian) {
     69       lo = this.dataView.getUint32(offset, kHostIsLittleEndian);
     70       hi = this.dataView.getUint32(offset + 4, kHostIsLittleEndian);
     71     } else {
     72       hi = this.dataView.getUint32(offset, kHostIsLittleEndian);
     73       lo = this.dataView.getUint32(offset + 4, kHostIsLittleEndian);
     74     }
     75     return lo + hi * kHighWordMultiplier;
     76   }
     77 
     78   Buffer.prototype.getInt8 = function(offset) {
     79     return this.dataView.getInt8(offset);
     80   }
     81   Buffer.prototype.getInt16 = function(offset) {
     82     return this.dataView.getInt16(offset, kHostIsLittleEndian);
     83   }
     84   Buffer.prototype.getInt32 = function(offset) {
     85     return this.dataView.getInt32(offset, kHostIsLittleEndian);
     86   }
     87   Buffer.prototype.getInt64 = function(offset) {
     88     var lo, hi;
     89     if (kHostIsLittleEndian) {
     90       lo = this.dataView.getUint32(offset, kHostIsLittleEndian);
     91       hi = this.dataView.getInt32(offset + 4, kHostIsLittleEndian);
     92     } else {
     93       hi = this.dataView.getInt32(offset, kHostIsLittleEndian);
     94       lo = this.dataView.getUint32(offset + 4, kHostIsLittleEndian);
     95     }
     96     return lo + hi * kHighWordMultiplier;
     97   }
     98 
     99   Buffer.prototype.getFloat32 = function(offset) {
    100     return this.dataView.getFloat32(offset, kHostIsLittleEndian);
    101   }
    102   Buffer.prototype.getFloat64 = function(offset) {
    103     return this.dataView.getFloat64(offset, kHostIsLittleEndian);
    104   }
    105 
    106   Buffer.prototype.setUint8 = function(offset, value) {
    107     this.dataView.setUint8(offset, value);
    108   }
    109   Buffer.prototype.setUint16 = function(offset, value) {
    110     this.dataView.setUint16(offset, value, kHostIsLittleEndian);
    111   }
    112   Buffer.prototype.setUint32 = function(offset, value) {
    113     this.dataView.setUint32(offset, value, kHostIsLittleEndian);
    114   }
    115   Buffer.prototype.setUint64 = function(offset, value) {
    116     var hi = (value / kHighWordMultiplier) | 0;
    117     if (kHostIsLittleEndian) {
    118       this.dataView.setInt32(offset, value, kHostIsLittleEndian);
    119       this.dataView.setInt32(offset + 4, hi, kHostIsLittleEndian);
    120     } else {
    121       this.dataView.setInt32(offset, hi, kHostIsLittleEndian);
    122       this.dataView.setInt32(offset + 4, value, kHostIsLittleEndian);
    123     }
    124   }
    125 
    126   Buffer.prototype.setInt8 = function(offset, value) {
    127     this.dataView.setInt8(offset, value);
    128   }
    129   Buffer.prototype.setInt16 = function(offset, value) {
    130     this.dataView.setInt16(offset, value, kHostIsLittleEndian);
    131   }
    132   Buffer.prototype.setInt32 = function(offset, value) {
    133     this.dataView.setInt32(offset, value, kHostIsLittleEndian);
    134   }
    135   Buffer.prototype.setInt64 = function(offset, value) {
    136     var hi = Math.floor(value / kHighWordMultiplier);
    137     if (kHostIsLittleEndian) {
    138       this.dataView.setInt32(offset, value, kHostIsLittleEndian);
    139       this.dataView.setInt32(offset + 4, hi, kHostIsLittleEndian);
    140     } else {
    141       this.dataView.setInt32(offset, hi, kHostIsLittleEndian);
    142       this.dataView.setInt32(offset + 4, value, kHostIsLittleEndian);
    143     }
    144   }
    145 
    146   Buffer.prototype.setFloat32 = function(offset, value) {
    147     this.dataView.setFloat32(offset, value, kHostIsLittleEndian);
    148   }
    149   Buffer.prototype.setFloat64 = function(offset, value) {
    150     this.dataView.setFloat64(offset, value, kHostIsLittleEndian);
    151   }
    152 
    153   var exports = {};
    154   exports.Buffer = Buffer;
    155   return exports;
    156 });
    157