Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(20)

Unified Diff: components/tracing/core/proto_utils.h

Issue 2228563002: Tracing V2: Proto message and utils improvements. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: components/tracing/core/proto_utils.h
diff --git a/components/tracing/core/proto_utils.h b/components/tracing/core/proto_utils.h
index 68599199688e98f0182aeb874a4e6e15e0585f2d..23eaba624ab902204291217eef4d7e7c66c75ae5 100644
--- a/components/tracing/core/proto_utils.h
+++ b/components/tracing/core/proto_utils.h
@@ -10,13 +10,14 @@
#include <type_traits>
#include "base/logging.h"
-#include "base/macros.h"
-#include "components/tracing/tracing_export.h"
namespace tracing {
namespace v2 {
namespace proto {
+// TODO(kraynov) Change namespace to tracing::proto::internal.
+// This stuff is required in headers and it's too low-level to be exposed.
+
// See https://developers.google.com/protocol-buffers/docs/encoding wire types.
enum : uint32_t {
@@ -30,69 +31,65 @@ enum : uint32_t {
constexpr size_t kMessageLengthFieldSize = 4;
constexpr size_t kMaxMessageLength = (1u << (kMessageLengthFieldSize * 7)) - 1;
-// Returns the number of bytes sufficient to encode the largest
-// |int_size_in_bits|-bits integer using a non-redundant varint encoding.
-template <typename T>
-constexpr size_t GetMaxVarIntEncodedSize() {
- return (sizeof(T) * 8 + 6) / 7;
-}
+// Varint maximum encoded size == (sizeof(T) * 8 + 6) / 7.
+// Tag is encoded as 32-bit varint (5 bytes at most).
+// Largest possible singilar value is 64-bit varint (10 bytes at most).
+constexpr size_t kMaxTagEncodedSize = 5;
+constexpr size_t kMaxSingilarFieldEncodedSize = 15;
-// Variable-length field types: (s)int32, (s)int64, bool, enum.
-inline uint32_t MakeTagVarInt(uint32_t field_id) {
+// Proto types: (int|uint|sint)(32|64), bool, enum.
+constexpr uint32_t MakeTagVarInt(uint32_t field_id) {
return (field_id << 3) | kFieldTypeVarInt;
}
-// Length-limited field types: string, bytes, embedded messages.
-inline uint32_t MakeTagLengthDelimited(uint32_t field_id) {
- return (field_id << 3) | kFieldTypeLengthDelimited;
+// Proto types: fixed64, sfixed64, fixed32, sfixed32, double, float.
+template <typename T>
+constexpr uint32_t MakeTagFixed(uint32_t field_id) {
+ static_assert(sizeof(T) == 8 || sizeof(T) == 4, "Value must be 4 or 8 bytes");
+ return (field_id << 3) |
+ (sizeof(T) == 8 ? kFieldTypeFixed64 : kFieldTypeFixed32);
}
-// 32-bit fixed-length field types: fixed32, sfixed32, float.
-inline uint32_t MakeTagFixed32(uint32_t field_id) {
- return (field_id << 3) | kFieldTypeFixed32;
+// Proto types: string, bytes, embedded messages.
+constexpr uint32_t MakeTagLengthDelimited(uint32_t field_id) {
+ return (field_id << 3) | kFieldTypeLengthDelimited;
}
-// 64-bit fixed-length field types: fixed64, sfixed64, double.
-inline uint32_t MakeTagFixed64(uint32_t field_id) {
- return (field_id << 3) | kFieldTypeFixed64;
+// Proto tipes: sint64, sint32.
+template <typename T>
+inline typename std::make_unsigned<T>::type ZigZagEncode(T value) {
+ return (value << 1) ^ (value >> (sizeof(T) * 8 - 1));
}
template <typename T>
-inline uint8_t* WriteVarIntInternal(T value, uint8_t* target) {
- static_assert(std::is_unsigned<T>::value, "value must be unsigned");
- while (value >= 0x80) {
- *target++ = static_cast<uint8_t>(value | 0x80);
- value >>= 7;
+inline uint8_t* WriteVarInt(T value, uint8_t* target) {
+ // Avoid arithmetic (sign expanding) shifts.
+ typedef typename std::make_unsigned<T>::type unsigned_T;
+ unsigned_T unsigned_value = static_cast<unsigned_T>(value);
+
+ while (unsigned_value >= 0x80) {
+ *target++ = static_cast<uint8_t>(unsigned_value | 0x80);
+ unsigned_value >>= 7;
}
- *target = static_cast<uint8_t>(value);
+ *target = static_cast<uint8_t>(unsigned_value);
return target + 1;
}
-inline uint8_t* WriteVarIntU32(uint32_t value, uint8_t* target) {
- return WriteVarIntInternal<uint32_t>(value, target);
-}
-
-inline uint8_t* WriteVarIntU64(uint64_t value, uint8_t* target) {
- return WriteVarIntInternal<uint64_t>(value, target);
-}
-
-// TODO(kraynov): add support for signed integers and zig-zag encoding.
-
// Writes a fixed-size redundant encoding of the given |value|. This is
-// used to backfill fixed-size reservations for the length field using a
+// used to backfill fixed-size reservations for the length of field using a
// non-canonical varint encoding (e.g. \x81\x80\x80\x00 instead of \x01).
// See https://github.com/google/protobuf/issues/1530.
// In particular, this is used for nested messages. The size of a nested message
-// is not known until all its field have been written. A fixed amount of bytes
-// is reserved to encode the size field and backfilled at the end.
-template <size_t LENGTH>
-void WriteRedundantVarIntU32(uint32_t value, uint8_t* buf) {
- for (size_t i = 0; i < LENGTH; ++i) {
- const uint8_t msb = (i < LENGTH - 1) ? 0x80 : 0;
+// is not known until all its field have been written.
+// A fixed kMessageLengthFieldSize amount of bytes is reserved to encode
+// the size field and backfilled at the end.
+inline void WriteRedundantLength(uint32_t value, uint8_t* buf) {
+ DCHECK_LT(value, kMaxMessageLength) << "Message is too large";
+ for (size_t i = 0; i < kMessageLengthFieldSize; ++i) {
+ const uint8_t msb = (i < kMessageLengthFieldSize - 1) ? 0x80 : 0;
buf[i] = static_cast<uint8_t>((value & 0x7F) | msb);
alph 2016/08/08 19:59:50 nit: & 0x7F is redundant
kraynov 2016/08/09 12:32:04 Done.
value >>= 7;
}
- DCHECK_EQ(0u, value) << "Buffer too short to encode the given value";
}
} // namespace proto
« no previous file with comments | « no previous file | components/tracing/core/proto_utils_unittest.cc » ('j') | components/tracing/core/proto_utils_unittest.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698