OLD | NEW |
(Empty) | |
| 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 kCollectionTypePhysical; |
| 94 case 0x02: |
| 95 return kCollectionTypePhysical; |
| 96 case 0x03: |
| 97 return kCollectionTypePhysical; |
| 98 case 0x04: |
| 99 return kCollectionTypePhysical; |
| 100 case 0x05: |
| 101 return kCollectionTypePhysical; |
| 102 case 0x06: |
| 103 return kCollectionTypePhysical; |
| 104 default: |
| 105 break; |
| 106 } |
| 107 if (0x80 < value && value < 0xFF) |
| 108 return kCollectionTypeVendor; |
| 109 return kCollectionTypeReserved; |
| 110 } |
| 111 |
| 112 } // namespace device |
OLD | NEW |