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

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

Issue 77563002: nfc: Add native NFC API definitions. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fixed clang error. Created 7 years 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 | Annotate | Revision Log
« 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 (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 "device/nfc/nfc_ndef_record.h"
6
7 #include <map>
8
9 #include "base/logging.h"
10
11 using base::DictionaryValue;
12 using base::ListValue;
13
14 namespace device {
15
16 namespace {
17
18 typedef std::map<std::string, base::Value::Type> FieldValueMap;
19
20 bool CheckFieldsAreValid(
21 const FieldValueMap& required_fields,
22 const FieldValueMap& optional_fields,
23 const DictionaryValue* data) {
24 size_t required_count = 0;
25 for (DictionaryValue::Iterator iter(*data);
26 !iter.IsAtEnd(); iter.Advance()) {
27 FieldValueMap::const_iterator field_iter =
28 required_fields.find(iter.key());
29 if (field_iter == required_fields.end()) {
30 // Field wasn't one of the required fields. Check if optional.
31 field_iter = optional_fields.find(iter.key());
32
33 if (field_iter == optional_fields.end()) {
34 // If the field isn't one of the optional fields either, then it's
35 // invalid.
36 VLOG(1) << "Tried to populate record with invalid field: "
37 << iter.key();
38 return false;
39 }
40 } else {
41 required_count++;
42 }
43 // The field is invalid, if the type of its value is incorrect.
44 if (field_iter->second != iter.value().GetType()) {
45 VLOG(1) << "Provided value for field \"" << iter.key() << "\" has type "
46 << iter.value().GetType() << ", expected: "
47 << field_iter->second;
48 return false;
49 }
50 }
51 // Check for required fields.
52 if (required_count != required_fields.size()) {
53 VLOG(1) << "Provided data did not contain all required fields for "
54 << "requested NDEF type.";
55 return false;
56 }
57 return true;
58 }
59
60 // Verifies that the contents of |data| conform to the fields of NDEF type
61 // "Text".
62 bool HandleTypeText(const DictionaryValue* data) {
63 VLOG(1) << "Populating record with type \"Text\".";
64 FieldValueMap required_fields;
65 required_fields[NfcNdefRecord::kFieldText] = base::Value::TYPE_STRING;
66 FieldValueMap optional_fields;
67 optional_fields[NfcNdefRecord::kFieldEncoding] = base::Value::TYPE_STRING;
68 optional_fields[NfcNdefRecord::kFieldLanguageCode] = base::Value::TYPE_STRING;
69 if (!CheckFieldsAreValid(required_fields, optional_fields, data)) {
70 VLOG(1) << "Failed to populate record.";
71 return false;
72 }
73 return true;
74 }
75
76 // Verifies that the contents of |data| conform to the fields of NDEF type
77 // "SmartPoster".
78 bool HandleTypeSmartPoster(const DictionaryValue* data) {
79 VLOG(1) << "Populating record with type \"SmartPoster\".";
80 FieldValueMap required_fields;
81 required_fields[NfcNdefRecord::kFieldURI] = base::Value::TYPE_STRING;
82 FieldValueMap optional_fields;
83 optional_fields[NfcNdefRecord::kFieldAction] = base::Value::TYPE_STRING;
84 optional_fields[NfcNdefRecord::kFieldMimeType] = base::Value::TYPE_STRING;
85 // base::Value restricts the number types to BOOL, INTEGER, and DOUBLE only.
86 // uint32 will automatically get converted to a double. "target size" is
87 // really a uint32 but we define it as a double for this reason.
88 // (See dbus/values_util.h).
89 optional_fields[NfcNdefRecord::kFieldTargetSize] = base::Value::TYPE_DOUBLE;
90 optional_fields[NfcNdefRecord::kFieldTitles] = base::Value::TYPE_LIST;
91 if (!CheckFieldsAreValid(required_fields, optional_fields, data)) {
92 VLOG(1) << "Failed to populate record.";
93 return false;
94 }
95 // Verify that the "titles" field was formatted correctly, if it exists.
96 const ListValue* titles = NULL;
97 if (data->GetList(NfcNdefRecord::kFieldTitles, &titles)) {
98 if (titles->empty()) {
99 VLOG(1) << "\"titles\" field of SmartPoster is empty.";
100 return false;
101 }
102 for (ListValue::const_iterator iter = titles->begin();
103 iter != titles->end(); ++iter) {
104 const DictionaryValue* title_data = NULL;
105 if (!(*iter)->GetAsDictionary(&title_data)) {
106 VLOG(1) << "\"title\" entry for SmartPoster contains an invalid value "
107 << "type";
108 return false;
109 }
110 if (!HandleTypeText(title_data)) {
111 VLOG(1) << "Badly formatted \"title\" entry for SmartPoster.";
112 return false;
113 }
114 }
115 }
116 return true;
117 }
118
119 // Verifies that the contents of |data| conform to the fields of NDEF type
120 // "URI".
121 bool HandleTypeUri(const DictionaryValue* data) {
122 VLOG(1) << "Populating record with type \"URI\".";
123 FieldValueMap required_fields;
124 required_fields[NfcNdefRecord::kFieldURI] = base::Value::TYPE_STRING;
125 FieldValueMap optional_fields;
126 optional_fields[NfcNdefRecord::kFieldMimeType] = base::Value::TYPE_STRING;
127 optional_fields[NfcNdefRecord::kFieldTargetSize] = base::Value::TYPE_DOUBLE;
128 if (!CheckFieldsAreValid(required_fields, optional_fields, data)) {
129 VLOG(1) << "Failed to populate record.";
130 return false;
131 }
132 return true;
133 }
134
135 } // namespace
136
137 // static
138 const char NfcNdefRecord::kFieldEncoding[] = "encoding";
139 // static
140 const char NfcNdefRecord::kFieldLanguageCode[] = "languageCode";
141 // static
142 const char NfcNdefRecord::kFieldText[] = "text";
143 // static
144 const char NfcNdefRecord::kFieldURI[] = "uri";
145 // static
146 const char NfcNdefRecord::kFieldMimeType[] = "mimeType";
147 // static
148 const char NfcNdefRecord::kFieldTargetSize[] = "targetSize";
149 // static
150 const char NfcNdefRecord::kFieldTitles[] = "titles";
151 // static
152 const char NfcNdefRecord::kFieldAction[] = "action";
153 // static
154 const char NfcNdefRecord::kEncodingUtf8[] = "UTF-8";
155 // static
156 const char NfcNdefRecord::kEncodingUtf16[] = "UTF-16";
157 // static
158 const char NfcNdefRecord::kSmartPosterActionDo[] = "do";
159 // static
160 const char NfcNdefRecord::kSmartPosterActionSave[] = "save";
161 // static
162 const char NfcNdefRecord::kSmartPosterActionOpen[] = "open";
163
164 NfcNdefRecord::NfcNdefRecord() : type_(kTypeUnknown) {
165 }
166
167 NfcNdefRecord::~NfcNdefRecord() {
168 }
169
170 bool NfcNdefRecord::IsPopulated() const {
171 return type_ != kTypeUnknown;
172 }
173
174 bool NfcNdefRecord::Populate(Type type, const DictionaryValue* data) {
175 if (IsPopulated())
176 return false;
177
178 DCHECK(data_.empty());
179
180 // At this time, only "Text", "URI", and "SmartPoster" are supported.
181 bool result = false;
182 switch (type) {
183 case kTypeText:
184 result = HandleTypeText(data);
185 break;
186 case kTypeSmartPoster:
187 result = HandleTypeSmartPoster(data);
188 break;
189 case kTypeURI:
190 result = HandleTypeUri(data);
191 break;
192 default:
193 VLOG(1) << "Unsupported NDEF type: " << type;
194 break;
195 }
196 if (!result)
197 return false;
198 type_ = type;
199 data_.MergeDictionary(data);
200 return true;
201 }
202
203 NfcNdefMessage::NfcNdefMessage() {
204 }
205
206 NfcNdefMessage::~NfcNdefMessage() {
207 }
208
209 void NfcNdefMessage::AddRecord(NfcNdefRecord* record) {
210 records_.push_back(record);
211 }
212
213 } // 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