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 #ifndef DEVICE_HID_HID_REPORT_DESCRIPTOR_H_ | |
6 #define DEVICE_HID_HID_REPORT_DESCRIPTOR_H_ | |
7 | |
8 #include <sstream> | |
9 #include <vector> | |
10 | |
11 #include "base/basictypes.h" | |
12 #include "device/hid/hid_usage_and_page.h" | |
13 | |
14 namespace device { | |
15 | |
16 // An element of a HID report descriptor. | |
17 class HidReportDescriptorItem { | |
Ken Rockot(use gerrit already)
2014/04/15 21:18:37
I think this is large enough that it deserves its
jracle (use Gerrit)
2014/04/16 16:39:19
Sure, done.
| |
18 | |
19 #pragma pack(push, 1) | |
Ken Rockot(use gerrit already)
2014/04/15 21:18:37
Please do not use packed structs to map onto a dat
jracle (use Gerrit)
2014/04/16 16:39:19
Got your point, I will refactor in next patch set.
| |
20 | |
21 public: | |
22 enum Type { | |
23 kTypeMain = 0, | |
Ken Rockot(use gerrit already)
2014/04/15 21:18:37
Please move Type into the next public block since
| |
24 kTypeGlobal = 1, | |
25 kTypeLocal = 2, | |
26 kTypeReserved = 3 | |
27 }; | |
28 | |
29 private: | |
30 // Tags | |
31 | |
32 enum MainTag { | |
33 kMainTagDefault = 0x00, // 0000 | |
Ken Rockot(use gerrit already)
2014/04/15 21:18:37
As these are only used internally, please move the
| |
34 kMainTagInput = 0x08, // 1000 | |
35 kMainTagOutput = 0x09, // 1001 | |
36 kMainTagFeature = 0x0B, // 1011 | |
37 kMainTagCollection = 0x0A, // 1010 | |
38 kMainTagEndCollection = 0x0C // 1100 | |
39 }; | |
40 | |
41 enum GlobalTag { | |
42 kGlobalTagUsagePage = 0x00, // 0000 | |
43 kGlobalTagLogicalMinimum = 0x01, // 0001 | |
44 kGlobalTagLogicalMaximum = 0x02, // 0010 | |
45 kGlobalTagPhysicalMinimum = 0x03, // 0011 | |
46 kGlobalTagPhysicalMaximum = 0x04, // 0100 | |
47 kGlobalTagUnitExponent = 0x05, // 0101 | |
48 kGlobalTagUnit = 0x06, // 0110 | |
49 kGlobalTagReportSize = 0x07, // 0111 | |
50 kGlobalTagReportId = 0x08, // 1000 | |
51 kGlobalTagReportCount = 0x09, // 1001 | |
52 kGlobalTagPush = 0x0A, // 1010 | |
53 kGlobalTagPop = 0x0B // 1011 | |
54 }; | |
55 | |
56 enum LocalTag { | |
57 kLocalTagUsage = 0x00, // 0000 | |
58 kLocalTagUsageMinimum = 0x01, // 0001 | |
59 kLocalTagUsageMaximum = 0x02, // 0010 | |
60 kLocalTagDesignatorIndex = 0x03, // 0011 | |
61 kLocalTagDesignatorMinimum = 0x04, // 0100 | |
62 kLocalTagDesignatorMaximum = 0x05, // 0101 | |
63 kLocalTagStringIndex = 0x07, // 0111 | |
64 kLocalTagStringMinimum = 0x08, // 1000 | |
65 kLocalTagStringMaximum = 0x09, // 1001 | |
66 kLocalTagDelimiter = 0x0A // 1010 | |
67 }; | |
68 | |
69 enum ReservedTag { | |
70 kReservedTagLong = 0xF // 1111 | |
71 }; | |
72 | |
73 public: | |
74 enum Tag { | |
75 kTagDefault = kMainTagDefault << 2 | kTypeMain, | |
76 kTagInput = kMainTagInput << 2 | kTypeMain, | |
77 kTagOutput = kMainTagOutput << 2 | kTypeMain, | |
78 kTagFeature = kMainTagFeature << 2 | kTypeMain, | |
79 kTagCollection = kMainTagCollection << 2 | kTypeMain, | |
80 kTagEndCollection = kMainTagEndCollection << 2 | kTypeMain, | |
81 kTagUsagePage = kGlobalTagUsagePage << 2 | kTypeGlobal, | |
82 kTagLogicalMinimum = kGlobalTagLogicalMinimum << 2 | kTypeGlobal, | |
83 kTagLogicalMaximum = kGlobalTagLogicalMaximum << 2 | kTypeGlobal, | |
84 kTagPhysicalMinimum = kGlobalTagPhysicalMinimum << 2 | kTypeGlobal, | |
85 kTagPhysicalMaximum = kGlobalTagPhysicalMaximum << 2 | kTypeGlobal, | |
86 kTagUnitExponent = kGlobalTagUnitExponent << 2 | kTypeGlobal, | |
87 kTagUnit = kGlobalTagUnit << 2 | kTypeGlobal, | |
88 kTagReportSize = kGlobalTagReportSize << 2 | kTypeGlobal, | |
89 kTagReportId = kGlobalTagReportId << 2 | kTypeGlobal, | |
90 kTagReportCount = kGlobalTagReportCount << 2 | kTypeGlobal, | |
91 kTagPush = kGlobalTagPush << 2 | kTypeGlobal, | |
92 kTagPop = kGlobalTagPop << 2 | kTypeGlobal, | |
93 kTagUsage = kLocalTagUsage << 2 | kTypeLocal, | |
94 kTagUsageMinimum = kLocalTagUsageMinimum << 2 | kTypeLocal, | |
95 kTagUsageMaximum = kLocalTagUsageMaximum << 2 | kTypeLocal, | |
96 kTagDesignatorIndex = kLocalTagDesignatorIndex << 2 | kTypeLocal, | |
97 kTagDesignatorMinimum = kLocalTagDesignatorMinimum << 2 | kTypeLocal, | |
98 kTagDesignatorMaximum = kLocalTagDesignatorMaximum << 2 | kTypeLocal, | |
99 kTagStringIndex = kLocalTagStringIndex << 2 | kTypeLocal, | |
100 kTagStringMinimum = kLocalTagStringMinimum << 2 | kTypeLocal, | |
101 kTagStringMaximum = kLocalTagStringMaximum << 2 | kTypeLocal, | |
102 kTagDelimiter = kLocalTagDelimiter << 2 | kTypeLocal, | |
103 kTagLong = kReservedTagLong << 2 | kTypeReserved | |
104 }; | |
105 | |
106 private: | |
107 friend std::ostream& operator<<(std::ostream& os, const Tag& tag) { | |
Ken Rockot(use gerrit already)
2014/04/15 21:18:37
Please do not inline this, and in fact it doesn't
jracle (use Gerrit)
2014/04/16 16:39:19
Done
| |
108 switch (tag) { | |
109 case kTagDefault: | |
110 os << "Default"; | |
111 break; | |
112 case kTagInput: | |
113 os << "Input"; | |
114 break; | |
115 case kTagOutput: | |
116 os << "Output"; | |
117 break; | |
118 case kTagFeature: | |
119 os << "Feature"; | |
120 break; | |
121 case kTagCollection: | |
122 os << "Collection"; | |
123 break; | |
124 case kTagEndCollection: | |
125 os << "End Collection"; | |
126 break; | |
127 case kTagUsagePage: | |
128 os << "Usage Page"; | |
129 break; | |
130 case kTagLogicalMinimum: | |
131 os << "Logical Minimum"; | |
132 break; | |
133 case kTagLogicalMaximum: | |
134 os << "Logical Maximum"; | |
135 break; | |
136 case kTagPhysicalMinimum: | |
137 os << "Physical Minimum"; | |
138 break; | |
139 case kTagPhysicalMaximum: | |
140 os << "Physical Maximum"; | |
141 break; | |
142 case kTagUnitExponent: | |
143 os << "Unit Exponent"; | |
144 break; | |
145 case kTagUnit: | |
146 os << "Unit"; | |
147 break; | |
148 case kTagReportSize: | |
149 os << "Report Size"; | |
150 break; | |
151 case kTagReportId: | |
152 os << "Report ID"; | |
153 break; | |
154 case kTagReportCount: | |
155 os << "Report Count"; | |
156 break; | |
157 case kTagPush: | |
158 os << "Push"; | |
159 break; | |
160 case kTagPop: | |
161 os << "Pop"; | |
162 break; | |
163 case kTagUsage: | |
164 os << "Usage"; | |
165 break; | |
166 case kTagUsageMinimum: | |
167 os << "Usage Minimum"; | |
168 break; | |
169 case kTagUsageMaximum: | |
170 os << "Usage Maximum"; | |
171 break; | |
172 case kTagDesignatorIndex: | |
173 os << "Designator Index"; | |
174 break; | |
175 case kTagDesignatorMinimum: | |
176 os << "Designator Minimum"; | |
177 break; | |
178 case kTagDesignatorMaximum: | |
179 os << "Designator Maximum"; | |
180 break; | |
181 case kTagStringIndex: | |
182 os << "String Index"; | |
183 break; | |
184 case kTagStringMinimum: | |
185 os << "String Minimum"; | |
186 break; | |
187 case kTagStringMaximum: | |
188 os << "String Maximum"; | |
189 break; | |
190 case kTagDelimiter: | |
191 os << "Delimeter"; | |
192 break; | |
193 case kTagLong: | |
194 os << "Long"; | |
195 break; | |
196 default: | |
197 NOTREACHED(); | |
198 break; | |
199 } | |
200 | |
201 return os; | |
202 }; | |
203 | |
204 public: | |
205 // Headers | |
206 | |
207 struct Header { | |
Ken Rockot(use gerrit already)
2014/04/15 21:18:37
I'm jumping around this CL a lot as I get a better
jracle (use Gerrit)
2014/04/16 16:39:19
Got it, no point to show those details. Confusing.
| |
208 uint8_t size : 2; | |
209 uint8_t type : 2; | |
210 uint8_t tag : 4; | |
211 }; | |
212 | |
213 struct LongHeader { | |
214 Header short_header; | |
215 uint8_t data_size; | |
216 uint8_t long_item_tag; | |
217 }; | |
218 | |
219 // Data | |
220 | |
221 // (Short) Main items | |
222 | |
223 struct Default { | |
Ken Rockot(use gerrit already)
2014/04/15 21:18:37
Default what? A more descriptive name may be in or
jracle (use Gerrit)
2014/04/16 16:39:19
Oops. Not meaningful.
| |
224 private: | |
225 friend std::ostream& operator<<(std::ostream& os, const Default& data) { | |
Ken Rockot(use gerrit already)
2014/04/15 21:18:37
See the comment in Input_Output_Feature about movi
jracle (use Gerrit)
2014/04/16 16:39:19
Indeed.
| |
226 return os; | |
227 } | |
228 }; | |
229 | |
230 struct Input_Output_Feature { | |
Ken Rockot(use gerrit already)
2014/04/15 21:18:37
InputOutputFeature, please
| |
231 uint8_t data_or_constant : 1; | |
Ken Rockot(use gerrit already)
2014/04/15 21:18:37
Same as previous comments. I know it's a lot of fi
| |
232 uint8_t array_or_variable : 1; | |
233 uint8_t absolute_or_relative : 1; | |
234 uint8_t wrap : 1; | |
235 uint8_t linear : 1; | |
236 uint8_t preferred : 1; | |
237 uint8_t null : 1; | |
238 uint8_t reserved_1 : 1; | |
239 uint8_t bit_field_or_buffer : 1; | |
240 uint8_t reserved_2 : 1; | |
241 | |
242 private: | |
243 friend std::ostream& operator<<(std::ostream& os, | |
244 const Input_Output_Feature& data) { | |
Ken Rockot(use gerrit already)
2014/04/15 21:18:37
Please do not inline this. In fact once again, thi
| |
245 if (data.data_or_constant) | |
246 os << "Con"; | |
247 else | |
248 os << "Dat"; | |
249 if (data.array_or_variable) | |
250 os << "|Arr"; | |
251 else | |
252 os << "|Var"; | |
253 if (data.absolute_or_relative) | |
254 os << "|Abs"; | |
255 else | |
256 os << "|Rel"; | |
257 if (data.wrap) | |
258 os << "|Wrp"; | |
259 else | |
260 os << "|NoWrp"; | |
261 if (data.linear) | |
262 os << "|NoLin"; | |
263 else | |
264 os << "|Lin"; | |
265 if (data.preferred) | |
266 os << "|NoPrf"; | |
267 else | |
268 os << "|Prf"; | |
269 if (data.null) | |
270 os << "|Null"; | |
271 else | |
272 os << "|NoNull"; | |
273 if (data.bit_field_or_buffer) | |
274 os << "|Buff"; | |
275 else | |
276 os << "|BitF"; | |
277 return os; | |
278 } | |
279 }; | |
280 | |
281 struct Collection { | |
282 | |
Ken Rockot(use gerrit already)
2014/04/15 21:18:37
Whitespace
| |
283 enum CollectionType { | |
284 kCollectionTypePhysical, | |
285 kCollectionTypeApplication, | |
286 kCollectionTypeLogical, | |
287 kCollectionTypeReport, | |
288 kCollectionTypeNamedArray, | |
289 kCollectionTypeUsageSwitch, | |
290 kCollectionTypeUsageModifier, | |
291 kCollectionTypeReserved, | |
292 kCollectionTypeVendor | |
293 }; | |
294 | |
295 uint8_t value; | |
296 | |
297 CollectionType collectionType() const { | |
Ken Rockot(use gerrit already)
2014/04/15 21:18:37
Please do not inline this. Same goes for the rest
| |
298 switch (value) { | |
299 case 0x00: | |
300 return kCollectionTypePhysical; | |
301 case 0x01: | |
302 return kCollectionTypePhysical; | |
303 case 0x02: | |
304 return kCollectionTypePhysical; | |
305 case 0x03: | |
306 return kCollectionTypePhysical; | |
307 case 0x04: | |
308 return kCollectionTypePhysical; | |
309 case 0x05: | |
310 return kCollectionTypePhysical; | |
311 case 0x06: | |
312 return kCollectionTypePhysical; | |
313 default: | |
314 break; | |
315 } | |
316 | |
317 if (0x80 < value && value < 0xFF) | |
318 return kCollectionTypeVendor; | |
319 | |
320 return kCollectionTypeReserved; | |
321 } | |
322 | |
323 private: | |
324 friend std::ostream& operator<<(std::ostream& os, const Collection& data) { | |
325 switch (data.collectionType()) { | |
326 case kCollectionTypePhysical: | |
327 os << "Physical"; | |
328 break; | |
329 case kCollectionTypeApplication: | |
330 os << "Application"; | |
331 break; | |
332 case kCollectionTypeLogical: | |
333 os << "Logical"; | |
334 break; | |
335 case kCollectionTypeReport: | |
336 os << "Report"; | |
337 break; | |
338 case kCollectionTypeNamedArray: | |
339 os << "Named Array"; | |
340 break; | |
341 case kCollectionTypeUsageSwitch: | |
342 os << "Usage Switch"; | |
343 break; | |
344 case kCollectionTypeUsageModifier: | |
345 os << "Usage Modifier"; | |
346 break; | |
347 case kCollectionTypeReserved: | |
348 os << "Reserved"; | |
349 break; | |
350 case kCollectionTypeVendor: | |
351 os << "Vendor"; | |
352 break; | |
353 default: | |
354 NOTREACHED(); | |
355 break; | |
356 } | |
357 return os; | |
358 } | |
359 }; | |
360 | |
361 struct EndCollection { | |
362 private: | |
363 friend std::ostream& operator<<(std::ostream& os, | |
364 const EndCollection& data) { | |
365 return os; | |
366 } | |
367 }; | |
368 | |
369 // (Short) Global Items | |
370 | |
371 struct UsagePage { | |
372 uint16_t value; | |
373 | |
374 private: | |
375 friend std::ostream& operator<<(std::ostream& os, const UsagePage& data) { | |
376 HidUsageAndPage::Page page = (HidUsageAndPage::Page)data.value; | |
377 os << page; | |
378 return os; | |
379 } | |
380 }; | |
381 | |
382 struct LogicalMinimum { | |
383 int32_t value; | |
384 | |
385 private: | |
386 friend std::ostream& operator<<(std::ostream& os, | |
387 const LogicalMinimum& data) { | |
388 os << data.value; | |
389 return os; | |
390 } | |
391 }; | |
392 | |
393 struct LogicalMaximum { | |
Ken Rockot(use gerrit already)
2014/04/15 21:18:37
There's a lot of code duplication going on here an
| |
394 int32_t value; | |
395 | |
396 private: | |
397 friend std::ostream& operator<<(std::ostream& os, | |
398 const LogicalMaximum& data) { | |
399 os << data.value; | |
400 return os; | |
401 } | |
402 }; | |
403 | |
404 struct PhysicalMinimum { | |
405 int32_t value; | |
406 | |
407 private: | |
408 friend std::ostream& operator<<(std::ostream& os, | |
409 const PhysicalMinimum& data) { | |
410 os << data.value; | |
411 return os; | |
412 } | |
413 }; | |
414 | |
415 struct PhysicalMaximum { | |
416 int32_t value; | |
417 | |
418 private: | |
419 friend std::ostream& operator<<(std::ostream& os, | |
420 const PhysicalMaximum& data) { | |
421 os << data.value; | |
422 return os; | |
423 } | |
424 }; | |
425 | |
426 struct UnitExponent { | |
427 uint32_t value; | |
428 | |
429 private: | |
430 friend std::ostream& operator<<(std::ostream& os, | |
431 const UnitExponent& data) { | |
432 os << data.value; | |
433 return os; | |
434 } | |
435 }; | |
436 | |
437 struct Unit { | |
438 uint32_t value; | |
439 | |
440 private: | |
441 friend std::ostream& operator<<(std::ostream& os, const Unit& data) { | |
442 os << data.value; | |
443 return os; | |
444 } | |
445 }; | |
446 | |
447 struct ReportSize { | |
448 uint32_t value; | |
449 | |
450 private: | |
451 friend std::ostream& operator<<(std::ostream& os, const ReportSize& data) { | |
452 os << data.value; | |
453 return os; | |
454 } | |
455 }; | |
456 | |
457 struct ReportId { | |
458 uint32_t value; | |
459 | |
460 private: | |
461 friend std::ostream& operator<<(std::ostream& os, const ReportId& data) { | |
462 os << "0x" << std::hex << std::uppercase << data.value; | |
463 return os; | |
464 } | |
465 }; | |
466 | |
467 struct ReportCount { | |
468 uint32_t value; | |
469 | |
470 private: | |
471 friend std::ostream& operator<<(std::ostream& os, const ReportCount& data) { | |
472 os << data.value; | |
473 return os; | |
474 } | |
475 }; | |
476 | |
477 struct Push { | |
478 private: | |
479 friend std::ostream& operator<<(std::ostream& os, const Push& data) { | |
480 return os; | |
481 } | |
482 }; | |
483 | |
484 struct Pop { | |
485 private: | |
486 friend std::ostream& operator<<(std::ostream& os, const Pop& data) { | |
487 return os; | |
488 } | |
489 }; | |
490 | |
491 // (Short) Local Items | |
492 | |
493 struct Usage { | |
494 uint16_t value; | |
495 | |
496 private: | |
497 friend std::ostream& operator<<(std::ostream& os, const Usage& data) { | |
498 os << "0x" << std::hex << std::uppercase << data.value; | |
499 return os; | |
500 } | |
501 }; | |
502 | |
503 struct UsageMinimum { | |
504 uint16_t value; | |
505 | |
506 private: | |
507 friend std::ostream& operator<<(std::ostream& os, | |
508 const UsageMinimum& data) { | |
509 os << "0x" << std::hex << std::uppercase << data.value; | |
510 return os; | |
511 } | |
512 }; | |
513 | |
514 struct UsageMaximum { | |
515 uint16_t value; | |
516 | |
517 private: | |
518 friend std::ostream& operator<<(std::ostream& os, | |
519 const UsageMaximum& data) { | |
520 os << "0x" << std::hex << std::uppercase << data.value; | |
521 return os; | |
522 } | |
523 }; | |
524 | |
525 struct DesignatorIndex { | |
526 private: | |
527 friend std::ostream& operator<<(std::ostream& os, | |
528 const DesignatorIndex& data) { | |
529 return os; | |
530 } | |
531 }; | |
532 | |
533 struct DesignatorMinimum { | |
534 private: | |
535 friend std::ostream& operator<<(std::ostream& os, | |
536 const DesignatorMinimum& data) { | |
537 return os; | |
538 } | |
539 }; | |
540 | |
541 struct DesignatorMaximum { | |
542 private: | |
543 friend std::ostream& operator<<(std::ostream& os, | |
544 const DesignatorMaximum& data) { | |
545 return os; | |
546 } | |
547 }; | |
548 | |
549 struct StringIndex { | |
550 private: | |
551 friend std::ostream& operator<<(std::ostream& os, const StringIndex& data) { | |
552 return os; | |
553 } | |
554 }; | |
555 | |
556 struct StringMinimum { | |
557 private: | |
558 friend std::ostream& operator<<(std::ostream& os, | |
559 const StringMinimum& data) { | |
560 return os; | |
561 } | |
562 }; | |
563 | |
564 struct StringMaximum { | |
565 private: | |
566 friend std::ostream& operator<<(std::ostream& os, | |
567 const StringMaximum& data) { | |
568 return os; | |
569 } | |
570 }; | |
571 | |
572 struct Delimiter { | |
573 private: | |
574 friend std::ostream& operator<<(std::ostream& os, const Delimiter& data) { | |
575 return os; | |
576 } | |
577 }; | |
578 | |
579 // (Long) Reserved items | |
580 // nothing for now | |
581 | |
582 // Data union | |
583 | |
584 struct Data { | |
585 union u { | |
586 // (Short) Main items | |
587 Default none; | |
588 Input_Output_Feature input; | |
589 Input_Output_Feature output; | |
590 Input_Output_Feature feature; | |
591 Collection collection; | |
592 EndCollection end_collection; | |
593 // (Short) Global items | |
594 UsagePage usage_page; | |
595 LogicalMinimum logical_minimum; | |
596 LogicalMaximum logical_maximum; | |
597 PhysicalMinimum physical_minimum; | |
598 PhysicalMaximum physical_maximum; | |
599 UnitExponent unit_exponent; | |
600 Unit unit; | |
601 ReportSize report_size; | |
602 ReportId report_id; | |
603 ReportCount report_count; | |
604 Push push; | |
605 Pop pop; | |
606 // (Short) Local items | |
607 Usage usage; | |
608 UsageMinimum usage_minimum; | |
609 UsageMaximum usage_maximum; | |
610 DesignatorIndex designator_index; | |
611 DesignatorMinimum designator_minimum; | |
612 DesignatorMaximum designator_maximum; | |
613 StringIndex string_index; | |
614 StringMinimum string_minimum; | |
615 StringMaximum string_maximum; | |
616 Delimiter delimiter; | |
617 // (Long) Reserved items | |
618 // nothing for now | |
619 }; | |
620 }; | |
621 | |
622 #pragma pack(pop) | |
623 | |
624 HidReportDescriptorItem(const uint8_t* bytes, | |
625 HidReportDescriptorItem* previous = NULL); | |
Ken Rockot(use gerrit already)
2014/04/15 21:18:37
Please, no default argument values. Please specify
jracle (use Gerrit)
2014/04/16 16:39:19
Done
| |
626 ~HidReportDescriptorItem(); | |
627 | |
628 HidReportDescriptorItem* previous() const { | |
Ken Rockot(use gerrit already)
2014/04/15 21:18:37
Please make it clear that neither this item nor th
| |
629 return previous_; | |
630 }; | |
631 HidReportDescriptorItem* next() const { | |
632 return next_; | |
633 }; | |
634 HidReportDescriptorItem* parent() const { | |
635 return parent_; | |
636 }; | |
637 size_t depth() const; | |
Ken Rockot(use gerrit already)
2014/04/15 21:18:37
GetDepth() please. Lowercase names are for trivial
| |
638 | |
639 bool isLong() const; | |
Ken Rockot(use gerrit already)
2014/04/15 21:18:37
IsLong() please.
| |
640 size_t headerSize() const; | |
Ken Rockot(use gerrit already)
2014/04/15 21:18:37
GetHeaderSize() please.
| |
641 size_t payloadSize() const; | |
Ken Rockot(use gerrit already)
2014/04/15 21:18:37
GetPayloadSize() please.
| |
642 size_t size() const; | |
Ken Rockot(use gerrit already)
2014/04/15 21:18:37
GetSize()
Also because none of these are trivial
| |
643 | |
644 Header* header() const; | |
Ken Rockot(use gerrit already)
2014/04/15 21:18:37
This (and longHeader) make me extremely uncomforta
jracle (use Gerrit)
2014/04/16 16:39:19
Now private in next patch-set, and accessed by val
| |
645 LongHeader* longHeader() const; | |
646 | |
647 Tag tag() const; | |
Ken Rockot(use gerrit already)
2014/04/15 21:18:37
GetTag() please.
| |
648 Data* data() const; | |
Ken Rockot(use gerrit already)
2014/04/15 21:18:37
Since Data is a POD type, and you can change it so
jracle (use Gerrit)
2014/04/16 16:39:19
Data is actually known only for short items.
It ha
| |
649 | |
650 private: | |
651 friend std::ostream& operator<<(std::ostream& os, | |
652 const HidReportDescriptorItem& item) { | |
Ken Rockot(use gerrit already)
2014/04/15 21:18:37
Please see base/strings/stringprintf.h for the bas
jracle (use Gerrit)
2014/04/16 16:39:19
This I didn't catch yet, can you handle it in a ne
| |
653 Tag tg = item.tag(); | |
654 Data* dt = item.data(); | |
655 | |
656 std::ostringstream sstr; | |
657 sstr << tg; | |
658 sstr << " ("; | |
659 | |
660 long pos = sstr.tellp(); | |
661 switch (tg) { | |
662 case kTagDefault: | |
663 sstr << *(Default*)dt; | |
664 break; | |
665 case kTagInput: | |
666 case kTagOutput: | |
667 case kTagFeature: | |
668 sstr << *(Input_Output_Feature*)dt; | |
669 break; | |
670 case kTagCollection: | |
671 sstr << *(Collection*)dt; | |
672 break; | |
673 case kTagEndCollection: | |
674 sstr << *(EndCollection*)dt; | |
675 break; | |
676 case kTagUsagePage: | |
677 sstr << *(UsagePage*)dt; | |
678 break; | |
679 case kTagLogicalMinimum: | |
680 sstr << *(LogicalMinimum*)dt; | |
681 break; | |
682 case kTagLogicalMaximum: | |
683 sstr << *(LogicalMaximum*)dt; | |
684 break; | |
685 case kTagPhysicalMinimum: | |
686 sstr << *(PhysicalMinimum*)dt; | |
687 break; | |
688 case kTagPhysicalMaximum: | |
689 sstr << *(PhysicalMaximum*)dt; | |
690 break; | |
691 case kTagUnitExponent: | |
692 sstr << *(UnitExponent*)dt; | |
693 break; | |
694 case kTagUnit: | |
695 sstr << *(Unit*)dt; | |
696 break; | |
697 case kTagReportSize: | |
698 sstr << *(ReportSize*)dt; | |
699 break; | |
700 case kTagReportId: | |
701 sstr << *(ReportId*)dt; | |
702 break; | |
703 case kTagReportCount: | |
704 sstr << *(ReportCount*)dt; | |
705 break; | |
706 case kTagPush: | |
707 sstr << *(Push*)dt; | |
708 break; | |
709 case kTagPop: | |
710 sstr << *(Pop*)dt; | |
711 break; | |
712 case kTagUsage: | |
713 sstr << *(Usage*)dt; | |
714 break; | |
715 case kTagUsageMinimum: | |
716 sstr << *(UsageMinimum*)dt; | |
717 break; | |
718 case kTagUsageMaximum: | |
719 sstr << *(UsageMaximum*)dt; | |
720 break; | |
721 case kTagDesignatorIndex: | |
722 sstr << *(DesignatorIndex*)dt; | |
723 break; | |
724 case kTagDesignatorMinimum: | |
725 sstr << *(DesignatorMinimum*)dt; | |
726 break; | |
727 case kTagDesignatorMaximum: | |
728 sstr << *(DesignatorMaximum*)dt; | |
729 break; | |
730 case kTagStringIndex: | |
731 sstr << *(StringIndex*)dt; | |
732 break; | |
733 case kTagStringMinimum: | |
734 sstr << *(StringMinimum*)dt; | |
735 break; | |
736 case kTagStringMaximum: | |
737 sstr << *(StringMaximum*)dt; | |
738 break; | |
739 case kTagDelimiter: | |
740 sstr << *(Delimiter*)dt; | |
741 break; | |
742 case kTagLong: | |
743 break; | |
744 default: | |
745 NOTREACHED(); | |
746 break; | |
747 } | |
748 | |
749 if (pos == sstr.tellp()) { | |
750 std::string str = sstr.str(); | |
751 str.erase(str.end() - 2, str.end()); | |
752 os << str; | |
753 } else { | |
754 os << sstr.str() << ")"; | |
755 } | |
756 | |
757 return os; | |
758 } | |
759 | |
760 const uint8_t* bytes_; | |
761 HidReportDescriptorItem* previous_; | |
762 HidReportDescriptorItem* next_; | |
763 HidReportDescriptorItem* parent_; | |
764 }; | |
765 | |
766 // HID report descriptor. | |
767 // See section 6.2.2 of HID specifications (v1.11). | |
768 class HidReportDescriptor { | |
769 | |
770 private: | |
771 static const char kIndentChar; | |
772 | |
773 public: | |
774 HidReportDescriptor(const uint8_t* bytes, size_t size); | |
775 ~HidReportDescriptor(); | |
776 | |
777 const std::vector<HidReportDescriptorItem*>& items() const; | |
Ken Rockot(use gerrit already)
2014/04/15 21:18:37
items is a trivial accessor; please feel free to i
jracle (use Gerrit)
2014/04/16 16:39:19
OK
| |
778 std::vector<HidUsageAndPage> topLevelCollections() const; | |
Ken Rockot(use gerrit already)
2014/04/15 21:18:37
GetTopLevelCollections() please. This is not a tri
jracle (use Gerrit)
2014/04/16 16:39:19
OK
| |
779 | |
780 private: | |
781 friend std::ostream& operator<<(std::ostream& os, | |
782 const HidReportDescriptor& descriptor) { | |
Ken Rockot(use gerrit already)
2014/04/15 21:18:37
Please do not inline this definition. In fact it d
| |
783 for (std::vector<HidReportDescriptorItem*>::const_iterator items_iter = | |
784 descriptor.items_.begin(); | |
785 items_iter != descriptor.items_.end(); | |
786 ++items_iter) { | |
787 HidReportDescriptorItem* item = *items_iter; | |
788 size_t indentLevel = item->depth(); | |
789 for (size_t i = 0; i < indentLevel; i++) | |
790 os << kIndentChar; | |
791 os << *item << std::endl; | |
792 } | |
793 return os; | |
794 } | |
795 | |
796 const uint8_t* bytes_; | |
797 size_t size_; | |
798 std::vector<HidReportDescriptorItem*> items_; | |
Ken Rockot(use gerrit already)
2014/04/15 21:18:37
Please use linked_ptr here
std::vector<linked_ptr
jracle (use Gerrit)
2014/04/16 16:39:19
Indeed
| |
799 }; | |
800 | |
801 } // namespace device | |
802 | |
803 #endif // DEVICE_HID_HID_REPORT_DESCRIPTOR_H_ | |
OLD | NEW |