OLD | NEW |
(Empty) | |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 'use strict'; |
| 6 |
| 7 if (mojo && mojo.internal) { |
| 8 throw new Error('The Mojo bindings library has been initialized.'); |
| 9 } |
| 10 |
| 11 var mojo = mojo || {}; |
| 12 mojo.internal = {}; |
| 13 mojo.internal.global = this; |
| 14 mojo.config = { |
| 15 // Whether to automatically load mojom dependencies. |
| 16 // For example, if foo.mojom imports bar.mojom, |autoLoadMojomDeps| set to |
| 17 // true means that loading foo.mojom.js will insert a <script> tag to load |
| 18 // bar.mojom.js, if it hasn't been loaded. |
| 19 // |
| 20 // The URL of bar.mojom.js is determined by the relative path of bar.mojom |
| 21 // (relative to the position of foo.mojom at build time) and the URL of |
| 22 // foo.mojom.js. For exmple, if at build time the two mojom files are |
| 23 // located at: |
| 24 // a/b/c/foo.mojom |
| 25 // a/b/d/bar.mojom |
| 26 // and the URL of foo.mojom.js is: |
| 27 // http://example.org/scripts/b/c/foo.mojom.js |
| 28 // then the URL of bar.mojom.js will be: |
| 29 // http://example.org/scripts/b/d/bar.mojom.js |
| 30 // |
| 31 // If you would like bar.mojom.js to live at a different location, you need |
| 32 // to turn off |autoLoadMojomDeps| before loading foo.mojom.js, and manually |
| 33 // load bar.mojom.js yourself. Similarly, you need to turn off the option if |
| 34 // you merge bar.mojom.js and foo.mojom.js into a single file. |
| 35 // |
| 36 // Performance tip: Avoid loading the same mojom.js file multiple times. |
| 37 // Assume that |autoLoadMojomDeps| is set to true: |
| 38 // <!-- No duplicate loading; recommended. --> |
| 39 // <script src="http://example.org/scripts/b/c/foo.mojom.js"></script> |
| 40 // |
| 41 // <!-- No duplicate loading, although unnecessary. --> |
| 42 // <script src="http://example.org/scripts/b/d/bar.mojom.js"></script> |
| 43 // <script src="http://example.org/scripts/b/c/foo.mojom.js"></script> |
| 44 // |
| 45 // <!-- Load bar.mojom.js twice; should be avoided. --> |
| 46 // <script src="http://example.org/scripts/b/c/foo.mojom.js"></script> |
| 47 // <script src="http://example.org/scripts/b/d/bar.mojom.js"></script> |
| 48 autoLoadMojomDeps: false |
| 49 }; |
| 50 |
| 51 (function() { |
| 52 var internal = mojo.internal; |
| 53 |
| 54 var LoadState = { |
| 55 PENDING_LOAD: 1, |
| 56 LOADED: 2 |
| 57 }; |
| 58 |
| 59 var mojomRegistry = new Map(); |
| 60 |
| 61 function exposeNamespace(namespace) { |
| 62 var current = internal.global; |
| 63 var parts = namespace.split('.'); |
| 64 |
| 65 for (var part; parts.length && (part = parts.shift());) { |
| 66 if (!current[part]) { |
| 67 current[part] = {}; |
| 68 } |
| 69 current = current[part]; |
| 70 } |
| 71 |
| 72 return current; |
| 73 } |
| 74 |
| 75 function isMojomPendingLoad(id) { |
| 76 return mojomRegistry.get(id) === LoadState.PENDING_LOAD; |
| 77 } |
| 78 |
| 79 function isMojomLoaded(id) { |
| 80 return mojomRegistry.get(id) === LoadState.LOADED; |
| 81 } |
| 82 |
| 83 function markMojomPendingLoad(id) { |
| 84 if (isMojomLoaded(id)) { |
| 85 throw new Error('The following mojom file has been loaded: ' + id); |
| 86 } |
| 87 |
| 88 mojomRegistry.set(id, LoadState.PENDING_LOAD); |
| 89 } |
| 90 |
| 91 function markMojomLoaded(id) { |
| 92 mojomRegistry.set(id, LoadState.LOADED); |
| 93 } |
| 94 |
| 95 function loadMojomIfNecessary(id, url) { |
| 96 if (mojomRegistry.has(id)) { |
| 97 return; |
| 98 } |
| 99 |
| 100 markMojomPendingLoad(id); |
| 101 internal.global.document.write('<script type="text/javascript" src="' + |
| 102 url + '"></script>'); |
| 103 } |
| 104 |
| 105 internal.exposeNamespace = exposeNamespace; |
| 106 internal.isMojomPendingLoad = isMojomPendingLoad; |
| 107 internal.isMojomLoaded = isMojomLoaded; |
| 108 internal.markMojomPendingLoad = markMojomPendingLoad; |
| 109 internal.markMojomLoaded = markMojomLoaded; |
| 110 internal.loadMojomIfNecessary = loadMojomIfNecessary; |
| 111 })(); |
| 112 // Copyright 2017 The Chromium Authors. All rights reserved. |
| 113 // Use of this source code is governed by a BSD-style license that can be |
| 114 // found in the LICENSE file. |
| 115 |
| 116 (function() { |
| 117 var internal = mojo.internal; |
| 118 |
| 119 // --------------------------------------------------------------------------- |
| 120 |
| 121 // |output| could be an interface pointer, InterfacePtrInfo or |
| 122 // AssociatedInterfacePtrInfo. |
| 123 function makeRequest(output) { |
| 124 if (output instanceof mojo.AssociatedInterfacePtrInfo) { |
| 125 var {handle0, handle1} = internal.createPairPendingAssociation(); |
| 126 output.interfaceEndpointHandle = handle0; |
| 127 output.version = 0; |
| 128 |
| 129 return new mojo.AssociatedInterfaceRequest(handle1); |
| 130 } |
| 131 |
| 132 if (output instanceof mojo.InterfacePtrInfo) { |
| 133 var pipe = Mojo.createMessagePipe(); |
| 134 output.handle = pipe.handle0; |
| 135 output.version = 0; |
| 136 |
| 137 return new mojo.InterfaceRequest(pipe.handle1); |
| 138 } |
| 139 |
| 140 var pipe = Mojo.createMessagePipe(); |
| 141 output.ptr.bind(new mojo.InterfacePtrInfo(pipe.handle0, 0)); |
| 142 return new mojo.InterfaceRequest(pipe.handle1); |
| 143 } |
| 144 |
| 145 // --------------------------------------------------------------------------- |
| 146 |
| 147 // Operations used to setup/configure an interface pointer. Exposed as the |
| 148 // |ptr| field of generated interface pointer classes. |
| 149 // |ptrInfoOrHandle| could be omitted and passed into bind() later. |
| 150 function InterfacePtrController(interfaceType, ptrInfoOrHandle) { |
| 151 this.version = 0; |
| 152 |
| 153 this.interfaceType_ = interfaceType; |
| 154 this.router_ = null; |
| 155 this.interfaceEndpointClient_ = null; |
| 156 this.proxy_ = null; |
| 157 |
| 158 // |router_| and |interfaceEndpointClient_| are lazily initialized. |
| 159 // |handle_| is valid between bind() and |
| 160 // the initialization of |router_| and |interfaceEndpointClient_|. |
| 161 this.handle_ = null; |
| 162 |
| 163 if (ptrInfoOrHandle) |
| 164 this.bind(ptrInfoOrHandle); |
| 165 } |
| 166 |
| 167 InterfacePtrController.prototype.bind = function(ptrInfoOrHandle) { |
| 168 this.reset(); |
| 169 |
| 170 if (ptrInfoOrHandle instanceof mojo.InterfacePtrInfo) { |
| 171 this.version = ptrInfoOrHandle.version; |
| 172 this.handle_ = ptrInfoOrHandle.handle; |
| 173 } else { |
| 174 this.handle_ = ptrInfoOrHandle; |
| 175 } |
| 176 }; |
| 177 |
| 178 InterfacePtrController.prototype.isBound = function() { |
| 179 return this.interfaceEndpointClient_ !== null || this.handle_ !== null; |
| 180 }; |
| 181 |
| 182 // Although users could just discard the object, reset() closes the pipe |
| 183 // immediately. |
| 184 InterfacePtrController.prototype.reset = function() { |
| 185 this.version = 0; |
| 186 if (this.interfaceEndpointClient_) { |
| 187 this.interfaceEndpointClient_.close(); |
| 188 this.interfaceEndpointClient_ = null; |
| 189 } |
| 190 if (this.router_) { |
| 191 this.router_.close(); |
| 192 this.router_ = null; |
| 193 |
| 194 this.proxy_ = null; |
| 195 } |
| 196 if (this.handle_) { |
| 197 this.handle_.close(); |
| 198 this.handle_ = null; |
| 199 } |
| 200 }; |
| 201 |
| 202 InterfacePtrController.prototype.resetWithReason = function(reason) { |
| 203 if (this.isBound()) { |
| 204 this.configureProxyIfNecessary_(); |
| 205 this.interfaceEndpointClient_.close(reason); |
| 206 this.interfaceEndpointClient_ = null; |
| 207 } |
| 208 this.reset(); |
| 209 }; |
| 210 |
| 211 InterfacePtrController.prototype.setConnectionErrorHandler = function( |
| 212 callback) { |
| 213 if (!this.isBound()) |
| 214 throw new Error("Cannot set connection error handler if not bound."); |
| 215 |
| 216 this.configureProxyIfNecessary_(); |
| 217 this.interfaceEndpointClient_.setConnectionErrorHandler(callback); |
| 218 }; |
| 219 |
| 220 InterfacePtrController.prototype.passInterface = function() { |
| 221 var result; |
| 222 if (this.router_) { |
| 223 // TODO(yzshen): Fix Router interface to support extracting handle. |
| 224 result = new mojo.InterfacePtrInfo( |
| 225 this.router_.connector_.handle_, this.version); |
| 226 this.router_.connector_.handle_ = null; |
| 227 } else { |
| 228 // This also handles the case when this object is not bound. |
| 229 result = new mojo.InterfacePtrInfo(this.handle_, this.version); |
| 230 this.handle_ = null; |
| 231 } |
| 232 |
| 233 this.reset(); |
| 234 return result; |
| 235 }; |
| 236 |
| 237 InterfacePtrController.prototype.getProxy = function() { |
| 238 this.configureProxyIfNecessary_(); |
| 239 return this.proxy_; |
| 240 }; |
| 241 |
| 242 InterfacePtrController.prototype.configureProxyIfNecessary_ = function() { |
| 243 if (!this.handle_) |
| 244 return; |
| 245 |
| 246 this.router_ = new internal.Router(this.handle_, true); |
| 247 this.handle_ = null; |
| 248 |
| 249 this.interfaceEndpointClient_ = new internal.InterfaceEndpointClient( |
| 250 this.router_.createLocalEndpointHandle(internal.kMasterInterfaceId)); |
| 251 |
| 252 this.interfaceEndpointClient_ .setPayloadValidators([ |
| 253 this.interfaceType_.validateResponse]); |
| 254 this.proxy_ = new this.interfaceType_.proxyClass( |
| 255 this.interfaceEndpointClient_); |
| 256 }; |
| 257 |
| 258 InterfacePtrController.prototype.queryVersion = function() { |
| 259 function onQueryVersion(version) { |
| 260 this.version = version; |
| 261 return version; |
| 262 } |
| 263 |
| 264 this.configureProxyIfNecessary_(); |
| 265 return this.interfaceEndpointClient_.queryVersion().then( |
| 266 onQueryVersion.bind(this)); |
| 267 }; |
| 268 |
| 269 InterfacePtrController.prototype.requireVersion = function(version) { |
| 270 this.configureProxyIfNecessary_(); |
| 271 |
| 272 if (this.version >= version) { |
| 273 return; |
| 274 } |
| 275 this.version = version; |
| 276 this.interfaceEndpointClient_.requireVersion(version); |
| 277 }; |
| 278 |
| 279 // --------------------------------------------------------------------------- |
| 280 |
| 281 // |request| could be omitted and passed into bind() later. |
| 282 // |
| 283 // Example: |
| 284 // |
| 285 // // FooImpl implements mojom.Foo. |
| 286 // function FooImpl() { ... } |
| 287 // FooImpl.prototype.fooMethod1 = function() { ... } |
| 288 // FooImpl.prototype.fooMethod2 = function() { ... } |
| 289 // |
| 290 // var fooPtr = new mojom.FooPtr(); |
| 291 // var request = makeRequest(fooPtr); |
| 292 // var binding = new Binding(mojom.Foo, new FooImpl(), request); |
| 293 // fooPtr.fooMethod1(); |
| 294 function Binding(interfaceType, impl, requestOrHandle) { |
| 295 this.interfaceType_ = interfaceType; |
| 296 this.impl_ = impl; |
| 297 this.router_ = null; |
| 298 this.interfaceEndpointClient_ = null; |
| 299 this.stub_ = null; |
| 300 |
| 301 if (requestOrHandle) |
| 302 this.bind(requestOrHandle); |
| 303 } |
| 304 |
| 305 Binding.prototype.isBound = function() { |
| 306 return this.router_ !== null; |
| 307 }; |
| 308 |
| 309 Binding.prototype.createInterfacePtrAndBind = function() { |
| 310 var ptr = new this.interfaceType_.ptrClass(); |
| 311 // TODO(yzshen): Set the version of the interface pointer. |
| 312 this.bind(makeRequest(ptr)); |
| 313 return ptr; |
| 314 }; |
| 315 |
| 316 Binding.prototype.bind = function(requestOrHandle) { |
| 317 this.close(); |
| 318 |
| 319 var handle = requestOrHandle instanceof mojo.InterfaceRequest ? |
| 320 requestOrHandle.handle : requestOrHandle; |
| 321 if (!(handle instanceof MojoHandle)) |
| 322 return; |
| 323 |
| 324 this.router_ = new internal.Router(handle); |
| 325 |
| 326 this.stub_ = new this.interfaceType_.stubClass(this.impl_); |
| 327 this.interfaceEndpointClient_ = new internal.InterfaceEndpointClient( |
| 328 this.router_.createLocalEndpointHandle(internal.kMasterInterfaceId), |
| 329 this.stub_, this.interfaceType_.kVersion); |
| 330 |
| 331 this.interfaceEndpointClient_ .setPayloadValidators([ |
| 332 this.interfaceType_.validateRequest]); |
| 333 }; |
| 334 |
| 335 Binding.prototype.close = function() { |
| 336 if (!this.isBound()) |
| 337 return; |
| 338 |
| 339 if (this.interfaceEndpointClient_) { |
| 340 this.interfaceEndpointClient_.close(); |
| 341 this.interfaceEndpointClient_ = null; |
| 342 } |
| 343 |
| 344 this.router_.close(); |
| 345 this.router_ = null; |
| 346 this.stub_ = null; |
| 347 }; |
| 348 |
| 349 Binding.prototype.closeWithReason = function(reason) { |
| 350 if (this.interfaceEndpointClient_) { |
| 351 this.interfaceEndpointClient_.close(reason); |
| 352 this.interfaceEndpointClient_ = null; |
| 353 } |
| 354 this.close(); |
| 355 }; |
| 356 |
| 357 Binding.prototype.setConnectionErrorHandler = function(callback) { |
| 358 if (!this.isBound()) { |
| 359 throw new Error("Cannot set connection error handler if not bound."); |
| 360 } |
| 361 this.interfaceEndpointClient_.setConnectionErrorHandler(callback); |
| 362 }; |
| 363 |
| 364 Binding.prototype.unbind = function() { |
| 365 if (!this.isBound()) |
| 366 return new mojo.InterfaceRequest(null); |
| 367 |
| 368 var result = new mojo.InterfaceRequest(this.router_.connector_.handle_); |
| 369 this.router_.connector_.handle_ = null; |
| 370 this.close(); |
| 371 return result; |
| 372 }; |
| 373 |
| 374 // --------------------------------------------------------------------------- |
| 375 |
| 376 function BindingSetEntry(bindingSet, interfaceType, bindingType, impl, |
| 377 requestOrHandle, bindingId) { |
| 378 this.bindingSet_ = bindingSet; |
| 379 this.bindingId_ = bindingId; |
| 380 this.binding_ = new bindingType(interfaceType, impl, |
| 381 requestOrHandle); |
| 382 |
| 383 this.binding_.setConnectionErrorHandler(function(reason) { |
| 384 this.bindingSet_.onConnectionError(bindingId, reason); |
| 385 }.bind(this)); |
| 386 } |
| 387 |
| 388 BindingSetEntry.prototype.close = function() { |
| 389 this.binding_.close(); |
| 390 }; |
| 391 |
| 392 function BindingSet(interfaceType) { |
| 393 this.interfaceType_ = interfaceType; |
| 394 this.nextBindingId_ = 0; |
| 395 this.bindings_ = new Map(); |
| 396 this.errorHandler_ = null; |
| 397 this.bindingType_ = Binding; |
| 398 } |
| 399 |
| 400 BindingSet.prototype.isEmpty = function() { |
| 401 return this.bindings_.size == 0; |
| 402 }; |
| 403 |
| 404 BindingSet.prototype.addBinding = function(impl, requestOrHandle) { |
| 405 this.bindings_.set( |
| 406 this.nextBindingId_, |
| 407 new BindingSetEntry(this, this.interfaceType_, this.bindingType_, impl, |
| 408 requestOrHandle, this.nextBindingId_)); |
| 409 ++this.nextBindingId_; |
| 410 }; |
| 411 |
| 412 BindingSet.prototype.closeAllBindings = function() { |
| 413 for (var entry of this.bindings_.values()) |
| 414 entry.close(); |
| 415 this.bindings_.clear(); |
| 416 }; |
| 417 |
| 418 BindingSet.prototype.setConnectionErrorHandler = function(callback) { |
| 419 this.errorHandler_ = callback; |
| 420 }; |
| 421 |
| 422 BindingSet.prototype.onConnectionError = function(bindingId, reason) { |
| 423 this.bindings_.delete(bindingId); |
| 424 |
| 425 if (this.errorHandler_) |
| 426 this.errorHandler_(reason); |
| 427 }; |
| 428 |
| 429 // --------------------------------------------------------------------------- |
| 430 |
| 431 // Operations used to setup/configure an associated interface pointer. |
| 432 // Exposed as |ptr| field of generated associated interface pointer classes. |
| 433 // |associatedPtrInfo| could be omitted and passed into bind() later. |
| 434 // |
| 435 // Example: |
| 436 // // IntegerSenderImpl implements mojom.IntegerSender |
| 437 // function IntegerSenderImpl() { ... } |
| 438 // IntegerSenderImpl.prototype.echo = function() { ... } |
| 439 // |
| 440 // // IntegerSenderConnectionImpl implements mojom.IntegerSenderConnection |
| 441 // function IntegerSenderConnectionImpl() { |
| 442 // this.senderBinding_ = null; |
| 443 // } |
| 444 // IntegerSenderConnectionImpl.prototype.getSender = function( |
| 445 // associatedRequest) { |
| 446 // this.senderBinding_ = new AssociatedBinding(mojom.IntegerSender, |
| 447 // new IntegerSenderImpl(), |
| 448 // associatedRequest); |
| 449 // } |
| 450 // |
| 451 // var integerSenderConnection = new mojom.IntegerSenderConnectionPtr(); |
| 452 // var integerSenderConnectionBinding = new Binding( |
| 453 // mojom.IntegerSenderConnection, |
| 454 // new IntegerSenderConnectionImpl(), |
| 455 // mojo.makeRequest(integerSenderConnection)); |
| 456 // |
| 457 // // A locally-created associated interface pointer can only be used to |
| 458 // // make calls when the corresponding associated request is sent over |
| 459 // // another interface (either the master interface or another |
| 460 // // associated interface). |
| 461 // var associatedInterfacePtrInfo = new AssociatedInterfacePtrInfo(); |
| 462 // var associatedRequest = makeRequest(interfacePtrInfo); |
| 463 // |
| 464 // integerSenderConnection.getSender(associatedRequest); |
| 465 // |
| 466 // // Create an associated interface and bind the associated handle. |
| 467 // var integerSender = new mojom.AssociatedIntegerSenderPtr(); |
| 468 // integerSender.ptr.bind(associatedInterfacePtrInfo); |
| 469 // integerSender.echo(); |
| 470 |
| 471 function AssociatedInterfacePtrController(interfaceType, associatedPtrInfo) { |
| 472 this.version = 0; |
| 473 |
| 474 this.interfaceType_ = interfaceType; |
| 475 this.interfaceEndpointClient_ = null; |
| 476 this.proxy_ = null; |
| 477 |
| 478 if (associatedPtrInfo) { |
| 479 this.bind(associatedPtrInfo); |
| 480 } |
| 481 } |
| 482 |
| 483 AssociatedInterfacePtrController.prototype.bind = function( |
| 484 associatedPtrInfo) { |
| 485 this.reset(); |
| 486 this.version = associatedPtrInfo.version; |
| 487 |
| 488 this.interfaceEndpointClient_ = new internal.InterfaceEndpointClient( |
| 489 associatedPtrInfo.interfaceEndpointHandle); |
| 490 |
| 491 this.interfaceEndpointClient_ .setPayloadValidators([ |
| 492 this.interfaceType_.validateResponse]); |
| 493 this.proxy_ = new this.interfaceType_.proxyClass( |
| 494 this.interfaceEndpointClient_); |
| 495 }; |
| 496 |
| 497 AssociatedInterfacePtrController.prototype.isBound = function() { |
| 498 return this.interfaceEndpointClient_ !== null; |
| 499 }; |
| 500 |
| 501 AssociatedInterfacePtrController.prototype.reset = function() { |
| 502 this.version = 0; |
| 503 if (this.interfaceEndpointClient_) { |
| 504 this.interfaceEndpointClient_.close(); |
| 505 this.interfaceEndpointClient_ = null; |
| 506 } |
| 507 if (this.proxy_) { |
| 508 this.proxy_ = null; |
| 509 } |
| 510 }; |
| 511 |
| 512 AssociatedInterfacePtrController.prototype.resetWithReason = function( |
| 513 reason) { |
| 514 if (this.isBound()) { |
| 515 this.interfaceEndpointClient_.close(reason); |
| 516 this.interfaceEndpointClient_ = null; |
| 517 } |
| 518 this.reset(); |
| 519 }; |
| 520 |
| 521 // Indicates whether an error has been encountered. If true, method calls |
| 522 // on this interface will be dropped (and may already have been dropped). |
| 523 AssociatedInterfacePtrController.prototype.getEncounteredError = function() { |
| 524 return this.interfaceEndpointClient_ ? |
| 525 this.interfaceEndpointClient_.getEncounteredError() : false; |
| 526 }; |
| 527 |
| 528 AssociatedInterfacePtrController.prototype.setConnectionErrorHandler = |
| 529 function(callback) { |
| 530 if (!this.isBound()) { |
| 531 throw new Error("Cannot set connection error handler if not bound."); |
| 532 } |
| 533 |
| 534 this.interfaceEndpointClient_.setConnectionErrorHandler(callback); |
| 535 }; |
| 536 |
| 537 AssociatedInterfacePtrController.prototype.passInterface = function() { |
| 538 if (!this.isBound()) { |
| 539 return new mojo.AssociatedInterfacePtrInfo(null); |
| 540 } |
| 541 |
| 542 var result = new mojo.AssociatedInterfacePtrInfo( |
| 543 this.interfaceEndpointClient_.passHandle(), this.version); |
| 544 this.reset(); |
| 545 return result; |
| 546 }; |
| 547 |
| 548 AssociatedInterfacePtrController.prototype.getProxy = function() { |
| 549 return this.proxy_; |
| 550 }; |
| 551 |
| 552 AssociatedInterfacePtrController.prototype.queryVersion = function() { |
| 553 function onQueryVersion(version) { |
| 554 this.version = version; |
| 555 return version; |
| 556 } |
| 557 |
| 558 return this.interfaceEndpointClient_.queryVersion().then( |
| 559 onQueryVersion.bind(this)); |
| 560 }; |
| 561 |
| 562 AssociatedInterfacePtrController.prototype.requireVersion = function( |
| 563 version) { |
| 564 if (this.version >= version) { |
| 565 return; |
| 566 } |
| 567 this.version = version; |
| 568 this.interfaceEndpointClient_.requireVersion(version); |
| 569 }; |
| 570 |
| 571 // --------------------------------------------------------------------------- |
| 572 |
| 573 // |associatedInterfaceRequest| could be omitted and passed into bind() |
| 574 // later. |
| 575 function AssociatedBinding(interfaceType, impl, associatedInterfaceRequest) { |
| 576 this.interfaceType_ = interfaceType; |
| 577 this.impl_ = impl; |
| 578 this.interfaceEndpointClient_ = null; |
| 579 this.stub_ = null; |
| 580 |
| 581 if (associatedInterfaceRequest) { |
| 582 this.bind(associatedInterfaceRequest); |
| 583 } |
| 584 } |
| 585 |
| 586 AssociatedBinding.prototype.isBound = function() { |
| 587 return this.interfaceEndpointClient_ !== null; |
| 588 }; |
| 589 |
| 590 AssociatedBinding.prototype.bind = function(associatedInterfaceRequest) { |
| 591 this.close(); |
| 592 |
| 593 this.stub_ = new this.interfaceType_.stubClass(this.impl_); |
| 594 this.interfaceEndpointClient_ = new internal.InterfaceEndpointClient( |
| 595 associatedInterfaceRequest.interfaceEndpointHandle, this.stub_, |
| 596 this.interfaceType_.kVersion); |
| 597 |
| 598 this.interfaceEndpointClient_ .setPayloadValidators([ |
| 599 this.interfaceType_.validateRequest]); |
| 600 }; |
| 601 |
| 602 |
| 603 AssociatedBinding.prototype.close = function() { |
| 604 if (!this.isBound()) { |
| 605 return; |
| 606 } |
| 607 |
| 608 if (this.interfaceEndpointClient_) { |
| 609 this.interfaceEndpointClient_.close(); |
| 610 this.interfaceEndpointClient_ = null; |
| 611 } |
| 612 |
| 613 this.stub_ = null; |
| 614 }; |
| 615 |
| 616 AssociatedBinding.prototype.closeWithReason = function(reason) { |
| 617 if (this.interfaceEndpointClient_) { |
| 618 this.interfaceEndpointClient_.close(reason); |
| 619 this.interfaceEndpointClient_ = null; |
| 620 } |
| 621 this.close(); |
| 622 }; |
| 623 |
| 624 AssociatedBinding.prototype.setConnectionErrorHandler = function(callback) { |
| 625 if (!this.isBound()) { |
| 626 throw new Error("Cannot set connection error handler if not bound."); |
| 627 } |
| 628 this.interfaceEndpointClient_.setConnectionErrorHandler(callback); |
| 629 }; |
| 630 |
| 631 AssociatedBinding.prototype.unbind = function() { |
| 632 if (!this.isBound()) { |
| 633 return new mojo.AssociatedInterfaceRequest(null); |
| 634 } |
| 635 |
| 636 var result = new mojo.AssociatedInterfaceRequest( |
| 637 this.interfaceEndpointClient_.passHandle()); |
| 638 this.close(); |
| 639 return result; |
| 640 }; |
| 641 |
| 642 // --------------------------------------------------------------------------- |
| 643 |
| 644 function AssociatedBindingSet(interfaceType) { |
| 645 mojo.BindingSet.call(this, interfaceType); |
| 646 this.bindingType_ = AssociatedBinding; |
| 647 } |
| 648 |
| 649 AssociatedBindingSet.prototype = Object.create(BindingSet.prototype); |
| 650 AssociatedBindingSet.prototype.constructor = AssociatedBindingSet; |
| 651 |
| 652 mojo.makeRequest = makeRequest; |
| 653 mojo.AssociatedInterfacePtrController = AssociatedInterfacePtrController; |
| 654 mojo.AssociatedBinding = AssociatedBinding; |
| 655 mojo.AssociatedBindingSet = AssociatedBindingSet; |
| 656 mojo.Binding = Binding; |
| 657 mojo.BindingSet = BindingSet; |
| 658 mojo.InterfacePtrController = InterfacePtrController; |
| 659 })(); |
| 660 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 661 // Use of this source code is governed by a BSD-style license that can be |
| 662 // found in the LICENSE file. |
| 663 |
| 664 (function() { |
| 665 var internal = mojo.internal; |
| 666 |
| 667 var kHostIsLittleEndian = (function () { |
| 668 var endianArrayBuffer = new ArrayBuffer(2); |
| 669 var endianUint8Array = new Uint8Array(endianArrayBuffer); |
| 670 var endianUint16Array = new Uint16Array(endianArrayBuffer); |
| 671 endianUint16Array[0] = 1; |
| 672 return endianUint8Array[0] == 1; |
| 673 })(); |
| 674 |
| 675 var kHighWordMultiplier = 0x100000000; |
| 676 |
| 677 function Buffer(sizeOrArrayBuffer) { |
| 678 if (sizeOrArrayBuffer instanceof ArrayBuffer) |
| 679 this.arrayBuffer = sizeOrArrayBuffer; |
| 680 else |
| 681 this.arrayBuffer = new ArrayBuffer(sizeOrArrayBuffer); |
| 682 |
| 683 this.dataView = new DataView(this.arrayBuffer); |
| 684 this.next = 0; |
| 685 } |
| 686 |
| 687 Object.defineProperty(Buffer.prototype, "byteLength", { |
| 688 get: function() { return this.arrayBuffer.byteLength; } |
| 689 }); |
| 690 |
| 691 Buffer.prototype.alloc = function(size) { |
| 692 var pointer = this.next; |
| 693 this.next += size; |
| 694 if (this.next > this.byteLength) { |
| 695 var newSize = (1.5 * (this.byteLength + size)) | 0; |
| 696 this.grow(newSize); |
| 697 } |
| 698 return pointer; |
| 699 }; |
| 700 |
| 701 function copyArrayBuffer(dstArrayBuffer, srcArrayBuffer) { |
| 702 (new Uint8Array(dstArrayBuffer)).set(new Uint8Array(srcArrayBuffer)); |
| 703 } |
| 704 |
| 705 Buffer.prototype.grow = function(size) { |
| 706 var newArrayBuffer = new ArrayBuffer(size); |
| 707 copyArrayBuffer(newArrayBuffer, this.arrayBuffer); |
| 708 this.arrayBuffer = newArrayBuffer; |
| 709 this.dataView = new DataView(this.arrayBuffer); |
| 710 }; |
| 711 |
| 712 Buffer.prototype.trim = function() { |
| 713 this.arrayBuffer = this.arrayBuffer.slice(0, this.next); |
| 714 this.dataView = new DataView(this.arrayBuffer); |
| 715 }; |
| 716 |
| 717 Buffer.prototype.getUint8 = function(offset) { |
| 718 return this.dataView.getUint8(offset); |
| 719 } |
| 720 Buffer.prototype.getUint16 = function(offset) { |
| 721 return this.dataView.getUint16(offset, kHostIsLittleEndian); |
| 722 } |
| 723 Buffer.prototype.getUint32 = function(offset) { |
| 724 return this.dataView.getUint32(offset, kHostIsLittleEndian); |
| 725 } |
| 726 Buffer.prototype.getUint64 = function(offset) { |
| 727 var lo, hi; |
| 728 if (kHostIsLittleEndian) { |
| 729 lo = this.dataView.getUint32(offset, kHostIsLittleEndian); |
| 730 hi = this.dataView.getUint32(offset + 4, kHostIsLittleEndian); |
| 731 } else { |
| 732 hi = this.dataView.getUint32(offset, kHostIsLittleEndian); |
| 733 lo = this.dataView.getUint32(offset + 4, kHostIsLittleEndian); |
| 734 } |
| 735 return lo + hi * kHighWordMultiplier; |
| 736 } |
| 737 |
| 738 Buffer.prototype.getInt8 = function(offset) { |
| 739 return this.dataView.getInt8(offset); |
| 740 } |
| 741 Buffer.prototype.getInt16 = function(offset) { |
| 742 return this.dataView.getInt16(offset, kHostIsLittleEndian); |
| 743 } |
| 744 Buffer.prototype.getInt32 = function(offset) { |
| 745 return this.dataView.getInt32(offset, kHostIsLittleEndian); |
| 746 } |
| 747 Buffer.prototype.getInt64 = function(offset) { |
| 748 var lo, hi; |
| 749 if (kHostIsLittleEndian) { |
| 750 lo = this.dataView.getUint32(offset, kHostIsLittleEndian); |
| 751 hi = this.dataView.getInt32(offset + 4, kHostIsLittleEndian); |
| 752 } else { |
| 753 hi = this.dataView.getInt32(offset, kHostIsLittleEndian); |
| 754 lo = this.dataView.getUint32(offset + 4, kHostIsLittleEndian); |
| 755 } |
| 756 return lo + hi * kHighWordMultiplier; |
| 757 } |
| 758 |
| 759 Buffer.prototype.getFloat32 = function(offset) { |
| 760 return this.dataView.getFloat32(offset, kHostIsLittleEndian); |
| 761 } |
| 762 Buffer.prototype.getFloat64 = function(offset) { |
| 763 return this.dataView.getFloat64(offset, kHostIsLittleEndian); |
| 764 } |
| 765 |
| 766 Buffer.prototype.setUint8 = function(offset, value) { |
| 767 this.dataView.setUint8(offset, value); |
| 768 } |
| 769 Buffer.prototype.setUint16 = function(offset, value) { |
| 770 this.dataView.setUint16(offset, value, kHostIsLittleEndian); |
| 771 } |
| 772 Buffer.prototype.setUint32 = function(offset, value) { |
| 773 this.dataView.setUint32(offset, value, kHostIsLittleEndian); |
| 774 } |
| 775 Buffer.prototype.setUint64 = function(offset, value) { |
| 776 var hi = (value / kHighWordMultiplier) | 0; |
| 777 if (kHostIsLittleEndian) { |
| 778 this.dataView.setInt32(offset, value, kHostIsLittleEndian); |
| 779 this.dataView.setInt32(offset + 4, hi, kHostIsLittleEndian); |
| 780 } else { |
| 781 this.dataView.setInt32(offset, hi, kHostIsLittleEndian); |
| 782 this.dataView.setInt32(offset + 4, value, kHostIsLittleEndian); |
| 783 } |
| 784 } |
| 785 |
| 786 Buffer.prototype.setInt8 = function(offset, value) { |
| 787 this.dataView.setInt8(offset, value); |
| 788 } |
| 789 Buffer.prototype.setInt16 = function(offset, value) { |
| 790 this.dataView.setInt16(offset, value, kHostIsLittleEndian); |
| 791 } |
| 792 Buffer.prototype.setInt32 = function(offset, value) { |
| 793 this.dataView.setInt32(offset, value, kHostIsLittleEndian); |
| 794 } |
| 795 Buffer.prototype.setInt64 = function(offset, value) { |
| 796 var hi = Math.floor(value / kHighWordMultiplier); |
| 797 if (kHostIsLittleEndian) { |
| 798 this.dataView.setInt32(offset, value, kHostIsLittleEndian); |
| 799 this.dataView.setInt32(offset + 4, hi, kHostIsLittleEndian); |
| 800 } else { |
| 801 this.dataView.setInt32(offset, hi, kHostIsLittleEndian); |
| 802 this.dataView.setInt32(offset + 4, value, kHostIsLittleEndian); |
| 803 } |
| 804 } |
| 805 |
| 806 Buffer.prototype.setFloat32 = function(offset, value) { |
| 807 this.dataView.setFloat32(offset, value, kHostIsLittleEndian); |
| 808 } |
| 809 Buffer.prototype.setFloat64 = function(offset, value) { |
| 810 this.dataView.setFloat64(offset, value, kHostIsLittleEndian); |
| 811 } |
| 812 |
| 813 internal.Buffer = Buffer; |
| 814 })(); |
| 815 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 816 // Use of this source code is governed by a BSD-style license that can be |
| 817 // found in the LICENSE file. |
| 818 |
| 819 (function() { |
| 820 var internal = mojo.internal; |
| 821 |
| 822 var kErrorUnsigned = "Passing negative value to unsigned"; |
| 823 var kErrorArray = "Passing non Array for array type"; |
| 824 var kErrorString = "Passing non String for string type"; |
| 825 var kErrorMap = "Passing non Map for map type"; |
| 826 |
| 827 // Memory ------------------------------------------------------------------- |
| 828 |
| 829 var kAlignment = 8; |
| 830 |
| 831 function align(size) { |
| 832 return size + (kAlignment - (size % kAlignment)) % kAlignment; |
| 833 } |
| 834 |
| 835 function isAligned(offset) { |
| 836 return offset >= 0 && (offset % kAlignment) === 0; |
| 837 } |
| 838 |
| 839 // Constants ---------------------------------------------------------------- |
| 840 |
| 841 var kArrayHeaderSize = 8; |
| 842 var kStructHeaderSize = 8; |
| 843 var kMessageV0HeaderSize = 24; |
| 844 var kMessageV1HeaderSize = 32; |
| 845 var kMessageV2HeaderSize = 48; |
| 846 var kMapStructPayloadSize = 16; |
| 847 |
| 848 var kStructHeaderNumBytesOffset = 0; |
| 849 var kStructHeaderVersionOffset = 4; |
| 850 |
| 851 var kEncodedInvalidHandleValue = 0xFFFFFFFF; |
| 852 |
| 853 // Decoder ------------------------------------------------------------------ |
| 854 |
| 855 function Decoder(buffer, handles, associatedEndpointHandles, base) { |
| 856 this.buffer = buffer; |
| 857 this.handles = handles; |
| 858 this.associatedEndpointHandles = associatedEndpointHandles; |
| 859 this.base = base; |
| 860 this.next = base; |
| 861 } |
| 862 |
| 863 Decoder.prototype.align = function() { |
| 864 this.next = align(this.next); |
| 865 }; |
| 866 |
| 867 Decoder.prototype.skip = function(offset) { |
| 868 this.next += offset; |
| 869 }; |
| 870 |
| 871 Decoder.prototype.readInt8 = function() { |
| 872 var result = this.buffer.getInt8(this.next); |
| 873 this.next += 1; |
| 874 return result; |
| 875 }; |
| 876 |
| 877 Decoder.prototype.readUint8 = function() { |
| 878 var result = this.buffer.getUint8(this.next); |
| 879 this.next += 1; |
| 880 return result; |
| 881 }; |
| 882 |
| 883 Decoder.prototype.readInt16 = function() { |
| 884 var result = this.buffer.getInt16(this.next); |
| 885 this.next += 2; |
| 886 return result; |
| 887 }; |
| 888 |
| 889 Decoder.prototype.readUint16 = function() { |
| 890 var result = this.buffer.getUint16(this.next); |
| 891 this.next += 2; |
| 892 return result; |
| 893 }; |
| 894 |
| 895 Decoder.prototype.readInt32 = function() { |
| 896 var result = this.buffer.getInt32(this.next); |
| 897 this.next += 4; |
| 898 return result; |
| 899 }; |
| 900 |
| 901 Decoder.prototype.readUint32 = function() { |
| 902 var result = this.buffer.getUint32(this.next); |
| 903 this.next += 4; |
| 904 return result; |
| 905 }; |
| 906 |
| 907 Decoder.prototype.readInt64 = function() { |
| 908 var result = this.buffer.getInt64(this.next); |
| 909 this.next += 8; |
| 910 return result; |
| 911 }; |
| 912 |
| 913 Decoder.prototype.readUint64 = function() { |
| 914 var result = this.buffer.getUint64(this.next); |
| 915 this.next += 8; |
| 916 return result; |
| 917 }; |
| 918 |
| 919 Decoder.prototype.readFloat = function() { |
| 920 var result = this.buffer.getFloat32(this.next); |
| 921 this.next += 4; |
| 922 return result; |
| 923 }; |
| 924 |
| 925 Decoder.prototype.readDouble = function() { |
| 926 var result = this.buffer.getFloat64(this.next); |
| 927 this.next += 8; |
| 928 return result; |
| 929 }; |
| 930 |
| 931 Decoder.prototype.decodePointer = function() { |
| 932 // TODO(abarth): To correctly decode a pointer, we need to know the real |
| 933 // base address of the array buffer. |
| 934 var offsetPointer = this.next; |
| 935 var offset = this.readUint64(); |
| 936 if (!offset) |
| 937 return 0; |
| 938 return offsetPointer + offset; |
| 939 }; |
| 940 |
| 941 Decoder.prototype.decodeAndCreateDecoder = function(pointer) { |
| 942 return new Decoder(this.buffer, this.handles, |
| 943 this.associatedEndpointHandles, pointer); |
| 944 }; |
| 945 |
| 946 Decoder.prototype.decodeHandle = function() { |
| 947 return this.handles[this.readUint32()] || null; |
| 948 }; |
| 949 |
| 950 Decoder.prototype.decodeAssociatedEndpointHandle = function() { |
| 951 return this.associatedEndpointHandles[this.readUint32()] || null; |
| 952 }; |
| 953 |
| 954 Decoder.prototype.decodeString = function() { |
| 955 var numberOfBytes = this.readUint32(); |
| 956 var numberOfElements = this.readUint32(); |
| 957 var base = this.next; |
| 958 this.next += numberOfElements; |
| 959 return internal.decodeUtf8String( |
| 960 new Uint8Array(this.buffer.arrayBuffer, base, numberOfElements)); |
| 961 }; |
| 962 |
| 963 Decoder.prototype.decodeArray = function(cls) { |
| 964 var numberOfBytes = this.readUint32(); |
| 965 var numberOfElements = this.readUint32(); |
| 966 var val = new Array(numberOfElements); |
| 967 if (cls === PackedBool) { |
| 968 var byte; |
| 969 for (var i = 0; i < numberOfElements; ++i) { |
| 970 if (i % 8 === 0) |
| 971 byte = this.readUint8(); |
| 972 val[i] = (byte & (1 << i % 8)) ? true : false; |
| 973 } |
| 974 } else { |
| 975 for (var i = 0; i < numberOfElements; ++i) { |
| 976 val[i] = cls.decode(this); |
| 977 } |
| 978 } |
| 979 return val; |
| 980 }; |
| 981 |
| 982 Decoder.prototype.decodeStruct = function(cls) { |
| 983 return cls.decode(this); |
| 984 }; |
| 985 |
| 986 Decoder.prototype.decodeStructPointer = function(cls) { |
| 987 var pointer = this.decodePointer(); |
| 988 if (!pointer) { |
| 989 return null; |
| 990 } |
| 991 return cls.decode(this.decodeAndCreateDecoder(pointer)); |
| 992 }; |
| 993 |
| 994 Decoder.prototype.decodeArrayPointer = function(cls) { |
| 995 var pointer = this.decodePointer(); |
| 996 if (!pointer) { |
| 997 return null; |
| 998 } |
| 999 return this.decodeAndCreateDecoder(pointer).decodeArray(cls); |
| 1000 }; |
| 1001 |
| 1002 Decoder.prototype.decodeStringPointer = function() { |
| 1003 var pointer = this.decodePointer(); |
| 1004 if (!pointer) { |
| 1005 return null; |
| 1006 } |
| 1007 return this.decodeAndCreateDecoder(pointer).decodeString(); |
| 1008 }; |
| 1009 |
| 1010 Decoder.prototype.decodeMap = function(keyClass, valueClass) { |
| 1011 this.skip(4); // numberOfBytes |
| 1012 this.skip(4); // version |
| 1013 var keys = this.decodeArrayPointer(keyClass); |
| 1014 var values = this.decodeArrayPointer(valueClass); |
| 1015 var val = new Map(); |
| 1016 for (var i = 0; i < keys.length; i++) |
| 1017 val.set(keys[i], values[i]); |
| 1018 return val; |
| 1019 }; |
| 1020 |
| 1021 Decoder.prototype.decodeMapPointer = function(keyClass, valueClass) { |
| 1022 var pointer = this.decodePointer(); |
| 1023 if (!pointer) { |
| 1024 return null; |
| 1025 } |
| 1026 var decoder = this.decodeAndCreateDecoder(pointer); |
| 1027 return decoder.decodeMap(keyClass, valueClass); |
| 1028 }; |
| 1029 |
| 1030 // Encoder ------------------------------------------------------------------ |
| 1031 |
| 1032 function Encoder(buffer, handles, associatedEndpointHandles, base) { |
| 1033 this.buffer = buffer; |
| 1034 this.handles = handles; |
| 1035 this.associatedEndpointHandles = associatedEndpointHandles; |
| 1036 this.base = base; |
| 1037 this.next = base; |
| 1038 } |
| 1039 |
| 1040 Encoder.prototype.align = function() { |
| 1041 this.next = align(this.next); |
| 1042 }; |
| 1043 |
| 1044 Encoder.prototype.skip = function(offset) { |
| 1045 this.next += offset; |
| 1046 }; |
| 1047 |
| 1048 Encoder.prototype.writeInt8 = function(val) { |
| 1049 this.buffer.setInt8(this.next, val); |
| 1050 this.next += 1; |
| 1051 }; |
| 1052 |
| 1053 Encoder.prototype.writeUint8 = function(val) { |
| 1054 if (val < 0) { |
| 1055 throw new Error(kErrorUnsigned); |
| 1056 } |
| 1057 this.buffer.setUint8(this.next, val); |
| 1058 this.next += 1; |
| 1059 }; |
| 1060 |
| 1061 Encoder.prototype.writeInt16 = function(val) { |
| 1062 this.buffer.setInt16(this.next, val); |
| 1063 this.next += 2; |
| 1064 }; |
| 1065 |
| 1066 Encoder.prototype.writeUint16 = function(val) { |
| 1067 if (val < 0) { |
| 1068 throw new Error(kErrorUnsigned); |
| 1069 } |
| 1070 this.buffer.setUint16(this.next, val); |
| 1071 this.next += 2; |
| 1072 }; |
| 1073 |
| 1074 Encoder.prototype.writeInt32 = function(val) { |
| 1075 this.buffer.setInt32(this.next, val); |
| 1076 this.next += 4; |
| 1077 }; |
| 1078 |
| 1079 Encoder.prototype.writeUint32 = function(val) { |
| 1080 if (val < 0) { |
| 1081 throw new Error(kErrorUnsigned); |
| 1082 } |
| 1083 this.buffer.setUint32(this.next, val); |
| 1084 this.next += 4; |
| 1085 }; |
| 1086 |
| 1087 Encoder.prototype.writeInt64 = function(val) { |
| 1088 this.buffer.setInt64(this.next, val); |
| 1089 this.next += 8; |
| 1090 }; |
| 1091 |
| 1092 Encoder.prototype.writeUint64 = function(val) { |
| 1093 if (val < 0) { |
| 1094 throw new Error(kErrorUnsigned); |
| 1095 } |
| 1096 this.buffer.setUint64(this.next, val); |
| 1097 this.next += 8; |
| 1098 }; |
| 1099 |
| 1100 Encoder.prototype.writeFloat = function(val) { |
| 1101 this.buffer.setFloat32(this.next, val); |
| 1102 this.next += 4; |
| 1103 }; |
| 1104 |
| 1105 Encoder.prototype.writeDouble = function(val) { |
| 1106 this.buffer.setFloat64(this.next, val); |
| 1107 this.next += 8; |
| 1108 }; |
| 1109 |
| 1110 Encoder.prototype.encodePointer = function(pointer) { |
| 1111 if (!pointer) |
| 1112 return this.writeUint64(0); |
| 1113 // TODO(abarth): To correctly encode a pointer, we need to know the real |
| 1114 // base address of the array buffer. |
| 1115 var offset = pointer - this.next; |
| 1116 this.writeUint64(offset); |
| 1117 }; |
| 1118 |
| 1119 Encoder.prototype.createAndEncodeEncoder = function(size) { |
| 1120 var pointer = this.buffer.alloc(align(size)); |
| 1121 this.encodePointer(pointer); |
| 1122 return new Encoder(this.buffer, this.handles, |
| 1123 this.associatedEndpointHandles, pointer); |
| 1124 }; |
| 1125 |
| 1126 Encoder.prototype.encodeHandle = function(handle) { |
| 1127 if (handle) { |
| 1128 this.handles.push(handle); |
| 1129 this.writeUint32(this.handles.length - 1); |
| 1130 } else { |
| 1131 this.writeUint32(kEncodedInvalidHandleValue); |
| 1132 } |
| 1133 }; |
| 1134 |
| 1135 Encoder.prototype.encodeAssociatedEndpointHandle = function(endpointHandle) { |
| 1136 if (endpointHandle) { |
| 1137 this.associatedEndpointHandles.push(endpointHandle); |
| 1138 this.writeUint32(this.associatedEndpointHandles.length - 1); |
| 1139 } else { |
| 1140 this.writeUint32(kEncodedInvalidHandleValue); |
| 1141 } |
| 1142 }; |
| 1143 |
| 1144 Encoder.prototype.encodeString = function(val) { |
| 1145 var base = this.next + kArrayHeaderSize; |
| 1146 var numberOfElements = internal.encodeUtf8String( |
| 1147 val, new Uint8Array(this.buffer.arrayBuffer, base)); |
| 1148 var numberOfBytes = kArrayHeaderSize + numberOfElements; |
| 1149 this.writeUint32(numberOfBytes); |
| 1150 this.writeUint32(numberOfElements); |
| 1151 this.next += numberOfElements; |
| 1152 }; |
| 1153 |
| 1154 Encoder.prototype.encodeArray = |
| 1155 function(cls, val, numberOfElements, encodedSize) { |
| 1156 if (numberOfElements === undefined) |
| 1157 numberOfElements = val.length; |
| 1158 if (encodedSize === undefined) |
| 1159 encodedSize = kArrayHeaderSize + cls.encodedSize * numberOfElements; |
| 1160 |
| 1161 this.writeUint32(encodedSize); |
| 1162 this.writeUint32(numberOfElements); |
| 1163 |
| 1164 if (cls === PackedBool) { |
| 1165 var byte = 0; |
| 1166 for (i = 0; i < numberOfElements; ++i) { |
| 1167 if (val[i]) |
| 1168 byte |= (1 << i % 8); |
| 1169 if (i % 8 === 7 || i == numberOfElements - 1) { |
| 1170 Uint8.encode(this, byte); |
| 1171 byte = 0; |
| 1172 } |
| 1173 } |
| 1174 } else { |
| 1175 for (var i = 0; i < numberOfElements; ++i) |
| 1176 cls.encode(this, val[i]); |
| 1177 } |
| 1178 }; |
| 1179 |
| 1180 Encoder.prototype.encodeStruct = function(cls, val) { |
| 1181 return cls.encode(this, val); |
| 1182 }; |
| 1183 |
| 1184 Encoder.prototype.encodeStructPointer = function(cls, val) { |
| 1185 if (val == null) { |
| 1186 // Also handles undefined, since undefined == null. |
| 1187 this.encodePointer(val); |
| 1188 return; |
| 1189 } |
| 1190 var encoder = this.createAndEncodeEncoder(cls.encodedSize); |
| 1191 cls.encode(encoder, val); |
| 1192 }; |
| 1193 |
| 1194 Encoder.prototype.encodeArrayPointer = function(cls, val) { |
| 1195 if (val == null) { |
| 1196 // Also handles undefined, since undefined == null. |
| 1197 this.encodePointer(val); |
| 1198 return; |
| 1199 } |
| 1200 |
| 1201 var numberOfElements = val.length; |
| 1202 if (!Number.isSafeInteger(numberOfElements) || numberOfElements < 0) |
| 1203 throw new Error(kErrorArray); |
| 1204 |
| 1205 var encodedSize = kArrayHeaderSize + ((cls === PackedBool) ? |
| 1206 Math.ceil(numberOfElements / 8) : cls.encodedSize * numberOfElements); |
| 1207 var encoder = this.createAndEncodeEncoder(encodedSize); |
| 1208 encoder.encodeArray(cls, val, numberOfElements, encodedSize); |
| 1209 }; |
| 1210 |
| 1211 Encoder.prototype.encodeStringPointer = function(val) { |
| 1212 if (val == null) { |
| 1213 // Also handles undefined, since undefined == null. |
| 1214 this.encodePointer(val); |
| 1215 return; |
| 1216 } |
| 1217 // Only accepts string primivites, not String Objects like new String("foo") |
| 1218 if (typeof(val) !== "string") { |
| 1219 throw new Error(kErrorString); |
| 1220 } |
| 1221 var encodedSize = kArrayHeaderSize + internal.utf8Length(val); |
| 1222 var encoder = this.createAndEncodeEncoder(encodedSize); |
| 1223 encoder.encodeString(val); |
| 1224 }; |
| 1225 |
| 1226 Encoder.prototype.encodeMap = function(keyClass, valueClass, val) { |
| 1227 var keys = new Array(val.size); |
| 1228 var values = new Array(val.size); |
| 1229 var i = 0; |
| 1230 val.forEach(function(value, key) { |
| 1231 values[i] = value; |
| 1232 keys[i++] = key; |
| 1233 }); |
| 1234 this.writeUint32(kStructHeaderSize + kMapStructPayloadSize); |
| 1235 this.writeUint32(0); // version |
| 1236 this.encodeArrayPointer(keyClass, keys); |
| 1237 this.encodeArrayPointer(valueClass, values); |
| 1238 } |
| 1239 |
| 1240 Encoder.prototype.encodeMapPointer = function(keyClass, valueClass, val) { |
| 1241 if (val == null) { |
| 1242 // Also handles undefined, since undefined == null. |
| 1243 this.encodePointer(val); |
| 1244 return; |
| 1245 } |
| 1246 if (!(val instanceof Map)) { |
| 1247 throw new Error(kErrorMap); |
| 1248 } |
| 1249 var encodedSize = kStructHeaderSize + kMapStructPayloadSize; |
| 1250 var encoder = this.createAndEncodeEncoder(encodedSize); |
| 1251 encoder.encodeMap(keyClass, valueClass, val); |
| 1252 }; |
| 1253 |
| 1254 // Message ------------------------------------------------------------------ |
| 1255 |
| 1256 var kMessageInterfaceIdOffset = kStructHeaderSize; |
| 1257 var kMessageNameOffset = kMessageInterfaceIdOffset + 4; |
| 1258 var kMessageFlagsOffset = kMessageNameOffset + 4; |
| 1259 var kMessageRequestIDOffset = kMessageFlagsOffset + 8; |
| 1260 var kMessagePayloadInterfaceIdsPointerOffset = kMessageV2HeaderSize - 8; |
| 1261 |
| 1262 var kMessageExpectsResponse = 1 << 0; |
| 1263 var kMessageIsResponse = 1 << 1; |
| 1264 |
| 1265 function Message(buffer, handles, associatedEndpointHandles) { |
| 1266 if (associatedEndpointHandles === undefined) { |
| 1267 associatedEndpointHandles = []; |
| 1268 } |
| 1269 |
| 1270 this.buffer = buffer; |
| 1271 this.handles = handles; |
| 1272 this.associatedEndpointHandles = associatedEndpointHandles; |
| 1273 } |
| 1274 |
| 1275 Message.prototype.getHeaderNumBytes = function() { |
| 1276 return this.buffer.getUint32(kStructHeaderNumBytesOffset); |
| 1277 }; |
| 1278 |
| 1279 Message.prototype.getHeaderVersion = function() { |
| 1280 return this.buffer.getUint32(kStructHeaderVersionOffset); |
| 1281 }; |
| 1282 |
| 1283 Message.prototype.getName = function() { |
| 1284 return this.buffer.getUint32(kMessageNameOffset); |
| 1285 }; |
| 1286 |
| 1287 Message.prototype.getFlags = function() { |
| 1288 return this.buffer.getUint32(kMessageFlagsOffset); |
| 1289 }; |
| 1290 |
| 1291 Message.prototype.getInterfaceId = function() { |
| 1292 return this.buffer.getUint32(kMessageInterfaceIdOffset); |
| 1293 }; |
| 1294 |
| 1295 Message.prototype.getPayloadInterfaceIds = function() { |
| 1296 if (this.getHeaderVersion() < 2) { |
| 1297 return null; |
| 1298 } |
| 1299 |
| 1300 var decoder = new Decoder(this.buffer, this.handles, |
| 1301 this.associatedEndpointHandles, |
| 1302 kMessagePayloadInterfaceIdsPointerOffset); |
| 1303 var payloadInterfaceIds = decoder.decodeArrayPointer(Uint32); |
| 1304 return payloadInterfaceIds; |
| 1305 }; |
| 1306 |
| 1307 Message.prototype.isResponse = function() { |
| 1308 return (this.getFlags() & kMessageIsResponse) != 0; |
| 1309 }; |
| 1310 |
| 1311 Message.prototype.expectsResponse = function() { |
| 1312 return (this.getFlags() & kMessageExpectsResponse) != 0; |
| 1313 }; |
| 1314 |
| 1315 Message.prototype.setRequestID = function(requestID) { |
| 1316 // TODO(darin): Verify that space was reserved for this field! |
| 1317 this.buffer.setUint64(kMessageRequestIDOffset, requestID); |
| 1318 }; |
| 1319 |
| 1320 Message.prototype.setInterfaceId = function(interfaceId) { |
| 1321 this.buffer.setUint32(kMessageInterfaceIdOffset, interfaceId); |
| 1322 }; |
| 1323 |
| 1324 Message.prototype.setPayloadInterfaceIds_ = function(payloadInterfaceIds) { |
| 1325 if (this.getHeaderVersion() < 2) { |
| 1326 throw new Error( |
| 1327 "Version of message does not support payload interface ids"); |
| 1328 } |
| 1329 |
| 1330 var decoder = new Decoder(this.buffer, this.handles, |
| 1331 this.associatedEndpointHandles, |
| 1332 kMessagePayloadInterfaceIdsPointerOffset); |
| 1333 var payloadInterfaceIdsOffset = decoder.decodePointer(); |
| 1334 var encoder = new Encoder(this.buffer, this.handles, |
| 1335 this.associatedEndpointHandles, |
| 1336 payloadInterfaceIdsOffset); |
| 1337 encoder.encodeArray(Uint32, payloadInterfaceIds); |
| 1338 }; |
| 1339 |
| 1340 Message.prototype.serializeAssociatedEndpointHandles = function( |
| 1341 associatedGroupController) { |
| 1342 if (this.associatedEndpointHandles.length > 0) { |
| 1343 if (this.getHeaderVersion() < 2) { |
| 1344 throw new Error( |
| 1345 "Version of message does not support associated endpoint handles"); |
| 1346 } |
| 1347 |
| 1348 var data = []; |
| 1349 for (var i = 0; i < this.associatedEndpointHandles.length; i++) { |
| 1350 var handle = this.associatedEndpointHandles[i]; |
| 1351 data.push(associatedGroupController.associateInterface(handle)); |
| 1352 } |
| 1353 this.associatedEndpointHandles = []; |
| 1354 this.setPayloadInterfaceIds_(data); |
| 1355 } |
| 1356 }; |
| 1357 |
| 1358 Message.prototype.deserializeAssociatedEndpointHandles = function( |
| 1359 associatedGroupController) { |
| 1360 if (this.getHeaderVersion() < 2) { |
| 1361 return true; |
| 1362 } |
| 1363 |
| 1364 this.associatedEndpointHandles = []; |
| 1365 var ids = this.getPayloadInterfaceIds(); |
| 1366 |
| 1367 var result = true; |
| 1368 for (var i = 0; i < ids.length; i++) { |
| 1369 var handle = associatedGroupController.createLocalEndpointHandle(ids[i]); |
| 1370 if (internal.isValidInterfaceId(ids[i]) && !handle.isValid()) { |
| 1371 // |ids[i]| itself is valid but handle creation failed. In that case, |
| 1372 // mark deserialization as failed but continue to deserialize the |
| 1373 // rest of handles. |
| 1374 result = false; |
| 1375 } |
| 1376 this.associatedEndpointHandles.push(handle); |
| 1377 ids[i] = internal.kInvalidInterfaceId; |
| 1378 } |
| 1379 |
| 1380 this.setPayloadInterfaceIds_(ids); |
| 1381 return result; |
| 1382 }; |
| 1383 |
| 1384 |
| 1385 // MessageV0Builder --------------------------------------------------------- |
| 1386 |
| 1387 function MessageV0Builder(messageName, payloadSize) { |
| 1388 // Currently, we don't compute the payload size correctly ahead of time. |
| 1389 // Instead, we resize the buffer at the end. |
| 1390 var numberOfBytes = kMessageV0HeaderSize + payloadSize; |
| 1391 this.buffer = new internal.Buffer(numberOfBytes); |
| 1392 this.handles = []; |
| 1393 var encoder = this.createEncoder(kMessageV0HeaderSize); |
| 1394 encoder.writeUint32(kMessageV0HeaderSize); |
| 1395 encoder.writeUint32(0); // version. |
| 1396 encoder.writeUint32(0); // interface ID. |
| 1397 encoder.writeUint32(messageName); |
| 1398 encoder.writeUint32(0); // flags. |
| 1399 encoder.writeUint32(0); // padding. |
| 1400 } |
| 1401 |
| 1402 MessageV0Builder.prototype.createEncoder = function(size) { |
| 1403 var pointer = this.buffer.alloc(size); |
| 1404 return new Encoder(this.buffer, this.handles, [], pointer); |
| 1405 }; |
| 1406 |
| 1407 MessageV0Builder.prototype.encodeStruct = function(cls, val) { |
| 1408 cls.encode(this.createEncoder(cls.encodedSize), val); |
| 1409 }; |
| 1410 |
| 1411 MessageV0Builder.prototype.finish = function() { |
| 1412 // TODO(abarth): Rather than resizing the buffer at the end, we could |
| 1413 // compute the size we need ahead of time, like we do in C++. |
| 1414 this.buffer.trim(); |
| 1415 var message = new Message(this.buffer, this.handles); |
| 1416 this.buffer = null; |
| 1417 this.handles = null; |
| 1418 this.encoder = null; |
| 1419 return message; |
| 1420 }; |
| 1421 |
| 1422 // MessageV1Builder ----------------------------------------------- |
| 1423 |
| 1424 function MessageV1Builder(messageName, payloadSize, flags, |
| 1425 requestID) { |
| 1426 // Currently, we don't compute the payload size correctly ahead of time. |
| 1427 // Instead, we resize the buffer at the end. |
| 1428 var numberOfBytes = kMessageV1HeaderSize + payloadSize; |
| 1429 this.buffer = new internal.Buffer(numberOfBytes); |
| 1430 this.handles = []; |
| 1431 var encoder = this.createEncoder(kMessageV1HeaderSize); |
| 1432 encoder.writeUint32(kMessageV1HeaderSize); |
| 1433 encoder.writeUint32(1); // version. |
| 1434 encoder.writeUint32(0); // interface ID. |
| 1435 encoder.writeUint32(messageName); |
| 1436 encoder.writeUint32(flags); |
| 1437 encoder.writeUint32(0); // padding. |
| 1438 encoder.writeUint64(requestID); |
| 1439 } |
| 1440 |
| 1441 MessageV1Builder.prototype = |
| 1442 Object.create(MessageV0Builder.prototype); |
| 1443 |
| 1444 MessageV1Builder.prototype.constructor = |
| 1445 MessageV1Builder; |
| 1446 |
| 1447 // MessageV2 ----------------------------------------------- |
| 1448 |
| 1449 function MessageV2Builder(messageName, payloadSize, flags, requestID) { |
| 1450 // Currently, we don't compute the payload size correctly ahead of time. |
| 1451 // Instead, we resize the buffer at the end. |
| 1452 var numberOfBytes = kMessageV2HeaderSize + payloadSize; |
| 1453 this.buffer = new internal.Buffer(numberOfBytes); |
| 1454 this.handles = []; |
| 1455 |
| 1456 this.payload = null; |
| 1457 this.associatedEndpointHandles = []; |
| 1458 |
| 1459 this.encoder = this.createEncoder(kMessageV2HeaderSize); |
| 1460 this.encoder.writeUint32(kMessageV2HeaderSize); |
| 1461 this.encoder.writeUint32(2); // version. |
| 1462 // Gets set to an appropriate interfaceId for the endpoint by the Router. |
| 1463 this.encoder.writeUint32(0); // interface ID. |
| 1464 this.encoder.writeUint32(messageName); |
| 1465 this.encoder.writeUint32(flags); |
| 1466 this.encoder.writeUint32(0); // padding. |
| 1467 this.encoder.writeUint64(requestID); |
| 1468 } |
| 1469 |
| 1470 MessageV2Builder.prototype.createEncoder = function(size) { |
| 1471 var pointer = this.buffer.alloc(size); |
| 1472 return new Encoder(this.buffer, this.handles, |
| 1473 this.associatedEndpointHandles, pointer); |
| 1474 }; |
| 1475 |
| 1476 MessageV2Builder.prototype.setPayload = function(cls, val) { |
| 1477 this.payload = {cls: cls, val: val}; |
| 1478 }; |
| 1479 |
| 1480 MessageV2Builder.prototype.finish = function() { |
| 1481 if (!this.payload) { |
| 1482 throw new Error("Payload needs to be set before calling finish"); |
| 1483 } |
| 1484 |
| 1485 this.encoder.encodeStructPointer(this.payload.cls, this.payload.val); |
| 1486 this.encoder.encodeArrayPointer(Uint32, |
| 1487 new Array(this.associatedEndpointHandles.length)); |
| 1488 |
| 1489 this.buffer.trim(); |
| 1490 var message = new Message(this.buffer, this.handles, |
| 1491 this.associatedEndpointHandles); |
| 1492 this.buffer = null; |
| 1493 this.handles = null; |
| 1494 this.encoder = null; |
| 1495 this.payload = null; |
| 1496 this.associatedEndpointHandles = null; |
| 1497 |
| 1498 return message; |
| 1499 }; |
| 1500 |
| 1501 // MessageReader ------------------------------------------------------------ |
| 1502 |
| 1503 function MessageReader(message) { |
| 1504 this.decoder = new Decoder(message.buffer, message.handles, |
| 1505 message.associatedEndpointHandles, 0); |
| 1506 var messageHeaderSize = this.decoder.readUint32(); |
| 1507 this.payloadSize = message.buffer.byteLength - messageHeaderSize; |
| 1508 var version = this.decoder.readUint32(); |
| 1509 var interface_id = this.decoder.readUint32(); |
| 1510 this.messageName = this.decoder.readUint32(); |
| 1511 this.flags = this.decoder.readUint32(); |
| 1512 // Skip the padding. |
| 1513 this.decoder.skip(4); |
| 1514 if (version >= 1) |
| 1515 this.requestID = this.decoder.readUint64(); |
| 1516 this.decoder.skip(messageHeaderSize - this.decoder.next); |
| 1517 } |
| 1518 |
| 1519 MessageReader.prototype.decodeStruct = function(cls) { |
| 1520 return cls.decode(this.decoder); |
| 1521 }; |
| 1522 |
| 1523 // Built-in types ----------------------------------------------------------- |
| 1524 |
| 1525 // This type is only used with ArrayOf(PackedBool). |
| 1526 function PackedBool() { |
| 1527 } |
| 1528 |
| 1529 function Int8() { |
| 1530 } |
| 1531 |
| 1532 Int8.encodedSize = 1; |
| 1533 |
| 1534 Int8.decode = function(decoder) { |
| 1535 return decoder.readInt8(); |
| 1536 }; |
| 1537 |
| 1538 Int8.encode = function(encoder, val) { |
| 1539 encoder.writeInt8(val); |
| 1540 }; |
| 1541 |
| 1542 Uint8.encode = function(encoder, val) { |
| 1543 encoder.writeUint8(val); |
| 1544 }; |
| 1545 |
| 1546 function Uint8() { |
| 1547 } |
| 1548 |
| 1549 Uint8.encodedSize = 1; |
| 1550 |
| 1551 Uint8.decode = function(decoder) { |
| 1552 return decoder.readUint8(); |
| 1553 }; |
| 1554 |
| 1555 Uint8.encode = function(encoder, val) { |
| 1556 encoder.writeUint8(val); |
| 1557 }; |
| 1558 |
| 1559 function Int16() { |
| 1560 } |
| 1561 |
| 1562 Int16.encodedSize = 2; |
| 1563 |
| 1564 Int16.decode = function(decoder) { |
| 1565 return decoder.readInt16(); |
| 1566 }; |
| 1567 |
| 1568 Int16.encode = function(encoder, val) { |
| 1569 encoder.writeInt16(val); |
| 1570 }; |
| 1571 |
| 1572 function Uint16() { |
| 1573 } |
| 1574 |
| 1575 Uint16.encodedSize = 2; |
| 1576 |
| 1577 Uint16.decode = function(decoder) { |
| 1578 return decoder.readUint16(); |
| 1579 }; |
| 1580 |
| 1581 Uint16.encode = function(encoder, val) { |
| 1582 encoder.writeUint16(val); |
| 1583 }; |
| 1584 |
| 1585 function Int32() { |
| 1586 } |
| 1587 |
| 1588 Int32.encodedSize = 4; |
| 1589 |
| 1590 Int32.decode = function(decoder) { |
| 1591 return decoder.readInt32(); |
| 1592 }; |
| 1593 |
| 1594 Int32.encode = function(encoder, val) { |
| 1595 encoder.writeInt32(val); |
| 1596 }; |
| 1597 |
| 1598 function Uint32() { |
| 1599 } |
| 1600 |
| 1601 Uint32.encodedSize = 4; |
| 1602 |
| 1603 Uint32.decode = function(decoder) { |
| 1604 return decoder.readUint32(); |
| 1605 }; |
| 1606 |
| 1607 Uint32.encode = function(encoder, val) { |
| 1608 encoder.writeUint32(val); |
| 1609 }; |
| 1610 |
| 1611 function Int64() { |
| 1612 } |
| 1613 |
| 1614 Int64.encodedSize = 8; |
| 1615 |
| 1616 Int64.decode = function(decoder) { |
| 1617 return decoder.readInt64(); |
| 1618 }; |
| 1619 |
| 1620 Int64.encode = function(encoder, val) { |
| 1621 encoder.writeInt64(val); |
| 1622 }; |
| 1623 |
| 1624 function Uint64() { |
| 1625 } |
| 1626 |
| 1627 Uint64.encodedSize = 8; |
| 1628 |
| 1629 Uint64.decode = function(decoder) { |
| 1630 return decoder.readUint64(); |
| 1631 }; |
| 1632 |
| 1633 Uint64.encode = function(encoder, val) { |
| 1634 encoder.writeUint64(val); |
| 1635 }; |
| 1636 |
| 1637 function String() { |
| 1638 }; |
| 1639 |
| 1640 String.encodedSize = 8; |
| 1641 |
| 1642 String.decode = function(decoder) { |
| 1643 return decoder.decodeStringPointer(); |
| 1644 }; |
| 1645 |
| 1646 String.encode = function(encoder, val) { |
| 1647 encoder.encodeStringPointer(val); |
| 1648 }; |
| 1649 |
| 1650 function NullableString() { |
| 1651 } |
| 1652 |
| 1653 NullableString.encodedSize = String.encodedSize; |
| 1654 |
| 1655 NullableString.decode = String.decode; |
| 1656 |
| 1657 NullableString.encode = String.encode; |
| 1658 |
| 1659 function Float() { |
| 1660 } |
| 1661 |
| 1662 Float.encodedSize = 4; |
| 1663 |
| 1664 Float.decode = function(decoder) { |
| 1665 return decoder.readFloat(); |
| 1666 }; |
| 1667 |
| 1668 Float.encode = function(encoder, val) { |
| 1669 encoder.writeFloat(val); |
| 1670 }; |
| 1671 |
| 1672 function Double() { |
| 1673 } |
| 1674 |
| 1675 Double.encodedSize = 8; |
| 1676 |
| 1677 Double.decode = function(decoder) { |
| 1678 return decoder.readDouble(); |
| 1679 }; |
| 1680 |
| 1681 Double.encode = function(encoder, val) { |
| 1682 encoder.writeDouble(val); |
| 1683 }; |
| 1684 |
| 1685 function Enum(cls) { |
| 1686 this.cls = cls; |
| 1687 } |
| 1688 |
| 1689 Enum.prototype.encodedSize = 4; |
| 1690 |
| 1691 Enum.prototype.decode = function(decoder) { |
| 1692 return decoder.readInt32(); |
| 1693 }; |
| 1694 |
| 1695 Enum.prototype.encode = function(encoder, val) { |
| 1696 encoder.writeInt32(val); |
| 1697 }; |
| 1698 |
| 1699 function PointerTo(cls) { |
| 1700 this.cls = cls; |
| 1701 } |
| 1702 |
| 1703 PointerTo.prototype.encodedSize = 8; |
| 1704 |
| 1705 PointerTo.prototype.decode = function(decoder) { |
| 1706 var pointer = decoder.decodePointer(); |
| 1707 if (!pointer) { |
| 1708 return null; |
| 1709 } |
| 1710 return this.cls.decode(decoder.decodeAndCreateDecoder(pointer)); |
| 1711 }; |
| 1712 |
| 1713 PointerTo.prototype.encode = function(encoder, val) { |
| 1714 if (!val) { |
| 1715 encoder.encodePointer(val); |
| 1716 return; |
| 1717 } |
| 1718 var objectEncoder = encoder.createAndEncodeEncoder(this.cls.encodedSize); |
| 1719 this.cls.encode(objectEncoder, val); |
| 1720 }; |
| 1721 |
| 1722 function NullablePointerTo(cls) { |
| 1723 PointerTo.call(this, cls); |
| 1724 } |
| 1725 |
| 1726 NullablePointerTo.prototype = Object.create(PointerTo.prototype); |
| 1727 |
| 1728 function ArrayOf(cls, length) { |
| 1729 this.cls = cls; |
| 1730 this.length = length || 0; |
| 1731 } |
| 1732 |
| 1733 ArrayOf.prototype.encodedSize = 8; |
| 1734 |
| 1735 ArrayOf.prototype.dimensions = function() { |
| 1736 return [this.length].concat( |
| 1737 (this.cls instanceof ArrayOf) ? this.cls.dimensions() : []); |
| 1738 } |
| 1739 |
| 1740 ArrayOf.prototype.decode = function(decoder) { |
| 1741 return decoder.decodeArrayPointer(this.cls); |
| 1742 }; |
| 1743 |
| 1744 ArrayOf.prototype.encode = function(encoder, val) { |
| 1745 encoder.encodeArrayPointer(this.cls, val); |
| 1746 }; |
| 1747 |
| 1748 function NullableArrayOf(cls) { |
| 1749 ArrayOf.call(this, cls); |
| 1750 } |
| 1751 |
| 1752 NullableArrayOf.prototype = Object.create(ArrayOf.prototype); |
| 1753 |
| 1754 function Handle() { |
| 1755 } |
| 1756 |
| 1757 Handle.encodedSize = 4; |
| 1758 |
| 1759 Handle.decode = function(decoder) { |
| 1760 return decoder.decodeHandle(); |
| 1761 }; |
| 1762 |
| 1763 Handle.encode = function(encoder, val) { |
| 1764 encoder.encodeHandle(val); |
| 1765 }; |
| 1766 |
| 1767 function NullableHandle() { |
| 1768 } |
| 1769 |
| 1770 NullableHandle.encodedSize = Handle.encodedSize; |
| 1771 |
| 1772 NullableHandle.decode = Handle.decode; |
| 1773 |
| 1774 NullableHandle.encode = Handle.encode; |
| 1775 |
| 1776 function Interface(cls) { |
| 1777 this.cls = cls; |
| 1778 } |
| 1779 |
| 1780 Interface.prototype.encodedSize = 8; |
| 1781 |
| 1782 Interface.prototype.decode = function(decoder) { |
| 1783 var interfacePtrInfo = new mojo.InterfacePtrInfo( |
| 1784 decoder.decodeHandle(), decoder.readUint32()); |
| 1785 var interfacePtr = new this.cls(); |
| 1786 interfacePtr.ptr.bind(interfacePtrInfo); |
| 1787 return interfacePtr; |
| 1788 }; |
| 1789 |
| 1790 Interface.prototype.encode = function(encoder, val) { |
| 1791 var interfacePtrInfo = |
| 1792 val ? val.ptr.passInterface() : new mojo.InterfacePtrInfo(null, 0); |
| 1793 encoder.encodeHandle(interfacePtrInfo.handle); |
| 1794 encoder.writeUint32(interfacePtrInfo.version); |
| 1795 }; |
| 1796 |
| 1797 function NullableInterface(cls) { |
| 1798 Interface.call(this, cls); |
| 1799 } |
| 1800 |
| 1801 NullableInterface.prototype = Object.create(Interface.prototype); |
| 1802 |
| 1803 function AssociatedInterfacePtrInfo() { |
| 1804 } |
| 1805 |
| 1806 AssociatedInterfacePtrInfo.prototype.encodedSize = 8; |
| 1807 |
| 1808 AssociatedInterfacePtrInfo.decode = function(decoder) { |
| 1809 return new mojo.AssociatedInterfacePtrInfo( |
| 1810 decoder.decodeAssociatedEndpointHandle(), decoder.readUint32()); |
| 1811 }; |
| 1812 |
| 1813 AssociatedInterfacePtrInfo.encode = function(encoder, val) { |
| 1814 var associatedinterfacePtrInfo = |
| 1815 val ? val : new mojo.AssociatedInterfacePtrInfo(null, 0); |
| 1816 encoder.encodeAssociatedEndpointHandle( |
| 1817 associatedinterfacePtrInfo.interfaceEndpointHandle); |
| 1818 encoder.writeUint32(associatedinterfacePtrInfo.version); |
| 1819 }; |
| 1820 |
| 1821 function NullableAssociatedInterfacePtrInfo() { |
| 1822 } |
| 1823 |
| 1824 NullableAssociatedInterfacePtrInfo.encodedSize = |
| 1825 AssociatedInterfacePtrInfo.encodedSize; |
| 1826 |
| 1827 NullableAssociatedInterfacePtrInfo.decode = |
| 1828 AssociatedInterfacePtrInfo.decode; |
| 1829 |
| 1830 NullableAssociatedInterfacePtrInfo.encode = |
| 1831 AssociatedInterfacePtrInfo.encode; |
| 1832 |
| 1833 function InterfaceRequest() { |
| 1834 } |
| 1835 |
| 1836 InterfaceRequest.encodedSize = 4; |
| 1837 |
| 1838 InterfaceRequest.decode = function(decoder) { |
| 1839 return new mojo.InterfaceRequest(decoder.decodeHandle()); |
| 1840 }; |
| 1841 |
| 1842 InterfaceRequest.encode = function(encoder, val) { |
| 1843 encoder.encodeHandle(val ? val.handle : null); |
| 1844 }; |
| 1845 |
| 1846 function NullableInterfaceRequest() { |
| 1847 } |
| 1848 |
| 1849 NullableInterfaceRequest.encodedSize = InterfaceRequest.encodedSize; |
| 1850 |
| 1851 NullableInterfaceRequest.decode = InterfaceRequest.decode; |
| 1852 |
| 1853 NullableInterfaceRequest.encode = InterfaceRequest.encode; |
| 1854 |
| 1855 function AssociatedInterfaceRequest() { |
| 1856 } |
| 1857 |
| 1858 AssociatedInterfaceRequest.decode = function(decoder) { |
| 1859 var handle = decoder.decodeAssociatedEndpointHandle(); |
| 1860 return new mojo.AssociatedInterfaceRequest(handle); |
| 1861 }; |
| 1862 |
| 1863 AssociatedInterfaceRequest.encode = function(encoder, val) { |
| 1864 encoder.encodeAssociatedEndpointHandle( |
| 1865 val ? val.interfaceEndpointHandle : null); |
| 1866 }; |
| 1867 |
| 1868 AssociatedInterfaceRequest.encodedSize = 4; |
| 1869 |
| 1870 function NullableAssociatedInterfaceRequest() { |
| 1871 } |
| 1872 |
| 1873 NullableAssociatedInterfaceRequest.encodedSize = |
| 1874 AssociatedInterfaceRequest.encodedSize; |
| 1875 |
| 1876 NullableAssociatedInterfaceRequest.decode = |
| 1877 AssociatedInterfaceRequest.decode; |
| 1878 |
| 1879 NullableAssociatedInterfaceRequest.encode = |
| 1880 AssociatedInterfaceRequest.encode; |
| 1881 |
| 1882 function MapOf(keyClass, valueClass) { |
| 1883 this.keyClass = keyClass; |
| 1884 this.valueClass = valueClass; |
| 1885 } |
| 1886 |
| 1887 MapOf.prototype.encodedSize = 8; |
| 1888 |
| 1889 MapOf.prototype.decode = function(decoder) { |
| 1890 return decoder.decodeMapPointer(this.keyClass, this.valueClass); |
| 1891 }; |
| 1892 |
| 1893 MapOf.prototype.encode = function(encoder, val) { |
| 1894 encoder.encodeMapPointer(this.keyClass, this.valueClass, val); |
| 1895 }; |
| 1896 |
| 1897 function NullableMapOf(keyClass, valueClass) { |
| 1898 MapOf.call(this, keyClass, valueClass); |
| 1899 } |
| 1900 |
| 1901 NullableMapOf.prototype = Object.create(MapOf.prototype); |
| 1902 |
| 1903 internal.align = align; |
| 1904 internal.isAligned = isAligned; |
| 1905 internal.Message = Message; |
| 1906 internal.MessageV0Builder = MessageV0Builder; |
| 1907 internal.MessageV1Builder = MessageV1Builder; |
| 1908 internal.MessageV2Builder = MessageV2Builder; |
| 1909 internal.MessageReader = MessageReader; |
| 1910 internal.kArrayHeaderSize = kArrayHeaderSize; |
| 1911 internal.kMapStructPayloadSize = kMapStructPayloadSize; |
| 1912 internal.kStructHeaderSize = kStructHeaderSize; |
| 1913 internal.kEncodedInvalidHandleValue = kEncodedInvalidHandleValue; |
| 1914 internal.kMessageV0HeaderSize = kMessageV0HeaderSize; |
| 1915 internal.kMessageV1HeaderSize = kMessageV1HeaderSize; |
| 1916 internal.kMessageV2HeaderSize = kMessageV2HeaderSize; |
| 1917 internal.kMessagePayloadInterfaceIdsPointerOffset = |
| 1918 kMessagePayloadInterfaceIdsPointerOffset; |
| 1919 internal.kMessageExpectsResponse = kMessageExpectsResponse; |
| 1920 internal.kMessageIsResponse = kMessageIsResponse; |
| 1921 internal.Int8 = Int8; |
| 1922 internal.Uint8 = Uint8; |
| 1923 internal.Int16 = Int16; |
| 1924 internal.Uint16 = Uint16; |
| 1925 internal.Int32 = Int32; |
| 1926 internal.Uint32 = Uint32; |
| 1927 internal.Int64 = Int64; |
| 1928 internal.Uint64 = Uint64; |
| 1929 internal.Float = Float; |
| 1930 internal.Double = Double; |
| 1931 internal.String = String; |
| 1932 internal.Enum = Enum; |
| 1933 internal.NullableString = NullableString; |
| 1934 internal.PointerTo = PointerTo; |
| 1935 internal.NullablePointerTo = NullablePointerTo; |
| 1936 internal.ArrayOf = ArrayOf; |
| 1937 internal.NullableArrayOf = NullableArrayOf; |
| 1938 internal.PackedBool = PackedBool; |
| 1939 internal.Handle = Handle; |
| 1940 internal.NullableHandle = NullableHandle; |
| 1941 internal.Interface = Interface; |
| 1942 internal.NullableInterface = NullableInterface; |
| 1943 internal.InterfaceRequest = InterfaceRequest; |
| 1944 internal.NullableInterfaceRequest = NullableInterfaceRequest; |
| 1945 internal.AssociatedInterfacePtrInfo = AssociatedInterfacePtrInfo; |
| 1946 internal.NullableAssociatedInterfacePtrInfo = |
| 1947 NullableAssociatedInterfacePtrInfo; |
| 1948 internal.AssociatedInterfaceRequest = AssociatedInterfaceRequest; |
| 1949 internal.NullableAssociatedInterfaceRequest = |
| 1950 NullableAssociatedInterfaceRequest; |
| 1951 internal.MapOf = MapOf; |
| 1952 internal.NullableMapOf = NullableMapOf; |
| 1953 })(); |
| 1954 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 1955 // Use of this source code is governed by a BSD-style license that can be |
| 1956 // found in the LICENSE file. |
| 1957 |
| 1958 (function() { |
| 1959 var internal = mojo.internal; |
| 1960 |
| 1961 function Connector(handle) { |
| 1962 if (!(handle instanceof MojoHandle)) |
| 1963 throw new Error("Connector: not a handle " + handle); |
| 1964 this.handle_ = handle; |
| 1965 this.dropWrites_ = false; |
| 1966 this.error_ = false; |
| 1967 this.incomingReceiver_ = null; |
| 1968 this.readWatcher_ = null; |
| 1969 this.errorHandler_ = null; |
| 1970 this.paused_ = false; |
| 1971 |
| 1972 this.waitToReadMore(); |
| 1973 } |
| 1974 |
| 1975 Connector.prototype.close = function() { |
| 1976 this.cancelWait(); |
| 1977 if (this.handle_ != null) { |
| 1978 this.handle_.close(); |
| 1979 this.handle_ = null; |
| 1980 } |
| 1981 }; |
| 1982 |
| 1983 Connector.prototype.pauseIncomingMethodCallProcessing = function() { |
| 1984 if (this.paused_) { |
| 1985 return; |
| 1986 } |
| 1987 this.paused_= true; |
| 1988 this.cancelWait(); |
| 1989 }; |
| 1990 |
| 1991 Connector.prototype.resumeIncomingMethodCallProcessing = function() { |
| 1992 if (!this.paused_) { |
| 1993 return; |
| 1994 } |
| 1995 this.paused_= false; |
| 1996 this.waitToReadMore(); |
| 1997 }; |
| 1998 |
| 1999 Connector.prototype.accept = function(message) { |
| 2000 if (this.error_) |
| 2001 return false; |
| 2002 |
| 2003 if (this.dropWrites_) |
| 2004 return true; |
| 2005 |
| 2006 var result = this.handle_.writeMessage( |
| 2007 new Uint8Array(message.buffer.arrayBuffer), message.handles); |
| 2008 switch (result) { |
| 2009 case Mojo.RESULT_OK: |
| 2010 // The handles were successfully transferred, so we don't own them |
| 2011 // anymore. |
| 2012 message.handles = []; |
| 2013 break; |
| 2014 case Mojo.RESULT_FAILED_PRECONDITION: |
| 2015 // There's no point in continuing to write to this pipe since the other |
| 2016 // end is gone. Avoid writing any future messages. Hide write failures |
| 2017 // from the caller since we'd like them to continue consuming any |
| 2018 // backlog of incoming messages before regarding the message pipe as |
| 2019 // closed. |
| 2020 this.dropWrites_ = true; |
| 2021 break; |
| 2022 default: |
| 2023 // This particular write was rejected, presumably because of bad input. |
| 2024 // The pipe is not necessarily in a bad state. |
| 2025 return false; |
| 2026 } |
| 2027 return true; |
| 2028 }; |
| 2029 |
| 2030 Connector.prototype.setIncomingReceiver = function(receiver) { |
| 2031 this.incomingReceiver_ = receiver; |
| 2032 }; |
| 2033 |
| 2034 Connector.prototype.setErrorHandler = function(handler) { |
| 2035 this.errorHandler_ = handler; |
| 2036 }; |
| 2037 |
| 2038 Connector.prototype.readMore_ = function(result) { |
| 2039 for (;;) { |
| 2040 if (this.paused_) { |
| 2041 return; |
| 2042 } |
| 2043 |
| 2044 var read = this.handle_.readMessage(); |
| 2045 if (this.handle_ == null) // The connector has been closed. |
| 2046 return; |
| 2047 if (read.result == Mojo.RESULT_SHOULD_WAIT) |
| 2048 return; |
| 2049 if (read.result != Mojo.RESULT_OK) { |
| 2050 this.handleError(read.result !== Mojo.RESULT_FAILED_PRECONDITION, |
| 2051 false); |
| 2052 return; |
| 2053 } |
| 2054 var messageBuffer = new internal.Buffer(read.buffer); |
| 2055 var message = new internal.Message(messageBuffer, read.handles); |
| 2056 var receiverResult = this.incomingReceiver_ && |
| 2057 this.incomingReceiver_.accept(message); |
| 2058 |
| 2059 // Handle invalid incoming message. |
| 2060 if (!internal.isTestingMode() && !receiverResult) { |
| 2061 // TODO(yzshen): Consider notifying the embedder. |
| 2062 this.handleError(true, false); |
| 2063 } |
| 2064 } |
| 2065 }; |
| 2066 |
| 2067 Connector.prototype.cancelWait = function() { |
| 2068 if (this.readWatcher_) { |
| 2069 this.readWatcher_.cancel(); |
| 2070 this.readWatcher_ = null; |
| 2071 } |
| 2072 }; |
| 2073 |
| 2074 Connector.prototype.waitToReadMore = function() { |
| 2075 if (this.handle_) { |
| 2076 this.readWatcher_ = this.handle_.watch({readable: true}, |
| 2077 this.readMore_.bind(this)); |
| 2078 } |
| 2079 }; |
| 2080 |
| 2081 Connector.prototype.handleError = function(forcePipeReset, |
| 2082 forceAsyncHandler) { |
| 2083 if (this.error_ || this.handle_ === null) { |
| 2084 return; |
| 2085 } |
| 2086 |
| 2087 if (this.paused_) { |
| 2088 // Enforce calling the error handler asynchronously if the user has |
| 2089 // paused receiving messages. We need to wait until the user starts |
| 2090 // receiving messages again. |
| 2091 forceAsyncHandler = true; |
| 2092 } |
| 2093 |
| 2094 if (!forcePipeReset && forceAsyncHandler) { |
| 2095 forcePipeReset = true; |
| 2096 } |
| 2097 |
| 2098 this.cancelWait(); |
| 2099 if (forcePipeReset) { |
| 2100 this.handle_.close(); |
| 2101 var dummyPipe = Mojo.createMessagePipe(); |
| 2102 this.handle_ = dummyPipe.handle0; |
| 2103 } |
| 2104 |
| 2105 if (forceAsyncHandler) { |
| 2106 if (!this.paused_) { |
| 2107 this.waitToReadMore(); |
| 2108 } |
| 2109 } else { |
| 2110 this.error_ = true; |
| 2111 if (this.errorHandler_) { |
| 2112 this.errorHandler_.onError(); |
| 2113 } |
| 2114 } |
| 2115 }; |
| 2116 |
| 2117 internal.Connector = Connector; |
| 2118 })(); |
| 2119 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2120 // Use of this source code is governed by a BSD-style license that can be |
| 2121 // found in the LICENSE file. |
| 2122 |
| 2123 (function() { |
| 2124 var internal = mojo.internal; |
| 2125 |
| 2126 // Constants ---------------------------------------------------------------- |
| 2127 var kInterfaceIdNamespaceMask = 0x80000000; |
| 2128 var kMasterInterfaceId = 0x00000000; |
| 2129 var kInvalidInterfaceId = 0xFFFFFFFF; |
| 2130 |
| 2131 // --------------------------------------------------------------------------- |
| 2132 |
| 2133 function InterfacePtrInfo(handle, version) { |
| 2134 this.handle = handle; |
| 2135 this.version = version; |
| 2136 } |
| 2137 |
| 2138 InterfacePtrInfo.prototype.isValid = function() { |
| 2139 return this.handle instanceof MojoHandle; |
| 2140 }; |
| 2141 |
| 2142 InterfacePtrInfo.prototype.close = function() { |
| 2143 if (!this.isValid()) |
| 2144 return; |
| 2145 |
| 2146 this.handle.close(); |
| 2147 this.handle = null; |
| 2148 this.version = 0; |
| 2149 }; |
| 2150 |
| 2151 function AssociatedInterfacePtrInfo(interfaceEndpointHandle, version) { |
| 2152 this.interfaceEndpointHandle = interfaceEndpointHandle; |
| 2153 this.version = version; |
| 2154 } |
| 2155 |
| 2156 AssociatedInterfacePtrInfo.prototype.isValid = function() { |
| 2157 return this.interfaceEndpointHandle.isValid(); |
| 2158 }; |
| 2159 |
| 2160 // --------------------------------------------------------------------------- |
| 2161 |
| 2162 function InterfaceRequest(handle) { |
| 2163 this.handle = handle; |
| 2164 } |
| 2165 |
| 2166 InterfaceRequest.prototype.isValid = function() { |
| 2167 return this.handle instanceof MojoHandle; |
| 2168 }; |
| 2169 |
| 2170 InterfaceRequest.prototype.close = function() { |
| 2171 if (!this.isValid()) |
| 2172 return; |
| 2173 |
| 2174 this.handle.close(); |
| 2175 this.handle = null; |
| 2176 }; |
| 2177 |
| 2178 function AssociatedInterfaceRequest(interfaceEndpointHandle) { |
| 2179 this.interfaceEndpointHandle = interfaceEndpointHandle; |
| 2180 } |
| 2181 |
| 2182 AssociatedInterfaceRequest.prototype.isValid = function() { |
| 2183 return this.interfaceEndpointHandle.isValid(); |
| 2184 }; |
| 2185 |
| 2186 AssociatedInterfaceRequest.prototype.resetWithReason = function(reason) { |
| 2187 this.interfaceEndpointHandle.reset(reason); |
| 2188 }; |
| 2189 |
| 2190 function isMasterInterfaceId(interfaceId) { |
| 2191 return interfaceId === kMasterInterfaceId; |
| 2192 } |
| 2193 |
| 2194 function isValidInterfaceId(interfaceId) { |
| 2195 return interfaceId !== kInvalidInterfaceId; |
| 2196 } |
| 2197 |
| 2198 mojo.InterfacePtrInfo = InterfacePtrInfo; |
| 2199 mojo.InterfaceRequest = InterfaceRequest; |
| 2200 mojo.AssociatedInterfacePtrInfo = AssociatedInterfacePtrInfo; |
| 2201 mojo.AssociatedInterfaceRequest = AssociatedInterfaceRequest; |
| 2202 internal.isMasterInterfaceId = isMasterInterfaceId; |
| 2203 internal.isValidInterfaceId = isValidInterfaceId; |
| 2204 internal.kInvalidInterfaceId = kInvalidInterfaceId; |
| 2205 internal.kMasterInterfaceId = kMasterInterfaceId; |
| 2206 internal.kInterfaceIdNamespaceMask = kInterfaceIdNamespaceMask; |
| 2207 })(); |
| 2208 // Copyright 2017 The Chromium Authors. All rights reserved. |
| 2209 // Use of this source code is governed by a BSD-style license that can be |
| 2210 // found in the LICENSE file. |
| 2211 |
| 2212 (function() { |
| 2213 var internal = mojo.internal; |
| 2214 |
| 2215 function validateControlRequestWithResponse(message) { |
| 2216 var messageValidator = new internal.Validator(message); |
| 2217 var error = messageValidator.validateMessageIsRequestExpectingResponse(); |
| 2218 if (error !== internal.validationError.NONE) { |
| 2219 throw error; |
| 2220 } |
| 2221 |
| 2222 if (message.getName() != mojo.interfaceControl2.kRunMessageId) { |
| 2223 throw new Error("Control message name is not kRunMessageId"); |
| 2224 } |
| 2225 |
| 2226 // Validate payload. |
| 2227 error = mojo.interfaceControl2.RunMessageParams.validate(messageValidator, |
| 2228 message.getHeaderNumBytes()); |
| 2229 if (error != internal.validationError.NONE) { |
| 2230 throw error; |
| 2231 } |
| 2232 } |
| 2233 |
| 2234 function validateControlRequestWithoutResponse(message) { |
| 2235 var messageValidator = new internal.Validator(message); |
| 2236 var error = messageValidator.validateMessageIsRequestWithoutResponse(); |
| 2237 if (error != internal.validationError.NONE) { |
| 2238 throw error; |
| 2239 } |
| 2240 |
| 2241 if (message.getName() != mojo.interfaceControl2.kRunOrClosePipeMessageId) { |
| 2242 throw new Error("Control message name is not kRunOrClosePipeMessageId"); |
| 2243 } |
| 2244 |
| 2245 // Validate payload. |
| 2246 error = mojo.interfaceControl2.RunOrClosePipeMessageParams.validate( |
| 2247 messageValidator, message.getHeaderNumBytes()); |
| 2248 if (error != internal.validationError.NONE) { |
| 2249 throw error; |
| 2250 } |
| 2251 } |
| 2252 |
| 2253 function runOrClosePipe(message, interfaceVersion) { |
| 2254 var reader = new internal.MessageReader(message); |
| 2255 var runOrClosePipeMessageParams = reader.decodeStruct( |
| 2256 mojo.interfaceControl2.RunOrClosePipeMessageParams); |
| 2257 return interfaceVersion >= |
| 2258 runOrClosePipeMessageParams.input.requireVersion.version; |
| 2259 } |
| 2260 |
| 2261 function run(message, responder, interfaceVersion) { |
| 2262 var reader = new internal.MessageReader(message); |
| 2263 var runMessageParams = |
| 2264 reader.decodeStruct(mojo.interfaceControl2.RunMessageParams); |
| 2265 var runOutput = null; |
| 2266 |
| 2267 if (runMessageParams.input.queryVersion) { |
| 2268 runOutput = new mojo.interfaceControl2.RunOutput(); |
| 2269 runOutput.queryVersionResult = new |
| 2270 mojo.interfaceControl2.QueryVersionResult( |
| 2271 {'version': interfaceVersion}); |
| 2272 } |
| 2273 |
| 2274 var runResponseMessageParams = new |
| 2275 mojo.interfaceControl2.RunResponseMessageParams(); |
| 2276 runResponseMessageParams.output = runOutput; |
| 2277 |
| 2278 var messageName = mojo.interfaceControl2.kRunMessageId; |
| 2279 var payloadSize = |
| 2280 mojo.interfaceControl2.RunResponseMessageParams.encodedSize; |
| 2281 var requestID = reader.requestID; |
| 2282 var builder = new internal.MessageV1Builder(messageName, |
| 2283 payloadSize, internal.kMessageIsResponse, requestID); |
| 2284 builder.encodeStruct(mojo.interfaceControl2.RunResponseMessageParams, |
| 2285 runResponseMessageParams); |
| 2286 responder.accept(builder.finish()); |
| 2287 return true; |
| 2288 } |
| 2289 |
| 2290 function isInterfaceControlMessage(message) { |
| 2291 return message.getName() == mojo.interfaceControl2.kRunMessageId || |
| 2292 message.getName() == mojo.interfaceControl2.kRunOrClosePipeMessageId; |
| 2293 } |
| 2294 |
| 2295 function ControlMessageHandler(interfaceVersion) { |
| 2296 this.interfaceVersion_ = interfaceVersion; |
| 2297 } |
| 2298 |
| 2299 ControlMessageHandler.prototype.accept = function(message) { |
| 2300 validateControlRequestWithoutResponse(message); |
| 2301 return runOrClosePipe(message, this.interfaceVersion_); |
| 2302 }; |
| 2303 |
| 2304 ControlMessageHandler.prototype.acceptWithResponder = function(message, |
| 2305 responder) { |
| 2306 validateControlRequestWithResponse(message); |
| 2307 return run(message, responder, this.interfaceVersion_); |
| 2308 }; |
| 2309 |
| 2310 internal.ControlMessageHandler = ControlMessageHandler; |
| 2311 internal.isInterfaceControlMessage = isInterfaceControlMessage; |
| 2312 })(); |
| 2313 // Copyright 2017 The Chromium Authors. All rights reserved. |
| 2314 // Use of this source code is governed by a BSD-style license that can be |
| 2315 // found in the LICENSE file. |
| 2316 |
| 2317 (function() { |
| 2318 var internal = mojo.internal; |
| 2319 |
| 2320 function constructRunOrClosePipeMessage(runOrClosePipeInput) { |
| 2321 var runOrClosePipeMessageParams = new |
| 2322 mojo.interfaceControl2.RunOrClosePipeMessageParams(); |
| 2323 runOrClosePipeMessageParams.input = runOrClosePipeInput; |
| 2324 |
| 2325 var messageName = mojo.interfaceControl2.kRunOrClosePipeMessageId; |
| 2326 var payloadSize = |
| 2327 mojo.interfaceControl2.RunOrClosePipeMessageParams.encodedSize; |
| 2328 var builder = new internal.MessageV0Builder(messageName, payloadSize); |
| 2329 builder.encodeStruct(mojo.interfaceControl2.RunOrClosePipeMessageParams, |
| 2330 runOrClosePipeMessageParams); |
| 2331 var message = builder.finish(); |
| 2332 return message; |
| 2333 } |
| 2334 |
| 2335 function validateControlResponse(message) { |
| 2336 var messageValidator = new internal.Validator(message); |
| 2337 var error = messageValidator.validateMessageIsResponse(); |
| 2338 if (error != internal.validationError.NONE) { |
| 2339 throw error; |
| 2340 } |
| 2341 |
| 2342 if (message.getName() != mojo.interfaceControl2.kRunMessageId) { |
| 2343 throw new Error("Control message name is not kRunMessageId"); |
| 2344 } |
| 2345 |
| 2346 // Validate payload. |
| 2347 error = mojo.interfaceControl2.RunResponseMessageParams.validate( |
| 2348 messageValidator, message.getHeaderNumBytes()); |
| 2349 if (error != internal.validationError.NONE) { |
| 2350 throw error; |
| 2351 } |
| 2352 } |
| 2353 |
| 2354 function acceptRunResponse(message) { |
| 2355 validateControlResponse(message); |
| 2356 |
| 2357 var reader = new internal.MessageReader(message); |
| 2358 var runResponseMessageParams = reader.decodeStruct( |
| 2359 mojo.interfaceControl2.RunResponseMessageParams); |
| 2360 |
| 2361 return Promise.resolve(runResponseMessageParams); |
| 2362 } |
| 2363 |
| 2364 /** |
| 2365 * Sends the given run message through the receiver. |
| 2366 * Accepts the response message from the receiver and decodes the message |
| 2367 * struct to RunResponseMessageParams. |
| 2368 * |
| 2369 * @param {Router} receiver. |
| 2370 * @param {RunMessageParams} runMessageParams to be sent via a message. |
| 2371 * @return {Promise} that resolves to a RunResponseMessageParams. |
| 2372 */ |
| 2373 function sendRunMessage(receiver, runMessageParams) { |
| 2374 var messageName = mojo.interfaceControl2.kRunMessageId; |
| 2375 var payloadSize = mojo.interfaceControl2.RunMessageParams.encodedSize; |
| 2376 // |requestID| is set to 0, but is later properly set by Router. |
| 2377 var builder = new internal.MessageV1Builder(messageName, |
| 2378 payloadSize, internal.kMessageExpectsResponse, 0); |
| 2379 builder.encodeStruct(mojo.interfaceControl2.RunMessageParams, |
| 2380 runMessageParams); |
| 2381 var message = builder.finish(); |
| 2382 |
| 2383 return receiver.acceptAndExpectResponse(message).then(acceptRunResponse); |
| 2384 } |
| 2385 |
| 2386 function ControlMessageProxy(receiver) { |
| 2387 this.receiver_ = receiver; |
| 2388 } |
| 2389 |
| 2390 ControlMessageProxy.prototype.queryVersion = function() { |
| 2391 var runMessageParams = new mojo.interfaceControl2.RunMessageParams(); |
| 2392 runMessageParams.input = new mojo.interfaceControl2.RunInput(); |
| 2393 runMessageParams.input.queryVersion = |
| 2394 new mojo.interfaceControl2.QueryVersion(); |
| 2395 |
| 2396 return sendRunMessage(this.receiver_, runMessageParams).then(function( |
| 2397 runResponseMessageParams) { |
| 2398 return runResponseMessageParams.output.queryVersionResult.version; |
| 2399 }); |
| 2400 }; |
| 2401 |
| 2402 ControlMessageProxy.prototype.requireVersion = function(version) { |
| 2403 var runOrClosePipeInput = new mojo.interfaceControl2.RunOrClosePipeInput(); |
| 2404 runOrClosePipeInput.requireVersion = |
| 2405 new mojo.interfaceControl2.RequireVersion({'version': version}); |
| 2406 var message = constructRunOrClosePipeMessage(runOrClosePipeInput); |
| 2407 this.receiver_.accept(message); |
| 2408 }; |
| 2409 |
| 2410 internal.ControlMessageProxy = ControlMessageProxy; |
| 2411 })(); |
| 2412 // Copyright 2017 The Chromium Authors. All rights reserved. |
| 2413 // Use of this source code is governed by a BSD-style license that can be |
| 2414 // found in the LICENSE file. |
| 2415 |
| 2416 (function() { |
| 2417 var internal = mojo.internal; |
| 2418 |
| 2419 function InterfaceEndpointClient(interfaceEndpointHandle, receiver, |
| 2420 interfaceVersion) { |
| 2421 this.controller_ = null; |
| 2422 this.encounteredError_ = false; |
| 2423 this.handle_ = interfaceEndpointHandle; |
| 2424 this.incomingReceiver_ = receiver; |
| 2425 |
| 2426 if (interfaceVersion !== undefined) { |
| 2427 this.controlMessageHandler_ = new internal.ControlMessageHandler( |
| 2428 interfaceVersion); |
| 2429 } else { |
| 2430 this.controlMessageProxy_ = new internal.ControlMessageProxy(this); |
| 2431 } |
| 2432 |
| 2433 this.nextRequestID_ = 0; |
| 2434 this.completers_ = new Map(); |
| 2435 this.payloadValidators_ = []; |
| 2436 this.connectionErrorHandler_ = null; |
| 2437 |
| 2438 if (interfaceEndpointHandle.pendingAssociation()) { |
| 2439 interfaceEndpointHandle.setAssociationEventHandler( |
| 2440 this.onAssociationEvent.bind(this)); |
| 2441 } else { |
| 2442 this.initControllerIfNecessary_(); |
| 2443 } |
| 2444 } |
| 2445 |
| 2446 InterfaceEndpointClient.prototype.initControllerIfNecessary_ = function() { |
| 2447 if (this.controller_ || this.handle_.pendingAssociation()) { |
| 2448 return; |
| 2449 } |
| 2450 |
| 2451 this.controller_ = this.handle_.groupController().attachEndpointClient( |
| 2452 this.handle_, this); |
| 2453 }; |
| 2454 |
| 2455 InterfaceEndpointClient.prototype.onAssociationEvent = function( |
| 2456 associationEvent) { |
| 2457 if (associationEvent === internal.AssociationEvent.ASSOCIATED) { |
| 2458 this.initControllerIfNecessary_(); |
| 2459 } else if (associationEvent === |
| 2460 internal.AssociationEvent.PEER_CLOSED_BEFORE_ASSOCIATION) { |
| 2461 setTimeout(this.notifyError.bind(this, this.handle_.disconnectReason()), |
| 2462 0); |
| 2463 } |
| 2464 }; |
| 2465 |
| 2466 InterfaceEndpointClient.prototype.passHandle = function() { |
| 2467 if (!this.handle_.isValid()) { |
| 2468 return new internal.InterfaceEndpointHandle(); |
| 2469 } |
| 2470 |
| 2471 // Used to clear the previously set callback. |
| 2472 this.handle_.setAssociationEventHandler(undefined); |
| 2473 |
| 2474 if (this.controller_) { |
| 2475 this.controller_ = null; |
| 2476 this.handle_.groupController().detachEndpointClient(this.handle_); |
| 2477 } |
| 2478 var handle = this.handle_; |
| 2479 this.handle_ = null; |
| 2480 return handle; |
| 2481 }; |
| 2482 |
| 2483 InterfaceEndpointClient.prototype.close = function(reason) { |
| 2484 var handle = this.passHandle(); |
| 2485 handle.reset(reason); |
| 2486 }; |
| 2487 |
| 2488 InterfaceEndpointClient.prototype.accept = function(message) { |
| 2489 if (message.associatedEndpointHandles.length > 0) { |
| 2490 message.serializeAssociatedEndpointHandles( |
| 2491 this.handle_.groupController()); |
| 2492 } |
| 2493 |
| 2494 if (this.encounteredError_) { |
| 2495 return false; |
| 2496 } |
| 2497 |
| 2498 this.initControllerIfNecessary_(); |
| 2499 return this.controller_.sendMessage(message); |
| 2500 }; |
| 2501 |
| 2502 InterfaceEndpointClient.prototype.acceptAndExpectResponse = function( |
| 2503 message) { |
| 2504 if (message.associatedEndpointHandles.length > 0) { |
| 2505 message.serializeAssociatedEndpointHandles( |
| 2506 this.handle_.groupController()); |
| 2507 } |
| 2508 |
| 2509 if (this.encounteredError_) { |
| 2510 return Promise.reject(); |
| 2511 } |
| 2512 |
| 2513 this.initControllerIfNecessary_(); |
| 2514 |
| 2515 // Reserve 0 in case we want it to convey special meaning in the future. |
| 2516 var requestID = this.nextRequestID_++; |
| 2517 if (requestID === 0) |
| 2518 requestID = this.nextRequestID_++; |
| 2519 |
| 2520 message.setRequestID(requestID); |
| 2521 var result = this.controller_.sendMessage(message); |
| 2522 if (!result) |
| 2523 return Promise.reject(Error("Connection error")); |
| 2524 |
| 2525 var completer = {}; |
| 2526 this.completers_.set(requestID, completer); |
| 2527 return new Promise(function(resolve, reject) { |
| 2528 completer.resolve = resolve; |
| 2529 completer.reject = reject; |
| 2530 }); |
| 2531 }; |
| 2532 |
| 2533 InterfaceEndpointClient.prototype.setPayloadValidators = function( |
| 2534 payloadValidators) { |
| 2535 this.payloadValidators_ = payloadValidators; |
| 2536 }; |
| 2537 |
| 2538 InterfaceEndpointClient.prototype.setIncomingReceiver = function(receiver) { |
| 2539 this.incomingReceiver_ = receiver; |
| 2540 }; |
| 2541 |
| 2542 InterfaceEndpointClient.prototype.setConnectionErrorHandler = function( |
| 2543 handler) { |
| 2544 this.connectionErrorHandler_ = handler; |
| 2545 }; |
| 2546 |
| 2547 InterfaceEndpointClient.prototype.handleIncomingMessage = function(message, |
| 2548 messageValidator) { |
| 2549 var noError = internal.validationError.NONE; |
| 2550 var err = noError; |
| 2551 for (var i = 0; err === noError && i < this.payloadValidators_.length; ++i) |
| 2552 err = this.payloadValidators_[i](messageValidator); |
| 2553 |
| 2554 if (err == noError) { |
| 2555 return this.handleValidIncomingMessage_(message); |
| 2556 } else { |
| 2557 internal.reportValidationError(err); |
| 2558 return false; |
| 2559 } |
| 2560 }; |
| 2561 |
| 2562 InterfaceEndpointClient.prototype.handleValidIncomingMessage_ = function( |
| 2563 message) { |
| 2564 if (internal.isTestingMode()) { |
| 2565 return true; |
| 2566 } |
| 2567 |
| 2568 if (this.encounteredError_) { |
| 2569 return false; |
| 2570 } |
| 2571 |
| 2572 var ok = false; |
| 2573 |
| 2574 if (message.expectsResponse()) { |
| 2575 if (internal.isInterfaceControlMessage(message) && |
| 2576 this.controlMessageHandler_) { |
| 2577 ok = this.controlMessageHandler_.acceptWithResponder(message, this); |
| 2578 } else if (this.incomingReceiver_) { |
| 2579 ok = this.incomingReceiver_.acceptWithResponder(message, this); |
| 2580 } |
| 2581 } else if (message.isResponse()) { |
| 2582 var reader = new internal.MessageReader(message); |
| 2583 var requestID = reader.requestID; |
| 2584 var completer = this.completers_.get(requestID); |
| 2585 if (completer) { |
| 2586 this.completers_.delete(requestID); |
| 2587 completer.resolve(message); |
| 2588 ok = true; |
| 2589 } else { |
| 2590 console.log("Unexpected response with request ID: " + requestID); |
| 2591 } |
| 2592 } else { |
| 2593 if (internal.isInterfaceControlMessage(message) && |
| 2594 this.controlMessageHandler_) { |
| 2595 ok = this.controlMessageHandler_.accept(message); |
| 2596 } else if (this.incomingReceiver_) { |
| 2597 ok = this.incomingReceiver_.accept(message); |
| 2598 } |
| 2599 } |
| 2600 return ok; |
| 2601 }; |
| 2602 |
| 2603 InterfaceEndpointClient.prototype.notifyError = function(reason) { |
| 2604 if (this.encounteredError_) { |
| 2605 return; |
| 2606 } |
| 2607 this.encounteredError_ = true; |
| 2608 |
| 2609 this.completers_.forEach(function(value) { |
| 2610 value.reject(); |
| 2611 }); |
| 2612 this.completers_.clear(); // Drop any responders. |
| 2613 |
| 2614 if (this.connectionErrorHandler_) { |
| 2615 this.connectionErrorHandler_(reason); |
| 2616 } |
| 2617 }; |
| 2618 |
| 2619 InterfaceEndpointClient.prototype.queryVersion = function() { |
| 2620 return this.controlMessageProxy_.queryVersion(); |
| 2621 }; |
| 2622 |
| 2623 InterfaceEndpointClient.prototype.requireVersion = function(version) { |
| 2624 this.controlMessageProxy_.requireVersion(version); |
| 2625 }; |
| 2626 |
| 2627 InterfaceEndpointClient.prototype.getEncounteredError = function() { |
| 2628 return this.encounteredError_; |
| 2629 }; |
| 2630 |
| 2631 internal.InterfaceEndpointClient = InterfaceEndpointClient; |
| 2632 })(); |
| 2633 // Copyright 2017 The Chromium Authors. All rights reserved. |
| 2634 // Use of this source code is governed by a BSD-style license that can be |
| 2635 // found in the LICENSE file. |
| 2636 |
| 2637 (function() { |
| 2638 var internal = mojo.internal; |
| 2639 |
| 2640 var AssociationEvent = { |
| 2641 // The interface has been associated with a message pipe. |
| 2642 ASSOCIATED: 'associated', |
| 2643 // The peer of this object has been closed before association. |
| 2644 PEER_CLOSED_BEFORE_ASSOCIATION: 'peer_closed_before_association' |
| 2645 }; |
| 2646 |
| 2647 function State(interfaceId, associatedGroupController) { |
| 2648 if (interfaceId === undefined) { |
| 2649 interfaceId = internal.kInvalidInterfaceId; |
| 2650 } |
| 2651 |
| 2652 this.interfaceId = interfaceId; |
| 2653 this.associatedGroupController = associatedGroupController; |
| 2654 this.pendingAssociation = false; |
| 2655 this.disconnectReason = null; |
| 2656 this.peerState_ = null; |
| 2657 this.associationEventHandler_ = null; |
| 2658 } |
| 2659 |
| 2660 State.prototype.initPendingState = function(peer) { |
| 2661 this.pendingAssociation = true; |
| 2662 this.peerState_ = peer; |
| 2663 }; |
| 2664 |
| 2665 State.prototype.isValid = function() { |
| 2666 return this.pendingAssociation || |
| 2667 internal.isValidInterfaceId(this.interfaceId); |
| 2668 }; |
| 2669 |
| 2670 State.prototype.close = function(disconnectReason) { |
| 2671 var cachedGroupController; |
| 2672 var cachedPeerState; |
| 2673 var cachedId = internal.kInvalidInterfaceId; |
| 2674 |
| 2675 if (!this.pendingAssociation) { |
| 2676 if (internal.isValidInterfaceId(this.interfaceId)) { |
| 2677 cachedGroupController = this.associatedGroupController; |
| 2678 this.associatedGroupController = null; |
| 2679 cachedId = this.interfaceId; |
| 2680 this.interfaceId = internal.kInvalidInterfaceId; |
| 2681 } |
| 2682 } else { |
| 2683 this.pendingAssociation = false; |
| 2684 cachedPeerState = this.peerState_; |
| 2685 this.peerState_ = null; |
| 2686 } |
| 2687 |
| 2688 if (cachedGroupController) { |
| 2689 cachedGroupController.closeEndpointHandle(cachedId, |
| 2690 disconnectReason); |
| 2691 } else if (cachedPeerState) { |
| 2692 cachedPeerState.onPeerClosedBeforeAssociation(disconnectReason); |
| 2693 } |
| 2694 }; |
| 2695 |
| 2696 State.prototype.runAssociationEventHandler = function(associationEvent) { |
| 2697 if (this.associationEventHandler_) { |
| 2698 var handler = this.associationEventHandler_; |
| 2699 this.associationEventHandler_ = null; |
| 2700 handler(associationEvent); |
| 2701 } |
| 2702 }; |
| 2703 |
| 2704 State.prototype.setAssociationEventHandler = function(handler) { |
| 2705 if (!this.pendingAssociation && |
| 2706 !internal.isValidInterfaceId(this.interfaceId)) { |
| 2707 return; |
| 2708 } |
| 2709 |
| 2710 if (!handler) { |
| 2711 this.associationEventHandler_ = null; |
| 2712 return; |
| 2713 } |
| 2714 |
| 2715 this.associationEventHandler_ = handler; |
| 2716 if (!this.pendingAssociation) { |
| 2717 setTimeout(this.runAssociationEventHandler.bind(this, |
| 2718 AssociationEvent.ASSOCIATED), 0); |
| 2719 } else if (!this.peerState_) { |
| 2720 setTimeout(this.runAssociationEventHandler.bind(this, |
| 2721 AssociationEvent.PEER_CLOSED_BEFORE_ASSOCIATION), 0); |
| 2722 } |
| 2723 }; |
| 2724 |
| 2725 State.prototype.notifyAssociation = function(interfaceId, |
| 2726 peerGroupController) { |
| 2727 var cachedPeerState = this.peerState_; |
| 2728 this.peerState_ = null; |
| 2729 |
| 2730 this.pendingAssociation = false; |
| 2731 |
| 2732 if (cachedPeerState) { |
| 2733 cachedPeerState.onAssociated(interfaceId, peerGroupController); |
| 2734 return true; |
| 2735 } |
| 2736 return false; |
| 2737 }; |
| 2738 |
| 2739 State.prototype.onAssociated = function(interfaceId, |
| 2740 associatedGroupController) { |
| 2741 if (!this.pendingAssociation) { |
| 2742 return; |
| 2743 } |
| 2744 |
| 2745 this.pendingAssociation = false; |
| 2746 this.peerState_ = null; |
| 2747 this.interfaceId = interfaceId; |
| 2748 this.associatedGroupController = associatedGroupController; |
| 2749 this.runAssociationEventHandler(AssociationEvent.ASSOCIATED); |
| 2750 }; |
| 2751 |
| 2752 State.prototype.onPeerClosedBeforeAssociation = function(disconnectReason) { |
| 2753 if (!this.pendingAssociation) { |
| 2754 return; |
| 2755 } |
| 2756 |
| 2757 this.peerState_ = null; |
| 2758 this.disconnectReason = disconnectReason; |
| 2759 |
| 2760 this.runAssociationEventHandler( |
| 2761 AssociationEvent.PEER_CLOSED_BEFORE_ASSOCIATION); |
| 2762 }; |
| 2763 |
| 2764 function createPairPendingAssociation() { |
| 2765 var handle0 = new InterfaceEndpointHandle(); |
| 2766 var handle1 = new InterfaceEndpointHandle(); |
| 2767 handle0.state_.initPendingState(handle1.state_); |
| 2768 handle1.state_.initPendingState(handle0.state_); |
| 2769 return {handle0: handle0, handle1: handle1}; |
| 2770 } |
| 2771 |
| 2772 function InterfaceEndpointHandle(interfaceId, associatedGroupController) { |
| 2773 this.state_ = new State(interfaceId, associatedGroupController); |
| 2774 } |
| 2775 |
| 2776 InterfaceEndpointHandle.prototype.isValid = function() { |
| 2777 return this.state_.isValid(); |
| 2778 }; |
| 2779 |
| 2780 InterfaceEndpointHandle.prototype.pendingAssociation = function() { |
| 2781 return this.state_.pendingAssociation; |
| 2782 }; |
| 2783 |
| 2784 InterfaceEndpointHandle.prototype.id = function() { |
| 2785 return this.state_.interfaceId; |
| 2786 }; |
| 2787 |
| 2788 InterfaceEndpointHandle.prototype.groupController = function() { |
| 2789 return this.state_.associatedGroupController; |
| 2790 }; |
| 2791 |
| 2792 InterfaceEndpointHandle.prototype.disconnectReason = function() { |
| 2793 return this.state_.disconnectReason; |
| 2794 }; |
| 2795 |
| 2796 InterfaceEndpointHandle.prototype.setAssociationEventHandler = function( |
| 2797 handler) { |
| 2798 this.state_.setAssociationEventHandler(handler); |
| 2799 }; |
| 2800 |
| 2801 InterfaceEndpointHandle.prototype.notifyAssociation = function(interfaceId, |
| 2802 peerGroupController) { |
| 2803 return this.state_.notifyAssociation(interfaceId, peerGroupController); |
| 2804 }; |
| 2805 |
| 2806 InterfaceEndpointHandle.prototype.reset = function(reason) { |
| 2807 this.state_.close(reason); |
| 2808 this.state_ = new State(); |
| 2809 }; |
| 2810 |
| 2811 internal.AssociationEvent = AssociationEvent; |
| 2812 internal.InterfaceEndpointHandle = InterfaceEndpointHandle; |
| 2813 internal.createPairPendingAssociation = createPairPendingAssociation; |
| 2814 })(); |
| 2815 // Copyright 2017 The Chromium Authors. All rights reserved. |
| 2816 // Use of this source code is governed by a BSD-style license that can be |
| 2817 // found in the LICENSE file. |
| 2818 |
| 2819 (function() { |
| 2820 var internal = mojo.internal; |
| 2821 |
| 2822 function validateControlRequestWithoutResponse(message) { |
| 2823 var messageValidator = new internal.Validator(message); |
| 2824 var error = messageValidator.validateMessageIsRequestWithoutResponse(); |
| 2825 if (error != internal.validationError.NONE) { |
| 2826 throw error; |
| 2827 } |
| 2828 |
| 2829 if (message.getName() != mojo.pipeControl2.kRunOrClosePipeMessageId) { |
| 2830 throw new Error("Control message name is not kRunOrClosePipeMessageId"); |
| 2831 } |
| 2832 |
| 2833 // Validate payload. |
| 2834 error = mojo.pipeControl2.RunOrClosePipeMessageParams.validate( |
| 2835 messageValidator, message.getHeaderNumBytes()); |
| 2836 if (error != internal.validationError.NONE) { |
| 2837 throw error; |
| 2838 } |
| 2839 } |
| 2840 |
| 2841 function runOrClosePipe(message, delegate) { |
| 2842 var reader = new internal.MessageReader(message); |
| 2843 var runOrClosePipeMessageParams = reader.decodeStruct( |
| 2844 mojo.pipeControl2.RunOrClosePipeMessageParams); |
| 2845 var event = runOrClosePipeMessageParams.input |
| 2846 .peerAssociatedEndpointClosedEvent; |
| 2847 return delegate.onPeerAssociatedEndpointClosed(event.id, |
| 2848 event.disconnectReason); |
| 2849 } |
| 2850 |
| 2851 function isPipeControlMessage(message) { |
| 2852 return !internal.isValidInterfaceId(message.getInterfaceId()); |
| 2853 } |
| 2854 |
| 2855 function PipeControlMessageHandler(delegate) { |
| 2856 this.delegate_ = delegate; |
| 2857 } |
| 2858 |
| 2859 PipeControlMessageHandler.prototype.accept = function(message) { |
| 2860 validateControlRequestWithoutResponse(message); |
| 2861 return runOrClosePipe(message, this.delegate_); |
| 2862 }; |
| 2863 |
| 2864 internal.PipeControlMessageHandler = PipeControlMessageHandler; |
| 2865 internal.isPipeControlMessage = isPipeControlMessage; |
| 2866 })(); |
| 2867 // Copyright 2017 The Chromium Authors. All rights reserved. |
| 2868 // Use of this source code is governed by a BSD-style license that can be |
| 2869 // found in the LICENSE file. |
| 2870 |
| 2871 (function() { |
| 2872 var internal = mojo.internal; |
| 2873 |
| 2874 function constructRunOrClosePipeMessage(runOrClosePipeInput) { |
| 2875 var runOrClosePipeMessageParams = new |
| 2876 mojo.pipeControl2.RunOrClosePipeMessageParams(); |
| 2877 runOrClosePipeMessageParams.input = runOrClosePipeInput; |
| 2878 |
| 2879 var messageName = mojo.pipeControl2.kRunOrClosePipeMessageId; |
| 2880 var payloadSize = |
| 2881 mojo.pipeControl2.RunOrClosePipeMessageParams.encodedSize; |
| 2882 |
| 2883 var builder = new internal.MessageV0Builder(messageName, payloadSize); |
| 2884 builder.encodeStruct(mojo.pipeControl2.RunOrClosePipeMessageParams, |
| 2885 runOrClosePipeMessageParams); |
| 2886 var message = builder.finish(); |
| 2887 message.setInterfaceId(internal.kInvalidInterfaceId); |
| 2888 return message; |
| 2889 } |
| 2890 |
| 2891 function PipeControlMessageProxy(receiver) { |
| 2892 this.receiver_ = receiver; |
| 2893 } |
| 2894 |
| 2895 PipeControlMessageProxy.prototype.notifyPeerEndpointClosed = function( |
| 2896 interfaceId, reason) { |
| 2897 var message = this.constructPeerEndpointClosedMessage(interfaceId, reason); |
| 2898 this.receiver_.accept(message); |
| 2899 }; |
| 2900 |
| 2901 PipeControlMessageProxy.prototype.constructPeerEndpointClosedMessage = |
| 2902 function(interfaceId, reason) { |
| 2903 var event = new mojo.pipeControl2.PeerAssociatedEndpointClosedEvent(); |
| 2904 event.id = interfaceId; |
| 2905 if (reason) { |
| 2906 event.disconnectReason = new mojo.pipeControl2.DisconnectReason({ |
| 2907 customReason: reason.customReason, |
| 2908 description: reason.description}); |
| 2909 } |
| 2910 var runOrClosePipeInput = new mojo.pipeControl2.RunOrClosePipeInput(); |
| 2911 runOrClosePipeInput.peerAssociatedEndpointClosedEvent = event; |
| 2912 return constructRunOrClosePipeMessage(runOrClosePipeInput); |
| 2913 }; |
| 2914 |
| 2915 internal.PipeControlMessageProxy = PipeControlMessageProxy; |
| 2916 })(); |
| 2917 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2918 // Use of this source code is governed by a BSD-style license that can be |
| 2919 // found in the LICENSE file. |
| 2920 |
| 2921 (function() { |
| 2922 var internal = mojo.internal; |
| 2923 |
| 2924 /** |
| 2925 * The state of |endpoint|. If both the endpoint and its peer have been |
| 2926 * closed, removes it from |endpoints_|. |
| 2927 * @enum {string} |
| 2928 */ |
| 2929 var EndpointStateUpdateType = { |
| 2930 ENDPOINT_CLOSED: 'endpoint_closed', |
| 2931 PEER_ENDPOINT_CLOSED: 'peer_endpoint_closed' |
| 2932 }; |
| 2933 |
| 2934 function check(condition, output) { |
| 2935 if (!condition) { |
| 2936 // testharness.js does not rethrow errors so the error stack needs to be |
| 2937 // included as a string in the error we throw for debugging layout tests. |
| 2938 throw new Error((new Error()).stack); |
| 2939 } |
| 2940 } |
| 2941 |
| 2942 function InterfaceEndpoint(router, interfaceId) { |
| 2943 this.router_ = router; |
| 2944 this.id = interfaceId; |
| 2945 this.closed = false; |
| 2946 this.peerClosed = false; |
| 2947 this.handleCreated = false; |
| 2948 this.disconnectReason = null; |
| 2949 this.client = null; |
| 2950 } |
| 2951 |
| 2952 InterfaceEndpoint.prototype.sendMessage = function(message) { |
| 2953 message.setInterfaceId(this.id); |
| 2954 return this.router_.connector_.accept(message); |
| 2955 }; |
| 2956 |
| 2957 function Router(handle, setInterfaceIdNamespaceBit) { |
| 2958 if (!(handle instanceof MojoHandle)) { |
| 2959 throw new Error("Router constructor: Not a handle"); |
| 2960 } |
| 2961 if (setInterfaceIdNamespaceBit === undefined) { |
| 2962 setInterfaceIdNamespaceBit = false; |
| 2963 } |
| 2964 |
| 2965 this.connector_ = new internal.Connector(handle); |
| 2966 |
| 2967 this.connector_.setIncomingReceiver({ |
| 2968 accept: this.accept.bind(this), |
| 2969 }); |
| 2970 this.connector_.setErrorHandler({ |
| 2971 onError: this.onPipeConnectionError.bind(this), |
| 2972 }); |
| 2973 |
| 2974 this.setInterfaceIdNamespaceBit_ = setInterfaceIdNamespaceBit; |
| 2975 // |cachedMessageData| caches infomation about a message, so it can be |
| 2976 // processed later if a client is not yet attached to the target endpoint. |
| 2977 this.cachedMessageData = null; |
| 2978 this.controlMessageHandler_ = new internal.PipeControlMessageHandler(this); |
| 2979 this.controlMessageProxy_ = |
| 2980 new internal.PipeControlMessageProxy(this.connector_); |
| 2981 this.nextInterfaceIdValue_ = 1; |
| 2982 this.encounteredError_ = false; |
| 2983 this.endpoints_ = new Map(); |
| 2984 } |
| 2985 |
| 2986 Router.prototype.associateInterface = function(handleToSend) { |
| 2987 if (!handleToSend.pendingAssociation()) { |
| 2988 return internal.kInvalidInterfaceId; |
| 2989 } |
| 2990 |
| 2991 var id = 0; |
| 2992 do { |
| 2993 if (this.nextInterfaceIdValue_ >= internal.kInterfaceIdNamespaceMask) { |
| 2994 this.nextInterfaceIdValue_ = 1; |
| 2995 } |
| 2996 id = this.nextInterfaceIdValue_++; |
| 2997 if (this.setInterfaceIdNamespaceBit_) { |
| 2998 id += internal.kInterfaceIdNamespaceMask; |
| 2999 } |
| 3000 } while (this.endpoints_.has(id)); |
| 3001 |
| 3002 var endpoint = new InterfaceEndpoint(this, id); |
| 3003 this.endpoints_.set(id, endpoint); |
| 3004 if (this.encounteredError_) { |
| 3005 this.updateEndpointStateMayRemove(endpoint, |
| 3006 EndpointStateUpdateType.PEER_ENDPOINT_CLOSED); |
| 3007 } |
| 3008 endpoint.handleCreated = true; |
| 3009 |
| 3010 if (!handleToSend.notifyAssociation(id, this)) { |
| 3011 // The peer handle of |handleToSend|, which is supposed to join this |
| 3012 // associated group, has been closed. |
| 3013 this.updateEndpointStateMayRemove(endpoint, |
| 3014 EndpointStateUpdateType.ENDPOINT_CLOSED); |
| 3015 |
| 3016 pipeControlMessageproxy.notifyPeerEndpointClosed(id, |
| 3017 handleToSend.disconnectReason()); |
| 3018 } |
| 3019 |
| 3020 return id; |
| 3021 }; |
| 3022 |
| 3023 Router.prototype.attachEndpointClient = function( |
| 3024 interfaceEndpointHandle, interfaceEndpointClient) { |
| 3025 check(internal.isValidInterfaceId(interfaceEndpointHandle.id())); |
| 3026 check(interfaceEndpointClient); |
| 3027 |
| 3028 var endpoint = this.endpoints_.get(interfaceEndpointHandle.id()); |
| 3029 check(endpoint); |
| 3030 check(!endpoint.client); |
| 3031 check(!endpoint.closed); |
| 3032 endpoint.client = interfaceEndpointClient; |
| 3033 |
| 3034 if (endpoint.peerClosed) { |
| 3035 setTimeout(endpoint.client.notifyError.bind(endpoint.client), 0); |
| 3036 } |
| 3037 |
| 3038 if (this.cachedMessageData && interfaceEndpointHandle.id() === |
| 3039 this.cachedMessageData.message.getInterfaceId()) { |
| 3040 setTimeout((function() { |
| 3041 if (!this.cachedMessageData) { |
| 3042 return; |
| 3043 } |
| 3044 |
| 3045 var targetEndpoint = this.endpoints_.get( |
| 3046 this.cachedMessageData.message.getInterfaceId()); |
| 3047 // Check that the target endpoint's client still exists. |
| 3048 if (targetEndpoint && targetEndpoint.client) { |
| 3049 var message = this.cachedMessageData.message; |
| 3050 var messageValidator = this.cachedMessageData.messageValidator; |
| 3051 this.cachedMessageData = null; |
| 3052 this.connector_.resumeIncomingMethodCallProcessing(); |
| 3053 var ok = endpoint.client.handleIncomingMessage(message, |
| 3054 messageValidator); |
| 3055 |
| 3056 // Handle invalid cached incoming message. |
| 3057 if (!internal.isTestingMode() && !ok) { |
| 3058 this.connector_.handleError(true, true); |
| 3059 } |
| 3060 } |
| 3061 }).bind(this), 0); |
| 3062 } |
| 3063 |
| 3064 return endpoint; |
| 3065 }; |
| 3066 |
| 3067 Router.prototype.detachEndpointClient = function( |
| 3068 interfaceEndpointHandle) { |
| 3069 check(internal.isValidInterfaceId(interfaceEndpointHandle.id())); |
| 3070 var endpoint = this.endpoints_.get(interfaceEndpointHandle.id()); |
| 3071 check(endpoint); |
| 3072 check(endpoint.client); |
| 3073 check(!endpoint.closed); |
| 3074 |
| 3075 endpoint.client = null; |
| 3076 }; |
| 3077 |
| 3078 Router.prototype.createLocalEndpointHandle = function( |
| 3079 interfaceId) { |
| 3080 if (!internal.isValidInterfaceId(interfaceId)) { |
| 3081 return new internal.InterfaceEndpointHandle(); |
| 3082 } |
| 3083 |
| 3084 var endpoint = this.endpoints_.get(interfaceId); |
| 3085 |
| 3086 if (!endpoint) { |
| 3087 endpoint = new InterfaceEndpoint(this, interfaceId); |
| 3088 this.endpoints_.set(interfaceId, endpoint); |
| 3089 |
| 3090 check(!endpoint.handleCreated); |
| 3091 |
| 3092 if (this.encounteredError_) { |
| 3093 this.updateEndpointStateMayRemove(endpoint, |
| 3094 EndpointStateUpdateType.PEER_ENDPOINT_CLOSED); |
| 3095 } |
| 3096 } else { |
| 3097 // If the endpoint already exist, it is because we have received a |
| 3098 // notification that the peer endpoint has closed. |
| 3099 check(!endpoint.closed); |
| 3100 check(endpoint.peerClosed); |
| 3101 |
| 3102 if (endpoint.handleCreated) { |
| 3103 return new internal.InterfaceEndpointHandle(); |
| 3104 } |
| 3105 } |
| 3106 |
| 3107 endpoint.handleCreated = true; |
| 3108 return new internal.InterfaceEndpointHandle(interfaceId, this); |
| 3109 }; |
| 3110 |
| 3111 Router.prototype.accept = function(message) { |
| 3112 var messageValidator = new internal.Validator(message); |
| 3113 var err = messageValidator.validateMessageHeader(); |
| 3114 |
| 3115 var ok = false; |
| 3116 if (err !== internal.validationError.NONE) { |
| 3117 internal.reportValidationError(err); |
| 3118 } else if (message.deserializeAssociatedEndpointHandles(this)) { |
| 3119 if (internal.isPipeControlMessage(message)) { |
| 3120 ok = this.controlMessageHandler_.accept(message); |
| 3121 } else { |
| 3122 var interfaceId = message.getInterfaceId(); |
| 3123 var endpoint = this.endpoints_.get(interfaceId); |
| 3124 if (!endpoint || endpoint.closed) { |
| 3125 return true; |
| 3126 } |
| 3127 |
| 3128 if (!endpoint.client) { |
| 3129 // We need to wait until a client is attached in order to dispatch |
| 3130 // further messages. |
| 3131 this.cachedMessageData = {message: message, |
| 3132 messageValidator: messageValidator}; |
| 3133 this.connector_.pauseIncomingMethodCallProcessing(); |
| 3134 return true; |
| 3135 } |
| 3136 ok = endpoint.client.handleIncomingMessage(message, messageValidator); |
| 3137 } |
| 3138 } |
| 3139 return ok; |
| 3140 }; |
| 3141 |
| 3142 Router.prototype.close = function() { |
| 3143 this.connector_.close(); |
| 3144 // Closing the message pipe won't trigger connection error handler. |
| 3145 // Explicitly call onPipeConnectionError() so that associated endpoints |
| 3146 // will get notified. |
| 3147 this.onPipeConnectionError(); |
| 3148 }; |
| 3149 |
| 3150 Router.prototype.onPeerAssociatedEndpointClosed = function(interfaceId, |
| 3151 reason) { |
| 3152 check(!internal.isMasterInterfaceId(interfaceId) || reason); |
| 3153 |
| 3154 var endpoint = this.endpoints_.get(interfaceId); |
| 3155 if (!endpoint) { |
| 3156 endpoint = new InterfaceEndpoint(this, interfaceId); |
| 3157 this.endpoints_.set(interfaceId, endpoint); |
| 3158 } |
| 3159 |
| 3160 if (reason) { |
| 3161 endpoint.disconnectReason = reason; |
| 3162 } |
| 3163 |
| 3164 if (!endpoint.peerClosed) { |
| 3165 if (endpoint.client) { |
| 3166 setTimeout(endpoint.client.notifyError.bind(endpoint.client, reason), |
| 3167 0); |
| 3168 } |
| 3169 this.updateEndpointStateMayRemove(endpoint, |
| 3170 EndpointStateUpdateType.PEER_ENDPOINT_CLOSED); |
| 3171 } |
| 3172 return true; |
| 3173 }; |
| 3174 |
| 3175 Router.prototype.onPipeConnectionError = function() { |
| 3176 this.encounteredError_ = true; |
| 3177 |
| 3178 for (var endpoint of this.endpoints_.values()) { |
| 3179 if (endpoint.client) { |
| 3180 setTimeout( |
| 3181 endpoint.client.notifyError.bind( |
| 3182 endpoint.client, endpoint.disconnectReason), |
| 3183 0); |
| 3184 } |
| 3185 this.updateEndpointStateMayRemove(endpoint, |
| 3186 EndpointStateUpdateType.PEER_ENDPOINT_CLOSED); |
| 3187 } |
| 3188 }; |
| 3189 |
| 3190 Router.prototype.closeEndpointHandle = function(interfaceId, reason) { |
| 3191 if (!internal.isValidInterfaceId(interfaceId)) { |
| 3192 return; |
| 3193 } |
| 3194 var endpoint = this.endpoints_.get(interfaceId); |
| 3195 check(endpoint); |
| 3196 check(!endpoint.client); |
| 3197 check(!endpoint.closed); |
| 3198 |
| 3199 this.updateEndpointStateMayRemove(endpoint, |
| 3200 EndpointStateUpdateType.ENDPOINT_CLOSED); |
| 3201 |
| 3202 if (!internal.isMasterInterfaceId(interfaceId) || reason) { |
| 3203 this.controlMessageProxy_.notifyPeerEndpointClosed(interfaceId, reason); |
| 3204 } |
| 3205 |
| 3206 if (this.cachedMessageData && interfaceId === |
| 3207 this.cachedMessageData.message.getInterfaceId()) { |
| 3208 this.cachedMessageData = null; |
| 3209 this.connector_.resumeIncomingMethodCallProcessing(); |
| 3210 } |
| 3211 }; |
| 3212 |
| 3213 Router.prototype.updateEndpointStateMayRemove = function(endpoint, |
| 3214 endpointStateUpdateType) { |
| 3215 if (endpointStateUpdateType === EndpointStateUpdateType.ENDPOINT_CLOSED) { |
| 3216 endpoint.closed = true; |
| 3217 } else { |
| 3218 endpoint.peerClosed = true; |
| 3219 } |
| 3220 if (endpoint.closed && endpoint.peerClosed) { |
| 3221 this.endpoints_.delete(endpoint.id); |
| 3222 } |
| 3223 }; |
| 3224 |
| 3225 internal.Router = Router; |
| 3226 })(); |
| 3227 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 3228 // Use of this source code is governed by a BSD-style license that can be |
| 3229 // found in the LICENSE file. |
| 3230 |
| 3231 /** |
| 3232 * Defines functions for translating between JavaScript strings and UTF8 strings |
| 3233 * stored in ArrayBuffers. There is much room for optimization in this code if |
| 3234 * it proves necessary. |
| 3235 */ |
| 3236 (function() { |
| 3237 var internal = mojo.internal; |
| 3238 |
| 3239 /** |
| 3240 * Decodes the UTF8 string from the given buffer. |
| 3241 * @param {ArrayBufferView} buffer The buffer containing UTF8 string data. |
| 3242 * @return {string} The corresponding JavaScript string. |
| 3243 */ |
| 3244 function decodeUtf8String(buffer) { |
| 3245 return decodeURIComponent(escape(String.fromCharCode.apply(null, buffer))); |
| 3246 } |
| 3247 |
| 3248 /** |
| 3249 * Encodes the given JavaScript string into UTF8. |
| 3250 * @param {string} str The string to encode. |
| 3251 * @param {ArrayBufferView} outputBuffer The buffer to contain the result. |
| 3252 * Should be pre-allocated to hold enough space. Use |utf8Length| to determine |
| 3253 * how much space is required. |
| 3254 * @return {number} The number of bytes written to |outputBuffer|. |
| 3255 */ |
| 3256 function encodeUtf8String(str, outputBuffer) { |
| 3257 var utf8String = unescape(encodeURIComponent(str)); |
| 3258 if (outputBuffer.length < utf8String.length) |
| 3259 throw new Error("Buffer too small for encodeUtf8String"); |
| 3260 for (var i = 0; i < outputBuffer.length && i < utf8String.length; i++) |
| 3261 outputBuffer[i] = utf8String.charCodeAt(i); |
| 3262 return i; |
| 3263 } |
| 3264 |
| 3265 /** |
| 3266 * Returns the number of bytes that a UTF8 encoding of the JavaScript string |
| 3267 * |str| would occupy. |
| 3268 */ |
| 3269 function utf8Length(str) { |
| 3270 var utf8String = unescape(encodeURIComponent(str)); |
| 3271 return utf8String.length; |
| 3272 } |
| 3273 |
| 3274 internal.decodeUtf8String = decodeUtf8String; |
| 3275 internal.encodeUtf8String = encodeUtf8String; |
| 3276 internal.utf8Length = utf8Length; |
| 3277 })(); |
| 3278 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 3279 // Use of this source code is governed by a BSD-style license that can be |
| 3280 // found in the LICENSE file. |
| 3281 |
| 3282 (function() { |
| 3283 var internal = mojo.internal; |
| 3284 |
| 3285 var validationError = { |
| 3286 NONE: 'VALIDATION_ERROR_NONE', |
| 3287 MISALIGNED_OBJECT: 'VALIDATION_ERROR_MISALIGNED_OBJECT', |
| 3288 ILLEGAL_MEMORY_RANGE: 'VALIDATION_ERROR_ILLEGAL_MEMORY_RANGE', |
| 3289 UNEXPECTED_STRUCT_HEADER: 'VALIDATION_ERROR_UNEXPECTED_STRUCT_HEADER', |
| 3290 UNEXPECTED_ARRAY_HEADER: 'VALIDATION_ERROR_UNEXPECTED_ARRAY_HEADER', |
| 3291 ILLEGAL_HANDLE: 'VALIDATION_ERROR_ILLEGAL_HANDLE', |
| 3292 UNEXPECTED_INVALID_HANDLE: 'VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE', |
| 3293 ILLEGAL_POINTER: 'VALIDATION_ERROR_ILLEGAL_POINTER', |
| 3294 UNEXPECTED_NULL_POINTER: 'VALIDATION_ERROR_UNEXPECTED_NULL_POINTER', |
| 3295 ILLEGAL_INTERFACE_ID: 'VALIDATION_ERROR_ILLEGAL_INTERFACE_ID', |
| 3296 UNEXPECTED_INVALID_INTERFACE_ID: |
| 3297 'VALIDATION_ERROR_UNEXPECTED_INVALID_INTERFACE_ID', |
| 3298 MESSAGE_HEADER_INVALID_FLAGS: |
| 3299 'VALIDATION_ERROR_MESSAGE_HEADER_INVALID_FLAGS', |
| 3300 MESSAGE_HEADER_MISSING_REQUEST_ID: |
| 3301 'VALIDATION_ERROR_MESSAGE_HEADER_MISSING_REQUEST_ID', |
| 3302 DIFFERENT_SIZED_ARRAYS_IN_MAP: |
| 3303 'VALIDATION_ERROR_DIFFERENT_SIZED_ARRAYS_IN_MAP', |
| 3304 INVALID_UNION_SIZE: 'VALIDATION_ERROR_INVALID_UNION_SIZE', |
| 3305 UNEXPECTED_NULL_UNION: 'VALIDATION_ERROR_UNEXPECTED_NULL_UNION', |
| 3306 UNKNOWN_ENUM_VALUE: 'VALIDATION_ERROR_UNKNOWN_ENUM_VALUE', |
| 3307 }; |
| 3308 |
| 3309 var NULL_MOJO_POINTER = "NULL_MOJO_POINTER"; |
| 3310 var gValidationErrorObserver = null; |
| 3311 |
| 3312 function reportValidationError(error) { |
| 3313 if (gValidationErrorObserver) { |
| 3314 gValidationErrorObserver.lastError = error; |
| 3315 } else { |
| 3316 console.warn('Invalid message: ' + error); |
| 3317 } |
| 3318 } |
| 3319 |
| 3320 var ValidationErrorObserverForTesting = (function() { |
| 3321 function Observer() { |
| 3322 this.lastError = validationError.NONE; |
| 3323 } |
| 3324 |
| 3325 Observer.prototype.reset = function() { |
| 3326 this.lastError = validationError.NONE; |
| 3327 }; |
| 3328 |
| 3329 return { |
| 3330 getInstance: function() { |
| 3331 if (!gValidationErrorObserver) { |
| 3332 gValidationErrorObserver = new Observer(); |
| 3333 } |
| 3334 return gValidationErrorObserver; |
| 3335 } |
| 3336 }; |
| 3337 })(); |
| 3338 |
| 3339 function isTestingMode() { |
| 3340 return Boolean(gValidationErrorObserver); |
| 3341 } |
| 3342 |
| 3343 function clearTestingMode() { |
| 3344 gValidationErrorObserver = null; |
| 3345 } |
| 3346 |
| 3347 function isEnumClass(cls) { |
| 3348 return cls instanceof internal.Enum; |
| 3349 } |
| 3350 |
| 3351 function isStringClass(cls) { |
| 3352 return cls === internal.String || cls === internal.NullableString; |
| 3353 } |
| 3354 |
| 3355 function isHandleClass(cls) { |
| 3356 return cls === internal.Handle || cls === internal.NullableHandle; |
| 3357 } |
| 3358 |
| 3359 function isInterfaceClass(cls) { |
| 3360 return cls instanceof internal.Interface; |
| 3361 } |
| 3362 |
| 3363 function isInterfaceRequestClass(cls) { |
| 3364 return cls === internal.InterfaceRequest || |
| 3365 cls === internal.NullableInterfaceRequest; |
| 3366 } |
| 3367 |
| 3368 function isAssociatedInterfaceClass(cls) { |
| 3369 return cls === internal.AssociatedInterfacePtrInfo || |
| 3370 cls === internal.NullableAssociatedInterfacePtrInfo; |
| 3371 } |
| 3372 |
| 3373 function isAssociatedInterfaceRequestClass(cls) { |
| 3374 return cls === internal.AssociatedInterfaceRequest || |
| 3375 cls === internal.NullableAssociatedInterfaceRequest; |
| 3376 } |
| 3377 |
| 3378 function isNullable(type) { |
| 3379 return type === internal.NullableString || |
| 3380 type === internal.NullableHandle || |
| 3381 type === internal.NullableAssociatedInterfacePtrInfo || |
| 3382 type === internal.NullableAssociatedInterfaceRequest || |
| 3383 type === internal.NullableInterface || |
| 3384 type === internal.NullableInterfaceRequest || |
| 3385 type instanceof internal.NullableArrayOf || |
| 3386 type instanceof internal.NullablePointerTo; |
| 3387 } |
| 3388 |
| 3389 function Validator(message) { |
| 3390 this.message = message; |
| 3391 this.offset = 0; |
| 3392 this.handleIndex = 0; |
| 3393 this.associatedEndpointHandleIndex = 0; |
| 3394 this.payloadInterfaceIds = null; |
| 3395 this.offsetLimit = this.message.buffer.byteLength; |
| 3396 } |
| 3397 |
| 3398 Object.defineProperty(Validator.prototype, "handleIndexLimit", { |
| 3399 get: function() { return this.message.handles.length; } |
| 3400 }); |
| 3401 |
| 3402 Object.defineProperty(Validator.prototype, "associatedHandleIndexLimit", { |
| 3403 get: function() { |
| 3404 return this.payloadInterfaceIds ? this.payloadInterfaceIds.length : 0; |
| 3405 } |
| 3406 }); |
| 3407 |
| 3408 // True if we can safely allocate a block of bytes from start to |
| 3409 // to start + numBytes. |
| 3410 Validator.prototype.isValidRange = function(start, numBytes) { |
| 3411 // Only positive JavaScript integers that are less than 2^53 |
| 3412 // (Number.MAX_SAFE_INTEGER) can be represented exactly. |
| 3413 if (start < this.offset || numBytes <= 0 || |
| 3414 !Number.isSafeInteger(start) || |
| 3415 !Number.isSafeInteger(numBytes)) |
| 3416 return false; |
| 3417 |
| 3418 var newOffset = start + numBytes; |
| 3419 if (!Number.isSafeInteger(newOffset) || newOffset > this.offsetLimit) |
| 3420 return false; |
| 3421 |
| 3422 return true; |
| 3423 }; |
| 3424 |
| 3425 Validator.prototype.claimRange = function(start, numBytes) { |
| 3426 if (this.isValidRange(start, numBytes)) { |
| 3427 this.offset = start + numBytes; |
| 3428 return true; |
| 3429 } |
| 3430 return false; |
| 3431 }; |
| 3432 |
| 3433 Validator.prototype.claimHandle = function(index) { |
| 3434 if (index === internal.kEncodedInvalidHandleValue) |
| 3435 return true; |
| 3436 |
| 3437 if (index < this.handleIndex || index >= this.handleIndexLimit) |
| 3438 return false; |
| 3439 |
| 3440 // This is safe because handle indices are uint32. |
| 3441 this.handleIndex = index + 1; |
| 3442 return true; |
| 3443 }; |
| 3444 |
| 3445 Validator.prototype.claimAssociatedEndpointHandle = function(index) { |
| 3446 if (index === internal.kEncodedInvalidHandleValue) { |
| 3447 return true; |
| 3448 } |
| 3449 |
| 3450 if (index < this.associatedEndpointHandleIndex || |
| 3451 index >= this.associatedHandleIndexLimit) { |
| 3452 return false; |
| 3453 } |
| 3454 |
| 3455 // This is safe because handle indices are uint32. |
| 3456 this.associatedEndpointHandleIndex = index + 1; |
| 3457 return true; |
| 3458 }; |
| 3459 |
| 3460 Validator.prototype.validateEnum = function(offset, enumClass) { |
| 3461 // Note: Assumes that enums are always 32 bits! But this matches |
| 3462 // mojom::generate::pack::PackedField::GetSizeForKind, so it should be okay. |
| 3463 var value = this.message.buffer.getInt32(offset); |
| 3464 return enumClass.validate(value); |
| 3465 } |
| 3466 |
| 3467 Validator.prototype.validateHandle = function(offset, nullable) { |
| 3468 var index = this.message.buffer.getUint32(offset); |
| 3469 |
| 3470 if (index === internal.kEncodedInvalidHandleValue) |
| 3471 return nullable ? |
| 3472 validationError.NONE : validationError.UNEXPECTED_INVALID_HANDLE; |
| 3473 |
| 3474 if (!this.claimHandle(index)) |
| 3475 return validationError.ILLEGAL_HANDLE; |
| 3476 |
| 3477 return validationError.NONE; |
| 3478 }; |
| 3479 |
| 3480 Validator.prototype.validateAssociatedEndpointHandle = function(offset, |
| 3481 nullable) { |
| 3482 var index = this.message.buffer.getUint32(offset); |
| 3483 |
| 3484 if (index === internal.kEncodedInvalidHandleValue) { |
| 3485 return nullable ? validationError.NONE : |
| 3486 validationError.UNEXPECTED_INVALID_INTERFACE_ID; |
| 3487 } |
| 3488 |
| 3489 if (!this.claimAssociatedEndpointHandle(index)) { |
| 3490 return validationError.ILLEGAL_INTERFACE_ID; |
| 3491 } |
| 3492 |
| 3493 return validationError.NONE; |
| 3494 }; |
| 3495 |
| 3496 Validator.prototype.validateInterface = function(offset, nullable) { |
| 3497 return this.validateHandle(offset, nullable); |
| 3498 }; |
| 3499 |
| 3500 Validator.prototype.validateInterfaceRequest = function(offset, nullable) { |
| 3501 return this.validateHandle(offset, nullable); |
| 3502 }; |
| 3503 |
| 3504 Validator.prototype.validateAssociatedInterface = function(offset, |
| 3505 nullable) { |
| 3506 return this.validateAssociatedEndpointHandle(offset, nullable); |
| 3507 }; |
| 3508 |
| 3509 Validator.prototype.validateAssociatedInterfaceRequest = function( |
| 3510 offset, nullable) { |
| 3511 return this.validateAssociatedEndpointHandle(offset, nullable); |
| 3512 }; |
| 3513 |
| 3514 Validator.prototype.validateStructHeader = function(offset, minNumBytes) { |
| 3515 if (!internal.isAligned(offset)) |
| 3516 return validationError.MISALIGNED_OBJECT; |
| 3517 |
| 3518 if (!this.isValidRange(offset, internal.kStructHeaderSize)) |
| 3519 return validationError.ILLEGAL_MEMORY_RANGE; |
| 3520 |
| 3521 var numBytes = this.message.buffer.getUint32(offset); |
| 3522 |
| 3523 if (numBytes < minNumBytes) |
| 3524 return validationError.UNEXPECTED_STRUCT_HEADER; |
| 3525 |
| 3526 if (!this.claimRange(offset, numBytes)) |
| 3527 return validationError.ILLEGAL_MEMORY_RANGE; |
| 3528 |
| 3529 return validationError.NONE; |
| 3530 }; |
| 3531 |
| 3532 Validator.prototype.validateStructVersion = function(offset, versionSizes) { |
| 3533 var numBytes = this.message.buffer.getUint32(offset); |
| 3534 var version = this.message.buffer.getUint32(offset + 4); |
| 3535 |
| 3536 if (version <= versionSizes[versionSizes.length - 1].version) { |
| 3537 // Scan in reverse order to optimize for more recent versionSizes. |
| 3538 for (var i = versionSizes.length - 1; i >= 0; --i) { |
| 3539 if (version >= versionSizes[i].version) { |
| 3540 if (numBytes == versionSizes[i].numBytes) |
| 3541 break; |
| 3542 return validationError.UNEXPECTED_STRUCT_HEADER; |
| 3543 } |
| 3544 } |
| 3545 } else if (numBytes < versionSizes[versionSizes.length-1].numBytes) { |
| 3546 return validationError.UNEXPECTED_STRUCT_HEADER; |
| 3547 } |
| 3548 |
| 3549 return validationError.NONE; |
| 3550 }; |
| 3551 |
| 3552 Validator.prototype.isFieldInStructVersion = function(offset, fieldVersion) { |
| 3553 var structVersion = this.message.buffer.getUint32(offset + 4); |
| 3554 return fieldVersion <= structVersion; |
| 3555 }; |
| 3556 |
| 3557 Validator.prototype.validateMessageHeader = function() { |
| 3558 var err = this.validateStructHeader(0, internal.kMessageV0HeaderSize); |
| 3559 if (err != validationError.NONE) { |
| 3560 return err; |
| 3561 } |
| 3562 |
| 3563 var numBytes = this.message.getHeaderNumBytes(); |
| 3564 var version = this.message.getHeaderVersion(); |
| 3565 |
| 3566 var validVersionAndNumBytes = |
| 3567 (version == 0 && numBytes == internal.kMessageV0HeaderSize) || |
| 3568 (version == 1 && numBytes == internal.kMessageV1HeaderSize) || |
| 3569 (version == 2 && numBytes == internal.kMessageV2HeaderSize) || |
| 3570 (version > 2 && numBytes >= internal.kMessageV2HeaderSize); |
| 3571 |
| 3572 if (!validVersionAndNumBytes) { |
| 3573 return validationError.UNEXPECTED_STRUCT_HEADER; |
| 3574 } |
| 3575 |
| 3576 var expectsResponse = this.message.expectsResponse(); |
| 3577 var isResponse = this.message.isResponse(); |
| 3578 |
| 3579 if (version == 0 && (expectsResponse || isResponse)) { |
| 3580 return validationError.MESSAGE_HEADER_MISSING_REQUEST_ID; |
| 3581 } |
| 3582 |
| 3583 if (isResponse && expectsResponse) { |
| 3584 return validationError.MESSAGE_HEADER_INVALID_FLAGS; |
| 3585 } |
| 3586 |
| 3587 if (version < 2) { |
| 3588 return validationError.NONE; |
| 3589 } |
| 3590 |
| 3591 var err = this.validateArrayPointer( |
| 3592 internal.kMessagePayloadInterfaceIdsPointerOffset, |
| 3593 internal.Uint32.encodedSize, internal.Uint32, true, [0], 0); |
| 3594 |
| 3595 if (err != validationError.NONE) { |
| 3596 return err; |
| 3597 } |
| 3598 |
| 3599 this.payloadInterfaceIds = this.message.getPayloadInterfaceIds(); |
| 3600 if (this.payloadInterfaceIds) { |
| 3601 for (var interfaceId of this.payloadInterfaceIds) { |
| 3602 if (!internal.isValidInterfaceId(interfaceId) || |
| 3603 internal.isMasterInterfaceId(interfaceId)) { |
| 3604 return validationError.ILLEGAL_INTERFACE_ID; |
| 3605 } |
| 3606 } |
| 3607 } |
| 3608 |
| 3609 // Set offset to the start of the payload and offsetLimit to the start of |
| 3610 // the payload interface Ids so that payload can be validated using the |
| 3611 // same messageValidator. |
| 3612 this.offset = this.message.getHeaderNumBytes(); |
| 3613 this.offsetLimit = this.decodePointer( |
| 3614 internal.kMessagePayloadInterfaceIdsPointerOffset); |
| 3615 |
| 3616 return validationError.NONE; |
| 3617 }; |
| 3618 |
| 3619 Validator.prototype.validateMessageIsRequestWithoutResponse = function() { |
| 3620 if (this.message.isResponse() || this.message.expectsResponse()) { |
| 3621 return validationError.MESSAGE_HEADER_INVALID_FLAGS; |
| 3622 } |
| 3623 return validationError.NONE; |
| 3624 }; |
| 3625 |
| 3626 Validator.prototype.validateMessageIsRequestExpectingResponse = function() { |
| 3627 if (this.message.isResponse() || !this.message.expectsResponse()) { |
| 3628 return validationError.MESSAGE_HEADER_INVALID_FLAGS; |
| 3629 } |
| 3630 return validationError.NONE; |
| 3631 }; |
| 3632 |
| 3633 Validator.prototype.validateMessageIsResponse = function() { |
| 3634 if (this.message.expectsResponse() || !this.message.isResponse()) { |
| 3635 return validationError.MESSAGE_HEADER_INVALID_FLAGS; |
| 3636 } |
| 3637 return validationError.NONE; |
| 3638 }; |
| 3639 |
| 3640 // Returns the message.buffer relative offset this pointer "points to", |
| 3641 // NULL_MOJO_POINTER if the pointer represents a null, or JS null if the |
| 3642 // pointer's value is not valid. |
| 3643 Validator.prototype.decodePointer = function(offset) { |
| 3644 var pointerValue = this.message.buffer.getUint64(offset); |
| 3645 if (pointerValue === 0) |
| 3646 return NULL_MOJO_POINTER; |
| 3647 var bufferOffset = offset + pointerValue; |
| 3648 return Number.isSafeInteger(bufferOffset) ? bufferOffset : null; |
| 3649 }; |
| 3650 |
| 3651 Validator.prototype.decodeUnionSize = function(offset) { |
| 3652 return this.message.buffer.getUint32(offset); |
| 3653 }; |
| 3654 |
| 3655 Validator.prototype.decodeUnionTag = function(offset) { |
| 3656 return this.message.buffer.getUint32(offset + 4); |
| 3657 }; |
| 3658 |
| 3659 Validator.prototype.validateArrayPointer = function( |
| 3660 offset, elementSize, elementType, nullable, expectedDimensionSizes, |
| 3661 currentDimension) { |
| 3662 var arrayOffset = this.decodePointer(offset); |
| 3663 if (arrayOffset === null) |
| 3664 return validationError.ILLEGAL_POINTER; |
| 3665 |
| 3666 if (arrayOffset === NULL_MOJO_POINTER) |
| 3667 return nullable ? |
| 3668 validationError.NONE : validationError.UNEXPECTED_NULL_POINTER; |
| 3669 |
| 3670 return this.validateArray(arrayOffset, elementSize, elementType, |
| 3671 expectedDimensionSizes, currentDimension); |
| 3672 }; |
| 3673 |
| 3674 Validator.prototype.validateStructPointer = function( |
| 3675 offset, structClass, nullable) { |
| 3676 var structOffset = this.decodePointer(offset); |
| 3677 if (structOffset === null) |
| 3678 return validationError.ILLEGAL_POINTER; |
| 3679 |
| 3680 if (structOffset === NULL_MOJO_POINTER) |
| 3681 return nullable ? |
| 3682 validationError.NONE : validationError.UNEXPECTED_NULL_POINTER; |
| 3683 |
| 3684 return structClass.validate(this, structOffset); |
| 3685 }; |
| 3686 |
| 3687 Validator.prototype.validateUnion = function( |
| 3688 offset, unionClass, nullable) { |
| 3689 var size = this.message.buffer.getUint32(offset); |
| 3690 if (size == 0) { |
| 3691 return nullable ? |
| 3692 validationError.NONE : validationError.UNEXPECTED_NULL_UNION; |
| 3693 } |
| 3694 |
| 3695 return unionClass.validate(this, offset); |
| 3696 }; |
| 3697 |
| 3698 Validator.prototype.validateNestedUnion = function( |
| 3699 offset, unionClass, nullable) { |
| 3700 var unionOffset = this.decodePointer(offset); |
| 3701 if (unionOffset === null) |
| 3702 return validationError.ILLEGAL_POINTER; |
| 3703 |
| 3704 if (unionOffset === NULL_MOJO_POINTER) |
| 3705 return nullable ? |
| 3706 validationError.NONE : validationError.UNEXPECTED_NULL_UNION; |
| 3707 |
| 3708 return this.validateUnion(unionOffset, unionClass, nullable); |
| 3709 }; |
| 3710 |
| 3711 // This method assumes that the array at arrayPointerOffset has |
| 3712 // been validated. |
| 3713 |
| 3714 Validator.prototype.arrayLength = function(arrayPointerOffset) { |
| 3715 var arrayOffset = this.decodePointer(arrayPointerOffset); |
| 3716 return this.message.buffer.getUint32(arrayOffset + 4); |
| 3717 }; |
| 3718 |
| 3719 Validator.prototype.validateMapPointer = function( |
| 3720 offset, mapIsNullable, keyClass, valueClass, valueIsNullable) { |
| 3721 // Validate the implicit map struct: |
| 3722 // struct {array<keyClass> keys; array<valueClass> values}; |
| 3723 var structOffset = this.decodePointer(offset); |
| 3724 if (structOffset === null) |
| 3725 return validationError.ILLEGAL_POINTER; |
| 3726 |
| 3727 if (structOffset === NULL_MOJO_POINTER) |
| 3728 return mapIsNullable ? |
| 3729 validationError.NONE : validationError.UNEXPECTED_NULL_POINTER; |
| 3730 |
| 3731 var mapEncodedSize = internal.kStructHeaderSize + |
| 3732 internal.kMapStructPayloadSize; |
| 3733 var err = this.validateStructHeader(structOffset, mapEncodedSize); |
| 3734 if (err !== validationError.NONE) |
| 3735 return err; |
| 3736 |
| 3737 // Validate the keys array. |
| 3738 var keysArrayPointerOffset = structOffset + internal.kStructHeaderSize; |
| 3739 err = this.validateArrayPointer( |
| 3740 keysArrayPointerOffset, keyClass.encodedSize, keyClass, false, [0], 0); |
| 3741 if (err !== validationError.NONE) |
| 3742 return err; |
| 3743 |
| 3744 // Validate the values array. |
| 3745 var valuesArrayPointerOffset = keysArrayPointerOffset + 8; |
| 3746 var valuesArrayDimensions = [0]; // Validate the actual length below. |
| 3747 if (valueClass instanceof internal.ArrayOf) |
| 3748 valuesArrayDimensions = |
| 3749 valuesArrayDimensions.concat(valueClass.dimensions()); |
| 3750 var err = this.validateArrayPointer(valuesArrayPointerOffset, |
| 3751 valueClass.encodedSize, |
| 3752 valueClass, |
| 3753 valueIsNullable, |
| 3754 valuesArrayDimensions, |
| 3755 0); |
| 3756 if (err !== validationError.NONE) |
| 3757 return err; |
| 3758 |
| 3759 // Validate the lengths of the keys and values arrays. |
| 3760 var keysArrayLength = this.arrayLength(keysArrayPointerOffset); |
| 3761 var valuesArrayLength = this.arrayLength(valuesArrayPointerOffset); |
| 3762 if (keysArrayLength != valuesArrayLength) |
| 3763 return validationError.DIFFERENT_SIZED_ARRAYS_IN_MAP; |
| 3764 |
| 3765 return validationError.NONE; |
| 3766 }; |
| 3767 |
| 3768 Validator.prototype.validateStringPointer = function(offset, nullable) { |
| 3769 return this.validateArrayPointer( |
| 3770 offset, internal.Uint8.encodedSize, internal.Uint8, nullable, [0], 0); |
| 3771 }; |
| 3772 |
| 3773 // Similar to Array_Data<T>::Validate() |
| 3774 // mojo/public/cpp/bindings/lib/array_internal.h |
| 3775 |
| 3776 Validator.prototype.validateArray = |
| 3777 function (offset, elementSize, elementType, expectedDimensionSizes, |
| 3778 currentDimension) { |
| 3779 if (!internal.isAligned(offset)) |
| 3780 return validationError.MISALIGNED_OBJECT; |
| 3781 |
| 3782 if (!this.isValidRange(offset, internal.kArrayHeaderSize)) |
| 3783 return validationError.ILLEGAL_MEMORY_RANGE; |
| 3784 |
| 3785 var numBytes = this.message.buffer.getUint32(offset); |
| 3786 var numElements = this.message.buffer.getUint32(offset + 4); |
| 3787 |
| 3788 // Note: this computation is "safe" because elementSize <= 8 and |
| 3789 // numElements is a uint32. |
| 3790 var elementsTotalSize = (elementType === internal.PackedBool) ? |
| 3791 Math.ceil(numElements / 8) : (elementSize * numElements); |
| 3792 |
| 3793 if (numBytes < internal.kArrayHeaderSize + elementsTotalSize) |
| 3794 return validationError.UNEXPECTED_ARRAY_HEADER; |
| 3795 |
| 3796 if (expectedDimensionSizes[currentDimension] != 0 && |
| 3797 numElements != expectedDimensionSizes[currentDimension]) { |
| 3798 return validationError.UNEXPECTED_ARRAY_HEADER; |
| 3799 } |
| 3800 |
| 3801 if (!this.claimRange(offset, numBytes)) |
| 3802 return validationError.ILLEGAL_MEMORY_RANGE; |
| 3803 |
| 3804 // Validate the array's elements if they are pointers or handles. |
| 3805 |
| 3806 var elementsOffset = offset + internal.kArrayHeaderSize; |
| 3807 var nullable = isNullable(elementType); |
| 3808 |
| 3809 if (isHandleClass(elementType)) |
| 3810 return this.validateHandleElements(elementsOffset, numElements, nullable); |
| 3811 if (isInterfaceClass(elementType)) |
| 3812 return this.validateInterfaceElements( |
| 3813 elementsOffset, numElements, nullable); |
| 3814 if (isInterfaceRequestClass(elementType)) |
| 3815 return this.validateInterfaceRequestElements( |
| 3816 elementsOffset, numElements, nullable); |
| 3817 if (isAssociatedInterfaceClass(elementType)) |
| 3818 return this.validateAssociatedInterfaceElements( |
| 3819 elementsOffset, numElements, nullable); |
| 3820 if (isAssociatedInterfaceRequestClass(elementType)) |
| 3821 return this.validateAssociatedInterfaceRequestElements( |
| 3822 elementsOffset, numElements, nullable); |
| 3823 if (isStringClass(elementType)) |
| 3824 return this.validateArrayElements( |
| 3825 elementsOffset, numElements, internal.Uint8, nullable, [0], 0); |
| 3826 if (elementType instanceof internal.PointerTo) |
| 3827 return this.validateStructElements( |
| 3828 elementsOffset, numElements, elementType.cls, nullable); |
| 3829 if (elementType instanceof internal.ArrayOf) |
| 3830 return this.validateArrayElements( |
| 3831 elementsOffset, numElements, elementType.cls, nullable, |
| 3832 expectedDimensionSizes, currentDimension + 1); |
| 3833 if (isEnumClass(elementType)) |
| 3834 return this.validateEnumElements(elementsOffset, numElements, |
| 3835 elementType.cls); |
| 3836 |
| 3837 return validationError.NONE; |
| 3838 }; |
| 3839 |
| 3840 // Note: the |offset + i * elementSize| computation in the validateFooElements |
| 3841 // methods below is "safe" because elementSize <= 8, offset and |
| 3842 // numElements are uint32, and 0 <= i < numElements. |
| 3843 |
| 3844 Validator.prototype.validateHandleElements = |
| 3845 function(offset, numElements, nullable) { |
| 3846 var elementSize = internal.Handle.encodedSize; |
| 3847 for (var i = 0; i < numElements; i++) { |
| 3848 var elementOffset = offset + i * elementSize; |
| 3849 var err = this.validateHandle(elementOffset, nullable); |
| 3850 if (err != validationError.NONE) |
| 3851 return err; |
| 3852 } |
| 3853 return validationError.NONE; |
| 3854 }; |
| 3855 |
| 3856 Validator.prototype.validateInterfaceElements = |
| 3857 function(offset, numElements, nullable) { |
| 3858 var elementSize = internal.Interface.prototype.encodedSize; |
| 3859 for (var i = 0; i < numElements; i++) { |
| 3860 var elementOffset = offset + i * elementSize; |
| 3861 var err = this.validateInterface(elementOffset, nullable); |
| 3862 if (err != validationError.NONE) |
| 3863 return err; |
| 3864 } |
| 3865 return validationError.NONE; |
| 3866 }; |
| 3867 |
| 3868 Validator.prototype.validateInterfaceRequestElements = |
| 3869 function(offset, numElements, nullable) { |
| 3870 var elementSize = internal.InterfaceRequest.encodedSize; |
| 3871 for (var i = 0; i < numElements; i++) { |
| 3872 var elementOffset = offset + i * elementSize; |
| 3873 var err = this.validateInterfaceRequest(elementOffset, nullable); |
| 3874 if (err != validationError.NONE) |
| 3875 return err; |
| 3876 } |
| 3877 return validationError.NONE; |
| 3878 }; |
| 3879 |
| 3880 Validator.prototype.validateAssociatedInterfaceElements = |
| 3881 function(offset, numElements, nullable) { |
| 3882 var elementSize = internal.AssociatedInterfacePtrInfo.prototype.encodedSize; |
| 3883 for (var i = 0; i < numElements; i++) { |
| 3884 var elementOffset = offset + i * elementSize; |
| 3885 var err = this.validateAssociatedInterface(elementOffset, nullable); |
| 3886 if (err != validationError.NONE) { |
| 3887 return err; |
| 3888 } |
| 3889 } |
| 3890 return validationError.NONE; |
| 3891 }; |
| 3892 |
| 3893 Validator.prototype.validateAssociatedInterfaceRequestElements = |
| 3894 function(offset, numElements, nullable) { |
| 3895 var elementSize = internal.AssociatedInterfaceRequest.encodedSize; |
| 3896 for (var i = 0; i < numElements; i++) { |
| 3897 var elementOffset = offset + i * elementSize; |
| 3898 var err = this.validateAssociatedInterfaceRequest(elementOffset, |
| 3899 nullable); |
| 3900 if (err != validationError.NONE) { |
| 3901 return err; |
| 3902 } |
| 3903 } |
| 3904 return validationError.NONE; |
| 3905 }; |
| 3906 |
| 3907 // The elementClass parameter is the element type of the element arrays. |
| 3908 Validator.prototype.validateArrayElements = |
| 3909 function(offset, numElements, elementClass, nullable, |
| 3910 expectedDimensionSizes, currentDimension) { |
| 3911 var elementSize = internal.PointerTo.prototype.encodedSize; |
| 3912 for (var i = 0; i < numElements; i++) { |
| 3913 var elementOffset = offset + i * elementSize; |
| 3914 var err = this.validateArrayPointer( |
| 3915 elementOffset, elementClass.encodedSize, elementClass, nullable, |
| 3916 expectedDimensionSizes, currentDimension); |
| 3917 if (err != validationError.NONE) |
| 3918 return err; |
| 3919 } |
| 3920 return validationError.NONE; |
| 3921 }; |
| 3922 |
| 3923 Validator.prototype.validateStructElements = |
| 3924 function(offset, numElements, structClass, nullable) { |
| 3925 var elementSize = internal.PointerTo.prototype.encodedSize; |
| 3926 for (var i = 0; i < numElements; i++) { |
| 3927 var elementOffset = offset + i * elementSize; |
| 3928 var err = |
| 3929 this.validateStructPointer(elementOffset, structClass, nullable); |
| 3930 if (err != validationError.NONE) |
| 3931 return err; |
| 3932 } |
| 3933 return validationError.NONE; |
| 3934 }; |
| 3935 |
| 3936 Validator.prototype.validateEnumElements = |
| 3937 function(offset, numElements, enumClass) { |
| 3938 var elementSize = internal.Enum.prototype.encodedSize; |
| 3939 for (var i = 0; i < numElements; i++) { |
| 3940 var elementOffset = offset + i * elementSize; |
| 3941 var err = this.validateEnum(elementOffset, enumClass); |
| 3942 if (err != validationError.NONE) |
| 3943 return err; |
| 3944 } |
| 3945 return validationError.NONE; |
| 3946 }; |
| 3947 |
| 3948 internal.validationError = validationError; |
| 3949 internal.Validator = Validator; |
| 3950 internal.ValidationErrorObserverForTesting = |
| 3951 ValidationErrorObserverForTesting; |
| 3952 internal.reportValidationError = reportValidationError; |
| 3953 internal.isTestingMode = isTestingMode; |
| 3954 internal.clearTestingMode = clearTestingMode; |
| 3955 })(); |
| 3956 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 3957 // Use of this source code is governed by a BSD-style license that can be |
| 3958 // found in the LICENSE file. |
| 3959 |
| 3960 'use strict'; |
| 3961 |
| 3962 (function() { |
| 3963 var mojomId = 'mojo/public/interfaces/bindings/new_bindings/interface_control_
messages.mojom'; |
| 3964 if (mojo.internal.isMojomLoaded(mojomId)) { |
| 3965 console.warn('The following mojom is loaded multiple times: ' + mojomId); |
| 3966 return; |
| 3967 } |
| 3968 mojo.internal.markMojomLoaded(mojomId); |
| 3969 |
| 3970 // TODO(yzshen): Define these aliases to minimize the differences between the |
| 3971 // old/new modes. Remove them when the old mode goes away. |
| 3972 var bindings = mojo; |
| 3973 var associatedBindings = mojo; |
| 3974 var codec = mojo.internal; |
| 3975 var validator = mojo.internal; |
| 3976 |
| 3977 |
| 3978 var kRunMessageId = 0xFFFFFFFF; |
| 3979 var kRunOrClosePipeMessageId = 0xFFFFFFFE; |
| 3980 |
| 3981 function RunMessageParams(values) { |
| 3982 this.initDefaults_(); |
| 3983 this.initFields_(values); |
| 3984 } |
| 3985 |
| 3986 |
| 3987 RunMessageParams.prototype.initDefaults_ = function() { |
| 3988 this.input = null; |
| 3989 }; |
| 3990 RunMessageParams.prototype.initFields_ = function(fields) { |
| 3991 for(var field in fields) { |
| 3992 if (this.hasOwnProperty(field)) |
| 3993 this[field] = fields[field]; |
| 3994 } |
| 3995 }; |
| 3996 |
| 3997 RunMessageParams.validate = function(messageValidator, offset) { |
| 3998 var err; |
| 3999 err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize)
; |
| 4000 if (err !== validator.validationError.NONE) |
| 4001 return err; |
| 4002 |
| 4003 var kVersionSizes = [ |
| 4004 {version: 0, numBytes: 24} |
| 4005 ]; |
| 4006 err = messageValidator.validateStructVersion(offset, kVersionSizes); |
| 4007 if (err !== validator.validationError.NONE) |
| 4008 return err; |
| 4009 |
| 4010 |
| 4011 // validate RunMessageParams.input |
| 4012 err = messageValidator.validateUnion(offset + codec.kStructHeaderSize + 0, R
unInput, false); |
| 4013 if (err !== validator.validationError.NONE) |
| 4014 return err; |
| 4015 |
| 4016 return validator.validationError.NONE; |
| 4017 }; |
| 4018 |
| 4019 RunMessageParams.encodedSize = codec.kStructHeaderSize + 16; |
| 4020 |
| 4021 RunMessageParams.decode = function(decoder) { |
| 4022 var packed; |
| 4023 var val = new RunMessageParams(); |
| 4024 var numberOfBytes = decoder.readUint32(); |
| 4025 var version = decoder.readUint32(); |
| 4026 val.input = decoder.decodeStruct(RunInput); |
| 4027 return val; |
| 4028 }; |
| 4029 |
| 4030 RunMessageParams.encode = function(encoder, val) { |
| 4031 var packed; |
| 4032 encoder.writeUint32(RunMessageParams.encodedSize); |
| 4033 encoder.writeUint32(0); |
| 4034 encoder.encodeStruct(RunInput, val.input); |
| 4035 }; |
| 4036 function RunResponseMessageParams(values) { |
| 4037 this.initDefaults_(); |
| 4038 this.initFields_(values); |
| 4039 } |
| 4040 |
| 4041 |
| 4042 RunResponseMessageParams.prototype.initDefaults_ = function() { |
| 4043 this.output = null; |
| 4044 }; |
| 4045 RunResponseMessageParams.prototype.initFields_ = function(fields) { |
| 4046 for(var field in fields) { |
| 4047 if (this.hasOwnProperty(field)) |
| 4048 this[field] = fields[field]; |
| 4049 } |
| 4050 }; |
| 4051 |
| 4052 RunResponseMessageParams.validate = function(messageValidator, offset) { |
| 4053 var err; |
| 4054 err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize)
; |
| 4055 if (err !== validator.validationError.NONE) |
| 4056 return err; |
| 4057 |
| 4058 var kVersionSizes = [ |
| 4059 {version: 0, numBytes: 24} |
| 4060 ]; |
| 4061 err = messageValidator.validateStructVersion(offset, kVersionSizes); |
| 4062 if (err !== validator.validationError.NONE) |
| 4063 return err; |
| 4064 |
| 4065 |
| 4066 // validate RunResponseMessageParams.output |
| 4067 err = messageValidator.validateUnion(offset + codec.kStructHeaderSize + 0, R
unOutput, true); |
| 4068 if (err !== validator.validationError.NONE) |
| 4069 return err; |
| 4070 |
| 4071 return validator.validationError.NONE; |
| 4072 }; |
| 4073 |
| 4074 RunResponseMessageParams.encodedSize = codec.kStructHeaderSize + 16; |
| 4075 |
| 4076 RunResponseMessageParams.decode = function(decoder) { |
| 4077 var packed; |
| 4078 var val = new RunResponseMessageParams(); |
| 4079 var numberOfBytes = decoder.readUint32(); |
| 4080 var version = decoder.readUint32(); |
| 4081 val.output = decoder.decodeStruct(RunOutput); |
| 4082 return val; |
| 4083 }; |
| 4084 |
| 4085 RunResponseMessageParams.encode = function(encoder, val) { |
| 4086 var packed; |
| 4087 encoder.writeUint32(RunResponseMessageParams.encodedSize); |
| 4088 encoder.writeUint32(0); |
| 4089 encoder.encodeStruct(RunOutput, val.output); |
| 4090 }; |
| 4091 function QueryVersion(values) { |
| 4092 this.initDefaults_(); |
| 4093 this.initFields_(values); |
| 4094 } |
| 4095 |
| 4096 |
| 4097 QueryVersion.prototype.initDefaults_ = function() { |
| 4098 }; |
| 4099 QueryVersion.prototype.initFields_ = function(fields) { |
| 4100 for(var field in fields) { |
| 4101 if (this.hasOwnProperty(field)) |
| 4102 this[field] = fields[field]; |
| 4103 } |
| 4104 }; |
| 4105 |
| 4106 QueryVersion.validate = function(messageValidator, offset) { |
| 4107 var err; |
| 4108 err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize)
; |
| 4109 if (err !== validator.validationError.NONE) |
| 4110 return err; |
| 4111 |
| 4112 var kVersionSizes = [ |
| 4113 {version: 0, numBytes: 8} |
| 4114 ]; |
| 4115 err = messageValidator.validateStructVersion(offset, kVersionSizes); |
| 4116 if (err !== validator.validationError.NONE) |
| 4117 return err; |
| 4118 |
| 4119 return validator.validationError.NONE; |
| 4120 }; |
| 4121 |
| 4122 QueryVersion.encodedSize = codec.kStructHeaderSize + 0; |
| 4123 |
| 4124 QueryVersion.decode = function(decoder) { |
| 4125 var packed; |
| 4126 var val = new QueryVersion(); |
| 4127 var numberOfBytes = decoder.readUint32(); |
| 4128 var version = decoder.readUint32(); |
| 4129 return val; |
| 4130 }; |
| 4131 |
| 4132 QueryVersion.encode = function(encoder, val) { |
| 4133 var packed; |
| 4134 encoder.writeUint32(QueryVersion.encodedSize); |
| 4135 encoder.writeUint32(0); |
| 4136 }; |
| 4137 function QueryVersionResult(values) { |
| 4138 this.initDefaults_(); |
| 4139 this.initFields_(values); |
| 4140 } |
| 4141 |
| 4142 |
| 4143 QueryVersionResult.prototype.initDefaults_ = function() { |
| 4144 this.version = 0; |
| 4145 }; |
| 4146 QueryVersionResult.prototype.initFields_ = function(fields) { |
| 4147 for(var field in fields) { |
| 4148 if (this.hasOwnProperty(field)) |
| 4149 this[field] = fields[field]; |
| 4150 } |
| 4151 }; |
| 4152 |
| 4153 QueryVersionResult.validate = function(messageValidator, offset) { |
| 4154 var err; |
| 4155 err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize)
; |
| 4156 if (err !== validator.validationError.NONE) |
| 4157 return err; |
| 4158 |
| 4159 var kVersionSizes = [ |
| 4160 {version: 0, numBytes: 16} |
| 4161 ]; |
| 4162 err = messageValidator.validateStructVersion(offset, kVersionSizes); |
| 4163 if (err !== validator.validationError.NONE) |
| 4164 return err; |
| 4165 |
| 4166 |
| 4167 return validator.validationError.NONE; |
| 4168 }; |
| 4169 |
| 4170 QueryVersionResult.encodedSize = codec.kStructHeaderSize + 8; |
| 4171 |
| 4172 QueryVersionResult.decode = function(decoder) { |
| 4173 var packed; |
| 4174 var val = new QueryVersionResult(); |
| 4175 var numberOfBytes = decoder.readUint32(); |
| 4176 var version = decoder.readUint32(); |
| 4177 val.version = decoder.decodeStruct(codec.Uint32); |
| 4178 decoder.skip(1); |
| 4179 decoder.skip(1); |
| 4180 decoder.skip(1); |
| 4181 decoder.skip(1); |
| 4182 return val; |
| 4183 }; |
| 4184 |
| 4185 QueryVersionResult.encode = function(encoder, val) { |
| 4186 var packed; |
| 4187 encoder.writeUint32(QueryVersionResult.encodedSize); |
| 4188 encoder.writeUint32(0); |
| 4189 encoder.encodeStruct(codec.Uint32, val.version); |
| 4190 encoder.skip(1); |
| 4191 encoder.skip(1); |
| 4192 encoder.skip(1); |
| 4193 encoder.skip(1); |
| 4194 }; |
| 4195 function FlushForTesting(values) { |
| 4196 this.initDefaults_(); |
| 4197 this.initFields_(values); |
| 4198 } |
| 4199 |
| 4200 |
| 4201 FlushForTesting.prototype.initDefaults_ = function() { |
| 4202 }; |
| 4203 FlushForTesting.prototype.initFields_ = function(fields) { |
| 4204 for(var field in fields) { |
| 4205 if (this.hasOwnProperty(field)) |
| 4206 this[field] = fields[field]; |
| 4207 } |
| 4208 }; |
| 4209 |
| 4210 FlushForTesting.validate = function(messageValidator, offset) { |
| 4211 var err; |
| 4212 err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize)
; |
| 4213 if (err !== validator.validationError.NONE) |
| 4214 return err; |
| 4215 |
| 4216 var kVersionSizes = [ |
| 4217 {version: 0, numBytes: 8} |
| 4218 ]; |
| 4219 err = messageValidator.validateStructVersion(offset, kVersionSizes); |
| 4220 if (err !== validator.validationError.NONE) |
| 4221 return err; |
| 4222 |
| 4223 return validator.validationError.NONE; |
| 4224 }; |
| 4225 |
| 4226 FlushForTesting.encodedSize = codec.kStructHeaderSize + 0; |
| 4227 |
| 4228 FlushForTesting.decode = function(decoder) { |
| 4229 var packed; |
| 4230 var val = new FlushForTesting(); |
| 4231 var numberOfBytes = decoder.readUint32(); |
| 4232 var version = decoder.readUint32(); |
| 4233 return val; |
| 4234 }; |
| 4235 |
| 4236 FlushForTesting.encode = function(encoder, val) { |
| 4237 var packed; |
| 4238 encoder.writeUint32(FlushForTesting.encodedSize); |
| 4239 encoder.writeUint32(0); |
| 4240 }; |
| 4241 function RunOrClosePipeMessageParams(values) { |
| 4242 this.initDefaults_(); |
| 4243 this.initFields_(values); |
| 4244 } |
| 4245 |
| 4246 |
| 4247 RunOrClosePipeMessageParams.prototype.initDefaults_ = function() { |
| 4248 this.input = null; |
| 4249 }; |
| 4250 RunOrClosePipeMessageParams.prototype.initFields_ = function(fields) { |
| 4251 for(var field in fields) { |
| 4252 if (this.hasOwnProperty(field)) |
| 4253 this[field] = fields[field]; |
| 4254 } |
| 4255 }; |
| 4256 |
| 4257 RunOrClosePipeMessageParams.validate = function(messageValidator, offset) { |
| 4258 var err; |
| 4259 err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize)
; |
| 4260 if (err !== validator.validationError.NONE) |
| 4261 return err; |
| 4262 |
| 4263 var kVersionSizes = [ |
| 4264 {version: 0, numBytes: 24} |
| 4265 ]; |
| 4266 err = messageValidator.validateStructVersion(offset, kVersionSizes); |
| 4267 if (err !== validator.validationError.NONE) |
| 4268 return err; |
| 4269 |
| 4270 |
| 4271 // validate RunOrClosePipeMessageParams.input |
| 4272 err = messageValidator.validateUnion(offset + codec.kStructHeaderSize + 0, R
unOrClosePipeInput, false); |
| 4273 if (err !== validator.validationError.NONE) |
| 4274 return err; |
| 4275 |
| 4276 return validator.validationError.NONE; |
| 4277 }; |
| 4278 |
| 4279 RunOrClosePipeMessageParams.encodedSize = codec.kStructHeaderSize + 16; |
| 4280 |
| 4281 RunOrClosePipeMessageParams.decode = function(decoder) { |
| 4282 var packed; |
| 4283 var val = new RunOrClosePipeMessageParams(); |
| 4284 var numberOfBytes = decoder.readUint32(); |
| 4285 var version = decoder.readUint32(); |
| 4286 val.input = decoder.decodeStruct(RunOrClosePipeInput); |
| 4287 return val; |
| 4288 }; |
| 4289 |
| 4290 RunOrClosePipeMessageParams.encode = function(encoder, val) { |
| 4291 var packed; |
| 4292 encoder.writeUint32(RunOrClosePipeMessageParams.encodedSize); |
| 4293 encoder.writeUint32(0); |
| 4294 encoder.encodeStruct(RunOrClosePipeInput, val.input); |
| 4295 }; |
| 4296 function RequireVersion(values) { |
| 4297 this.initDefaults_(); |
| 4298 this.initFields_(values); |
| 4299 } |
| 4300 |
| 4301 |
| 4302 RequireVersion.prototype.initDefaults_ = function() { |
| 4303 this.version = 0; |
| 4304 }; |
| 4305 RequireVersion.prototype.initFields_ = function(fields) { |
| 4306 for(var field in fields) { |
| 4307 if (this.hasOwnProperty(field)) |
| 4308 this[field] = fields[field]; |
| 4309 } |
| 4310 }; |
| 4311 |
| 4312 RequireVersion.validate = function(messageValidator, offset) { |
| 4313 var err; |
| 4314 err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize)
; |
| 4315 if (err !== validator.validationError.NONE) |
| 4316 return err; |
| 4317 |
| 4318 var kVersionSizes = [ |
| 4319 {version: 0, numBytes: 16} |
| 4320 ]; |
| 4321 err = messageValidator.validateStructVersion(offset, kVersionSizes); |
| 4322 if (err !== validator.validationError.NONE) |
| 4323 return err; |
| 4324 |
| 4325 |
| 4326 return validator.validationError.NONE; |
| 4327 }; |
| 4328 |
| 4329 RequireVersion.encodedSize = codec.kStructHeaderSize + 8; |
| 4330 |
| 4331 RequireVersion.decode = function(decoder) { |
| 4332 var packed; |
| 4333 var val = new RequireVersion(); |
| 4334 var numberOfBytes = decoder.readUint32(); |
| 4335 var version = decoder.readUint32(); |
| 4336 val.version = decoder.decodeStruct(codec.Uint32); |
| 4337 decoder.skip(1); |
| 4338 decoder.skip(1); |
| 4339 decoder.skip(1); |
| 4340 decoder.skip(1); |
| 4341 return val; |
| 4342 }; |
| 4343 |
| 4344 RequireVersion.encode = function(encoder, val) { |
| 4345 var packed; |
| 4346 encoder.writeUint32(RequireVersion.encodedSize); |
| 4347 encoder.writeUint32(0); |
| 4348 encoder.encodeStruct(codec.Uint32, val.version); |
| 4349 encoder.skip(1); |
| 4350 encoder.skip(1); |
| 4351 encoder.skip(1); |
| 4352 encoder.skip(1); |
| 4353 }; |
| 4354 |
| 4355 function RunInput(value) { |
| 4356 this.initDefault_(); |
| 4357 this.initValue_(value); |
| 4358 } |
| 4359 |
| 4360 |
| 4361 RunInput.Tags = { |
| 4362 queryVersion: 0, |
| 4363 flushForTesting: 1, |
| 4364 }; |
| 4365 |
| 4366 RunInput.prototype.initDefault_ = function() { |
| 4367 this.$data = null; |
| 4368 this.$tag = undefined; |
| 4369 } |
| 4370 |
| 4371 RunInput.prototype.initValue_ = function(value) { |
| 4372 if (value == undefined) { |
| 4373 return; |
| 4374 } |
| 4375 |
| 4376 var keys = Object.keys(value); |
| 4377 if (keys.length == 0) { |
| 4378 return; |
| 4379 } |
| 4380 |
| 4381 if (keys.length > 1) { |
| 4382 throw new TypeError("You may set only one member on a union."); |
| 4383 } |
| 4384 |
| 4385 var fields = [ |
| 4386 "queryVersion", |
| 4387 "flushForTesting", |
| 4388 ]; |
| 4389 |
| 4390 if (fields.indexOf(keys[0]) < 0) { |
| 4391 throw new ReferenceError(keys[0] + " is not a RunInput member."); |
| 4392 |
| 4393 } |
| 4394 |
| 4395 this[keys[0]] = value[keys[0]]; |
| 4396 } |
| 4397 Object.defineProperty(RunInput.prototype, "queryVersion", { |
| 4398 get: function() { |
| 4399 if (this.$tag != RunInput.Tags.queryVersion) { |
| 4400 throw new ReferenceError( |
| 4401 "RunInput.queryVersion is not currently set."); |
| 4402 } |
| 4403 return this.$data; |
| 4404 }, |
| 4405 |
| 4406 set: function(value) { |
| 4407 this.$tag = RunInput.Tags.queryVersion; |
| 4408 this.$data = value; |
| 4409 } |
| 4410 }); |
| 4411 Object.defineProperty(RunInput.prototype, "flushForTesting", { |
| 4412 get: function() { |
| 4413 if (this.$tag != RunInput.Tags.flushForTesting) { |
| 4414 throw new ReferenceError( |
| 4415 "RunInput.flushForTesting is not currently set."); |
| 4416 } |
| 4417 return this.$data; |
| 4418 }, |
| 4419 |
| 4420 set: function(value) { |
| 4421 this.$tag = RunInput.Tags.flushForTesting; |
| 4422 this.$data = value; |
| 4423 } |
| 4424 }); |
| 4425 |
| 4426 |
| 4427 RunInput.encode = function(encoder, val) { |
| 4428 if (val == null) { |
| 4429 encoder.writeUint64(0); |
| 4430 encoder.writeUint64(0); |
| 4431 return; |
| 4432 } |
| 4433 if (val.$tag == undefined) { |
| 4434 throw new TypeError("Cannot encode unions with an unknown member set."); |
| 4435 } |
| 4436 |
| 4437 encoder.writeUint32(16); |
| 4438 encoder.writeUint32(val.$tag); |
| 4439 switch (val.$tag) { |
| 4440 case RunInput.Tags.queryVersion: |
| 4441 encoder.encodeStructPointer(QueryVersion, val.queryVersion); |
| 4442 break; |
| 4443 case RunInput.Tags.flushForTesting: |
| 4444 encoder.encodeStructPointer(FlushForTesting, val.flushForTesting); |
| 4445 break; |
| 4446 } |
| 4447 encoder.align(); |
| 4448 }; |
| 4449 |
| 4450 |
| 4451 RunInput.decode = function(decoder) { |
| 4452 var size = decoder.readUint32(); |
| 4453 if (size == 0) { |
| 4454 decoder.readUint32(); |
| 4455 decoder.readUint64(); |
| 4456 return null; |
| 4457 } |
| 4458 |
| 4459 var result = new RunInput(); |
| 4460 var tag = decoder.readUint32(); |
| 4461 switch (tag) { |
| 4462 case RunInput.Tags.queryVersion: |
| 4463 result.queryVersion = decoder.decodeStructPointer(QueryVersion); |
| 4464 break; |
| 4465 case RunInput.Tags.flushForTesting: |
| 4466 result.flushForTesting = decoder.decodeStructPointer(FlushForTesting); |
| 4467 break; |
| 4468 } |
| 4469 decoder.align(); |
| 4470 |
| 4471 return result; |
| 4472 }; |
| 4473 |
| 4474 |
| 4475 RunInput.validate = function(messageValidator, offset) { |
| 4476 var size = messageValidator.decodeUnionSize(offset); |
| 4477 if (size != 16) { |
| 4478 return validator.validationError.INVALID_UNION_SIZE; |
| 4479 } |
| 4480 |
| 4481 var tag = messageValidator.decodeUnionTag(offset); |
| 4482 var data_offset = offset + 8; |
| 4483 var err; |
| 4484 switch (tag) { |
| 4485 case RunInput.Tags.queryVersion: |
| 4486 |
| 4487 |
| 4488 // validate RunInput.queryVersion |
| 4489 err = messageValidator.validateStructPointer(data_offset, QueryVersion, fals
e); |
| 4490 if (err !== validator.validationError.NONE) |
| 4491 return err; |
| 4492 break; |
| 4493 case RunInput.Tags.flushForTesting: |
| 4494 |
| 4495 |
| 4496 // validate RunInput.flushForTesting |
| 4497 err = messageValidator.validateStructPointer(data_offset, FlushForTesting, f
alse); |
| 4498 if (err !== validator.validationError.NONE) |
| 4499 return err; |
| 4500 break; |
| 4501 } |
| 4502 |
| 4503 return validator.validationError.NONE; |
| 4504 }; |
| 4505 |
| 4506 RunInput.encodedSize = 16; |
| 4507 |
| 4508 function RunOutput(value) { |
| 4509 this.initDefault_(); |
| 4510 this.initValue_(value); |
| 4511 } |
| 4512 |
| 4513 |
| 4514 RunOutput.Tags = { |
| 4515 queryVersionResult: 0, |
| 4516 }; |
| 4517 |
| 4518 RunOutput.prototype.initDefault_ = function() { |
| 4519 this.$data = null; |
| 4520 this.$tag = undefined; |
| 4521 } |
| 4522 |
| 4523 RunOutput.prototype.initValue_ = function(value) { |
| 4524 if (value == undefined) { |
| 4525 return; |
| 4526 } |
| 4527 |
| 4528 var keys = Object.keys(value); |
| 4529 if (keys.length == 0) { |
| 4530 return; |
| 4531 } |
| 4532 |
| 4533 if (keys.length > 1) { |
| 4534 throw new TypeError("You may set only one member on a union."); |
| 4535 } |
| 4536 |
| 4537 var fields = [ |
| 4538 "queryVersionResult", |
| 4539 ]; |
| 4540 |
| 4541 if (fields.indexOf(keys[0]) < 0) { |
| 4542 throw new ReferenceError(keys[0] + " is not a RunOutput member."); |
| 4543 |
| 4544 } |
| 4545 |
| 4546 this[keys[0]] = value[keys[0]]; |
| 4547 } |
| 4548 Object.defineProperty(RunOutput.prototype, "queryVersionResult", { |
| 4549 get: function() { |
| 4550 if (this.$tag != RunOutput.Tags.queryVersionResult) { |
| 4551 throw new ReferenceError( |
| 4552 "RunOutput.queryVersionResult is not currently set."); |
| 4553 } |
| 4554 return this.$data; |
| 4555 }, |
| 4556 |
| 4557 set: function(value) { |
| 4558 this.$tag = RunOutput.Tags.queryVersionResult; |
| 4559 this.$data = value; |
| 4560 } |
| 4561 }); |
| 4562 |
| 4563 |
| 4564 RunOutput.encode = function(encoder, val) { |
| 4565 if (val == null) { |
| 4566 encoder.writeUint64(0); |
| 4567 encoder.writeUint64(0); |
| 4568 return; |
| 4569 } |
| 4570 if (val.$tag == undefined) { |
| 4571 throw new TypeError("Cannot encode unions with an unknown member set."); |
| 4572 } |
| 4573 |
| 4574 encoder.writeUint32(16); |
| 4575 encoder.writeUint32(val.$tag); |
| 4576 switch (val.$tag) { |
| 4577 case RunOutput.Tags.queryVersionResult: |
| 4578 encoder.encodeStructPointer(QueryVersionResult, val.queryVersionResult
); |
| 4579 break; |
| 4580 } |
| 4581 encoder.align(); |
| 4582 }; |
| 4583 |
| 4584 |
| 4585 RunOutput.decode = function(decoder) { |
| 4586 var size = decoder.readUint32(); |
| 4587 if (size == 0) { |
| 4588 decoder.readUint32(); |
| 4589 decoder.readUint64(); |
| 4590 return null; |
| 4591 } |
| 4592 |
| 4593 var result = new RunOutput(); |
| 4594 var tag = decoder.readUint32(); |
| 4595 switch (tag) { |
| 4596 case RunOutput.Tags.queryVersionResult: |
| 4597 result.queryVersionResult = decoder.decodeStructPointer(QueryVersionRe
sult); |
| 4598 break; |
| 4599 } |
| 4600 decoder.align(); |
| 4601 |
| 4602 return result; |
| 4603 }; |
| 4604 |
| 4605 |
| 4606 RunOutput.validate = function(messageValidator, offset) { |
| 4607 var size = messageValidator.decodeUnionSize(offset); |
| 4608 if (size != 16) { |
| 4609 return validator.validationError.INVALID_UNION_SIZE; |
| 4610 } |
| 4611 |
| 4612 var tag = messageValidator.decodeUnionTag(offset); |
| 4613 var data_offset = offset + 8; |
| 4614 var err; |
| 4615 switch (tag) { |
| 4616 case RunOutput.Tags.queryVersionResult: |
| 4617 |
| 4618 |
| 4619 // validate RunOutput.queryVersionResult |
| 4620 err = messageValidator.validateStructPointer(data_offset, QueryVersionResult
, false); |
| 4621 if (err !== validator.validationError.NONE) |
| 4622 return err; |
| 4623 break; |
| 4624 } |
| 4625 |
| 4626 return validator.validationError.NONE; |
| 4627 }; |
| 4628 |
| 4629 RunOutput.encodedSize = 16; |
| 4630 |
| 4631 function RunOrClosePipeInput(value) { |
| 4632 this.initDefault_(); |
| 4633 this.initValue_(value); |
| 4634 } |
| 4635 |
| 4636 |
| 4637 RunOrClosePipeInput.Tags = { |
| 4638 requireVersion: 0, |
| 4639 }; |
| 4640 |
| 4641 RunOrClosePipeInput.prototype.initDefault_ = function() { |
| 4642 this.$data = null; |
| 4643 this.$tag = undefined; |
| 4644 } |
| 4645 |
| 4646 RunOrClosePipeInput.prototype.initValue_ = function(value) { |
| 4647 if (value == undefined) { |
| 4648 return; |
| 4649 } |
| 4650 |
| 4651 var keys = Object.keys(value); |
| 4652 if (keys.length == 0) { |
| 4653 return; |
| 4654 } |
| 4655 |
| 4656 if (keys.length > 1) { |
| 4657 throw new TypeError("You may set only one member on a union."); |
| 4658 } |
| 4659 |
| 4660 var fields = [ |
| 4661 "requireVersion", |
| 4662 ]; |
| 4663 |
| 4664 if (fields.indexOf(keys[0]) < 0) { |
| 4665 throw new ReferenceError(keys[0] + " is not a RunOrClosePipeInput member."
); |
| 4666 |
| 4667 } |
| 4668 |
| 4669 this[keys[0]] = value[keys[0]]; |
| 4670 } |
| 4671 Object.defineProperty(RunOrClosePipeInput.prototype, "requireVersion", { |
| 4672 get: function() { |
| 4673 if (this.$tag != RunOrClosePipeInput.Tags.requireVersion) { |
| 4674 throw new ReferenceError( |
| 4675 "RunOrClosePipeInput.requireVersion is not currently set."); |
| 4676 } |
| 4677 return this.$data; |
| 4678 }, |
| 4679 |
| 4680 set: function(value) { |
| 4681 this.$tag = RunOrClosePipeInput.Tags.requireVersion; |
| 4682 this.$data = value; |
| 4683 } |
| 4684 }); |
| 4685 |
| 4686 |
| 4687 RunOrClosePipeInput.encode = function(encoder, val) { |
| 4688 if (val == null) { |
| 4689 encoder.writeUint64(0); |
| 4690 encoder.writeUint64(0); |
| 4691 return; |
| 4692 } |
| 4693 if (val.$tag == undefined) { |
| 4694 throw new TypeError("Cannot encode unions with an unknown member set."); |
| 4695 } |
| 4696 |
| 4697 encoder.writeUint32(16); |
| 4698 encoder.writeUint32(val.$tag); |
| 4699 switch (val.$tag) { |
| 4700 case RunOrClosePipeInput.Tags.requireVersion: |
| 4701 encoder.encodeStructPointer(RequireVersion, val.requireVersion); |
| 4702 break; |
| 4703 } |
| 4704 encoder.align(); |
| 4705 }; |
| 4706 |
| 4707 |
| 4708 RunOrClosePipeInput.decode = function(decoder) { |
| 4709 var size = decoder.readUint32(); |
| 4710 if (size == 0) { |
| 4711 decoder.readUint32(); |
| 4712 decoder.readUint64(); |
| 4713 return null; |
| 4714 } |
| 4715 |
| 4716 var result = new RunOrClosePipeInput(); |
| 4717 var tag = decoder.readUint32(); |
| 4718 switch (tag) { |
| 4719 case RunOrClosePipeInput.Tags.requireVersion: |
| 4720 result.requireVersion = decoder.decodeStructPointer(RequireVersion); |
| 4721 break; |
| 4722 } |
| 4723 decoder.align(); |
| 4724 |
| 4725 return result; |
| 4726 }; |
| 4727 |
| 4728 |
| 4729 RunOrClosePipeInput.validate = function(messageValidator, offset) { |
| 4730 var size = messageValidator.decodeUnionSize(offset); |
| 4731 if (size != 16) { |
| 4732 return validator.validationError.INVALID_UNION_SIZE; |
| 4733 } |
| 4734 |
| 4735 var tag = messageValidator.decodeUnionTag(offset); |
| 4736 var data_offset = offset + 8; |
| 4737 var err; |
| 4738 switch (tag) { |
| 4739 case RunOrClosePipeInput.Tags.requireVersion: |
| 4740 |
| 4741 |
| 4742 // validate RunOrClosePipeInput.requireVersion |
| 4743 err = messageValidator.validateStructPointer(data_offset, RequireVersion, fa
lse); |
| 4744 if (err !== validator.validationError.NONE) |
| 4745 return err; |
| 4746 break; |
| 4747 } |
| 4748 |
| 4749 return validator.validationError.NONE; |
| 4750 }; |
| 4751 |
| 4752 RunOrClosePipeInput.encodedSize = 16; |
| 4753 var exports = mojo.internal.exposeNamespace("mojo.interfaceControl2"); |
| 4754 exports.kRunMessageId = kRunMessageId; |
| 4755 exports.kRunOrClosePipeMessageId = kRunOrClosePipeMessageId; |
| 4756 exports.RunMessageParams = RunMessageParams; |
| 4757 exports.RunResponseMessageParams = RunResponseMessageParams; |
| 4758 exports.QueryVersion = QueryVersion; |
| 4759 exports.QueryVersionResult = QueryVersionResult; |
| 4760 exports.FlushForTesting = FlushForTesting; |
| 4761 exports.RunOrClosePipeMessageParams = RunOrClosePipeMessageParams; |
| 4762 exports.RequireVersion = RequireVersion; |
| 4763 exports.RunInput = RunInput; |
| 4764 exports.RunOutput = RunOutput; |
| 4765 exports.RunOrClosePipeInput = RunOrClosePipeInput; |
| 4766 })();// Copyright 2014 The Chromium Authors. All rights reserved. |
| 4767 // Use of this source code is governed by a BSD-style license that can be |
| 4768 // found in the LICENSE file. |
| 4769 |
| 4770 'use strict'; |
| 4771 |
| 4772 (function() { |
| 4773 var mojomId = 'mojo/public/interfaces/bindings/new_bindings/pipe_control_messa
ges.mojom'; |
| 4774 if (mojo.internal.isMojomLoaded(mojomId)) { |
| 4775 console.warn('The following mojom is loaded multiple times: ' + mojomId); |
| 4776 return; |
| 4777 } |
| 4778 mojo.internal.markMojomLoaded(mojomId); |
| 4779 |
| 4780 // TODO(yzshen): Define these aliases to minimize the differences between the |
| 4781 // old/new modes. Remove them when the old mode goes away. |
| 4782 var bindings = mojo; |
| 4783 var associatedBindings = mojo; |
| 4784 var codec = mojo.internal; |
| 4785 var validator = mojo.internal; |
| 4786 |
| 4787 |
| 4788 var kRunOrClosePipeMessageId = 0xFFFFFFFE; |
| 4789 |
| 4790 function RunOrClosePipeMessageParams(values) { |
| 4791 this.initDefaults_(); |
| 4792 this.initFields_(values); |
| 4793 } |
| 4794 |
| 4795 |
| 4796 RunOrClosePipeMessageParams.prototype.initDefaults_ = function() { |
| 4797 this.input = null; |
| 4798 }; |
| 4799 RunOrClosePipeMessageParams.prototype.initFields_ = function(fields) { |
| 4800 for(var field in fields) { |
| 4801 if (this.hasOwnProperty(field)) |
| 4802 this[field] = fields[field]; |
| 4803 } |
| 4804 }; |
| 4805 |
| 4806 RunOrClosePipeMessageParams.validate = function(messageValidator, offset) { |
| 4807 var err; |
| 4808 err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize)
; |
| 4809 if (err !== validator.validationError.NONE) |
| 4810 return err; |
| 4811 |
| 4812 var kVersionSizes = [ |
| 4813 {version: 0, numBytes: 24} |
| 4814 ]; |
| 4815 err = messageValidator.validateStructVersion(offset, kVersionSizes); |
| 4816 if (err !== validator.validationError.NONE) |
| 4817 return err; |
| 4818 |
| 4819 |
| 4820 // validate RunOrClosePipeMessageParams.input |
| 4821 err = messageValidator.validateUnion(offset + codec.kStructHeaderSize + 0, R
unOrClosePipeInput, false); |
| 4822 if (err !== validator.validationError.NONE) |
| 4823 return err; |
| 4824 |
| 4825 return validator.validationError.NONE; |
| 4826 }; |
| 4827 |
| 4828 RunOrClosePipeMessageParams.encodedSize = codec.kStructHeaderSize + 16; |
| 4829 |
| 4830 RunOrClosePipeMessageParams.decode = function(decoder) { |
| 4831 var packed; |
| 4832 var val = new RunOrClosePipeMessageParams(); |
| 4833 var numberOfBytes = decoder.readUint32(); |
| 4834 var version = decoder.readUint32(); |
| 4835 val.input = decoder.decodeStruct(RunOrClosePipeInput); |
| 4836 return val; |
| 4837 }; |
| 4838 |
| 4839 RunOrClosePipeMessageParams.encode = function(encoder, val) { |
| 4840 var packed; |
| 4841 encoder.writeUint32(RunOrClosePipeMessageParams.encodedSize); |
| 4842 encoder.writeUint32(0); |
| 4843 encoder.encodeStruct(RunOrClosePipeInput, val.input); |
| 4844 }; |
| 4845 function DisconnectReason(values) { |
| 4846 this.initDefaults_(); |
| 4847 this.initFields_(values); |
| 4848 } |
| 4849 |
| 4850 |
| 4851 DisconnectReason.prototype.initDefaults_ = function() { |
| 4852 this.customReason = 0; |
| 4853 this.description = null; |
| 4854 }; |
| 4855 DisconnectReason.prototype.initFields_ = function(fields) { |
| 4856 for(var field in fields) { |
| 4857 if (this.hasOwnProperty(field)) |
| 4858 this[field] = fields[field]; |
| 4859 } |
| 4860 }; |
| 4861 |
| 4862 DisconnectReason.validate = function(messageValidator, offset) { |
| 4863 var err; |
| 4864 err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize)
; |
| 4865 if (err !== validator.validationError.NONE) |
| 4866 return err; |
| 4867 |
| 4868 var kVersionSizes = [ |
| 4869 {version: 0, numBytes: 24} |
| 4870 ]; |
| 4871 err = messageValidator.validateStructVersion(offset, kVersionSizes); |
| 4872 if (err !== validator.validationError.NONE) |
| 4873 return err; |
| 4874 |
| 4875 |
| 4876 |
| 4877 |
| 4878 // validate DisconnectReason.description |
| 4879 err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSiz
e + 8, false) |
| 4880 if (err !== validator.validationError.NONE) |
| 4881 return err; |
| 4882 |
| 4883 return validator.validationError.NONE; |
| 4884 }; |
| 4885 |
| 4886 DisconnectReason.encodedSize = codec.kStructHeaderSize + 16; |
| 4887 |
| 4888 DisconnectReason.decode = function(decoder) { |
| 4889 var packed; |
| 4890 var val = new DisconnectReason(); |
| 4891 var numberOfBytes = decoder.readUint32(); |
| 4892 var version = decoder.readUint32(); |
| 4893 val.customReason = decoder.decodeStruct(codec.Uint32); |
| 4894 decoder.skip(1); |
| 4895 decoder.skip(1); |
| 4896 decoder.skip(1); |
| 4897 decoder.skip(1); |
| 4898 val.description = decoder.decodeStruct(codec.String); |
| 4899 return val; |
| 4900 }; |
| 4901 |
| 4902 DisconnectReason.encode = function(encoder, val) { |
| 4903 var packed; |
| 4904 encoder.writeUint32(DisconnectReason.encodedSize); |
| 4905 encoder.writeUint32(0); |
| 4906 encoder.encodeStruct(codec.Uint32, val.customReason); |
| 4907 encoder.skip(1); |
| 4908 encoder.skip(1); |
| 4909 encoder.skip(1); |
| 4910 encoder.skip(1); |
| 4911 encoder.encodeStruct(codec.String, val.description); |
| 4912 }; |
| 4913 function PeerAssociatedEndpointClosedEvent(values) { |
| 4914 this.initDefaults_(); |
| 4915 this.initFields_(values); |
| 4916 } |
| 4917 |
| 4918 |
| 4919 PeerAssociatedEndpointClosedEvent.prototype.initDefaults_ = function() { |
| 4920 this.id = 0; |
| 4921 this.disconnectReason = null; |
| 4922 }; |
| 4923 PeerAssociatedEndpointClosedEvent.prototype.initFields_ = function(fields) { |
| 4924 for(var field in fields) { |
| 4925 if (this.hasOwnProperty(field)) |
| 4926 this[field] = fields[field]; |
| 4927 } |
| 4928 }; |
| 4929 |
| 4930 PeerAssociatedEndpointClosedEvent.validate = function(messageValidator, offset
) { |
| 4931 var err; |
| 4932 err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize)
; |
| 4933 if (err !== validator.validationError.NONE) |
| 4934 return err; |
| 4935 |
| 4936 var kVersionSizes = [ |
| 4937 {version: 0, numBytes: 24} |
| 4938 ]; |
| 4939 err = messageValidator.validateStructVersion(offset, kVersionSizes); |
| 4940 if (err !== validator.validationError.NONE) |
| 4941 return err; |
| 4942 |
| 4943 |
| 4944 |
| 4945 |
| 4946 // validate PeerAssociatedEndpointClosedEvent.disconnectReason |
| 4947 err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSiz
e + 8, DisconnectReason, true); |
| 4948 if (err !== validator.validationError.NONE) |
| 4949 return err; |
| 4950 |
| 4951 return validator.validationError.NONE; |
| 4952 }; |
| 4953 |
| 4954 PeerAssociatedEndpointClosedEvent.encodedSize = codec.kStructHeaderSize + 16; |
| 4955 |
| 4956 PeerAssociatedEndpointClosedEvent.decode = function(decoder) { |
| 4957 var packed; |
| 4958 var val = new PeerAssociatedEndpointClosedEvent(); |
| 4959 var numberOfBytes = decoder.readUint32(); |
| 4960 var version = decoder.readUint32(); |
| 4961 val.id = decoder.decodeStruct(codec.Uint32); |
| 4962 decoder.skip(1); |
| 4963 decoder.skip(1); |
| 4964 decoder.skip(1); |
| 4965 decoder.skip(1); |
| 4966 val.disconnectReason = decoder.decodeStructPointer(DisconnectReason); |
| 4967 return val; |
| 4968 }; |
| 4969 |
| 4970 PeerAssociatedEndpointClosedEvent.encode = function(encoder, val) { |
| 4971 var packed; |
| 4972 encoder.writeUint32(PeerAssociatedEndpointClosedEvent.encodedSize); |
| 4973 encoder.writeUint32(0); |
| 4974 encoder.encodeStruct(codec.Uint32, val.id); |
| 4975 encoder.skip(1); |
| 4976 encoder.skip(1); |
| 4977 encoder.skip(1); |
| 4978 encoder.skip(1); |
| 4979 encoder.encodeStructPointer(DisconnectReason, val.disconnectReason); |
| 4980 }; |
| 4981 |
| 4982 function RunOrClosePipeInput(value) { |
| 4983 this.initDefault_(); |
| 4984 this.initValue_(value); |
| 4985 } |
| 4986 |
| 4987 |
| 4988 RunOrClosePipeInput.Tags = { |
| 4989 peerAssociatedEndpointClosedEvent: 0, |
| 4990 }; |
| 4991 |
| 4992 RunOrClosePipeInput.prototype.initDefault_ = function() { |
| 4993 this.$data = null; |
| 4994 this.$tag = undefined; |
| 4995 } |
| 4996 |
| 4997 RunOrClosePipeInput.prototype.initValue_ = function(value) { |
| 4998 if (value == undefined) { |
| 4999 return; |
| 5000 } |
| 5001 |
| 5002 var keys = Object.keys(value); |
| 5003 if (keys.length == 0) { |
| 5004 return; |
| 5005 } |
| 5006 |
| 5007 if (keys.length > 1) { |
| 5008 throw new TypeError("You may set only one member on a union."); |
| 5009 } |
| 5010 |
| 5011 var fields = [ |
| 5012 "peerAssociatedEndpointClosedEvent", |
| 5013 ]; |
| 5014 |
| 5015 if (fields.indexOf(keys[0]) < 0) { |
| 5016 throw new ReferenceError(keys[0] + " is not a RunOrClosePipeInput member."
); |
| 5017 |
| 5018 } |
| 5019 |
| 5020 this[keys[0]] = value[keys[0]]; |
| 5021 } |
| 5022 Object.defineProperty(RunOrClosePipeInput.prototype, "peerAssociatedEndpointCl
osedEvent", { |
| 5023 get: function() { |
| 5024 if (this.$tag != RunOrClosePipeInput.Tags.peerAssociatedEndpointClosedEven
t) { |
| 5025 throw new ReferenceError( |
| 5026 "RunOrClosePipeInput.peerAssociatedEndpointClosedEvent is not curren
tly set."); |
| 5027 } |
| 5028 return this.$data; |
| 5029 }, |
| 5030 |
| 5031 set: function(value) { |
| 5032 this.$tag = RunOrClosePipeInput.Tags.peerAssociatedEndpointClosedEvent; |
| 5033 this.$data = value; |
| 5034 } |
| 5035 }); |
| 5036 |
| 5037 |
| 5038 RunOrClosePipeInput.encode = function(encoder, val) { |
| 5039 if (val == null) { |
| 5040 encoder.writeUint64(0); |
| 5041 encoder.writeUint64(0); |
| 5042 return; |
| 5043 } |
| 5044 if (val.$tag == undefined) { |
| 5045 throw new TypeError("Cannot encode unions with an unknown member set."); |
| 5046 } |
| 5047 |
| 5048 encoder.writeUint32(16); |
| 5049 encoder.writeUint32(val.$tag); |
| 5050 switch (val.$tag) { |
| 5051 case RunOrClosePipeInput.Tags.peerAssociatedEndpointClosedEvent: |
| 5052 encoder.encodeStructPointer(PeerAssociatedEndpointClosedEvent, val.pee
rAssociatedEndpointClosedEvent); |
| 5053 break; |
| 5054 } |
| 5055 encoder.align(); |
| 5056 }; |
| 5057 |
| 5058 |
| 5059 RunOrClosePipeInput.decode = function(decoder) { |
| 5060 var size = decoder.readUint32(); |
| 5061 if (size == 0) { |
| 5062 decoder.readUint32(); |
| 5063 decoder.readUint64(); |
| 5064 return null; |
| 5065 } |
| 5066 |
| 5067 var result = new RunOrClosePipeInput(); |
| 5068 var tag = decoder.readUint32(); |
| 5069 switch (tag) { |
| 5070 case RunOrClosePipeInput.Tags.peerAssociatedEndpointClosedEvent: |
| 5071 result.peerAssociatedEndpointClosedEvent = decoder.decodeStructPointer
(PeerAssociatedEndpointClosedEvent); |
| 5072 break; |
| 5073 } |
| 5074 decoder.align(); |
| 5075 |
| 5076 return result; |
| 5077 }; |
| 5078 |
| 5079 |
| 5080 RunOrClosePipeInput.validate = function(messageValidator, offset) { |
| 5081 var size = messageValidator.decodeUnionSize(offset); |
| 5082 if (size != 16) { |
| 5083 return validator.validationError.INVALID_UNION_SIZE; |
| 5084 } |
| 5085 |
| 5086 var tag = messageValidator.decodeUnionTag(offset); |
| 5087 var data_offset = offset + 8; |
| 5088 var err; |
| 5089 switch (tag) { |
| 5090 case RunOrClosePipeInput.Tags.peerAssociatedEndpointClosedEvent: |
| 5091 |
| 5092 |
| 5093 // validate RunOrClosePipeInput.peerAssociatedEndpointClosedEvent |
| 5094 err = messageValidator.validateStructPointer(data_offset, PeerAssociatedEndp
ointClosedEvent, false); |
| 5095 if (err !== validator.validationError.NONE) |
| 5096 return err; |
| 5097 break; |
| 5098 } |
| 5099 |
| 5100 return validator.validationError.NONE; |
| 5101 }; |
| 5102 |
| 5103 RunOrClosePipeInput.encodedSize = 16; |
| 5104 var exports = mojo.internal.exposeNamespace("mojo.pipeControl2"); |
| 5105 exports.kRunOrClosePipeMessageId = kRunOrClosePipeMessageId; |
| 5106 exports.RunOrClosePipeMessageParams = RunOrClosePipeMessageParams; |
| 5107 exports.DisconnectReason = DisconnectReason; |
| 5108 exports.PeerAssociatedEndpointClosedEvent = PeerAssociatedEndpointClosedEvent; |
| 5109 exports.RunOrClosePipeInput = RunOrClosePipeInput; |
| 5110 })(); |
OLD | NEW |