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 if (result_) { 110 response->Set(kResultParam, result_->DeepCopy()); 111 } 112 113 return response; 114 } 115 116 // static 117 DevToolsProtocol::Command* DevToolsProtocol::ParseCommand( 118 base::DictionaryValue* command_dict) { 119 if (!command_dict) 120 return NULL; 121 122 int id; 123 if (!command_dict->GetInteger(kIdParam, &id) || id < 0) 124 return NULL; 125 126 std::string method; 127 if (!command_dict->GetString(kMethodParam, &method)) 128 return NULL; 129 130 base::DictionaryValue* params = NULL; 131 command_dict->GetDictionary(kParamsParam, ¶ms); 132 return new Command(id, method, params); 133 } 134 135 // static 136 DevToolsProtocol::Notification* DevToolsProtocol::ParseNotification( 137 const std::string& json) { 138 scoped_ptr<base::Value> value(base::JSONReader::Read(json)); 139 if (!value || !value->IsType(base::Value::TYPE_DICTIONARY)) 140 return NULL; 141 142 scoped_ptr<base::DictionaryValue> dict( 143 static_cast<base::DictionaryValue*>(value.release())); 144 145 std::string method; 146 if (!dict->GetString(kMethodParam, &method)) 147 return NULL; 148 149 base::DictionaryValue* params = NULL; 150 dict->GetDictionary(kParamsParam, ¶ms); 151 return new Notification(method, params); 152 } 153 154 DevToolsProtocol::Response* DevToolsProtocol::ParseResponse( 155 const std::string& json) { 156 scoped_ptr<base::Value> value(base::JSONReader::Read(json)); 157 if (!value || !value->IsType(base::Value::TYPE_DICTIONARY)) 158 return NULL; 159 160 scoped_ptr<base::DictionaryValue> dict( 161 static_cast<base::DictionaryValue*>(value.release())); 162 163 int id; 164 if (!dict->GetInteger(kIdParam, &id)) 165 return NULL; 166 167 int error_code = 0; 168 base::DictionaryValue* error_dict = NULL; 169 if (dict->GetDictionary(kErrorParam, &error_dict)) 170 error_dict->GetInteger(kErrorCodeParam, &error_code); 171 return new Response(id, error_code, std::string()); 172 } 173