text:
using base::Time;

namespace net {

namespace {

bool KeyExchangeGroupIsValid(int ssl_connection_status) {
  // TLS 1.3 and later always treat the field correctly.
  if (SSLConnectionStatusToVersion(ssl_connection_status) >=
      SSL_CONNECTION_VERSION_TLS1_3) {
    return true;
  }

  // Prior to TLS 1.3, only ECDHE ciphers have groups.
  const SSL_CIPHER* cipher = SSL_get_cipher_by_value(
      SSLConnectionStatusToCipherSuite(ssl_connection_status));
  return cipher && SSL_CIPHER_get_kx_nid(cipher) == NID_kx_ecdhe;
}

}  // namespace

// These values can be bit-wise combined to form the flags field of the
// serialized HttpResponseInfo.
enum {
  // The version of the response info used when persisting response info.
  RESPONSE_INFO_VERSION = 3,

  // The minimum version supported for deserializing response info.
  RESPONSE_INFO_MINIMUM_VERSION = 3,

  // We reserve up to 8 bits for the version number.
  RESPONSE_INFO_VERSION_MASK = 0xFF,

  // This bit is set if the response info has a cert at the end.
  // Version 1 serialized only the end-entity certificate, while subsequent
  // versions include the available certificate chain.
  RESPONSE_INFO_HAS_CERT = 1 << 8,

  // This bit was historically set if the response info had a security-bits
  // field (security strength, in bits, of the SSL connection) at the end.
  RESPONSE_INFO_HAS_SECURITY_BITS = 1 << 9,

  // This bit is set if the response info has a cert status at the end.
  RESPONSE_INFO_HAS_CERT_STATUS = 1 << 10,

  // This bit is set if the response info has vary header data.
  RESPONSE_INFO_HAS_VARY_DATA = 1 << 11,

  // This bit is set if the request was cancelled before completion.
  RESPONSE_INFO_TRUNCATED = 1 << 12,

  // This bit is set if the response was received via SPDY.
  RESPONSE_INFO_WAS_SPDY = 1 << 13,

  // This bit is set if the request has ALPN negotiated.
  RESPONSE_INFO_WAS_ALPN = 1 << 14,

  // This bit is set if the request was fetched via an explicit proxy.
  RESPONSE_INFO_WAS_PROXY = 1 << 15,

  // This bit is set if the response info has an SSL connection status field.
  // This contains the ciphersuite used to fetch the resource as well as the
  // protocol version, compression method and whether SSLv3 fallback was used.
  RESPONSE_INFO_HAS_SSL_CONNECTION_STATUS = 1 << 16,

  // This bit is set if the response info has protocol version.
  RESPONSE_INFO_HAS_ALPN_NEGOTIATED_PROTOCOL = 1 << 17,

  // This bit is set if the response info has connection info.
  RESPONSE_INFO_HAS_CONNECTION_INFO = 1 << 18,

  // This bit is set if the request has http authentication.
  RESPONSE_INFO_USE_HTTP_AUTHENTICATION = 1 << 19,

  // This bit is set if ssl_info has SCTs.
  RESPONSE_INFO_HAS_SIGNED_CERTIFICATE_TIMESTAMPS = 1 << 20,

  RESPONSE_INFO_UNUSED_SINCE_PREFETCH = 1 << 21,

  // This bit is set if the response has a key exchange group.
  RESPONSE_INFO_HAS_KEY_EXCHANGE_GROUP = 1 << 22,

  // This bit is set if ssl_info recorded that PKP was bypassed due to a local
  // trust anchor.
  RESPONSE_INFO_PKP_BYPASSED = 1 << 23,

  // This bit is set if stale_revalidate_time is stored.
  RESPONSE_INFO_HAS_STALENESS = 1 << 24,

  // This bit is set if the response has a peer signature algorithm.
  RESPONSE_INFO_HAS_PEER_SIGNATURE_ALGORITHM = 1 << 25,

  // This bit is set if the response is a prefetch whose reuse should be
  // restricted in some way.
  RESPONSE_INFO_RESTRICTED_PREFETCH = 1 << 26,

  // This bit is set if the response has a nonempty `dns_aliases` entry.
  RESPONSE_INFO_HAS_DNS_ALIASES = 1 << 27,

