1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "device/hid/hid_report_descriptor_item.h" 6 7 #include <stdlib.h> 8 9 #include "base/logging.h" 10 #include "device/hid/hid_usage_and_page.h" 11 12 namespace device { 13 14 namespace { 15 16 struct Header { 17 uint8_t size : 2; 18 uint8_t type : 2; 19 uint8_t tag : 4; 20 }; 21 22 } // namespace 23 24 HidReportDescriptorItem::HidReportDescriptorItem( 25 const uint8_t* bytes, 26 HidReportDescriptorItem* previous) 27 : previous_(previous), next_(NULL), parent_(NULL), shortData_(0) { 28 Header* header = (Header*)&bytes[0]; 29 tag_ = (Tag)(header->tag << 2 | header->type); 30 31 if (IsLong()) { 32 // In a long item, payload size is the second byte. 33 payload_size_ = bytes[1]; 34 } else { 35 payload_size_ = header->size; 36 DCHECK(payload_size_ <= sizeof(shortData_)); 37 memcpy(&shortData_, &bytes[GetHeaderSize()], payload_size()); 38 } 39 40 if (previous) { 41 DCHECK(!previous->next_); 42 previous->next_ = this; 43 switch (previous->tag()) { 44 case kTagCollection: 45 parent_ = previous; 46 break; 47 default: 48 break; 49 } 50 if (!parent_) { 51 switch (tag()) { 52 case kTagEndCollection: 53 if (previous->parent()) { 54 parent_ = previous->parent()->parent(); 55 } 56 break; 57 default: 58 parent_ = previous->parent(); 59 break; 60 } 61 } 62 } 63 } 64 65 size_t HidReportDescriptorItem::GetDepth() const { 66 HidReportDescriptorItem* parent_item = parent(); 67 if (parent_item) 68 return parent_item->GetDepth() + 1; 69 return 0; 70 } 71 72 bool HidReportDescriptorItem::IsLong() const { return tag() == kTagLong; } 73 74 size_t HidReportDescriptorItem::GetHeaderSize() const { 75 return IsLong() ? 3 : 1; 76 } 77 78 size_t HidReportDescriptorItem::GetSize() const { 79 return GetHeaderSize() + payload_size(); 80 } 81 82 uint32_t HidReportDescriptorItem::GetShortData() const { 83 DCHECK(!IsLong()); 84 return shortData_; 85 } 86 87 HidReportDescriptorItem::CollectionType 88 HidReportDescriptorItem::GetCollectionTypeFromValue(uint32_t value) { 89 switch (value) { 90 case 0x00: 91 return kCollectionTypePhysical; 92 case 0x01: 93 return kCollectionTypeApplication; 94 case 0x02: 95 return kCollectionTypeLogical; 96 case 0x03: 97 return kCollectionTypeReport; 98 case 0x04: 99 return kCollectionTypeNamedArray; 100 case 0x05: 101 return kCollectionTypeUsageSwitch; 102 case 0x06: 103 return kCollectionTypeUsageModifier; 104 default: 105 break; 106 } 107 if (0x80 < value && value < 0xFF) 108 return kCollectionTypeVendor; 109 return kCollectionTypeReserved; 110 } 111 112 } // namespace device 113