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

Side by Side Diff: components/tracing/core/proto_utils.h

Issue 2271653004: Reland of tracing v2: Introduce TraceBufferWriter (https://codereview.chromium.org/2196663002) (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix undefined behavior of move ctor that caused revert on Win 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
« no previous file with comments | « components/tracing/BUILD.gn ('k') | components/tracing/core/proto_utils_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 13
14 namespace tracing { 14 namespace tracing {
15 namespace v2 { 15 namespace v2 {
16 namespace proto { 16 namespace proto {
17 17
18 // TODO(kraynov): Change namespace to tracing::proto::internal.
19 // This is required in headers and it's too low-level to be exposed.
20
21 // See https://developers.google.com/protocol-buffers/docs/encoding wire types. 18 // See https://developers.google.com/protocol-buffers/docs/encoding wire types.
22 19
23 enum : uint32_t { 20 enum : uint32_t {
24 kFieldTypeVarInt = 0, 21 kFieldTypeVarInt = 0,
25 kFieldTypeFixed64 = 1, 22 kFieldTypeFixed64 = 1,
26 kFieldTypeLengthDelimited = 2, 23 kFieldTypeLengthDelimited = 2,
27 kFieldTypeFixed32 = 5, 24 kFieldTypeFixed32 = 5,
28 }; 25 };
29 26
30 // Maximum message size supported: 256 MiB (4 x 7-bit due to varint encoding). 27 // Maximum message size supported: 256 MiB (4 x 7-bit due to varint encoding).
31 constexpr size_t kMessageLengthFieldSize = 4; 28 constexpr size_t kMessageLengthFieldSize = 4;
32 constexpr size_t kMaxMessageLength = (1u << (kMessageLengthFieldSize * 7)) - 1; 29 constexpr size_t kMaxMessageLength = (1u << (kMessageLengthFieldSize * 7)) - 1;
33 30
34 // Field tag is encoded as 32-bit varint (5 bytes at most). 31 // Field tag is encoded as 32-bit varint (5 bytes at most).
35 // Largest value of simple (not length-delimited) field is 64-bit varint 32 // Largest value of simple (not length-delimited) field is 64-bit varint
36 // (10 bytes at most). 15 bytes buffer is enough to store a simple field. 33 // (10 bytes at most). 15 bytes buffer is enough to store a simple field.
37 constexpr size_t kMaxTagEncodedSize = 5; 34 constexpr size_t kMaxTagEncodedSize = 5;
38 constexpr size_t kMaxSimpleFieldEncodedSize = 15; 35 constexpr size_t kMaxSimpleFieldEncodedSize = kMaxTagEncodedSize + 10;
39 36
40 // Proto types: (int|uint|sint)(32|64), bool, enum. 37 // Proto types: (int|uint|sint)(32|64), bool, enum.
41 constexpr uint32_t MakeTagVarInt(uint32_t field_id) { 38 constexpr uint32_t MakeTagVarInt(uint32_t field_id) {
42 return (field_id << 3) | kFieldTypeVarInt; 39 return (field_id << 3) | kFieldTypeVarInt;
43 } 40 }
44 41
45 // Proto types: fixed64, sfixed64, fixed32, sfixed32, double, float. 42 // Proto types: fixed64, sfixed64, fixed32, sfixed32, double, float.
46 template <typename T> 43 template <typename T>
47 constexpr uint32_t MakeTagFixed(uint32_t field_id) { 44 constexpr uint32_t MakeTagFixed(uint32_t field_id) {
48 static_assert(sizeof(T) == 8 || sizeof(T) == 4, "Value must be 4 or 8 bytes"); 45 static_assert(sizeof(T) == 8 || sizeof(T) == 4, "Value must be 4 or 8 bytes");
(...skipping 20 matching lines...) Expand all
69 66
70 while (unsigned_value >= 0x80) { 67 while (unsigned_value >= 0x80) {
71 *target++ = static_cast<uint8_t>(unsigned_value) | 0x80; 68 *target++ = static_cast<uint8_t>(unsigned_value) | 0x80;
72 unsigned_value >>= 7; 69 unsigned_value >>= 7;
73 } 70 }
74 *target = static_cast<uint8_t>(unsigned_value); 71 *target = static_cast<uint8_t>(unsigned_value);
75 return target + 1; 72 return target + 1;
76 } 73 }
77 74
78 // Writes a fixed-size redundant encoding of the given |value|. This is 75 // Writes a fixed-size redundant encoding of the given |value|. This is
79 // used to backfill fixed-size reservations for the length of field using a 76 // used to backfill fixed-size reservations for the length field using a
80 // non-canonical varint encoding (e.g. \x81\x80\x80\x00 instead of \x01). 77 // non-canonical varint encoding (e.g. \x81\x80\x80\x00 instead of \x01).
81 // See https://github.com/google/protobuf/issues/1530. 78 // See https://github.com/google/protobuf/issues/1530.
82 // In particular, this is used for nested messages. The size of a nested message 79 // In particular, this is used for nested messages. The size of a nested message
83 // is not known until all its field have been written. |kMessageLengthFieldSize| 80 // is not known until all its field have been written. |kMessageLengthFieldSize|
84 // bytes are reserved to encode the size field and backfilled at the end. 81 // bytes are reserved to encode the size field and backfilled at the end.
85 inline void WriteRedundantLength(uint32_t value, uint8_t* buf) { 82 inline void WriteRedundantVarInt(uint32_t value, uint8_t* buf) {
86 DCHECK_LE(value, kMaxMessageLength) << "Message is too long";
87 for (size_t i = 0; i < kMessageLengthFieldSize; ++i) { 83 for (size_t i = 0; i < kMessageLengthFieldSize; ++i) {
88 const uint8_t msb = (i < kMessageLengthFieldSize - 1) ? 0x80 : 0; 84 const uint8_t msb = (i < kMessageLengthFieldSize - 1) ? 0x80 : 0;
89 buf[i] = static_cast<uint8_t>(value) | msb; 85 buf[i] = static_cast<uint8_t>(value) | msb;
90 value >>= 7; 86 value >>= 7;
91 } 87 }
88 DCHECK_EQ(0u, value) << "Message is too long";
92 } 89 }
93 90
91 template <uint32_t field_id>
92 void StaticAssertSingleBytePreamble() {
93 static_assert(field_id < 16,
94 "Proto field id too big to fit in a single byte preamble");
95 };
96
94 } // namespace proto 97 } // namespace proto
95 } // namespace v2 98 } // namespace v2
96 } // namespace tracing 99 } // namespace tracing
97 100
98 #endif // COMPONENTS_TRACING_CORE_PROTO_UTILS_H_ 101 #endif // COMPONENTS_TRACING_CORE_PROTO_UTILS_H_
OLDNEW
« no previous file with comments | « components/tracing/BUILD.gn ('k') | components/tracing/core/proto_utils_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698