123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672 |
- #ifndef BASE_TRACE_EVENT_TRACE_ARGUMENTS_H_
- #define BASE_TRACE_EVENT_TRACE_ARGUMENTS_H_
- #include <stdlib.h>
- #include <string.h>
- #include <algorithm>
- #include <memory>
- #include <string>
- #include "base/base_export.h"
- #include "base/macros.h"
- #include "base/trace_event/common/trace_event_common.h"
- namespace base {
- class Time;
- class TimeTicks;
- class ThreadTicks;
- namespace trace_event {
- class TraceEventMemoryOverhead;
- class BASE_EXPORT ConvertableToTraceFormat {
- public:
- ConvertableToTraceFormat() = default;
- virtual ~ConvertableToTraceFormat() = default;
-
-
-
-
- virtual void AppendAsTraceFormat(std::string* out) const = 0;
-
-
-
-
- class BASE_EXPORT ProtoAppender {
- public:
- virtual ~ProtoAppender() = default;
- virtual void AddBuffer(uint8_t* begin, uint8_t* end) = 0;
-
-
- virtual size_t Finalize(uint32_t field_id) = 0;
- };
- virtual bool AppendToProto(ProtoAppender* appender);
- virtual void EstimateTraceMemoryOverhead(TraceEventMemoryOverhead* overhead);
- private:
- DISALLOW_COPY_AND_ASSIGN(ConvertableToTraceFormat);
- };
- const int kTraceMaxNumArgs = 2;
- union BASE_EXPORT TraceValue {
- bool as_bool;
- unsigned long long as_uint;
- long long as_int;
- double as_double;
- const void* as_pointer;
- const char* as_string;
- ConvertableToTraceFormat* as_convertable;
-
-
-
-
-
-
-
-
-
-
-
-
-
- template <typename T>
- void Init(T&& value) {
- using ValueType = typename InnerType<T>::type;
- Helper<ValueType>::SetValue(this, std::forward<T>(value));
- }
-
-
-
-
-
-
-
-
-
-
-
-
- template <typename T>
- static TraceValue Make(T&& value) {
- TraceValue ret;
- ret.Init(std::forward<T>(value));
- return ret;
- }
-
-
- void AppendAsJSON(unsigned char type, std::string* out) const;
-
-
-
- void AppendAsString(unsigned char type, std::string* out) const;
- private:
- void Append(unsigned char type, bool as_json, std::string* out) const;
-
-
- template <typename T>
- struct InnerType {
- using type = typename std::remove_cv<typename std::remove_reference<
- typename std::decay<T>::type>::type>::type;
- };
- public:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- template <typename T, class = void>
- struct Helper {};
-
-
- template <typename T>
- struct TypeFor {
- using ValueType = typename InnerType<T>::type;
- static const unsigned char value = Helper<ValueType>::kType;
- };
-
-
-
-
- template <typename T,
- class = decltype(TraceValue::Helper<
- typename TraceValue::InnerType<T>::type>::kType)>
- struct TypeCheck {
- static const bool value = true;
- };
- };
- template <typename T>
- struct TraceValue::Helper<
- T,
- typename std::enable_if<std::is_integral<T>::value ||
- std::is_enum<T>::value>::type> {
- static constexpr unsigned char kType =
- std::is_signed<T>::value ? TRACE_VALUE_TYPE_INT : TRACE_VALUE_TYPE_UINT;
- static inline void SetValue(TraceValue* v, T value) {
- v->as_uint = static_cast<unsigned long long>(value);
- }
- };
- template <typename T>
- struct TraceValue::
- Helper<T, typename std::enable_if<std::is_floating_point<T>::value>::type> {
- static constexpr unsigned char kType = TRACE_VALUE_TYPE_DOUBLE;
- static inline void SetValue(TraceValue* v, T value) { v->as_double = value; }
- };
- template <>
- struct TraceValue::Helper<bool> {
- static constexpr unsigned char kType = TRACE_VALUE_TYPE_BOOL;
- static inline void SetValue(TraceValue* v, bool value) { v->as_bool = value; }
- };
- template <typename T>
- struct TraceValue::Helper<T*> {
- static constexpr unsigned char kType = TRACE_VALUE_TYPE_POINTER;
- static inline void SetValue(TraceValue* v,
- const typename std::decay<T>::type* value) {
- v->as_pointer = value;
- }
- };
- template <>
- struct TraceValue::Helper<const char*> {
- static constexpr unsigned char kType = TRACE_VALUE_TYPE_STRING;
- static inline void SetValue(TraceValue* v, const char* value) {
- v->as_string = value;
- }
- };
- template <>
- struct TraceValue::Helper<std::string> {
- static constexpr unsigned char kType = TRACE_VALUE_TYPE_COPY_STRING;
- static inline void SetValue(TraceValue* v, const std::string& value) {
- v->as_string = value.c_str();
- }
- };
- template <typename CONVERTABLE_TYPE>
- struct TraceValue::Helper<std::unique_ptr<CONVERTABLE_TYPE>,
- typename std::enable_if<std::is_convertible<
- CONVERTABLE_TYPE*,
- ConvertableToTraceFormat*>::value>::type> {
- static constexpr unsigned char kType = TRACE_VALUE_TYPE_CONVERTABLE;
- static inline void SetValue(TraceValue* v,
- std::unique_ptr<CONVERTABLE_TYPE> value) {
- v->as_convertable = value.release();
- }
- };
- template <typename T>
- struct TraceValue::Helper<
- T,
- typename std::enable_if<std::is_same<T, base::Time>::value ||
- std::is_same<T, base::TimeTicks>::value ||
- std::is_same<T, base::ThreadTicks>::value>::type> {
- static constexpr unsigned char kType = TRACE_VALUE_TYPE_INT;
- static inline void SetValue(TraceValue* v, const T& value) {
- v->as_int = value.ToInternalValue();
- }
- };
- class TraceStringWithCopy {
- public:
- explicit TraceStringWithCopy(const char* str) : str_(str) {}
- const char* str() const { return str_; }
- private:
- const char* str_;
- };
- template <>
- struct TraceValue::Helper<TraceStringWithCopy> {
- static constexpr unsigned char kType = TRACE_VALUE_TYPE_COPY_STRING;
- static inline void SetValue(TraceValue* v, const TraceStringWithCopy& value) {
- v->as_string = value.str();
- }
- };
- class TraceArguments;
- class BASE_EXPORT StringStorage {
- public:
- constexpr StringStorage() = default;
- explicit StringStorage(size_t alloc_size) { Reset(alloc_size); }
- ~StringStorage() {
- if (data_)
- ::free(data_);
- }
- StringStorage(StringStorage&& other) noexcept : data_(other.data_) {
- other.data_ = nullptr;
- }
- StringStorage& operator=(StringStorage&& other) noexcept {
- if (this != &other) {
- if (data_)
- ::free(data_);
- data_ = other.data_;
- other.data_ = nullptr;
- }
- return *this;
- }
-
-
-
- void Reset(size_t alloc_size = 0);
-
- constexpr size_t size() const { return data_ ? data_->size : 0u; }
- constexpr const char* data() const { return data_ ? data_->chars : nullptr; }
- constexpr char* data() { return data_ ? data_->chars : nullptr; }
- constexpr const char* begin() const { return data(); }
- constexpr const char* end() const { return data() + size(); }
- inline char* begin() { return data(); }
- inline char* end() { return data() + size(); }
-
- constexpr bool empty() const { return size() == 0; }
-
-
- constexpr bool Contains(const void* ptr) const {
- const char* char_ptr = static_cast<const char*>(ptr);
- return (char_ptr >= begin() && char_ptr < end());
- }
-
-
- bool Contains(const TraceArguments& args) const;
-
-
- constexpr size_t EstimateTraceMemoryOverhead() const {
- return data_ ? sizeof(size_t) + data_->size : 0u;
- }
- private:
-
-
-
-
-
- struct Data {
- size_t size = 0;
- char chars[1];
- };
-
-
-
-
- Data* data_ = nullptr;
- };
- class BASE_EXPORT TraceArguments {
- public:
-
- static constexpr size_t kMaxSize = 2;
-
- TraceArguments() : size_(0) {}
-
- template <typename T, class = decltype(TraceValue::TypeCheck<T>::value)>
- TraceArguments(const char* arg1_name, T&& arg1_value) : size_(1) {
- types_[0] = TraceValue::TypeFor<T>::value;
- names_[0] = arg1_name;
- values_[0].Init(std::forward<T>(arg1_value));
- }
-
- template <typename T1,
- typename T2,
- class = decltype(TraceValue::TypeCheck<T1>::value &&
- TraceValue::TypeCheck<T2>::value)>
- TraceArguments(const char* arg1_name,
- T1&& arg1_value,
- const char* arg2_name,
- T2&& arg2_value)
- : size_(2) {
- types_[0] = TraceValue::TypeFor<T1>::value;
- types_[1] = TraceValue::TypeFor<T2>::value;
- names_[0] = arg1_name;
- names_[1] = arg2_name;
- values_[0].Init(std::forward<T1>(arg1_value));
- values_[1].Init(std::forward<T2>(arg2_value));
- }
-
-
- TraceArguments(int num_args,
- const char* const* arg_names,
- const unsigned char* arg_types,
- const unsigned long long* arg_values);
-
-
- template <typename CONVERTABLE_TYPE>
- TraceArguments(int num_args,
- const char* const* arg_names,
- const unsigned char* arg_types,
- const unsigned long long* arg_values,
- CONVERTABLE_TYPE* arg_convertables) {
- static int max_args = static_cast<int>(kMaxSize);
- if (num_args > max_args)
- num_args = max_args;
- size_ = static_cast<unsigned char>(num_args);
- for (size_t n = 0; n < size_; ++n) {
- types_[n] = arg_types[n];
- names_[n] = arg_names[n];
- if (arg_types[n] == TRACE_VALUE_TYPE_CONVERTABLE) {
- values_[n].Init(
- std::forward<CONVERTABLE_TYPE>(std::move(arg_convertables[n])));
- } else {
- values_[n].as_uint = arg_values[n];
- }
- }
- }
-
- ~TraceArguments() {
- for (size_t n = 0; n < size_; ++n) {
- if (types_[n] == TRACE_VALUE_TYPE_CONVERTABLE)
- delete values_[n].as_convertable;
- }
- }
-
- TraceArguments(const TraceArguments&) = delete;
- TraceArguments& operator=(const TraceArguments&) = delete;
-
- TraceArguments(TraceArguments&& other) noexcept {
- ::memcpy(this, &other, sizeof(*this));
-
-
- other.size_ = 0;
- }
- TraceArguments& operator=(TraceArguments&&) noexcept;
-
- size_t size() const { return size_; }
- const unsigned char* types() const { return types_; }
- const char* const* names() const { return names_; }
- const TraceValue* values() const { return values_; }
-
- void Reset();
-
-
-
-
-
-
- void CopyStringsTo(StringStorage* storage,
- bool copy_all_strings,
- const char** extra_string1,
- const char** extra_string2);
-
- void AppendDebugString(std::string* out);
- private:
- unsigned char size_;
- unsigned char types_[kMaxSize];
- const char* names_[kMaxSize];
- TraceValue values_[kMaxSize];
- };
- }
- }
- #endif
|