Path: blob/trunk/third_party/closure/goog/labs/net/webchannel/wirev8.js
1865 views
// Copyright 2013 The Closure Library Authors. All Rights Reserved.1//2// Licensed under the Apache License, Version 2.0 (the "License");3// you may not use this file except in compliance with the License.4// You may obtain a copy of the License at5//6// http://www.apache.org/licenses/LICENSE-2.07//8// Unless required by applicable law or agreed to in writing, software9// distributed under the License is distributed on an "AS-IS" BASIS,10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.11// See the License for the specific language governing permissions and12// limitations under the License.1314/**15* @fileoverview Codec functions of the v8 wire protocol. Eventually we'd want16* to support pluggable wire-format to improve wire efficiency and to enable17* binary encoding. Such support will require an interface class, which18* will be added later.19*20* @visibility {:internal}21*/222324goog.provide('goog.labs.net.webChannel.WireV8');2526goog.require('goog.asserts');27goog.require('goog.json');28goog.require('goog.json.NativeJsonProcessor');29goog.require('goog.labs.net.webChannel.Wire');30goog.require('goog.structs');31323334/**35* The v8 codec class.36*37* @constructor38* @struct39*/40goog.labs.net.webChannel.WireV8 = function() {41/**42* Parser for a response payload. The parser should return an array.43* @private {!goog.string.Parser}44*/45this.parser_ = new goog.json.NativeJsonProcessor();46};474849goog.scope(function() {50var WireV8 = goog.labs.net.webChannel.WireV8;51var Wire = goog.labs.net.webChannel.Wire;525354/**55* Encodes a standalone message into the wire format.56*57* May throw exception if the message object contains any invalid elements.58*59* @param {!Object|!goog.structs.Map} message The message data.60* V8 only support JS objects (or Map).61* @param {!Array<string>} buffer The text buffer to write the message to.62* @param {string=} opt_prefix The prefix for each field of the object.63*/64WireV8.prototype.encodeMessage = function(message, buffer, opt_prefix) {65var prefix = opt_prefix || '';66try {67goog.structs.forEach(message, function(value, key) {68var encodedValue = value;69if (goog.isObject(value)) {70encodedValue = goog.json.serialize(value);71} // keep the fast-path for primitive types72buffer.push(prefix + key + '=' + encodeURIComponent(encodedValue));73});74} catch (ex) {75// We send a map here because lots of the retry logic relies on map IDs,76// so we have to send something (possibly redundant).77buffer.push(78prefix + 'type' +79'=' + encodeURIComponent('_badmap'));80throw ex;81}82};838485/**86* Encodes all the buffered messages of the forward channel.87*88* @param {!Array<Wire.QueuedMap>} messageQueue The message data.89* V8 only support JS objects.90* @param {number} count The number of messages to be encoded.91* @param {?function(!Object)} badMapHandler Callback for bad messages.92* @return {string} the encoded messages93*/94WireV8.prototype.encodeMessageQueue = function(95messageQueue, count, badMapHandler) {96var sb = ['count=' + count];97var offset;98if (count > 0) {99// To save a bit of bandwidth, specify the base mapId and the rest as100// offsets from it.101offset = messageQueue[0].mapId;102sb.push('ofs=' + offset);103} else {104offset = 0;105}106for (var i = 0; i < count; i++) {107var mapId = messageQueue[i].mapId;108var map = messageQueue[i].map;109mapId -= offset;110try {111this.encodeMessage(map, sb, 'req' + mapId + '_');112} catch (ex) {113if (badMapHandler) {114badMapHandler(map);115}116}117}118return sb.join('&');119};120121122/**123* Decodes a standalone message received from the wire. May throw exception124* if text is ill-formatted.125*126* Must be valid JSON as it is insecure to use eval() to decode JS literals;127* and eval() is disallowed in Chrome apps too.128*129* Invalid JS literals include null array elements, quotas etc.130*131* @param {string} messageText The string content as received from the wire.132* @return {*} The decoded message object.133*/134WireV8.prototype.decodeMessage = function(messageText) {135var response = this.parser_.parse(messageText);136goog.asserts.assert(goog.isArray(response)); // throw exception137return response;138};139}); // goog.scope140141142