blob: 775a412a35096292e9963d1b4488070b6ade0cf5 [file] [log] [blame]
Myles Watson6c252872018-11-21 16:24:52 -08001/******************************************************************************
2 *
3 * Copyright 2018 The Android Open Source Project
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
18
19#include "class_of_device.h"
20
21#include <base/strings/string_split.h>
22#include <base/strings/stringprintf.h>
23#include <stdint.h>
24#include <algorithm>
25#include <vector>
26
27static_assert(sizeof(ClassOfDevice) == ClassOfDevice::kLength,
28 "ClassOfDevice must be 3 bytes long!");
29
30ClassOfDevice::ClassOfDevice(const uint8_t (&class_of_device)[kLength]) {
31 std::copy(class_of_device, class_of_device + kLength, cod);
32};
33
34std::string ClassOfDevice::ToString() const {
35 return base::StringPrintf("%03x-%01x-%02x",
36 (static_cast<uint16_t>(cod[2]) << 4) | cod[1] >> 4,
37 cod[1] & 0x0f, cod[0]);
38}
39
40bool ClassOfDevice::FromString(const std::string& from, ClassOfDevice& to) {
41 ClassOfDevice new_cod;
42 if (from.length() != 8) return false;
43
44 std::vector<std::string> byte_tokens =
45 base::SplitString(from, "-", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
46
47 if (byte_tokens.size() != 3) return false;
48 if (byte_tokens[0].length() != 3) return false;
49 if (byte_tokens[1].length() != 1) return false;
50 if (byte_tokens[2].length() != 2) return false;
51
52 uint16_t values[3];
53
54 for (size_t i = 0; i < kLength; i++) {
55 const auto& token = byte_tokens[i];
56
57 char* temp = nullptr;
58 values[i] = strtol(token.c_str(), &temp, 16);
59 if (*temp != '\0') return false;
60 }
61
62 new_cod.cod[0] = values[2];
63 new_cod.cod[1] = values[1] | ((values[0] & 0xf) << 4);
64 new_cod.cod[2] = values[0] >> 4;
65
66 to = new_cod;
67 return true;
68}
69
70size_t ClassOfDevice::FromOctets(const uint8_t* from) {
71 std::copy(from, from + kLength, cod);
72 return kLength;
73};
74
75bool ClassOfDevice::IsValid(const std::string& cod) {
76 ClassOfDevice tmp;
77 return ClassOfDevice::FromString(cod, tmp);
78}