Index: base/debug/trace_event_value.h |
diff --git a/base/debug/trace_event_value.h b/base/debug/trace_event_value.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..f2ed888620f989b53c8e08d85323548306d6aafd |
--- /dev/null |
+++ b/base/debug/trace_event_value.h |
@@ -0,0 +1,160 @@ |
+// Copyright 2013 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#ifndef BASE_DEBUG_TRACE_EVENT_VALUE_H_ |
+#define BASE_DEBUG_TRACE_EVENT_VALUE_H_ |
+ |
+#include <stack> |
+#include <string> |
+ |
+#include "base/debug/trace_event.h" |
+#include "base/debug/trace_event_object.h" |
+#include "base/format_macros.h" |
+#include "base/memory/scoped_ptr.h" |
+#include "base/pickle.h" |
+#include "base/threading/non_thread_safe.h" |
+ |
+namespace base { |
+namespace debug { |
+ |
+// TracedValue has several functions to push data that will be converted to |
+// trace event format without depending on base::Value objects. |
+class BASE_EXPORT TracedValue : public base::debug::ConvertableToTraceFormat, |
+ public base::NonThreadSafe { |
+ public: |
+ TracedValue(); |
+ virtual ~TracedValue(); |
+ |
+ virtual void AppendAsTraceFormat(std::string* out) const OVERRIDE; |
+ |
+ // Begin a dictionary, it can either be a top-level structure or a value in |
+ // an array. |
+ void BeginDictionary(); |
+ // Used for both BeginDictionary() and PushDictionary(). |
+ void EndDictionary(); |
+ // Begin an array, that is either a top-level structure or a value in an |
+ // array. |
+ void BeginArray(); |
+ // Used for both BeginArray() and PushArray(). |
+ void EndArray(); |
+ |
+ // Put stuff in dictionary using statically allocated string keys. |
+ // Begins a dictionary, that is an entry within another dictionary. |
+ void PushDictionary(const char* key_in_parent_dict); |
+ // Begins an array, that is an entry within a dictonary. |
+ void PushArray(const char* key_in_parent_dict); |
+#define TRACE_PUSH(type) \ |
+ void Push(const char* key, type value) { \ |
+ DCHECK_EQ(BEGIN_DICTIONARY, begin_opcodes_.top()); \ |
+ BeginDictionaryEntry(); \ |
+ PushKeyToPickle(key); \ |
+ PushValueToPickle(value); \ |
+ EndDictionaryEntry(); \ |
+ } |
+TRACE_PUSH(const char*) |
+TRACE_PUSH(const std::string&) |
+TRACE_PUSH(int32) |
+TRACE_PUSH(int64) |
+TRACE_PUSH(uint32) |
+TRACE_PUSH(uint64) |
+TRACE_PUSH(float) |
+TRACE_PUSH(bool) |
+TRACE_PUSH(const TracedObject&) |
+#undef TRACE_PUSH |
+ |
+// Put stuff in an array. |
+#define TRACE_PUSH(type) \ |
+ void Push(type value) { \ |
+ DCHECK_EQ(BEGIN_ARRAY, begin_opcodes_.top()); \ |
+ PushValueToPickle(value); \ |
+ } |
+TRACE_PUSH(const char*) |
+TRACE_PUSH(const std::string&) |
+TRACE_PUSH(int32) |
+TRACE_PUSH(int64) |
+TRACE_PUSH(uint32) |
+TRACE_PUSH(uint64) |
+TRACE_PUSH(float) |
+TRACE_PUSH(bool) |
+TRACE_PUSH(const TracedObject&) |
+#undef TRACE_PUSH |
+ |
+ private: |
+ // Begin and end dictionary entry methods allow us to know that we're writing |
+ // a dictionary entry, this is needed for scenarios where we don't write the |
+ // value write away, but defer to some other implementation how to write the |
dsinclair
2013/08/12 13:34:40
s/write/right
|
+ // entry's value for example with TracedObject.PushInto(). |
+ void BeginDictionaryEntry(); |
+ void EndDictionaryEntry(); |
+ // Push key/value should not be exposed, instead, the Push methods are |
+ // exposed, to have them assert that we are in the right state before writing |
+ // to the pickle. |
+ void PushKeyToPickle(const char* key); |
+ void PushValueToPickle(const char* value); |
+ void PushValueToPickle(const std::string& value); |
+ void PushValueToPickle(int value); |
+ void PushValueToPickle(int64 value); |
+ void PushValueToPickle(uint32 value); |
+ void PushValueToPickle(uint64 value); |
+ void PushValueToPickle(float value); |
+ void PushValueToPickle(bool value); |
+ void PushValueToPickle(const TracedObject& value); |
+ |
+ // Helper methods used in AppendAsTraceFormat(). |
+ void AppendKeyAsRawPointer(std::string* out, PickleIterator* iter) const; |
+ void AppendValueAsRawPointer(std::string* out, PickleIterator* iter) const; |
+ void AppendValueAsString(std::string* out, PickleIterator* iter) const; |
+ void AppendValueAsInt32(std::string* out, PickleIterator* iter) const; |
+ void AppendValueAsInt64(std::string* out, PickleIterator* iter) const; |
+ void AppendValueAsUInt32(std::string* out, PickleIterator* iter) const; |
+ void AppendValueAsUInt64(std::string* out, PickleIterator* iter) const; |
+ void AppendValueAsFloat(std::string* out, PickleIterator* iter) const; |
+ void AppendValueAsBool(std::string* out, PickleIterator* iter) const; |
+ |
+ void CheckNotWithinDictionary(); |
+ |
+ Pickle pickle_; |
+ enum Opcode { |
+ BEGIN_DICTIONARY, |
+ END_DICTIONARY, |
+ BEGIN_ARRAY, |
+ END_ARRAY, |
+ KEY_AS_RAW_POINTER, |
+ // BEGIN_DICTIONARY_ENTRY is only used to know that we are in the middle |
+ // of writing a dictionary entry to the pickle, however, it is not |
+ // written into the pickle, only into the stack where we keep track of |
+ // the state. |
+ BEGIN_DICTIONARY_ENTRY, |
+ VALUE_AS_RAW_POINTER, |
+ VALUE_AS_STRING, |
+ INT32_VALUE, |
+ INT64_VALUE, |
+ UINT32_VALUE, |
+ UINT64_VALUE, |
+ FLOAT_VALUE, |
+ BOOL_VALUE |
+ }; |
+ |
+ // This method is in charge of preppending a comma before a value within an |
+ // array, or a dictionary. If necessary, the element count will be |
+ // incremented. |
+ static void AppendComma(std::string* out, Opcode begin_opcode, |
+ Opcode current_opcode, int* element_count); |
+ |
+ // This is used to keep track of the operations that need to be closed, in |
+ // in order to enforce consistency in the operations. The only opcodes that |
+ // need to be kept in this datastructure are BEGIN_* opcodes, such as |
+ // BEGIN_ARRAY or BEGIN_DICTIONARY, using this stack, we know that we can't |
+ // do an array push, when we have a dictionary, and we end a dictionary, when |
+ // we were working on an array. |
+ std::stack<Opcode> begin_opcodes_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(TracedValue); |
+}; |
+ |
+} // namespace debug |
+} // namespace base |
+ |
+#endif |
+ |