| // 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, |
| // |
| // <!-- |
| // (This comment tag is necessary on IOS to avoid interpreting the closing |
| // script tags in the example.) |
| // |
| // 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: true |
| }; |
| |
| (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, relativePath) { |
| if (mojomRegistry.has(id)) { |
| return; |
| } |
| |
| if (internal.global.document === undefined) { |
| throw new Error( |
| 'Mojom dependency autoloading is not implemented in workers. ' + |
| 'Please see config variable mojo.config.autoLoadMojomDeps for more ' + |
| 'details.'); |
| } |
| |
| markMojomPendingLoad(id); |
| var url = new URL(relativePath, document.currentScript.src).href; |
| 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 exports = mojo.internal.exposeNamespace('mojo.interfaceControl2'); |
| |
| |
| 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; |
| 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 exports = mojo.internal.exposeNamespace('mojo.pipeControl2'); |
| |
| |
| 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; |
| exports.kRunOrClosePipeMessageId = kRunOrClosePipeMessageId; |
| exports.RunOrClosePipeMessageParams = RunOrClosePipeMessageParams; |
| exports.DisconnectReason = DisconnectReason; |
| exports.PeerAssociatedEndpointClosedEvent = PeerAssociatedEndpointClosedEvent; |
| exports.RunOrClosePipeInput = RunOrClosePipeInput; |
| })(); |