  // TODO(darin): Add other bits to indicate alternate request methods.
  // For now, we don't support storing those.
};

HttpResponseInfo::ConnectionInfoCoarse HttpResponseInfo::ConnectionInfoToCoarse(
    ConnectionInfo info) {
  switch (info) {
    case CONNECTION_INFO_HTTP0_9:
    case CONNECTION_INFO_HTTP1_0:
    case CONNECTION_INFO_HTTP1_1:
      return CONNECTION_INFO_COARSE_HTTP1;

    case CONNECTION_INFO_HTTP2:
    case CONNECTION_INFO_DEPRECATED_SPDY2:
    case CONNECTION_INFO_DEPRECATED_SPDY3:
    case CONNECTION_INFO_DEPRECATED_HTTP2_14:
    case CONNECTION_INFO_DEPRECATED_HTTP2_15:
      return CONNECTION_INFO_COARSE_HTTP2;

    case CONNECTION_INFO_QUIC_UNKNOWN_VERSION:
    case CONNECTION_INFO_QUIC_32:
    case CONNECTION_INFO_QUIC_33:
    case CONNECTION_INFO_QUIC_34:
    case CONNECTION_INFO_QUIC_35:
    case CONNECTION_INFO_QUIC_36:
    case CONNECTION_INFO_QUIC_37:
    case CONNECTION_INFO_QUIC_38:
    case CONNECTION_INFO_QUIC_39:
    case CONNECTION_INFO_QUIC_40:
    case CONNECTION_INFO_QUIC_41:
    case CONNECTION_INFO_QUIC_42:
    case CONNECTION_INFO_QUIC_43:
    case CONNECTION_INFO_QUIC_44:
    case CONNECTION_INFO_QUIC_45:
    case CONNECTION_INFO_QUIC_46:
    case CONNECTION_INFO_QUIC_47:
    case CONNECTION_INFO_QUIC_Q048:
    case CONNECTION_INFO_QUIC_T048:
    case CONNECTION_INFO_QUIC_Q049:
    case CONNECTION_INFO_QUIC_T049:
    case CONNECTION_INFO_QUIC_Q050:
    case CONNECTION_INFO_QUIC_T050:
    case CONNECTION_INFO_QUIC_Q099:
    case CONNECTION_INFO_QUIC_T099:
    case CONNECTION_INFO_QUIC_999:
    case CONNECTION_INFO_QUIC_DRAFT_25:
    case CONNECTION_INFO_QUIC_DRAFT_27:
    case CONNECTION_INFO_QUIC_DRAFT_28:
    case CONNECTION_INFO_QUIC_DRAFT_29:
    case CONNECTION_INFO_QUIC_T051:
    case CONNECTION_INFO_QUIC_RFC_V1:
    case CONNECTION_INFO_QUIC_2_DRAFT_1:
      return CONNECTION_INFO_COARSE_QUIC;

    case CONNECTION_INFO_UNKNOWN:
      return CONNECTION_INFO_COARSE_OTHER;

    case NUM_OF_CONNECTION_INFOS:
      NOTREACHED();
      return CONNECTION_INFO_COARSE_OTHER;
  }

  NOTREACHED();
  return CONNECTION_INFO_COARSE_OTHER;
}

HttpResponseInfo::HttpResponseInfo()
    : was_cached(false),
      cache_entry_status(CacheEntryStatus::ENTRY_UNDEFINED),
      network_accessed(false),
      was_fetched_via_spdy(false),
      was_alpn_negotiated(false),
      was_fetched_via_proxy(false),
      did_use_http_auth(false),
      unused_since_prefetch(false),
      restricted_prefetch(false),
      async_revalidation_requested(false),
      connection_info(CONNECTION_INFO_UNKNOWN) {}

HttpResponseInfo::HttpResponseInfo(const HttpResponseInfo& rhs) = default;

HttpResponseInfo::~HttpResponseInfo() = default;

HttpResponseInfo& HttpResponseInfo::operator=(const HttpResponseInfo& rhs) =
    default;

bool HttpResponseInfo::InitFromPickle(const base::Pickle& pickle,
                                      bool* response_truncated) {
  base::PickleIterator iter(pickle);

  // Read flags and verify version
  int flags;
  if (!iter.ReadInt(&flags))
    return false;
  int version = flags & RESPONSE_INFO_VERSION_MASK;
  if (version < RESPONSE_INFO_MINIMUM_VERSION ||
      version > RESPONSE_INFO_VERSION) {
    DLOG(ERROR) << "unexpected response info version: " << version;
    return false;
  }

  // Read request-time
  int64_t time_val;
  if (!iter.ReadInt64(&time_val))
    return false;
  request_time = Time::FromInternalValue(time_val);
  was_cached = true;  // Set status to show cache resurrection.

  // Read response-time
  if (!iter.ReadInt64(&time_val))
    return false;
  response_time = Time::FromInternalValue(time_val);

  // Read response-headers
  headers = new HttpResponseHeaders(&iter);
  if (headers->response_code() == -1)
    return false;

  // Read ssl-info
  if (flags & RESPONSE_INFO_HAS_CERT) {
    ssl_info.cert = X509Certificate::CreateFromPickle(&iter);
    if (!ssl_info.cert.get())
      return false;
  }
  if (flags & RESPONSE_INFO_HAS_CERT_STATUS) {
    CertStatus cert_status;
    if (!iter.ReadUInt32(&cert_status))
      return false;
    ssl_info.cert_status = cert_status;
  }
  if (flags & RESPONSE_INFO_HAS_SECURITY_BITS) {
    // The security_bits field has been removed from ssl_info. For backwards
    // compatibility, we should still read the value out of iter.
    int security_bits;
    if (!iter.ReadInt(&security_bits))
      return false;
  }

  if (flags & RESPONSE_INFO_HAS_SSL_CONNECTION_STATUS) {
    int connection_status;
    if (!iter.ReadInt(&connection_status))
      return false;

    // SSLv3 is gone, so drop cached entries that were loaded over SSLv3.
    if (SSLConnectionStatusToVersion(connection_status) ==
        SSL_CONNECTION_VERSION_SSL3) {
      return false;
    }
    ssl_info.connection_status = connection_status;
  }

  // Signed Certificate Timestamps are no longer persisted to the cache, so
  // ignore them when reading them out.
  if (flags & RESPONSE_INFO_HAS_SIGNED_CERTIFICATE_TIMESTAMPS) {
    int num_scts;
    if (!iter.ReadInt(&num_scts))
      return false;
    for (int i = 0; i < num_scts; ++i) {
      scoped_refptr<ct::SignedCertificateTimestamp> sct(
          ct::SignedCertificateTimestamp::CreateFromPickle(&iter));
      uint16_t status;
      if (!sct.get() || !iter.ReadUInt16(&status))
        return false;
    }
  }

  // Read vary-data
  if (flags & RESPONSE_INFO_HAS_VARY_DATA) {
    if (!vary_data.InitFromPickle(&iter))
      return false;
  }

  // Read socket_address.
  std::string socket_address_host;
  if (!iter.ReadString(&socket_address_host))
    return false;
  // If the host was written, we always expect the port to follow.
  uint16_t socket_address_port;
  if (!iter.ReadUInt16(&socket_address_port))
    return false;

  IPAddress ip_address;
  if (ip_address.AssignFromIPLiteral(socket_address_host)) {
    remote_endpoint = IPEndPoint(ip_address, socket_address_port);
  } else if (ParseURLHostnameToAddress(socket_address_host, &ip_address)) {
    remote_endpoint = IPEndPoint(ip_address, socket_address_port);
  }

  // Read protocol-version.
  if (flags & RESPONSE_INFO_HAS_ALPN_NEGOTIATED_PROTOCOL) {
    if (!iter.ReadString(&alpn_negotiated_protocol))
      return false;
  }

  // Read connection info.
  if (flags & RESPONSE_INFO_HAS_CONNECTION_INFO) {
    int value;
    if (!iter.ReadInt(&value))
      return false;

    if (value > static_cast<int>(CONNECTION_INFO_UNKNOWN) &&
        value < static_cast<int>(NUM_OF_CONNECTION_INFOS)) {
      connection_info = static_cast<ConnectionInfo>(value);
    }
  }

  // Read key_exchange_group
  if (flags & RESPONSE_INFO_HAS_KEY_EXCHANGE_GROUP) {
    int key_exchange_group;
    if (!iter.ReadInt(&key_exchange_group))
      return false;

    // Historically, the key_exchange_group field was key_exchange_info which
    // conflated a number of different values based on the cipher suite, so some
    // values must be discarded. See https://crbug.com/639421.
    if (KeyExchangeGroupIsValid(ssl_info.connection_status))
      ssl_info.key_exchange_group = key_exchange_group;
  }

  // Read staleness time.
  if (flags & RESPONSE_INFO_HAS_STALENESS) {
    if (!iter.ReadInt64(&time_val))
      return false;
    stale_revalidate_timeout = base::Time() + base::Microseconds(time_val);
  }

  was_fetched_via_spdy = (flags & RESPONSE_INFO_WAS_SPDY) != 0;

  was_alpn_negotiated = (flags & RESPONSE_INFO_WAS_ALPN) != 0;

  was_fetched_via_proxy = (flags & RESPONSE_INFO_WAS_PROXY) != 0;

  *response_truncated = (flags & RESPONSE_INFO_TRUNCATED) != 0;

  did_use_http_auth = (flags & RESPONSE_INFO_USE_HTTP_AUTHENTICATION) != 0;

  unused_since_prefetch = (flags & RESPONSE_INFO_UNUSED_SINCE_PREFETCH) != 0;

  restricted_prefetch = (flags & RESPONSE_INFO_RESTRICTED_PREFETCH) != 0;

  ssl_info.pkp_bypassed = (flags & RESPONSE_INFO_PKP_BYPASSED) != 0;

  // Read peer_signature_algorithm.
  if (flags & RESPONSE_INFO_HAS_PEER_SIGNATURE_ALGORITHM) {
    int peer_signature_algorithm;
    if (!iter.ReadInt(&peer_signature_algorithm) ||
        !base::IsValueInRangeForNumericType<uint16_t>(
            peer_signature_algorithm)) {
      return false;
    }
    ssl_info.peer_signature_algorithm =
        base::checked_cast<uint16_t>(peer_signature_algorithm);
  }

  // Read DNS aliases.
  if (flags & RESPONSE_INFO_HAS_DNS_ALIASES) {
    int num_aliases;
    if (!iter.ReadInt(&num_aliases))
      return false;

    std::string alias;
    for (int i = 0; i < num_aliases; i++) {
      if (!iter.ReadString(&alias))
        return false;
      dns_aliases.insert(alias);
    }
  }

  return true;
}

void HttpResponseInfo::Persist(base::Pickle* pickle,
                               bool skip_transient_headers,
                               bool response_truncated) const {
  int flags = RESPONSE_INFO_VERSION;
  if (ssl_info.is_valid()) {
    flags |= RESPONSE_INFO_HAS_CERT;
    flags |= RESPONSE_INFO_HAS_CERT_STATUS;
    if (ssl_info.key_exchange_group != 0)
      flags |= RESPONSE_INFO_HAS_KEY_EXCHANGE_GROUP;
    if (ssl_info.connection_status != 0)
      flags |= RESPONSE_INFO_HAS_SSL_CONNECTION_STATUS;
    if (ssl_info.peer_signature_algorithm != 0)
      flags |= RESPONSE_INFO_HAS_PEER_SIGNATURE_ALGORITHM;
  }
  if (vary_data.is_valid())
    flags |= RESPONSE_INFO_HAS_VARY_DATA;
  if (response_truncated)
    flags |= RESPONSE_INFO_TRUNCATED;
  if (was_fetched_via_spdy)
    flags |= RESPONSE_INFO_WAS_SPDY;
  if (was_alpn_negotiated) {
    flags |= RESPONSE_INFO_WAS_ALPN;
    flags |= RESPONSE_INFO_HAS_ALPN_NEGOTIATED_PROTOCOL;
  }
  if (was_fetched_via_proxy)
    flags |= RESPONSE_INFO_WAS_PROXY;
  if (connection_info != CONNECTION_INFO_UNKNOWN)
    flags |= RESPONSE_INFO_HAS_CONNECTION_INFO;
  if (did_use_http_auth)
    flags |= RESPONSE_INFO_USE_HTTP_AUTHENTICATION;
  if (unused_since_prefetch)
    flags |= RESPONSE_INFO_UNUSED_SINCE_PREFETCH;
  if (restricted_prefetch)
    flags |= RESPONSE_INFO_RESTRICTED_PREFETCH;
  if (ssl_info.pkp_bypassed)
    flags |= RESPONSE_INFO_PKP_BYPASSED;
  if (!stale_revalidate_timeout.is_null())
    flags |= RESPONSE_INFO_HAS_STALENESS;
  if (!dns_aliases.empty())
    flags |= RESPONSE_INFO_HAS_DNS_ALIASES;

  pickle->WriteInt(flags);
  pickle->WriteInt64(request_time.ToInternalValue());
  pickle->WriteInt64(response_time.ToInternalValue());

  HttpResponseHeaders::PersistOptions persist_options =
      HttpResponseHeaders::PERSIST_RAW;

  if (skip_transient_headers) {
    persist_options = HttpResponseHeaders::PERSIST_SANS_COOKIES |
                      HttpResponseHeaders::PERSIST_SANS_CHALLENGES |
                      HttpResponseHeaders::PERSIST_SANS_HOP_BY_HOP |
                      HttpResponseHeaders::PERSIST_SANS_NON_CACHEABLE |
                      HttpResponseHeaders::PERSIST_SANS_RANGES |
                      HttpResponseHeaders::PERSIST_SANS_SECURITY_STATE;
  }

  headers->Persist(pickle, persist_options);

  if (ssl_info.is_valid()) {
    ssl_info.cert->Persist(pickle);
    pickle->WriteUInt32(ssl_info.cert_status);
    if (ssl_info.connection_status != 0)
      pickle->WriteInt(ssl_info.connection_status);
  }

  if (vary_data.is_valid())
    vary_data.Persist(pickle);

  pickle->WriteString(remote_endpoint.ToStringWithoutPort());
  pickle->WriteUInt16(remote_endpoint.port());

  if (was_alpn_negotiated)
    pickle->WriteString(alpn_negotiated_protocol);

  if (connection_info != CONNECTION_INFO_UNKNOWN)
    pickle->WriteInt(static_cast<int>(connection_info));

  if (ssl_info.is_valid() && ssl_info.key_exchange_group != 0)
    pickle->WriteInt(ssl_info.key_exchange_group);

  if (flags & RESPONSE_INFO_HAS_STALENESS) {
    pickle->WriteInt64(
        (stale_revalidate_timeout - base::Time()).InMicroseconds());
  }

  if (ssl_info.is_valid() && ssl_info.peer_signature_algorithm != 0)
    pickle->WriteInt(ssl_info.peer_signature_algorithm);

  if (!dns_aliases.empty()) {
    pickle->WriteInt(dns_aliases.size());
    for (const auto& alias : dns_aliases)
      pickle->WriteString(alias);
  }
}

bool HttpResponseInfo::DidUseQuic() const {
  switch (connection_info) {
    case CONNECTION_INFO_UNKNOWN:
    case CONNECTION_INFO_HTTP1_1:
    case CONNECTION_INFO_DEPRECATED_SPDY2:
    case CONNECTION_INFO_DEPRECATED_SPDY3:
    case CONNECTION_INFO_HTTP2:
    case CONNECTION_INFO_DEPRECATED_HTTP2_14:
    case CONNECTION_INFO_DEPRECATED_HTTP2_15:
    case CONNECTION_INFO_HTTP0_9:
    case CONNECTION_INFO_HTTP1_0:
      return false;
    case CONNECTION_INFO_QUIC_UNKNOWN_VERSION:
    case CONNECTION_INFO_QUIC_32:
    case CONNECTION_INFO_QUIC_33:
    case CONNECTION_INFO_QUIC_34:
    case CONNECTION_INFO_QUIC_35:
    case CONNECTION_INFO_QUIC_36:
    case CONNECTION_INFO_QUIC_37:
    case CONNECTION_INFO_QUIC_38:
    case CONNECTION_INFO_QUIC_39:
    case CONNECTION_INFO_QUIC_40:
    case CONNECTION_INFO_QUIC_41:
    case CONNECTION_INFO_QUIC_42:
    case CONNECTION_INFO_QUIC_43:
    case CONNECTION_INFO_QUIC_44:
    case CONNECTION_INFO_QUIC_45:
    case CONNECTION_INFO_QUIC_46:
    case CONNECTION_INFO_QUIC_47:
    case CONNECTION_INFO_QUIC_Q048:
    case CONNECTION_INFO_QUIC_T048:
    case CONNECTION_INFO_QUIC_Q049:
    case CONNECTION_INFO_QUIC_T049:
    case CONNECTION_INFO_QUIC_Q050:
    case CONNECTION_INFO_QUIC_T050:
    case CONNECTION_INFO_QUIC_Q099:
    case CONNECTION_INFO_QUIC_T099:
    case CONNECTION_INFO_QUIC_999:
    case CONNECTION_INFO_QUIC_DRAFT_25:
    case CONNECTION_INFO_QUIC_DRAFT_27:
    case CONNECTION_INFO_QUIC_DRAFT_28:
    case CONNECTION_INFO_QUIC_DRAFT_29:
    case CONNECTION_INFO_QUIC_T051:
    case CONNECTION_INFO_QUIC_RFC_V1:
    case CONNECTION_INFO_QUIC_2_DRAFT_1:
      return true;
    case NUM_OF_CONNECTION_INFOS:
      NOTREACHED();
      return false;
  }
  NOTREACHED();
  return false;
}

// static
std::string HttpResponseInfo::ConnectionInfoToString(
    ConnectionInfo connection_info) {
  switch (connection_info) {
    case CONNECTION_INFO_UNKNOWN:
      return "unknown";
    case CONNECTION_INFO_HTTP1_1:
      return "http/1.1";
    case CONNECTION_INFO_DEPRECATED_SPDY2:
      NOTREACHED();
      return "";
    case CONNECTION_INFO_DEPRECATED_SPDY3:
      return "spdy/3";
    // Since ConnectionInfo is persisted to disk, deprecated values have to be
    // handled. Note that h2-14 and h2-15 are essentially wire compatible with
    // h2.
    // Intentional fallthrough.
    case CONNECTION_INFO_DEPRECATED_HTTP2_14:
    case CONNECTION_INFO_DEPRECATED_HTTP2_15:
    case CONNECTION_INFO_HTTP2:
      return "h2";
    case CONNECTION_INFO_QUIC_UNKNOWN_VERSION:
      return "http/2+quic";
    case CONNECTION_INFO_QUIC_32:
      return "http/2+quic/32";
    case CONNECTION_INFO_QUIC_33:
      return "http/2+quic/33";
    case CONNECTION_INFO_QUIC_34:
      return "http/2+quic/34";
    case CONNECTION_INFO_QUIC_35:
      return "http/2+quic/35";
    case CONNECTION_INFO_QUIC_36:
      return "http/2+quic/36";
    case CONNECTION_INFO_QUIC_37:
      return "http/2+quic/37";
    case CONNECTION_INFO_QUIC_38:
      return "http/2+quic/38";
    case CONNECTION_INFO_QUIC_39:
      return "http/2+quic/39";
    case CONNECTION_INFO_QUIC_40:
      return "http/2+quic/40";
    case CONNECTION_INFO_QUIC_41:
      return "http/2+quic/41";
    case CONNECTION_INFO_QUIC_42:
      return "http/2+quic/42";
    case CONNECTION_INFO_QUIC_43:
      return "http/2+quic/43";
    case CONNECTION_INFO_QUIC_44:
      return "http/2+quic/44";
    case CONNECTION_INFO_QUIC_45:
      return "http/2+quic/45";
    case CONNECTION_INFO_QUIC_46:
      return "http/2+quic/46";
    case CONNECTION_INFO_QUIC_47:
      return "http/2+quic/47";
    case CONNECTION_INFO_QUIC_Q048:
      return "h3-Q048";
    case CONNECTION_INFO_QUIC_T048:
      return "h3-T048";
    case CONNECTION_INFO_QUIC_Q049:
      return "h3-Q049";
    case CONNECTION_INFO_QUIC_T049:
      return "h3-T049";
    case CONNECTION_INFO_QUIC_Q050:
      return "h3-Q050";
    case CONNECTION_INFO_QUIC_T050:
      return "h3-T050";
    case CONNECTION_INFO_QUIC_Q099:
      return "h3-Q099";
    case CONNECTION_INFO_QUIC_DRAFT_25:
      return "h3-25";
    case CONNECTION_INFO_QUIC_DRAFT_27:
      return "h3-27";
    case CONNECTION_INFO_QUIC_DRAFT_28:
      return "h3-28";
    case CONNECTION_INFO_QUIC_DRAFT_29:
      return "h3-29";
    case CONNECTION_INFO_QUIC_T099:
      return "h3-T099";
    case CONNECTION_INFO_HTTP0_9:
      return "http/0.9";
    case CONNECTION_INFO_HTTP1_0:
      return "http/1.0";
    case CONNECTION_INFO_QUIC_999:
      return "http2+quic/999";
    case CONNECTION_INFO_QUIC_T051:
      return "h3-T051";
    case CONNECTION_INFO_QUIC_RFC_V1:
      return "h3";
    case CONNECTION_INFO_QUIC_2_DRAFT_1:
      return "h3/quic2draft01";
    case NUM_OF_CONNECTION_INFOS:
      break;
  }
  NOTREACHED();
  return "";
}

}  // namespace net


