blob: c6e9081d0bd0816786ae18eaaba557d5063d921a [file] [log] [blame]
// Copyright 2025 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef LIB_SYSLOG_CPP_HOST_LOG_BUFFER_H_
#define LIB_SYSLOG_CPP_HOST_LOG_BUFFER_H_
#include <lib/syslog/cpp/log_level.h>
#include <cstdint>
#include <optional>
#include <string>
#include <string_view>
namespace fuchsia_logging {
template <typename Key, typename Value>
class KeyValue final {
public:
constexpr KeyValue(Key key, Value value) : key_(key), value_(value) {}
constexpr const Key& key() const { return key_; }
constexpr const Value& value() const { return value_; }
private:
Key key_;
Value value_;
};
// Opaque structure representing the backend encode state.
// This structure only has meaning to the backend and application code shouldn't
// touch these values.
class LogBuffer final {
public:
void WriteKeyValue(std::string_view key, std::string_view value);
void WriteKeyValue(std::string_view key, int64_t value);
void WriteKeyValue(std::string_view key, uint64_t value);
void WriteKeyValue(std::string_view key, double value);
void WriteKeyValue(std::string_view key, bool value);
void WriteKeyValue(std::string_view key, const char* value) {
WriteKeyValue(key, std::string_view(value));
}
// Encodes an int8
void Encode(KeyValue<const char*, int8_t> value) {
Encode(KeyValue<const char*, int64_t>(value.key(), value.value()));
}
// Encodes an int16
void Encode(KeyValue<const char*, int16_t> value) {
Encode(KeyValue<const char*, int64_t>(value.key(), value.value()));
}
// Encodes an int32
void Encode(KeyValue<const char*, int32_t> value) {
Encode(KeyValue<const char*, int64_t>(value.key(), value.value()));
}
// Encodes an int64
void Encode(KeyValue<const char*, int64_t> value) { WriteKeyValue(value.key(), value.value()); }
#ifdef __APPLE__
// Encodes a size_t. On Apple Clang, size_t is a special type.
void Encode(KeyValue<const char*, size_t> value) {
WriteKeyValue(value.key(), static_cast<int64_t>(value.value()));
}
#endif
// Encodes an uint8_t
void Encode(KeyValue<const char*, uint8_t> value) {
Encode(KeyValue<const char*, uint64_t>(value.key(), value.value()));
}
// Encodes an uint16_t
void Encode(KeyValue<const char*, uint16_t> value) {
Encode(KeyValue<const char*, uint64_t>(value.key(), value.value()));
}
// Encodes a uint32_t
void Encode(KeyValue<const char*, uint32_t> value) {
Encode(KeyValue<const char*, uint64_t>(value.key(), value.value()));
}
// Encodes an uint64
void Encode(KeyValue<const char*, uint64_t> value) { WriteKeyValue(value.key(), value.value()); }
// Encodes a NULL-terminated C-string.
void Encode(KeyValue<const char*, const char*> value) {
WriteKeyValue(value.key(), value.value());
}
// Encodes a NULL-terminated C-string.
void Encode(KeyValue<const char*, char*> value) { WriteKeyValue(value.key(), value.value()); }
// Encodes a C++ std::string.
void Encode(KeyValue<const char*, std::string> value) {
WriteKeyValue(value.key(), value.value());
}
// Encodes a C++ std::string_view.
void Encode(KeyValue<const char*, std::string_view> value) {
WriteKeyValue(value.key(), value.value());
}
// Encodes a double floating point value
void Encode(KeyValue<const char*, double> value) { WriteKeyValue(value.key(), value.value()); }
// Encodes a floating point value
void Encode(KeyValue<const char*, float> value) { WriteKeyValue(value.key(), value.value()); }
// Encodes a boolean value
void Encode(KeyValue<const char*, bool> value) { WriteKeyValue(value.key(), value.value()); }
// Writes the log.
bool Flush();
uint64_t* data() { return data_; }
uint64_t* record_state() { return record_state_; }
static constexpr size_t record_state_size() { return sizeof(record_state_); }
static constexpr size_t data_size() { return sizeof(data_); }
private:
// Max size of log buffer. This number may change as additional fields
// are added to the internal encoding state. It is based on trial-and-error
// and is adjusted when compilation fails due to it not being large enough.
static constexpr auto kBufferSize = (1 << 15) / 8;
// Additional storage for internal log state.
static constexpr auto kStateSize = 18;
// Record state (for keeping track of backend-specific details)
uint64_t record_state_[kStateSize];
// Log data (used by the backend to encode the log into). The format
// for this is backend-specific.
uint64_t data_[kBufferSize];
};
} // namespace fuchsia_logging
#endif // LIB_SYSLOG_CPP_HOST_LOG_BUFFER_H_