text:
class WhitelistedHost < ApplicationRecord
  has_paper_trail

  before_save :ensure_papertrail_user_config

  before_validation { hostname.try(:downcase!) }
  before_validation { hostname.try(:strip!) }
  validates :hostname, presence: true
  validates :hostname, hostname: true
  validates :hostname, uniqueness: { message: "is already in the list" }
  validate :hostname_is_not_automatically_allowed_anyway

  def ensure_papertrail_user_config
    Transition::History.ensure_user!
  end

  def hostname_is_not_automatically_allowed_anyway
    return if hostname.nil?

    if hostname.end_with?(".gov.uk", ".mod.uk", ".nhs.uk")
      errors.add(:hostname, "cannot end in .gov.uk, .mod.uk or .nhs.uk - these are automatically whitelisted")
    end
  end
end

redpajama_set_name: RedPajamaGithub


text:
using System;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Text;
using System.Xml.Serialization;

namespace TorrentSearch.TorrentSearcher.KickassTorrents
{
    public class KickassTorrentSearcher : ITorrentSearcher
    {
        private const string BaseUrl = "https://kickass.so/usearch/";

        public Torrent[] Search(string query, TorrentCategory category, TorrentSortOrder sortOrder = TorrentSortOrder.Title,
            TorrentSortOptions sortOptions = TorrentSortOptions.Ascending)
        {
            var url = BuildUrlString(query, category, sortOrder, sortOptions);
            Debug.WriteLine("URL = " + url);
            var xmlStream = PerformKickassRequest(url);
            var xmlSerializer = new XmlSerializer(typeof(KickassRssContainer));
            var torrents = (KickassRssContainer)xmlSerializer.Deserialize(xmlStream);
            xmlStream.Close();

            return torrents.Channel.Torrents;
        }

        private static Stream PerformKickassRequest(string url)
        {
            var webRequest = (HttpWebRequest)WebRequest.Create(url);
            webRequest.UserAgent = "Mozilla/5.0 (Windows NT 6.3; WOW64; rv:34.0) Gecko/20100101 Firefox/34.0";
            webRequest.AllowAutoRedirect = true;
            webRequest.AutomaticDecompression = DecompressionMethods.Deflate |
                                                DecompressionMethods.GZip |
                                                DecompressionMethods.None;
            var stream = new MemoryStream();
            using (var webResponse = (HttpWebResponse)webRequest.GetResponse())
            {
                var responseStream = webResponse.GetResponseStream();
                if (responseStream == null)
                {
                    Debug.WriteLine("Response from kickass torrents server was null.");
                    return null;
                }
                var reader = new StreamReader(responseStream);
                var text = reader.ReadToEnd();
                Debug.WriteLine("---- Response ----\n" + text + "\n----   Halt   ----");
                reader.Close();
                var bytes = Encoding.UTF8.GetBytes(text);
                stream.Write(bytes, 0, bytes.Length);
            }
            stream.Position = 0;
            return stream;
        }

        private static string BuildUrlString(string query, TorrentCategory category, TorrentSortOrder sortOrder,
            TorrentSortOptions sortOptions)
        {
            string sortOpt = null, sortOrd = null;
            switch (sortOrder)
            {
                case TorrentSortOrder.Title:        sortOrd = "name"; break;
                case TorrentSortOrder.Size:         sortOrd = "size"; break;
                case TorrentSortOrder.Seeders:      sortOrd = "seeders"; break;
                case TorrentSortOrder.Leechers:     sortOrd = "leechers"; break;
                case TorrentSortOrder.Files:        sortOrd = "files_count"; break;
                case TorrentSortOrder.Age:          sortOrd = "time_add"; break;
            }
            switch (sortOptions)
            {
                case TorrentSortOptions.Ascending:  sortOpt = "asc"; break;
                case TorrentSortOptions.Decending:  sortOpt = "desc"; break;
            }
            return String.Format("{0}{1} category:{2}/?field={3}&sorder={4}&rss=1", BaseUrl, query, category.ToString().ToLower(), sortOrd, sortOpt);
        }
    }
}


text:
%!TEX root = ../hr-paper.tex
\newpage
\section{Results} % (fold)
\label{sec:results}

This section will show the direct results of the intersection over union from the segmentation system. It will also show some cases where the segmentation seemed to have failed and where it succeeded.

\begin{minipage}{\linewidth}
\flushleft
\captionof{table}{IoU Results} \label{tab:results:iou}
\begin{tabular}{ c c c c c c c c c c}
\hline
\hline
0.1		&	0.2		&	0.3		&	0.4		&	0.5		&	0.6		&	0.7		&	0.8		&	0.9		&	1		\\
0.988	&	0.973	&	0.948	&	0.905	&	0.841	&	0.769	&	0.704	&	0.631	&	0.532	&	0.117	\\
\hline
\end{tabular}\par
\bigskip
The results from the segmented characters with the labeled data from the dataset.
\end{minipage}

%2comps

\begin{figure}[ht]
  \centering
  \begin{subfigure}{0.49\textwidth}
    \centering
    \fbox{\includegraphics[width=0.5\textwidth]{./images/results/2-comps-merged.png}}
    \caption{2 connected compoments merged}
    \label{fig:results:2cm:s}
  \end{subfigure}
  \begin{subfigure}{0.49\textwidth}
    \centering
    \fbox{\includegraphics[width=0.5\textwidth]{./images/results/2-comps-merged-o.png}}
    \caption{Cropped image from the dataset with the original character}
    \label{fig:results:2cm:o}
  \end{subfigure}
  \caption{The merger of two connected components illustrated}
  \label{fig:results:2cm}
\end{figure}

%small image

\begin{figure}[ht]
  \centering
  \begin{subfigure}{0.49\textwidth}
    \centering
    \fbox{\includegraphics[width=0.05\textwidth]{./images/results/small-whitespace.png}}
    \caption{A small character segmented correctly}
    \label{fig:results:sw:s}
  \end{subfigure}
  \begin{subfigure}{0.49\textwidth}
    \centering
    \fbox{\includegraphics[width=0.5\textwidth]{./images/results/small-whitespace-o.png}}
    \caption{Cropped image from the dataset with the original character}
    \label{fig:results:sw:o}
  \end{subfigure}
  \caption{original character and segmented character next to each other}
  \label{fig:results:sw}
\end{figure}

%2 in one

\begin{figure}[ht]
  \centering
  \fbox{\includegraphics[width=0.25\textwidth]{./images/results/2inone.png}}
  \caption{Two characters segmented as one}
  \label{fig:results:2i1}
\end{figure}

\newpage

%3 lines

\begin{figure}[ht]
  \centering
  \begin{subfigure}{0.49\textwidth}
    \centering
    \fbox{\includegraphics[width=0.01\textwidth]{./images/results/3-lines.png}}
    \caption{Character partially removed}
    \label{fig:results:3l:s}
  \end{subfigure}
  \begin{subfigure}{0.49\textwidth}
    \centering
    \fbox{\includegraphics[width=0.5\textwidth]{./images/results/3-lines-o.png}}
    \caption{Cropped image from the dataset with the original character}
    \label{fig:results:3l:o}
  \end{subfigure}
  \caption{Character in the dataset and the segmented character}
  \label{fig:results:3l}
\end{figure}

%1.5

\begin{figure}[ht]
  \centering
  \begin{subfigure}{0.49\textwidth}
    \centering
    \fbox{\includegraphics[width=0.3\textwidth]{./images/results/15-1.png}}
    \caption{First character split}
    \label{fig:results:15:s1}
  \end{subfigure}
  \begin{subfigure}{0.49\textwidth}
    \centering
    \fbox{\includegraphics[width=0.3\textwidth]{./images/results/15-2.png}}
    \caption{Second character split}
    \label{fig:results:15:s2}
  \end{subfigure}
    \begin{subfigure}{\textwidth}
    \centering
    \fbox{\includegraphics[width=0.6\textwidth]{./images/results/15-o.png}}
    \caption{Cropped image from the dataset with the original character}
    \label{fig:results:15:o}
  \end{subfigure}
  \caption{Character Split wrongly to contain 1.5 of character}
  \label{fig:results:15}
\end{figure}

\newpage

%Big line

\begin{figure}[ht]
  \centering
  \fbox{\includegraphics[width=0.8\textwidth]{./images/results/big-line.png}}
  \caption{Character segmentation with a noise line}
  \label{fig:results:bl}
\end{figure}

%Blackbar

%Noise ball