text:
var gulp = require('gulp');
var paths = require('./paths');
var plugins = require('gulp-load-plugins')();
var mainBowerFiles = require('main-bower-files');
var base = 'bower_components';

// Download bower dependencies
gulp.task('initialize:bower:install', function () {
    return plugins.bower();
});

gulp.task('initialize:tsd', function () {
    return gulp.src(paths.ts.tsd).pipe(plugins.tsd());
});

// Move bower packages to each folder
gulp.task('initialize:bower', ['initialize:bower:install'], function () {
    gulp.src(mainBowerFiles('**/*.scss'), { base: base })
        .pipe(gulp.dest(paths.scss.bower));

    gulp.src(mainBowerFiles('**/*.js'), { base: base })
        .pipe(gulp.dest(paths.js.path.bower));

    return gulp.src(mainBowerFiles('**/fonts/**.*'), { base: base })
        .pipe(gulp.dest(paths.fonts.bower));
});

redpajama_set_name: RedPajamaGithub


text:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<title>Uses of Package org.jsimpledb.kv.simple (Java Class Library API)</title>
<meta name="date" content="2015-04-16">
<link rel="stylesheet" type="text/css" href="../../../../stylesheet.css" title="Style">

JavaScript is disabled on your browser.

Skip navigation links

Overview

