1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef BASE_TRACE_EVENT_TRACED_VALUE_H_ 6 #define BASE_TRACE_EVENT_TRACED_VALUE_H_ 7 8 #include <stddef.h> 9 10 #include <memory> 11 #include <string> 12 #include <vector> 13 14 #include "base/macros.h" 15 #include "base/pickle.h" 16 #include "base/strings/string_piece.h" 17 #include "base/trace_event/trace_event_impl.h" 18 19 namespace base { 20 21 class Value; 22 23 namespace trace_event { 24 25 class BASE_EXPORT TracedValue : public ConvertableToTraceFormat { 26 public: 27 // TODO(oysteine): |capacity| is not used in any production code. Consider 28 // removing it. 29 explicit TracedValue(size_t capacity = 0); 30 ~TracedValue() override; 31 32 void EndDictionary(); 33 void EndArray(); 34 35 // These methods assume that |name| is a long lived "quoted" string. 36 void SetInteger(const char* name, int value); 37 void SetDouble(const char* name, double value); 38 void SetBoolean(const char* name, bool value); 39 void SetString(const char* name, base::StringPiece value); 40 void SetValue(const char* name, TracedValue* value); 41 void BeginDictionary(const char* name); 42 void BeginArray(const char* name); 43 44 // These, instead, can be safely passed a temporary string. 45 void SetIntegerWithCopiedName(base::StringPiece name, int value); 46 void SetDoubleWithCopiedName(base::StringPiece name, double value); 47 void SetBooleanWithCopiedName(base::StringPiece name, bool value); 48 void SetStringWithCopiedName(base::StringPiece name, base::StringPiece value); 49 void SetValueWithCopiedName(base::StringPiece name, TracedValue* value); 50 void BeginDictionaryWithCopiedName(base::StringPiece name); 51 void BeginArrayWithCopiedName(base::StringPiece name); 52 53 void AppendInteger(int); 54 void AppendDouble(double); 55 void AppendBoolean(bool); 56 void AppendString(base::StringPiece); 57 void BeginArray(); 58 void BeginDictionary(); 59 60 // ConvertableToTraceFormat implementation. 61 void AppendAsTraceFormat(std::string* out) const override; 62 bool AppendToProto(ProtoAppender* appender) override; 63 64 void EstimateTraceMemoryOverhead(TraceEventMemoryOverhead* overhead) override; 65 66 // A custom serialization class can be supplied by implementing the 67 // Writer interface and supplying a factory class to SetWriterFactoryCallback. 68 // Primarily used by Perfetto to write TracedValues directly into its proto 69 // format, which lets us do a direct memcpy() in AppendToProto() rather than 70 // a JSON serialization step in AppendAsTraceFormat. 71 class BASE_EXPORT Writer { 72 public: 73 virtual ~Writer() = default; 74 75 virtual void BeginArray() = 0; 76 virtual void BeginDictionary() = 0; 77 virtual void EndDictionary() = 0; 78 virtual void EndArray() = 0; 79 80 // These methods assume that |name| is a long lived "quoted" string. 81 virtual void SetInteger(const char* name, int value) = 0; 82 virtual void SetDouble(const char* name, double value) = 0; 83 virtual void SetBoolean(const char* name, bool value) = 0; 84 virtual void SetString(const char* name, base::StringPiece value) = 0; 85 virtual void SetValue(const char* name, Writer* value) = 0; 86 virtual void BeginDictionary(const char* name) = 0; 87 virtual void BeginArray(const char* name) = 0; 88 89 // These, instead, can be safely passed a temporary string. 90 virtual void SetIntegerWithCopiedName(base::StringPiece name, 91 int value) = 0; 92 virtual void SetDoubleWithCopiedName(base::StringPiece name, 93 double value) = 0; 94 virtual void SetBooleanWithCopiedName(base::StringPiece name, 95 bool value) = 0; 96 virtual void SetStringWithCopiedName(base::StringPiece name, 97 base::StringPiece value) = 0; 98 virtual void SetValueWithCopiedName(base::StringPiece name, 99 Writer* value) = 0; 100 virtual void BeginDictionaryWithCopiedName(base::StringPiece name) = 0; 101 virtual void BeginArrayWithCopiedName(base::StringPiece name) = 0; 102 103 virtual void AppendInteger(int) = 0; 104 virtual void AppendDouble(double) = 0; 105 virtual void AppendBoolean(bool) = 0; 106 virtual void AppendString(base::StringPiece) = 0; 107 108 virtual void AppendAsTraceFormat(std::string* out) const = 0; 109 110 virtual bool AppendToProto(ProtoAppender* appender); 111 112 virtual void EstimateTraceMemoryOverhead( 113 TraceEventMemoryOverhead* overhead) = 0; 114 115 virtual bool IsPickleWriter() const = 0; 116 virtual bool IsProtoWriter() const = 0; 117 }; 118 119 typedef std::unique_ptr<Writer> (*WriterFactoryCallback)(size_t capacity); 120 static void SetWriterFactoryCallback(WriterFactoryCallback callback); 121 122 protected: 123 TracedValue(size_t capacity, bool forced_json); 124 125 std::unique_ptr<base::Value> ToBaseValue() const; 126 127 private: 128 std::unique_ptr<Writer> writer_; 129 130 #ifndef NDEBUG 131 // In debug builds checks the pairings of {Start,End}{Dictionary,Array} 132 std::vector<bool> nesting_stack_; 133 #endif 134 135 DISALLOW_COPY_AND_ASSIGN(TracedValue); 136 }; 137 138 // TracedValue that is convertable to JSON format. This has lower performance 139 // than the default TracedValue in production code, and should be used only for 140 // testing and debugging. Should be avoided in tracing. It's for 141 // testing/debugging code calling value dumping function designed for tracing, 142 // like the following: 143 // 144 // TracedValueJSON value; 145 // AsValueInto(&value); // which is designed for tracing. 146 // return value.ToJSON(); 147 // 148 // If the code is merely for testing/debugging, base::Value should be used 149 // instead. 150 class BASE_EXPORT TracedValueJSON : public TracedValue { 151 public: 152 explicit TracedValueJSON(size_t capacity = 0) TracedValue(capacity,true)153 : TracedValue(capacity, /*forced_josn*/ true) {} 154 155 using TracedValue::ToBaseValue; 156 157 // Converts the value into a JSON string without formatting. Suitable for 158 // printing a simple value or printing a value in a single line context. 159 std::string ToJSON() const; 160 161 // Converts the value into a formatted JSON string, with indentation, spaces 162 // and new lines for better human readability of complex values. 163 std::string ToFormattedJSON() const; 164 }; 165 166 } // namespace trace_event 167 } // namespace base 168 169 #endif // BASE_TRACE_EVENT_TRACED_VALUE_H_ 170