/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "HidDefs.h"
#include "HidLog.h"
#include "HidTree.h"
#include <memory>
namespace HidUtil {
// HidTreeNode
HidTreeNode::HidTreeNode() : mNodeType(TYPE_UNINITIALIZED), mData(0), mFullUsage(0) {
}
HidTreeNode::HidTreeNode(std::shared_ptr<HidTreeNode> parent,
uint32_t data, uint32_t fullUsage, int nodeType)
: mNodeType(nodeType), mData(data),
mFullUsage(fullUsage), mParent(parent) {
}
HidTreeNode::HidTreeNode(std::shared_ptr<HidTreeNode> parent,
uint32_t data, uint32_t fullUsage)
: mNodeType(TYPE_NORMAL), mData(data),
mFullUsage(fullUsage), mParent(parent) {
}
void HidTreeNode::outputRecursive(std::ostream &os, int level) const {
insertIndentation(os, level);
os << "Node data: " << mData
<< ", usage " << std::hex << mFullUsage << std::dec << LOG_ENDL;
for (auto &child : mChildren) {
child->outputRecursive(os, level + 1);
}
}
std::shared_ptr<HidTreeNode> HidTreeNode::deepCopy(
std::shared_ptr<HidTreeNode> parent) const {
std::shared_ptr<HidTreeNode> copy(new HidTreeNode(parent, mData, mFullUsage, mNodeType));
for (auto &i : mChildren) {
copy->mChildren.push_back(i->deepCopy(copy));
}
return copy;
}
void HidTreeNode::insertIndentation(std::ostream &os, int level) const {
constexpr char indentCharacter = '\t';
std::fill_n(std::ostreambuf_iterator<char>(os), level, indentCharacter);
}
std::shared_ptr<HidTreeNode> HidTreeNode::addChild(std::shared_ptr<HidTreeNode> child) {
mChildren.push_back(child);
return child;
}
std::shared_ptr<HidTreeNode> HidTreeNode::getParent() const {
return mParent.lock();
}
bool HidTreeNode::isReportCollection() const {
return mNodeType == TYPE_NORMAL && mChildren.size() == 1
&& mChildren.front()->mNodeType == TYPE_REPORT;
}
unsigned int HidTreeNode::getFullUsage() const {
return mFullUsage;
}
std::vector<std::shared_ptr<HidTreeNode>>& HidTreeNode::getChildren() {
return mChildren;
}
const std::vector<std::shared_ptr<HidTreeNode>>& HidTreeNode::getChildren() const {
return mChildren;
}
bool HidTreeNode::isUsageCollection() const {
using namespace HidDef::CollectionType;
return mNodeType == TYPE_NORMAL && (mData == PHYSICAL || mData == APPLICATION);
}
int HidTreeNode::getNodeType() const {
return mNodeType;
}
std::ostream& operator<<(std::ostream& os, const HidTreeNode& n) {
n.outputRecursive(os, 0);
return os;
}
// HidReportNode
HidReportNode::HidReportNode(std::shared_ptr<HidTreeNode> parent, const HidReport &report)
: HidTreeNode(parent, 0 /*data*/, 0 /*fullUsage*/, TYPE_REPORT), mReport(report) {
}
void HidReportNode::outputRecursive(std::ostream &os, int level) const {
insertIndentation(os, level);
os << mReport << LOG_ENDL;
}
std::shared_ptr<HidTreeNode> HidReportNode::deepCopy(
std::shared_ptr<HidTreeNode> parent) const {
std::shared_ptr<HidTreeNode> copy(new HidReportNode(parent, mReport));
return copy;
}
const HidReport& HidReportNode::getReport() const {
return mReport;
}
void HidReportNode::collapse(unsigned int newUsage) {
mReport.setCollapsed(newUsage);
}
} //namespace HidUtil