1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
|
// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/segmentation_platform/internal/database/signal_key_internal.h"
#include <stdint.h>
#include <ostream>
#include <sstream>
#include <string>
#include <utility>
#include "base/check.h"
#include "base/check_op.h"
#include "base/containers/span.h"
#include "base/containers/span_reader.h"
#include "base/containers/span_writer.h"
#include "base/logging.h"
namespace segmentation_platform {
namespace {
void ClearKeyPrefix(SignalKeyInternal::Prefix* prefix) {
DCHECK(prefix);
prefix->kind = 0;
prefix->name_hash = 0;
}
void ClearKey(SignalKeyInternal* key) {
DCHECK(key);
ClearKeyPrefix(&key->prefix);
key->time_range_end_sec = 0;
key->time_range_start_sec = 0;
}
} // namespace
std::string SignalKeyInternalToBinary(const SignalKeyInternal& input) {
uint8_t output_buf[sizeof(SignalKeyInternal)];
auto output = base::span(output_buf);
auto writer = base::SpanWriter(output);
writer.WriteU8BigEndian(input.prefix.kind);
writer.Write(base::as_byte_span(input.prefix.padding));
writer.WriteU64BigEndian(input.prefix.name_hash);
// SAFETY: If the value is negative we want to store the bit pattern of the
// negative value, which static_cast preserves. The reader will be required to
// convert back to a signed value.
writer.WriteU64BigEndian(static_cast<uint64_t>(input.time_range_end_sec));
// SAFETY: If the value is negative we want to store the bit pattern of the
// negative value, which static_cast preserves. The reader will be required to
// convert back to a signed value.
writer.WriteU64BigEndian(static_cast<uint64_t>(input.time_range_start_sec));
CHECK_EQ(writer.remaining(), 0u);
return std::string(output.begin(), output.end());
}
bool SignalKeyInternalFromBinary(const std::string& input,
SignalKeyInternal* output) {
if (input.size() != sizeof(SignalKeyInternal)) {
ClearKey(output);
return false;
}
auto reader = base::SpanReader(base::as_byte_span(input));
reader.ReadChar(output->prefix.kind);
reader.Skip(sizeof(SignalKeyInternal::Prefix::padding));
reader.ReadU64BigEndian(output->prefix.name_hash);
reader.ReadI64BigEndian(output->time_range_end_sec);
reader.ReadI64BigEndian(output->time_range_start_sec);
CHECK_EQ(reader.remaining(), 0u);
return true;
}
std::string SignalKeyInternalToDebugString(const SignalKeyInternal& input) {
std::stringstream buffer;
buffer << input;
return buffer.str();
}
std::string SignalKeyInternalPrefixToBinary(
const SignalKeyInternal::Prefix& input) {
uint8_t output[sizeof(SignalKeyInternal::Prefix)];
auto writer = base::SpanWriter(base::span(output));
writer.WriteU8BigEndian(input.kind);
writer.Write(base::as_byte_span(input.padding));
writer.WriteU64BigEndian(input.name_hash);
CHECK_EQ(writer.remaining(), 0u);
std::string output_str = std::string(std::begin(output), std::end(output));
return output_str;
}
bool SignalKeyInternalPrefixFromBinary(const std::string& input,
SignalKeyInternal::Prefix* output) {
if (input.size() != sizeof(SignalKeyInternal::Prefix)) {
ClearKeyPrefix(output);
return false;
}
auto reader = base::SpanReader(base::as_byte_span(input));
reader.ReadChar(output->kind);
reader.Skip(sizeof(SignalKeyInternal::Prefix::padding));
reader.ReadU64BigEndian(output->name_hash);
CHECK_EQ(reader.remaining(), 0u);
return true;
}
std::string SignalKeyInternalPrefixToDebugString(
const SignalKeyInternal::Prefix& input) {
std::stringstream buffer;
buffer << input;
return buffer.str();
}
std::ostream& operator<<(std::ostream& os,
const SignalKeyInternal::Prefix& prefix) {
return os << "{" << prefix.kind << ":" << prefix.name_hash << "}";
}
std::ostream& operator<<(std::ostream& os, const SignalKeyInternal& key) {
return os << "{" << key.prefix << ":" << key.time_range_end_sec << ":"
<< key.time_range_start_sec << "}";
}
} // namespace segmentation_platform
|