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 27 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 34 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 41 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 48 void HidLocal::clear() { 49 *this = HidLocal(); 50 } 51 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