Package

Class

Use

Tree

Deprecated

Index

Help

Prev

Next

Frames

No Frames

All Classes

Uses of Package
org.jsimpledb.kv.simple

Packages that use org.jsimpledb.kv.simple

Package
Description

org.jsimpledb.kv.simple

A simple in-memory implementation of the KVDatabase interface.

org.jsimpledb.spring

Spring Framework integration classes.

Classes in org.jsimpledb.kv.simple used by org.jsimpledb.kv.simple

Class and Description

SimpleKVDatabase

Simple implementation of the KVDatabase interface that provides a concurrent, transactional view
 of an underlying KVStore with strong ACID semantics (Durability must be provided by the KVStore).

SimpleKVTransaction

KVTransaction implementation for SimpleKVDatabase.

XMLKVTransaction

Transaction associated with a XMLKVDatabase.

Classes in org.jsimpledb.kv.simple used by org.jsimpledb.spring

Class and Description

SimpleKVDatabase

Simple implementation of the KVDatabase interface that provides a concurrent, transactional view
 of an underlying KVStore with strong ACID semantics (Durability must be provided by the KVStore).

XMLKVDatabase

Simple persistent KVDatabase backed by an XML file stored in a StreamRepository.

Skip navigation links

Overview

Package

Class

Use

Tree

