1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #include "HidDefs.h"
17 #include "HidLocal.h"
18 #include "HidLog.h"
19 #include <cstddef>
20 
21 namespace HidUtil {
22 
23 constexpr uint32_t INVALID_USAGE = 0xFFFF;
24 constexpr uint32_t INVALID_DESIGNATOR = 0xFFFF;
25 constexpr uint32_t INVALID_STRING = 0xFFFF;
26 
getUsage(size_t index) const27 uint32_t HidLocal::getUsage(size_t index) const {
28     if (usage.empty()) {
29         return INVALID_USAGE;
30     }
31     return (index >= usage.size()) ? usage.back() : usage[index];
32 }
33 
getDesignator(size_t index) const34 uint32_t HidLocal::getDesignator(size_t index) const {
35     if (designator.empty()) {
36         return INVALID_DESIGNATOR;
37     }
38     return (index >= designator.size()) ? designator.back() : designator[index];
39 }
40 
getString(size_t index) const41 uint32_t HidLocal::getString(size_t index) const {
42     if (string.empty()) {
43         return INVALID_STRING;
44     }
45     return (index >= string.size()) ? string.back() : string[index];
46 }
47 
clear()48 void HidLocal::clear() {
49     *this = HidLocal();
50 }
51 
append(const HidItem & i)52 bool HidLocal::append(const HidItem &i) {
53     using namespace HidDef::LocalTag;
54 
55     bool ret = true;
56     unsigned unsignedInteger;
57     bool unsignedError = !i.dataAsUnsigned(&unsignedInteger);
58     bool valueError = false;
59 
60     switch (i.tag) {
61         case USAGE:
62             usage.push_back(unsignedInteger);
63             valueError = unsignedError;
64             break;
65         case USAGE_MINIMUM:
66             usageMin = unsignedInteger;
67             valueError = unsignedError;
68             break;
69         case USAGE_MAXIMUM:
70             if (!usageMin.isSet()) {
71                 LOG_E << "usage min not set when saw usage max " << i << LOG_ENDL;
72                 ret = false;
73             } else {
74                 uint32_t usagemax = unsignedInteger;
75                 valueError = unsignedError;
76                 for (size_t j = usageMin.get(0); j <= usagemax; ++j) {
77                     usage.push_back(j);
78                 }
79                 usageMin.clear();
80             }
81             break;
82         case STRING_INDEX:
83             string.push_back(unsignedInteger);
84             valueError = unsignedError;
85             break;
86         case STRING_MINIMUM:
87             stringMin = unsignedInteger;
88             valueError = unsignedError;
89             break;
90         case STRING_MAXIMUM: {
91             if (!usageMin.isSet()) {
92                 LOG_E << "string min not set when saw string max " << i << LOG_ENDL;
93                 ret = false;
94             } else {
95                 uint32_t stringMax = unsignedInteger;
96                 valueError = unsignedError;
97                 for (size_t j = stringMin.get(0); j <= stringMax; ++j) {
98                     string.push_back(j);
99                 }
100                 stringMin.clear();
101             }
102             break;
103         }
104         case DELIMITOR:
105             delimeter = unsignedInteger;
106             valueError = unsignedError;
107             break;
108         default:
109             LOG_E << "unknown local tag, " << i << LOG_ENDL;
110             ret = false;
111     }
112     if (valueError) {
113         LOG_E << "Cannot get unsigned data at " << i << LOG_ENDL;
114         ret = false;
115     }
116     return ret;
117 }
118 } //namespace HidUtil
119