\begin{figure}[ht]
  \centering
  \begin{subfigure}{0.49\textwidth}
    \centering
    \fbox{\includegraphics[width=0.05\textwidth]{./images/results/noise-ball.png}}
    \caption{`Noise ball'}
    \label{fig:results:noise:nb}
  \end{subfigure}
  \begin{subfigure}{0.49\textwidth}
    \centering
    \fbox{\includegraphics[width=0.05\textwidth]{./images/results/blackbar.png}}
    \caption{`Black bar'}
    \label{fig:results:noise:bb}
  \end{subfigure}
  \caption{Character segmentation of noise components}
  \label{fig:results:noise}
\end{figure}

% - image to big due to line noise
% image to big due to other noise
% correct small
% 2 in one
% - 1.5

% section results (end)


text:
% Hevea - ITILv3 Resumo
% An ITILv3 overview.
%
% Author: José Lopes de Oliveira Jr. <jilo.cc>
%
% LICENSE
% This program is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% This program is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with this program.  If not, see <http://www.gnu.org/licenses/>.
%%

\fancyhead{}  % clear header
\fancyfoot{}  % clear footer
\fancyhead[RO]{\rightmark}  % section name in upper right
\fancyhead[LE]{\leftmark}  % chapter name in upper left
\fancyfoot[LO,RE]{\thepage}  % numbering in outter border

% Preparing for textinfo content
\pagestyle{empty}
\pagenumbering{roman}

\input{./metacontent-title.tex}  % \include{} can't be nested

% Back cover
\hspace{.1cm}\centerline{\includegraphics[scale=.7]{img/indiecode}}

% Cataloguing rules
\vspace{3.5cm}
\fbox{
    \begin{minipage}[b][7.5cm][c]{\linewidth}
        Oliveira Júnior, José Lopes\\
        ITIL\textsuperscript{\textregistered}v3: Resumo\\
        1\textordfeminine edição, \pageref{LastPage} páginas --- março de 2012\
        \begin{enumerate}
            \item ITIL\textsuperscript{\textregistered}
            \item Tecnologia da Informação
            \item Governança de TI
        \end{enumerate}
        I. Título\\
        \vfill
        Correções, sugestões ou críticas: \url{http://jilo.cc}\\
    \end{minipage}
}

\vspace{1cm}
\hfill\fbox{
    \begin{minipage}{10cm}
        O trabalho \textbf{ITIL\textsuperscript{\textregistered}v3: Resumo} de
        \href{http://jilo.cc}{José Lopes Oliveira Jr.} foi licenciado com uma
        \href{http://creativecommons.org/licenses/by-sa/3.0/br/}{CC BY-SA 3.0
        Brasil}.
    \end{minipage}
}\hfill

% List of elements
\printnomenclature[3cm]  % acronym [3cm] Explanation
\tableofcontents

% Preparing for the content
\newpage
\pagestyle{fancy}
\pagenumbering{arabic}


text:
package com.geth1b.coding.skills.lc;

/**
 *  [Reference URL]:  https://leetcode.com/problems/reverse-bits/
 *      [Algorithm]:  Bit manipulation
 * [Data Structure]:  Array
 *      [Time BigO]:  O(n)
 *     [Space BigO]:  O(1)
 *
 * @author geth1b
 */
public class _190_ReverseBits {

  // ===========================================================================
  // you need treat n as an unsigned value
  // thus cannot use % (i.e. remainder operator as it could return negative)

  // ===========================================================================
  // for the hint, we may create a hashmap to maintain
  // if reverse A is B, then add a B->A in case next call is B; simple idea
  // at least we can talk about

  // ===========================================================================
  // Bit manipulation - use left / right shift and bit & is a lot clear; mod 2 will *NOT* work
  //                  - process from right only to make it easier; swap bits at interior pos are confusing
  //
  // [KEY POINT] early exit when n is already 0; shift result for remaining 0's bits
  //
  // O(1) time - loop 32 bits
  // O(1) space

  public int reverseBits(int n) {
    int result = 0;
    int i = 0; // ith pos from right most to left
    while (i < 32 && n != 0) {
      int bit = n & 1;
      result <<= 1; // left shift to make one bit room to the right most
      result |= bit;
      n >>>= 1; // remove right bit in old num n
      i++;
    }
    return result << (32 - i);
  }

  // Bit manipulation - use left / right shift and bit & is a lot clear; mod 2 will *NOT* work
  //                  - process from right only to make it easier; swap bits at interior pos are confusing
  //
  // O(1) time - loop 32 bits
  // O(1) space
  // you need treat n as an unsigned value

  public int reverseBits_basic(int n) {
    int result = 0;
    for (int i = 0; i < 32; i++) {
      int bit = n & 1;
      result <<= 1; // left shift to make one bit room to the right most
      result |= bit;
      n >>>= 1; // remove right bit in old num n
    }
    return result;
  }

}


text:
// Copyright (c) 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "quiche/quic/core/crypto/transport_parameters.h"

#include <cstdint>
#include <cstring>
#include <forward_list>
#include <memory>
#include <utility>

#include "absl/strings/escaping.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "openssl/digest.h"
#include "openssl/sha.h"
#include "quiche/quic/core/quic_connection_id.h"
#include "quiche/quic/core/quic_data_reader.h"
#include "quiche/quic/core/quic_data_writer.h"
#include "quiche/quic/core/quic_types.h"
#include "quiche/quic/core/quic_utils.h"
#include "quiche/quic/core/quic_versions.h"
#include "quiche/quic/platform/api/quic_bug_tracker.h"
#include "quiche/quic/platform/api/quic_flag_utils.h"
#include "quiche/quic/platform/api/quic_ip_address.h"

namespace quic {

// Values of the TransportParameterId enum as defined in the
// "Transport Parameter Encoding" section of draft-ietf-quic-transport.
// When parameters are encoded, one of these enum values is used to indicate
// which parameter is encoded. The supported draft version is noted in
// transport_parameters.h.
enum TransportParameters::TransportParameterId : uint64_t {
  kOriginalDestinationConnectionId = 0,
  kMaxIdleTimeout = 1,
  kStatelessResetToken = 2,
  kMaxPacketSize = 3,
  kInitialMaxData = 4,
  kInitialMaxStreamDataBidiLocal = 5,
  kInitialMaxStreamDataBidiRemote = 6,
  kInitialMaxStreamDataUni = 7,
  kInitialMaxStreamsBidi = 8,
  kInitialMaxStreamsUni = 9,
  kAckDelayExponent = 0xa,
  kMaxAckDelay = 0xb,
  kDisableActiveMigration = 0xc,
  kPreferredAddress = 0xd,
  kActiveConnectionIdLimit = 0xe,
  kInitialSourceConnectionId = 0xf,
  kRetrySourceConnectionId = 0x10,

  kMaxDatagramFrameSize = 0x20,

  kGoogleHandshakeMessage = 0x26ab,

  kInitialRoundTripTime = 0x3127,
  kGoogleConnectionOptions = 0x3128,
  // 0x3129 was used to convey the user agent string.
  // 0x312A was used only in T050 to indicate support for HANDSHAKE_DONE.
  // 0x312B was used to indicate that QUIC+TLS key updates were not supported.
  // 0x4751 was used for non-standard Google-specific parameters encoded as a
  // Google QUIC_CRYPTO CHLO, it has been replaced by individual parameters.
  kGoogleQuicVersion =
      0x4752,  // Used to transmit version and supported_versions.

  kMinAckDelay = 0xDE1A,           // draft-iyengar-quic-delayed-ack.
  kVersionInformation = 0xFF73DB,  // draft-ietf-quic-version-negotiation.
};

namespace {

constexpr QuicVersionLabel kReservedVersionMask = 0x0f0f0f0f;
constexpr QuicVersionLabel kReservedVersionBits = 0x0a0a0a0a;

// The following constants define minimum and maximum allowed values for some of
// the parameters. These come from the "Transport Parameter Definitions"
// section of draft-ietf-quic-transport.
constexpr uint64_t kMinMaxPacketSizeTransportParam = 1200;
constexpr uint64_t kMaxAckDelayExponentTransportParam = 20;
constexpr uint64_t kDefaultAckDelayExponentTransportParam = 3;
constexpr uint64_t kMaxMaxAckDelayTransportParam = 16383;
constexpr uint64_t kDefaultMaxAckDelayTransportParam = 25;
constexpr uint64_t kMinActiveConnectionIdLimitTransportParam = 2;
constexpr uint64_t kDefaultActiveConnectionIdLimitTransportParam = 2;

std::string TransportParameterIdToString(
    TransportParameters::TransportParameterId param_id) {
  switch (param_id) {
    case TransportParameters::kOriginalDestinationConnectionId:
      return "original_destination_connection_id";
    case TransportParameters::kMaxIdleTimeout:
      return "max_idle_timeout";
    case TransportParameters::kStatelessResetToken:
      return "stateless_reset_token";
    case TransportParameters::kMaxPacketSize:
      return "max_udp_payload_size";
    case TransportParameters::kInitialMaxData:
      return "initial_max_data";
    case TransportParameters::kInitialMaxStreamDataBidiLocal:
      return "initial_max_stream_data_bidi_local";
    case TransportParameters::kInitialMaxStreamDataBidiRemote:
      return "initial_max_stream_data_bidi_remote";
    case TransportParameters::kInitialMaxStreamDataUni:
      return "initial_max_stream_data_uni";
    case TransportParameters::kInitialMaxStreamsBidi:
      return "initial_max_streams_bidi";
    case TransportParameters::kInitialMaxStreamsUni:
      return "initial_max_streams_uni";
    case TransportParameters::kAckDelayExponent:
      return "ack_delay_exponent";
    case TransportParameters::kMaxAckDelay:
      return "max_ack_delay";
    case TransportParameters::kDisableActiveMigration:
      return "disable_active_migration";
    case TransportParameters::kPreferredAddress:
      return "preferred_address";
    case TransportParameters::kActiveConnectionIdLimit:
      return "active_connection_id_limit";
    case TransportParameters::kInitialSourceConnectionId:
      return "initial_source_connection_id";
    case TransportParameters::kRetrySourceConnectionId:
      return "retry_source_connection_id";
    case TransportParameters::kMaxDatagramFrameSize:
      return "max_datagram_frame_size";
    case TransportParameters::kGoogleHandshakeMessage:
      return "google_handshake_message";
    case TransportParameters::kInitialRoundTripTime:
      return "initial_round_trip_time";
    case TransportParameters::kGoogleConnectionOptions:
      return "google_connection_options";
    case TransportParameters::kGoogleQuicVersion:
      return "google-version";
    case TransportParameters::kMinAckDelay:
      return "min_ack_delay_us";
    case TransportParameters::kVersionInformation:
      return "version_information";
  }
  return absl::StrCat("Unknown(", param_id, ")");
}

bool TransportParameterIdIsKnown(
    TransportParameters::TransportParameterId param_id) {
  switch (param_id) {
    case TransportParameters::kOriginalDestinationConnectionId:
    case TransportParameters::kMaxIdleTimeout:
    case TransportParameters::kStatelessResetToken:
    case TransportParameters::kMaxPacketSize:
    case TransportParameters::kInitialMaxData:
    case TransportParameters::kInitialMaxStreamDataBidiLocal:
    case TransportParameters::kInitialMaxStreamDataBidiRemote:
    case TransportParameters::kInitialMaxStreamDataUni:
    case TransportParameters::kInitialMaxStreamsBidi:
    case TransportParameters::kInitialMaxStreamsUni:
    case TransportParameters::kAckDelayExponent:
    case TransportParameters::kMaxAckDelay:
    case TransportParameters::kDisableActiveMigration:
    case TransportParameters::kPreferredAddress:
    case TransportParameters::kActiveConnectionIdLimit:
    case TransportParameters::kInitialSourceConnectionId:
    case TransportParameters::kRetrySourceConnectionId:
    case TransportParameters::kMaxDatagramFrameSize:
    case TransportParameters::kGoogleHandshakeMessage:
    case TransportParameters::kInitialRoundTripTime:
    case TransportParameters::kGoogleConnectionOptions:
    case TransportParameters::kGoogleQuicVersion:
    case TransportParameters::kMinAckDelay:
    case TransportParameters::kVersionInformation:
      return true;
  }
  return false;
}

}  // namespace

TransportParameters::IntegerParameter::IntegerParameter(
    TransportParameters::TransportParameterId param_id, uint64_t default_value,
    uint64_t min_value, uint64_t max_value)
    : param_id_(param_id),
      value_(default_value),
      default_value_(default_value),
      min_value_(min_value),
      max_value_(max_value),
      has_been_read_(false) {
  QUICHE_DCHECK_LE(min_value, default_value);
  QUICHE_DCHECK_LE(default_value, max_value);
  QUICHE_DCHECK_LE(max_value, quiche::kVarInt62MaxValue);
}

TransportParameters::IntegerParameter::IntegerParameter(
    TransportParameters::TransportParameterId param_id)
    : TransportParameters::IntegerParameter::IntegerParameter(
          param_id, 0, 0, quiche::kVarInt62MaxValue) {}

void TransportParameters::IntegerParameter::set_value(uint64_t value) {
  value_ = value;
}

uint64_t TransportParameters::IntegerParameter::value() const { return value_; }

bool TransportParameters::IntegerParameter::IsValid() const {
  return min_value_ <= value_ && value_ <= max_value_;
}

bool TransportParameters::IntegerParameter::Write(
    QuicDataWriter* writer) const {
  QUICHE_DCHECK(IsValid());
  if (value_ == default_value_) {
    // Do not write if the value is default.
    return true;
  }
  if (!writer->WriteVarInt62(param_id_)) {
    QUIC_BUG(quic_bug_10743_1) << "Failed to write param_id for " << *this;
    return false;
  }
  const quiche::QuicheVariableLengthIntegerLength value_length =
      QuicDataWriter::GetVarInt62Len(value_);
  if (!writer->WriteVarInt62(value_length)) {
    QUIC_BUG(quic_bug_10743_2) << "Failed to write value_length for " << *this;
    return false;
  }
  if (!writer->WriteVarInt62WithForcedLength(value_, value_length)) {
    QUIC_BUG(quic_bug_10743_3) << "Failed to write value for " << *this;
    return false;
  }
  return true;
}

bool TransportParameters::IntegerParameter::Read(QuicDataReader* reader,
                                                 std::string* error_details) {
  if (has_been_read_) {
    *error_details =
        "Received a second " + TransportParameterIdToString(param_id_);
    return false;
  }
  has_been_read_ = true;

  if (!reader->ReadVarInt62(&value_)) {
    *error_details =
        "Failed to parse value for " + TransportParameterIdToString(param_id_);
    return false;
  }
  if (!reader->IsDoneReading()) {
    *error_details =
        absl::StrCat("Received unexpected ", reader->BytesRemaining(),
                     " bytes after parsing ", this->ToString(false));
    return false;
  }
  return true;
}

std::string TransportParameters::IntegerParameter::ToString(
    bool for_use_in_list) const {
  if (for_use_in_list && value_ == default_value_) {
    return "";
  }
  std::string rv = for_use_in_list ? " " : "";
  absl::StrAppend(&rv, TransportParameterIdToString(param_id_), " ", value_);
  if (!IsValid()) {
    rv += " (Invalid)";
  }
  return rv;
}

std::ostream& operator<<(std::ostream& os,
                         const TransportParameters::IntegerParameter& param) {
  os << param.ToString(/*for_use_in_list=*/false);
  return os;
}

TransportParameters::PreferredAddress::PreferredAddress()
    : ipv4_socket_address(QuicIpAddress::Any4(), 0),
      ipv6_socket_address(QuicIpAddress::Any6(), 0),
      connection_id(EmptyQuicConnectionId()),
      stateless_reset_token(kStatelessResetTokenLength, 0) {}

TransportParameters::PreferredAddress::~PreferredAddress() {}

bool TransportParameters::PreferredAddress::operator==(
    const PreferredAddress& rhs) const {
  return ipv4_socket_address == rhs.ipv4_socket_address &&
         ipv6_socket_address == rhs.ipv6_socket_address &&
         connection_id == rhs.connection_id &&
         stateless_reset_token == rhs.stateless_reset_token;
}

bool TransportParameters::PreferredAddress::operator!=(
    const PreferredAddress& rhs) const {
  return !(*this == rhs);
}

std::ostream& operator<<(
    std::ostream& os,
    const TransportParameters::PreferredAddress& preferred_address) {
  os << preferred_address.ToString();
  return os;
}

std::string TransportParameters::PreferredAddress::ToString() const {
  return "[" + ipv4_socket_address.ToString() + " " +
         ipv6_socket_address.ToString() + " connection_id " +
         connection_id.ToString() + " stateless_reset_token " +
         absl::BytesToHexString(absl::string_view(
             reinterpret_cast<const char*>(stateless_reset_token.data()),
             stateless_reset_token.size())) +
         "]";
}

TransportParameters::LegacyVersionInformation::LegacyVersionInformation()
    : version(0) {}

bool TransportParameters::LegacyVersionInformation::operator==(
    const LegacyVersionInformation& rhs) const {
  return version == rhs.version && supported_versions == rhs.supported_versions;
}

bool TransportParameters::LegacyVersionInformation::operator!=(
    const LegacyVersionInformation& rhs) const {
  return !(*this == rhs);
}

std::string TransportParameters::LegacyVersionInformation::ToString() const {
  std::string rv =
      absl::StrCat("legacy[version ", QuicVersionLabelToString(version));
  if (!supported_versions.empty()) {
    absl::StrAppend(&rv,
                    " supported_versions " +
                        QuicVersionLabelVectorToString(supported_versions));
  }
  absl::StrAppend(&rv, "]");
  return rv;
}

std::ostream& operator<<(std::ostream& os,
                         const TransportParameters::LegacyVersionInformation&
                             legacy_version_information) {
  os << legacy_version_information.ToString();
  return os;
}

TransportParameters::VersionInformation::VersionInformation()
    : chosen_version(0) {}

bool TransportParameters::VersionInformation::operator==(
    const VersionInformation& rhs) const {
  return chosen_version == rhs.chosen_version &&
         other_versions == rhs.other_versions;
}

bool TransportParameters::VersionInformation::operator!=(
    const VersionInformation& rhs) const {
  return !(*this == rhs);
}

std::string TransportParameters::VersionInformation::ToString() const {
  std::string rv = absl::StrCat("[chosen_version ",
                                QuicVersionLabelToString(chosen_version));
  if (!other_versions.empty()) {
    absl::StrAppend(&rv, " other_versions " +
                             QuicVersionLabelVectorToString(other_versions));
  }
  absl::StrAppend(&rv, "]");
  return rv;
}

std::ostream& operator<<(
    std::ostream& os,
    const TransportParameters::VersionInformation& version_information) {
  os << version_information.ToString();
  return os;
}

std::ostream& operator<<(std::ostream& os, const TransportParameters& params) {
  os << params.ToString();
  return os;
}

std::string TransportParameters::ToString() const {
  std::string rv = "[";
  if (perspective == Perspective::IS_SERVER) {
    rv += "Server";
  } else {
    rv += "Client";
  }
  if (legacy_version_information.has_value()) {
    rv += " " + legacy_version_information.value().ToString();
  }
  if (version_information.has_value()) {
    rv += " " + version_information.value().ToString();
  }
  if (original_destination_connection_id.has_value()) {
    rv += " " + TransportParameterIdToString(kOriginalDestinationConnectionId) +
          " " + original_destination_connection_id.value().ToString();
  }
  rv += max_idle_timeout_ms.ToString(/*for_use_in_list=*/true);
  if (!stateless_reset_token.empty()) {
    rv += " " + TransportParameterIdToString(kStatelessResetToken) + " " +
          absl::BytesToHexString(absl::string_view(
              reinterpret_cast<const char*>(stateless_reset_token.data()),
              stateless_reset_token.size()));
  }
  rv += max_udp_payload_size.ToString(/*for_use_in_list=*/true);
  rv += initial_max_data.ToString(/*for_use_in_list=*/true);
  rv += initial_max_stream_data_bidi_local.ToString(/*for_use_in_list=*/true);
  rv += initial_max_stream_data_bidi_remote.ToString(/*for_use_in_list=*/true);
  rv += initial_max_stream_data_uni.ToString(/*for_use_in_list=*/true);
  rv += initial_max_streams_bidi.ToString(/*for_use_in_list=*/true);
  rv += initial_max_streams_uni.ToString(/*for_use_in_list=*/true);
  rv += ack_delay_exponent.ToString(/*for_use_in_list=*/true);
  rv += max_ack_delay.ToString(/*for_use_in_list=*/true);
  rv += min_ack_delay_us.ToString(/*for_use_in_list=*/true);
  if (disable_active_migration) {
    rv += " " + TransportParameterIdToString(kDisableActiveMigration);
  }
  if (preferred_address) {
    rv += " " + TransportParameterIdToString(kPreferredAddress) + " " +
          preferred_address->ToString();
  }
  rv += active_connection_id_limit.ToString(/*for_use_in_list=*/true);
  if (initial_source_connection_id.has_value()) {
    rv += " " + TransportParameterIdToString(kInitialSourceConnectionId) + " " +
          initial_source_connection_id.value().ToString();
  }
  if (retry_source_connection_id.has_value()) {
    rv += " " + TransportParameterIdToString(kRetrySourceConnectionId) + " " +
          retry_source_connection_id.value().ToString();
  }
  rv += max_datagram_frame_size.ToString(/*for_use_in_list=*/true);
  if (google_handshake_message.has_value()) {
    absl::StrAppend(&rv, " ",
                    TransportParameterIdToString(kGoogleHandshakeMessage),
                    " length: ", google_handshake_message.value().length());
  }
  rv += initial_round_trip_time_us.ToString(/*for_use_in_list=*/true);
  if (google_connection_options.has_value()) {
    rv += " " + TransportParameterIdToString(kGoogleConnectionOptions) + " ";
    bool first = true;
    for (const QuicTag& connection_option : google_connection_options.value()) {
      if (first) {
        first = false;
      } else {
        rv += ",";
      }
      rv += QuicTagToString(connection_option);
    }
  }
  for (const auto& kv : custom_parameters) {
    absl::StrAppend(&rv, " 0x", absl::Hex(static_cast<uint32_t>(kv.first)),
                    "=");
    static constexpr size_t kMaxPrintableLength = 32;
    if (kv.second.length() <= kMaxPrintableLength) {
      rv += absl::BytesToHexString(kv.second);
    } else {
      absl::string_view truncated(kv.second.data(), kMaxPrintableLength);
      rv += absl::StrCat(absl::BytesToHexString(truncated), "...(length ",
                         kv.second.length(), ")");
    }
  }
  rv += "]";
  return rv;
}

TransportParameters::TransportParameters()
    : max_idle_timeout_ms(kMaxIdleTimeout),
      max_udp_payload_size(kMaxPacketSize, kDefaultMaxPacketSizeTransportParam,
                           kMinMaxPacketSizeTransportParam,
                           quiche::kVarInt62MaxValue),
      initial_max_data(kInitialMaxData),
      initial_max_stream_data_bidi_local(kInitialMaxStreamDataBidiLocal),
      initial_max_stream_data_bidi_remote(kInitialMaxStreamDataBidiRemote),
      initial_max_stream_data_uni(kInitialMaxStreamDataUni),
      initial_max_streams_bidi(kInitialMaxStreamsBidi),
      initial_max_streams_uni(kInitialMaxStreamsUni),
      ack_delay_exponent(kAckDelayExponent,
                         kDefaultAckDelayExponentTransportParam, 0,
                         kMaxAckDelayExponentTransportParam),
      max_ack_delay(kMaxAckDelay, kDefaultMaxAckDelayTransportParam, 0,
                    kMaxMaxAckDelayTransportParam),
      min_ack_delay_us(kMinAckDelay, 0, 0,
                       kMaxMaxAckDelayTransportParam * kNumMicrosPerMilli),
      disable_active_migration(false),
      active_connection_id_limit(kActiveConnectionIdLimit,
                                 kDefaultActiveConnectionIdLimitTransportParam,
                                 kMinActiveConnectionIdLimitTransportParam,
                                 quiche::kVarInt62MaxValue),
      max_datagram_frame_size(kMaxDatagramFrameSize),
      initial_round_trip_time_us(kInitialRoundTripTime)
// Important note: any new transport parameters must be added
// to TransportParameters::AreValid, SerializeTransportParameters and
// ParseTransportParameters, TransportParameters's custom copy constructor, the
// operator==, and TransportParametersTest.Comparator.
{}

TransportParameters::TransportParameters(const TransportParameters& other)
    : perspective(other.perspective),
      legacy_version_information(other.legacy_version_information),
      version_information(other.version_information),
      original_destination_connection_id(
          other.original_destination_connection_id),
      max_idle_timeout_ms(other.max_idle_timeout_ms),
      stateless_reset_token(other.stateless_reset_token),
      max_udp_payload_size(other.max_udp_payload_size),
      initial_max_data(other.initial_max_data),
      initial_max_stream_data_bidi_local(
          other.initial_max_stream_data_bidi_local),
      initial_max_stream_data_bidi_remote(
          other.initial_max_stream_data_bidi_remote),
      initial_max_stream_data_uni(other.initial_max_stream_data_uni),
      initial_max_streams_bidi(other.initial_max_streams_bidi),
      initial_max_streams_uni(other.initial_max_streams_uni),
      ack_delay_exponent(other.ack_delay_exponent),
      max_ack_delay(other.max_ack_delay),
      min_ack_delay_us(other.min_ack_delay_us),
      disable_active_migration(other.disable_active_migration),
      active_connection_id_limit(other.active_connection_id_limit),
      initial_source_connection_id(other.initial_source_connection_id),
      retry_source_connection_id(other.retry_source_connection_id),
      max_datagram_frame_size(other.max_datagram_frame_size),
      initial_round_trip_time_us(other.initial_round_trip_time_us),
      google_handshake_message(other.google_handshake_message),
      google_connection_options(other.google_connection_options),
      custom_parameters(other.custom_parameters) {
  if (other.preferred_address) {
    preferred_address = std::make_unique<TransportParameters::PreferredAddress>(
        *other.preferred_address);
  }
}

bool TransportParameters::operator==(const TransportParameters& rhs) const {
  if (!(perspective == rhs.perspective &&
        legacy_version_information == rhs.legacy_version_information &&
        version_information == rhs.version_information &&
        original_destination_connection_id ==
            rhs.original_destination_connection_id &&
        max_idle_timeout_ms.value() == rhs.max_idle_timeout_ms.value() &&
        stateless_reset_token == rhs.stateless_reset_token &&
        max_udp_payload_size.value() == rhs.max_udp_payload_size.value() &&
        initial_max_data.value() == rhs.initial_max_data.value() &&
        initial_max_stream_data_bidi_local.value() ==
            rhs.initial_max_stream_data_bidi_local.value() &&
        initial_max_stream_data_bidi_remote.value() ==
            rhs.initial_max_stream_data_bidi_remote.value() &&
        initial_max_stream_data_uni.value() ==
            rhs.initial_max_stream_data_uni.value() &&
        initial_max_streams_bidi.value() ==
            rhs.initial_max_streams_bidi.value() &&
        initial_max_streams_uni.value() ==
            rhs.initial_max_streams_uni.value() &&
        ack_delay_exponent.value() == rhs.ack_delay_exponent.value() &&
        max_ack_delay.value() == rhs.max_ack_delay.value() &&
        min_ack_delay_us.value() == rhs.min_ack_delay_us.value() &&
        disable_active_migration == rhs.disable_active_migration &&
        active_connection_id_limit.value() ==
            rhs.active_connection_id_limit.value() &&
        initial_source_connection_id == rhs.initial_source_connection_id &&
        retry_source_connection_id == rhs.retry_source_connection_id &&
        max_datagram_frame_size.value() ==
            rhs.max_datagram_frame_size.value() &&
        initial_round_trip_time_us.value() ==
            rhs.initial_round_trip_time_us.value() &&
        google_handshake_message == rhs.google_handshake_message &&
        google_connection_options == rhs.google_connection_options &&
        custom_parameters == rhs.custom_parameters)) {
    return false;
  }

  if ((!preferred_address && rhs.preferred_address) ||
      (preferred_address && !rhs.preferred_address)) {
    return false;
  }
  if (preferred_address && rhs.preferred_address &&
      *preferred_address != *rhs.preferred_address) {
    return false;
  }

  return true;
}

bool TransportParameters::operator!=(const TransportParameters& rhs) const {
  return !(*this == rhs);
}

bool TransportParameters::AreValid(std::string* error_details) const {
  QUICHE_DCHECK(perspective == Perspective::IS_CLIENT ||
                perspective == Perspective::IS_SERVER);
  if (perspective == Perspective::IS_CLIENT && !stateless_reset_token.empty()) {
    *error_details = "Client cannot send stateless reset token";
    return false;
  }
  if (perspective == Perspective::IS_CLIENT &&
      original_destination_connection_id.has_value()) {
    *error_details = "Client cannot send original_destination_connection_id";
    return false;
  }
  if (!stateless_reset_token.empty() &&
      stateless_reset_token.size() != kStatelessResetTokenLength) {
    *error_details = absl::StrCat("Stateless reset token has bad length ",
                                  stateless_reset_token.size());
    return false;
  }
  if (perspective == Perspective::IS_CLIENT && preferred_address) {
    *error_details = "Client cannot send preferred address";
    return false;
  }
  if (preferred_address && preferred_address->stateless_reset_token.size() !=
                               kStatelessResetTokenLength) {
    *error_details =
        absl::StrCat("Preferred address stateless reset token has bad length ",
                     preferred_address->stateless_reset_token.size());
    return false;
  }
  if (preferred_address &&
      (!preferred_address->ipv4_socket_address.host().IsIPv4() ||
       !preferred_address->ipv6_socket_address.host().IsIPv6())) {
    QUIC_BUG(quic_bug_10743_4) << "Preferred address family failure";
    *error_details = "Internal preferred address family failure";
    return false;
  }
  if (perspective == Perspective::IS_CLIENT &&
      retry_source_connection_id.has_value()) {
    *error_details = "Client cannot send retry_source_connection_id";
    return false;
  }
  for (const auto& kv : custom_parameters) {
    if (TransportParameterIdIsKnown(kv.first)) {
      *error_details = absl::StrCat("Using custom_parameters with known ID ",
                                    TransportParameterIdToString(kv.first),
                                    " is not allowed");
      return false;
    }
  }
  if (perspective == Perspective::IS_SERVER &&
      google_handshake_message.has_value()) {
    *error_details = "Server cannot send google_handshake_message";
    return false;
  }
  if (perspective == Perspective::IS_SERVER &&
      initial_round_trip_time_us.value() > 0) {
    *error_details = "Server cannot send initial round trip time";
    return false;
  }
  if (version_information.has_value()) {
    const QuicVersionLabel& chosen_version =
        version_information.value().chosen_version;
    const QuicVersionLabelVector& other_versions =
        version_information.value().other_versions;
    if (chosen_version == 0) {
      *error_details = "Invalid chosen version";
      return false;
    }
    if (perspective == Perspective::IS_CLIENT &&
        std::find(other_versions.begin(), other_versions.end(),
                  chosen_version) == other_versions.end()) {
      // When sent by the client, chosen_version needs to be present in
      // other_versions because other_versions lists the compatible versions and
      // the chosen version is part of that list. When sent by the server,
      // other_version contains the list of fully-deployed versions which is
      // generally equal to the list of supported versions but can slightly
      // differ during removal of versions across a server fleet. See
      // draft-ietf-quic-version-negotiation for details.
      *error_details = "Client chosen version not in other versions";
      return false;
    }
  }
  const bool ok =
      max_idle_timeout_ms.IsValid() && max_udp_payload_size.IsValid() &&
      initial_max_data.IsValid() &&
      initial_max_stream_data_bidi_local.IsValid() &&
      initial_max_stream_data_bidi_remote.IsValid() &&
      initial_max_stream_data_uni.IsValid() &&
      initial_max_streams_bidi.IsValid() && initial_max_streams_uni.IsValid() &&
      ack_delay_exponent.IsValid() && max_ack_delay.IsValid() &&
      min_ack_delay_us.IsValid() && active_connection_id_limit.IsValid() &&
      max_datagram_frame_size.IsValid() && initial_round_trip_time_us.IsValid();
  if (!ok) {
    *error_details = "Invalid transport parameters " + this->ToString();
  }
  return ok;
}

TransportParameters::~TransportParameters() = default;

bool SerializeTransportParameters(const TransportParameters& in,
                                  std::vector<uint8_t>* out) {
  std::string error_details;
  if (!in.AreValid(&error_details)) {
    QUIC_BUG(invalid transport parameters)
        << "Not serializing invalid transport parameters: " << error_details;
    return false;
  }
  if (!in.legacy_version_information.has_value() ||
      in.legacy_version_information.value().version == 0 ||
      (in.perspective == Perspective::IS_SERVER &&
       in.legacy_version_information.value().supported_versions.empty())) {
    QUIC_BUG(missing versions) << "Refusing to serialize without versions";
    return false;
  }
  TransportParameters::ParameterMap custom_parameters = in.custom_parameters;
  for (const auto& kv : custom_parameters) {
    if (kv.first % 31 == 27) {
      // See the "Reserved Transport Parameters" section of RFC 9000.
      QUIC_BUG(custom_parameters with GREASE)
          << "Serializing custom_parameters with GREASE ID " << kv.first
          << " is not allowed";
      return false;
    }
  }

  // Maximum length of the GREASE transport parameter (see below).
  static constexpr size_t kMaxGreaseLength = 16;

  // Empirically transport parameters generally fit within 128 bytes, but we
  // need to allocate the size up front. Integer transport parameters
  // have a maximum encoded length of 24 bytes (3 variable length integers),
  // other transport parameters have a length of 16 + the maximum value length.
  static constexpr size_t kTypeAndValueLength = 2 * sizeof(uint64_t);
  static constexpr size_t kIntegerParameterLength =
      kTypeAndValueLength + sizeof(uint64_t);
  static constexpr size_t kStatelessResetParameterLength =
      kTypeAndValueLength + 16 /* stateless reset token length */;
  static constexpr size_t kConnectionIdParameterLength =
      kTypeAndValueLength + 255 /* maximum connection ID length */;
  static constexpr size_t kPreferredAddressParameterLength =
      kTypeAndValueLength + 4 /*IPv4 address */ + 2 /* IPv4 port */ +
      16 /* IPv6 address */ + 1 /* Connection ID length */ +
      255 /* maximum connection ID length */ + 16 /* stateless reset token */;
  static constexpr size_t kKnownTransportParamLength =
      kConnectionIdParameterLength +      // original_destination_connection_id
      kIntegerParameterLength +           // max_idle_timeout
      kStatelessResetParameterLength +    // stateless_reset_token
      kIntegerParameterLength +           // max_udp_payload_size
      kIntegerParameterLength +           // initial_max_data
      kIntegerParameterLength +           // initial_max_stream_data_bidi_local
      kIntegerParameterLength +           // initial_max_stream_data_bidi_remote
      kIntegerParameterLength +           // initial_max_stream_data_uni
      kIntegerParameterLength +           // initial_max_streams_bidi
      kIntegerParameterLength +           // initial_max_streams_uni
      kIntegerParameterLength +           // ack_delay_exponent
      kIntegerParameterLength +           // max_ack_delay
      kIntegerParameterLength +           // min_ack_delay_us
      kTypeAndValueLength +               // disable_active_migration
      kPreferredAddressParameterLength +  // preferred_address
      kIntegerParameterLength +           // active_connection_id_limit
      kConnectionIdParameterLength +      // initial_source_connection_id
      kConnectionIdParameterLength +      // retry_source_connection_id
      kIntegerParameterLength +           // max_datagram_frame_size
      kIntegerParameterLength +           // initial_round_trip_time_us
      kTypeAndValueLength +               // google_handshake_message
      kTypeAndValueLength +               // google_connection_options
      kTypeAndValueLength;                // google-version

  std::vector<TransportParameters::TransportParameterId> parameter_ids = {
      TransportParameters::kOriginalDestinationConnectionId,
      TransportParameters::kMaxIdleTimeout,
      TransportParameters::kStatelessResetToken,
      TransportParameters::kMaxPacketSize,
      TransportParameters::kInitialMaxData,
      TransportParameters::kInitialMaxStreamDataBidiLocal,
      TransportParameters::kInitialMaxStreamDataBidiRemote,
      TransportParameters::kInitialMaxStreamDataUni,
      TransportParameters::kInitialMaxStreamsBidi,
      TransportParameters::kInitialMaxStreamsUni,
      TransportParameters::kAckDelayExponent,
      TransportParameters::kMaxAckDelay,
      TransportParameters::kMinAckDelay,
      TransportParameters::kActiveConnectionIdLimit,
      TransportParameters::kMaxDatagramFrameSize,
      TransportParameters::kGoogleHandshakeMessage,
      TransportParameters::kInitialRoundTripTime,
      TransportParameters::kDisableActiveMigration,
      TransportParameters::kPreferredAddress,
      TransportParameters::kInitialSourceConnectionId,
      TransportParameters::kRetrySourceConnectionId,
      TransportParameters::kGoogleConnectionOptions,
      TransportParameters::kGoogleQuicVersion,
      TransportParameters::kVersionInformation,
  };

  size_t max_transport_param_length = kKnownTransportParamLength;
  // google_connection_options.
  if (in.google_connection_options.has_value()) {
    max_transport_param_length +=
        in.google_connection_options.value().size() * sizeof(QuicTag);
  }
  // Google-specific version extension.
  if (in.legacy_version_information.has_value()) {
    max_transport_param_length +=
        sizeof(in.legacy_version_information.value().version) +
        1 /* versions length */ +
        in.legacy_version_information.value().supported_versions.size() *
            sizeof(QuicVersionLabel);
  }
  // version_information.
  if (in.version_information.has_value()) {
    max_transport_param_length +=
        sizeof(in.version_information.value().chosen_version) +
        // Add one for the added GREASE version.
        (in.version_information.value().other_versions.size() + 1) *
            sizeof(QuicVersionLabel);
  }
  // google_handshake_message.
  if (in.google_handshake_message.has_value()) {
    max_transport_param_length += in.google_handshake_message.value().length();
  }

  // Add a random GREASE transport parameter, as defined in the
  // "Reserved Transport Parameters" section of RFC 9000.
  // This forces receivers to support unexpected input.
  QuicRandom* random = QuicRandom::GetInstance();
  // Transport parameter identifiers are 62 bits long so we need to
  // ensure that the output of the computation below fits in 62 bits.
  uint64_t grease_id64 = random->RandUint64() % ((1ULL << 62) - 31);
  // Make sure grease_id % 31 == 27. Note that this is not uniformely
  // distributed but is acceptable since no security depends on this
  // randomness.
  grease_id64 = (grease_id64 / 31) * 31 + 27;
  TransportParameters::TransportParameterId grease_id =
      static_cast<TransportParameters::TransportParameterId>(grease_id64);
  const size_t grease_length = random->RandUint64() % kMaxGreaseLength;
  QUICHE_DCHECK_GE(kMaxGreaseLength, grease_length);
  char grease_contents[kMaxGreaseLength];
  random->RandBytes(grease_contents, grease_length);
  custom_parameters[grease_id] = std::string(grease_contents, grease_length);

  // Custom parameters.
  for (const auto& kv : custom_parameters) {
    max_transport_param_length += kTypeAndValueLength + kv.second.length();
    parameter_ids.push_back(kv.first);
  }

  // Randomize order of sent transport parameters by walking the array
  // backwards and swapping each element with a random earlier one.
  for (size_t i = parameter_ids.size() - 1; i > 0; i--) {
    std::swap(parameter_ids[i],
              parameter_ids[random->InsecureRandUint64() % (i + 1)]);
  }

  out->resize(max_transport_param_length);
  QuicDataWriter writer(out->size(), reinterpret_cast<char*>(out->data()));

  for (TransportParameters::TransportParameterId parameter_id : parameter_ids) {
    switch (parameter_id) {
      // original_destination_connection_id
      case TransportParameters::kOriginalDestinationConnectionId: {
        if (in.original_destination_connection_id.has_value()) {
          QUICHE_DCHECK_EQ(Perspective::IS_SERVER, in.perspective);
          QuicConnectionId original_destination_connection_id =
              in.original_destination_connection_id.value();
          if (!writer.WriteVarInt62(
                  TransportParameters::kOriginalDestinationConnectionId) ||
              !writer.WriteStringPieceVarInt62(absl::string_view(
                  original_destination_connection_id.data(),
                  original_destination_connection_id.length()))) {
            QUIC_BUG(Failed to write original_destination_connection_id)
                << "Failed to write original_destination_connection_id "
                << original_destination_connection_id << " for " << in;
            return false;
          }
        }
      } break;
      // max_idle_timeout
      case TransportParameters::kMaxIdleTimeout: {
        if (!in.max_idle_timeout_ms.Write(&writer)) {
          QUIC_BUG(Failed to write idle_timeout)
              << "Failed to write idle_timeout for " << in;
          return false;
        }
      } break;
      // stateless_reset_token
      case TransportParameters::kStatelessResetToken: {
        if (!in.stateless_reset_token.empty()) {
          QUICHE_DCHECK_EQ(kStatelessResetTokenLength,
                           in.stateless_reset_token.size());
          QUICHE_DCHECK_EQ(Perspective::IS_SERVER, in.perspective);
          if (!writer.WriteVarInt62(
                  TransportParameters::kStatelessResetToken) ||
              !writer.WriteStringPieceVarInt62(
                  absl::string_view(reinterpret_cast<const char*>(
                                        in.stateless_reset_token.data()),
                                    in.stateless_reset_token.size()))) {
            QUIC_BUG(Failed to write stateless_reset_token)
                << "Failed to write stateless_reset_token of length "
                << in.stateless_reset_token.size() << " for " << in;
            return false;
          }
        }
      } break;
      // max_udp_payload_size
      case TransportParameters::kMaxPacketSize: {
        if (!in.max_udp_payload_size.Write(&writer)) {
          QUIC_BUG(Failed to write max_udp_payload_size)
              << "Failed to write max_udp_payload_size for " << in;
          return false;
        }
      } break;
      // initial_max_data
      case TransportParameters::kInitialMaxData: {
        if (!in.initial_max_data.Write(&writer)) {
          QUIC_BUG(Failed to write initial_max_data)
              << "Failed to write initial_max_data for " << in;
          return false;
        }
      } break;
      // initial_max_stream_data_bidi_local
      case TransportParameters::kInitialMaxStreamDataBidiLocal: {
        if (!in.initial_max_stream_data_bidi_local.Write(&writer)) {
          QUIC_BUG(Failed to write initial_max_stream_data_bidi_local)
              << "Failed to write initial_max_stream_data_bidi_local for "
              << in;
          return false;
        }
      } break;
      // initial_max_stream_data_bidi_remote
      case TransportParameters::kInitialMaxStreamDataBidiRemote: {
        if (!in.initial_max_stream_data_bidi_remote.Write(&writer)) {
          QUIC_BUG(Failed to write initial_max_stream_data_bidi_remote)
              << "Failed to write initial_max_stream_data_bidi_remote for "
              << in;
          return false;
        }
      } break;
      // initial_max_stream_data_uni
      case TransportParameters::kInitialMaxStreamDataUni: {
        if (!in.initial_max_stream_data_uni.Write(&writer)) {
          QUIC_BUG(Failed to write initial_max_stream_data_uni)
              << "Failed to write initial_max_stream_data_uni for " << in;
          return false;
        }
      } break;
      // initial_max_streams_bidi
      case TransportParameters::kInitialMaxStreamsBidi: {
        if (!in.initial_max_streams_bidi.Write(&writer)) {
          QUIC_BUG(Failed to write initial_max_streams_bidi)
              << "Failed to write initial_max_streams_bidi for " << in;
          return false;
        }
      } break;
      // initial_max_streams_uni
      case TransportParameters::kInitialMaxStreamsUni: {
        if (!in.initial_max_streams_uni.Write(&writer)) {
          QUIC_BUG(Failed to write initial_max_streams_uni)
              << "Failed to write initial_max_streams_uni for " << in;
          return false;
        }
      } break;
      // ack_delay_exponent
      case TransportParameters::kAckDelayExponent: {
        if (!in.ack_delay_exponent.Write(&writer)) {
          QUIC_BUG(Failed to write ack_delay_exponent)
              << "Failed to write ack_delay_exponent for " << in;
          return false;
        }
      } break;
      // max_ack_delay
      case TransportParameters::kMaxAckDelay: {
        if (!in.max_ack_delay.Write(&writer)) {
          QUIC_BUG(Failed to write max_ack_delay)
              << "Failed to write max_ack_delay for " << in;
          return false;
        }
      } break;
      // min_ack_delay_us
      case TransportParameters::kMinAckDelay: {
        if (!in.min_ack_delay_us.Write(&writer)) {
          QUIC_BUG(Failed to write min_ack_delay_us)
              << "Failed to write min_ack_delay_us for " << in;
          return false;
        }
      } break;
      // active_connection_id_limit
      case TransportParameters::kActiveConnectionIdLimit: {
        if (!in.active_connection_id_limit.Write(&writer)) {
          QUIC_BUG(Failed to write active_connection_id_limit)
              << "Failed to write active_connection_id_limit for " << in;
          return false;
        }
      } break;
      // max_datagram_frame_size
      case TransportParameters::kMaxDatagramFrameSize: {
        if (!in.max_datagram_frame_size.Write(&writer)) {
          QUIC_BUG(Failed to write max_datagram_frame_size)
              << "Failed to write max_datagram_frame_size for " << in;
          return false;
        }
      } break;
      // google_handshake_message
      case TransportParameters::kGoogleHandshakeMessage: {
        if (in.google_handshake_message.has_value()) {
          if (!writer.WriteVarInt62(
                  TransportParameters::kGoogleHandshakeMessage) ||
              !writer.WriteStringPieceVarInt62(
                  in.google_handshake_message.value())) {
            QUIC_BUG(Failed to write google_handshake_message)
                << "Failed to write google_handshake_message: "
                << in.google_handshake_message.value() << " for " << in;
            return false;
          }
        }
      } break;
      // initial_round_trip_time_us
      case TransportParameters::kInitialRoundTripTime: {
        if (!in.initial_round_trip_time_us.Write(&writer)) {
          QUIC_BUG(Failed to write initial_round_trip_time_us)
              << "Failed to write initial_round_trip_time_us for " << in;
          return false;
        }
      } break;
      // disable_active_migration
      case TransportParameters::kDisableActiveMigration: {
        if (in.disable_active_migration) {
          if (!writer.WriteVarInt62(
                  TransportParameters::kDisableActiveMigration) ||
              !writer.WriteVarInt62(/* transport parameter length */ 0)) {
            QUIC_BUG(Failed to write disable_active_migration)
                << "Failed to write disable_active_migration for " << in;
            return false;
          }
        }
      } break;
      // preferred_address
      case TransportParameters::kPreferredAddress: {
        if (in.preferred_address) {
          std::string v4_address_bytes =
              in.preferred_address->ipv4_socket_address.host().ToPackedString();
          std::string v6_address_bytes =
              in.preferred_address->ipv6_socket_address.host().ToPackedString();
          if (v4_address_bytes.length() != 4 ||
              v6_address_bytes.length() != 16 ||
              in.preferred_address->stateless_reset_token.size() !=
                  kStatelessResetTokenLength) {
            QUIC_BUG(quic_bug_10743_12)
                << "Bad lengths " << *in.preferred_address;
            return false;
          }
          const uint64_t preferred_address_length =
              v4_address_bytes.length() + /* IPv4 port */ sizeof(uint16_t) +
              v6_address_bytes.length() + /* IPv6 port */ sizeof(uint16_t) +
              /* connection ID length byte */ sizeof(uint8_t) +
              in.preferred_address->connection_id.length() +
              in.preferred_address->stateless_reset_token.size();
          if (!writer.WriteVarInt62(TransportParameters::kPreferredAddress) ||
              !writer.WriteVarInt62(
                  /* transport parameter length */ preferred_address_length) ||
              !writer.WriteStringPiece(v4_address_bytes) ||
              !writer.WriteUInt16(
                  in.preferred_address->ipv4_socket_address.port()) ||
              !writer.WriteStringPiece(v6_address_bytes) ||
              !writer.WriteUInt16(
                  in.preferred_address->ipv6_socket_address.port()) ||
              !writer.WriteUInt8(
                  in.preferred_address->connection_id.length()) ||
              !writer.WriteBytes(
                  in.preferred_address->connection_id.data(),
                  in.preferred_address->connection_id.length()) ||
              !writer.WriteBytes(
                  in.preferred_address->stateless_reset_token.data(),
                  in.preferred_address->stateless_reset_token.size())) {
            QUIC_BUG(Failed to write preferred_address)
                << "Failed to write preferred_address for " << in;
            return false;
          }
        }
      } break;
      // initial_source_connection_id
      case TransportParameters::kInitialSourceConnectionId: {
        if (in.initial_source_connection_id.has_value()) {
          QuicConnectionId initial_source_connection_id =
              in.initial_source_connection_id.value();
          if (!writer.WriteVarInt62(
                  TransportParameters::kInitialSourceConnectionId) ||
              !writer.WriteStringPieceVarInt62(
                  absl::string_view(initial_source_connection_id.data(),
                                    initial_source_connection_id.length()))) {
            QUIC_BUG(Failed to write initial_source_connection_id)
                << "Failed to write initial_source_connection_id "
                << initial_source_connection_id << " for " << in;
            return false;
          }
        }
      } break;
      // retry_source_connection_id
      case TransportParameters::kRetrySourceConnectionId: {
        if (in.retry_source_connection_id.has_value()) {
          QUICHE_DCHECK_EQ(Perspective::IS_SERVER, in.perspective);
          QuicConnectionId retry_source_connection_id =
              in.retry_source_connection_id.value();
          if (!writer.WriteVarInt62(
                  TransportParameters::kRetrySourceConnectionId) ||
              !writer.WriteStringPieceVarInt62(
                  absl::string_view(retry_source_connection_id.data(),
                                    retry_source_connection_id.length()))) {
            QUIC_BUG(Failed to write retry_source_connection_id)
                << "Failed to write retry_source_connection_id "
                << retry_source_connection_id << " for " << in;
            return false;
          }
        }
      } break;
      // Google-specific connection options.
      case TransportParameters::kGoogleConnectionOptions: {
        if (in.google_connection_options.has_value()) {
          static_assert(
              sizeof(in.google_connection_options.value().front()) == 4,
              "bad size");
          uint64_t connection_options_length =
              in.google_connection_options.value().size() * 4;
          if (!writer.WriteVarInt62(
                  TransportParameters::kGoogleConnectionOptions) ||
              !writer.WriteVarInt62(
                  /* transport parameter length */ connection_options_length)) {
            QUIC_BUG(Failed to write google_connection_options)
                << "Failed to write google_connection_options of length "
                << connection_options_length << " for " << in;
            return false;
          }
          for (const QuicTag& connection_option :
               in.google_connection_options.value()) {
            if (!writer.WriteTag(connection_option)) {
              QUIC_BUG(Failed to write google_connection_option)
                  << "Failed to write google_connection_option "
                  << QuicTagToString(connection_option) << " for " << in;
              return false;
            }
          }
        }
      } break;
      // Google-specific version extension.
      case TransportParameters::kGoogleQuicVersion: {
        if (!in.legacy_version_information.has_value()) {
          break;
        }
        static_assert(sizeof(QuicVersionLabel) == sizeof(uint32_t),
                      "bad length");
        uint64_t google_version_length =
            sizeof(in.legacy_version_information.value().version);
        if (in.perspective == Perspective::IS_SERVER) {
          google_version_length +=
              /* versions length */ sizeof(uint8_t) +
              sizeof(QuicVersionLabel) * in.legacy_version_information.value()
                                             .supported_versions.size();
        }
        if (!writer.WriteVarInt62(TransportParameters::kGoogleQuicVersion) ||
            !writer.WriteVarInt62(
                /* transport parameter length */ google_version_length) ||
            !writer.WriteUInt32(
                in.legacy_version_information.value().version)) {
          QUIC_BUG(Failed to write Google version extension)
              << "Failed to write Google version extension for " << in;
          return false;
        }
        if (in.perspective == Perspective::IS_SERVER) {
          if (!writer.WriteUInt8(sizeof(QuicVersionLabel) *
                                 in.legacy_version_information.value()
                                     .supported_versions.size())) {
            QUIC_BUG(Failed to write versions length)
                << "Failed to write versions length for " << in;
            return false;
          }
          for (QuicVersionLabel version_label :
               in.legacy_version_information.value().supported_versions) {
            if (!writer.WriteUInt32(version_label)) {
              QUIC_BUG(Failed to write supported version)
                  << "Failed to write supported version for " << in;
              return false;
            }
          }
        }
      } break;
      // version_information.
      case TransportParameters::kVersionInformation: {
        if (!in.version_information.has_value()) {
          break;
        }
        static_assert(sizeof(QuicVersionLabel) == sizeof(uint32_t),
                      "bad length");
        QuicVersionLabelVector other_versions =
            in.version_information.value().other_versions;
        // Insert one GREASE version at a random index.
        const size_t grease_index =
            random->InsecureRandUint64() % (other_versions.size() + 1);
        other_versions.insert(
            other_versions.begin() + grease_index,
            CreateQuicVersionLabel(QuicVersionReservedForNegotiation()));
        const uint64_t version_information_length =
            sizeof(in.version_information.value().chosen_version) +
            sizeof(QuicVersionLabel) * other_versions.size();
        if (!writer.WriteVarInt62(TransportParameters::kVersionInformation) ||
            !writer.WriteVarInt62(
                /* transport parameter length */ version_information_length) ||
            !writer.WriteUInt32(
                in.version_information.value().chosen_version)) {
          QUIC_BUG(Failed to write chosen version)
              << "Failed to write chosen version for " << in;
          return false;
        }
        for (QuicVersionLabel version_label : other_versions) {
          if (!writer.WriteUInt32(version_label)) {
            QUIC_BUG(Failed to write other version)
                << "Failed to write other version for " << in;
            return false;
          }
        }
      } break;
      // Custom parameters and GREASE.
      default: {
        auto it = custom_parameters.find(parameter_id);
        if (it == custom_parameters.end()) {
          QUIC_BUG(Unknown parameter) << "Unknown parameter " << parameter_id;
          return false;
        }
        if (!writer.WriteVarInt62(parameter_id) ||
            !writer.WriteStringPieceVarInt62(it->second)) {
          QUIC_BUG(Failed to write custom parameter)
              << "Failed to write custom parameter " << parameter_id;
          return false;
        }
      } break;
    }
  }

  out->resize(writer.length());

  QUIC_DLOG(INFO) << "Serialized " << in << " as " << writer.length()
                  << " bytes";

  return true;
}

bool ParseTransportParameters(ParsedQuicVersion version,
                              Perspective perspective, const uint8_t* in,
                              size_t in_len, TransportParameters* out,
                              std::string* error_details) {
  out->perspective = perspective;
  QuicDataReader reader(reinterpret_cast<const char*>(in), in_len);

  while (!reader.IsDoneReading()) {
    uint64_t param_id64;
    if (!reader.ReadVarInt62(&param_id64)) {
      *error_details = "Failed to parse transport parameter ID";
      return false;
    }
    TransportParameters::TransportParameterId param_id =
        static_cast<TransportParameters::TransportParameterId>(param_id64);
    absl::string_view value;
    if (!reader.ReadStringPieceVarInt62(&value)) {
      *error_details =
          "Failed to read length and value of transport parameter " +
          TransportParameterIdToString(param_id);
      return false;
    }
    QuicDataReader value_reader(value);
    bool parse_success = true;
    switch (param_id) {
      case TransportParameters::kOriginalDestinationConnectionId: {
        if (out->original_destination_connection_id.has_value()) {
          *error_details =
              "Received a second original_destination_connection_id";
          return false;
        }
        const size_t connection_id_length = value_reader.BytesRemaining();
        if (!QuicUtils::IsConnectionIdLengthValidForVersion(
                connection_id_length, version.transport_version)) {
          *error_details = absl::StrCat(
              "Received original_destination_connection_id of invalid length ",
              connection_id_length);
          return false;
        }
        QuicConnectionId original_destination_connection_id;
        if (!value_reader.ReadConnectionId(&original_destination_connection_id,
                                           connection_id_length)) {
          *error_details = "Failed to read original_destination_connection_id";
          return false;
        }
        out->original_destination_connection_id =
            original_destination_connection_id;
      } break;
      case TransportParameters::kMaxIdleTimeout:
        parse_success =
            out->max_idle_timeout_ms.Read(&value_reader, error_details);
        break;
      case TransportParameters::kStatelessResetToken: {
        if (!out->stateless_reset_token.empty()) {
          *error_details = "Received a second stateless_reset_token";
          return false;
        }
        absl::string_view stateless_reset_token =
            value_reader.ReadRemainingPayload();
        if (stateless_reset_token.length() != kStatelessResetTokenLength) {
          *error_details =
              absl::StrCat("Received stateless_reset_token of invalid length ",
                           stateless_reset_token.length());
          return false;
        }
        out->stateless_reset_token.assign(
            stateless_reset_token.data(),
            stateless_reset_token.data() + stateless_reset_token.length());
      } break;
      case TransportParameters::kMaxPacketSize:
        parse_success =
            out->max_udp_payload_size.Read(&value_reader, error_details);
        break;
      case TransportParameters::kInitialMaxData:
        parse_success =
            out->initial_max_data.Read(&value_reader, error_details);
        break;
      case TransportParameters::kInitialMaxStreamDataBidiLocal:
        parse_success = out->initial_max_stream_data_bidi_local.Read(
            &value_reader, error_details);
        break;
      case TransportParameters::kInitialMaxStreamDataBidiRemote:
        parse_success = out->initial_max_stream_data_bidi_remote.Read(
            &value_reader, error_details);
        break;
      case TransportParameters::kInitialMaxStreamDataUni:
        parse_success =
            out->initial_max_stream_data_uni.Read(&value_reader, error_details);
        break;
      case TransportParameters::kInitialMaxStreamsBidi:
        parse_success =
            out->initial_max_streams_bidi.Read(&value_reader, error_details);
        break;
      case TransportParameters::kInitialMaxStreamsUni:
        parse_success =
            out->initial_max_streams_uni.Read(&value_reader, error_details);
        break;
      case TransportParameters::kAckDelayExponent:
        parse_success =
            out->ack_delay_exponent.Read(&value_reader, error_details);
        break;
      case TransportParameters::kMaxAckDelay:
        parse_success = out->max_ack_delay.Read(&value_reader, error_details);
        break;
      case TransportParameters::kDisableActiveMigration:
        if (out->disable_active_migration) {
          *error_details = "Received a second disable_active_migration";
          return false;
        }
        out->disable_active_migration = true;
        break;
      case TransportParameters::kPreferredAddress: {
        TransportParameters::PreferredAddress preferred_address;
        uint16_t ipv4_port, ipv6_port;
        in_addr ipv4_address;
        in6_addr ipv6_address;
        preferred_address.stateless_reset_token.resize(
            kStatelessResetTokenLength);
        if (!value_reader.ReadBytes(&ipv4_address, sizeof(ipv4_address)) ||
            !value_reader.ReadUInt16(&ipv4_port) ||
            !value_reader.ReadBytes(&ipv6_address, sizeof(ipv6_address)) ||
            !value_reader.ReadUInt16(&ipv6_port) ||
            !value_reader.ReadLengthPrefixedConnectionId(
                &preferred_address.connection_id) ||
            !value_reader.ReadBytes(&preferred_address.stateless_reset_token[0],
                                    kStatelessResetTokenLength)) {
          *error_details = "Failed to read preferred_address";
          return false;
        }
        preferred_address.ipv4_socket_address =
            QuicSocketAddress(QuicIpAddress(ipv4_address), ipv4_port);
        preferred_address.ipv6_socket_address =
            QuicSocketAddress(QuicIpAddress(ipv6_address), ipv6_port);
        if (!preferred_address.ipv4_socket_address.host().IsIPv4() ||
            !preferred_address.ipv6_socket_address.host().IsIPv6()) {
          *error_details = "Received preferred_address of bad families " +
                           preferred_address.ToString();
          return false;
        }
        if (!QuicUtils::IsConnectionIdValidForVersion(
                preferred_address.connection_id, version.transport_version)) {
          *error_details = "Received invalid preferred_address connection ID " +
                           preferred_address.ToString();
          return false;
        }
        out->preferred_address =
            std::make_unique<TransportParameters::PreferredAddress>(
                preferred_address);
      } break;
      case TransportParameters::kActiveConnectionIdLimit:
        parse_success =
            out->active_connection_id_limit.Read(&value_reader, error_details);
        break;
      case TransportParameters::kInitialSourceConnectionId: {
        if (out->initial_source_connection_id.has_value()) {
          *error_details = "Received a second initial_source_connection_id";
          return false;
        }
        const size_t connection_id_length = value_reader.BytesRemaining();
        if (!QuicUtils::IsConnectionIdLengthValidForVersion(
                connection_id_length, version.transport_version)) {
          *error_details = absl::StrCat(
              "Received initial_source_connection_id of invalid length ",
              connection_id_length);
          return false;
        }
        QuicConnectionId initial_source_connection_id;
        if (!value_reader.ReadConnectionId(&initial_source_connection_id,
                                           connection_id_length)) {
          *error_details = "Failed to read initial_source_connection_id";
          return false;
        }
        out->initial_source_connection_id = initial_source_connection_id;
      } break;
      case TransportParameters::kRetrySourceConnectionId: {
        if (out->retry_source_connection_id.has_value()) {
          *error_details = "Received a second retry_source_connection_id";
          return false;
        }
        const size_t connection_id_length = value_reader.BytesRemaining();
        if (!QuicUtils::IsConnectionIdLengthValidForVersion(
                connection_id_length, version.transport_version)) {
          *error_details = absl::StrCat(
              "Received retry_source_connection_id of invalid length ",
              connection_id_length);
          return false;
        }
        QuicConnectionId retry_source_connection_id;
        if (!value_reader.ReadConnectionId(&retry_source_connection_id,
                                           connection_id_length)) {
          *error_details = "Failed to read retry_source_connection_id";
          return false;
        }
        out->retry_source_connection_id = retry_source_connection_id;
      } break;
      case TransportParameters::kMaxDatagramFrameSize:
        parse_success =
            out->max_datagram_frame_size.Read(&value_reader, error_details);
        break;
      case TransportParameters::kGoogleHandshakeMessage:
        if (out->google_handshake_message.has_value()) {
          *error_details = "Received a second google_handshake_message";
          return false;
        }
        out->google_handshake_message =
            std::string(value_reader.ReadRemainingPayload());
        break;
      case TransportParameters::kInitialRoundTripTime:
        parse_success =
            out->initial_round_trip_time_us.Read(&value_reader, error_details);
        break;
      case TransportParameters::kGoogleConnectionOptions: {
        if (out->google_connection_options.has_value()) {
          *error_details = "Received a second google_connection_options";
          return false;
        }
        out->google_connection_options = QuicTagVector{};
        while (!value_reader.IsDoneReading()) {
          QuicTag connection_option;
          if (!value_reader.ReadTag(&connection_option)) {
            *error_details = "Failed to read a google_connection_options";
            return false;
          }
          out->google_connection_options.value().push_back(connection_option);
        }
      } break;
      case TransportParameters::kGoogleQuicVersion: {
        if (!out->legacy_version_information.has_value()) {
          out->legacy_version_information =
              TransportParameters::LegacyVersionInformation();
        }
        if (!value_reader.ReadUInt32(
                &out->legacy_version_information.value().version)) {
          *error_details = "Failed to read Google version extension version";
          return false;
        }
        if (perspective == Perspective::IS_SERVER) {
          uint8_t versions_length;
          if (!value_reader.ReadUInt8(&versions_length)) {
            *error_details = "Failed to parse Google supported versions length";
            return false;
          }
          const uint8_t num_versions = versions_length / sizeof(uint32_t);
          for (uint8_t i = 0; i < num_versions; ++i) {
            QuicVersionLabel version;
            if (!value_reader.ReadUInt32(&version)) {
              *error_details = "Failed to parse Google supported version";
              return false;
            }
            out->legacy_version_information.value()
                .supported_versions.push_back(version);
          }
        }
      } break;
      case TransportParameters::kVersionInformation: {
        if (out->version_information.has_value()) {
          *error_details = "Received a second version_information";
          return false;
        }
        out->version_information = TransportParameters::VersionInformation();
        if (!value_reader.ReadUInt32(
                &out->version_information.value().chosen_version)) {
          *error_details = "Failed to read chosen version";
          return false;
        }
        while (!value_reader.IsDoneReading()) {
          QuicVersionLabel other_version;
          if (!value_reader.ReadUInt32(&other_version)) {
            *error_details = "Failed to parse other version";
            return false;
          }
          out->version_information.value().other_versions.push_back(
              other_version);
        }
      } break;
      case TransportParameters::kMinAckDelay:
        parse_success =
            out->min_ack_delay_us.Read(&value_reader, error_details);
        break;
      default:
        if (out->custom_parameters.find(param_id) !=
            out->custom_parameters.end()) {
          *error_details = "Received a second unknown parameter" +
                           TransportParameterIdToString(param_id);
          return false;
        }
        out->custom_parameters[param_id] =
            std::string(value_reader.ReadRemainingPayload());
        break;
    }
    if (!parse_success) {
      QUICHE_DCHECK(!error_details->empty());
      return false;
    }
    if (!value_reader.IsDoneReading()) {
      *error_details = absl::StrCat(
          "Received unexpected ", value_reader.BytesRemaining(),
          " bytes after parsing ", TransportParameterIdToString(param_id));
      return false;
    }
  }

  if (!out->AreValid(error_details)) {
    QUICHE_DCHECK(!error_details->empty());
    return false;
  }

  QUIC_DLOG(INFO) << "Parsed transport parameters " << *out << " from "
                  << in_len << " bytes";

  return true;
}

namespace {

bool DigestUpdateIntegerParam(
    EVP_MD_CTX* hash_ctx, const TransportParameters::IntegerParameter& param) {
  uint64_t value = param.value();
  return EVP_DigestUpdate(hash_ctx, &value, sizeof(value));
}

}  // namespace

bool SerializeTransportParametersForTicket(
    const TransportParameters& in, const std::vector<uint8_t>& application_data,
    std::vector<uint8_t>* out) {
  std::string error_details;
  if (!in.AreValid(&error_details)) {
    QUIC_BUG(quic_bug_10743_26)
        << "Not serializing invalid transport parameters: " << error_details;
    return false;
  }

  out->resize(SHA256_DIGEST_LENGTH + 1);
  const uint8_t serialization_version = 0;
  (*out)[0] = serialization_version;

  bssl::ScopedEVP_MD_CTX hash_ctx;
  // Write application data:
  uint64_t app_data_len = application_data.size();
  const uint64_t parameter_version = 0;
  // The format of the input to the hash function is as follows:
  // - The application data, prefixed with a 64-bit length field.
  // - Transport parameters:
  //   - A 64-bit version field indicating which version of encoding is used
  //     for transport parameters.
  //   - A list of 64-bit integers representing the relevant parameters.
  //
  //   When changing which parameters are included, additional parameters can be
  //   added to the end of the list without changing the version field. New
  //   parameters that are variable length must be length prefixed. If
  //   parameters are removed from the list, the version field must be
  //   incremented.
  //
  // Integers happen to be written in host byte order, not network byte order.
  if (!EVP_DigestInit(hash_ctx.get(), EVP_sha256()) ||
      !EVP_DigestUpdate(hash_ctx.get(), &app_data_len, sizeof(app_data_len)) ||
      !EVP_DigestUpdate(hash_ctx.get(), application_data.data(),
                        application_data.size()) ||
      !EVP_DigestUpdate(hash_ctx.get(), &parameter_version,
                        sizeof(parameter_version))) {
    QUIC_BUG(quic_bug_10743_27)
        << "Unexpected failure of EVP_Digest functions when hashing "
           "Transport Parameters for ticket";
    return false;
  }

  // Write transport parameters specified by draft-ietf-quic-transport-28,
  // section 7.4.1, that are remembered for 0-RTT.
  if (!DigestUpdateIntegerParam(hash_ctx.get(), in.initial_max_data) ||
      !DigestUpdateIntegerParam(hash_ctx.get(),
                                in.initial_max_stream_data_bidi_local) ||
      !DigestUpdateIntegerParam(hash_ctx.get(),
                                in.initial_max_stream_data_bidi_remote) ||
      !DigestUpdateIntegerParam(hash_ctx.get(),
                                in.initial_max_stream_data_uni) ||
      !DigestUpdateIntegerParam(hash_ctx.get(), in.initial_max_streams_bidi) ||
      !DigestUpdateIntegerParam(hash_ctx.get(), in.initial_max_streams_uni) ||
      !DigestUpdateIntegerParam(hash_ctx.get(),
                                in.active_connection_id_limit)) {
    QUIC_BUG(quic_bug_10743_28)
        << "Unexpected failure of EVP_Digest functions when hashing "
           "Transport Parameters for ticket";
    return false;
  }
  uint8_t disable_active_migration = in.disable_active_migration ? 1 : 0;
  if (!EVP_DigestUpdate(hash_ctx.get(), &disable_active_migration,
                        sizeof(disable_active_migration)) ||
      !EVP_DigestFinal(hash_ctx.get(), out->data() + 1, nullptr)) {
    QUIC_BUG(quic_bug_10743_29)
        << "Unexpected failure of EVP_Digest functions when hashing "
           "Transport Parameters for ticket";
    return false;
  }
  return true;
}

void DegreaseTransportParameters(TransportParameters& parameters) {
  // Strip GREASE from custom parameters.
  for (auto it = parameters.custom_parameters.begin();
       it != parameters.custom_parameters.end();
       /**/) {
    // See the "Reserved Transport Parameters" section of RFC 9000.
    if (it->first % 31 == 27) {
      parameters.custom_parameters.erase(it++);
    } else {
      ++it;
    }
  }

  // Strip GREASE from versions.
  if (parameters.version_information.has_value()) {
    QuicVersionLabelVector clean_versions;
    for (QuicVersionLabel version :
         parameters.version_information->other_versions) {
      // See the "Versions" section of RFC 9000.
      if ((version & kReservedVersionMask) != kReservedVersionBits) {
        clean_versions.push_back(version);
      }
    }

    parameters.version_information->other_versions = std::move(clean_versions);
  }
}

}  // namespace quic


text:
package speedy.model.database;

import speedy.SpeedyConstants;

public class NullValue implements IValue {

    private Object value;

    public NullValue(Object value) {
        this.value = value;
    }

    public String getType() {
        return SpeedyConstants.NULL;
    }

    public Object getPrimitiveValue() {
        return this.value;
    }

    public boolean isLabeledNull() {
        return !value.toString().equals(SpeedyConstants.NULL_VALUE);
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) return false;
        if (getClass() != obj.getClass()) return false;
        final NullValue other = (NullValue) obj;
        return this.value.toString().equals(other.value.toString());
    }

    @Override
    public int hashCode() {
        int hash = 3;
        hash = 97 * hash + (this.value != null ? this.value.hashCode() : 0);
        return hash;
    }

    @Override
    public String toString() {
        return value.toString();
    }
}


text:
import { ValueResolver } from '../types';
import * as Path from 'path';
import * as _ from 'lodash';
import Logger from '../utils/simple-logger';

const NAME = 'VR-REFERENCE';

const Log = new Logger('vr-reference');

/**
 * Load the module (or any sub property) specified by the "path" within the pattern "ref=path".
 * E.g: "ref=/path/to/module" -> loads the module pointed by the path.
 *
 * You could access the module sub-properties separating the path and the property name by the character "#"
 * E.g: "ref=/path/to/module#propName.anotherSubProp"
 */
export default class VrReference implements ValueResolver {
  readonly name: string = NAME;
  readonly pattern: RegExp = /^ref=/i;
  readonly pwd: string;

  constructor(options: RefOptions) {
    this.pwd = options.pwd;
  }

  public resolve(value: any): any {
    const content: string = value.split(this.pattern)[1];

    let moduleProp: string = content.split('#')[1];
    let modulePath: string = content.split('#')[0];
    let module: any;

    try {
      if (/^[a-zA-Z]/.test(modulePath)) {
        module = require(modulePath);
        return !!moduleProp ? _.get(module, moduleProp) : module;
      }
    } catch (err) { /* ignore this error. */ }

    try {
      module = require(Path.join(this.pwd, modulePath));
      return !!moduleProp ? _.get(module, moduleProp) : module;

    } catch (err) {
      Log.e('Faile to load the file pointed by the path "' + modulePath + '"');
      throw err;
    }

  }

  public canResolve(value: any): boolean {
    return this.pattern.test(value);
  }
}

export interface RefOptions {
  pwd: string;
}


text:
package practicework;

import core.ChromeDriverTest;
import org.junit.Before;
import org.junit.Test;
import practicework.pages.ReserveConfirmPage;
import practicework.pages.ReserveInputPage;

import java.io.File;
import java.util.concurrent.TimeUnit;

import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertThat;

public class PracticeWork3Test extends ChromeDriverTest {
    @Before
    public void setUp() {
        super.setUp();
        // ページ遷移の際に少し待機するため
        driver.manage().timeouts().implicitlyWait(500, TimeUnit.MILLISECONDS);
    }

    @Test
    public void testReserveWith1Member() {
        File html = new File("reserveApp/index.html");
        String url = html.toURI().toString();
        driver.get(url);

        ReserveInputPage inputPage = new ReserveInputPage(driver);
        inputPage.setReserveDate("2013", "12", "8"); // TODO 明日以降直近の日曜日に変更
        inputPage.setReserveTerm("3");
        inputPage.setHeadCount("1");
        inputPage.setBreakfast(false);
        inputPage.setPlanA(false);
        inputPage.setPlanB(false);
        inputPage.setGuestName("abcd");
        ReserveConfirmPage confirmPage = inputPage.goToNext();

        // 2ページ目入力画面
        assertThat(confirmPage.getPrice(), is("22750"));
        assertThat(confirmPage.getDateFrom(), is("2013年12月8日")); // TODO 変更
        assertThat(confirmPage.getDateTo(), is("2013年12月11日")); // TODO 変更
        assertThat(confirmPage.getDaysCount(), is("3"));
        assertThat(confirmPage.getHeadCount(), is("1"));
        assertThat(confirmPage.getBreakfast(), is("なし"));
        assertThat(confirmPage.existsPlanA(), is(false));
        assertThat(confirmPage.existsPlanB(), is(false));
        assertThat(confirmPage.getGuestName(), is("abcd"));
        confirmPage.commit();
    }
}


text:
/**
 * Phone.com API
 * This is a Phone.com api Swagger definition
 *
 * OpenAPI spec version: 1.0.0
 * Contact: apisupport@phone.com
 *
 * NOTE: This class is auto generated by the swagger code generator program.
 * https://github.com/swagger-api/swagger-codegen.git
 * Do not edit the class manually.
 */

package io.swagger.client.api;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;

import java.util.ArrayList;
import java.util.List;

import org.junit.Before;
import org.junit.Test;

import io.swagger.client.ApiException;
import io.swagger.client.helper.TestConfig;
import io.swagger.client.model.AccountFull;
import io.swagger.client.model.ContactAccount;
import io.swagger.client.model.FilterIdArray;
import io.swagger.client.model.ListAccounts;
import io.swagger.client.model.SortId;

/**
 * API tests for AccountsApi
 */
public class AccountsApiTest {

    private final AccountsApi api = new AccountsApi();

    @Before
    public void initTest() {
    	TestConfig.setAuthorization();
    }

    /**
     * Retrieve details of an individual account
     *
     * This service shows the details of an individual account. See Accounts for more info on the properties.
     *
     * @throws ApiException
     *          if the Api call fails
     */
    @Test
    public void getAccountTest() throws ApiException {

    	Integer accountId = 1315091;

    	AccountFull response = api.getAccount(accountId);

    	assertNotNull(response);

    	ContactAccount billingContact = response.getBillingContact();
    	assertNotNull(billingContact);
    	ContactAccount contact = response.getContact();
    	assertNotNull(contact);
    	Integer id = response.getId();
    	assertNotNull(id);
//    	AccountSummary masterAccount = response.getMasterAccount();
//    	assertNotNull(masterAccount);
    	String name = response.getName();
    	assertNotNull(name);
    	String password = response.getPassword();
    	assertNotNull(password);
    	String username = response.getUsername();
    	assertNotNull(username);

    }

    /**
     * Get a list of accounts visible to the authenticated user or client
     *
     * This service lists the accounts accessible to the authenticated client. In most cases, there will only be one such account. See Accounts for more info on the properties.
     *
     * @throws ApiException
     *          if the Api call fails
     */
    @Test
    public void listAccountsTest() throws ApiException {

        List<String> filtersId = new ArrayList<>();
        filtersId.add("lt:100000");
        String lastFilterId = "gt:1";
        filtersId.add(lastFilterId);

        String sortId = "asc";
        Integer limit = 4;
        Integer offset = 1;
        String fields = null;

         ListAccounts response = api.listAccounts(filtersId, sortId, limit, offset, fields);
         assertNotNull(response);
         List<AccountFull> items = response.getItems();
         assertNotNull(items);

         FilterIdArray filters = response.getFilters();
         assertNotNull(filters);
         assertEquals(lastFilterId, filters.getId());

         Integer limitActual = response.getLimit();
         assertNotNull(limitActual);
         assertEquals(limit, limitActual);

         Integer offsetActual = response.getOffset();
         assertNotNull(offsetActual);
         assertEquals(offset, offsetActual);

         SortId sort = response.getSort();
         assertNotNull(sort);
         assertEquals(sortId, sort.getId());
    }

}


text:
"""
fasta io - utility functions to read and write fasta files for epride
   easy primer design for multiple sequence alignments

@author: manutamminen
"""

import os
import random
import string
import types
from itertools import groupby

def generate_id(size=6):
    """
    Generate random sequences of characters for temporary file names.
    """
    chars = string.ascii_uppercase + string.digits
    return ''.join(random.choice(chars) for _ in range(size))

def read_fasta(fasta, remove_commas=False):
    """
    Read a fasta file and yield pairs of fasta ids and DNA sequences.
    """
    with open(fasta) as f:
        grouped = groupby(f, lambda x: x[0] == ">")
        for cond, entry in grouped:
            if cond:
                fasta_id = next(entry)
                if remove_commas:
                    fasta_id = fasta_id.replace(",", "")
                _, seq_iter = next(grouped)
                seq = ''.join([line.strip() for line in seq_iter]).upper()
                yield ([fasta_id, seq])

def read_fastq(fastq):
    """
    Read a fastq file and yield chunks of four lines, corresponding to each entry
    :param fastq: str; fastq file name
    :return: list; a list of id, sequence, other id and quality score
    """
    with open(fastq) as f:
        for line in f:
            id_line = line
            seq_line = next(f)
            other_id_line = next(f)
            quality_score = next(f)
            yield ([id_line, seq_line, other_id_line, quality_score])

def write_fasta(fasta_iter, output_file, size_limit=100000):
    """
    Write fasta iterables (such as those created by create_fasta_iter) into fasta files.
    """
    with open(output_file, "w") as f:
        for fasta_id, seq in fasta_iter:
            if fasta_id[0] != ">":
                fasta_id = ">" + fasta_id
            if "\n" not in fasta_id:
                fasta_id += "\n"
            if len(seq) < size_limit:
                output = "{}{}\n".format(fasta_id, seq)
                f.write(output)

def write_fastq(fastq_iter, output_file):
    """
    Write a fastq file and yield chunks of four lines,
    corresponding to each entry
    :param fastq_iter: nested list; fastq iterable
    :param output_file: string; name of the output file
    """
    with open(output_file, "w") as f:
        for id_line, seq_line, other_id_line, quality_score in fastq_iter:
            id_line = id_line.strip()
            seq_line = seq_line.strip()
            other_id_line = other_id_line.strip()
            quality_score = quality_score.strip()
            output = "{}\n{}\n{}\n{}\n".format(id_line, seq_line,
                                               other_id_line, quality_score)
            f.write(output)

class SavedFasta:
    """
    A context manager for creating a temporary fasta file of a
    fasta iterable.
    """

    def __init__(self, seq, size_limit=100000):
        self.seq = seq
        self.seq_name = generate_id()
        self.size_limit = size_limit

    def __enter__(self):
        if isinstance(self.seq, types.GeneratorType) or isinstance(
                self.seq, list):
            write_fasta(self.seq, self.seq_name, size_limit=self.size_limit)
        elif isinstance(self.seq, str):
            fasta_iter = read_fasta(self.seq)
            write_fasta(fasta_iter, self.seq_name, size_limit=100000)
        return self.seq_name

    def __exit__(self, exc_type, exc_value, traceback):
        os.remove(self.seq_name)


text: .titbg{background: none repeat scroll 0 0 #EEEEEE;}


text:
<?php

namespace Omega\NAOBundle\Services;

class MailInscriptionService
{
    public function getMailInscriptionService($bodyEmail, $mail)
    {
        $transport = \Swift_SmtpTransport::newInstance('smtp.gmail.com', 465, 'ssl')
            ->setUsername('geteolastpiece')
            ->setPassword('bmpmpnxqojewxlxc');
        //création d'un objet mailer
        $mailer = \Swift_Mailer::newInstance($transport);
        $message = \Swift_Message::newInstance();
        $message->setSubject("Votre compte a bien été enregistré");
        $message->setFrom('geteolastpiece@gmail.com');
        $message->setTo($mail);
        // pour envoyer le message en HTML
        $message->setBody($bodyEmail,'text/html');
        //envoi du message
        $mailer->send($message);
    }

}


text:
package model;

public class Variable extends Expression {
	private double value;
	private char name;

	public Variable(char term) {
		this.name = term;
		this.value = 0;
		this.varList.add(this);
	}

	public Variable(char term, double value) {
		this.name = term;
		this.value = value;
		this.varList.add(this);
	}

	public char getName() {
		return this.name;
	}

	public void setValue(double value) {
		this.value = value;
	}

	@Override
	public double calc() {
		return value;
	}

	@Override
	public String stringify() {
		return Character.toString(this.name);
	}

	@Override
	public Expression derivative(Variable var) throws Exception {
		if(var == this) return new Constant(1);
		return new Constant(0);
	}

	@Override
	public Expression integrate(Variable var) throws Exception {
		return new Divide(new Power(this, 2.0), new Constant(2.0));
	}

}


text:
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Threading.Tasks;
using Disqus.NET.Models;
using Disqus.NET.Requests;

namespace Disqus.NET
{
    public class DisqusApplicationsApi : DisqusApiBase, IDisqusApplicationsApi
    {
        public DisqusApplicationsApi(IDisqusRequestProcessor requestProcessor, DisqusAuthMethod authMethod, string key) : base(requestProcessor, authMethod, key)
        {
        }

        public async Task<DisqusResponse<IEnumerable<DisqusApplicationUsage>>> ListUsageAsync(DisqusAccessToken accessToken, DisqusApplicationListUsageRequest request)
        {
            Collection<KeyValuePair<string, string>> parameters = Parameters
                .WithMultipleParameters(request.Parameters)
                .WithOptionalParameter("access_token", accessToken);

            var response = await RequestProcessor
                .ExecuteAsync<DisqusResponse<IEnumerable<string[]>>>(DisqusRequestMethod.Get, DisqusEndpoints.Applications.ListUsage, parameters)
                .ConfigureAwait(false);

            List<DisqusApplicationUsage> usages = new List<DisqusApplicationUsage>();

            foreach (var item in response.Response)
            {
                DisqusApplicationUsage usage = new DisqusApplicationUsage
                {
                    Date = DateTime.Parse(item[0]),
                    Usage = int.Parse(item[1])
                };

                usages.Add(usage);
            }

            return new DisqusResponse<IEnumerable<DisqusApplicationUsage>>
            {
                Code = response.Code,
                Response = usages
            };
        }
    }
}