Deprecated

Index

Help

Prev

Next

Frames

No Frames

All Classes


text:
class BaseScene;

class SceneGraph
{
public:
	SceneGraph() :
		currentScene(nullptr)
	{}
	~SceneGraph();

	void Initialize();
	void Update(float dt);
	void Draw(float dt);

	void OnKeyDown(SDL_Keycode key);
	void OnKeyUp(SDL_Keycode key);

	virtual void GoToScene(int sceneId);
protected:
	BaseScene* currentScene;
};


text:
@interface TGLDevice() {
    dispatch_queue_t _texture_cache_queue;
    pthread_mutex_t _mutex;
}

@property (nonatomic, readwrite) EAGLContext *root_context;
@property (nonatomic, readwrite) EAGLContext *texture_cache_context;
@end

@implementation TGLDevice

+ (TGLDevice *)sharedInstance
{
    static TGLDevice * __instance;
    static dispatch_once_t __once_token;
    dispatch_once(&__once_token, ^{
        __instance = [[TGLDevice alloc] init];
    });
    return __instance;
}

- (id)init
{
    self = [super init];
    if (self) {
        self.root_context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2 sharegroup:nil];
        self.texture_cache_context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2 sharegroup:self.root_context.sharegroup];
        _texture_cache_queue = dispatch_queue_create("com.monadworks.tgl.texture_cache", 0);
        pthread_mutex_init(&_mutex, NULL);
        dispatch_queue_set_specific(_texture_cache_queue, &_texture_cache_queue, (__bridge void *)self, NULL);
    }
    return self;
}

