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.h" | |
6 | |
7 #include <stdlib.h> | |
8 | |
9 #include <algorithm> | |
10 | |
11 using namespace std; | |
12 | |
13 namespace device { | |
14 | |
15 HidReportDescriptorItem::HidReportDescriptorItem( | |
16 const uint8_t* bytes, | |
17 HidReportDescriptorItem* previous) | |
18 : bytes_(bytes), previous_(previous), parent_(NULL) { | |
19 | |
Ken Rockot(use gerrit already)
2014/04/15 21:18:37
Sorry - I guess the auto-format tool does not do t
jracle (use Gerrit)
2014/04/16 16:39:19
Oh sorry, got it now.
| |
20 if (previous) { | |
21 | |
22 previous->next_ = this; | |
23 | |
24 switch (previous->tag()) { | |
25 case kTagCollection: | |
26 parent_ = previous; | |
27 break; | |
28 default: | |
29 break; | |
30 } | |
31 | |
32 if (!parent_) { | |
33 switch (tag()) { | |
34 case kTagEndCollection: | |
35 if (previous->parent()) { | |
36 parent_ = previous->parent()->parent(); | |
37 } | |
38 break; | |
39 default: | |
40 parent_ = previous->parent(); | |
41 break; | |
42 } | |
43 } | |
44 } | |
45 } | |
46 | |
47 HidReportDescriptorItem::~HidReportDescriptorItem() {} | |
48 | |
49 size_t HidReportDescriptorItem::depth() const { | |
50 HidReportDescriptorItem* parnt = parent(); | |
51 if (parnt) | |
Ken Rockot(use gerrit already)
2014/04/15 21:18:37
Please rename parnt. As a general rule, always pre
jracle (use Gerrit)
2014/04/16 16:39:19
Sorry, was done in separate CL. I violated my own
| |
52 return parnt->depth() + 1; | |
53 return 0; | |
54 } | |
55 | |
56 bool HidReportDescriptorItem::isLong() const { return tag() == kTagLong; } | |
57 | |
58 size_t HidReportDescriptorItem::headerSize() const { return isLong() ? 3 : 1; } | |
59 | |
60 size_t HidReportDescriptorItem::payloadSize() const { | |
61 return isLong() ? longHeader()->data_size : header()->size; | |
62 } | |
63 | |
64 size_t HidReportDescriptorItem::size() const { | |
65 return headerSize() + payloadSize(); | |
66 } | |
67 | |
68 HidReportDescriptorItem::Header* HidReportDescriptorItem::header() const { | |
69 return (HidReportDescriptorItem::Header*)(&bytes_[0]); | |
70 } | |
71 | |
72 HidReportDescriptorItem::LongHeader* HidReportDescriptorItem::longHeader() | |
73 const { | |
74 DCHECK(isLong()); | |
75 return (HidReportDescriptorItem::LongHeader*)(&bytes_[0]); | |
76 } | |
77 | |
78 HidReportDescriptorItem::Tag HidReportDescriptorItem::tag() const { | |
79 return (HidReportDescriptorItem::Tag)(header()->tag << 2 | header()->type); | |
80 } | |
81 | |
82 HidReportDescriptorItem::Data* HidReportDescriptorItem::data() const { | |
83 void* data = malloc(sizeof(HidReportDescriptorItem::Data)); | |
84 memset(data, 0, sizeof(data)); | |
85 memcpy(data, &bytes_[headerSize()], payloadSize()); | |
86 return (HidReportDescriptorItem::Data*)data; | |
87 } | |
88 | |
89 HidReportDescriptor::HidReportDescriptor(const uint8_t* bytes, size_t size) | |
90 : bytes_(bytes), size_(size) { | |
91 size_t header_index = 0; | |
92 HidReportDescriptorItem* item = NULL; | |
93 while (header_index < size_) { | |
94 item = new HidReportDescriptorItem(&bytes_[header_index], item); | |
95 items_.push_back(item); | |
96 header_index += item->size(); | |
97 } | |
98 } | |
99 | |
100 const char HidReportDescriptor::kIndentChar = ' '; | |
101 | |
102 HidReportDescriptor::~HidReportDescriptor() { | |
103 for (vector<HidReportDescriptorItem*>::const_iterator items_iter = | |
104 items_.begin(); | |
105 items_iter != items_.end(); | |
106 ++items_iter) { | |
107 delete *items_iter; | |
108 } | |
109 items_.clear(); | |
110 } | |
111 | |
112 const std::vector<HidReportDescriptorItem*>& HidReportDescriptor::items() | |
113 const { | |
114 return items_; | |
115 } | |
116 | |
117 std::vector<HidUsageAndPage> HidReportDescriptor::topLevelCollections() const { | |
118 | |
119 std::vector<HidUsageAndPage> tlcs; | |
120 | |
121 for (std::vector<HidReportDescriptorItem*>::const_iterator items_iter = | |
122 items_.begin(); | |
123 items_iter != items_.end(); | |
124 ++items_iter) { | |
125 HidReportDescriptorItem* item = *items_iter; | |
126 | |
127 bool isTopLevelCollection = | |
128 item->tag() == HidReportDescriptorItem::kTagCollection && | |
129 item->parent() == NULL; | |
130 | |
131 if (isTopLevelCollection) { | |
132 HidReportDescriptorItem* usage = item->previous(); | |
133 HidReportDescriptorItem* usage_page = usage->previous(); | |
134 | |
135 HidUsageAndPage usage_and_page; | |
136 if (usage && usage->tag() == HidReportDescriptorItem::kTagUsage) { | |
137 usage_and_page.usage = | |
138 ((HidReportDescriptorItem::Usage*)usage->data())->value; | |
139 } | |
140 if (usage_page && | |
141 usage_page->tag() == HidReportDescriptorItem::kTagUsagePage) { | |
142 usage_and_page.usage_page = | |
143 ((HidReportDescriptorItem::UsagePage*)usage_page->data())->value; | |
144 } | |
145 tlcs.push_back(usage_and_page); | |
146 } | |
147 } | |
148 | |
149 return tlcs; | |
150 } | |
151 | |
152 } // namespace device | |
OLD | NEW |