1 // Copyright (c) 2013 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/browser/devtools/devtools_protocol.h" 6 7 #include "base/json/json_reader.h" 8 #include "base/json/json_writer.h" 9 #include "base/strings/stringprintf.h" 10 11 namespace { 12 13 const char kErrorCodeParam[] = "code"; 14 const char kErrorParam[] = "error"; 15 const char kErrorMessageParam[] = "message"; 16 const char kIdParam[] = "id"; 17 const char kMethodParam[] = "method"; 18 const char kParamsParam[] = "params"; 19 const char kResultParam[] = "result"; 20 21 // JSON RPC 2.0 spec: http://www.jsonrpc.org/specification#error_object 22 enum Error { 23 kErrorInvalidParams = -32602 24 }; 25 26 } // namespace 27 28 DevToolsProtocol::Message::~Message() { 29 } 30 31 DevToolsProtocol::Message::Message(const std::string& method, 32 base::DictionaryValue* params) 33 : method_(method), 34 params_(params ? params->DeepCopy() : NULL) { 35 } 36 37 DevToolsProtocol::Command::Command(int id, 38 const std::string& method, 39 base::DictionaryValue* params) 40 : Message(method, params), 41 id_(id) { 42 } 43 44 DevToolsProtocol::Command::~Command() { 45 } 46 47 std::string DevToolsProtocol::Command::Serialize() { 48 base::DictionaryValue command; 49 command.SetInteger(kIdParam, id_); 50 command.SetString(kMethodParam, method_); 51 if (params_) 52 command.Set(kParamsParam, params_->DeepCopy()); 53 54 std::string json_command; 55 base::JSONWriter::Write(&command, &json_command); 56 return json_command; 57 } 58 59 scoped_ptr<DevToolsProtocol::Response> 60 DevToolsProtocol::Command::SuccessResponse(base::DictionaryValue* result) { 61 return scoped_ptr<DevToolsProtocol::Response>( 62 new DevToolsProtocol::Response(id_, result)); 63 } 64 65 scoped_ptr<DevToolsProtocol::Response> 66 DevToolsProtocol::Command::InvalidParamResponse(const std::string& param) { 67 std::string message = 68 base::StringPrintf("Missing or invalid '%s' parameter", param.c_str()); 69 return scoped_ptr<DevToolsProtocol::Response>( 70 new DevToolsProtocol::Response(id_, kErrorInvalidParams, message)); 71 } 72 73 DevToolsProtocol::Notification::~Notification() { 74 } 75 76 DevToolsProtocol::Notification::Notification(const std::string& method, 77 base::DictionaryValue* params) 78 : Message(method, params) { 79 } 80 81 DevToolsProtocol::Response::~Response() { 82 } 83 84 DevToolsProtocol::Response::Response(int id, 85 int error_code, 86 const std::string error_message) 87 : id_(id), 88 error_code_(error_code), 89 error_message_(error_message) { 90 } 91 92 DevToolsProtocol::Response::Response(int id, base::DictionaryValue* result) 93 : id_(id), 94 error_code_(0), 95 result_(result) { 96 } 97 98 base::DictionaryValue* DevToolsProtocol::Response::Serialize() { 99 base::DictionaryValue* response = new base::DictionaryValue(); 100 101 response->SetInteger(kIdParam, id_); 102 103 if (error_code_) { 104 base::DictionaryValue* error_object = new base::DictionaryValue(); 105 response->Set(kErrorParam, error_object); 106 error_object->SetInteger(kErrorCodeParam, error_code_); 107 if (!error_message_.empty()) 108 error_object->SetString(kErrorMessageParam, error_message_); 109 } else { 110 if (result_) 111 response->Set(kResultParam, result_->DeepCopy()); 112 else 113 response->Set(kResultParam, new base::DictionaryValue()); 114 } 115 116 return response; 117 } 118 119 // static 120 DevToolsProtocol::Command* DevToolsProtocol::ParseCommand( 121 base::DictionaryValue* command_dict) { 122 if (!command_dict) 123 return NULL; 124 125 int id; 126 if (!command_dict->GetInteger(kIdParam, &id) || id < 0) 127 return NULL; 128 129 std::string method; 130 if (!command_dict->GetString(kMethodParam, &method)) 131 return NULL; 132 133 base::DictionaryValue* params = NULL; 134 command_dict->GetDictionary(kParamsParam, ¶ms); 135 return new Command(id, method, params); 136 } 137 138 // static 139 DevToolsProtocol::Notification* DevToolsProtocol::ParseNotification( 140 const std::string& json) { 141 scoped_ptr<base::Value> value(base::JSONReader::Read(json)); 142 if (!value || !value->IsType(base::Value::TYPE_DICTIONARY)) 143 return NULL; 144 145 scoped_ptr<base::DictionaryValue> dict( 146 static_cast<base::DictionaryValue*>(value.release())); 147 148 std::string method; 149 if (!dict->GetString(kMethodParam, &method)) 150 return NULL; 151 152 base::DictionaryValue* params = NULL; 153 dict->GetDictionary(kParamsParam, ¶ms); 154 return new Notification(method, params); 155 } 156 157 DevToolsProtocol::Response* DevToolsProtocol::ParseResponse( 158 const std::string& json) { 159 scoped_ptr<base::Value> value(base::JSONReader::Read(json)); 160 if (!value || !value->IsType(base::Value::TYPE_DICTIONARY)) 161 return NULL; 162 163 scoped_ptr<base::DictionaryValue> dict( 164 static_cast<base::DictionaryValue*>(value.release())); 165 166 int id; 167 if (!dict->GetInteger(kIdParam, &id)) 168 return NULL; 169 170 int error_code = 0; 171 base::DictionaryValue* error_dict = NULL; 172 if (dict->GetDictionary(kErrorParam, &error_dict)) 173 error_dict->GetInteger(kErrorCodeParam, &error_code); 174 return new Response(id, error_code, std::string()); 175 } 176