- (void)runTextureCache:(void (^)())block
{
    EAGLContext *prev_context = [EAGLContext currentContext];

    if (prev_context != _texture_cache_context) {
        [EAGLContext setCurrentContext:_texture_cache_context];
    }

    block();

    [TGLDevice fenceSync];

    [TGLDevice setContext:prev_context];
}

- (void)runTextureCacheQueue:(void (^)())block
{
    TGLDevice *device = [TGLDevice sharedInstance];
    if (dispatch_get_specific(&_texture_cache_queue) == (__bridge void *)self) {
        [device runTextureCache:block];
    } else {
        dispatch_sync(_texture_cache_queue, ^{
            [device runTextureCache:block];
        });
    }
}

+ (void)runTextureCacheQueueSync:(void (^)())block
{
    TGLDevice *device = [TGLDevice sharedInstance];

    [device runTextureCacheQueue:block];
}

+ (EAGLContext *)createContext
{
    TGLDevice *device = [TGLDevice sharedInstance];

    return [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2 sharegroup:device.root_context.sharegroup];
}

+ (void)setContext:(EAGLContext *)context
{
    if ([EAGLContext currentContext] != context) {
        [EAGLContext setCurrentContext:context];
    }
}

+ (void)runPassiveContextSync:(void (^)())block
{
    EAGLContext *prev_context = [EAGLContext currentContext];

    NSASSERT(prev_context);

    block();

    [TGLDevice fenceSync];

    [TGLDevice setContext:prev_context];
}

