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

Side by Side 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 unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef COMPONENTS_TRACING_CORE_PROTO_UTILS_H_ 5 #ifndef COMPONENTS_TRACING_CORE_PROTO_UTILS_H_
6 #define COMPONENTS_TRACING_CORE_PROTO_UTILS_H_ 6 #define COMPONENTS_TRACING_CORE_PROTO_UTILS_H_
7 7
8 #include <inttypes.h> 8 #include <inttypes.h>
9 9
10 #include <type_traits> 10 #include <type_traits>
11 11
12 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "base/macros.h"
14 #include "components/tracing/tracing_export.h"
15 13
16 namespace tracing { 14 namespace tracing {
17 namespace v2 { 15 namespace v2 {
18 namespace proto { 16 namespace proto {
19 17
18 // TODO(kraynov) Change namespace to tracing::proto::internal.
19 // This stuff is required in headers and it's too low-level to be exposed.
20
20 // See https://developers.google.com/protocol-buffers/docs/encoding wire types. 21 // See https://developers.google.com/protocol-buffers/docs/encoding wire types.
21 22
22 enum : uint32_t { 23 enum : uint32_t {
23 kFieldTypeVarInt = 0, 24 kFieldTypeVarInt = 0,
24 kFieldTypeFixed64 = 1, 25 kFieldTypeFixed64 = 1,
25 kFieldTypeLengthDelimited = 2, 26 kFieldTypeLengthDelimited = 2,
26 kFieldTypeFixed32 = 5, 27 kFieldTypeFixed32 = 5,
27 }; 28 };
28 29
29 // Maximum message size supported: 256 MiB (4 x 7-bit due to varint encoding). 30 // Maximum message size supported: 256 MiB (4 x 7-bit due to varint encoding).
30 constexpr size_t kMessageLengthFieldSize = 4; 31 constexpr size_t kMessageLengthFieldSize = 4;
31 constexpr size_t kMaxMessageLength = (1u << (kMessageLengthFieldSize * 7)) - 1; 32 constexpr size_t kMaxMessageLength = (1u << (kMessageLengthFieldSize * 7)) - 1;
32 33
33 // Returns the number of bytes sufficient to encode the largest 34 // Varint maximum encoded size == (sizeof(T) * 8 + 6) / 7.
34 // |int_size_in_bits|-bits integer using a non-redundant varint encoding. 35 // Tag is encoded as 32-bit varint (5 bytes at most).
35 template <typename T> 36 // Largest possible singilar value is 64-bit varint (10 bytes at most).
36 constexpr size_t GetMaxVarIntEncodedSize() { 37 constexpr size_t kMaxTagEncodedSize = 5;
37 return (sizeof(T) * 8 + 6) / 7; 38 constexpr size_t kMaxSingilarFieldEncodedSize = 15;
38 }
39 39
40 // Variable-length field types: (s)int32, (s)int64, bool, enum. 40 // Proto types: (int|uint|sint)(32|64), bool, enum.
41 inline uint32_t MakeTagVarInt(uint32_t field_id) { 41 constexpr uint32_t MakeTagVarInt(uint32_t field_id) {
42 return (field_id << 3) | kFieldTypeVarInt; 42 return (field_id << 3) | kFieldTypeVarInt;
43 } 43 }
44 44
45 // Length-limited field types: string, bytes, embedded messages. 45 // Proto types: fixed64, sfixed64, fixed32, sfixed32, double, float.
46 inline uint32_t MakeTagLengthDelimited(uint32_t field_id) { 46 template <typename T>
47 constexpr uint32_t MakeTagFixed(uint32_t field_id) {
48 static_assert(sizeof(T) == 8 || sizeof(T) == 4, "Value must be 4 or 8 bytes");
49 return (field_id << 3) |
50 (sizeof(T) == 8 ? kFieldTypeFixed64 : kFieldTypeFixed32);
51 }
52
53 // Proto types: string, bytes, embedded messages.
54 constexpr uint32_t MakeTagLengthDelimited(uint32_t field_id) {
47 return (field_id << 3) | kFieldTypeLengthDelimited; 55 return (field_id << 3) | kFieldTypeLengthDelimited;
48 } 56 }
49 57
50 // 32-bit fixed-length field types: fixed32, sfixed32, float. 58 // Proto tipes: sint64, sint32.
51 inline uint32_t MakeTagFixed32(uint32_t field_id) { 59 template <typename T>
52 return (field_id << 3) | kFieldTypeFixed32; 60 inline typename std::make_unsigned<T>::type ZigZagEncode(T value) {
53 } 61 return (value << 1) ^ (value >> (sizeof(T) * 8 - 1));
54
55 // 64-bit fixed-length field types: fixed64, sfixed64, double.
56 inline uint32_t MakeTagFixed64(uint32_t field_id) {
57 return (field_id << 3) | kFieldTypeFixed64;
58 } 62 }
59 63
60 template <typename T> 64 template <typename T>
61 inline uint8_t* WriteVarIntInternal(T value, uint8_t* target) { 65 inline uint8_t* WriteVarInt(T value, uint8_t* target) {
62 static_assert(std::is_unsigned<T>::value, "value must be unsigned"); 66 // Avoid arithmetic (sign expanding) shifts.
63 while (value >= 0x80) { 67 typedef typename std::make_unsigned<T>::type unsigned_T;
64 *target++ = static_cast<uint8_t>(value | 0x80); 68 unsigned_T unsigned_value = static_cast<unsigned_T>(value);
65 value >>= 7; 69
70 while (unsigned_value >= 0x80) {
71 *target++ = static_cast<uint8_t>(unsigned_value | 0x80);
72 unsigned_value >>= 7;
66 } 73 }
67 *target = static_cast<uint8_t>(value); 74 *target = static_cast<uint8_t>(unsigned_value);
68 return target + 1; 75 return target + 1;
69 } 76 }
70 77
71 inline uint8_t* WriteVarIntU32(uint32_t value, uint8_t* target) {
72 return WriteVarIntInternal<uint32_t>(value, target);
73 }
74
75 inline uint8_t* WriteVarIntU64(uint64_t value, uint8_t* target) {
76 return WriteVarIntInternal<uint64_t>(value, target);
77 }
78
79 // TODO(kraynov): add support for signed integers and zig-zag encoding.
80
81 // Writes a fixed-size redundant encoding of the given |value|. This is 78 // Writes a fixed-size redundant encoding of the given |value|. This is
82 // used to backfill fixed-size reservations for the length field using a 79 // used to backfill fixed-size reservations for the length of field using a
83 // non-canonical varint encoding (e.g. \x81\x80\x80\x00 instead of \x01). 80 // non-canonical varint encoding (e.g. \x81\x80\x80\x00 instead of \x01).
84 // See https://github.com/google/protobuf/issues/1530. 81 // See https://github.com/google/protobuf/issues/1530.
85 // In particular, this is used for nested messages. The size of a nested message 82 // In particular, this is used for nested messages. The size of a nested message
86 // is not known until all its field have been written. A fixed amount of bytes 83 // is not known until all its field have been written.
87 // is reserved to encode the size field and backfilled at the end. 84 // A fixed kMessageLengthFieldSize amount of bytes is reserved to encode
88 template <size_t LENGTH> 85 // the size field and backfilled at the end.
89 void WriteRedundantVarIntU32(uint32_t value, uint8_t* buf) { 86 inline void WriteRedundantLength(uint32_t value, uint8_t* buf) {
90 for (size_t i = 0; i < LENGTH; ++i) { 87 DCHECK_LT(value, kMaxMessageLength) << "Message is too large";
91 const uint8_t msb = (i < LENGTH - 1) ? 0x80 : 0; 88 for (size_t i = 0; i < kMessageLengthFieldSize; ++i) {
89 const uint8_t msb = (i < kMessageLengthFieldSize - 1) ? 0x80 : 0;
92 buf[i] = static_cast<uint8_t>((value & 0x7F) | msb); 90 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.
93 value >>= 7; 91 value >>= 7;
94 } 92 }
95 DCHECK_EQ(0u, value) << "Buffer too short to encode the given value";
96 } 93 }
97 94
98 } // namespace proto 95 } // namespace proto
99 } // namespace v2 96 } // namespace v2
100 } // namespace tracing 97 } // namespace tracing
101 98
102 #endif // COMPONENTS_TRACING_CORE_PROTO_UTILS_H_ 99 #endif // COMPONENTS_TRACING_CORE_PROTO_UTILS_H_
OLDNEW
« 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