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 "HidLog.h" 18 #include "HidTree.h" 19 #include <memory> 20 21 namespace HidUtil { 22 23 // HidTreeNode 24 HidTreeNode::HidTreeNode() : mNodeType(TYPE_UNINITIALIZED), mData(0), mFullUsage(0) { 25 } 26 27 HidTreeNode::HidTreeNode(std::shared_ptr<HidTreeNode> parent, 28 uint32_t data, uint32_t fullUsage, int nodeType) 29 : mNodeType(nodeType), mData(data), 30 mFullUsage(fullUsage), mParent(parent) { 31 } 32 33 HidTreeNode::HidTreeNode(std::shared_ptr<HidTreeNode> parent, 34 uint32_t data, uint32_t fullUsage) 35 : mNodeType(TYPE_NORMAL), mData(data), 36 mFullUsage(fullUsage), mParent(parent) { 37 } 38 39 void HidTreeNode::outputRecursive(std::ostream &os, int level) const { 40 insertIndentation(os, level); 41 os << "Node data: " << mData 42 << ", usage " << std::hex << mFullUsage << std::dec << LOG_ENDL; 43 44 for (auto &child : mChildren) { 45 child->outputRecursive(os, level + 1); 46 } 47 } 48 49 std::shared_ptr<HidTreeNode> HidTreeNode::deepCopy( 50 std::shared_ptr<HidTreeNode> parent) const { 51 std::shared_ptr<HidTreeNode> copy(new HidTreeNode(parent, mData, mFullUsage, mNodeType)); 52 for (auto &i : mChildren) { 53 copy->mChildren.push_back(i->deepCopy(copy)); 54 } 55 return copy; 56 } 57 58 void HidTreeNode::insertIndentation(std::ostream &os, int level) const { 59 constexpr char indentCharacter = '\t'; 60 std::fill_n(std::ostreambuf_iterator<char>(os), level, indentCharacter); 61 } 62 63 std::shared_ptr<HidTreeNode> HidTreeNode::addChild(std::shared_ptr<HidTreeNode> child) { 64 mChildren.push_back(child); 65 return child; 66 } 67 68 std::shared_ptr<HidTreeNode> HidTreeNode::getParent() const { 69 return mParent.lock(); 70 } 71 72 bool HidTreeNode::isReportCollection() const { 73 return mNodeType == TYPE_NORMAL && mChildren.size() == 1 74 && mChildren.front()->mNodeType == TYPE_REPORT; 75 } 76 77 unsigned int HidTreeNode::getFullUsage() const { 78 return mFullUsage; 79 } 80 81 std::vector<std::shared_ptr<HidTreeNode>>& HidTreeNode::getChildren() { 82 return mChildren; 83 } 84 85 const std::vector<std::shared_ptr<HidTreeNode>>& HidTreeNode::getChildren() const { 86 return mChildren; 87 } 88 89 bool HidTreeNode::isUsageCollection() const { 90 using namespace HidDef::CollectionType; 91 return mNodeType == TYPE_NORMAL && (mData == PHYSICAL || mData == APPLICATION); 92 } 93 94 int HidTreeNode::getNodeType() const { 95 return mNodeType; 96 } 97 98 std::ostream& operator<<(std::ostream& os, const HidTreeNode& n) { 99 n.outputRecursive(os, 0); 100 return os; 101 } 102 103 // HidReportNode 104 HidReportNode::HidReportNode(std::shared_ptr<HidTreeNode> parent, const HidReport &report) 105 : HidTreeNode(parent, 0 /*data*/, 0 /*fullUsage*/, TYPE_REPORT), mReport(report) { 106 } 107 108 void HidReportNode::outputRecursive(std::ostream &os, int level) const { 109 insertIndentation(os, level); 110 os << mReport << LOG_ENDL; 111 } 112 113 std::shared_ptr<HidTreeNode> HidReportNode::deepCopy( 114 std::shared_ptr<HidTreeNode> parent) const { 115 std::shared_ptr<HidTreeNode> copy(new HidReportNode(parent, mReport)); 116 return copy; 117 } 118 119 const HidReport& HidReportNode::getReport() const { 120 return mReport; 121 } 122 123 void HidReportNode::collapse(unsigned int newUsage) { 124 mReport.setCollapsed(newUsage); 125 } 126 127 } //namespace HidUtil 128