+ (void)runMainThreadSync:(void (^)())block
{
    TGLDevice *device = [TGLDevice sharedInstance];

    if ([NSThread isMainThread]) {
        [device runMain:block];
    } else {
        dispatch_sync(dispatch_get_main_queue(), ^{
            [device runMain:block];
        });
    }
}

+ (EAGLContext *)currentContext
{
    return [EAGLContext currentContext];
}

+ (EAGLContext *)setNewContext
{
    EAGLContext *context = [TGLDevice createContext];
    [TGLDevice setContext:context];

    return context;
}

- (void)runMain:(void (^)())block
{
    EAGLContext *prev_context = [EAGLContext currentContext];

    if (prev_context != self.root_context) {
        [EAGLContext setCurrentContext:self.root_context];
    }

    block();

    [TGLDevice fenceSync];

    [TGLDevice setContext:prev_context];
}

+ (void)useFastTextureCacheRef:(void (^)(CVOpenGLESTextureCacheRef))block
{
    static CVOpenGLESTextureCacheRef __ref = NULL;
    static dispatch_once_t __once_token;

    dispatch_once(&__once_token, ^{
        TGLDevice *device = [TGLDevice sharedInstance];

        [TGLDevice runTextureCacheQueueSync:^{
#ifdef DEBUG
            CVReturn err =
#endif
                CVOpenGLESTextureCacheCreate(kCFAllocatorDefault, NULL, device.texture_cache_context, NULL, &__ref);
            NSASSERT(!err);
        }];
    });

    [TGLDevice runTextureCacheQueueSync:^{
        block(__ref);
    }];
}

