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

Side by Side Diff: device/nfc/nfc_ndef_record.cc

Issue 2292703002: chromeos: Remove unused NFC D-Bus client library (Closed)
Patch Set: rebase Created 4 years, 3 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
« no previous file with comments | « device/nfc/nfc_ndef_record.h ('k') | device/nfc/nfc_ndef_record_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 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 "device/nfc/nfc_ndef_record.h"
6
7 #include <stddef.h>
8 #include <stdint.h>
9
10 #include <map>
11
12 #include "base/logging.h"
13 #include "url/gurl.h"
14
15 using base::DictionaryValue;
16 using base::ListValue;
17
18 namespace device {
19
20 namespace {
21
22 typedef std::map<std::string, base::Value::Type> FieldValueMap;
23
24 bool ValidateURI(const DictionaryValue* data) {
25 std::string uri;
26 if (!data->GetString(NfcNdefRecord::kFieldURI, &uri)) {
27 VLOG(1) << "No URI entry in data.";
28 return false;
29 }
30 DCHECK(!uri.empty());
31
32 // Use GURL to check validity.
33 GURL url(uri);
34 if (!url.is_valid()) {
35 LOG(ERROR) << "Invalid URI given: " << uri;
36 return false;
37 }
38 return true;
39 }
40
41 bool CheckFieldsAreValid(
42 const FieldValueMap& required_fields,
43 const FieldValueMap& optional_fields,
44 const DictionaryValue* data) {
45 size_t required_count = 0;
46 for (DictionaryValue::Iterator iter(*data);
47 !iter.IsAtEnd(); iter.Advance()) {
48 FieldValueMap::const_iterator field_iter =
49 required_fields.find(iter.key());
50 if (field_iter == required_fields.end()) {
51 // Field wasn't one of the required fields. Check if optional.
52 field_iter = optional_fields.find(iter.key());
53
54 if (field_iter == optional_fields.end()) {
55 // If the field isn't one of the optional fields either, then it's
56 // invalid.
57 VLOG(1) << "Tried to populate record with invalid field: "
58 << iter.key();
59 return false;
60 }
61 } else {
62 required_count++;
63 }
64 // The field is invalid, if the type of its value is incorrect.
65 if (field_iter->second != iter.value().GetType()) {
66 VLOG(1) << "Provided value for field \"" << iter.key() << "\" has type "
67 << iter.value().GetType() << ", expected: "
68 << field_iter->second;
69 return false;
70 }
71 // Make sure that the value is non-empty, if the value is a string.
72 std::string string_value;
73 if (iter.value().GetAsString(&string_value) && string_value.empty()) {
74 VLOG(1) << "Empty value given for field of type string: " << iter.key();
75 return false;
76 }
77 }
78 // Check for required fields.
79 if (required_count != required_fields.size()) {
80 VLOG(1) << "Provided data did not contain all required fields for "
81 << "requested NDEF type.";
82 return false;
83 }
84 return true;
85 }
86
87 // Verifies that the contents of |data| conform to the fields of NDEF type
88 // "Text".
89 bool HandleTypeText(const DictionaryValue* data) {
90 VLOG(1) << "Populating record with type \"Text\".";
91 FieldValueMap required_fields;
92 required_fields[NfcNdefRecord::kFieldText] = base::Value::TYPE_STRING;
93 required_fields[NfcNdefRecord::kFieldEncoding] = base::Value::TYPE_STRING;
94 required_fields[NfcNdefRecord::kFieldLanguageCode] = base::Value::TYPE_STRING;
95 FieldValueMap optional_fields;
96 if (!CheckFieldsAreValid(required_fields, optional_fields, data)) {
97 VLOG(1) << "Failed to populate record.";
98 return false;
99 }
100
101 // Verify that the "Encoding" property has valid values.
102 std::string encoding;
103 if (!data->GetString(NfcNdefRecord::kFieldEncoding, &encoding)) {
104 if (encoding != NfcNdefRecord::kEncodingUtf8 ||
105 encoding != NfcNdefRecord::kEncodingUtf16) {
106 VLOG(1) << "Invalid \"Encoding\" value:" << encoding;
107 return false;
108 }
109 }
110 return true;
111 }
112
113 // Verifies that the contents of |data| conform to the fields of NDEF type
114 // "SmartPoster".
115 bool HandleTypeSmartPoster(const DictionaryValue* data) {
116 VLOG(1) << "Populating record with type \"SmartPoster\".";
117 FieldValueMap required_fields;
118 required_fields[NfcNdefRecord::kFieldURI] = base::Value::TYPE_STRING;
119 FieldValueMap optional_fields;
120 optional_fields[NfcNdefRecord::kFieldAction] = base::Value::TYPE_STRING;
121 optional_fields[NfcNdefRecord::kFieldMimeType] = base::Value::TYPE_STRING;
122 // base::Value restricts the number types to BOOL, INTEGER, and DOUBLE only.
123 // uint32_t will automatically get converted to a double. "target size" is
124 // really a uint32_t but we define it as a double for this reason.
125 // (See dbus/values_util.h).
126 optional_fields[NfcNdefRecord::kFieldTargetSize] = base::Value::TYPE_DOUBLE;
127 optional_fields[NfcNdefRecord::kFieldTitles] = base::Value::TYPE_LIST;
128 if (!CheckFieldsAreValid(required_fields, optional_fields, data)) {
129 VLOG(1) << "Failed to populate record.";
130 return false;
131 }
132 // Verify that the "titles" field was formatted correctly, if it exists.
133 const ListValue* titles = NULL;
134 if (data->GetList(NfcNdefRecord::kFieldTitles, &titles)) {
135 if (titles->empty()) {
136 VLOG(1) << "\"titles\" field of SmartPoster is empty.";
137 return false;
138 }
139 for (ListValue::const_iterator iter = titles->begin();
140 iter != titles->end(); ++iter) {
141 const DictionaryValue* title_data = NULL;
142 if (!(*iter)->GetAsDictionary(&title_data)) {
143 VLOG(1) << "\"title\" entry for SmartPoster contains an invalid value "
144 << "type";
145 return false;
146 }
147 if (!HandleTypeText(title_data)) {
148 VLOG(1) << "Badly formatted \"title\" entry for SmartPoster.";
149 return false;
150 }
151 }
152 }
153 return ValidateURI(data);
154 }
155
156 // Verifies that the contents of |data| conform to the fields of NDEF type
157 // "URI".
158 bool HandleTypeUri(const DictionaryValue* data) {
159 VLOG(1) << "Populating record with type \"URI\".";
160 FieldValueMap required_fields;
161 required_fields[NfcNdefRecord::kFieldURI] = base::Value::TYPE_STRING;
162 FieldValueMap optional_fields;
163 optional_fields[NfcNdefRecord::kFieldMimeType] = base::Value::TYPE_STRING;
164 optional_fields[NfcNdefRecord::kFieldTargetSize] = base::Value::TYPE_DOUBLE;
165
166 // Allow passing TargetSize as an integer, but convert it to a double.
167 if (!CheckFieldsAreValid(required_fields, optional_fields, data)) {
168 VLOG(1) << "Failed to populate record.";
169 return false;
170 }
171 return ValidateURI(data);
172 }
173
174 } // namespace
175
176 // static
177 const char NfcNdefRecord::kFieldEncoding[] = "encoding";
178 // static
179 const char NfcNdefRecord::kFieldLanguageCode[] = "languageCode";
180 // static
181 const char NfcNdefRecord::kFieldText[] = "text";
182 // static
183 const char NfcNdefRecord::kFieldURI[] = "uri";
184 // static
185 const char NfcNdefRecord::kFieldMimeType[] = "mimeType";
186 // static
187 const char NfcNdefRecord::kFieldTargetSize[] = "targetSize";
188 // static
189 const char NfcNdefRecord::kFieldTitles[] = "titles";
190 // static
191 const char NfcNdefRecord::kFieldAction[] = "action";
192 // static
193 const char NfcNdefRecord::kEncodingUtf8[] = "UTF-8";
194 // static
195 const char NfcNdefRecord::kEncodingUtf16[] = "UTF-16";
196 // static
197 const char NfcNdefRecord::kSmartPosterActionDo[] = "do";
198 // static
199 const char NfcNdefRecord::kSmartPosterActionSave[] = "save";
200 // static
201 const char NfcNdefRecord::kSmartPosterActionOpen[] = "open";
202
203 NfcNdefRecord::NfcNdefRecord() : type_(kTypeUnknown) {
204 }
205
206 NfcNdefRecord::~NfcNdefRecord() {
207 }
208
209 bool NfcNdefRecord::IsPopulated() const {
210 return type_ != kTypeUnknown;
211 }
212
213 bool NfcNdefRecord::Populate(Type type, const DictionaryValue* data) {
214 if (IsPopulated())
215 return false;
216
217 DCHECK(data_.empty());
218
219 // At this time, only "Text", "URI", and "SmartPoster" are supported.
220 bool result = false;
221 switch (type) {
222 case kTypeText:
223 result = HandleTypeText(data);
224 break;
225 case kTypeSmartPoster:
226 result = HandleTypeSmartPoster(data);
227 break;
228 case kTypeURI:
229 result = HandleTypeUri(data);
230 break;
231 default:
232 VLOG(1) << "Unsupported NDEF type: " << type;
233 break;
234 }
235 if (!result)
236 return false;
237 type_ = type;
238 data_.MergeDictionary(data);
239 return true;
240 }
241
242 NfcNdefMessage::NfcNdefMessage() {
243 }
244
245 NfcNdefMessage::~NfcNdefMessage() {
246 }
247
248 void NfcNdefMessage::AddRecord(NfcNdefRecord* record) {
249 records_.push_back(record);
250 }
251
252 bool NfcNdefMessage::RemoveRecord(NfcNdefRecord* record) {
253 for (RecordList::iterator iter = records_.begin();
254 iter != records_.end(); ++iter) {
255 if (*iter == record) {
256 records_.erase(iter);
257 return true;
258 }
259 }
260 return false;
261 }
262
263 } // namespace device
OLDNEW
« no previous file with comments | « device/nfc/nfc_ndef_record.h ('k') | device/nfc/nfc_ndef_record_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698