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

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: Created 6 years, 2 months 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_number_conversions.h"
9 #include "base/values.h"
10
11 namespace {
12
13 static const char* kAnswerJsonLines = "l";
14 static const char* kAnswerJsonImageLine = "il";
15 static const char* kAnswerJsonText = "t";
16 static const char* kAnswerJsonAdditionalText = "at";
17 static const char* kAnswerJsonStatusText = "st";
18 static const char* kAnswerJsonTextType = "tt";
19 static const char* kAnswerJsonImage = "i";
20 static const char* kAnswerJsonImageData = "i.d";
21
22 }
23
24 // SuggestionAnswer::TextField -------------------------------------------------
25
26 SuggestionAnswer::TextField::TextField() {}
27 SuggestionAnswer::TextField::~TextField() {}
28
29 // static
30 bool SuggestionAnswer::TextField::ParseTextField(
31 const base::DictionaryValue* field_json, TextField* text_field) {
32 if (!field_json->GetString(kAnswerJsonText, &text_field->text_) ||
33 text_field->text_.empty())
34 return false;
35 if (!field_json->GetInteger(kAnswerJsonTextType, &text_field->type_))
36 return false;
37 return true;
38 }
39
40 bool SuggestionAnswer::TextField::operator==(const TextField& field) const {
41 return type_ == field.type_ && text_ == field.text_;
42 }
43
44 bool SuggestionAnswer::TextField::operator!=(const TextField& field) const {
45 return !operator==(field);
46 }
47
48 void SuggestionAnswer::TextField::Clear() {
49 text_.clear();
50 type_ = 0;
51 }
52
53 // SuggestionAnswer::ImageLine -------------------------------------------------
54
55 SuggestionAnswer::ImageLine::ImageLine() {}
56 SuggestionAnswer::ImageLine::~ImageLine() {}
57
58 // static
59 bool SuggestionAnswer::ImageLine::ParseImageLine(
60 const base::DictionaryValue* line_json, ImageLine* image_line) {
61 const base::DictionaryValue* inner_json;
62 if (!line_json->GetDictionary(kAnswerJsonImageLine, &inner_json))
63 return false;
64
65 const base::ListValue* fields_json;
66 if (!inner_json->GetList(kAnswerJsonText, &fields_json) ||
67 fields_json->GetSize() == 0)
68 return false;
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 !TextField::ParseTextField(field_json, &text_field))
75 return false;
76 image_line->text_fields_.push_back(text_field);
77 }
78
79 if (inner_json->HasKey(kAnswerJsonAdditionalText)) {
80 const base::DictionaryValue* field_json;
81 if (!inner_json->GetDictionary(kAnswerJsonAdditionalText, &field_json) ||
82 !TextField::ParseTextField(field_json, &image_line->additional_text_))
83 return false;
84 }
85
86 if (inner_json->HasKey(kAnswerJsonStatusText)) {
87 const base::DictionaryValue* field_json;
88 if (!inner_json->GetDictionary(kAnswerJsonStatusText, &field_json) ||
89 !TextField::ParseTextField(field_json, &image_line->status_text_))
90 return false;
91 }
92
93 if (inner_json->HasKey(kAnswerJsonImage)) {
94 std::string url_string;
95 if (!inner_json->GetString(kAnswerJsonImageData, &url_string) ||
96 url_string.empty())
97 return false;
98 // Concatenate scheme and host/path using only ':' as separator. This is
99 // due to the results delivering strings of the form '//host/path', which
100 // is web-speak for "use the enclosing page's scheme", but not a valid path
101 // of an URL.
102 GURL url("https:" + url_string);
103 if (!url.is_valid())
104 return false;
105 image_line->image_url_ = url;
106 }
107
108 return true;
109 }
110
111 bool SuggestionAnswer::ImageLine::operator==(const ImageLine& line) const {
112 if (text_fields_.size() != line.text_fields_.size())
113 return false;
114 for (size_t i = 0; i < text_fields_.size(); ++i) {
115 if (text_fields_[i] != line.text_fields_[i])
116 return false;
117 }
118 return additional_text_ == line.additional_text_ &&
119 status_text_ == line.status_text_ &&
120 image_url_ == line.image_url_;
121 }
122
123 bool SuggestionAnswer::ImageLine::operator!=(const ImageLine& line) const {
124 return !operator==(line);
125 }
126
127 bool SuggestionAnswer::ImageLine::HasImageURL() const {
128 // If no URL was present in the source JSON then image_url_ will never be set
129 // and the default value of is_valid() is false.
130 return image_url_.is_valid();
131 }
132
133 void SuggestionAnswer::ImageLine::Clear() {
134 text_fields_.clear();
135 additional_text_.Clear();
136 status_text_.Clear();
137 image_url_ = GURL();
138 }
139
140 // SuggestionAnswer ------------------------------------------------------------
141
142 SuggestionAnswer::SuggestionAnswer() : type_(0), is_valid_(false) {}
143 SuggestionAnswer::~SuggestionAnswer() {}
144
145 // static
146 bool SuggestionAnswer::ParseAnswer(
147 const std::string& answer_json, SuggestionAnswer* answer) {
148 scoped_ptr<base::Value> value(base::JSONReader::Read(answer_json));
149 base::DictionaryValue* dict;
150 if (!value.get() || !value->GetAsDictionary(&dict))
151 return false;
152
153 return ParseAnswer(dict, answer);
154 }
155
156 // static
157 bool SuggestionAnswer::ParseAnswer(
158 const base::DictionaryValue* answer_json, SuggestionAnswer* answer) {
159 answer->Clear();
160 const base::ListValue* lines_json;
161 if (!answer_json->GetList(kAnswerJsonLines, &lines_json) ||
162 lines_json->GetSize() != 2)
163 return false;
164
165 const base::DictionaryValue* first_line_json;
166 if (!lines_json->GetDictionary(0, &first_line_json) ||
167 !ImageLine::ParseImageLine(first_line_json, &answer->first_line_))
168 return false;
169 const base::DictionaryValue* second_line_json;
170 if (!lines_json->GetDictionary(1, &second_line_json) ||
171 !ImageLine::ParseImageLine(second_line_json, &answer->second_line_))
172 return false;
173
174 answer->is_valid_ = true;
175
176 return true;
177 }
178
179 bool SuggestionAnswer::operator==(const SuggestionAnswer& answer) const {
180 return is_valid_ == answer.is_valid_ &&
181 type_ == answer.type_ &&
182 first_line_ == answer.first_line_ &&
183 second_line_ == answer.second_line_;
184 }
185
186 bool SuggestionAnswer::operator!=(const SuggestionAnswer& answer) const {
187 return !operator==(answer);
188 }
189
190 void SuggestionAnswer::SetType(const base::string16& type) {
191 if (!base::StringToInt(type, &type_))
192 type_ = 0;
193 }
194
195 void SuggestionAnswer::Clear() {
196 first_line_.Clear();
197 second_line_.Clear();
198 type_ = 0;
199 is_valid_ = false;
200 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698