+ (void)flushTextureCache
{
    [TGLDevice useFastTextureCacheRef:^(CVOpenGLESTextureCacheRef ref) {
        CVOpenGLESTextureCacheFlush(ref, 0);
    }];
}

- (void)lock
{
    pthread_mutex_lock(&_mutex);
}

- (void)unlock
{
    pthread_mutex_unlock(&_mutex);
}

+ (void)fenceSync
{
    TGLDevice *device = [TGLDevice sharedInstance];

    // NOTE:
    // This lock is conceptually unnecessary but there are witnesses without doing this
    // may cause fatal crash on multi-threaded multi-context, only in iOS6.
    [device lock];
    GLsync sync = glFenceSyncAPPLE(GL_SYNC_GPU_COMMANDS_COMPLETE_APPLE, 0);GLASSERT;
    [device unlock];

    int yield_count = 0;
    GLenum result;

    do {
        // NOTE:
        // glClientWaitSyncAPPLE sometimes spends up lots of CPU by calling mach_absolute_time()
        // while detecting timeout in its busy loop.
        // So we do not count on its blocking mechanism considering CPU effeciency in multi threads.
        result = glClientWaitSyncAPPLE(sync, GL_SYNC_FLUSH_COMMANDS_BIT_APPLE, 0);GLASSERT;

        if (result == GL_TIMEOUT_EXPIRED_APPLE) {
            if (yield_count < 1) {
                ++yield_count;
                sched_yield();
            } else {
                // call glFinish() to avoid bursting sched_yield()
                glFinish();
                break;
            }
        } else {
            break;
        }
    } while (1);

    [device lock];
    if (glIsSyncAPPLE(sync)) {
        glDeleteSyncAPPLE(sync);GLASSERT;
    } else {
        ERROR("glIsSyncAPPLE may be failed with wait-sync result: %08x", result);
    }
    [device unlock];
}

- (void)dealloc
{
    pthread_mutex_destroy(&_mutex);
}

@end


text:
package com.amazon.carbonado.stored;

import com.amazon.carbonado.*;
import com.amazon.carbonado.constraint.*;

/**
 *
 *
 * @author Brian S O'Neill (boneill)
 */
@Indexes({
    @Index("firstName"),
    @Index("lastName"),
    @Index("addressID")
})
@PrimaryKey("userID")
public abstract class UserInfo implements Storable<UserInfo> {
    public abstract int getUserID();
    public abstract void setUserID(int id);

    public abstract int getStateID();
    @IntegerConstraint(allowed={1, 2, 3})
    public abstract void setStateID(int state);

    public abstract String getFirstName();
    @LengthConstraint(min=1, max=50)
    public abstract void setFirstName(String value);

    public abstract String getLastName();
    @LengthConstraint(min=1, max=50)
    public abstract void setLastName(String value);

    public abstract int getAddressID();
    public abstract void setAddressID(int id);

    @Join
    public abstract UserAddress getAddress() throws FetchException;
    public abstract void setAddress(UserAddress address);
}


text:
Data Center Journal
===========

[Страница проекта](http://club.prog-school.ru/project/view/51) в [Клубе разработчиков](http://club.prog-school.ru/) [ШП](http://prog-school.ru/)

Open DCIM для ДатаЦентров

Для многих будет не совсем понятно, что такое DCIM ?
- загляните например сюда [http://dctrack.ru/](http://dctrack.ru/) - это один из лидеров рынка в данной области.

==

### Настройка IDE Eclipse

- Git Help

==

### Документация Git

- Git Book (оригинал)

- Git Book (на русском)

- Скачать книгу ProGit

- Статья авторов перевода на ХабраХабре

==

### Дополнительно

- Хороший практический tuturial по git

- Неплохое введение в игровой форме


text:
#ifndef CTKPLUGINGENERATORUIPLUGIN_H
#define CTKPLUGINGENERATORUIPLUGIN_H

#include <ctkPluginActivator.h>

class ctkPluginGeneratorAbstractUiExtension;

class ctkPluginGeneratorUiPlugin : public QObject,
                                   public ctkPluginActivator
{
  Q_OBJECT
  Q_INTERFACES(ctkPluginActivator)
#ifdef HAVE_QT5
  Q_PLUGIN_METADATA(IID "org_commontk_plugingenerator_ui")
#endif

public:

  void start(ctkPluginContext* context);
  void stop(ctkPluginContext* context);

private:

  ctkPluginGeneratorAbstractUiExtension* mainExtension;
};

#endif // CTKPLUGINGENERATORUIPLUGIN_H


text:
ACCEPTED

#### According to
The Catalogue of Life, 3rd January 2011

#### Published in
in Gams, O'Donnell, Schroers & Christensen, Can. J. Bot. 76(9): 1580 (1999)

#### Original name
Stanjemonium grisellum W. Gams, Schroers & M. Chr., 1999

### Remarks
null