tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

structured_proto.h (3729B)


      1 // Copyright 2024 The Abseil Authors.
      2 //
      3 // Licensed under the Apache License, Version 2.0 (the "License");
      4 // you may not use this file except in compliance with the License.
      5 // You may obtain a copy of the License at
      6 //
      7 //      https://www.apache.org/licenses/LICENSE-2.0
      8 //
      9 // Unless required by applicable law or agreed to in writing, software
     10 // distributed under the License is distributed on an "AS IS" BASIS,
     11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 // See the License for the specific language governing permissions and
     13 // limitations under the License.
     14 //
     15 // -----------------------------------------------------------------------------
     16 // File: log/internal/structured_proto.h
     17 // -----------------------------------------------------------------------------
     18 
     19 #ifndef ABSL_LOG_INTERNAL_STRUCTURED_PROTO_H_
     20 #define ABSL_LOG_INTERNAL_STRUCTURED_PROTO_H_
     21 
     22 #include <cstddef>
     23 #include <cstdint>
     24 
     25 #include "absl/base/config.h"
     26 #include "absl/log/internal/proto.h"
     27 #include "absl/types/span.h"
     28 #include "absl/types/variant.h"
     29 
     30 namespace absl {
     31 ABSL_NAMESPACE_BEGIN
     32 namespace log_internal {
     33 
     34 // Sum type holding a single valid protobuf field suitable for encoding.
     35 struct StructuredProtoField final {
     36  // Numeric type encoded with varint encoding:
     37  // https://protobuf.dev/programming-guides/encoding/#varints
     38  using Varint = absl::variant<uint64_t, int64_t, uint32_t, int32_t, bool>;
     39 
     40  // Fixed-length 64-bit integer encoding:
     41  // https://protobuf.dev/programming-guides/encoding/#non-varints
     42  using I64 = absl::variant<uint64_t, int64_t, double>;
     43 
     44  // Length-delimited record type (string, sub-message):
     45  // https://protobuf.dev/programming-guides/encoding/#length-types
     46  using LengthDelimited = absl::Span<const char>;
     47 
     48  // Fixed-length 32-bit integer encoding:
     49  // https://protobuf.dev/programming-guides/encoding/#non-varints
     50  using I32 = absl::variant<uint32_t, int32_t, float>;
     51 
     52  // Valid record type:
     53  // https://protobuf.dev/programming-guides/encoding/#structure
     54  using Value = absl::variant<Varint, I64, LengthDelimited, I32>;
     55 
     56  // Field number for the protobuf value.
     57  uint64_t field_number;
     58 
     59  // Value to encode.
     60  Value value;
     61 };
     62 
     63 // Estimates the number of bytes needed to encode `field` using
     64 // protobuf encoding.
     65 //
     66 // The returned value might be larger than the actual number of bytes needed.
     67 inline size_t BufferSizeForStructuredProtoField(StructuredProtoField field) {
     68  // Visitor to estimate the number of bytes of one of the types contained
     69  // inside `StructuredProtoField`.
     70  struct BufferSizeVisitor final {
     71    size_t operator()(StructuredProtoField::Varint /*unused*/) {
     72      return BufferSizeFor(field_number, WireType::kVarint);
     73    }
     74 
     75    size_t operator()(StructuredProtoField::I64 /*unused*/) {
     76      return BufferSizeFor(field_number, WireType::k64Bit);
     77    }
     78 
     79    size_t operator()(StructuredProtoField::LengthDelimited length_delimited) {
     80      return BufferSizeFor(field_number, WireType::kLengthDelimited) +
     81             length_delimited.size();
     82    }
     83 
     84    size_t operator()(StructuredProtoField::I32 /*unused*/) {
     85      return BufferSizeFor(field_number, WireType::k32Bit);
     86    }
     87 
     88    uint64_t field_number;
     89  };
     90 
     91  return absl::visit(BufferSizeVisitor{field.field_number}, field.value);
     92 }
     93 
     94 // Encodes `field` into `buf` using protobuf encoding.
     95 //
     96 // On success, returns `true` and advances `buf` to the end of
     97 // the bytes consumed.
     98 //
     99 // On failure (if `buf` was too small), returns `false`.
    100 bool EncodeStructuredProtoField(StructuredProtoField field,
    101                                absl::Span<char>& buf);
    102 
    103 }  // namespace log_internal
    104 ABSL_NAMESPACE_END
    105 }  // namespace absl
    106 
    107 #endif  // ABSL_LOG_INTERNAL_STRUCTURED_PROTO_H_