X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fmojo%2Fpublic%2Fjs%2Fbindings%2Fcodec.js;h=02a701ce2e265357fc27f10e3326e703970e1061;hb=4a1a0bdd01eef90b0826a0e761d3379d3715c10f;hp=84c86c1299125a654fdf3a9dec84b6295bcf6bbc;hpb=b1be5ca53587d23e7aeb77b26861fdc0a181ffd8;p=platform%2Fframework%2Fweb%2Fcrosswalk.git diff --git a/src/mojo/public/js/bindings/codec.js b/src/mojo/public/js/bindings/codec.js index 84c86c1..02a701c 100644 --- a/src/mojo/public/js/bindings/codec.js +++ b/src/mojo/public/js/bindings/codec.js @@ -3,112 +3,24 @@ // found in the LICENSE file. define("mojo/public/js/bindings/codec", [ - "mojo/public/js/bindings/unicode" -], function(unicode) { + "mojo/public/js/bindings/unicode", + "mojo/public/js/bindings/buffer" + ], function(unicode, buffer) { var kErrorUnsigned = "Passing negative value to unsigned"; // Memory ------------------------------------------------------------------- var kAlignment = 8; - var kHighWordMultiplier = 0x100000000; - var kHostIsLittleEndian = (function () { - var endianArrayBuffer = new ArrayBuffer(2); - var endianUint8Array = new Uint8Array(endianArrayBuffer); - var endianUint16Array = new Uint16Array(endianArrayBuffer); - endianUint16Array[0] = 1; - return endianUint8Array[0] == 1; - })(); function align(size) { return size + (kAlignment - (size % kAlignment)) % kAlignment; } - function getInt64(dataView, byteOffset, value) { - var lo, hi; - if (kHostIsLittleEndian) { - lo = dataView.getUint32(byteOffset, kHostIsLittleEndian); - hi = dataView.getInt32(byteOffset + 4, kHostIsLittleEndian); - } else { - hi = dataView.getInt32(byteOffset, kHostIsLittleEndian); - lo = dataView.getUint32(byteOffset + 4, kHostIsLittleEndian); - } - return lo + hi * kHighWordMultiplier; - } - - function getUint64(dataView, byteOffset, value) { - var lo, hi; - if (kHostIsLittleEndian) { - lo = dataView.getUint32(byteOffset, kHostIsLittleEndian); - hi = dataView.getUint32(byteOffset + 4, kHostIsLittleEndian); - } else { - hi = dataView.getUint32(byteOffset, kHostIsLittleEndian); - lo = dataView.getUint32(byteOffset + 4, kHostIsLittleEndian); - } - return lo + hi * kHighWordMultiplier; - } - - function setInt64(dataView, byteOffset, value) { - var hi = Math.floor(value / kHighWordMultiplier); - if (kHostIsLittleEndian) { - dataView.setInt32(byteOffset, value, kHostIsLittleEndian); - dataView.setInt32(byteOffset + 4, hi, kHostIsLittleEndian); - } else { - dataView.setInt32(byteOffset, hi, kHostIsLittleEndian); - dataView.setInt32(byteOffset + 4, value, kHostIsLittleEndian); - } - } - - function setUint64(dataView, byteOffset, value) { - var hi = (value / kHighWordMultiplier) | 0; - if (kHostIsLittleEndian) { - dataView.setInt32(byteOffset, value, kHostIsLittleEndian); - dataView.setInt32(byteOffset + 4, hi, kHostIsLittleEndian); - } else { - dataView.setInt32(byteOffset, hi, kHostIsLittleEndian); - dataView.setInt32(byteOffset + 4, value, kHostIsLittleEndian); - } + function isAligned(offset) { + return offset >= 0 && (offset % kAlignment) === 0; } - function copyArrayBuffer(dstArrayBuffer, srcArrayBuffer) { - (new Uint8Array(dstArrayBuffer)).set(new Uint8Array(srcArrayBuffer)); - } - - // Buffer ------------------------------------------------------------------- - - function Buffer(sizeOrArrayBuffer) { - if (sizeOrArrayBuffer instanceof ArrayBuffer) { - this.arrayBuffer = sizeOrArrayBuffer; - } else { - this.arrayBuffer = new ArrayBuffer(sizeOrArrayBuffer); - }; - - this.dataView = new DataView(this.arrayBuffer); - this.next = 0; - } - - Buffer.prototype.alloc = function(size) { - var pointer = this.next; - this.next += size; - if (this.next > this.arrayBuffer.byteLength) { - var newSize = (1.5 * (this.arrayBuffer.byteLength + size)) | 0; - this.grow(newSize); - } - return pointer; - }; - - Buffer.prototype.grow = function(size) { - var newArrayBuffer = new ArrayBuffer(size); - copyArrayBuffer(newArrayBuffer, this.arrayBuffer); - this.arrayBuffer = newArrayBuffer; - this.dataView = new DataView(this.arrayBuffer); - }; - - Buffer.prototype.trim = function() { - this.arrayBuffer = this.arrayBuffer.slice(0, this.next); - this.dataView = new DataView(this.arrayBuffer); - }; - // Constants ---------------------------------------------------------------- var kArrayHeaderSize = 8; @@ -116,6 +28,9 @@ define("mojo/public/js/bindings/codec", [ var kMessageHeaderSize = 16; var kMessageWithRequestIDHeaderSize = 24; + var kStructHeaderNumBytesOffset = 0; + var kStructHeaderNumFieldsOffset = 4; + // Decoder ------------------------------------------------------------------ function Decoder(buffer, handles, base) { @@ -130,64 +45,61 @@ define("mojo/public/js/bindings/codec", [ }; Decoder.prototype.readInt8 = function() { - var result = this.buffer.dataView.getInt8(this.next, kHostIsLittleEndian); + var result = this.buffer.getInt8(this.next); this.next += 1; return result; }; Decoder.prototype.readUint8 = function() { - var result = this.buffer.dataView.getUint8(this.next, kHostIsLittleEndian); + var result = this.buffer.getUint8(this.next); this.next += 1; return result; }; Decoder.prototype.readInt16 = function() { - var result = this.buffer.dataView.getInt16(this.next, kHostIsLittleEndian); + var result = this.buffer.getInt16(this.next); this.next += 2; return result; }; Decoder.prototype.readUint16 = function() { - var result = this.buffer.dataView.getUint16(this.next, kHostIsLittleEndian); + var result = this.buffer.getUint16(this.next); this.next += 2; return result; }; Decoder.prototype.readInt32 = function() { - var result = this.buffer.dataView.getInt32(this.next, kHostIsLittleEndian); + var result = this.buffer.getInt32(this.next); this.next += 4; return result; }; Decoder.prototype.readUint32 = function() { - var result = this.buffer.dataView.getUint32(this.next, kHostIsLittleEndian); + var result = this.buffer.getUint32(this.next); this.next += 4; return result; }; Decoder.prototype.readInt64 = function() { - var result = getInt64(this.buffer.dataView, this.next, kHostIsLittleEndian); + var result = this.buffer.getInt64(this.next); this.next += 8; return result; }; Decoder.prototype.readUint64 = function() { - var result = getUint64( - this.buffer.dataView, this.next, kHostIsLittleEndian); + var result = this.buffer.getUint64(this.next); this.next += 8; return result; }; Decoder.prototype.readFloat = function() { - var result = this.buffer.dataView.getFloat32( - this.next, kHostIsLittleEndian); + var result = this.buffer.getFloat32(this.next); this.next += 4; return result; }; Decoder.prototype.readDouble = function() { - var result = this.buffer.dataView.getFloat64( - this.next, kHostIsLittleEndian); + var result = this.buffer.getFloat64(this.next); this.next += 8; return result; }; @@ -223,8 +135,17 @@ define("mojo/public/js/bindings/codec", [ var numberOfBytes = this.readUint32(); var numberOfElements = this.readUint32(); var val = new Array(numberOfElements); - for (var i = 0; i < numberOfElements; ++i) { - val[i] = cls.decode(this); + if (cls.cls === PackedBool) { + var byte; + for (var i = 0; i < numberOfElements; ++i) { + if (i % 8 === 0) + byte = this.readUint8(); + val[i] = (byte & (1 << i % 8)) ? true : false; + } + } else { + for (var i = 0; i < numberOfElements; ++i) { + val[i] = cls.decode(this); + } } return val; }; @@ -271,8 +192,7 @@ define("mojo/public/js/bindings/codec", [ }; Encoder.prototype.writeInt8 = function(val) { - // NOTE: Endianness doesn't come into play for single bytes. - this.buffer.dataView.setInt8(this.next, val); + this.buffer.setInt8(this.next, val); this.next += 1; }; @@ -280,13 +200,12 @@ define("mojo/public/js/bindings/codec", [ if (val < 0) { throw new Error(kErrorUnsigned); } - // NOTE: Endianness doesn't come into play for single bytes. - this.buffer.dataView.setUint8(this.next, val); + this.buffer.setUint8(this.next, val); this.next += 1; }; Encoder.prototype.writeInt16 = function(val) { - this.buffer.dataView.setInt16(this.next, val, kHostIsLittleEndian); + this.buffer.setInt16(this.next, val); this.next += 2; }; @@ -294,12 +213,12 @@ define("mojo/public/js/bindings/codec", [ if (val < 0) { throw new Error(kErrorUnsigned); } - this.buffer.dataView.setUint16(this.next, val, kHostIsLittleEndian); + this.buffer.setUint16(this.next, val); this.next += 2; }; Encoder.prototype.writeInt32 = function(val) { - this.buffer.dataView.setInt32(this.next, val, kHostIsLittleEndian); + this.buffer.setInt32(this.next, val); this.next += 4; }; @@ -307,12 +226,12 @@ define("mojo/public/js/bindings/codec", [ if (val < 0) { throw new Error(kErrorUnsigned); } - this.buffer.dataView.setUint32(this.next, val, kHostIsLittleEndian); + this.buffer.setUint32(this.next, val); this.next += 4; }; Encoder.prototype.writeInt64 = function(val) { - setInt64(this.buffer.dataView, this.next, val); + this.buffer.setInt64(this.next, val); this.next += 8; }; @@ -320,17 +239,17 @@ define("mojo/public/js/bindings/codec", [ if (val < 0) { throw new Error(kErrorUnsigned); } - setUint64(this.buffer.dataView, this.next, val); + this.buffer.setUint64(this.next, val); this.next += 8; }; Encoder.prototype.writeFloat = function(val) { - this.buffer.dataView.setFloat32(this.next, val, kHostIsLittleEndian); + this.buffer.setFloat32(this.next, val); this.next += 4; }; Encoder.prototype.writeDouble = function(val) { - this.buffer.dataView.setFloat64(this.next, val, kHostIsLittleEndian); + this.buffer.setFloat64(this.next, val); this.next += 8; }; @@ -364,13 +283,29 @@ define("mojo/public/js/bindings/codec", [ this.next += numberOfElements; }; - Encoder.prototype.encodeArray = function(cls, val) { - var numberOfElements = val.length; - var numberOfBytes = kArrayHeaderSize + cls.encodedSize * numberOfElements; - this.writeUint32(numberOfBytes); + Encoder.prototype.encodeArray = + function(cls, val, numberOfElements, encodedSize) { + if (numberOfElements === undefined) + numberOfElements = val.length; + if (encodedSize === undefined) + encodedSize = kArrayHeaderSize + cls.encodedSize * numberOfElements; + + this.writeUint32(encodedSize); this.writeUint32(numberOfElements); - for (var i = 0; i < numberOfElements; ++i) { - cls.encode(this, val[i]); + + if (cls.cls === PackedBool) { + var byte = 0; + for (i = 0; i < numberOfElements; ++i) { + if (val[i]) + byte |= (1 << i % 8); + if (i % 8 === 7 || i == numberOfElements - 1) { + Uint8.encode(this, byte); + byte = 0; + } + } + } else { + for (var i = 0; i < numberOfElements; ++i) + cls.encode(this, val[i]); } }; @@ -392,9 +327,11 @@ define("mojo/public/js/bindings/codec", [ this.encodePointer(val); return; } - var encodedSize = kArrayHeaderSize + cls.encodedSize * val.length; + var numberOfElements = val.length; + var encodedSize = kArrayHeaderSize + ((cls.cls === PackedBool) ? + Math.ceil(numberOfElements / 8) : cls.encodedSize * numberOfElements); var encoder = this.createAndEncodeEncoder(encodedSize); - encoder.encodeArray(cls, val); + encoder.encodeArray(cls, val, numberOfElements, encodedSize); }; Encoder.prototype.encodeStringPointer = function(val) { @@ -409,36 +346,51 @@ define("mojo/public/js/bindings/codec", [ // Message ------------------------------------------------------------------ + var kMessageNameOffset = kStructHeaderSize; + var kMessageFlagsOffset = kMessageNameOffset + 4; + var kMessageRequestIDOffset = kMessageFlagsOffset + 4; + var kMessageExpectsResponse = 1 << 0; var kMessageIsResponse = 1 << 1; - // Skip over num_bytes, num_fields, and message_name. - var kFlagsOffset = 4 + 4 + 4; - - // Skip over num_bytes, num_fields, message_name, and flags. - var kRequestIDOffset = 4 + 4 + 4 + 4; - function Message(buffer, handles) { this.buffer = buffer; this.handles = handles; } - Message.prototype.setRequestID = function(requestID) { - // TODO(darin): Verify that space was reserved for this field! - setUint64(this.buffer.dataView, kRequestIDOffset, requestID); + Message.prototype.getHeaderNumBytes = function() { + return this.buffer.getUint32(kStructHeaderNumBytesOffset); + }; + + Message.prototype.getHeaderNumFields = function() { + return this.buffer.getUint32(kStructHeaderNumFieldsOffset); }; Message.prototype.getFlags = function() { - return this.buffer.dataView.getUint32(kFlagsOffset, kHostIsLittleEndian); + return this.buffer.getUint32(kMessageFlagsOffset); + }; + + Message.prototype.isResponse = function() { + return (this.getFlags() & kMessageIsResponse) != 0; }; + Message.prototype.expectsResponse = function() { + return (this.getFlags() & kMessageExpectsResponse) != 0; + }; + + Message.prototype.setRequestID = function(requestID) { + // TODO(darin): Verify that space was reserved for this field! + this.buffer.setUint64(kMessageRequestIDOffset, requestID); + }; + + // MessageBuilder ----------------------------------------------------------- function MessageBuilder(messageName, payloadSize) { // Currently, we don't compute the payload size correctly ahead of time. // Instead, we resize the buffer at the end. var numberOfBytes = kMessageHeaderSize + payloadSize; - this.buffer = new Buffer(numberOfBytes); + this.buffer = new buffer.Buffer(numberOfBytes); this.handles = []; var encoder = this.createEncoder(kMessageHeaderSize); encoder.writeUint32(kMessageHeaderSize); @@ -474,7 +426,7 @@ define("mojo/public/js/bindings/codec", [ // Currently, we don't compute the payload size correctly ahead of time. // Instead, we resize the buffer at the end. var numberOfBytes = kMessageWithRequestIDHeaderSize + payloadSize; - this.buffer = new Buffer(numberOfBytes); + this.buffer = new buffer.Buffer(numberOfBytes); this.handles = []; var encoder = this.createEncoder(kMessageWithRequestIDHeaderSize); encoder.writeUint32(kMessageWithRequestIDHeaderSize); @@ -495,8 +447,7 @@ define("mojo/public/js/bindings/codec", [ function MessageReader(message) { this.decoder = new Decoder(message.buffer, message.handles, 0); var messageHeaderSize = this.decoder.readUint32(); - this.payloadSize = - message.buffer.arrayBuffer.byteLength - messageHeaderSize; + this.payloadSize = message.buffer.byteLength - messageHeaderSize; var numFields = this.decoder.readUint32(); this.messageName = this.decoder.readUint32(); this.flags = this.decoder.readUint32(); @@ -511,6 +462,10 @@ define("mojo/public/js/bindings/codec", [ // Built-in types ----------------------------------------------------------- + // This type is only used with ArrayOf(PackedBool). + function PackedBool() { + } + function Int8() { } @@ -711,7 +666,7 @@ define("mojo/public/js/bindings/codec", [ var exports = {}; exports.align = align; - exports.Buffer = Buffer; + exports.isAligned = isAligned; exports.Message = Message; exports.MessageBuilder = MessageBuilder; exports.MessageWithRequestIDBuilder = MessageWithRequestIDBuilder; @@ -719,6 +674,7 @@ define("mojo/public/js/bindings/codec", [ exports.kArrayHeaderSize = kArrayHeaderSize; exports.kStructHeaderSize = kStructHeaderSize; exports.kMessageHeaderSize = kMessageHeaderSize; + exports.kMessageWithRequestIDHeaderSize = kMessageWithRequestIDHeaderSize; exports.kMessageExpectsResponse = kMessageExpectsResponse; exports.kMessageIsResponse = kMessageIsResponse; exports.Int8 = Int8; @@ -734,6 +690,7 @@ define("mojo/public/js/bindings/codec", [ exports.String = String; exports.PointerTo = PointerTo; exports.ArrayOf = ArrayOf; + exports.PackedBool = PackedBool; exports.Handle = Handle; return exports; });