// content/public/common/alternative_error_page_override_info.mojom.js is auto generated by mojom_bindings_generator.py, do not edit

// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

'use strict';

(function() {
  var mojomId = 'content/public/common/alternative_error_page_override_info.mojom';
  if (mojo.internal.isMojomLoaded(mojomId)) {
    console.warn('The following mojom is loaded multiple times: ' + mojomId);
    return;
  }
  mojo.internal.markMojomLoaded(mojomId);
  var bindings = mojo;
  var associatedBindings = mojo;
  var codec = mojo.internal;
  var validator = mojo.internal;

  var exports = mojo.internal.exposeNamespace('content.mojom');
  var values$ =
      mojo.internal.exposeNamespace('mojoBase.mojom');
  if (mojo.config.autoLoadMojomDeps) {
    mojo.internal.loadMojomIfNecessary(
        'mojo/public/mojom/base/values.mojom', '../../../mojo/public/mojom/base/values.mojom.js');
  }



  function AlternativeErrorPageOverrideInfo(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  AlternativeErrorPageOverrideInfo.prototype.initDefaults_ = function() {
    this.resourceId = 0;
    this.alternativeErrorPageParams = null;
  };
  AlternativeErrorPageOverrideInfo.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  AlternativeErrorPageOverrideInfo.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 24}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;



    // validate AlternativeErrorPageOverrideInfo.alternativeErrorPageParams
    err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 8, values$.DictionaryValue, false);
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  AlternativeErrorPageOverrideInfo.encodedSize = codec.kStructHeaderSize + 16;

  AlternativeErrorPageOverrideInfo.decode = function(decoder) {
    var packed;
    var val = new AlternativeErrorPageOverrideInfo();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.resourceId =
        decoder.decodeStruct(codec.Uint32);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    val.alternativeErrorPageParams =
        decoder.decodeStructPointer(values$.DictionaryValue);
    return val;
  };

  AlternativeErrorPageOverrideInfo.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(AlternativeErrorPageOverrideInfo.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStruct(codec.Uint32, val.resourceId);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.encodeStructPointer(values$.DictionaryValue, val.alternativeErrorPageParams);
  };
  exports.AlternativeErrorPageOverrideInfo = AlternativeErrorPageOverrideInfo;
})();