Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(92)

Unified Diff: device/hid/hid_report_descriptor_item.cc

Issue 225513005: chrome.hid : enrich device info with Top-Level collections usages (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: refactoring + style aligment Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: device/hid/hid_report_descriptor_item.cc
diff --git a/device/hid/hid_report_descriptor_item.cc b/device/hid/hid_report_descriptor_item.cc
new file mode 100644
index 0000000000000000000000000000000000000000..f2ce3b7dd5c0371c81c4359ae6437add2268237e
--- /dev/null
+++ b/device/hid/hid_report_descriptor_item.cc
@@ -0,0 +1,340 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "device/hid/hid_report_descriptor_item.h"
+
+#include <stdlib.h>
+
+#include "base/logging.h"
+#include "device/hid/hid_usage_and_page.h"
+
+namespace device {
+
+namespace {
+
+std::ostream& operator<<(std::ostream& os,
+ const HidReportDescriptorItem::Tag& tag) {
+ switch (tag) {
+ case HidReportDescriptorItem::kTagDefault:
+ os << "Default";
+ break;
+ case HidReportDescriptorItem::kTagInput:
+ os << "Input";
+ break;
+ case HidReportDescriptorItem::kTagOutput:
+ os << "Output";
+ break;
+ case HidReportDescriptorItem::kTagFeature:
+ os << "Feature";
+ break;
+ case HidReportDescriptorItem::kTagCollection:
+ os << "Collection";
+ break;
+ case HidReportDescriptorItem::kTagEndCollection:
+ os << "End Collection";
+ break;
+ case HidReportDescriptorItem::kTagUsagePage:
+ os << "Usage Page";
+ break;
+ case HidReportDescriptorItem::kTagLogicalMinimum:
+ os << "Logical Minimum";
+ break;
+ case HidReportDescriptorItem::kTagLogicalMaximum:
+ os << "Logical Maximum";
+ break;
+ case HidReportDescriptorItem::kTagPhysicalMinimum:
+ os << "Physical Minimum";
+ break;
+ case HidReportDescriptorItem::kTagPhysicalMaximum:
+ os << "Physical Maximum";
+ break;
+ case HidReportDescriptorItem::kTagUnitExponent:
+ os << "Unit Exponent";
+ break;
+ case HidReportDescriptorItem::kTagUnit:
+ os << "Unit";
+ break;
+ case HidReportDescriptorItem::kTagReportSize:
+ os << "Report Size";
+ break;
+ case HidReportDescriptorItem::kTagReportId:
+ os << "Report ID";
+ break;
+ case HidReportDescriptorItem::kTagReportCount:
+ os << "Report Count";
+ break;
+ case HidReportDescriptorItem::kTagPush:
+ os << "Push";
+ break;
+ case HidReportDescriptorItem::kTagPop:
+ os << "Pop";
+ break;
+ case HidReportDescriptorItem::kTagUsage:
+ os << "Usage";
+ break;
+ case HidReportDescriptorItem::kTagUsageMinimum:
+ os << "Usage Minimum";
+ break;
+ case HidReportDescriptorItem::kTagUsageMaximum:
+ os << "Usage Maximum";
+ break;
+ case HidReportDescriptorItem::kTagDesignatorIndex:
+ os << "Designator Index";
+ break;
+ case HidReportDescriptorItem::kTagDesignatorMinimum:
+ os << "Designator Minimum";
+ break;
+ case HidReportDescriptorItem::kTagDesignatorMaximum:
+ os << "Designator Maximum";
+ break;
+ case HidReportDescriptorItem::kTagStringIndex:
+ os << "String Index";
+ break;
+ case HidReportDescriptorItem::kTagStringMinimum:
+ os << "String Minimum";
+ break;
+ case HidReportDescriptorItem::kTagStringMaximum:
+ os << "String Maximum";
+ break;
+ case HidReportDescriptorItem::kTagDelimiter:
+ os << "Delimeter";
+ break;
+ case HidReportDescriptorItem::kTagLong:
+ os << "Long";
+ break;
+ default:
+ NOTREACHED();
+ break;
+ }
+
+ return os;
+}
+
+std::ostream& operator<<(std::ostream& os,
+ const HidReportDescriptorItem::ReportInfo& data) {
+ if (data.data_or_constant)
+ os << "Con";
+ else
+ os << "Dat";
+ if (data.array_or_variable)
+ os << "|Arr";
+ else
+ os << "|Var";
+ if (data.absolute_or_relative)
+ os << "|Abs";
+ else
+ os << "|Rel";
+ if (data.wrap)
+ os << "|Wrp";
+ else
+ os << "|NoWrp";
+ if (data.linear)
+ os << "|NoLin";
+ else
+ os << "|Lin";
+ if (data.preferred)
+ os << "|NoPrf";
+ else
+ os << "|Prf";
+ if (data.null)
+ os << "|Null";
+ else
+ os << "|NoNull";
+ if (data.bit_field_or_buffer)
+ os << "|Buff";
+ else
+ os << "|BitF";
+ return os;
+}
+
+std::ostream& operator<<(std::ostream& os,
+ const HidReportDescriptorItem::CollectionType& type) {
+ switch (type) {
+ case HidReportDescriptorItem::kCollectionTypePhysical:
+ os << "Physical";
+ break;
+ case HidReportDescriptorItem::kCollectionTypeApplication:
+ os << "Application";
+ break;
+ case HidReportDescriptorItem::kCollectionTypeLogical:
+ os << "Logical";
+ break;
+ case HidReportDescriptorItem::kCollectionTypeReport:
+ os << "Report";
+ break;
+ case HidReportDescriptorItem::kCollectionTypeNamedArray:
+ os << "Named Array";
+ break;
+ case HidReportDescriptorItem::kCollectionTypeUsageSwitch:
+ os << "Usage Switch";
+ break;
+ case HidReportDescriptorItem::kCollectionTypeUsageModifier:
+ os << "Usage Modifier";
+ break;
+ case HidReportDescriptorItem::kCollectionTypeReserved:
+ os << "Reserved";
+ break;
+ case HidReportDescriptorItem::kCollectionTypeVendor:
+ os << "Vendor";
+ break;
+ default:
+ NOTREACHED();
+ break;
+ }
+ return os;
+}
+
+struct Header {
+ uint8_t size : 2;
+ uint8_t type : 2;
+ uint8_t tag : 4;
+};
+
+struct LongHeader {
+ Header short_header;
+ uint8_t data_size;
+ uint8_t long_item_tag;
+};
+
+} // namespace
+
+HidReportDescriptorItem::HidReportDescriptorItem(
+ const uint8_t* bytes,
+ HidReportDescriptorItem* previous)
+ : previous_(previous), next_(NULL), parent_(NULL), shortData_(0) {
+ Header* header = (Header*)&bytes[0];
+ tag_ = (Tag)(header->tag << 2 | header->type);
+
+ if (IsLong()) {
+ LongHeader* long_header = (LongHeader*)&bytes[0];
Ken Rockot(use gerrit already) 2014/04/21 21:53:53 Please do not do this. You already have the short
jracle (use Gerrit) 2014/04/23 07:48:32 Sure, it will be equivalent in terms of clarity if
+ payload_size_ = long_header->data_size;
+ } else {
+ payload_size_ = header->size;
Ken Rockot(use gerrit already) 2014/04/21 21:53:53 Please verify that payload_size_ <= sizeof(shortDa
jracle (use Gerrit) 2014/04/23 07:48:32 oops, thanks. Don't wanna end-up to another a-la o
+ memcpy(&shortData_, &bytes[GetHeaderSize()], payloadSize());
+ }
+
+ if (previous) {
Ken Rockot(use gerrit already) 2014/04/21 21:53:53 Please at least DCHECK(!previous->next_) to clarif
jracle (use Gerrit) 2014/04/23 07:48:32 OK
+ previous->next_ = this;
+ switch (previous->tag()) {
+ case kTagCollection:
+ parent_ = previous;
+ break;
+ default:
+ break;
+ }
+ if (!parent_) {
+ switch (tag()) {
+ case kTagEndCollection:
+ if (previous->parent()) {
+ parent_ = previous->parent()->parent();
+ }
+ break;
+ default:
+ parent_ = previous->parent();
+ break;
+ }
+ }
+ }
+}
+
+size_t HidReportDescriptorItem::GetDepth() const {
+ HidReportDescriptorItem* parent_item = parent();
+ if (parent_item)
+ return parent_item->GetDepth() + 1;
+ return 0;
+}
+
+bool HidReportDescriptorItem::IsLong() const { return tag() == kTagLong; }
+
+size_t HidReportDescriptorItem::GetHeaderSize() const {
+ return IsLong() ? 3 : 1;
+}
+
+size_t HidReportDescriptorItem::GetSize() const {
+ return GetHeaderSize() + payloadSize();
+}
+
+uint32_t HidReportDescriptorItem::GetShortData() const {
+ DCHECK(!IsLong());
+ return shortData_;
+}
+
+HidReportDescriptorItem::CollectionType
+HidReportDescriptorItem::GetCollectionTypeFromValue(uint32_t value) {
+ switch (value) {
+ case 0x00:
+ return kCollectionTypePhysical;
+ case 0x01:
+ return kCollectionTypePhysical;
+ case 0x02:
+ return kCollectionTypePhysical;
+ case 0x03:
+ return kCollectionTypePhysical;
+ case 0x04:
+ return kCollectionTypePhysical;
+ case 0x05:
+ return kCollectionTypePhysical;
+ case 0x06:
+ return kCollectionTypePhysical;
+ default:
+ break;
+ }
+ if (0x80 < value && value < 0xFF)
+ return kCollectionTypeVendor;
+ return kCollectionTypeReserved;
+}
+
+std::ostream& operator<<(std::ostream& os,
+ const HidReportDescriptorItem& item) {
+ HidReportDescriptorItem::Tag item_tag = item.tag();
+ uint32_t data = item.GetShortData();
+
+ std::ostringstream sstr;
+ sstr << item_tag;
+ sstr << " (";
+
+ long pos = sstr.tellp();
+ switch (item_tag) {
+ case HidReportDescriptorItem::kTagDefault:
+ case HidReportDescriptorItem::kTagEndCollection:
+ case HidReportDescriptorItem::kTagPush:
+ case HidReportDescriptorItem::kTagPop:
+ case HidReportDescriptorItem::kTagLong:
+ break;
+
+ case HidReportDescriptorItem::kTagCollection:
+ sstr << HidReportDescriptorItem::GetCollectionTypeFromValue(data);
+ break;
+
+ case HidReportDescriptorItem::kTagInput:
+ case HidReportDescriptorItem::kTagOutput:
+ case HidReportDescriptorItem::kTagFeature:
+ sstr << (HidReportDescriptorItem::ReportInfo&)data;
+ break;
+
+ case HidReportDescriptorItem::kTagUsagePage:
+ sstr << (HidUsageAndPage::Page)data;
+ break;
+
+ case HidReportDescriptorItem::kTagUsage:
+ case HidReportDescriptorItem::kTagReportId:
+ sstr << "0x" << std::hex << std::uppercase << data;
+ break;
+
+ default:
+ sstr << data;
+ break;
+ }
+ if (pos == sstr.tellp()) {
+ std::string str = sstr.str();
+ str.erase(str.end() - 2, str.end());
+ os << str;
+ } else {
+ os << sstr.str() << ")";
+ }
+
+ return os;
+}
+
+} // namespace device

Powered by Google App Engine
This is Rietveld 408576698