15beee10b17e676380727da0b16b98ba7568669ecPeng Xu/*
25beee10b17e676380727da0b16b98ba7568669ecPeng Xu * Copyright (C) 2017 The Android Open Source Project
35beee10b17e676380727da0b16b98ba7568669ecPeng Xu *
45beee10b17e676380727da0b16b98ba7568669ecPeng Xu * Licensed under the Apache License, Version 2.0 (the "License");
55beee10b17e676380727da0b16b98ba7568669ecPeng Xu * you may not use this file except in compliance with the License.
65beee10b17e676380727da0b16b98ba7568669ecPeng Xu * You may obtain a copy of the License at
75beee10b17e676380727da0b16b98ba7568669ecPeng Xu *
85beee10b17e676380727da0b16b98ba7568669ecPeng Xu *      http://www.apache.org/licenses/LICENSE-2.0
95beee10b17e676380727da0b16b98ba7568669ecPeng Xu *
105beee10b17e676380727da0b16b98ba7568669ecPeng Xu * Unless required by applicable law or agreed to in writing, software
115beee10b17e676380727da0b16b98ba7568669ecPeng Xu * distributed under the License is distributed on an "AS IS" BASIS,
125beee10b17e676380727da0b16b98ba7568669ecPeng Xu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135beee10b17e676380727da0b16b98ba7568669ecPeng Xu * See the License for the specific language governing permissions and
145beee10b17e676380727da0b16b98ba7568669ecPeng Xu * limitations under the License.
155beee10b17e676380727da0b16b98ba7568669ecPeng Xu */
165beee10b17e676380727da0b16b98ba7568669ecPeng Xu#include "HidDefs.h"
175beee10b17e676380727da0b16b98ba7568669ecPeng Xu#include "HidGlobal.h"
185beee10b17e676380727da0b16b98ba7568669ecPeng Xu#include "HidLog.h"
195beee10b17e676380727da0b16b98ba7568669ecPeng Xu
205beee10b17e676380727da0b16b98ba7568669ecPeng Xunamespace HidUtil {
215beee10b17e676380727da0b16b98ba7568669ecPeng Xuusing namespace HidDef::GlobalTag;
225beee10b17e676380727da0b16b98ba7568669ecPeng Xu
235beee10b17e676380727da0b16b98ba7568669ecPeng Xubool HidGlobal::append(const HidItem &i) {
245beee10b17e676380727da0b16b98ba7568669ecPeng Xu    using namespace HidDef::TagType;
255beee10b17e676380727da0b16b98ba7568669ecPeng Xu    if (i.type != GLOBAL) {
265beee10b17e676380727da0b16b98ba7568669ecPeng Xu        LOG_E << "HidGlobal::append cannot process tag that is not global, " << i << LOG_ENDL;
275beee10b17e676380727da0b16b98ba7568669ecPeng Xu        return false;
285beee10b17e676380727da0b16b98ba7568669ecPeng Xu    }
295beee10b17e676380727da0b16b98ba7568669ecPeng Xu
305beee10b17e676380727da0b16b98ba7568669ecPeng Xu    if (i.tag == PUSH || i.tag == POP) {
315beee10b17e676380727da0b16b98ba7568669ecPeng Xu        LOG_E << "PUSH and POP should be handled in HidGlobalStack, " << i << LOG_ENDL;
325beee10b17e676380727da0b16b98ba7568669ecPeng Xu        return false;
335beee10b17e676380727da0b16b98ba7568669ecPeng Xu    }
345beee10b17e676380727da0b16b98ba7568669ecPeng Xu
355beee10b17e676380727da0b16b98ba7568669ecPeng Xu    int signedInteger;
365beee10b17e676380727da0b16b98ba7568669ecPeng Xu    unsigned unsignedInteger;
375beee10b17e676380727da0b16b98ba7568669ecPeng Xu    bool signedError = !i.dataAsSigned(&signedInteger);
385beee10b17e676380727da0b16b98ba7568669ecPeng Xu    bool unsignedError = !i.dataAsUnsigned(&unsignedInteger);
395beee10b17e676380727da0b16b98ba7568669ecPeng Xu
405beee10b17e676380727da0b16b98ba7568669ecPeng Xu    bool valueError = false;
415beee10b17e676380727da0b16b98ba7568669ecPeng Xu    bool ret = true;
425beee10b17e676380727da0b16b98ba7568669ecPeng Xu    switch (i.tag) {
435beee10b17e676380727da0b16b98ba7568669ecPeng Xu        case USAGE_PAGE:
445beee10b17e676380727da0b16b98ba7568669ecPeng Xu            usagePage = unsignedInteger;
455beee10b17e676380727da0b16b98ba7568669ecPeng Xu            valueError = unsignedError;
465beee10b17e676380727da0b16b98ba7568669ecPeng Xu            break;
475beee10b17e676380727da0b16b98ba7568669ecPeng Xu        case LOGICAL_MINIMUM:
485beee10b17e676380727da0b16b98ba7568669ecPeng Xu            logicalMin = signedInteger;
495beee10b17e676380727da0b16b98ba7568669ecPeng Xu            valueError = signedError;
505beee10b17e676380727da0b16b98ba7568669ecPeng Xu            break;
515beee10b17e676380727da0b16b98ba7568669ecPeng Xu        case LOGICAL_MAXIMUM:
525beee10b17e676380727da0b16b98ba7568669ecPeng Xu            logicalMax = signedInteger;
535beee10b17e676380727da0b16b98ba7568669ecPeng Xu            valueError = signedError;
545beee10b17e676380727da0b16b98ba7568669ecPeng Xu            break;
555beee10b17e676380727da0b16b98ba7568669ecPeng Xu        case PHYSICAL_MINIMUM:
565beee10b17e676380727da0b16b98ba7568669ecPeng Xu            physicalMin = signedInteger;
575beee10b17e676380727da0b16b98ba7568669ecPeng Xu            valueError = signedError;
585beee10b17e676380727da0b16b98ba7568669ecPeng Xu            break;
595beee10b17e676380727da0b16b98ba7568669ecPeng Xu        case PHYSICAL_MAXIMUM:
605beee10b17e676380727da0b16b98ba7568669ecPeng Xu            physicalMax = signedInteger;
615beee10b17e676380727da0b16b98ba7568669ecPeng Xu            valueError = signedError;
625beee10b17e676380727da0b16b98ba7568669ecPeng Xu            break;
635beee10b17e676380727da0b16b98ba7568669ecPeng Xu        case UNIT_EXPONENT:
645beee10b17e676380727da0b16b98ba7568669ecPeng Xu            exponent = unsignedInteger;
655beee10b17e676380727da0b16b98ba7568669ecPeng Xu            valueError = unsignedError;
665beee10b17e676380727da0b16b98ba7568669ecPeng Xu            break;
675beee10b17e676380727da0b16b98ba7568669ecPeng Xu        case UNIT:
685beee10b17e676380727da0b16b98ba7568669ecPeng Xu            unit = unsignedInteger;
695beee10b17e676380727da0b16b98ba7568669ecPeng Xu            valueError = unsignedError;
705beee10b17e676380727da0b16b98ba7568669ecPeng Xu            break;
715beee10b17e676380727da0b16b98ba7568669ecPeng Xu        case REPORT_SIZE:
725beee10b17e676380727da0b16b98ba7568669ecPeng Xu            reportSize = unsignedInteger;
735beee10b17e676380727da0b16b98ba7568669ecPeng Xu            valueError = unsignedError;
745beee10b17e676380727da0b16b98ba7568669ecPeng Xu            break;
755beee10b17e676380727da0b16b98ba7568669ecPeng Xu        case REPORT_ID:
765beee10b17e676380727da0b16b98ba7568669ecPeng Xu            reportId = unsignedInteger;
775beee10b17e676380727da0b16b98ba7568669ecPeng Xu            valueError = unsignedError;
785beee10b17e676380727da0b16b98ba7568669ecPeng Xu            break;
795beee10b17e676380727da0b16b98ba7568669ecPeng Xu        case REPORT_COUNT:
805beee10b17e676380727da0b16b98ba7568669ecPeng Xu            reportCount = unsignedInteger;
815beee10b17e676380727da0b16b98ba7568669ecPeng Xu            valueError = unsignedError;
825beee10b17e676380727da0b16b98ba7568669ecPeng Xu            break;
835beee10b17e676380727da0b16b98ba7568669ecPeng Xu        default:
845beee10b17e676380727da0b16b98ba7568669ecPeng Xu            LOG_E << "unknown global tag, " << i << LOG_ENDL;
855beee10b17e676380727da0b16b98ba7568669ecPeng Xu            ret = false;
865beee10b17e676380727da0b16b98ba7568669ecPeng Xu    }
875beee10b17e676380727da0b16b98ba7568669ecPeng Xu
885beee10b17e676380727da0b16b98ba7568669ecPeng Xu    if (valueError) {
895beee10b17e676380727da0b16b98ba7568669ecPeng Xu        LOG_E << "Cannot get signed / unsigned data at " << i << LOG_ENDL;
905beee10b17e676380727da0b16b98ba7568669ecPeng Xu        ret = false;
915beee10b17e676380727da0b16b98ba7568669ecPeng Xu    }
925beee10b17e676380727da0b16b98ba7568669ecPeng Xu    return ret;
935beee10b17e676380727da0b16b98ba7568669ecPeng Xu}
945beee10b17e676380727da0b16b98ba7568669ecPeng Xu
955beee10b17e676380727da0b16b98ba7568669ecPeng Xubool HidGlobalStack::append(const HidItem &i) {
965beee10b17e676380727da0b16b98ba7568669ecPeng Xu    using namespace HidDef::TagType;
975beee10b17e676380727da0b16b98ba7568669ecPeng Xu    if (i.type != GLOBAL) {
985beee10b17e676380727da0b16b98ba7568669ecPeng Xu        return false;
995beee10b17e676380727da0b16b98ba7568669ecPeng Xu    }
1005beee10b17e676380727da0b16b98ba7568669ecPeng Xu
1015beee10b17e676380727da0b16b98ba7568669ecPeng Xu    bool ret = true;
1025beee10b17e676380727da0b16b98ba7568669ecPeng Xu    if (i.tag == PUSH) {
1035beee10b17e676380727da0b16b98ba7568669ecPeng Xu        mStack.push_back(top());
1045beee10b17e676380727da0b16b98ba7568669ecPeng Xu    } else if (i.tag == POP) {
1055beee10b17e676380727da0b16b98ba7568669ecPeng Xu        mStack.pop_back();
1065beee10b17e676380727da0b16b98ba7568669ecPeng Xu        if (mStack.size() == 0) {
1075beee10b17e676380727da0b16b98ba7568669ecPeng Xu            mStack.push_back(HidGlobal()); // fail-safe
1085beee10b17e676380727da0b16b98ba7568669ecPeng Xu            ret = false;
1095beee10b17e676380727da0b16b98ba7568669ecPeng Xu        }
1105beee10b17e676380727da0b16b98ba7568669ecPeng Xu    } else {
1115beee10b17e676380727da0b16b98ba7568669ecPeng Xu        ret = mStack.back().append(i);
1125beee10b17e676380727da0b16b98ba7568669ecPeng Xu    }
1135beee10b17e676380727da0b16b98ba7568669ecPeng Xu    return ret;
1145beee10b17e676380727da0b16b98ba7568669ecPeng Xu}
1155beee10b17e676380727da0b16b98ba7568669ecPeng Xu
1165beee10b17e676380727da0b16b98ba7568669ecPeng XuHidGlobalStack::HidGlobalStack() {
1175beee10b17e676380727da0b16b98ba7568669ecPeng Xu    // default element
1185beee10b17e676380727da0b16b98ba7568669ecPeng Xu    mStack.push_back(HidGlobal());
1195beee10b17e676380727da0b16b98ba7568669ecPeng Xu}
1205beee10b17e676380727da0b16b98ba7568669ecPeng Xu
1215beee10b17e676380727da0b16b98ba7568669ecPeng Xuconst HidGlobal& HidGlobalStack::top() const {
1225beee10b17e676380727da0b16b98ba7568669ecPeng Xu    return mStack.back();
1235beee10b17e676380727da0b16b98ba7568669ecPeng Xu}
1245beee10b17e676380727da0b16b98ba7568669ecPeng Xu
1255beee10b17e676380727da0b16b98ba7568669ecPeng Xu} // namespace HidUtil
126