Home | History | Annotate | Download | only in devtools
      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, &params);
    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, &params);
    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