Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / device / bluetooth / bluetooth_uuid.cc
blob4a0ab22d27ee425c29ec837ae8d51eeac537f6fb
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.
5 #include "device/bluetooth/bluetooth_uuid.h"
7 #include "base/basictypes.h"
8 #include "base/logging.h"
9 #include "base/strings/string_util.h"
10 #include "ipc/ipc_message.h"
12 namespace device {
14 namespace {
16 const char* kCommonUuidPostfix = "-0000-1000-8000-00805f9b34fb";
17 const char* kCommonUuidPrefix = "0000";
19 // Returns the canonical, 128-bit canonical, and the format of the UUID
20 // in |canonical|, |canonical_128|, and |format| based on |uuid|.
21 void GetCanonicalUuid(std::string uuid,
22 std::string* canonical,
23 std::string* canonical_128,
24 BluetoothUUID::Format* format) {
25 // Initialize the values for the failure case.
26 canonical->clear();
27 canonical_128->clear();
28 *format = BluetoothUUID::kFormatInvalid;
30 if (uuid.empty())
31 return;
33 if (uuid.size() < 11 && uuid.find("0x") == 0)
34 uuid = uuid.substr(2);
36 if (!(uuid.size() == 4 || uuid.size() == 8 || uuid.size() == 36))
37 return;
39 for (size_t i = 0; i < uuid.size(); ++i) {
40 if (i == 8 || i == 13 || i == 18 || i == 23) {
41 if (uuid[i] != '-')
42 return;
43 } else {
44 if (!base::IsHexDigit(uuid[i]))
45 return;
46 uuid[i] = base::ToLowerASCII(uuid[i]);
50 canonical->assign(uuid);
51 if (uuid.size() == 4) {
52 canonical_128->assign(kCommonUuidPrefix + uuid + kCommonUuidPostfix);
53 *format = BluetoothUUID::kFormat16Bit;
54 } else if (uuid.size() == 8) {
55 canonical_128->assign(uuid + kCommonUuidPostfix);
56 *format = BluetoothUUID::kFormat32Bit;
57 } else {
58 canonical_128->assign(uuid);
59 *format = BluetoothUUID::kFormat128Bit;
63 } // namespace
66 BluetoothUUID::BluetoothUUID(const std::string& uuid) {
67 GetCanonicalUuid(uuid, &value_, &canonical_value_, &format_);
70 BluetoothUUID::BluetoothUUID() : format_(kFormatInvalid) {
73 BluetoothUUID::~BluetoothUUID() {
76 bool BluetoothUUID::IsValid() const {
77 return format_ != kFormatInvalid;
80 bool BluetoothUUID::operator<(const BluetoothUUID& uuid) const {
81 return canonical_value_ < uuid.canonical_value_;
84 bool BluetoothUUID::operator==(const BluetoothUUID& uuid) const {
85 return canonical_value_ == uuid.canonical_value_;
88 bool BluetoothUUID::operator!=(const BluetoothUUID& uuid) const {
89 return canonical_value_ != uuid.canonical_value_;
92 void PrintTo(const BluetoothUUID& uuid, std::ostream* out) {
93 *out << uuid.canonical_value();
96 } // namespace device
98 void IPC::ParamTraits<device::BluetoothUUID>::Write(Message* m,
99 const param_type& p) {
100 m->WriteString(p.canonical_value());
103 bool IPC::ParamTraits<device::BluetoothUUID>::Read(const Message* m,
104 base::PickleIterator* iter,
105 param_type* r) {
106 std::string value;
107 if (!iter->ReadString(&value))
108 return false;
109 *r = device::BluetoothUUID(value);
110 // If the format isn't 128-bit, .value() would return a different answer than
111 // .canonical_value(). Then if browser-side code accidentally checks .value()
112 // against a 128-bit string literal, a hostile renderer could use the 16- or
113 // 32-bit format and evade the check.
114 return r->format() == device::BluetoothUUID::kFormat128Bit;
117 void IPC::ParamTraits<device::BluetoothUUID>::Log(const param_type& p,
118 std::string* l) {
119 l->append(p.canonical_value());