<commit_before>/* -*- indent-tabs-mode: nil -*- */
#include <glog/logging.h>
#include <string>

#include "include/types.h"
#include "proto/ct.pb.h"
#include "proto/serializer.h"

const size_t Serializer::kMaxCertificateLength = (1 << 24) - 1;
const size_t Serializer::kMaxCertificateChainLength = (1 << 24) - 1;
const size_t Serializer::kMaxSignatureLength = (1 << 16) - 1;
const size_t Serializer::kMaxExtensionsLength = (1 << 16) - 1;
const size_t Serializer::kMaxSerializedSCTLength = (1 << 16) - 1;
const size_t Serializer::kMaxSCTListLength = (1 << 16) - 1;

const size_t Serializer::kLogEntryTypeLengthInBytes = 2;
const size_t Serializer::kSignatureTypeLengthInBytes = 1;
const size_t Serializer::kHashAlgorithmLengthInBytes = 1;
const size_t Serializer::kSigAlgorithmLengthInBytes = 1;
const size_t Serializer::kVersionLengthInBytes = 1;
const size_t Serializer::kKeyIDLengthInBytes = 32;
const size_t Serializer::kMerkleLeafTypeLengthInBytes = 1;
const size_t Serializer::kKeyHashLengthInBytes = 32;
const size_t Serializer::kTimestampLengthInBytes = 8;

using ct::LogEntry;
using ct::LogEntryType_IsValid;
using ct::DigitallySigned;
using ct::DigitallySigned_HashAlgorithm_IsValid;
using ct::DigitallySigned_SignatureAlgorithm_IsValid;
using ct::SignedCertificateTimestamp;
using ct::SignedCertificateTimestampList;
using ct::X509ChainEntry;
using ct::PrecertChainEntry;
using ct::Version_IsValid;
using std::string;

// static
size_t Serializer::PrefixLength(size_t max_length) {
  CHECK_GT(max_length, 0U);
  size_t prefix_length = 0;

  for ( ; max_length > 0; max_length >>= 8)
    ++prefix_length;

  return prefix_length;
}

// static
Serializer::SerializeResult
Serializer::CheckLogEntryFormat(const LogEntry &entry) {
  switch (entry.type()) {
    case ct::X509_ENTRY:
      return CheckX509ChainEntryFormat(entry.x509_entry());
    case ct::PRECERT_ENTRY:
      return CheckPrecertChainEntryFormat(entry.precert_entry());
    default:
      return INVALID_ENTRY_TYPE;
  }
}

// static
string Serializer::LeafCertificate(const LogEntry &entry) {
  switch (entry.type()) {
    case ct::X509_ENTRY:
      CHECK(entry.x509_entry().has_leaf_certificate())
          << "Missing leaf certificate";
      return entry.x509_entry().leaf_certificate();
    case ct::PRECERT_ENTRY:
      CHECK(entry.precert_entry().pre_cert().has_tbs_certificate())
          << "Missing tbs certificate";
      return entry.precert_entry().pre_cert().tbs_certificate();
    default:
      LOG(FATAL) << "Invalid entry type " << entry.type();
  }
}<commit_msg>Small refactoring of Serializer::PrefixLength: Rather than bean-counting each byte, do a direct calculation of bytes needed.<commit_after>/* -*- indent-tabs-mode: nil -*- */
#include <glog/logging.h>
#include <string>
#include <math.h>

#include "include/types.h"
#include "proto/ct.pb.h"
#include "proto/serializer.h"

const size_t Serializer::kMaxCertificateLength = (1 << 24) - 1;
const size_t Serializer::kMaxCertificateChainLength = (1 << 24) - 1;
const size_t Serializer::kMaxSignatureLength = (1 << 16) - 1;
const size_t Serializer::kMaxExtensionsLength = (1 << 16) - 1;
const size_t Serializer::kMaxSerializedSCTLength = (1 << 16) - 1;
const size_t Serializer::kMaxSCTListLength = (1 << 16) - 1;

const size_t Serializer::kLogEntryTypeLengthInBytes = 2;
const size_t Serializer::kSignatureTypeLengthInBytes = 1;
const size_t Serializer::kHashAlgorithmLengthInBytes = 1;
const size_t Serializer::kSigAlgorithmLengthInBytes = 1;
const size_t Serializer::kVersionLengthInBytes = 1;
const size_t Serializer::kKeyIDLengthInBytes = 32;
const size_t Serializer::kMerkleLeafTypeLengthInBytes = 1;
const size_t Serializer::kKeyHashLengthInBytes = 32;
const size_t Serializer::kTimestampLengthInBytes = 8;

using ct::LogEntry;
using ct::LogEntryType_IsValid;
using ct::DigitallySigned;
using ct::DigitallySigned_HashAlgorithm_IsValid;
using ct::DigitallySigned_SignatureAlgorithm_IsValid;
using ct::SignedCertificateTimestamp;
using ct::SignedCertificateTimestampList;
using ct::X509ChainEntry;
using ct::PrecertChainEntry;
using ct::Version_IsValid;
using std::string;

// static
// Returns the number of bytes needed to store a value up to max_length.
size_t Serializer::PrefixLength(size_t max_length) {
  CHECK_GT(max_length, 0U);
  return ceil(log2(max_length) / float(8));
}

// static
Serializer::SerializeResult
Serializer::CheckLogEntryFormat(const LogEntry &entry) {
  switch (entry.type()) {
    case ct::X509_ENTRY:
      return CheckX509ChainEntryFormat(entry.x509_entry());
    case ct::PRECERT_ENTRY:
      return CheckPrecertChainEntryFormat(entry.precert_entry());
    default:
      return INVALID_ENTRY_TYPE;
  }
}

// static
string Serializer::LeafCertificate(const LogEntry &entry) {
  switch (entry.type()) {
    case ct::X509_ENTRY:
      CHECK(entry.x509_entry().has_leaf_certificate())
          << "Missing leaf certificate";
      return entry.x509_entry().leaf_certificate();
    case ct::PRECERT_ENTRY:
      CHECK(entry.precert_entry().pre_cert().has_tbs_certificate())
          << "Missing tbs certificate";
      return entry.precert_entry().pre_cert().tbs_certificate();
    default:
      LOG(FATAL) << "Invalid entry type " << entry.type();
  }
}
{'fraction_non_alphanumeric': 0.1190521689279572, 'fraction_numerical': 0.02274030193005924, 'mean_word_length': 5.600252206809584, 'pattern_counts': {'":': 0, '<': 48, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6852394', 'n_tokens_mistral': 1815, 'n_tokens_neox': 1697, 'n_words': 364}