1 // Copyright (c) 2012 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 #include "chrome/test/chromedriver/chrome/log.h" 6 7 #include "base/json/json_reader.h" 8 #include "base/json/json_writer.h" 9 #include "base/strings/string_util.h" 10 #include "base/values.h" 11 12 void Log::AddEntry(Level level, const std::string& message) { 13 AddEntry(level, "", message); 14 } 15 16 void Log::AddEntry(Level level, 17 const std::string& source, 18 const std::string& message) { 19 AddEntryTimestamped(base::Time::Now(), level, source, message); 20 } 21 22 namespace { 23 24 IsVLogOnFunc g_is_vlog_on_func = NULL; 25 26 void TruncateString(std::string* data) { 27 const size_t kMaxLength = 200; 28 if (data->length() > kMaxLength) { 29 data->resize(kMaxLength); 30 data->replace(kMaxLength - 3, 3, "..."); 31 } 32 } 33 34 scoped_ptr<base::Value> SmartDeepCopy(const base::Value* value) { 35 const size_t kMaxChildren = 20; 36 const base::ListValue* list = NULL; 37 const base::DictionaryValue* dict = NULL; 38 std::string data; 39 if (value->GetAsDictionary(&dict)) { 40 scoped_ptr<base::DictionaryValue> dict_copy(new base::DictionaryValue()); 41 for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd(); 42 it.Advance()) { 43 if (dict_copy->size() >= kMaxChildren - 1) { 44 dict_copy->SetStringWithoutPathExpansion("~~~", "..."); 45 break; 46 } 47 const base::Value* child = NULL; 48 dict->GetWithoutPathExpansion(it.key(), &child); 49 dict_copy->SetWithoutPathExpansion(it.key(), 50 SmartDeepCopy(child).release()); 51 } 52 return dict_copy.PassAs<base::Value>(); 53 } else if (value->GetAsList(&list)) { 54 scoped_ptr<base::ListValue> list_copy(new base::ListValue()); 55 for (size_t i = 0; i < list->GetSize(); ++i) { 56 const base::Value* child = NULL; 57 if (!list->Get(i, &child)) 58 continue; 59 if (list_copy->GetSize() >= kMaxChildren - 1) { 60 list_copy->AppendString("..."); 61 break; 62 } 63 list_copy->Append(SmartDeepCopy(child).release()); 64 } 65 return list_copy.PassAs<base::Value>(); 66 } else if (value->GetAsString(&data)) { 67 TruncateString(&data); 68 return scoped_ptr<base::Value>(new base::StringValue(data)); 69 } 70 return scoped_ptr<base::Value>(value->DeepCopy()); 71 } 72 73 } // namespace 74 75 void InitLogging(IsVLogOnFunc is_vlog_on_func) { 76 g_is_vlog_on_func = is_vlog_on_func; 77 } 78 79 bool IsVLogOn(int vlog_level) { 80 if (!g_is_vlog_on_func) 81 return false; 82 return g_is_vlog_on_func(vlog_level); 83 } 84 85 std::string PrettyPrintValue(const base::Value& value) { 86 std::string json; 87 base::JSONWriter::WriteWithOptions( 88 &value, base::JSONWriter::OPTIONS_PRETTY_PRINT, &json); 89 #if defined(OS_WIN) 90 base::RemoveChars(json, "\r", &json); 91 #endif 92 // Remove the trailing newline. 93 if (json.length()) 94 json.resize(json.length() - 1); 95 return json; 96 } 97 98 std::string FormatValueForDisplay(const base::Value& value) { 99 scoped_ptr<base::Value> copy(SmartDeepCopy(&value)); 100 return PrettyPrintValue(*copy); 101 } 102 103 std::string FormatJsonForDisplay(const std::string& json) { 104 scoped_ptr<base::Value> value(base::JSONReader::Read(json)); 105 if (!value) 106 value.reset(new base::StringValue(json)); 107 return FormatValueForDisplay(*value); 108 } 109