Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(68)

Side by Side Diff: components/omnibox/suggestion_answer.cc

Issue 669573005: Add a class to parse answer json. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Sync and respond to comments Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2014 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 "components/omnibox/suggestion_answer.h"
6
7 #include "base/json/json_reader.h"
8 #include "base/strings/string_util.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "base/values.h"
11 #include "url/url_constants.h"
12
13 namespace {
14
15 // All of these are defined here (even though they're only used once each) so
16 // the format details are easy to locate and update or compare to the spec doc.
17 static const char* kAnswerJsonLines = "l";
18 static const char* kAnswerJsonImageLine = "il";
19 static const char* kAnswerJsonText = "t";
20 static const char* kAnswerJsonAdditionalText = "at";
21 static const char* kAnswerJsonStatusText = "st";
22 static const char* kAnswerJsonTextType = "tt";
23 static const char* kAnswerJsonImage = "i";
24 static const char* kAnswerJsonImageData = "i.d";
25
26 } // namespace
27
28 // SuggestionAnswer::TextField -------------------------------------------------
29
30 SuggestionAnswer::TextField::TextField() : type_(-1) {}
31 SuggestionAnswer::TextField::~TextField() {}
32
33 // static
34 void SuggestionAnswer::TextField::ParseTextField(
35 const base::DictionaryValue* field_json, TextField* text_field) {
36 if (!field_json->GetString(kAnswerJsonText, &text_field->text_) ||
37 text_field->text_.empty())
38 return;
39 field_json->GetInteger(kAnswerJsonTextType, &text_field->type_);
40 }
41
42 bool SuggestionAnswer::TextField::Equals(const TextField& field) const {
43 return type_ == field.type_ && text_ == field.text_;
44 }
45
46 void SuggestionAnswer::TextField::Clear() {
47 text_.clear();
48 type_ = -1;
49 }
50
51 // SuggestionAnswer::ImageLine -------------------------------------------------
52
53 SuggestionAnswer::ImageLine::ImageLine() : is_valid_(false) {}
54 SuggestionAnswer::ImageLine::~ImageLine() {}
55
56 // static
57 void SuggestionAnswer::ImageLine::ParseImageLine(
58 const base::DictionaryValue* line_json, ImageLine* image_line) {
59 image_line->is_valid_ = false;
60
61 const base::DictionaryValue* inner_json;
62 if (!line_json->GetDictionary(kAnswerJsonImageLine, &inner_json))
63 return;
64
65 const base::ListValue* fields_json;
66 if (!inner_json->GetList(kAnswerJsonText, &fields_json) ||
67 fields_json->GetSize() == 0)
68 return;
69
70 for (size_t i = 0; i < fields_json->GetSize(); ++i) {
71 const base::DictionaryValue* field_json;
72 TextField text_field;
73 if (!fields_json->GetDictionary(i, &field_json))
74 return;
75 TextField::ParseTextField(field_json, &text_field);
76 if (!text_field.is_valid())
77 return;
78 image_line->text_fields_.push_back(text_field);
79 }
80
81 if (inner_json->HasKey(kAnswerJsonAdditionalText)) {
82 const base::DictionaryValue* field_json;
83 if (!inner_json->GetDictionary(kAnswerJsonAdditionalText, &field_json))
84 return;
85 TextField::ParseTextField(field_json, &image_line->additional_text_);
86 if (!image_line->additional_text_.is_valid())
87 return;
88 }
89
90 if (inner_json->HasKey(kAnswerJsonStatusText)) {
91 const base::DictionaryValue* field_json;
92 if (!inner_json->GetDictionary(kAnswerJsonStatusText, &field_json))
93 return;
94 TextField::ParseTextField(field_json, &image_line->status_text_);
95 if (!image_line->status_text_.is_valid())
96 return;
97 }
98
99 if (inner_json->HasKey(kAnswerJsonImage)) {
100 base::string16 url_string;
101 if (!inner_json->GetString(kAnswerJsonImageData, &url_string) ||
102 url_string.empty())
103 return;
104 // If necessary, concatenate scheme and host/path using only ':' as
105 // separator. This is due to the results delivering strings of the form
106 // "//host/path", which is web-speak for "use the enclosing page's scheme",
107 // but not a valid path of an URL. The GWS frontend commonly (always?)
108 // redirects to HTTPS so we just default to that here.
109 image_line->image_url_ = GURL(
110 StartsWith(url_string, base::ASCIIToUTF16("//"), false) ?
111 (base::ASCIIToUTF16(url::kHttpsScheme) + base::ASCIIToUTF16(":") +
112 url_string) :
113 url_string);
114
115 if (!image_line->image_url_.is_valid())
116 return;
117 }
118
119 image_line->is_valid_ = true;
120 }
121
122 bool SuggestionAnswer::ImageLine::Equals(const ImageLine& line) const {
123 if (text_fields_.size() != line.text_fields_.size())
124 return false;
125 for (size_t i = 0; i < text_fields_.size(); ++i) {
126 if (!text_fields_[i].Equals(line.text_fields_[i]))
127 return false;
128 }
129 return additional_text_.Equals(line.additional_text_) &&
130 status_text_.Equals(line.status_text_) &&
131 image_url_ == line.image_url_;
132 }
133
134 void SuggestionAnswer::ImageLine::Clear() {
135 text_fields_.clear();
136 additional_text_.Clear();
137 status_text_.Clear();
138 image_url_ = GURL();
139 is_valid_ = false;
140 }
141
142 // SuggestionAnswer ------------------------------------------------------------
143
144 SuggestionAnswer::SuggestionAnswer() : type_(-1) {}
145 SuggestionAnswer::~SuggestionAnswer() {}
146
147 // static
148 void SuggestionAnswer::ParseAnswer(
149 const std::string& answer_json, SuggestionAnswer* answer) {
150 scoped_ptr<base::Value> value(base::JSONReader::Read(answer_json));
151 base::DictionaryValue* dict;
152 if (!value.get() || !value->GetAsDictionary(&dict))
153 return;
154
155 ParseAnswer(dict, answer);
156 }
157
158 // static
159 void SuggestionAnswer::ParseAnswer(
160 const base::DictionaryValue* answer_json, SuggestionAnswer* answer) {
161 const base::ListValue* lines_json;
162 if (!answer_json->GetList(kAnswerJsonLines, &lines_json) ||
163 lines_json->GetSize() != 2)
164 return;
165
166 const base::DictionaryValue* first_line_json;
167 if (!lines_json->GetDictionary(0, &first_line_json)) {
168 answer->Clear();
169 return;
170 }
171 ImageLine::ParseImageLine(first_line_json, &answer->first_line_);
172 if (!answer->first_line_.is_valid()) {
173 answer->Clear();
174 return;
175 }
176
177 const base::DictionaryValue* second_line_json;
178 if (!lines_json->GetDictionary(1, &second_line_json)) {
179 answer->Clear();
180 return;
181 }
182 ImageLine::ParseImageLine(second_line_json, &answer->second_line_);
183 if (!answer->second_line_.is_valid()) {
184 answer->Clear();
185 return;
186 }
187 }
188
189 bool SuggestionAnswer::Equals(const SuggestionAnswer& answer) const {
190 return type_ == answer.type_ &&
191 first_line_.Equals(answer.first_line_) &&
192 second_line_.Equals(answer.second_line_);
193 }
194
195 void SuggestionAnswer::Clear() {
196 first_line_.Clear();
197 second_line_.Clear();
198 type_ = -1;
199 }
200
201 void SuggestionAnswer::GetImageURLs(std::vector<GURL>* urls) const {
202 urls->clear();
203
204 if (!is_valid())
205 return;
206
207 if (first_line_.has_image_url())
208 urls->push_back(first_line_.image_url());
209 if (second_line_.has_image_url())
210 urls->push_back(second_line_.image_url());
211 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698