Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(710)

Unified Diff: third_party/WebKit/LayoutTests/external/wpt/resources/chromium/mojo_bindings.js

Issue 2789723003: Migrate WebUSB LayoutTests into external/wpt (Closed)
Patch Set: Add README.md and more comments explaining the polyfill Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/LayoutTests/external/wpt/resources/chromium/mojo_bindings.js
diff --git a/third_party/WebKit/LayoutTests/external/wpt/resources/chromium/mojo_bindings.js b/third_party/WebKit/LayoutTests/external/wpt/resources/chromium/mojo_bindings.js
new file mode 100644
index 0000000000000000000000000000000000000000..af8d8592dc1a8910948cddf30809b0839066d36f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/resources/chromium/mojo_bindings.js
@@ -0,0 +1,5110 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+'use strict';
+
+if (mojo && mojo.internal) {
+ throw new Error('The Mojo bindings library has been initialized.');
+}
+
+var mojo = mojo || {};
+mojo.internal = {};
+mojo.internal.global = this;
+mojo.config = {
+ // Whether to automatically load mojom dependencies.
+ // For example, if foo.mojom imports bar.mojom, |autoLoadMojomDeps| set to
+ // true means that loading foo.mojom.js will insert a <script> tag to load
+ // bar.mojom.js, if it hasn't been loaded.
+ //
+ // The URL of bar.mojom.js is determined by the relative path of bar.mojom
+ // (relative to the position of foo.mojom at build time) and the URL of
+ // foo.mojom.js. For exmple, if at build time the two mojom files are
+ // located at:
+ // a/b/c/foo.mojom
+ // a/b/d/bar.mojom
+ // and the URL of foo.mojom.js is:
+ // http://example.org/scripts/b/c/foo.mojom.js
+ // then the URL of bar.mojom.js will be:
+ // http://example.org/scripts/b/d/bar.mojom.js
+ //
+ // If you would like bar.mojom.js to live at a different location, you need
+ // to turn off |autoLoadMojomDeps| before loading foo.mojom.js, and manually
+ // load bar.mojom.js yourself. Similarly, you need to turn off the option if
+ // you merge bar.mojom.js and foo.mojom.js into a single file.
+ //
+ // Performance tip: Avoid loading the same mojom.js file multiple times.
+ // Assume that |autoLoadMojomDeps| is set to true:
+ // <!-- No duplicate loading; recommended. -->
+ // <script src="http://example.org/scripts/b/c/foo.mojom.js"></script>
+ //
+ // <!-- No duplicate loading, although unnecessary. -->
+ // <script src="http://example.org/scripts/b/d/bar.mojom.js"></script>
+ // <script src="http://example.org/scripts/b/c/foo.mojom.js"></script>
+ //
+ // <!-- Load bar.mojom.js twice; should be avoided. -->
+ // <script src="http://example.org/scripts/b/c/foo.mojom.js"></script>
+ // <script src="http://example.org/scripts/b/d/bar.mojom.js"></script>
+ autoLoadMojomDeps: false
+};
+
+(function() {
+ var internal = mojo.internal;
+
+ var LoadState = {
+ PENDING_LOAD: 1,
+ LOADED: 2
+ };
+
+ var mojomRegistry = new Map();
+
+ function exposeNamespace(namespace) {
+ var current = internal.global;
+ var parts = namespace.split('.');
+
+ for (var part; parts.length && (part = parts.shift());) {
+ if (!current[part]) {
+ current[part] = {};
+ }
+ current = current[part];
+ }
+
+ return current;
+ }
+
+ function isMojomPendingLoad(id) {
+ return mojomRegistry.get(id) === LoadState.PENDING_LOAD;
+ }
+
+ function isMojomLoaded(id) {
+ return mojomRegistry.get(id) === LoadState.LOADED;
+ }
+
+ function markMojomPendingLoad(id) {
+ if (isMojomLoaded(id)) {
+ throw new Error('The following mojom file has been loaded: ' + id);
+ }
+
+ mojomRegistry.set(id, LoadState.PENDING_LOAD);
+ }
+
+ function markMojomLoaded(id) {
+ mojomRegistry.set(id, LoadState.LOADED);
+ }
+
+ function loadMojomIfNecessary(id, url) {
+ if (mojomRegistry.has(id)) {
+ return;
+ }
+
+ markMojomPendingLoad(id);
+ internal.global.document.write('<script type="text/javascript" src="' +
+ url + '"></script>');
+ }
+
+ internal.exposeNamespace = exposeNamespace;
+ internal.isMojomPendingLoad = isMojomPendingLoad;
+ internal.isMojomLoaded = isMojomLoaded;
+ internal.markMojomPendingLoad = markMojomPendingLoad;
+ internal.markMojomLoaded = markMojomLoaded;
+ internal.loadMojomIfNecessary = loadMojomIfNecessary;
+})();
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+(function() {
+ var internal = mojo.internal;
+
+ // ---------------------------------------------------------------------------
+
+ // |output| could be an interface pointer, InterfacePtrInfo or
+ // AssociatedInterfacePtrInfo.
+ function makeRequest(output) {
+ if (output instanceof mojo.AssociatedInterfacePtrInfo) {
+ var {handle0, handle1} = internal.createPairPendingAssociation();
+ output.interfaceEndpointHandle = handle0;
+ output.version = 0;
+
+ return new mojo.AssociatedInterfaceRequest(handle1);
+ }
+
+ if (output instanceof mojo.InterfacePtrInfo) {
+ var pipe = Mojo.createMessagePipe();
+ output.handle = pipe.handle0;
+ output.version = 0;
+
+ return new mojo.InterfaceRequest(pipe.handle1);
+ }
+
+ var pipe = Mojo.createMessagePipe();
+ output.ptr.bind(new mojo.InterfacePtrInfo(pipe.handle0, 0));
+ return new mojo.InterfaceRequest(pipe.handle1);
+ }
+
+ // ---------------------------------------------------------------------------
+
+ // Operations used to setup/configure an interface pointer. Exposed as the
+ // |ptr| field of generated interface pointer classes.
+ // |ptrInfoOrHandle| could be omitted and passed into bind() later.
+ function InterfacePtrController(interfaceType, ptrInfoOrHandle) {
+ this.version = 0;
+
+ this.interfaceType_ = interfaceType;
+ this.router_ = null;
+ this.interfaceEndpointClient_ = null;
+ this.proxy_ = null;
+
+ // |router_| and |interfaceEndpointClient_| are lazily initialized.
+ // |handle_| is valid between bind() and
+ // the initialization of |router_| and |interfaceEndpointClient_|.
+ this.handle_ = null;
+
+ if (ptrInfoOrHandle)
+ this.bind(ptrInfoOrHandle);
+ }
+
+ InterfacePtrController.prototype.bind = function(ptrInfoOrHandle) {
+ this.reset();
+
+ if (ptrInfoOrHandle instanceof mojo.InterfacePtrInfo) {
+ this.version = ptrInfoOrHandle.version;
+ this.handle_ = ptrInfoOrHandle.handle;
+ } else {
+ this.handle_ = ptrInfoOrHandle;
+ }
+ };
+
+ InterfacePtrController.prototype.isBound = function() {
+ return this.interfaceEndpointClient_ !== null || this.handle_ !== null;
+ };
+
+ // Although users could just discard the object, reset() closes the pipe
+ // immediately.
+ InterfacePtrController.prototype.reset = function() {
+ this.version = 0;
+ if (this.interfaceEndpointClient_) {
+ this.interfaceEndpointClient_.close();
+ this.interfaceEndpointClient_ = null;
+ }
+ if (this.router_) {
+ this.router_.close();
+ this.router_ = null;
+
+ this.proxy_ = null;
+ }
+ if (this.handle_) {
+ this.handle_.close();
+ this.handle_ = null;
+ }
+ };
+
+ InterfacePtrController.prototype.resetWithReason = function(reason) {
+ if (this.isBound()) {
+ this.configureProxyIfNecessary_();
+ this.interfaceEndpointClient_.close(reason);
+ this.interfaceEndpointClient_ = null;
+ }
+ this.reset();
+ };
+
+ InterfacePtrController.prototype.setConnectionErrorHandler = function(
+ callback) {
+ if (!this.isBound())
+ throw new Error("Cannot set connection error handler if not bound.");
+
+ this.configureProxyIfNecessary_();
+ this.interfaceEndpointClient_.setConnectionErrorHandler(callback);
+ };
+
+ InterfacePtrController.prototype.passInterface = function() {
+ var result;
+ if (this.router_) {
+ // TODO(yzshen): Fix Router interface to support extracting handle.
+ result = new mojo.InterfacePtrInfo(
+ this.router_.connector_.handle_, this.version);
+ this.router_.connector_.handle_ = null;
+ } else {
+ // This also handles the case when this object is not bound.
+ result = new mojo.InterfacePtrInfo(this.handle_, this.version);
+ this.handle_ = null;
+ }
+
+ this.reset();
+ return result;
+ };
+
+ InterfacePtrController.prototype.getProxy = function() {
+ this.configureProxyIfNecessary_();
+ return this.proxy_;
+ };
+
+ InterfacePtrController.prototype.configureProxyIfNecessary_ = function() {
+ if (!this.handle_)
+ return;
+
+ this.router_ = new internal.Router(this.handle_, true);
+ this.handle_ = null;
+
+ this.interfaceEndpointClient_ = new internal.InterfaceEndpointClient(
+ this.router_.createLocalEndpointHandle(internal.kMasterInterfaceId));
+
+ this.interfaceEndpointClient_ .setPayloadValidators([
+ this.interfaceType_.validateResponse]);
+ this.proxy_ = new this.interfaceType_.proxyClass(
+ this.interfaceEndpointClient_);
+ };
+
+ InterfacePtrController.prototype.queryVersion = function() {
+ function onQueryVersion(version) {
+ this.version = version;
+ return version;
+ }
+
+ this.configureProxyIfNecessary_();
+ return this.interfaceEndpointClient_.queryVersion().then(
+ onQueryVersion.bind(this));
+ };
+
+ InterfacePtrController.prototype.requireVersion = function(version) {
+ this.configureProxyIfNecessary_();
+
+ if (this.version >= version) {
+ return;
+ }
+ this.version = version;
+ this.interfaceEndpointClient_.requireVersion(version);
+ };
+
+ // ---------------------------------------------------------------------------
+
+ // |request| could be omitted and passed into bind() later.
+ //
+ // Example:
+ //
+ // // FooImpl implements mojom.Foo.
+ // function FooImpl() { ... }
+ // FooImpl.prototype.fooMethod1 = function() { ... }
+ // FooImpl.prototype.fooMethod2 = function() { ... }
+ //
+ // var fooPtr = new mojom.FooPtr();
+ // var request = makeRequest(fooPtr);
+ // var binding = new Binding(mojom.Foo, new FooImpl(), request);
+ // fooPtr.fooMethod1();
+ function Binding(interfaceType, impl, requestOrHandle) {
+ this.interfaceType_ = interfaceType;
+ this.impl_ = impl;
+ this.router_ = null;
+ this.interfaceEndpointClient_ = null;
+ this.stub_ = null;
+
+ if (requestOrHandle)
+ this.bind(requestOrHandle);
+ }
+
+ Binding.prototype.isBound = function() {
+ return this.router_ !== null;
+ };
+
+ Binding.prototype.createInterfacePtrAndBind = function() {
+ var ptr = new this.interfaceType_.ptrClass();
+ // TODO(yzshen): Set the version of the interface pointer.
+ this.bind(makeRequest(ptr));
+ return ptr;
+ };
+
+ Binding.prototype.bind = function(requestOrHandle) {
+ this.close();
+
+ var handle = requestOrHandle instanceof mojo.InterfaceRequest ?
+ requestOrHandle.handle : requestOrHandle;
+ if (!(handle instanceof MojoHandle))
+ return;
+
+ this.router_ = new internal.Router(handle);
+
+ this.stub_ = new this.interfaceType_.stubClass(this.impl_);
+ this.interfaceEndpointClient_ = new internal.InterfaceEndpointClient(
+ this.router_.createLocalEndpointHandle(internal.kMasterInterfaceId),
+ this.stub_, this.interfaceType_.kVersion);
+
+ this.interfaceEndpointClient_ .setPayloadValidators([
+ this.interfaceType_.validateRequest]);
+ };
+
+ Binding.prototype.close = function() {
+ if (!this.isBound())
+ return;
+
+ if (this.interfaceEndpointClient_) {
+ this.interfaceEndpointClient_.close();
+ this.interfaceEndpointClient_ = null;
+ }
+
+ this.router_.close();
+ this.router_ = null;
+ this.stub_ = null;
+ };
+
+ Binding.prototype.closeWithReason = function(reason) {
+ if (this.interfaceEndpointClient_) {
+ this.interfaceEndpointClient_.close(reason);
+ this.interfaceEndpointClient_ = null;
+ }
+ this.close();
+ };
+
+ Binding.prototype.setConnectionErrorHandler = function(callback) {
+ if (!this.isBound()) {
+ throw new Error("Cannot set connection error handler if not bound.");
+ }
+ this.interfaceEndpointClient_.setConnectionErrorHandler(callback);
+ };
+
+ Binding.prototype.unbind = function() {
+ if (!this.isBound())
+ return new mojo.InterfaceRequest(null);
+
+ var result = new mojo.InterfaceRequest(this.router_.connector_.handle_);
+ this.router_.connector_.handle_ = null;
+ this.close();
+ return result;
+ };
+
+ // ---------------------------------------------------------------------------
+
+ function BindingSetEntry(bindingSet, interfaceType, bindingType, impl,
+ requestOrHandle, bindingId) {
+ this.bindingSet_ = bindingSet;
+ this.bindingId_ = bindingId;
+ this.binding_ = new bindingType(interfaceType, impl,
+ requestOrHandle);
+
+ this.binding_.setConnectionErrorHandler(function(reason) {
+ this.bindingSet_.onConnectionError(bindingId, reason);
+ }.bind(this));
+ }
+
+ BindingSetEntry.prototype.close = function() {
+ this.binding_.close();
+ };
+
+ function BindingSet(interfaceType) {
+ this.interfaceType_ = interfaceType;
+ this.nextBindingId_ = 0;
+ this.bindings_ = new Map();
+ this.errorHandler_ = null;
+ this.bindingType_ = Binding;
+ }
+
+ BindingSet.prototype.isEmpty = function() {
+ return this.bindings_.size == 0;
+ };
+
+ BindingSet.prototype.addBinding = function(impl, requestOrHandle) {
+ this.bindings_.set(
+ this.nextBindingId_,
+ new BindingSetEntry(this, this.interfaceType_, this.bindingType_, impl,
+ requestOrHandle, this.nextBindingId_));
+ ++this.nextBindingId_;
+ };
+
+ BindingSet.prototype.closeAllBindings = function() {
+ for (var entry of this.bindings_.values())
+ entry.close();
+ this.bindings_.clear();
+ };
+
+ BindingSet.prototype.setConnectionErrorHandler = function(callback) {
+ this.errorHandler_ = callback;
+ };
+
+ BindingSet.prototype.onConnectionError = function(bindingId, reason) {
+ this.bindings_.delete(bindingId);
+
+ if (this.errorHandler_)
+ this.errorHandler_(reason);
+ };
+
+ // ---------------------------------------------------------------------------
+
+ // Operations used to setup/configure an associated interface pointer.
+ // Exposed as |ptr| field of generated associated interface pointer classes.
+ // |associatedPtrInfo| could be omitted and passed into bind() later.
+ //
+ // Example:
+ // // IntegerSenderImpl implements mojom.IntegerSender
+ // function IntegerSenderImpl() { ... }
+ // IntegerSenderImpl.prototype.echo = function() { ... }
+ //
+ // // IntegerSenderConnectionImpl implements mojom.IntegerSenderConnection
+ // function IntegerSenderConnectionImpl() {
+ // this.senderBinding_ = null;
+ // }
+ // IntegerSenderConnectionImpl.prototype.getSender = function(
+ // associatedRequest) {
+ // this.senderBinding_ = new AssociatedBinding(mojom.IntegerSender,
+ // new IntegerSenderImpl(),
+ // associatedRequest);
+ // }
+ //
+ // var integerSenderConnection = new mojom.IntegerSenderConnectionPtr();
+ // var integerSenderConnectionBinding = new Binding(
+ // mojom.IntegerSenderConnection,
+ // new IntegerSenderConnectionImpl(),
+ // mojo.makeRequest(integerSenderConnection));
+ //
+ // // A locally-created associated interface pointer can only be used to
+ // // make calls when the corresponding associated request is sent over
+ // // another interface (either the master interface or another
+ // // associated interface).
+ // var associatedInterfacePtrInfo = new AssociatedInterfacePtrInfo();
+ // var associatedRequest = makeRequest(interfacePtrInfo);
+ //
+ // integerSenderConnection.getSender(associatedRequest);
+ //
+ // // Create an associated interface and bind the associated handle.
+ // var integerSender = new mojom.AssociatedIntegerSenderPtr();
+ // integerSender.ptr.bind(associatedInterfacePtrInfo);
+ // integerSender.echo();
+
+ function AssociatedInterfacePtrController(interfaceType, associatedPtrInfo) {
+ this.version = 0;
+
+ this.interfaceType_ = interfaceType;
+ this.interfaceEndpointClient_ = null;
+ this.proxy_ = null;
+
+ if (associatedPtrInfo) {
+ this.bind(associatedPtrInfo);
+ }
+ }
+
+ AssociatedInterfacePtrController.prototype.bind = function(
+ associatedPtrInfo) {
+ this.reset();
+ this.version = associatedPtrInfo.version;
+
+ this.interfaceEndpointClient_ = new internal.InterfaceEndpointClient(
+ associatedPtrInfo.interfaceEndpointHandle);
+
+ this.interfaceEndpointClient_ .setPayloadValidators([
+ this.interfaceType_.validateResponse]);
+ this.proxy_ = new this.interfaceType_.proxyClass(
+ this.interfaceEndpointClient_);
+ };
+
+ AssociatedInterfacePtrController.prototype.isBound = function() {
+ return this.interfaceEndpointClient_ !== null;
+ };
+
+ AssociatedInterfacePtrController.prototype.reset = function() {
+ this.version = 0;
+ if (this.interfaceEndpointClient_) {
+ this.interfaceEndpointClient_.close();
+ this.interfaceEndpointClient_ = null;
+ }
+ if (this.proxy_) {
+ this.proxy_ = null;
+ }
+ };
+
+ AssociatedInterfacePtrController.prototype.resetWithReason = function(
+ reason) {
+ if (this.isBound()) {
+ this.interfaceEndpointClient_.close(reason);
+ this.interfaceEndpointClient_ = null;
+ }
+ this.reset();
+ };
+
+ // Indicates whether an error has been encountered. If true, method calls
+ // on this interface will be dropped (and may already have been dropped).
+ AssociatedInterfacePtrController.prototype.getEncounteredError = function() {
+ return this.interfaceEndpointClient_ ?
+ this.interfaceEndpointClient_.getEncounteredError() : false;
+ };
+
+ AssociatedInterfacePtrController.prototype.setConnectionErrorHandler =
+ function(callback) {
+ if (!this.isBound()) {
+ throw new Error("Cannot set connection error handler if not bound.");
+ }
+
+ this.interfaceEndpointClient_.setConnectionErrorHandler(callback);
+ };
+
+ AssociatedInterfacePtrController.prototype.passInterface = function() {
+ if (!this.isBound()) {
+ return new mojo.AssociatedInterfacePtrInfo(null);
+ }
+
+ var result = new mojo.AssociatedInterfacePtrInfo(
+ this.interfaceEndpointClient_.passHandle(), this.version);
+ this.reset();
+ return result;
+ };
+
+ AssociatedInterfacePtrController.prototype.getProxy = function() {
+ return this.proxy_;
+ };
+
+ AssociatedInterfacePtrController.prototype.queryVersion = function() {
+ function onQueryVersion(version) {
+ this.version = version;
+ return version;
+ }
+
+ return this.interfaceEndpointClient_.queryVersion().then(
+ onQueryVersion.bind(this));
+ };
+
+ AssociatedInterfacePtrController.prototype.requireVersion = function(
+ version) {
+ if (this.version >= version) {
+ return;
+ }
+ this.version = version;
+ this.interfaceEndpointClient_.requireVersion(version);
+ };
+
+ // ---------------------------------------------------------------------------
+
+ // |associatedInterfaceRequest| could be omitted and passed into bind()
+ // later.
+ function AssociatedBinding(interfaceType, impl, associatedInterfaceRequest) {
+ this.interfaceType_ = interfaceType;
+ this.impl_ = impl;
+ this.interfaceEndpointClient_ = null;
+ this.stub_ = null;
+
+ if (associatedInterfaceRequest) {
+ this.bind(associatedInterfaceRequest);
+ }
+ }
+
+ AssociatedBinding.prototype.isBound = function() {
+ return this.interfaceEndpointClient_ !== null;
+ };
+
+ AssociatedBinding.prototype.bind = function(associatedInterfaceRequest) {
+ this.close();
+
+ this.stub_ = new this.interfaceType_.stubClass(this.impl_);
+ this.interfaceEndpointClient_ = new internal.InterfaceEndpointClient(
+ associatedInterfaceRequest.interfaceEndpointHandle, this.stub_,
+ this.interfaceType_.kVersion);
+
+ this.interfaceEndpointClient_ .setPayloadValidators([
+ this.interfaceType_.validateRequest]);
+ };
+
+
+ AssociatedBinding.prototype.close = function() {
+ if (!this.isBound()) {
+ return;
+ }
+
+ if (this.interfaceEndpointClient_) {
+ this.interfaceEndpointClient_.close();
+ this.interfaceEndpointClient_ = null;
+ }
+
+ this.stub_ = null;
+ };
+
+ AssociatedBinding.prototype.closeWithReason = function(reason) {
+ if (this.interfaceEndpointClient_) {
+ this.interfaceEndpointClient_.close(reason);
+ this.interfaceEndpointClient_ = null;
+ }
+ this.close();
+ };
+
+ AssociatedBinding.prototype.setConnectionErrorHandler = function(callback) {
+ if (!this.isBound()) {
+ throw new Error("Cannot set connection error handler if not bound.");
+ }
+ this.interfaceEndpointClient_.setConnectionErrorHandler(callback);
+ };
+
+ AssociatedBinding.prototype.unbind = function() {
+ if (!this.isBound()) {
+ return new mojo.AssociatedInterfaceRequest(null);
+ }
+
+ var result = new mojo.AssociatedInterfaceRequest(
+ this.interfaceEndpointClient_.passHandle());
+ this.close();
+ return result;
+ };
+
+ // ---------------------------------------------------------------------------
+
+ function AssociatedBindingSet(interfaceType) {
+ mojo.BindingSet.call(this, interfaceType);
+ this.bindingType_ = AssociatedBinding;
+ }
+
+ AssociatedBindingSet.prototype = Object.create(BindingSet.prototype);
+ AssociatedBindingSet.prototype.constructor = AssociatedBindingSet;
+
+ mojo.makeRequest = makeRequest;
+ mojo.AssociatedInterfacePtrController = AssociatedInterfacePtrController;
+ mojo.AssociatedBinding = AssociatedBinding;
+ mojo.AssociatedBindingSet = AssociatedBindingSet;
+ mojo.Binding = Binding;
+ mojo.BindingSet = BindingSet;
+ mojo.InterfacePtrController = InterfacePtrController;
+})();
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+(function() {
+ var internal = mojo.internal;
+
+ 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;
+ })();
+
+ var kHighWordMultiplier = 0x100000000;
+
+ 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;
+ }
+
+ Object.defineProperty(Buffer.prototype, "byteLength", {
+ get: function() { return this.arrayBuffer.byteLength; }
+ });
+
+ Buffer.prototype.alloc = function(size) {
+ var pointer = this.next;
+ this.next += size;
+ if (this.next > this.byteLength) {
+ var newSize = (1.5 * (this.byteLength + size)) | 0;
+ this.grow(newSize);
+ }
+ return pointer;
+ };
+
+ function copyArrayBuffer(dstArrayBuffer, srcArrayBuffer) {
+ (new Uint8Array(dstArrayBuffer)).set(new Uint8Array(srcArrayBuffer));
+ }
+
+ 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);
+ };
+
+ Buffer.prototype.getUint8 = function(offset) {
+ return this.dataView.getUint8(offset);
+ }
+ Buffer.prototype.getUint16 = function(offset) {
+ return this.dataView.getUint16(offset, kHostIsLittleEndian);
+ }
+ Buffer.prototype.getUint32 = function(offset) {
+ return this.dataView.getUint32(offset, kHostIsLittleEndian);
+ }
+ Buffer.prototype.getUint64 = function(offset) {
+ var lo, hi;
+ if (kHostIsLittleEndian) {
+ lo = this.dataView.getUint32(offset, kHostIsLittleEndian);
+ hi = this.dataView.getUint32(offset + 4, kHostIsLittleEndian);
+ } else {
+ hi = this.dataView.getUint32(offset, kHostIsLittleEndian);
+ lo = this.dataView.getUint32(offset + 4, kHostIsLittleEndian);
+ }
+ return lo + hi * kHighWordMultiplier;
+ }
+
+ Buffer.prototype.getInt8 = function(offset) {
+ return this.dataView.getInt8(offset);
+ }
+ Buffer.prototype.getInt16 = function(offset) {
+ return this.dataView.getInt16(offset, kHostIsLittleEndian);
+ }
+ Buffer.prototype.getInt32 = function(offset) {
+ return this.dataView.getInt32(offset, kHostIsLittleEndian);
+ }
+ Buffer.prototype.getInt64 = function(offset) {
+ var lo, hi;
+ if (kHostIsLittleEndian) {
+ lo = this.dataView.getUint32(offset, kHostIsLittleEndian);
+ hi = this.dataView.getInt32(offset + 4, kHostIsLittleEndian);
+ } else {
+ hi = this.dataView.getInt32(offset, kHostIsLittleEndian);
+ lo = this.dataView.getUint32(offset + 4, kHostIsLittleEndian);
+ }
+ return lo + hi * kHighWordMultiplier;
+ }
+
+ Buffer.prototype.getFloat32 = function(offset) {
+ return this.dataView.getFloat32(offset, kHostIsLittleEndian);
+ }
+ Buffer.prototype.getFloat64 = function(offset) {
+ return this.dataView.getFloat64(offset, kHostIsLittleEndian);
+ }
+
+ Buffer.prototype.setUint8 = function(offset, value) {
+ this.dataView.setUint8(offset, value);
+ }
+ Buffer.prototype.setUint16 = function(offset, value) {
+ this.dataView.setUint16(offset, value, kHostIsLittleEndian);
+ }
+ Buffer.prototype.setUint32 = function(offset, value) {
+ this.dataView.setUint32(offset, value, kHostIsLittleEndian);
+ }
+ Buffer.prototype.setUint64 = function(offset, value) {
+ var hi = (value / kHighWordMultiplier) | 0;
+ if (kHostIsLittleEndian) {
+ this.dataView.setInt32(offset, value, kHostIsLittleEndian);
+ this.dataView.setInt32(offset + 4, hi, kHostIsLittleEndian);
+ } else {
+ this.dataView.setInt32(offset, hi, kHostIsLittleEndian);
+ this.dataView.setInt32(offset + 4, value, kHostIsLittleEndian);
+ }
+ }
+
+ Buffer.prototype.setInt8 = function(offset, value) {
+ this.dataView.setInt8(offset, value);
+ }
+ Buffer.prototype.setInt16 = function(offset, value) {
+ this.dataView.setInt16(offset, value, kHostIsLittleEndian);
+ }
+ Buffer.prototype.setInt32 = function(offset, value) {
+ this.dataView.setInt32(offset, value, kHostIsLittleEndian);
+ }
+ Buffer.prototype.setInt64 = function(offset, value) {
+ var hi = Math.floor(value / kHighWordMultiplier);
+ if (kHostIsLittleEndian) {
+ this.dataView.setInt32(offset, value, kHostIsLittleEndian);
+ this.dataView.setInt32(offset + 4, hi, kHostIsLittleEndian);
+ } else {
+ this.dataView.setInt32(offset, hi, kHostIsLittleEndian);
+ this.dataView.setInt32(offset + 4, value, kHostIsLittleEndian);
+ }
+ }
+
+ Buffer.prototype.setFloat32 = function(offset, value) {
+ this.dataView.setFloat32(offset, value, kHostIsLittleEndian);
+ }
+ Buffer.prototype.setFloat64 = function(offset, value) {
+ this.dataView.setFloat64(offset, value, kHostIsLittleEndian);
+ }
+
+ internal.Buffer = Buffer;
+})();
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+(function() {
+ var internal = mojo.internal;
+
+ var kErrorUnsigned = "Passing negative value to unsigned";
+ var kErrorArray = "Passing non Array for array type";
+ var kErrorString = "Passing non String for string type";
+ var kErrorMap = "Passing non Map for map type";
+
+ // Memory -------------------------------------------------------------------
+
+ var kAlignment = 8;
+
+ function align(size) {
+ return size + (kAlignment - (size % kAlignment)) % kAlignment;
+ }
+
+ function isAligned(offset) {
+ return offset >= 0 && (offset % kAlignment) === 0;
+ }
+
+ // Constants ----------------------------------------------------------------
+
+ var kArrayHeaderSize = 8;
+ var kStructHeaderSize = 8;
+ var kMessageV0HeaderSize = 24;
+ var kMessageV1HeaderSize = 32;
+ var kMessageV2HeaderSize = 48;
+ var kMapStructPayloadSize = 16;
+
+ var kStructHeaderNumBytesOffset = 0;
+ var kStructHeaderVersionOffset = 4;
+
+ var kEncodedInvalidHandleValue = 0xFFFFFFFF;
+
+ // Decoder ------------------------------------------------------------------
+
+ function Decoder(buffer, handles, associatedEndpointHandles, base) {
+ this.buffer = buffer;
+ this.handles = handles;
+ this.associatedEndpointHandles = associatedEndpointHandles;
+ this.base = base;
+ this.next = base;
+ }
+
+ Decoder.prototype.align = function() {
+ this.next = align(this.next);
+ };
+
+ Decoder.prototype.skip = function(offset) {
+ this.next += offset;
+ };
+
+ Decoder.prototype.readInt8 = function() {
+ var result = this.buffer.getInt8(this.next);
+ this.next += 1;
+ return result;
+ };
+
+ Decoder.prototype.readUint8 = function() {
+ var result = this.buffer.getUint8(this.next);
+ this.next += 1;
+ return result;
+ };
+
+ Decoder.prototype.readInt16 = function() {
+ var result = this.buffer.getInt16(this.next);
+ this.next += 2;
+ return result;
+ };
+
+ Decoder.prototype.readUint16 = function() {
+ var result = this.buffer.getUint16(this.next);
+ this.next += 2;
+ return result;
+ };
+
+ Decoder.prototype.readInt32 = function() {
+ var result = this.buffer.getInt32(this.next);
+ this.next += 4;
+ return result;
+ };
+
+ Decoder.prototype.readUint32 = function() {
+ var result = this.buffer.getUint32(this.next);
+ this.next += 4;
+ return result;
+ };
+
+ Decoder.prototype.readInt64 = function() {
+ var result = this.buffer.getInt64(this.next);
+ this.next += 8;
+ return result;
+ };
+
+ Decoder.prototype.readUint64 = function() {
+ var result = this.buffer.getUint64(this.next);
+ this.next += 8;
+ return result;
+ };
+
+ Decoder.prototype.readFloat = function() {
+ var result = this.buffer.getFloat32(this.next);
+ this.next += 4;
+ return result;
+ };
+
+ Decoder.prototype.readDouble = function() {
+ var result = this.buffer.getFloat64(this.next);
+ this.next += 8;
+ return result;
+ };
+
+ Decoder.prototype.decodePointer = function() {
+ // TODO(abarth): To correctly decode a pointer, we need to know the real
+ // base address of the array buffer.
+ var offsetPointer = this.next;
+ var offset = this.readUint64();
+ if (!offset)
+ return 0;
+ return offsetPointer + offset;
+ };
+
+ Decoder.prototype.decodeAndCreateDecoder = function(pointer) {
+ return new Decoder(this.buffer, this.handles,
+ this.associatedEndpointHandles, pointer);
+ };
+
+ Decoder.prototype.decodeHandle = function() {
+ return this.handles[this.readUint32()] || null;
+ };
+
+ Decoder.prototype.decodeAssociatedEndpointHandle = function() {
+ return this.associatedEndpointHandles[this.readUint32()] || null;
+ };
+
+ Decoder.prototype.decodeString = function() {
+ var numberOfBytes = this.readUint32();
+ var numberOfElements = this.readUint32();
+ var base = this.next;
+ this.next += numberOfElements;
+ return internal.decodeUtf8String(
+ new Uint8Array(this.buffer.arrayBuffer, base, numberOfElements));
+ };
+
+ Decoder.prototype.decodeArray = function(cls) {
+ var numberOfBytes = this.readUint32();
+ var numberOfElements = this.readUint32();
+ var val = new Array(numberOfElements);
+ if (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;
+ };
+
+ Decoder.prototype.decodeStruct = function(cls) {
+ return cls.decode(this);
+ };
+
+ Decoder.prototype.decodeStructPointer = function(cls) {
+ var pointer = this.decodePointer();
+ if (!pointer) {
+ return null;
+ }
+ return cls.decode(this.decodeAndCreateDecoder(pointer));
+ };
+
+ Decoder.prototype.decodeArrayPointer = function(cls) {
+ var pointer = this.decodePointer();
+ if (!pointer) {
+ return null;
+ }
+ return this.decodeAndCreateDecoder(pointer).decodeArray(cls);
+ };
+
+ Decoder.prototype.decodeStringPointer = function() {
+ var pointer = this.decodePointer();
+ if (!pointer) {
+ return null;
+ }
+ return this.decodeAndCreateDecoder(pointer).decodeString();
+ };
+
+ Decoder.prototype.decodeMap = function(keyClass, valueClass) {
+ this.skip(4); // numberOfBytes
+ this.skip(4); // version
+ var keys = this.decodeArrayPointer(keyClass);
+ var values = this.decodeArrayPointer(valueClass);
+ var val = new Map();
+ for (var i = 0; i < keys.length; i++)
+ val.set(keys[i], values[i]);
+ return val;
+ };
+
+ Decoder.prototype.decodeMapPointer = function(keyClass, valueClass) {
+ var pointer = this.decodePointer();
+ if (!pointer) {
+ return null;
+ }
+ var decoder = this.decodeAndCreateDecoder(pointer);
+ return decoder.decodeMap(keyClass, valueClass);
+ };
+
+ // Encoder ------------------------------------------------------------------
+
+ function Encoder(buffer, handles, associatedEndpointHandles, base) {
+ this.buffer = buffer;
+ this.handles = handles;
+ this.associatedEndpointHandles = associatedEndpointHandles;
+ this.base = base;
+ this.next = base;
+ }
+
+ Encoder.prototype.align = function() {
+ this.next = align(this.next);
+ };
+
+ Encoder.prototype.skip = function(offset) {
+ this.next += offset;
+ };
+
+ Encoder.prototype.writeInt8 = function(val) {
+ this.buffer.setInt8(this.next, val);
+ this.next += 1;
+ };
+
+ Encoder.prototype.writeUint8 = function(val) {
+ if (val < 0) {
+ throw new Error(kErrorUnsigned);
+ }
+ this.buffer.setUint8(this.next, val);
+ this.next += 1;
+ };
+
+ Encoder.prototype.writeInt16 = function(val) {
+ this.buffer.setInt16(this.next, val);
+ this.next += 2;
+ };
+
+ Encoder.prototype.writeUint16 = function(val) {
+ if (val < 0) {
+ throw new Error(kErrorUnsigned);
+ }
+ this.buffer.setUint16(this.next, val);
+ this.next += 2;
+ };
+
+ Encoder.prototype.writeInt32 = function(val) {
+ this.buffer.setInt32(this.next, val);
+ this.next += 4;
+ };
+
+ Encoder.prototype.writeUint32 = function(val) {
+ if (val < 0) {
+ throw new Error(kErrorUnsigned);
+ }
+ this.buffer.setUint32(this.next, val);
+ this.next += 4;
+ };
+
+ Encoder.prototype.writeInt64 = function(val) {
+ this.buffer.setInt64(this.next, val);
+ this.next += 8;
+ };
+
+ Encoder.prototype.writeUint64 = function(val) {
+ if (val < 0) {
+ throw new Error(kErrorUnsigned);
+ }
+ this.buffer.setUint64(this.next, val);
+ this.next += 8;
+ };
+
+ Encoder.prototype.writeFloat = function(val) {
+ this.buffer.setFloat32(this.next, val);
+ this.next += 4;
+ };
+
+ Encoder.prototype.writeDouble = function(val) {
+ this.buffer.setFloat64(this.next, val);
+ this.next += 8;
+ };
+
+ Encoder.prototype.encodePointer = function(pointer) {
+ if (!pointer)
+ return this.writeUint64(0);
+ // TODO(abarth): To correctly encode a pointer, we need to know the real
+ // base address of the array buffer.
+ var offset = pointer - this.next;
+ this.writeUint64(offset);
+ };
+
+ Encoder.prototype.createAndEncodeEncoder = function(size) {
+ var pointer = this.buffer.alloc(align(size));
+ this.encodePointer(pointer);
+ return new Encoder(this.buffer, this.handles,
+ this.associatedEndpointHandles, pointer);
+ };
+
+ Encoder.prototype.encodeHandle = function(handle) {
+ if (handle) {
+ this.handles.push(handle);
+ this.writeUint32(this.handles.length - 1);
+ } else {
+ this.writeUint32(kEncodedInvalidHandleValue);
+ }
+ };
+
+ Encoder.prototype.encodeAssociatedEndpointHandle = function(endpointHandle) {
+ if (endpointHandle) {
+ this.associatedEndpointHandles.push(endpointHandle);
+ this.writeUint32(this.associatedEndpointHandles.length - 1);
+ } else {
+ this.writeUint32(kEncodedInvalidHandleValue);
+ }
+ };
+
+ Encoder.prototype.encodeString = function(val) {
+ var base = this.next + kArrayHeaderSize;
+ var numberOfElements = internal.encodeUtf8String(
+ val, new Uint8Array(this.buffer.arrayBuffer, base));
+ var numberOfBytes = kArrayHeaderSize + numberOfElements;
+ this.writeUint32(numberOfBytes);
+ this.writeUint32(numberOfElements);
+ this.next += numberOfElements;
+ };
+
+ 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);
+
+ if (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]);
+ }
+ };
+
+ Encoder.prototype.encodeStruct = function(cls, val) {
+ return cls.encode(this, val);
+ };
+
+ Encoder.prototype.encodeStructPointer = function(cls, val) {
+ if (val == null) {
+ // Also handles undefined, since undefined == null.
+ this.encodePointer(val);
+ return;
+ }
+ var encoder = this.createAndEncodeEncoder(cls.encodedSize);
+ cls.encode(encoder, val);
+ };
+
+ Encoder.prototype.encodeArrayPointer = function(cls, val) {
+ if (val == null) {
+ // Also handles undefined, since undefined == null.
+ this.encodePointer(val);
+ return;
+ }
+
+ var numberOfElements = val.length;
+ if (!Number.isSafeInteger(numberOfElements) || numberOfElements < 0)
+ throw new Error(kErrorArray);
+
+ var encodedSize = kArrayHeaderSize + ((cls === PackedBool) ?
+ Math.ceil(numberOfElements / 8) : cls.encodedSize * numberOfElements);
+ var encoder = this.createAndEncodeEncoder(encodedSize);
+ encoder.encodeArray(cls, val, numberOfElements, encodedSize);
+ };
+
+ Encoder.prototype.encodeStringPointer = function(val) {
+ if (val == null) {
+ // Also handles undefined, since undefined == null.
+ this.encodePointer(val);
+ return;
+ }
+ // Only accepts string primivites, not String Objects like new String("foo")
+ if (typeof(val) !== "string") {
+ throw new Error(kErrorString);
+ }
+ var encodedSize = kArrayHeaderSize + internal.utf8Length(val);
+ var encoder = this.createAndEncodeEncoder(encodedSize);
+ encoder.encodeString(val);
+ };
+
+ Encoder.prototype.encodeMap = function(keyClass, valueClass, val) {
+ var keys = new Array(val.size);
+ var values = new Array(val.size);
+ var i = 0;
+ val.forEach(function(value, key) {
+ values[i] = value;
+ keys[i++] = key;
+ });
+ this.writeUint32(kStructHeaderSize + kMapStructPayloadSize);
+ this.writeUint32(0); // version
+ this.encodeArrayPointer(keyClass, keys);
+ this.encodeArrayPointer(valueClass, values);
+ }
+
+ Encoder.prototype.encodeMapPointer = function(keyClass, valueClass, val) {
+ if (val == null) {
+ // Also handles undefined, since undefined == null.
+ this.encodePointer(val);
+ return;
+ }
+ if (!(val instanceof Map)) {
+ throw new Error(kErrorMap);
+ }
+ var encodedSize = kStructHeaderSize + kMapStructPayloadSize;
+ var encoder = this.createAndEncodeEncoder(encodedSize);
+ encoder.encodeMap(keyClass, valueClass, val);
+ };
+
+ // Message ------------------------------------------------------------------
+
+ var kMessageInterfaceIdOffset = kStructHeaderSize;
+ var kMessageNameOffset = kMessageInterfaceIdOffset + 4;
+ var kMessageFlagsOffset = kMessageNameOffset + 4;
+ var kMessageRequestIDOffset = kMessageFlagsOffset + 8;
+ var kMessagePayloadInterfaceIdsPointerOffset = kMessageV2HeaderSize - 8;
+
+ var kMessageExpectsResponse = 1 << 0;
+ var kMessageIsResponse = 1 << 1;
+
+ function Message(buffer, handles, associatedEndpointHandles) {
+ if (associatedEndpointHandles === undefined) {
+ associatedEndpointHandles = [];
+ }
+
+ this.buffer = buffer;
+ this.handles = handles;
+ this.associatedEndpointHandles = associatedEndpointHandles;
+ }
+
+ Message.prototype.getHeaderNumBytes = function() {
+ return this.buffer.getUint32(kStructHeaderNumBytesOffset);
+ };
+
+ Message.prototype.getHeaderVersion = function() {
+ return this.buffer.getUint32(kStructHeaderVersionOffset);
+ };
+
+ Message.prototype.getName = function() {
+ return this.buffer.getUint32(kMessageNameOffset);
+ };
+
+ Message.prototype.getFlags = function() {
+ return this.buffer.getUint32(kMessageFlagsOffset);
+ };
+
+ Message.prototype.getInterfaceId = function() {
+ return this.buffer.getUint32(kMessageInterfaceIdOffset);
+ };
+
+ Message.prototype.getPayloadInterfaceIds = function() {
+ if (this.getHeaderVersion() < 2) {
+ return null;
+ }
+
+ var decoder = new Decoder(this.buffer, this.handles,
+ this.associatedEndpointHandles,
+ kMessagePayloadInterfaceIdsPointerOffset);
+ var payloadInterfaceIds = decoder.decodeArrayPointer(Uint32);
+ return payloadInterfaceIds;
+ };
+
+ 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);
+ };
+
+ Message.prototype.setInterfaceId = function(interfaceId) {
+ this.buffer.setUint32(kMessageInterfaceIdOffset, interfaceId);
+ };
+
+ Message.prototype.setPayloadInterfaceIds_ = function(payloadInterfaceIds) {
+ if (this.getHeaderVersion() < 2) {
+ throw new Error(
+ "Version of message does not support payload interface ids");
+ }
+
+ var decoder = new Decoder(this.buffer, this.handles,
+ this.associatedEndpointHandles,
+ kMessagePayloadInterfaceIdsPointerOffset);
+ var payloadInterfaceIdsOffset = decoder.decodePointer();
+ var encoder = new Encoder(this.buffer, this.handles,
+ this.associatedEndpointHandles,
+ payloadInterfaceIdsOffset);
+ encoder.encodeArray(Uint32, payloadInterfaceIds);
+ };
+
+ Message.prototype.serializeAssociatedEndpointHandles = function(
+ associatedGroupController) {
+ if (this.associatedEndpointHandles.length > 0) {
+ if (this.getHeaderVersion() < 2) {
+ throw new Error(
+ "Version of message does not support associated endpoint handles");
+ }
+
+ var data = [];
+ for (var i = 0; i < this.associatedEndpointHandles.length; i++) {
+ var handle = this.associatedEndpointHandles[i];
+ data.push(associatedGroupController.associateInterface(handle));
+ }
+ this.associatedEndpointHandles = [];
+ this.setPayloadInterfaceIds_(data);
+ }
+ };
+
+ Message.prototype.deserializeAssociatedEndpointHandles = function(
+ associatedGroupController) {
+ if (this.getHeaderVersion() < 2) {
+ return true;
+ }
+
+ this.associatedEndpointHandles = [];
+ var ids = this.getPayloadInterfaceIds();
+
+ var result = true;
+ for (var i = 0; i < ids.length; i++) {
+ var handle = associatedGroupController.createLocalEndpointHandle(ids[i]);
+ if (internal.isValidInterfaceId(ids[i]) && !handle.isValid()) {
+ // |ids[i]| itself is valid but handle creation failed. In that case,
+ // mark deserialization as failed but continue to deserialize the
+ // rest of handles.
+ result = false;
+ }
+ this.associatedEndpointHandles.push(handle);
+ ids[i] = internal.kInvalidInterfaceId;
+ }
+
+ this.setPayloadInterfaceIds_(ids);
+ return result;
+ };
+
+
+ // MessageV0Builder ---------------------------------------------------------
+
+ function MessageV0Builder(messageName, payloadSize) {
+ // Currently, we don't compute the payload size correctly ahead of time.
+ // Instead, we resize the buffer at the end.
+ var numberOfBytes = kMessageV0HeaderSize + payloadSize;
+ this.buffer = new internal.Buffer(numberOfBytes);
+ this.handles = [];
+ var encoder = this.createEncoder(kMessageV0HeaderSize);
+ encoder.writeUint32(kMessageV0HeaderSize);
+ encoder.writeUint32(0); // version.
+ encoder.writeUint32(0); // interface ID.
+ encoder.writeUint32(messageName);
+ encoder.writeUint32(0); // flags.
+ encoder.writeUint32(0); // padding.
+ }
+
+ MessageV0Builder.prototype.createEncoder = function(size) {
+ var pointer = this.buffer.alloc(size);
+ return new Encoder(this.buffer, this.handles, [], pointer);
+ };
+
+ MessageV0Builder.prototype.encodeStruct = function(cls, val) {
+ cls.encode(this.createEncoder(cls.encodedSize), val);
+ };
+
+ MessageV0Builder.prototype.finish = function() {
+ // TODO(abarth): Rather than resizing the buffer at the end, we could
+ // compute the size we need ahead of time, like we do in C++.
+ this.buffer.trim();
+ var message = new Message(this.buffer, this.handles);
+ this.buffer = null;
+ this.handles = null;
+ this.encoder = null;
+ return message;
+ };
+
+ // MessageV1Builder -----------------------------------------------
+
+ function MessageV1Builder(messageName, payloadSize, flags,
+ requestID) {
+ // Currently, we don't compute the payload size correctly ahead of time.
+ // Instead, we resize the buffer at the end.
+ var numberOfBytes = kMessageV1HeaderSize + payloadSize;
+ this.buffer = new internal.Buffer(numberOfBytes);
+ this.handles = [];
+ var encoder = this.createEncoder(kMessageV1HeaderSize);
+ encoder.writeUint32(kMessageV1HeaderSize);
+ encoder.writeUint32(1); // version.
+ encoder.writeUint32(0); // interface ID.
+ encoder.writeUint32(messageName);
+ encoder.writeUint32(flags);
+ encoder.writeUint32(0); // padding.
+ encoder.writeUint64(requestID);
+ }
+
+ MessageV1Builder.prototype =
+ Object.create(MessageV0Builder.prototype);
+
+ MessageV1Builder.prototype.constructor =
+ MessageV1Builder;
+
+ // MessageV2 -----------------------------------------------
+
+ function MessageV2Builder(messageName, payloadSize, flags, requestID) {
+ // Currently, we don't compute the payload size correctly ahead of time.
+ // Instead, we resize the buffer at the end.
+ var numberOfBytes = kMessageV2HeaderSize + payloadSize;
+ this.buffer = new internal.Buffer(numberOfBytes);
+ this.handles = [];
+
+ this.payload = null;
+ this.associatedEndpointHandles = [];
+
+ this.encoder = this.createEncoder(kMessageV2HeaderSize);
+ this.encoder.writeUint32(kMessageV2HeaderSize);
+ this.encoder.writeUint32(2); // version.
+ // Gets set to an appropriate interfaceId for the endpoint by the Router.
+ this.encoder.writeUint32(0); // interface ID.
+ this.encoder.writeUint32(messageName);
+ this.encoder.writeUint32(flags);
+ this.encoder.writeUint32(0); // padding.
+ this.encoder.writeUint64(requestID);
+ }
+
+ MessageV2Builder.prototype.createEncoder = function(size) {
+ var pointer = this.buffer.alloc(size);
+ return new Encoder(this.buffer, this.handles,
+ this.associatedEndpointHandles, pointer);
+ };
+
+ MessageV2Builder.prototype.setPayload = function(cls, val) {
+ this.payload = {cls: cls, val: val};
+ };
+
+ MessageV2Builder.prototype.finish = function() {
+ if (!this.payload) {
+ throw new Error("Payload needs to be set before calling finish");
+ }
+
+ this.encoder.encodeStructPointer(this.payload.cls, this.payload.val);
+ this.encoder.encodeArrayPointer(Uint32,
+ new Array(this.associatedEndpointHandles.length));
+
+ this.buffer.trim();
+ var message = new Message(this.buffer, this.handles,
+ this.associatedEndpointHandles);
+ this.buffer = null;
+ this.handles = null;
+ this.encoder = null;
+ this.payload = null;
+ this.associatedEndpointHandles = null;
+
+ return message;
+ };
+
+ // MessageReader ------------------------------------------------------------
+
+ function MessageReader(message) {
+ this.decoder = new Decoder(message.buffer, message.handles,
+ message.associatedEndpointHandles, 0);
+ var messageHeaderSize = this.decoder.readUint32();
+ this.payloadSize = message.buffer.byteLength - messageHeaderSize;
+ var version = this.decoder.readUint32();
+ var interface_id = this.decoder.readUint32();
+ this.messageName = this.decoder.readUint32();
+ this.flags = this.decoder.readUint32();
+ // Skip the padding.
+ this.decoder.skip(4);
+ if (version >= 1)
+ this.requestID = this.decoder.readUint64();
+ this.decoder.skip(messageHeaderSize - this.decoder.next);
+ }
+
+ MessageReader.prototype.decodeStruct = function(cls) {
+ return cls.decode(this.decoder);
+ };
+
+ // Built-in types -----------------------------------------------------------
+
+ // This type is only used with ArrayOf(PackedBool).
+ function PackedBool() {
+ }
+
+ function Int8() {
+ }
+
+ Int8.encodedSize = 1;
+
+ Int8.decode = function(decoder) {
+ return decoder.readInt8();
+ };
+
+ Int8.encode = function(encoder, val) {
+ encoder.writeInt8(val);
+ };
+
+ Uint8.encode = function(encoder, val) {
+ encoder.writeUint8(val);
+ };
+
+ function Uint8() {
+ }
+
+ Uint8.encodedSize = 1;
+
+ Uint8.decode = function(decoder) {
+ return decoder.readUint8();
+ };
+
+ Uint8.encode = function(encoder, val) {
+ encoder.writeUint8(val);
+ };
+
+ function Int16() {
+ }
+
+ Int16.encodedSize = 2;
+
+ Int16.decode = function(decoder) {
+ return decoder.readInt16();
+ };
+
+ Int16.encode = function(encoder, val) {
+ encoder.writeInt16(val);
+ };
+
+ function Uint16() {
+ }
+
+ Uint16.encodedSize = 2;
+
+ Uint16.decode = function(decoder) {
+ return decoder.readUint16();
+ };
+
+ Uint16.encode = function(encoder, val) {
+ encoder.writeUint16(val);
+ };
+
+ function Int32() {
+ }
+
+ Int32.encodedSize = 4;
+
+ Int32.decode = function(decoder) {
+ return decoder.readInt32();
+ };
+
+ Int32.encode = function(encoder, val) {
+ encoder.writeInt32(val);
+ };
+
+ function Uint32() {
+ }
+
+ Uint32.encodedSize = 4;
+
+ Uint32.decode = function(decoder) {
+ return decoder.readUint32();
+ };
+
+ Uint32.encode = function(encoder, val) {
+ encoder.writeUint32(val);
+ };
+
+ function Int64() {
+ }
+
+ Int64.encodedSize = 8;
+
+ Int64.decode = function(decoder) {
+ return decoder.readInt64();
+ };
+
+ Int64.encode = function(encoder, val) {
+ encoder.writeInt64(val);
+ };
+
+ function Uint64() {
+ }
+
+ Uint64.encodedSize = 8;
+
+ Uint64.decode = function(decoder) {
+ return decoder.readUint64();
+ };
+
+ Uint64.encode = function(encoder, val) {
+ encoder.writeUint64(val);
+ };
+
+ function String() {
+ };
+
+ String.encodedSize = 8;
+
+ String.decode = function(decoder) {
+ return decoder.decodeStringPointer();
+ };
+
+ String.encode = function(encoder, val) {
+ encoder.encodeStringPointer(val);
+ };
+
+ function NullableString() {
+ }
+
+ NullableString.encodedSize = String.encodedSize;
+
+ NullableString.decode = String.decode;
+
+ NullableString.encode = String.encode;
+
+ function Float() {
+ }
+
+ Float.encodedSize = 4;
+
+ Float.decode = function(decoder) {
+ return decoder.readFloat();
+ };
+
+ Float.encode = function(encoder, val) {
+ encoder.writeFloat(val);
+ };
+
+ function Double() {
+ }
+
+ Double.encodedSize = 8;
+
+ Double.decode = function(decoder) {
+ return decoder.readDouble();
+ };
+
+ Double.encode = function(encoder, val) {
+ encoder.writeDouble(val);
+ };
+
+ function Enum(cls) {
+ this.cls = cls;
+ }
+
+ Enum.prototype.encodedSize = 4;
+
+ Enum.prototype.decode = function(decoder) {
+ return decoder.readInt32();
+ };
+
+ Enum.prototype.encode = function(encoder, val) {
+ encoder.writeInt32(val);
+ };
+
+ function PointerTo(cls) {
+ this.cls = cls;
+ }
+
+ PointerTo.prototype.encodedSize = 8;
+
+ PointerTo.prototype.decode = function(decoder) {
+ var pointer = decoder.decodePointer();
+ if (!pointer) {
+ return null;
+ }
+ return this.cls.decode(decoder.decodeAndCreateDecoder(pointer));
+ };
+
+ PointerTo.prototype.encode = function(encoder, val) {
+ if (!val) {
+ encoder.encodePointer(val);
+ return;
+ }
+ var objectEncoder = encoder.createAndEncodeEncoder(this.cls.encodedSize);
+ this.cls.encode(objectEncoder, val);
+ };
+
+ function NullablePointerTo(cls) {
+ PointerTo.call(this, cls);
+ }
+
+ NullablePointerTo.prototype = Object.create(PointerTo.prototype);
+
+ function ArrayOf(cls, length) {
+ this.cls = cls;
+ this.length = length || 0;
+ }
+
+ ArrayOf.prototype.encodedSize = 8;
+
+ ArrayOf.prototype.dimensions = function() {
+ return [this.length].concat(
+ (this.cls instanceof ArrayOf) ? this.cls.dimensions() : []);
+ }
+
+ ArrayOf.prototype.decode = function(decoder) {
+ return decoder.decodeArrayPointer(this.cls);
+ };
+
+ ArrayOf.prototype.encode = function(encoder, val) {
+ encoder.encodeArrayPointer(this.cls, val);
+ };
+
+ function NullableArrayOf(cls) {
+ ArrayOf.call(this, cls);
+ }
+
+ NullableArrayOf.prototype = Object.create(ArrayOf.prototype);
+
+ function Handle() {
+ }
+
+ Handle.encodedSize = 4;
+
+ Handle.decode = function(decoder) {
+ return decoder.decodeHandle();
+ };
+
+ Handle.encode = function(encoder, val) {
+ encoder.encodeHandle(val);
+ };
+
+ function NullableHandle() {
+ }
+
+ NullableHandle.encodedSize = Handle.encodedSize;
+
+ NullableHandle.decode = Handle.decode;
+
+ NullableHandle.encode = Handle.encode;
+
+ function Interface(cls) {
+ this.cls = cls;
+ }
+
+ Interface.prototype.encodedSize = 8;
+
+ Interface.prototype.decode = function(decoder) {
+ var interfacePtrInfo = new mojo.InterfacePtrInfo(
+ decoder.decodeHandle(), decoder.readUint32());
+ var interfacePtr = new this.cls();
+ interfacePtr.ptr.bind(interfacePtrInfo);
+ return interfacePtr;
+ };
+
+ Interface.prototype.encode = function(encoder, val) {
+ var interfacePtrInfo =
+ val ? val.ptr.passInterface() : new mojo.InterfacePtrInfo(null, 0);
+ encoder.encodeHandle(interfacePtrInfo.handle);
+ encoder.writeUint32(interfacePtrInfo.version);
+ };
+
+ function NullableInterface(cls) {
+ Interface.call(this, cls);
+ }
+
+ NullableInterface.prototype = Object.create(Interface.prototype);
+
+ function AssociatedInterfacePtrInfo() {
+ }
+
+ AssociatedInterfacePtrInfo.prototype.encodedSize = 8;
+
+ AssociatedInterfacePtrInfo.decode = function(decoder) {
+ return new mojo.AssociatedInterfacePtrInfo(
+ decoder.decodeAssociatedEndpointHandle(), decoder.readUint32());
+ };
+
+ AssociatedInterfacePtrInfo.encode = function(encoder, val) {
+ var associatedinterfacePtrInfo =
+ val ? val : new mojo.AssociatedInterfacePtrInfo(null, 0);
+ encoder.encodeAssociatedEndpointHandle(
+ associatedinterfacePtrInfo.interfaceEndpointHandle);
+ encoder.writeUint32(associatedinterfacePtrInfo.version);
+ };
+
+ function NullableAssociatedInterfacePtrInfo() {
+ }
+
+ NullableAssociatedInterfacePtrInfo.encodedSize =
+ AssociatedInterfacePtrInfo.encodedSize;
+
+ NullableAssociatedInterfacePtrInfo.decode =
+ AssociatedInterfacePtrInfo.decode;
+
+ NullableAssociatedInterfacePtrInfo.encode =
+ AssociatedInterfacePtrInfo.encode;
+
+ function InterfaceRequest() {
+ }
+
+ InterfaceRequest.encodedSize = 4;
+
+ InterfaceRequest.decode = function(decoder) {
+ return new mojo.InterfaceRequest(decoder.decodeHandle());
+ };
+
+ InterfaceRequest.encode = function(encoder, val) {
+ encoder.encodeHandle(val ? val.handle : null);
+ };
+
+ function NullableInterfaceRequest() {
+ }
+
+ NullableInterfaceRequest.encodedSize = InterfaceRequest.encodedSize;
+
+ NullableInterfaceRequest.decode = InterfaceRequest.decode;
+
+ NullableInterfaceRequest.encode = InterfaceRequest.encode;
+
+ function AssociatedInterfaceRequest() {
+ }
+
+ AssociatedInterfaceRequest.decode = function(decoder) {
+ var handle = decoder.decodeAssociatedEndpointHandle();
+ return new mojo.AssociatedInterfaceRequest(handle);
+ };
+
+ AssociatedInterfaceRequest.encode = function(encoder, val) {
+ encoder.encodeAssociatedEndpointHandle(
+ val ? val.interfaceEndpointHandle : null);
+ };
+
+ AssociatedInterfaceRequest.encodedSize = 4;
+
+ function NullableAssociatedInterfaceRequest() {
+ }
+
+ NullableAssociatedInterfaceRequest.encodedSize =
+ AssociatedInterfaceRequest.encodedSize;
+
+ NullableAssociatedInterfaceRequest.decode =
+ AssociatedInterfaceRequest.decode;
+
+ NullableAssociatedInterfaceRequest.encode =
+ AssociatedInterfaceRequest.encode;
+
+ function MapOf(keyClass, valueClass) {
+ this.keyClass = keyClass;
+ this.valueClass = valueClass;
+ }
+
+ MapOf.prototype.encodedSize = 8;
+
+ MapOf.prototype.decode = function(decoder) {
+ return decoder.decodeMapPointer(this.keyClass, this.valueClass);
+ };
+
+ MapOf.prototype.encode = function(encoder, val) {
+ encoder.encodeMapPointer(this.keyClass, this.valueClass, val);
+ };
+
+ function NullableMapOf(keyClass, valueClass) {
+ MapOf.call(this, keyClass, valueClass);
+ }
+
+ NullableMapOf.prototype = Object.create(MapOf.prototype);
+
+ internal.align = align;
+ internal.isAligned = isAligned;
+ internal.Message = Message;
+ internal.MessageV0Builder = MessageV0Builder;
+ internal.MessageV1Builder = MessageV1Builder;
+ internal.MessageV2Builder = MessageV2Builder;
+ internal.MessageReader = MessageReader;
+ internal.kArrayHeaderSize = kArrayHeaderSize;
+ internal.kMapStructPayloadSize = kMapStructPayloadSize;
+ internal.kStructHeaderSize = kStructHeaderSize;
+ internal.kEncodedInvalidHandleValue = kEncodedInvalidHandleValue;
+ internal.kMessageV0HeaderSize = kMessageV0HeaderSize;
+ internal.kMessageV1HeaderSize = kMessageV1HeaderSize;
+ internal.kMessageV2HeaderSize = kMessageV2HeaderSize;
+ internal.kMessagePayloadInterfaceIdsPointerOffset =
+ kMessagePayloadInterfaceIdsPointerOffset;
+ internal.kMessageExpectsResponse = kMessageExpectsResponse;
+ internal.kMessageIsResponse = kMessageIsResponse;
+ internal.Int8 = Int8;
+ internal.Uint8 = Uint8;
+ internal.Int16 = Int16;
+ internal.Uint16 = Uint16;
+ internal.Int32 = Int32;
+ internal.Uint32 = Uint32;
+ internal.Int64 = Int64;
+ internal.Uint64 = Uint64;
+ internal.Float = Float;
+ internal.Double = Double;
+ internal.String = String;
+ internal.Enum = Enum;
+ internal.NullableString = NullableString;
+ internal.PointerTo = PointerTo;
+ internal.NullablePointerTo = NullablePointerTo;
+ internal.ArrayOf = ArrayOf;
+ internal.NullableArrayOf = NullableArrayOf;
+ internal.PackedBool = PackedBool;
+ internal.Handle = Handle;
+ internal.NullableHandle = NullableHandle;
+ internal.Interface = Interface;
+ internal.NullableInterface = NullableInterface;
+ internal.InterfaceRequest = InterfaceRequest;
+ internal.NullableInterfaceRequest = NullableInterfaceRequest;
+ internal.AssociatedInterfacePtrInfo = AssociatedInterfacePtrInfo;
+ internal.NullableAssociatedInterfacePtrInfo =
+ NullableAssociatedInterfacePtrInfo;
+ internal.AssociatedInterfaceRequest = AssociatedInterfaceRequest;
+ internal.NullableAssociatedInterfaceRequest =
+ NullableAssociatedInterfaceRequest;
+ internal.MapOf = MapOf;
+ internal.NullableMapOf = NullableMapOf;
+})();
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+(function() {
+ var internal = mojo.internal;
+
+ function Connector(handle) {
+ if (!(handle instanceof MojoHandle))
+ throw new Error("Connector: not a handle " + handle);
+ this.handle_ = handle;
+ this.dropWrites_ = false;
+ this.error_ = false;
+ this.incomingReceiver_ = null;
+ this.readWatcher_ = null;
+ this.errorHandler_ = null;
+ this.paused_ = false;
+
+ this.waitToReadMore();
+ }
+
+ Connector.prototype.close = function() {
+ this.cancelWait();
+ if (this.handle_ != null) {
+ this.handle_.close();
+ this.handle_ = null;
+ }
+ };
+
+ Connector.prototype.pauseIncomingMethodCallProcessing = function() {
+ if (this.paused_) {
+ return;
+ }
+ this.paused_= true;
+ this.cancelWait();
+ };
+
+ Connector.prototype.resumeIncomingMethodCallProcessing = function() {
+ if (!this.paused_) {
+ return;
+ }
+ this.paused_= false;
+ this.waitToReadMore();
+ };
+
+ Connector.prototype.accept = function(message) {
+ if (this.error_)
+ return false;
+
+ if (this.dropWrites_)
+ return true;
+
+ var result = this.handle_.writeMessage(
+ new Uint8Array(message.buffer.arrayBuffer), message.handles);
+ switch (result) {
+ case Mojo.RESULT_OK:
+ // The handles were successfully transferred, so we don't own them
+ // anymore.
+ message.handles = [];
+ break;
+ case Mojo.RESULT_FAILED_PRECONDITION:
+ // There's no point in continuing to write to this pipe since the other
+ // end is gone. Avoid writing any future messages. Hide write failures
+ // from the caller since we'd like them to continue consuming any
+ // backlog of incoming messages before regarding the message pipe as
+ // closed.
+ this.dropWrites_ = true;
+ break;
+ default:
+ // This particular write was rejected, presumably because of bad input.
+ // The pipe is not necessarily in a bad state.
+ return false;
+ }
+ return true;
+ };
+
+ Connector.prototype.setIncomingReceiver = function(receiver) {
+ this.incomingReceiver_ = receiver;
+ };
+
+ Connector.prototype.setErrorHandler = function(handler) {
+ this.errorHandler_ = handler;
+ };
+
+ Connector.prototype.readMore_ = function(result) {
+ for (;;) {
+ if (this.paused_) {
+ return;
+ }
+
+ var read = this.handle_.readMessage();
+ if (this.handle_ == null) // The connector has been closed.
+ return;
+ if (read.result == Mojo.RESULT_SHOULD_WAIT)
+ return;
+ if (read.result != Mojo.RESULT_OK) {
+ this.handleError(read.result !== Mojo.RESULT_FAILED_PRECONDITION,
+ false);
+ return;
+ }
+ var messageBuffer = new internal.Buffer(read.buffer);
+ var message = new internal.Message(messageBuffer, read.handles);
+ var receiverResult = this.incomingReceiver_ &&
+ this.incomingReceiver_.accept(message);
+
+ // Handle invalid incoming message.
+ if (!internal.isTestingMode() && !receiverResult) {
+ // TODO(yzshen): Consider notifying the embedder.
+ this.handleError(true, false);
+ }
+ }
+ };
+
+ Connector.prototype.cancelWait = function() {
+ if (this.readWatcher_) {
+ this.readWatcher_.cancel();
+ this.readWatcher_ = null;
+ }
+ };
+
+ Connector.prototype.waitToReadMore = function() {
+ if (this.handle_) {
+ this.readWatcher_ = this.handle_.watch({readable: true},
+ this.readMore_.bind(this));
+ }
+ };
+
+ Connector.prototype.handleError = function(forcePipeReset,
+ forceAsyncHandler) {
+ if (this.error_ || this.handle_ === null) {
+ return;
+ }
+
+ if (this.paused_) {
+ // Enforce calling the error handler asynchronously if the user has
+ // paused receiving messages. We need to wait until the user starts
+ // receiving messages again.
+ forceAsyncHandler = true;
+ }
+
+ if (!forcePipeReset && forceAsyncHandler) {
+ forcePipeReset = true;
+ }
+
+ this.cancelWait();
+ if (forcePipeReset) {
+ this.handle_.close();
+ var dummyPipe = Mojo.createMessagePipe();
+ this.handle_ = dummyPipe.handle0;
+ }
+
+ if (forceAsyncHandler) {
+ if (!this.paused_) {
+ this.waitToReadMore();
+ }
+ } else {
+ this.error_ = true;
+ if (this.errorHandler_) {
+ this.errorHandler_.onError();
+ }
+ }
+ };
+
+ internal.Connector = Connector;
+})();
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+(function() {
+ var internal = mojo.internal;
+
+ // Constants ----------------------------------------------------------------
+ var kInterfaceIdNamespaceMask = 0x80000000;
+ var kMasterInterfaceId = 0x00000000;
+ var kInvalidInterfaceId = 0xFFFFFFFF;
+
+ // ---------------------------------------------------------------------------
+
+ function InterfacePtrInfo(handle, version) {
+ this.handle = handle;
+ this.version = version;
+ }
+
+ InterfacePtrInfo.prototype.isValid = function() {
+ return this.handle instanceof MojoHandle;
+ };
+
+ InterfacePtrInfo.prototype.close = function() {
+ if (!this.isValid())
+ return;
+
+ this.handle.close();
+ this.handle = null;
+ this.version = 0;
+ };
+
+ function AssociatedInterfacePtrInfo(interfaceEndpointHandle, version) {
+ this.interfaceEndpointHandle = interfaceEndpointHandle;
+ this.version = version;
+ }
+
+ AssociatedInterfacePtrInfo.prototype.isValid = function() {
+ return this.interfaceEndpointHandle.isValid();
+ };
+
+ // ---------------------------------------------------------------------------
+
+ function InterfaceRequest(handle) {
+ this.handle = handle;
+ }
+
+ InterfaceRequest.prototype.isValid = function() {
+ return this.handle instanceof MojoHandle;
+ };
+
+ InterfaceRequest.prototype.close = function() {
+ if (!this.isValid())
+ return;
+
+ this.handle.close();
+ this.handle = null;
+ };
+
+ function AssociatedInterfaceRequest(interfaceEndpointHandle) {
+ this.interfaceEndpointHandle = interfaceEndpointHandle;
+ }
+
+ AssociatedInterfaceRequest.prototype.isValid = function() {
+ return this.interfaceEndpointHandle.isValid();
+ };
+
+ AssociatedInterfaceRequest.prototype.resetWithReason = function(reason) {
+ this.interfaceEndpointHandle.reset(reason);
+ };
+
+ function isMasterInterfaceId(interfaceId) {
+ return interfaceId === kMasterInterfaceId;
+ }
+
+ function isValidInterfaceId(interfaceId) {
+ return interfaceId !== kInvalidInterfaceId;
+ }
+
+ mojo.InterfacePtrInfo = InterfacePtrInfo;
+ mojo.InterfaceRequest = InterfaceRequest;
+ mojo.AssociatedInterfacePtrInfo = AssociatedInterfacePtrInfo;
+ mojo.AssociatedInterfaceRequest = AssociatedInterfaceRequest;
+ internal.isMasterInterfaceId = isMasterInterfaceId;
+ internal.isValidInterfaceId = isValidInterfaceId;
+ internal.kInvalidInterfaceId = kInvalidInterfaceId;
+ internal.kMasterInterfaceId = kMasterInterfaceId;
+ internal.kInterfaceIdNamespaceMask = kInterfaceIdNamespaceMask;
+})();
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+(function() {
+ var internal = mojo.internal;
+
+ function validateControlRequestWithResponse(message) {
+ var messageValidator = new internal.Validator(message);
+ var error = messageValidator.validateMessageIsRequestExpectingResponse();
+ if (error !== internal.validationError.NONE) {
+ throw error;
+ }
+
+ if (message.getName() != mojo.interfaceControl2.kRunMessageId) {
+ throw new Error("Control message name is not kRunMessageId");
+ }
+
+ // Validate payload.
+ error = mojo.interfaceControl2.RunMessageParams.validate(messageValidator,
+ message.getHeaderNumBytes());
+ if (error != internal.validationError.NONE) {
+ throw error;
+ }
+ }
+
+ function validateControlRequestWithoutResponse(message) {
+ var messageValidator = new internal.Validator(message);
+ var error = messageValidator.validateMessageIsRequestWithoutResponse();
+ if (error != internal.validationError.NONE) {
+ throw error;
+ }
+
+ if (message.getName() != mojo.interfaceControl2.kRunOrClosePipeMessageId) {
+ throw new Error("Control message name is not kRunOrClosePipeMessageId");
+ }
+
+ // Validate payload.
+ error = mojo.interfaceControl2.RunOrClosePipeMessageParams.validate(
+ messageValidator, message.getHeaderNumBytes());
+ if (error != internal.validationError.NONE) {
+ throw error;
+ }
+ }
+
+ function runOrClosePipe(message, interfaceVersion) {
+ var reader = new internal.MessageReader(message);
+ var runOrClosePipeMessageParams = reader.decodeStruct(
+ mojo.interfaceControl2.RunOrClosePipeMessageParams);
+ return interfaceVersion >=
+ runOrClosePipeMessageParams.input.requireVersion.version;
+ }
+
+ function run(message, responder, interfaceVersion) {
+ var reader = new internal.MessageReader(message);
+ var runMessageParams =
+ reader.decodeStruct(mojo.interfaceControl2.RunMessageParams);
+ var runOutput = null;
+
+ if (runMessageParams.input.queryVersion) {
+ runOutput = new mojo.interfaceControl2.RunOutput();
+ runOutput.queryVersionResult = new
+ mojo.interfaceControl2.QueryVersionResult(
+ {'version': interfaceVersion});
+ }
+
+ var runResponseMessageParams = new
+ mojo.interfaceControl2.RunResponseMessageParams();
+ runResponseMessageParams.output = runOutput;
+
+ var messageName = mojo.interfaceControl2.kRunMessageId;
+ var payloadSize =
+ mojo.interfaceControl2.RunResponseMessageParams.encodedSize;
+ var requestID = reader.requestID;
+ var builder = new internal.MessageV1Builder(messageName,
+ payloadSize, internal.kMessageIsResponse, requestID);
+ builder.encodeStruct(mojo.interfaceControl2.RunResponseMessageParams,
+ runResponseMessageParams);
+ responder.accept(builder.finish());
+ return true;
+ }
+
+ function isInterfaceControlMessage(message) {
+ return message.getName() == mojo.interfaceControl2.kRunMessageId ||
+ message.getName() == mojo.interfaceControl2.kRunOrClosePipeMessageId;
+ }
+
+ function ControlMessageHandler(interfaceVersion) {
+ this.interfaceVersion_ = interfaceVersion;
+ }
+
+ ControlMessageHandler.prototype.accept = function(message) {
+ validateControlRequestWithoutResponse(message);
+ return runOrClosePipe(message, this.interfaceVersion_);
+ };
+
+ ControlMessageHandler.prototype.acceptWithResponder = function(message,
+ responder) {
+ validateControlRequestWithResponse(message);
+ return run(message, responder, this.interfaceVersion_);
+ };
+
+ internal.ControlMessageHandler = ControlMessageHandler;
+ internal.isInterfaceControlMessage = isInterfaceControlMessage;
+})();
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+(function() {
+ var internal = mojo.internal;
+
+ function constructRunOrClosePipeMessage(runOrClosePipeInput) {
+ var runOrClosePipeMessageParams = new
+ mojo.interfaceControl2.RunOrClosePipeMessageParams();
+ runOrClosePipeMessageParams.input = runOrClosePipeInput;
+
+ var messageName = mojo.interfaceControl2.kRunOrClosePipeMessageId;
+ var payloadSize =
+ mojo.interfaceControl2.RunOrClosePipeMessageParams.encodedSize;
+ var builder = new internal.MessageV0Builder(messageName, payloadSize);
+ builder.encodeStruct(mojo.interfaceControl2.RunOrClosePipeMessageParams,
+ runOrClosePipeMessageParams);
+ var message = builder.finish();
+ return message;
+ }
+
+ function validateControlResponse(message) {
+ var messageValidator = new internal.Validator(message);
+ var error = messageValidator.validateMessageIsResponse();
+ if (error != internal.validationError.NONE) {
+ throw error;
+ }
+
+ if (message.getName() != mojo.interfaceControl2.kRunMessageId) {
+ throw new Error("Control message name is not kRunMessageId");
+ }
+
+ // Validate payload.
+ error = mojo.interfaceControl2.RunResponseMessageParams.validate(
+ messageValidator, message.getHeaderNumBytes());
+ if (error != internal.validationError.NONE) {
+ throw error;
+ }
+ }
+
+ function acceptRunResponse(message) {
+ validateControlResponse(message);
+
+ var reader = new internal.MessageReader(message);
+ var runResponseMessageParams = reader.decodeStruct(
+ mojo.interfaceControl2.RunResponseMessageParams);
+
+ return Promise.resolve(runResponseMessageParams);
+ }
+
+ /**
+ * Sends the given run message through the receiver.
+ * Accepts the response message from the receiver and decodes the message
+ * struct to RunResponseMessageParams.
+ *
+ * @param {Router} receiver.
+ * @param {RunMessageParams} runMessageParams to be sent via a message.
+ * @return {Promise} that resolves to a RunResponseMessageParams.
+ */
+ function sendRunMessage(receiver, runMessageParams) {
+ var messageName = mojo.interfaceControl2.kRunMessageId;
+ var payloadSize = mojo.interfaceControl2.RunMessageParams.encodedSize;
+ // |requestID| is set to 0, but is later properly set by Router.
+ var builder = new internal.MessageV1Builder(messageName,
+ payloadSize, internal.kMessageExpectsResponse, 0);
+ builder.encodeStruct(mojo.interfaceControl2.RunMessageParams,
+ runMessageParams);
+ var message = builder.finish();
+
+ return receiver.acceptAndExpectResponse(message).then(acceptRunResponse);
+ }
+
+ function ControlMessageProxy(receiver) {
+ this.receiver_ = receiver;
+ }
+
+ ControlMessageProxy.prototype.queryVersion = function() {
+ var runMessageParams = new mojo.interfaceControl2.RunMessageParams();
+ runMessageParams.input = new mojo.interfaceControl2.RunInput();
+ runMessageParams.input.queryVersion =
+ new mojo.interfaceControl2.QueryVersion();
+
+ return sendRunMessage(this.receiver_, runMessageParams).then(function(
+ runResponseMessageParams) {
+ return runResponseMessageParams.output.queryVersionResult.version;
+ });
+ };
+
+ ControlMessageProxy.prototype.requireVersion = function(version) {
+ var runOrClosePipeInput = new mojo.interfaceControl2.RunOrClosePipeInput();
+ runOrClosePipeInput.requireVersion =
+ new mojo.interfaceControl2.RequireVersion({'version': version});
+ var message = constructRunOrClosePipeMessage(runOrClosePipeInput);
+ this.receiver_.accept(message);
+ };
+
+ internal.ControlMessageProxy = ControlMessageProxy;
+})();
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+(function() {
+ var internal = mojo.internal;
+
+ function InterfaceEndpointClient(interfaceEndpointHandle, receiver,
+ interfaceVersion) {
+ this.controller_ = null;
+ this.encounteredError_ = false;
+ this.handle_ = interfaceEndpointHandle;
+ this.incomingReceiver_ = receiver;
+
+ if (interfaceVersion !== undefined) {
+ this.controlMessageHandler_ = new internal.ControlMessageHandler(
+ interfaceVersion);
+ } else {
+ this.controlMessageProxy_ = new internal.ControlMessageProxy(this);
+ }
+
+ this.nextRequestID_ = 0;
+ this.completers_ = new Map();
+ this.payloadValidators_ = [];
+ this.connectionErrorHandler_ = null;
+
+ if (interfaceEndpointHandle.pendingAssociation()) {
+ interfaceEndpointHandle.setAssociationEventHandler(
+ this.onAssociationEvent.bind(this));
+ } else {
+ this.initControllerIfNecessary_();
+ }
+ }
+
+ InterfaceEndpointClient.prototype.initControllerIfNecessary_ = function() {
+ if (this.controller_ || this.handle_.pendingAssociation()) {
+ return;
+ }
+
+ this.controller_ = this.handle_.groupController().attachEndpointClient(
+ this.handle_, this);
+ };
+
+ InterfaceEndpointClient.prototype.onAssociationEvent = function(
+ associationEvent) {
+ if (associationEvent === internal.AssociationEvent.ASSOCIATED) {
+ this.initControllerIfNecessary_();
+ } else if (associationEvent ===
+ internal.AssociationEvent.PEER_CLOSED_BEFORE_ASSOCIATION) {
+ setTimeout(this.notifyError.bind(this, this.handle_.disconnectReason()),
+ 0);
+ }
+ };
+
+ InterfaceEndpointClient.prototype.passHandle = function() {
+ if (!this.handle_.isValid()) {
+ return new internal.InterfaceEndpointHandle();
+ }
+
+ // Used to clear the previously set callback.
+ this.handle_.setAssociationEventHandler(undefined);
+
+ if (this.controller_) {
+ this.controller_ = null;
+ this.handle_.groupController().detachEndpointClient(this.handle_);
+ }
+ var handle = this.handle_;
+ this.handle_ = null;
+ return handle;
+ };
+
+ InterfaceEndpointClient.prototype.close = function(reason) {
+ var handle = this.passHandle();
+ handle.reset(reason);
+ };
+
+ InterfaceEndpointClient.prototype.accept = function(message) {
+ if (message.associatedEndpointHandles.length > 0) {
+ message.serializeAssociatedEndpointHandles(
+ this.handle_.groupController());
+ }
+
+ if (this.encounteredError_) {
+ return false;
+ }
+
+ this.initControllerIfNecessary_();
+ return this.controller_.sendMessage(message);
+ };
+
+ InterfaceEndpointClient.prototype.acceptAndExpectResponse = function(
+ message) {
+ if (message.associatedEndpointHandles.length > 0) {
+ message.serializeAssociatedEndpointHandles(
+ this.handle_.groupController());
+ }
+
+ if (this.encounteredError_) {
+ return Promise.reject();
+ }
+
+ this.initControllerIfNecessary_();
+
+ // Reserve 0 in case we want it to convey special meaning in the future.
+ var requestID = this.nextRequestID_++;
+ if (requestID === 0)
+ requestID = this.nextRequestID_++;
+
+ message.setRequestID(requestID);
+ var result = this.controller_.sendMessage(message);
+ if (!result)
+ return Promise.reject(Error("Connection error"));
+
+ var completer = {};
+ this.completers_.set(requestID, completer);
+ return new Promise(function(resolve, reject) {
+ completer.resolve = resolve;
+ completer.reject = reject;
+ });
+ };
+
+ InterfaceEndpointClient.prototype.setPayloadValidators = function(
+ payloadValidators) {
+ this.payloadValidators_ = payloadValidators;
+ };
+
+ InterfaceEndpointClient.prototype.setIncomingReceiver = function(receiver) {
+ this.incomingReceiver_ = receiver;
+ };
+
+ InterfaceEndpointClient.prototype.setConnectionErrorHandler = function(
+ handler) {
+ this.connectionErrorHandler_ = handler;
+ };
+
+ InterfaceEndpointClient.prototype.handleIncomingMessage = function(message,
+ messageValidator) {
+ var noError = internal.validationError.NONE;
+ var err = noError;
+ for (var i = 0; err === noError && i < this.payloadValidators_.length; ++i)
+ err = this.payloadValidators_[i](messageValidator);
+
+ if (err == noError) {
+ return this.handleValidIncomingMessage_(message);
+ } else {
+ internal.reportValidationError(err);
+ return false;
+ }
+ };
+
+ InterfaceEndpointClient.prototype.handleValidIncomingMessage_ = function(
+ message) {
+ if (internal.isTestingMode()) {
+ return true;
+ }
+
+ if (this.encounteredError_) {
+ return false;
+ }
+
+ var ok = false;
+
+ if (message.expectsResponse()) {
+ if (internal.isInterfaceControlMessage(message) &&
+ this.controlMessageHandler_) {
+ ok = this.controlMessageHandler_.acceptWithResponder(message, this);
+ } else if (this.incomingReceiver_) {
+ ok = this.incomingReceiver_.acceptWithResponder(message, this);
+ }
+ } else if (message.isResponse()) {
+ var reader = new internal.MessageReader(message);
+ var requestID = reader.requestID;
+ var completer = this.completers_.get(requestID);
+ if (completer) {
+ this.completers_.delete(requestID);
+ completer.resolve(message);
+ ok = true;
+ } else {
+ console.log("Unexpected response with request ID: " + requestID);
+ }
+ } else {
+ if (internal.isInterfaceControlMessage(message) &&
+ this.controlMessageHandler_) {
+ ok = this.controlMessageHandler_.accept(message);
+ } else if (this.incomingReceiver_) {
+ ok = this.incomingReceiver_.accept(message);
+ }
+ }
+ return ok;
+ };
+
+ InterfaceEndpointClient.prototype.notifyError = function(reason) {
+ if (this.encounteredError_) {
+ return;
+ }
+ this.encounteredError_ = true;
+
+ this.completers_.forEach(function(value) {
+ value.reject();
+ });
+ this.completers_.clear(); // Drop any responders.
+
+ if (this.connectionErrorHandler_) {
+ this.connectionErrorHandler_(reason);
+ }
+ };
+
+ InterfaceEndpointClient.prototype.queryVersion = function() {
+ return this.controlMessageProxy_.queryVersion();
+ };
+
+ InterfaceEndpointClient.prototype.requireVersion = function(version) {
+ this.controlMessageProxy_.requireVersion(version);
+ };
+
+ InterfaceEndpointClient.prototype.getEncounteredError = function() {
+ return this.encounteredError_;
+ };
+
+ internal.InterfaceEndpointClient = InterfaceEndpointClient;
+})();
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+(function() {
+ var internal = mojo.internal;
+
+ var AssociationEvent = {
+ // The interface has been associated with a message pipe.
+ ASSOCIATED: 'associated',
+ // The peer of this object has been closed before association.
+ PEER_CLOSED_BEFORE_ASSOCIATION: 'peer_closed_before_association'
+ };
+
+ function State(interfaceId, associatedGroupController) {
+ if (interfaceId === undefined) {
+ interfaceId = internal.kInvalidInterfaceId;
+ }
+
+ this.interfaceId = interfaceId;
+ this.associatedGroupController = associatedGroupController;
+ this.pendingAssociation = false;
+ this.disconnectReason = null;
+ this.peerState_ = null;
+ this.associationEventHandler_ = null;
+ }
+
+ State.prototype.initPendingState = function(peer) {
+ this.pendingAssociation = true;
+ this.peerState_ = peer;
+ };
+
+ State.prototype.isValid = function() {
+ return this.pendingAssociation ||
+ internal.isValidInterfaceId(this.interfaceId);
+ };
+
+ State.prototype.close = function(disconnectReason) {
+ var cachedGroupController;
+ var cachedPeerState;
+ var cachedId = internal.kInvalidInterfaceId;
+
+ if (!this.pendingAssociation) {
+ if (internal.isValidInterfaceId(this.interfaceId)) {
+ cachedGroupController = this.associatedGroupController;
+ this.associatedGroupController = null;
+ cachedId = this.interfaceId;
+ this.interfaceId = internal.kInvalidInterfaceId;
+ }
+ } else {
+ this.pendingAssociation = false;
+ cachedPeerState = this.peerState_;
+ this.peerState_ = null;
+ }
+
+ if (cachedGroupController) {
+ cachedGroupController.closeEndpointHandle(cachedId,
+ disconnectReason);
+ } else if (cachedPeerState) {
+ cachedPeerState.onPeerClosedBeforeAssociation(disconnectReason);
+ }
+ };
+
+ State.prototype.runAssociationEventHandler = function(associationEvent) {
+ if (this.associationEventHandler_) {
+ var handler = this.associationEventHandler_;
+ this.associationEventHandler_ = null;
+ handler(associationEvent);
+ }
+ };
+
+ State.prototype.setAssociationEventHandler = function(handler) {
+ if (!this.pendingAssociation &&
+ !internal.isValidInterfaceId(this.interfaceId)) {
+ return;
+ }
+
+ if (!handler) {
+ this.associationEventHandler_ = null;
+ return;
+ }
+
+ this.associationEventHandler_ = handler;
+ if (!this.pendingAssociation) {
+ setTimeout(this.runAssociationEventHandler.bind(this,
+ AssociationEvent.ASSOCIATED), 0);
+ } else if (!this.peerState_) {
+ setTimeout(this.runAssociationEventHandler.bind(this,
+ AssociationEvent.PEER_CLOSED_BEFORE_ASSOCIATION), 0);
+ }
+ };
+
+ State.prototype.notifyAssociation = function(interfaceId,
+ peerGroupController) {
+ var cachedPeerState = this.peerState_;
+ this.peerState_ = null;
+
+ this.pendingAssociation = false;
+
+ if (cachedPeerState) {
+ cachedPeerState.onAssociated(interfaceId, peerGroupController);
+ return true;
+ }
+ return false;
+ };
+
+ State.prototype.onAssociated = function(interfaceId,
+ associatedGroupController) {
+ if (!this.pendingAssociation) {
+ return;
+ }
+
+ this.pendingAssociation = false;
+ this.peerState_ = null;
+ this.interfaceId = interfaceId;
+ this.associatedGroupController = associatedGroupController;
+ this.runAssociationEventHandler(AssociationEvent.ASSOCIATED);
+ };
+
+ State.prototype.onPeerClosedBeforeAssociation = function(disconnectReason) {
+ if (!this.pendingAssociation) {
+ return;
+ }
+
+ this.peerState_ = null;
+ this.disconnectReason = disconnectReason;
+
+ this.runAssociationEventHandler(
+ AssociationEvent.PEER_CLOSED_BEFORE_ASSOCIATION);
+ };
+
+ function createPairPendingAssociation() {
+ var handle0 = new InterfaceEndpointHandle();
+ var handle1 = new InterfaceEndpointHandle();
+ handle0.state_.initPendingState(handle1.state_);
+ handle1.state_.initPendingState(handle0.state_);
+ return {handle0: handle0, handle1: handle1};
+ }
+
+ function InterfaceEndpointHandle(interfaceId, associatedGroupController) {
+ this.state_ = new State(interfaceId, associatedGroupController);
+ }
+
+ InterfaceEndpointHandle.prototype.isValid = function() {
+ return this.state_.isValid();
+ };
+
+ InterfaceEndpointHandle.prototype.pendingAssociation = function() {
+ return this.state_.pendingAssociation;
+ };
+
+ InterfaceEndpointHandle.prototype.id = function() {
+ return this.state_.interfaceId;
+ };
+
+ InterfaceEndpointHandle.prototype.groupController = function() {
+ return this.state_.associatedGroupController;
+ };
+
+ InterfaceEndpointHandle.prototype.disconnectReason = function() {
+ return this.state_.disconnectReason;
+ };
+
+ InterfaceEndpointHandle.prototype.setAssociationEventHandler = function(
+ handler) {
+ this.state_.setAssociationEventHandler(handler);
+ };
+
+ InterfaceEndpointHandle.prototype.notifyAssociation = function(interfaceId,
+ peerGroupController) {
+ return this.state_.notifyAssociation(interfaceId, peerGroupController);
+ };
+
+ InterfaceEndpointHandle.prototype.reset = function(reason) {
+ this.state_.close(reason);
+ this.state_ = new State();
+ };
+
+ internal.AssociationEvent = AssociationEvent;
+ internal.InterfaceEndpointHandle = InterfaceEndpointHandle;
+ internal.createPairPendingAssociation = createPairPendingAssociation;
+})();
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+(function() {
+ var internal = mojo.internal;
+
+ function validateControlRequestWithoutResponse(message) {
+ var messageValidator = new internal.Validator(message);
+ var error = messageValidator.validateMessageIsRequestWithoutResponse();
+ if (error != internal.validationError.NONE) {
+ throw error;
+ }
+
+ if (message.getName() != mojo.pipeControl2.kRunOrClosePipeMessageId) {
+ throw new Error("Control message name is not kRunOrClosePipeMessageId");
+ }
+
+ // Validate payload.
+ error = mojo.pipeControl2.RunOrClosePipeMessageParams.validate(
+ messageValidator, message.getHeaderNumBytes());
+ if (error != internal.validationError.NONE) {
+ throw error;
+ }
+ }
+
+ function runOrClosePipe(message, delegate) {
+ var reader = new internal.MessageReader(message);
+ var runOrClosePipeMessageParams = reader.decodeStruct(
+ mojo.pipeControl2.RunOrClosePipeMessageParams);
+ var event = runOrClosePipeMessageParams.input
+ .peerAssociatedEndpointClosedEvent;
+ return delegate.onPeerAssociatedEndpointClosed(event.id,
+ event.disconnectReason);
+ }
+
+ function isPipeControlMessage(message) {
+ return !internal.isValidInterfaceId(message.getInterfaceId());
+ }
+
+ function PipeControlMessageHandler(delegate) {
+ this.delegate_ = delegate;
+ }
+
+ PipeControlMessageHandler.prototype.accept = function(message) {
+ validateControlRequestWithoutResponse(message);
+ return runOrClosePipe(message, this.delegate_);
+ };
+
+ internal.PipeControlMessageHandler = PipeControlMessageHandler;
+ internal.isPipeControlMessage = isPipeControlMessage;
+})();
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+(function() {
+ var internal = mojo.internal;
+
+ function constructRunOrClosePipeMessage(runOrClosePipeInput) {
+ var runOrClosePipeMessageParams = new
+ mojo.pipeControl2.RunOrClosePipeMessageParams();
+ runOrClosePipeMessageParams.input = runOrClosePipeInput;
+
+ var messageName = mojo.pipeControl2.kRunOrClosePipeMessageId;
+ var payloadSize =
+ mojo.pipeControl2.RunOrClosePipeMessageParams.encodedSize;
+
+ var builder = new internal.MessageV0Builder(messageName, payloadSize);
+ builder.encodeStruct(mojo.pipeControl2.RunOrClosePipeMessageParams,
+ runOrClosePipeMessageParams);
+ var message = builder.finish();
+ message.setInterfaceId(internal.kInvalidInterfaceId);
+ return message;
+ }
+
+ function PipeControlMessageProxy(receiver) {
+ this.receiver_ = receiver;
+ }
+
+ PipeControlMessageProxy.prototype.notifyPeerEndpointClosed = function(
+ interfaceId, reason) {
+ var message = this.constructPeerEndpointClosedMessage(interfaceId, reason);
+ this.receiver_.accept(message);
+ };
+
+ PipeControlMessageProxy.prototype.constructPeerEndpointClosedMessage =
+ function(interfaceId, reason) {
+ var event = new mojo.pipeControl2.PeerAssociatedEndpointClosedEvent();
+ event.id = interfaceId;
+ if (reason) {
+ event.disconnectReason = new mojo.pipeControl2.DisconnectReason({
+ customReason: reason.customReason,
+ description: reason.description});
+ }
+ var runOrClosePipeInput = new mojo.pipeControl2.RunOrClosePipeInput();
+ runOrClosePipeInput.peerAssociatedEndpointClosedEvent = event;
+ return constructRunOrClosePipeMessage(runOrClosePipeInput);
+ };
+
+ internal.PipeControlMessageProxy = PipeControlMessageProxy;
+})();
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+(function() {
+ var internal = mojo.internal;
+
+ /**
+ * The state of |endpoint|. If both the endpoint and its peer have been
+ * closed, removes it from |endpoints_|.
+ * @enum {string}
+ */
+ var EndpointStateUpdateType = {
+ ENDPOINT_CLOSED: 'endpoint_closed',
+ PEER_ENDPOINT_CLOSED: 'peer_endpoint_closed'
+ };
+
+ function check(condition, output) {
+ if (!condition) {
+ // testharness.js does not rethrow errors so the error stack needs to be
+ // included as a string in the error we throw for debugging layout tests.
+ throw new Error((new Error()).stack);
+ }
+ }
+
+ function InterfaceEndpoint(router, interfaceId) {
+ this.router_ = router;
+ this.id = interfaceId;
+ this.closed = false;
+ this.peerClosed = false;
+ this.handleCreated = false;
+ this.disconnectReason = null;
+ this.client = null;
+ }
+
+ InterfaceEndpoint.prototype.sendMessage = function(message) {
+ message.setInterfaceId(this.id);
+ return this.router_.connector_.accept(message);
+ };
+
+ function Router(handle, setInterfaceIdNamespaceBit) {
+ if (!(handle instanceof MojoHandle)) {
+ throw new Error("Router constructor: Not a handle");
+ }
+ if (setInterfaceIdNamespaceBit === undefined) {
+ setInterfaceIdNamespaceBit = false;
+ }
+
+ this.connector_ = new internal.Connector(handle);
+
+ this.connector_.setIncomingReceiver({
+ accept: this.accept.bind(this),
+ });
+ this.connector_.setErrorHandler({
+ onError: this.onPipeConnectionError.bind(this),
+ });
+
+ this.setInterfaceIdNamespaceBit_ = setInterfaceIdNamespaceBit;
+ // |cachedMessageData| caches infomation about a message, so it can be
+ // processed later if a client is not yet attached to the target endpoint.
+ this.cachedMessageData = null;
+ this.controlMessageHandler_ = new internal.PipeControlMessageHandler(this);
+ this.controlMessageProxy_ =
+ new internal.PipeControlMessageProxy(this.connector_);
+ this.nextInterfaceIdValue_ = 1;
+ this.encounteredError_ = false;
+ this.endpoints_ = new Map();
+ }
+
+ Router.prototype.associateInterface = function(handleToSend) {
+ if (!handleToSend.pendingAssociation()) {
+ return internal.kInvalidInterfaceId;
+ }
+
+ var id = 0;
+ do {
+ if (this.nextInterfaceIdValue_ >= internal.kInterfaceIdNamespaceMask) {
+ this.nextInterfaceIdValue_ = 1;
+ }
+ id = this.nextInterfaceIdValue_++;
+ if (this.setInterfaceIdNamespaceBit_) {
+ id += internal.kInterfaceIdNamespaceMask;
+ }
+ } while (this.endpoints_.has(id));
+
+ var endpoint = new InterfaceEndpoint(this, id);
+ this.endpoints_.set(id, endpoint);
+ if (this.encounteredError_) {
+ this.updateEndpointStateMayRemove(endpoint,
+ EndpointStateUpdateType.PEER_ENDPOINT_CLOSED);
+ }
+ endpoint.handleCreated = true;
+
+ if (!handleToSend.notifyAssociation(id, this)) {
+ // The peer handle of |handleToSend|, which is supposed to join this
+ // associated group, has been closed.
+ this.updateEndpointStateMayRemove(endpoint,
+ EndpointStateUpdateType.ENDPOINT_CLOSED);
+
+ pipeControlMessageproxy.notifyPeerEndpointClosed(id,
+ handleToSend.disconnectReason());
+ }
+
+ return id;
+ };
+
+ Router.prototype.attachEndpointClient = function(
+ interfaceEndpointHandle, interfaceEndpointClient) {
+ check(internal.isValidInterfaceId(interfaceEndpointHandle.id()));
+ check(interfaceEndpointClient);
+
+ var endpoint = this.endpoints_.get(interfaceEndpointHandle.id());
+ check(endpoint);
+ check(!endpoint.client);
+ check(!endpoint.closed);
+ endpoint.client = interfaceEndpointClient;
+
+ if (endpoint.peerClosed) {
+ setTimeout(endpoint.client.notifyError.bind(endpoint.client), 0);
+ }
+
+ if (this.cachedMessageData && interfaceEndpointHandle.id() ===
+ this.cachedMessageData.message.getInterfaceId()) {
+ setTimeout((function() {
+ if (!this.cachedMessageData) {
+ return;
+ }
+
+ var targetEndpoint = this.endpoints_.get(
+ this.cachedMessageData.message.getInterfaceId());
+ // Check that the target endpoint's client still exists.
+ if (targetEndpoint && targetEndpoint.client) {
+ var message = this.cachedMessageData.message;
+ var messageValidator = this.cachedMessageData.messageValidator;
+ this.cachedMessageData = null;
+ this.connector_.resumeIncomingMethodCallProcessing();
+ var ok = endpoint.client.handleIncomingMessage(message,
+ messageValidator);
+
+ // Handle invalid cached incoming message.
+ if (!internal.isTestingMode() && !ok) {
+ this.connector_.handleError(true, true);
+ }
+ }
+ }).bind(this), 0);
+ }
+
+ return endpoint;
+ };
+
+ Router.prototype.detachEndpointClient = function(
+ interfaceEndpointHandle) {
+ check(internal.isValidInterfaceId(interfaceEndpointHandle.id()));
+ var endpoint = this.endpoints_.get(interfaceEndpointHandle.id());
+ check(endpoint);
+ check(endpoint.client);
+ check(!endpoint.closed);
+
+ endpoint.client = null;
+ };
+
+ Router.prototype.createLocalEndpointHandle = function(
+ interfaceId) {
+ if (!internal.isValidInterfaceId(interfaceId)) {
+ return new internal.InterfaceEndpointHandle();
+ }
+
+ var endpoint = this.endpoints_.get(interfaceId);
+
+ if (!endpoint) {
+ endpoint = new InterfaceEndpoint(this, interfaceId);
+ this.endpoints_.set(interfaceId, endpoint);
+
+ check(!endpoint.handleCreated);
+
+ if (this.encounteredError_) {
+ this.updateEndpointStateMayRemove(endpoint,
+ EndpointStateUpdateType.PEER_ENDPOINT_CLOSED);
+ }
+ } else {
+ // If the endpoint already exist, it is because we have received a
+ // notification that the peer endpoint has closed.
+ check(!endpoint.closed);
+ check(endpoint.peerClosed);
+
+ if (endpoint.handleCreated) {
+ return new internal.InterfaceEndpointHandle();
+ }
+ }
+
+ endpoint.handleCreated = true;
+ return new internal.InterfaceEndpointHandle(interfaceId, this);
+ };
+
+ Router.prototype.accept = function(message) {
+ var messageValidator = new internal.Validator(message);
+ var err = messageValidator.validateMessageHeader();
+
+ var ok = false;
+ if (err !== internal.validationError.NONE) {
+ internal.reportValidationError(err);
+ } else if (message.deserializeAssociatedEndpointHandles(this)) {
+ if (internal.isPipeControlMessage(message)) {
+ ok = this.controlMessageHandler_.accept(message);
+ } else {
+ var interfaceId = message.getInterfaceId();
+ var endpoint = this.endpoints_.get(interfaceId);
+ if (!endpoint || endpoint.closed) {
+ return true;
+ }
+
+ if (!endpoint.client) {
+ // We need to wait until a client is attached in order to dispatch
+ // further messages.
+ this.cachedMessageData = {message: message,
+ messageValidator: messageValidator};
+ this.connector_.pauseIncomingMethodCallProcessing();
+ return true;
+ }
+ ok = endpoint.client.handleIncomingMessage(message, messageValidator);
+ }
+ }
+ return ok;
+ };
+
+ Router.prototype.close = function() {
+ this.connector_.close();
+ // Closing the message pipe won't trigger connection error handler.
+ // Explicitly call onPipeConnectionError() so that associated endpoints
+ // will get notified.
+ this.onPipeConnectionError();
+ };
+
+ Router.prototype.onPeerAssociatedEndpointClosed = function(interfaceId,
+ reason) {
+ check(!internal.isMasterInterfaceId(interfaceId) || reason);
+
+ var endpoint = this.endpoints_.get(interfaceId);
+ if (!endpoint) {
+ endpoint = new InterfaceEndpoint(this, interfaceId);
+ this.endpoints_.set(interfaceId, endpoint);
+ }
+
+ if (reason) {
+ endpoint.disconnectReason = reason;
+ }
+
+ if (!endpoint.peerClosed) {
+ if (endpoint.client) {
+ setTimeout(endpoint.client.notifyError.bind(endpoint.client, reason),
+ 0);
+ }
+ this.updateEndpointStateMayRemove(endpoint,
+ EndpointStateUpdateType.PEER_ENDPOINT_CLOSED);
+ }
+ return true;
+ };
+
+ Router.prototype.onPipeConnectionError = function() {
+ this.encounteredError_ = true;
+
+ for (var endpoint of this.endpoints_.values()) {
+ if (endpoint.client) {
+ setTimeout(
+ endpoint.client.notifyError.bind(
+ endpoint.client, endpoint.disconnectReason),
+ 0);
+ }
+ this.updateEndpointStateMayRemove(endpoint,
+ EndpointStateUpdateType.PEER_ENDPOINT_CLOSED);
+ }
+ };
+
+ Router.prototype.closeEndpointHandle = function(interfaceId, reason) {
+ if (!internal.isValidInterfaceId(interfaceId)) {
+ return;
+ }
+ var endpoint = this.endpoints_.get(interfaceId);
+ check(endpoint);
+ check(!endpoint.client);
+ check(!endpoint.closed);
+
+ this.updateEndpointStateMayRemove(endpoint,
+ EndpointStateUpdateType.ENDPOINT_CLOSED);
+
+ if (!internal.isMasterInterfaceId(interfaceId) || reason) {
+ this.controlMessageProxy_.notifyPeerEndpointClosed(interfaceId, reason);
+ }
+
+ if (this.cachedMessageData && interfaceId ===
+ this.cachedMessageData.message.getInterfaceId()) {
+ this.cachedMessageData = null;
+ this.connector_.resumeIncomingMethodCallProcessing();
+ }
+ };
+
+ Router.prototype.updateEndpointStateMayRemove = function(endpoint,
+ endpointStateUpdateType) {
+ if (endpointStateUpdateType === EndpointStateUpdateType.ENDPOINT_CLOSED) {
+ endpoint.closed = true;
+ } else {
+ endpoint.peerClosed = true;
+ }
+ if (endpoint.closed && endpoint.peerClosed) {
+ this.endpoints_.delete(endpoint.id);
+ }
+ };
+
+ internal.Router = Router;
+})();
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * Defines functions for translating between JavaScript strings and UTF8 strings
+ * stored in ArrayBuffers. There is much room for optimization in this code if
+ * it proves necessary.
+ */
+(function() {
+ var internal = mojo.internal;
+
+ /**
+ * Decodes the UTF8 string from the given buffer.
+ * @param {ArrayBufferView} buffer The buffer containing UTF8 string data.
+ * @return {string} The corresponding JavaScript string.
+ */
+ function decodeUtf8String(buffer) {
+ return decodeURIComponent(escape(String.fromCharCode.apply(null, buffer)));
+ }
+
+ /**
+ * Encodes the given JavaScript string into UTF8.
+ * @param {string} str The string to encode.
+ * @param {ArrayBufferView} outputBuffer The buffer to contain the result.
+ * Should be pre-allocated to hold enough space. Use |utf8Length| to determine
+ * how much space is required.
+ * @return {number} The number of bytes written to |outputBuffer|.
+ */
+ function encodeUtf8String(str, outputBuffer) {
+ var utf8String = unescape(encodeURIComponent(str));
+ if (outputBuffer.length < utf8String.length)
+ throw new Error("Buffer too small for encodeUtf8String");
+ for (var i = 0; i < outputBuffer.length && i < utf8String.length; i++)
+ outputBuffer[i] = utf8String.charCodeAt(i);
+ return i;
+ }
+
+ /**
+ * Returns the number of bytes that a UTF8 encoding of the JavaScript string
+ * |str| would occupy.
+ */
+ function utf8Length(str) {
+ var utf8String = unescape(encodeURIComponent(str));
+ return utf8String.length;
+ }
+
+ internal.decodeUtf8String = decodeUtf8String;
+ internal.encodeUtf8String = encodeUtf8String;
+ internal.utf8Length = utf8Length;
+})();
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+(function() {
+ var internal = mojo.internal;
+
+ var validationError = {
+ NONE: 'VALIDATION_ERROR_NONE',
+ MISALIGNED_OBJECT: 'VALIDATION_ERROR_MISALIGNED_OBJECT',
+ ILLEGAL_MEMORY_RANGE: 'VALIDATION_ERROR_ILLEGAL_MEMORY_RANGE',
+ UNEXPECTED_STRUCT_HEADER: 'VALIDATION_ERROR_UNEXPECTED_STRUCT_HEADER',
+ UNEXPECTED_ARRAY_HEADER: 'VALIDATION_ERROR_UNEXPECTED_ARRAY_HEADER',
+ ILLEGAL_HANDLE: 'VALIDATION_ERROR_ILLEGAL_HANDLE',
+ UNEXPECTED_INVALID_HANDLE: 'VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE',
+ ILLEGAL_POINTER: 'VALIDATION_ERROR_ILLEGAL_POINTER',
+ UNEXPECTED_NULL_POINTER: 'VALIDATION_ERROR_UNEXPECTED_NULL_POINTER',
+ ILLEGAL_INTERFACE_ID: 'VALIDATION_ERROR_ILLEGAL_INTERFACE_ID',
+ UNEXPECTED_INVALID_INTERFACE_ID:
+ 'VALIDATION_ERROR_UNEXPECTED_INVALID_INTERFACE_ID',
+ MESSAGE_HEADER_INVALID_FLAGS:
+ 'VALIDATION_ERROR_MESSAGE_HEADER_INVALID_FLAGS',
+ MESSAGE_HEADER_MISSING_REQUEST_ID:
+ 'VALIDATION_ERROR_MESSAGE_HEADER_MISSING_REQUEST_ID',
+ DIFFERENT_SIZED_ARRAYS_IN_MAP:
+ 'VALIDATION_ERROR_DIFFERENT_SIZED_ARRAYS_IN_MAP',
+ INVALID_UNION_SIZE: 'VALIDATION_ERROR_INVALID_UNION_SIZE',
+ UNEXPECTED_NULL_UNION: 'VALIDATION_ERROR_UNEXPECTED_NULL_UNION',
+ UNKNOWN_ENUM_VALUE: 'VALIDATION_ERROR_UNKNOWN_ENUM_VALUE',
+ };
+
+ var NULL_MOJO_POINTER = "NULL_MOJO_POINTER";
+ var gValidationErrorObserver = null;
+
+ function reportValidationError(error) {
+ if (gValidationErrorObserver) {
+ gValidationErrorObserver.lastError = error;
+ } else {
+ console.warn('Invalid message: ' + error);
+ }
+ }
+
+ var ValidationErrorObserverForTesting = (function() {
+ function Observer() {
+ this.lastError = validationError.NONE;
+ }
+
+ Observer.prototype.reset = function() {
+ this.lastError = validationError.NONE;
+ };
+
+ return {
+ getInstance: function() {
+ if (!gValidationErrorObserver) {
+ gValidationErrorObserver = new Observer();
+ }
+ return gValidationErrorObserver;
+ }
+ };
+ })();
+
+ function isTestingMode() {
+ return Boolean(gValidationErrorObserver);
+ }
+
+ function clearTestingMode() {
+ gValidationErrorObserver = null;
+ }
+
+ function isEnumClass(cls) {
+ return cls instanceof internal.Enum;
+ }
+
+ function isStringClass(cls) {
+ return cls === internal.String || cls === internal.NullableString;
+ }
+
+ function isHandleClass(cls) {
+ return cls === internal.Handle || cls === internal.NullableHandle;
+ }
+
+ function isInterfaceClass(cls) {
+ return cls instanceof internal.Interface;
+ }
+
+ function isInterfaceRequestClass(cls) {
+ return cls === internal.InterfaceRequest ||
+ cls === internal.NullableInterfaceRequest;
+ }
+
+ function isAssociatedInterfaceClass(cls) {
+ return cls === internal.AssociatedInterfacePtrInfo ||
+ cls === internal.NullableAssociatedInterfacePtrInfo;
+ }
+
+ function isAssociatedInterfaceRequestClass(cls) {
+ return cls === internal.AssociatedInterfaceRequest ||
+ cls === internal.NullableAssociatedInterfaceRequest;
+ }
+
+ function isNullable(type) {
+ return type === internal.NullableString ||
+ type === internal.NullableHandle ||
+ type === internal.NullableAssociatedInterfacePtrInfo ||
+ type === internal.NullableAssociatedInterfaceRequest ||
+ type === internal.NullableInterface ||
+ type === internal.NullableInterfaceRequest ||
+ type instanceof internal.NullableArrayOf ||
+ type instanceof internal.NullablePointerTo;
+ }
+
+ function Validator(message) {
+ this.message = message;
+ this.offset = 0;
+ this.handleIndex = 0;
+ this.associatedEndpointHandleIndex = 0;
+ this.payloadInterfaceIds = null;
+ this.offsetLimit = this.message.buffer.byteLength;
+ }
+
+ Object.defineProperty(Validator.prototype, "handleIndexLimit", {
+ get: function() { return this.message.handles.length; }
+ });
+
+ Object.defineProperty(Validator.prototype, "associatedHandleIndexLimit", {
+ get: function() {
+ return this.payloadInterfaceIds ? this.payloadInterfaceIds.length : 0;
+ }
+ });
+
+ // True if we can safely allocate a block of bytes from start to
+ // to start + numBytes.
+ Validator.prototype.isValidRange = function(start, numBytes) {
+ // Only positive JavaScript integers that are less than 2^53
+ // (Number.MAX_SAFE_INTEGER) can be represented exactly.
+ if (start < this.offset || numBytes <= 0 ||
+ !Number.isSafeInteger(start) ||
+ !Number.isSafeInteger(numBytes))
+ return false;
+
+ var newOffset = start + numBytes;
+ if (!Number.isSafeInteger(newOffset) || newOffset > this.offsetLimit)
+ return false;
+
+ return true;
+ };
+
+ Validator.prototype.claimRange = function(start, numBytes) {
+ if (this.isValidRange(start, numBytes)) {
+ this.offset = start + numBytes;
+ return true;
+ }
+ return false;
+ };
+
+ Validator.prototype.claimHandle = function(index) {
+ if (index === internal.kEncodedInvalidHandleValue)
+ return true;
+
+ if (index < this.handleIndex || index >= this.handleIndexLimit)
+ return false;
+
+ // This is safe because handle indices are uint32.
+ this.handleIndex = index + 1;
+ return true;
+ };
+
+ Validator.prototype.claimAssociatedEndpointHandle = function(index) {
+ if (index === internal.kEncodedInvalidHandleValue) {
+ return true;
+ }
+
+ if (index < this.associatedEndpointHandleIndex ||
+ index >= this.associatedHandleIndexLimit) {
+ return false;
+ }
+
+ // This is safe because handle indices are uint32.
+ this.associatedEndpointHandleIndex = index + 1;
+ return true;
+ };
+
+ Validator.prototype.validateEnum = function(offset, enumClass) {
+ // Note: Assumes that enums are always 32 bits! But this matches
+ // mojom::generate::pack::PackedField::GetSizeForKind, so it should be okay.
+ var value = this.message.buffer.getInt32(offset);
+ return enumClass.validate(value);
+ }
+
+ Validator.prototype.validateHandle = function(offset, nullable) {
+ var index = this.message.buffer.getUint32(offset);
+
+ if (index === internal.kEncodedInvalidHandleValue)
+ return nullable ?
+ validationError.NONE : validationError.UNEXPECTED_INVALID_HANDLE;
+
+ if (!this.claimHandle(index))
+ return validationError.ILLEGAL_HANDLE;
+
+ return validationError.NONE;
+ };
+
+ Validator.prototype.validateAssociatedEndpointHandle = function(offset,
+ nullable) {
+ var index = this.message.buffer.getUint32(offset);
+
+ if (index === internal.kEncodedInvalidHandleValue) {
+ return nullable ? validationError.NONE :
+ validationError.UNEXPECTED_INVALID_INTERFACE_ID;
+ }
+
+ if (!this.claimAssociatedEndpointHandle(index)) {
+ return validationError.ILLEGAL_INTERFACE_ID;
+ }
+
+ return validationError.NONE;
+ };
+
+ Validator.prototype.validateInterface = function(offset, nullable) {
+ return this.validateHandle(offset, nullable);
+ };
+
+ Validator.prototype.validateInterfaceRequest = function(offset, nullable) {
+ return this.validateHandle(offset, nullable);
+ };
+
+ Validator.prototype.validateAssociatedInterface = function(offset,
+ nullable) {
+ return this.validateAssociatedEndpointHandle(offset, nullable);
+ };
+
+ Validator.prototype.validateAssociatedInterfaceRequest = function(
+ offset, nullable) {
+ return this.validateAssociatedEndpointHandle(offset, nullable);
+ };
+
+ Validator.prototype.validateStructHeader = function(offset, minNumBytes) {
+ if (!internal.isAligned(offset))
+ return validationError.MISALIGNED_OBJECT;
+
+ if (!this.isValidRange(offset, internal.kStructHeaderSize))
+ return validationError.ILLEGAL_MEMORY_RANGE;
+
+ var numBytes = this.message.buffer.getUint32(offset);
+
+ if (numBytes < minNumBytes)
+ return validationError.UNEXPECTED_STRUCT_HEADER;
+
+ if (!this.claimRange(offset, numBytes))
+ return validationError.ILLEGAL_MEMORY_RANGE;
+
+ return validationError.NONE;
+ };
+
+ Validator.prototype.validateStructVersion = function(offset, versionSizes) {
+ var numBytes = this.message.buffer.getUint32(offset);
+ var version = this.message.buffer.getUint32(offset + 4);
+
+ if (version <= versionSizes[versionSizes.length - 1].version) {
+ // Scan in reverse order to optimize for more recent versionSizes.
+ for (var i = versionSizes.length - 1; i >= 0; --i) {
+ if (version >= versionSizes[i].version) {
+ if (numBytes == versionSizes[i].numBytes)
+ break;
+ return validationError.UNEXPECTED_STRUCT_HEADER;
+ }
+ }
+ } else if (numBytes < versionSizes[versionSizes.length-1].numBytes) {
+ return validationError.UNEXPECTED_STRUCT_HEADER;
+ }
+
+ return validationError.NONE;
+ };
+
+ Validator.prototype.isFieldInStructVersion = function(offset, fieldVersion) {
+ var structVersion = this.message.buffer.getUint32(offset + 4);
+ return fieldVersion <= structVersion;
+ };
+
+ Validator.prototype.validateMessageHeader = function() {
+ var err = this.validateStructHeader(0, internal.kMessageV0HeaderSize);
+ if (err != validationError.NONE) {
+ return err;
+ }
+
+ var numBytes = this.message.getHeaderNumBytes();
+ var version = this.message.getHeaderVersion();
+
+ var validVersionAndNumBytes =
+ (version == 0 && numBytes == internal.kMessageV0HeaderSize) ||
+ (version == 1 && numBytes == internal.kMessageV1HeaderSize) ||
+ (version == 2 && numBytes == internal.kMessageV2HeaderSize) ||
+ (version > 2 && numBytes >= internal.kMessageV2HeaderSize);
+
+ if (!validVersionAndNumBytes) {
+ return validationError.UNEXPECTED_STRUCT_HEADER;
+ }
+
+ var expectsResponse = this.message.expectsResponse();
+ var isResponse = this.message.isResponse();
+
+ if (version == 0 && (expectsResponse || isResponse)) {
+ return validationError.MESSAGE_HEADER_MISSING_REQUEST_ID;
+ }
+
+ if (isResponse && expectsResponse) {
+ return validationError.MESSAGE_HEADER_INVALID_FLAGS;
+ }
+
+ if (version < 2) {
+ return validationError.NONE;
+ }
+
+ var err = this.validateArrayPointer(
+ internal.kMessagePayloadInterfaceIdsPointerOffset,
+ internal.Uint32.encodedSize, internal.Uint32, true, [0], 0);
+
+ if (err != validationError.NONE) {
+ return err;
+ }
+
+ this.payloadInterfaceIds = this.message.getPayloadInterfaceIds();
+ if (this.payloadInterfaceIds) {
+ for (var interfaceId of this.payloadInterfaceIds) {
+ if (!internal.isValidInterfaceId(interfaceId) ||
+ internal.isMasterInterfaceId(interfaceId)) {
+ return validationError.ILLEGAL_INTERFACE_ID;
+ }
+ }
+ }
+
+ // Set offset to the start of the payload and offsetLimit to the start of
+ // the payload interface Ids so that payload can be validated using the
+ // same messageValidator.
+ this.offset = this.message.getHeaderNumBytes();
+ this.offsetLimit = this.decodePointer(
+ internal.kMessagePayloadInterfaceIdsPointerOffset);
+
+ return validationError.NONE;
+ };
+
+ Validator.prototype.validateMessageIsRequestWithoutResponse = function() {
+ if (this.message.isResponse() || this.message.expectsResponse()) {
+ return validationError.MESSAGE_HEADER_INVALID_FLAGS;
+ }
+ return validationError.NONE;
+ };
+
+ Validator.prototype.validateMessageIsRequestExpectingResponse = function() {
+ if (this.message.isResponse() || !this.message.expectsResponse()) {
+ return validationError.MESSAGE_HEADER_INVALID_FLAGS;
+ }
+ return validationError.NONE;
+ };
+
+ Validator.prototype.validateMessageIsResponse = function() {
+ if (this.message.expectsResponse() || !this.message.isResponse()) {
+ return validationError.MESSAGE_HEADER_INVALID_FLAGS;
+ }
+ return validationError.NONE;
+ };
+
+ // Returns the message.buffer relative offset this pointer "points to",
+ // NULL_MOJO_POINTER if the pointer represents a null, or JS null if the
+ // pointer's value is not valid.
+ Validator.prototype.decodePointer = function(offset) {
+ var pointerValue = this.message.buffer.getUint64(offset);
+ if (pointerValue === 0)
+ return NULL_MOJO_POINTER;
+ var bufferOffset = offset + pointerValue;
+ return Number.isSafeInteger(bufferOffset) ? bufferOffset : null;
+ };
+
+ Validator.prototype.decodeUnionSize = function(offset) {
+ return this.message.buffer.getUint32(offset);
+ };
+
+ Validator.prototype.decodeUnionTag = function(offset) {
+ return this.message.buffer.getUint32(offset + 4);
+ };
+
+ Validator.prototype.validateArrayPointer = function(
+ offset, elementSize, elementType, nullable, expectedDimensionSizes,
+ currentDimension) {
+ var arrayOffset = this.decodePointer(offset);
+ if (arrayOffset === null)
+ return validationError.ILLEGAL_POINTER;
+
+ if (arrayOffset === NULL_MOJO_POINTER)
+ return nullable ?
+ validationError.NONE : validationError.UNEXPECTED_NULL_POINTER;
+
+ return this.validateArray(arrayOffset, elementSize, elementType,
+ expectedDimensionSizes, currentDimension);
+ };
+
+ Validator.prototype.validateStructPointer = function(
+ offset, structClass, nullable) {
+ var structOffset = this.decodePointer(offset);
+ if (structOffset === null)
+ return validationError.ILLEGAL_POINTER;
+
+ if (structOffset === NULL_MOJO_POINTER)
+ return nullable ?
+ validationError.NONE : validationError.UNEXPECTED_NULL_POINTER;
+
+ return structClass.validate(this, structOffset);
+ };
+
+ Validator.prototype.validateUnion = function(
+ offset, unionClass, nullable) {
+ var size = this.message.buffer.getUint32(offset);
+ if (size == 0) {
+ return nullable ?
+ validationError.NONE : validationError.UNEXPECTED_NULL_UNION;
+ }
+
+ return unionClass.validate(this, offset);
+ };
+
+ Validator.prototype.validateNestedUnion = function(
+ offset, unionClass, nullable) {
+ var unionOffset = this.decodePointer(offset);
+ if (unionOffset === null)
+ return validationError.ILLEGAL_POINTER;
+
+ if (unionOffset === NULL_MOJO_POINTER)
+ return nullable ?
+ validationError.NONE : validationError.UNEXPECTED_NULL_UNION;
+
+ return this.validateUnion(unionOffset, unionClass, nullable);
+ };
+
+ // This method assumes that the array at arrayPointerOffset has
+ // been validated.
+
+ Validator.prototype.arrayLength = function(arrayPointerOffset) {
+ var arrayOffset = this.decodePointer(arrayPointerOffset);
+ return this.message.buffer.getUint32(arrayOffset + 4);
+ };
+
+ Validator.prototype.validateMapPointer = function(
+ offset, mapIsNullable, keyClass, valueClass, valueIsNullable) {
+ // Validate the implicit map struct:
+ // struct {array<keyClass> keys; array<valueClass> values};
+ var structOffset = this.decodePointer(offset);
+ if (structOffset === null)
+ return validationError.ILLEGAL_POINTER;
+
+ if (structOffset === NULL_MOJO_POINTER)
+ return mapIsNullable ?
+ validationError.NONE : validationError.UNEXPECTED_NULL_POINTER;
+
+ var mapEncodedSize = internal.kStructHeaderSize +
+ internal.kMapStructPayloadSize;
+ var err = this.validateStructHeader(structOffset, mapEncodedSize);
+ if (err !== validationError.NONE)
+ return err;
+
+ // Validate the keys array.
+ var keysArrayPointerOffset = structOffset + internal.kStructHeaderSize;
+ err = this.validateArrayPointer(
+ keysArrayPointerOffset, keyClass.encodedSize, keyClass, false, [0], 0);
+ if (err !== validationError.NONE)
+ return err;
+
+ // Validate the values array.
+ var valuesArrayPointerOffset = keysArrayPointerOffset + 8;
+ var valuesArrayDimensions = [0]; // Validate the actual length below.
+ if (valueClass instanceof internal.ArrayOf)
+ valuesArrayDimensions =
+ valuesArrayDimensions.concat(valueClass.dimensions());
+ var err = this.validateArrayPointer(valuesArrayPointerOffset,
+ valueClass.encodedSize,
+ valueClass,
+ valueIsNullable,
+ valuesArrayDimensions,
+ 0);
+ if (err !== validationError.NONE)
+ return err;
+
+ // Validate the lengths of the keys and values arrays.
+ var keysArrayLength = this.arrayLength(keysArrayPointerOffset);
+ var valuesArrayLength = this.arrayLength(valuesArrayPointerOffset);
+ if (keysArrayLength != valuesArrayLength)
+ return validationError.DIFFERENT_SIZED_ARRAYS_IN_MAP;
+
+ return validationError.NONE;
+ };
+
+ Validator.prototype.validateStringPointer = function(offset, nullable) {
+ return this.validateArrayPointer(
+ offset, internal.Uint8.encodedSize, internal.Uint8, nullable, [0], 0);
+ };
+
+ // Similar to Array_Data<T>::Validate()
+ // mojo/public/cpp/bindings/lib/array_internal.h
+
+ Validator.prototype.validateArray =
+ function (offset, elementSize, elementType, expectedDimensionSizes,
+ currentDimension) {
+ if (!internal.isAligned(offset))
+ return validationError.MISALIGNED_OBJECT;
+
+ if (!this.isValidRange(offset, internal.kArrayHeaderSize))
+ return validationError.ILLEGAL_MEMORY_RANGE;
+
+ var numBytes = this.message.buffer.getUint32(offset);
+ var numElements = this.message.buffer.getUint32(offset + 4);
+
+ // Note: this computation is "safe" because elementSize <= 8 and
+ // numElements is a uint32.
+ var elementsTotalSize = (elementType === internal.PackedBool) ?
+ Math.ceil(numElements / 8) : (elementSize * numElements);
+
+ if (numBytes < internal.kArrayHeaderSize + elementsTotalSize)
+ return validationError.UNEXPECTED_ARRAY_HEADER;
+
+ if (expectedDimensionSizes[currentDimension] != 0 &&
+ numElements != expectedDimensionSizes[currentDimension]) {
+ return validationError.UNEXPECTED_ARRAY_HEADER;
+ }
+
+ if (!this.claimRange(offset, numBytes))
+ return validationError.ILLEGAL_MEMORY_RANGE;
+
+ // Validate the array's elements if they are pointers or handles.
+
+ var elementsOffset = offset + internal.kArrayHeaderSize;
+ var nullable = isNullable(elementType);
+
+ if (isHandleClass(elementType))
+ return this.validateHandleElements(elementsOffset, numElements, nullable);
+ if (isInterfaceClass(elementType))
+ return this.validateInterfaceElements(
+ elementsOffset, numElements, nullable);
+ if (isInterfaceRequestClass(elementType))
+ return this.validateInterfaceRequestElements(
+ elementsOffset, numElements, nullable);
+ if (isAssociatedInterfaceClass(elementType))
+ return this.validateAssociatedInterfaceElements(
+ elementsOffset, numElements, nullable);
+ if (isAssociatedInterfaceRequestClass(elementType))
+ return this.validateAssociatedInterfaceRequestElements(
+ elementsOffset, numElements, nullable);
+ if (isStringClass(elementType))
+ return this.validateArrayElements(
+ elementsOffset, numElements, internal.Uint8, nullable, [0], 0);
+ if (elementType instanceof internal.PointerTo)
+ return this.validateStructElements(
+ elementsOffset, numElements, elementType.cls, nullable);
+ if (elementType instanceof internal.ArrayOf)
+ return this.validateArrayElements(
+ elementsOffset, numElements, elementType.cls, nullable,
+ expectedDimensionSizes, currentDimension + 1);
+ if (isEnumClass(elementType))
+ return this.validateEnumElements(elementsOffset, numElements,
+ elementType.cls);
+
+ return validationError.NONE;
+ };
+
+ // Note: the |offset + i * elementSize| computation in the validateFooElements
+ // methods below is "safe" because elementSize <= 8, offset and
+ // numElements are uint32, and 0 <= i < numElements.
+
+ Validator.prototype.validateHandleElements =
+ function(offset, numElements, nullable) {
+ var elementSize = internal.Handle.encodedSize;
+ for (var i = 0; i < numElements; i++) {
+ var elementOffset = offset + i * elementSize;
+ var err = this.validateHandle(elementOffset, nullable);
+ if (err != validationError.NONE)
+ return err;
+ }
+ return validationError.NONE;
+ };
+
+ Validator.prototype.validateInterfaceElements =
+ function(offset, numElements, nullable) {
+ var elementSize = internal.Interface.prototype.encodedSize;
+ for (var i = 0; i < numElements; i++) {
+ var elementOffset = offset + i * elementSize;
+ var err = this.validateInterface(elementOffset, nullable);
+ if (err != validationError.NONE)
+ return err;
+ }
+ return validationError.NONE;
+ };
+
+ Validator.prototype.validateInterfaceRequestElements =
+ function(offset, numElements, nullable) {
+ var elementSize = internal.InterfaceRequest.encodedSize;
+ for (var i = 0; i < numElements; i++) {
+ var elementOffset = offset + i * elementSize;
+ var err = this.validateInterfaceRequest(elementOffset, nullable);
+ if (err != validationError.NONE)
+ return err;
+ }
+ return validationError.NONE;
+ };
+
+ Validator.prototype.validateAssociatedInterfaceElements =
+ function(offset, numElements, nullable) {
+ var elementSize = internal.AssociatedInterfacePtrInfo.prototype.encodedSize;
+ for (var i = 0; i < numElements; i++) {
+ var elementOffset = offset + i * elementSize;
+ var err = this.validateAssociatedInterface(elementOffset, nullable);
+ if (err != validationError.NONE) {
+ return err;
+ }
+ }
+ return validationError.NONE;
+ };
+
+ Validator.prototype.validateAssociatedInterfaceRequestElements =
+ function(offset, numElements, nullable) {
+ var elementSize = internal.AssociatedInterfaceRequest.encodedSize;
+ for (var i = 0; i < numElements; i++) {
+ var elementOffset = offset + i * elementSize;
+ var err = this.validateAssociatedInterfaceRequest(elementOffset,
+ nullable);
+ if (err != validationError.NONE) {
+ return err;
+ }
+ }
+ return validationError.NONE;
+ };
+
+ // The elementClass parameter is the element type of the element arrays.
+ Validator.prototype.validateArrayElements =
+ function(offset, numElements, elementClass, nullable,
+ expectedDimensionSizes, currentDimension) {
+ var elementSize = internal.PointerTo.prototype.encodedSize;
+ for (var i = 0; i < numElements; i++) {
+ var elementOffset = offset + i * elementSize;
+ var err = this.validateArrayPointer(
+ elementOffset, elementClass.encodedSize, elementClass, nullable,
+ expectedDimensionSizes, currentDimension);
+ if (err != validationError.NONE)
+ return err;
+ }
+ return validationError.NONE;
+ };
+
+ Validator.prototype.validateStructElements =
+ function(offset, numElements, structClass, nullable) {
+ var elementSize = internal.PointerTo.prototype.encodedSize;
+ for (var i = 0; i < numElements; i++) {
+ var elementOffset = offset + i * elementSize;
+ var err =
+ this.validateStructPointer(elementOffset, structClass, nullable);
+ if (err != validationError.NONE)
+ return err;
+ }
+ return validationError.NONE;
+ };
+
+ Validator.prototype.validateEnumElements =
+ function(offset, numElements, enumClass) {
+ var elementSize = internal.Enum.prototype.encodedSize;
+ for (var i = 0; i < numElements; i++) {
+ var elementOffset = offset + i * elementSize;
+ var err = this.validateEnum(elementOffset, enumClass);
+ if (err != validationError.NONE)
+ return err;
+ }
+ return validationError.NONE;
+ };
+
+ internal.validationError = validationError;
+ internal.Validator = Validator;
+ internal.ValidationErrorObserverForTesting =
+ ValidationErrorObserverForTesting;
+ internal.reportValidationError = reportValidationError;
+ internal.isTestingMode = isTestingMode;
+ internal.clearTestingMode = clearTestingMode;
+})();
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+'use strict';
+
+(function() {
+ var mojomId = 'mojo/public/interfaces/bindings/new_bindings/interface_control_messages.mojom';
+ if (mojo.internal.isMojomLoaded(mojomId)) {
+ console.warn('The following mojom is loaded multiple times: ' + mojomId);
+ return;
+ }
+ mojo.internal.markMojomLoaded(mojomId);
+
+ // TODO(yzshen): Define these aliases to minimize the differences between the
+ // old/new modes. Remove them when the old mode goes away.
+ var bindings = mojo;
+ var associatedBindings = mojo;
+ var codec = mojo.internal;
+ var validator = mojo.internal;
+
+
+ var kRunMessageId = 0xFFFFFFFF;
+ var kRunOrClosePipeMessageId = 0xFFFFFFFE;
+
+ function RunMessageParams(values) {
+ this.initDefaults_();
+ this.initFields_(values);
+ }
+
+
+ RunMessageParams.prototype.initDefaults_ = function() {
+ this.input = null;
+ };
+ RunMessageParams.prototype.initFields_ = function(fields) {
+ for(var field in fields) {
+ if (this.hasOwnProperty(field))
+ this[field] = fields[field];
+ }
+ };
+
+ RunMessageParams.validate = function(messageValidator, offset) {
+ var err;
+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
+ if (err !== validator.validationError.NONE)
+ return err;
+
+ var kVersionSizes = [
+ {version: 0, numBytes: 24}
+ ];
+ err = messageValidator.validateStructVersion(offset, kVersionSizes);
+ if (err !== validator.validationError.NONE)
+ return err;
+
+
+ // validate RunMessageParams.input
+ err = messageValidator.validateUnion(offset + codec.kStructHeaderSize + 0, RunInput, false);
+ if (err !== validator.validationError.NONE)
+ return err;
+
+ return validator.validationError.NONE;
+ };
+
+ RunMessageParams.encodedSize = codec.kStructHeaderSize + 16;
+
+ RunMessageParams.decode = function(decoder) {
+ var packed;
+ var val = new RunMessageParams();
+ var numberOfBytes = decoder.readUint32();
+ var version = decoder.readUint32();
+ val.input = decoder.decodeStruct(RunInput);
+ return val;
+ };
+
+ RunMessageParams.encode = function(encoder, val) {
+ var packed;
+ encoder.writeUint32(RunMessageParams.encodedSize);
+ encoder.writeUint32(0);
+ encoder.encodeStruct(RunInput, val.input);
+ };
+ function RunResponseMessageParams(values) {
+ this.initDefaults_();
+ this.initFields_(values);
+ }
+
+
+ RunResponseMessageParams.prototype.initDefaults_ = function() {
+ this.output = null;
+ };
+ RunResponseMessageParams.prototype.initFields_ = function(fields) {
+ for(var field in fields) {
+ if (this.hasOwnProperty(field))
+ this[field] = fields[field];
+ }
+ };
+
+ RunResponseMessageParams.validate = function(messageValidator, offset) {
+ var err;
+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
+ if (err !== validator.validationError.NONE)
+ return err;
+
+ var kVersionSizes = [
+ {version: 0, numBytes: 24}
+ ];
+ err = messageValidator.validateStructVersion(offset, kVersionSizes);
+ if (err !== validator.validationError.NONE)
+ return err;
+
+
+ // validate RunResponseMessageParams.output
+ err = messageValidator.validateUnion(offset + codec.kStructHeaderSize + 0, RunOutput, true);
+ if (err !== validator.validationError.NONE)
+ return err;
+
+ return validator.validationError.NONE;
+ };
+
+ RunResponseMessageParams.encodedSize = codec.kStructHeaderSize + 16;
+
+ RunResponseMessageParams.decode = function(decoder) {
+ var packed;
+ var val = new RunResponseMessageParams();
+ var numberOfBytes = decoder.readUint32();
+ var version = decoder.readUint32();
+ val.output = decoder.decodeStruct(RunOutput);
+ return val;
+ };
+
+ RunResponseMessageParams.encode = function(encoder, val) {
+ var packed;
+ encoder.writeUint32(RunResponseMessageParams.encodedSize);
+ encoder.writeUint32(0);
+ encoder.encodeStruct(RunOutput, val.output);
+ };
+ function QueryVersion(values) {
+ this.initDefaults_();
+ this.initFields_(values);
+ }
+
+
+ QueryVersion.prototype.initDefaults_ = function() {
+ };
+ QueryVersion.prototype.initFields_ = function(fields) {
+ for(var field in fields) {
+ if (this.hasOwnProperty(field))
+ this[field] = fields[field];
+ }
+ };
+
+ QueryVersion.validate = function(messageValidator, offset) {
+ var err;
+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
+ if (err !== validator.validationError.NONE)
+ return err;
+
+ var kVersionSizes = [
+ {version: 0, numBytes: 8}
+ ];
+ err = messageValidator.validateStructVersion(offset, kVersionSizes);
+ if (err !== validator.validationError.NONE)
+ return err;
+
+ return validator.validationError.NONE;
+ };
+
+ QueryVersion.encodedSize = codec.kStructHeaderSize + 0;
+
+ QueryVersion.decode = function(decoder) {
+ var packed;
+ var val = new QueryVersion();
+ var numberOfBytes = decoder.readUint32();
+ var version = decoder.readUint32();
+ return val;
+ };
+
+ QueryVersion.encode = function(encoder, val) {
+ var packed;
+ encoder.writeUint32(QueryVersion.encodedSize);
+ encoder.writeUint32(0);
+ };
+ function QueryVersionResult(values) {
+ this.initDefaults_();
+ this.initFields_(values);
+ }
+
+
+ QueryVersionResult.prototype.initDefaults_ = function() {
+ this.version = 0;
+ };
+ QueryVersionResult.prototype.initFields_ = function(fields) {
+ for(var field in fields) {
+ if (this.hasOwnProperty(field))
+ this[field] = fields[field];
+ }
+ };
+
+ QueryVersionResult.validate = function(messageValidator, offset) {
+ var err;
+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
+ if (err !== validator.validationError.NONE)
+ return err;
+
+ var kVersionSizes = [
+ {version: 0, numBytes: 16}
+ ];
+ err = messageValidator.validateStructVersion(offset, kVersionSizes);
+ if (err !== validator.validationError.NONE)
+ return err;
+
+
+ return validator.validationError.NONE;
+ };
+
+ QueryVersionResult.encodedSize = codec.kStructHeaderSize + 8;
+
+ QueryVersionResult.decode = function(decoder) {
+ var packed;
+ var val = new QueryVersionResult();
+ var numberOfBytes = decoder.readUint32();
+ var version = decoder.readUint32();
+ val.version = decoder.decodeStruct(codec.Uint32);
+ decoder.skip(1);
+ decoder.skip(1);
+ decoder.skip(1);
+ decoder.skip(1);
+ return val;
+ };
+
+ QueryVersionResult.encode = function(encoder, val) {
+ var packed;
+ encoder.writeUint32(QueryVersionResult.encodedSize);
+ encoder.writeUint32(0);
+ encoder.encodeStruct(codec.Uint32, val.version);
+ encoder.skip(1);
+ encoder.skip(1);
+ encoder.skip(1);
+ encoder.skip(1);
+ };
+ function FlushForTesting(values) {
+ this.initDefaults_();
+ this.initFields_(values);
+ }
+
+
+ FlushForTesting.prototype.initDefaults_ = function() {
+ };
+ FlushForTesting.prototype.initFields_ = function(fields) {
+ for(var field in fields) {
+ if (this.hasOwnProperty(field))
+ this[field] = fields[field];
+ }
+ };
+
+ FlushForTesting.validate = function(messageValidator, offset) {
+ var err;
+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
+ if (err !== validator.validationError.NONE)
+ return err;
+
+ var kVersionSizes = [
+ {version: 0, numBytes: 8}
+ ];
+ err = messageValidator.validateStructVersion(offset, kVersionSizes);
+ if (err !== validator.validationError.NONE)
+ return err;
+
+ return validator.validationError.NONE;
+ };
+
+ FlushForTesting.encodedSize = codec.kStructHeaderSize + 0;
+
+ FlushForTesting.decode = function(decoder) {
+ var packed;
+ var val = new FlushForTesting();
+ var numberOfBytes = decoder.readUint32();
+ var version = decoder.readUint32();
+ return val;
+ };
+
+ FlushForTesting.encode = function(encoder, val) {
+ var packed;
+ encoder.writeUint32(FlushForTesting.encodedSize);
+ encoder.writeUint32(0);
+ };
+ function RunOrClosePipeMessageParams(values) {
+ this.initDefaults_();
+ this.initFields_(values);
+ }
+
+
+ RunOrClosePipeMessageParams.prototype.initDefaults_ = function() {
+ this.input = null;
+ };
+ RunOrClosePipeMessageParams.prototype.initFields_ = function(fields) {
+ for(var field in fields) {
+ if (this.hasOwnProperty(field))
+ this[field] = fields[field];
+ }
+ };
+
+ RunOrClosePipeMessageParams.validate = function(messageValidator, offset) {
+ var err;
+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
+ if (err !== validator.validationError.NONE)
+ return err;
+
+ var kVersionSizes = [
+ {version: 0, numBytes: 24}
+ ];
+ err = messageValidator.validateStructVersion(offset, kVersionSizes);
+ if (err !== validator.validationError.NONE)
+ return err;
+
+
+ // validate RunOrClosePipeMessageParams.input
+ err = messageValidator.validateUnion(offset + codec.kStructHeaderSize + 0, RunOrClosePipeInput, false);
+ if (err !== validator.validationError.NONE)
+ return err;
+
+ return validator.validationError.NONE;
+ };
+
+ RunOrClosePipeMessageParams.encodedSize = codec.kStructHeaderSize + 16;
+
+ RunOrClosePipeMessageParams.decode = function(decoder) {
+ var packed;
+ var val = new RunOrClosePipeMessageParams();
+ var numberOfBytes = decoder.readUint32();
+ var version = decoder.readUint32();
+ val.input = decoder.decodeStruct(RunOrClosePipeInput);
+ return val;
+ };
+
+ RunOrClosePipeMessageParams.encode = function(encoder, val) {
+ var packed;
+ encoder.writeUint32(RunOrClosePipeMessageParams.encodedSize);
+ encoder.writeUint32(0);
+ encoder.encodeStruct(RunOrClosePipeInput, val.input);
+ };
+ function RequireVersion(values) {
+ this.initDefaults_();
+ this.initFields_(values);
+ }
+
+
+ RequireVersion.prototype.initDefaults_ = function() {
+ this.version = 0;
+ };
+ RequireVersion.prototype.initFields_ = function(fields) {
+ for(var field in fields) {
+ if (this.hasOwnProperty(field))
+ this[field] = fields[field];
+ }
+ };
+
+ RequireVersion.validate = function(messageValidator, offset) {
+ var err;
+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
+ if (err !== validator.validationError.NONE)
+ return err;
+
+ var kVersionSizes = [
+ {version: 0, numBytes: 16}
+ ];
+ err = messageValidator.validateStructVersion(offset, kVersionSizes);
+ if (err !== validator.validationError.NONE)
+ return err;
+
+
+ return validator.validationError.NONE;
+ };
+
+ RequireVersion.encodedSize = codec.kStructHeaderSize + 8;
+
+ RequireVersion.decode = function(decoder) {
+ var packed;
+ var val = new RequireVersion();
+ var numberOfBytes = decoder.readUint32();
+ var version = decoder.readUint32();
+ val.version = decoder.decodeStruct(codec.Uint32);
+ decoder.skip(1);
+ decoder.skip(1);
+ decoder.skip(1);
+ decoder.skip(1);
+ return val;
+ };
+
+ RequireVersion.encode = function(encoder, val) {
+ var packed;
+ encoder.writeUint32(RequireVersion.encodedSize);
+ encoder.writeUint32(0);
+ encoder.encodeStruct(codec.Uint32, val.version);
+ encoder.skip(1);
+ encoder.skip(1);
+ encoder.skip(1);
+ encoder.skip(1);
+ };
+
+ function RunInput(value) {
+ this.initDefault_();
+ this.initValue_(value);
+ }
+
+
+ RunInput.Tags = {
+ queryVersion: 0,
+ flushForTesting: 1,
+ };
+
+ RunInput.prototype.initDefault_ = function() {
+ this.$data = null;
+ this.$tag = undefined;
+ }
+
+ RunInput.prototype.initValue_ = function(value) {
+ if (value == undefined) {
+ return;
+ }
+
+ var keys = Object.keys(value);
+ if (keys.length == 0) {
+ return;
+ }
+
+ if (keys.length > 1) {
+ throw new TypeError("You may set only one member on a union.");
+ }
+
+ var fields = [
+ "queryVersion",
+ "flushForTesting",
+ ];
+
+ if (fields.indexOf(keys[0]) < 0) {
+ throw new ReferenceError(keys[0] + " is not a RunInput member.");
+
+ }
+
+ this[keys[0]] = value[keys[0]];
+ }
+ Object.defineProperty(RunInput.prototype, "queryVersion", {
+ get: function() {
+ if (this.$tag != RunInput.Tags.queryVersion) {
+ throw new ReferenceError(
+ "RunInput.queryVersion is not currently set.");
+ }
+ return this.$data;
+ },
+
+ set: function(value) {
+ this.$tag = RunInput.Tags.queryVersion;
+ this.$data = value;
+ }
+ });
+ Object.defineProperty(RunInput.prototype, "flushForTesting", {
+ get: function() {
+ if (this.$tag != RunInput.Tags.flushForTesting) {
+ throw new ReferenceError(
+ "RunInput.flushForTesting is not currently set.");
+ }
+ return this.$data;
+ },
+
+ set: function(value) {
+ this.$tag = RunInput.Tags.flushForTesting;
+ this.$data = value;
+ }
+ });
+
+
+ RunInput.encode = function(encoder, val) {
+ if (val == null) {
+ encoder.writeUint64(0);
+ encoder.writeUint64(0);
+ return;
+ }
+ if (val.$tag == undefined) {
+ throw new TypeError("Cannot encode unions with an unknown member set.");
+ }
+
+ encoder.writeUint32(16);
+ encoder.writeUint32(val.$tag);
+ switch (val.$tag) {
+ case RunInput.Tags.queryVersion:
+ encoder.encodeStructPointer(QueryVersion, val.queryVersion);
+ break;
+ case RunInput.Tags.flushForTesting:
+ encoder.encodeStructPointer(FlushForTesting, val.flushForTesting);
+ break;
+ }
+ encoder.align();
+ };
+
+
+ RunInput.decode = function(decoder) {
+ var size = decoder.readUint32();
+ if (size == 0) {
+ decoder.readUint32();
+ decoder.readUint64();
+ return null;
+ }
+
+ var result = new RunInput();
+ var tag = decoder.readUint32();
+ switch (tag) {
+ case RunInput.Tags.queryVersion:
+ result.queryVersion = decoder.decodeStructPointer(QueryVersion);
+ break;
+ case RunInput.Tags.flushForTesting:
+ result.flushForTesting = decoder.decodeStructPointer(FlushForTesting);
+ break;
+ }
+ decoder.align();
+
+ return result;
+ };
+
+
+ RunInput.validate = function(messageValidator, offset) {
+ var size = messageValidator.decodeUnionSize(offset);
+ if (size != 16) {
+ return validator.validationError.INVALID_UNION_SIZE;
+ }
+
+ var tag = messageValidator.decodeUnionTag(offset);
+ var data_offset = offset + 8;
+ var err;
+ switch (tag) {
+ case RunInput.Tags.queryVersion:
+
+
+ // validate RunInput.queryVersion
+ err = messageValidator.validateStructPointer(data_offset, QueryVersion, false);
+ if (err !== validator.validationError.NONE)
+ return err;
+ break;
+ case RunInput.Tags.flushForTesting:
+
+
+ // validate RunInput.flushForTesting
+ err = messageValidator.validateStructPointer(data_offset, FlushForTesting, false);
+ if (err !== validator.validationError.NONE)
+ return err;
+ break;
+ }
+
+ return validator.validationError.NONE;
+ };
+
+ RunInput.encodedSize = 16;
+
+ function RunOutput(value) {
+ this.initDefault_();
+ this.initValue_(value);
+ }
+
+
+ RunOutput.Tags = {
+ queryVersionResult: 0,
+ };
+
+ RunOutput.prototype.initDefault_ = function() {
+ this.$data = null;
+ this.$tag = undefined;
+ }
+
+ RunOutput.prototype.initValue_ = function(value) {
+ if (value == undefined) {
+ return;
+ }
+
+ var keys = Object.keys(value);
+ if (keys.length == 0) {
+ return;
+ }
+
+ if (keys.length > 1) {
+ throw new TypeError("You may set only one member on a union.");
+ }
+
+ var fields = [
+ "queryVersionResult",
+ ];
+
+ if (fields.indexOf(keys[0]) < 0) {
+ throw new ReferenceError(keys[0] + " is not a RunOutput member.");
+
+ }
+
+ this[keys[0]] = value[keys[0]];
+ }
+ Object.defineProperty(RunOutput.prototype, "queryVersionResult", {
+ get: function() {
+ if (this.$tag != RunOutput.Tags.queryVersionResult) {
+ throw new ReferenceError(
+ "RunOutput.queryVersionResult is not currently set.");
+ }
+ return this.$data;
+ },
+
+ set: function(value) {
+ this.$tag = RunOutput.Tags.queryVersionResult;
+ this.$data = value;
+ }
+ });
+
+
+ RunOutput.encode = function(encoder, val) {
+ if (val == null) {
+ encoder.writeUint64(0);
+ encoder.writeUint64(0);
+ return;
+ }
+ if (val.$tag == undefined) {
+ throw new TypeError("Cannot encode unions with an unknown member set.");
+ }
+
+ encoder.writeUint32(16);
+ encoder.writeUint32(val.$tag);
+ switch (val.$tag) {
+ case RunOutput.Tags.queryVersionResult:
+ encoder.encodeStructPointer(QueryVersionResult, val.queryVersionResult);
+ break;
+ }
+ encoder.align();
+ };
+
+
+ RunOutput.decode = function(decoder) {
+ var size = decoder.readUint32();
+ if (size == 0) {
+ decoder.readUint32();
+ decoder.readUint64();
+ return null;
+ }
+
+ var result = new RunOutput();
+ var tag = decoder.readUint32();
+ switch (tag) {
+ case RunOutput.Tags.queryVersionResult:
+ result.queryVersionResult = decoder.decodeStructPointer(QueryVersionResult);
+ break;
+ }
+ decoder.align();
+
+ return result;
+ };
+
+
+ RunOutput.validate = function(messageValidator, offset) {
+ var size = messageValidator.decodeUnionSize(offset);
+ if (size != 16) {
+ return validator.validationError.INVALID_UNION_SIZE;
+ }
+
+ var tag = messageValidator.decodeUnionTag(offset);
+ var data_offset = offset + 8;
+ var err;
+ switch (tag) {
+ case RunOutput.Tags.queryVersionResult:
+
+
+ // validate RunOutput.queryVersionResult
+ err = messageValidator.validateStructPointer(data_offset, QueryVersionResult, false);
+ if (err !== validator.validationError.NONE)
+ return err;
+ break;
+ }
+
+ return validator.validationError.NONE;
+ };
+
+ RunOutput.encodedSize = 16;
+
+ function RunOrClosePipeInput(value) {
+ this.initDefault_();
+ this.initValue_(value);
+ }
+
+
+ RunOrClosePipeInput.Tags = {
+ requireVersion: 0,
+ };
+
+ RunOrClosePipeInput.prototype.initDefault_ = function() {
+ this.$data = null;
+ this.$tag = undefined;
+ }
+
+ RunOrClosePipeInput.prototype.initValue_ = function(value) {
+ if (value == undefined) {
+ return;
+ }
+
+ var keys = Object.keys(value);
+ if (keys.length == 0) {
+ return;
+ }
+
+ if (keys.length > 1) {
+ throw new TypeError("You may set only one member on a union.");
+ }
+
+ var fields = [
+ "requireVersion",
+ ];
+
+ if (fields.indexOf(keys[0]) < 0) {
+ throw new ReferenceError(keys[0] + " is not a RunOrClosePipeInput member.");
+
+ }
+
+ this[keys[0]] = value[keys[0]];
+ }
+ Object.defineProperty(RunOrClosePipeInput.prototype, "requireVersion", {
+ get: function() {
+ if (this.$tag != RunOrClosePipeInput.Tags.requireVersion) {
+ throw new ReferenceError(
+ "RunOrClosePipeInput.requireVersion is not currently set.");
+ }
+ return this.$data;
+ },
+
+ set: function(value) {
+ this.$tag = RunOrClosePipeInput.Tags.requireVersion;
+ this.$data = value;
+ }
+ });
+
+
+ RunOrClosePipeInput.encode = function(encoder, val) {
+ if (val == null) {
+ encoder.writeUint64(0);
+ encoder.writeUint64(0);
+ return;
+ }
+ if (val.$tag == undefined) {
+ throw new TypeError("Cannot encode unions with an unknown member set.");
+ }
+
+ encoder.writeUint32(16);
+ encoder.writeUint32(val.$tag);
+ switch (val.$tag) {
+ case RunOrClosePipeInput.Tags.requireVersion:
+ encoder.encodeStructPointer(RequireVersion, val.requireVersion);
+ break;
+ }
+ encoder.align();
+ };
+
+
+ RunOrClosePipeInput.decode = function(decoder) {
+ var size = decoder.readUint32();
+ if (size == 0) {
+ decoder.readUint32();
+ decoder.readUint64();
+ return null;
+ }
+
+ var result = new RunOrClosePipeInput();
+ var tag = decoder.readUint32();
+ switch (tag) {
+ case RunOrClosePipeInput.Tags.requireVersion:
+ result.requireVersion = decoder.decodeStructPointer(RequireVersion);
+ break;
+ }
+ decoder.align();
+
+ return result;
+ };
+
+
+ RunOrClosePipeInput.validate = function(messageValidator, offset) {
+ var size = messageValidator.decodeUnionSize(offset);
+ if (size != 16) {
+ return validator.validationError.INVALID_UNION_SIZE;
+ }
+
+ var tag = messageValidator.decodeUnionTag(offset);
+ var data_offset = offset + 8;
+ var err;
+ switch (tag) {
+ case RunOrClosePipeInput.Tags.requireVersion:
+
+
+ // validate RunOrClosePipeInput.requireVersion
+ err = messageValidator.validateStructPointer(data_offset, RequireVersion, false);
+ if (err !== validator.validationError.NONE)
+ return err;
+ break;
+ }
+
+ return validator.validationError.NONE;
+ };
+
+ RunOrClosePipeInput.encodedSize = 16;
+ var exports = mojo.internal.exposeNamespace("mojo.interfaceControl2");
+ exports.kRunMessageId = kRunMessageId;
+ exports.kRunOrClosePipeMessageId = kRunOrClosePipeMessageId;
+ exports.RunMessageParams = RunMessageParams;
+ exports.RunResponseMessageParams = RunResponseMessageParams;
+ exports.QueryVersion = QueryVersion;
+ exports.QueryVersionResult = QueryVersionResult;
+ exports.FlushForTesting = FlushForTesting;
+ exports.RunOrClosePipeMessageParams = RunOrClosePipeMessageParams;
+ exports.RequireVersion = RequireVersion;
+ exports.RunInput = RunInput;
+ exports.RunOutput = RunOutput;
+ exports.RunOrClosePipeInput = RunOrClosePipeInput;
+})();// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+'use strict';
+
+(function() {
+ var mojomId = 'mojo/public/interfaces/bindings/new_bindings/pipe_control_messages.mojom';
+ if (mojo.internal.isMojomLoaded(mojomId)) {
+ console.warn('The following mojom is loaded multiple times: ' + mojomId);
+ return;
+ }
+ mojo.internal.markMojomLoaded(mojomId);
+
+ // TODO(yzshen): Define these aliases to minimize the differences between the
+ // old/new modes. Remove them when the old mode goes away.
+ var bindings = mojo;
+ var associatedBindings = mojo;
+ var codec = mojo.internal;
+ var validator = mojo.internal;
+
+
+ var kRunOrClosePipeMessageId = 0xFFFFFFFE;
+
+ function RunOrClosePipeMessageParams(values) {
+ this.initDefaults_();
+ this.initFields_(values);
+ }
+
+
+ RunOrClosePipeMessageParams.prototype.initDefaults_ = function() {
+ this.input = null;
+ };
+ RunOrClosePipeMessageParams.prototype.initFields_ = function(fields) {
+ for(var field in fields) {
+ if (this.hasOwnProperty(field))
+ this[field] = fields[field];
+ }
+ };
+
+ RunOrClosePipeMessageParams.validate = function(messageValidator, offset) {
+ var err;
+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
+ if (err !== validator.validationError.NONE)
+ return err;
+
+ var kVersionSizes = [
+ {version: 0, numBytes: 24}
+ ];
+ err = messageValidator.validateStructVersion(offset, kVersionSizes);
+ if (err !== validator.validationError.NONE)
+ return err;
+
+
+ // validate RunOrClosePipeMessageParams.input
+ err = messageValidator.validateUnion(offset + codec.kStructHeaderSize + 0, RunOrClosePipeInput, false);
+ if (err !== validator.validationError.NONE)
+ return err;
+
+ return validator.validationError.NONE;
+ };
+
+ RunOrClosePipeMessageParams.encodedSize = codec.kStructHeaderSize + 16;
+
+ RunOrClosePipeMessageParams.decode = function(decoder) {
+ var packed;
+ var val = new RunOrClosePipeMessageParams();
+ var numberOfBytes = decoder.readUint32();
+ var version = decoder.readUint32();
+ val.input = decoder.decodeStruct(RunOrClosePipeInput);
+ return val;
+ };
+
+ RunOrClosePipeMessageParams.encode = function(encoder, val) {
+ var packed;
+ encoder.writeUint32(RunOrClosePipeMessageParams.encodedSize);
+ encoder.writeUint32(0);
+ encoder.encodeStruct(RunOrClosePipeInput, val.input);
+ };
+ function DisconnectReason(values) {
+ this.initDefaults_();
+ this.initFields_(values);
+ }
+
+
+ DisconnectReason.prototype.initDefaults_ = function() {
+ this.customReason = 0;
+ this.description = null;
+ };
+ DisconnectReason.prototype.initFields_ = function(fields) {
+ for(var field in fields) {
+ if (this.hasOwnProperty(field))
+ this[field] = fields[field];
+ }
+ };
+
+ DisconnectReason.validate = function(messageValidator, offset) {
+ var err;
+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
+ if (err !== validator.validationError.NONE)
+ return err;
+
+ var kVersionSizes = [
+ {version: 0, numBytes: 24}
+ ];
+ err = messageValidator.validateStructVersion(offset, kVersionSizes);
+ if (err !== validator.validationError.NONE)
+ return err;
+
+
+
+
+ // validate DisconnectReason.description
+ err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 8, false)
+ if (err !== validator.validationError.NONE)
+ return err;
+
+ return validator.validationError.NONE;
+ };
+
+ DisconnectReason.encodedSize = codec.kStructHeaderSize + 16;
+
+ DisconnectReason.decode = function(decoder) {
+ var packed;
+ var val = new DisconnectReason();
+ var numberOfBytes = decoder.readUint32();
+ var version = decoder.readUint32();
+ val.customReason = decoder.decodeStruct(codec.Uint32);
+ decoder.skip(1);
+ decoder.skip(1);
+ decoder.skip(1);
+ decoder.skip(1);
+ val.description = decoder.decodeStruct(codec.String);
+ return val;
+ };
+
+ DisconnectReason.encode = function(encoder, val) {
+ var packed;
+ encoder.writeUint32(DisconnectReason.encodedSize);
+ encoder.writeUint32(0);
+ encoder.encodeStruct(codec.Uint32, val.customReason);
+ encoder.skip(1);
+ encoder.skip(1);
+ encoder.skip(1);
+ encoder.skip(1);
+ encoder.encodeStruct(codec.String, val.description);
+ };
+ function PeerAssociatedEndpointClosedEvent(values) {
+ this.initDefaults_();
+ this.initFields_(values);
+ }
+
+
+ PeerAssociatedEndpointClosedEvent.prototype.initDefaults_ = function() {
+ this.id = 0;
+ this.disconnectReason = null;
+ };
+ PeerAssociatedEndpointClosedEvent.prototype.initFields_ = function(fields) {
+ for(var field in fields) {
+ if (this.hasOwnProperty(field))
+ this[field] = fields[field];
+ }
+ };
+
+ PeerAssociatedEndpointClosedEvent.validate = function(messageValidator, offset) {
+ var err;
+ err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
+ if (err !== validator.validationError.NONE)
+ return err;
+
+ var kVersionSizes = [
+ {version: 0, numBytes: 24}
+ ];
+ err = messageValidator.validateStructVersion(offset, kVersionSizes);
+ if (err !== validator.validationError.NONE)
+ return err;
+
+
+
+
+ // validate PeerAssociatedEndpointClosedEvent.disconnectReason
+ err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 8, DisconnectReason, true);
+ if (err !== validator.validationError.NONE)
+ return err;
+
+ return validator.validationError.NONE;
+ };
+
+ PeerAssociatedEndpointClosedEvent.encodedSize = codec.kStructHeaderSize + 16;
+
+ PeerAssociatedEndpointClosedEvent.decode = function(decoder) {
+ var packed;
+ var val = new PeerAssociatedEndpointClosedEvent();
+ var numberOfBytes = decoder.readUint32();
+ var version = decoder.readUint32();
+ val.id = decoder.decodeStruct(codec.Uint32);
+ decoder.skip(1);
+ decoder.skip(1);
+ decoder.skip(1);
+ decoder.skip(1);
+ val.disconnectReason = decoder.decodeStructPointer(DisconnectReason);
+ return val;
+ };
+
+ PeerAssociatedEndpointClosedEvent.encode = function(encoder, val) {
+ var packed;
+ encoder.writeUint32(PeerAssociatedEndpointClosedEvent.encodedSize);
+ encoder.writeUint32(0);
+ encoder.encodeStruct(codec.Uint32, val.id);
+ encoder.skip(1);
+ encoder.skip(1);
+ encoder.skip(1);
+ encoder.skip(1);
+ encoder.encodeStructPointer(DisconnectReason, val.disconnectReason);
+ };
+
+ function RunOrClosePipeInput(value) {
+ this.initDefault_();
+ this.initValue_(value);
+ }
+
+
+ RunOrClosePipeInput.Tags = {
+ peerAssociatedEndpointClosedEvent: 0,
+ };
+
+ RunOrClosePipeInput.prototype.initDefault_ = function() {
+ this.$data = null;
+ this.$tag = undefined;
+ }
+
+ RunOrClosePipeInput.prototype.initValue_ = function(value) {
+ if (value == undefined) {
+ return;
+ }
+
+ var keys = Object.keys(value);
+ if (keys.length == 0) {
+ return;
+ }
+
+ if (keys.length > 1) {
+ throw new TypeError("You may set only one member on a union.");
+ }
+
+ var fields = [
+ "peerAssociatedEndpointClosedEvent",
+ ];
+
+ if (fields.indexOf(keys[0]) < 0) {
+ throw new ReferenceError(keys[0] + " is not a RunOrClosePipeInput member.");
+
+ }
+
+ this[keys[0]] = value[keys[0]];
+ }
+ Object.defineProperty(RunOrClosePipeInput.prototype, "peerAssociatedEndpointClosedEvent", {
+ get: function() {
+ if (this.$tag != RunOrClosePipeInput.Tags.peerAssociatedEndpointClosedEvent) {
+ throw new ReferenceError(
+ "RunOrClosePipeInput.peerAssociatedEndpointClosedEvent is not currently set.");
+ }
+ return this.$data;
+ },
+
+ set: function(value) {
+ this.$tag = RunOrClosePipeInput.Tags.peerAssociatedEndpointClosedEvent;
+ this.$data = value;
+ }
+ });
+
+
+ RunOrClosePipeInput.encode = function(encoder, val) {
+ if (val == null) {
+ encoder.writeUint64(0);
+ encoder.writeUint64(0);
+ return;
+ }
+ if (val.$tag == undefined) {
+ throw new TypeError("Cannot encode unions with an unknown member set.");
+ }
+
+ encoder.writeUint32(16);
+ encoder.writeUint32(val.$tag);
+ switch (val.$tag) {
+ case RunOrClosePipeInput.Tags.peerAssociatedEndpointClosedEvent:
+ encoder.encodeStructPointer(PeerAssociatedEndpointClosedEvent, val.peerAssociatedEndpointClosedEvent);
+ break;
+ }
+ encoder.align();
+ };
+
+
+ RunOrClosePipeInput.decode = function(decoder) {
+ var size = decoder.readUint32();
+ if (size == 0) {
+ decoder.readUint32();
+ decoder.readUint64();
+ return null;
+ }
+
+ var result = new RunOrClosePipeInput();
+ var tag = decoder.readUint32();
+ switch (tag) {
+ case RunOrClosePipeInput.Tags.peerAssociatedEndpointClosedEvent:
+ result.peerAssociatedEndpointClosedEvent = decoder.decodeStructPointer(PeerAssociatedEndpointClosedEvent);
+ break;
+ }
+ decoder.align();
+
+ return result;
+ };
+
+
+ RunOrClosePipeInput.validate = function(messageValidator, offset) {
+ var size = messageValidator.decodeUnionSize(offset);
+ if (size != 16) {
+ return validator.validationError.INVALID_UNION_SIZE;
+ }
+
+ var tag = messageValidator.decodeUnionTag(offset);
+ var data_offset = offset + 8;
+ var err;
+ switch (tag) {
+ case RunOrClosePipeInput.Tags.peerAssociatedEndpointClosedEvent:
+
+
+ // validate RunOrClosePipeInput.peerAssociatedEndpointClosedEvent
+ err = messageValidator.validateStructPointer(data_offset, PeerAssociatedEndpointClosedEvent, false);
+ if (err !== validator.validationError.NONE)
+ return err;
+ break;
+ }
+
+ return validator.validationError.NONE;
+ };
+
+ RunOrClosePipeInput.encodedSize = 16;
+ var exports = mojo.internal.exposeNamespace("mojo.pipeControl2");
+ exports.kRunOrClosePipeMessageId = kRunOrClosePipeMessageId;
+ exports.RunOrClosePipeMessageParams = RunOrClosePipeMessageParams;
+ exports.DisconnectReason = DisconnectReason;
+ exports.PeerAssociatedEndpointClosedEvent = PeerAssociatedEndpointClosedEvent;
+ exports.RunOrClosePipeInput = RunOrClosePipeInput;
+})();

Powered by Google App Engine
This is Rietveld 408576698