blob: 70f6cad5e5f06f4f64a0fd4cdcd693fcea12bb78 [file] [log] [blame]
// 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 ((typeof mojo !== 'undefined') && mojo.bindingsLibraryInitialized) {
throw new Error('The Mojo bindings library has been initialized.');
}
var mojo = mojo || {};
mojo.bindingsLibraryInitialized = true;
mojo.internal = mojo.internal || {};
mojo.config = mojo.config || {};
if (typeof mojo.config.global === 'undefined') {
mojo.config.global = this;
}
if (typeof mojo.config.autoLoadMojomDeps === 'undefined') {
// 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>
//
// -->
mojo.config.autoLoadMojomDeps = true;
}
(function() {
var internal = mojo.internal;
var config = mojo.config;
var LoadState = {
PENDING_LOAD: 1,
LOADED: 2
};
var mojomRegistry = new Map();
function exposeNamespace(namespace) {
var current = config.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 (config.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;
config.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 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;
}
function hasInterfaceIdNamespaceBitSet(interfaceId) {
if (interfaceId >= 2 * kInterfaceIdNamespaceMask) {
throw new Error("Interface ID should be a 32-bit unsigned integer.");
}
return interfaceId >= kInterfaceIdNamespaceMask;
}
mojo.InterfacePtrInfo = InterfacePtrInfo;
mojo.InterfaceRequest = InterfaceRequest;
mojo.AssociatedInterfacePtrInfo = AssociatedInterfacePtrInfo;
mojo.AssociatedInterfaceRequest = AssociatedInterfaceRequest;
internal.isMasterInterfaceId = isMasterInterfaceId;
internal.isValidInterfaceId = isValidInterfaceId;
internal.hasInterfaceIdNamespaceBitSet = hasInterfaceIdNamespaceBitSet;
internal.kInvalidInterfaceId = kInvalidInterfaceId;
internal.kMasterInterfaceId = kMasterInterfaceId;
internal.kInterfaceIdNamespaceMask = kInterfaceIdNamespaceMask;
})();
// 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);
// Dispatching the message may have closed the connector.
if (this.handle_ == null)
return;
// 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 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.interfaceControl.kRunMessageId) {
throw new Error("Control message name is not kRunMessageId");
}
// Validate payload.
error = mojo.interfaceControl.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.interfaceControl.kRunOrClosePipeMessageId) {
throw new Error("Control message name is not kRunOrClosePipeMessageId");
}
// Validate payload.
error = mojo.interfaceControl.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.interfaceControl.RunOrClosePipeMessageParams);
return interfaceVersion >=
runOrClosePipeMessageParams.input.requireVersion.version;
}
function run(message, responder, interfaceVersion) {
var reader = new internal.MessageReader(message);
var runMessageParams =
reader.decodeStruct(mojo.interfaceControl.RunMessageParams);
var runOutput = null;
if (runMessageParams.input.queryVersion) {
runOutput = new mojo.interfaceControl.RunOutput();
runOutput.queryVersionResult = new
mojo.interfaceControl.QueryVersionResult(
{'version': interfaceVersion});
}
var runResponseMessageParams = new
mojo.interfaceControl.RunResponseMessageParams();
runResponseMessageParams.output = runOutput;
var messageName = mojo.interfaceControl.kRunMessageId;
var payloadSize =
mojo.interfaceControl.RunResponseMessageParams.encodedSize;
var requestID = reader.requestID;
var builder = new internal.MessageV1Builder(messageName,
payloadSize, internal.kMessageIsResponse, requestID);
builder.encodeStruct(mojo.interfaceControl.RunResponseMessageParams,
runResponseMessageParams);
responder.accept(builder.finish());
return true;
}
function isInterfaceControlMessage(message) {
return message.getName() == mojo.interfaceControl.kRunMessageId ||
message.getName() == mojo.interfaceControl.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.interfaceControl.RunOrClosePipeMessageParams();
runOrClosePipeMessageParams.input = runOrClosePipeInput;
var messageName = mojo.interfaceControl.kRunOrClosePipeMessageId;
var payloadSize =
mojo.interfaceControl.RunOrClosePipeMessageParams.encodedSize;
var builder = new internal.MessageV0Builder(messageName, payloadSize);
builder.encodeStruct(mojo.interfaceControl.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.interfaceControl.kRunMessageId) {
throw new Error("Control message name is not kRunMessageId");
}
// Validate payload.
error = mojo.interfaceControl.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.interfaceControl.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.interfaceControl.kRunMessageId;
var payloadSize = mojo.interfaceControl.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.interfaceControl.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.interfaceControl.RunMessageParams();
runMessageParams.input = new mojo.interfaceControl.RunInput();
runMessageParams.input.queryVersion =
new mojo.interfaceControl.QueryVersion();
return sendRunMessage(this.receiver_, runMessageParams).then(function(
runResponseMessageParams) {
return runResponseMessageParams.output.queryVersionResult.version;
});
};
ControlMessageProxy.prototype.requireVersion = function(version) {
var runOrClosePipeInput = new mojo.interfaceControl.RunOrClosePipeInput();
runOrClosePipeInput.requireVersion =
new mojo.interfaceControl.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.pipeControl.kRunOrClosePipeMessageId) {
throw new Error("Control message name is not kRunOrClosePipeMessageId");
}
// Validate payload.
error = mojo.pipeControl.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.pipeControl.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.pipeControl.RunOrClosePipeMessageParams();
runOrClosePipeMessageParams.input = runOrClosePipeInput;
var messageName = mojo.pipeControl.kRunOrClosePipeMessageId;
var payloadSize =
mojo.pipeControl.RunOrClosePipeMessageParams.encodedSize;
var builder = new internal.MessageV0Builder(messageName, payloadSize);
builder.encodeStruct(mojo.pipeControl.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.pipeControl.PeerAssociatedEndpointClosedEvent();
event.id = interfaceId;
if (reason) {
event.disconnectReason = new mojo.pipeControl.DisconnectReason({
customReason: reason.customReason,
description: reason.description});
}
var runOrClosePipeInput = new mojo.pipeControl.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();
}
// Unless it is the master ID, |interfaceId| is from the remote side and
// therefore its namespace bit is supposed to be different than the value
// that this router would use.
if (!internal.isMasterInterfaceId(interfaceId) &&
this.setInterfaceIdNamespaceBit_ ===
internal.hasInterfaceIdNamespaceBitSet(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) {
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;
var textDecoder = new TextDecoder('utf-8');
var textEncoder = new TextEncoder('utf-8');
/**
* 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 textDecoder.decode(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) {
const utf8Buffer = textEncoder.encode(str);
if (outputBuffer.length < utf8Buffer.length)
throw new Error("Buffer too small for encodeUtf8String");
outputBuffer.set(utf8Buffer);
return utf8Buffer.length;
}
/**
* Returns the number of bytes that a UTF8 encoding of the JavaScript string
* |str| would occupy.
*/
function utf8Length(str) {
return textEncoder.encode(str).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/interface_control_messages.mojom';
if (mojo.internal.isMojomLoaded(mojomId)) {
console.warn('The following mojom is loaded multiple times: ' + mojomId);
return;
}
mojo.internal.markMojomLoaded(mojomId);
var bindings = mojo;
var associatedBindings = mojo;
var codec = mojo.internal;
var validator = mojo.internal;
var exports = mojo.internal.exposeNamespace('mojo.interfaceControl');
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/pipe_control_messages.mojom';
if (mojo.internal.isMojomLoaded(mojomId)) {
console.warn('The following mojom is loaded multiple times: ' + mojomId);
return;
}
mojo.internal.markMojomLoaded(mojomId);
var bindings = mojo;
var associatedBindings = mojo;
var codec = mojo.internal;
var validator = mojo.internal;
var exports = mojo.internal.exposeNamespace('mojo.pipeControl');
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;
})();