VirtualBox

source: vbox/trunk/src/VBox/Main/include/USBIdDatabase.h@ 63470

Last change on this file since 63470 was 62485, checked in by vboxsync, 8 years ago

(C) 2016

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.2 KB
Line 
1/* $Id: USBIdDatabase.h 62485 2016-07-22 18:36:43Z vboxsync $ */
2/** @file
3 * USB device vendor and product ID database.
4 */
5
6/*
7 * Copyright (C) 2015-2016 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18#ifndef ___USBIdDatabase_h
19#define ___USBIdDatabase_h
20
21#include <iprt/assert.h>
22#include <iprt/stdint.h>
23#include <iprt/cpp/ministring.h>
24#include <iprt/bldprog-strtab.h>
25
26
27/** Saves a few bytes (~25%) on strings. */
28#define USB_ID_DATABASE_WITH_COMPRESSION
29
30/** Max string length. */
31#define USB_ID_DATABASE_MAX_STRING _1K
32
33
34AssertCompileSize(RTBLDPROGSTRREF, sizeof(uint32_t));
35
36
37/**
38 * Elements of product table.
39 */
40typedef struct USBIDDBPROD
41{
42 /** Product ID. */
43 uint16_t idProduct;
44} USBIDDBPROD;
45AssertCompileSize(USBIDDBPROD, sizeof(uint16_t));
46
47
48/**
49 * Element of vendor table.
50 */
51typedef struct USBIDDBVENDOR
52{
53 /** Vendor ID. */
54 uint16_t idVendor;
55 /** Index of the first product. */
56 uint16_t iProduct;
57 /** Number of products. */
58 uint16_t cProducts;
59} USBIDDBVENDOR;
60AssertCompileSize(USBIDDBVENDOR, sizeof(uint16_t) * 3);
61
62
63/**
64 * Wrapper for static array of Aliases.
65 */
66class USBIdDatabase
67{
68public: // For assertions and statis in the generator.
69 /** The compressed string table. */
70 static RTBLDPROGSTRTAB const s_StrTab;
71
72 /** Number of vendors in the two parallel arrays. */
73 static const size_t s_cVendors;
74 /** Vendor IDs lookup table. */
75 static const USBIDDBVENDOR s_aVendors[];
76 /** Vendor names table running parallel to s_aVendors. */
77 static const RTBLDPROGSTRREF s_aVendorNames[];
78
79 /** Number of products in the two parallel arrays. */
80 static const size_t s_cProducts;
81 /** Vendor+Product keys for lookup purposes. */
82 static const USBIDDBPROD s_aProducts[];
83 /** Product names table running parallel to s_aProducts. */
84 static const RTBLDPROGSTRREF s_aProductNames[];
85
86public:
87 static RTCString returnString(PCRTBLDPROGSTRREF pStr)
88 {
89 char szTmp[USB_ID_DATABASE_MAX_STRING * 2];
90 ssize_t cchTmp = RTBldProgStrTabQueryString(&s_StrTab, pStr->off, pStr->cch, szTmp, sizeof(szTmp));
91 return RTCString(szTmp, RT_MAX(cchTmp, 0));
92 }
93
94private:
95 /**
96 * Performs a binary lookup of @a idVendor.
97 *
98 * @returns The index in the vendor tables, UINT32_MAX if not found.
99 * @param idVendor The vendor ID.
100 */
101 static uint32_t lookupVendor(uint16_t idVendor)
102 {
103 size_t iEnd = s_cVendors;
104 if (iEnd)
105 {
106 size_t iStart = 0;
107 for (;;)
108 {
109 size_t idx = iStart + (iEnd - iStart) / 2;
110 if (s_aVendors[idx].idVendor < idVendor)
111 {
112 idx++;
113 if (idx < iEnd)
114 iStart = idx;
115 else
116 break;
117 }
118 else if (s_aVendors[idx].idVendor > idVendor)
119 {
120 if (idx != iStart)
121 iEnd = idx;
122 else
123 break;
124 }
125 else
126 return (uint32_t)idx;
127 }
128 }
129 return UINT32_MAX;
130 }
131
132 /**
133 * Performs a binary lookup of @a idProduct.
134 *
135 * @returns The index in the product tables, UINT32_MAX if not found.
136 * @param idProduct The product ID.
137 * @param iStart The index of the first entry for the vendor.
138 * @param iEnd The index of after the last entry.
139 */
140 static uint32_t lookupProduct(uint16_t idProduct, size_t iStart, size_t iEnd)
141 {
142 if (iStart < iEnd)
143 {
144 for (;;)
145 {
146 size_t idx = iStart + (iEnd - iStart) / 2;
147 if (s_aProducts[idx].idProduct < idProduct)
148 {
149 idx++;
150 if (idx < iEnd)
151 iStart = idx;
152 else
153 break;
154 }
155 else if (s_aProducts[idx].idProduct > idProduct)
156 {
157 if (idx != iStart)
158 iEnd = idx;
159 else
160 break;
161 }
162 else
163 return (uint32_t)idx;
164 }
165 }
166 return UINT32_MAX;
167 }
168
169
170public:
171 static RTCString findProduct(uint16_t idVendor, uint16_t idProduct)
172 {
173 uint32_t idxVendor = lookupVendor(idVendor);
174 if (idxVendor != UINT32_MAX)
175 {
176 uint32_t idxProduct = lookupProduct(idProduct, s_aVendors[idxVendor].iProduct,
177 s_aVendors[idxVendor].iProduct + s_aVendors[idxVendor].cProducts);
178 if (idxProduct != UINT32_MAX)
179 return returnString(&s_aProductNames[idxProduct]);
180 }
181 return RTCString();
182 }
183
184 static RTCString findVendor(uint16_t idVendor)
185 {
186 uint32_t idxVendor = lookupVendor(idVendor);
187 if (idxVendor != UINT32_MAX)
188 return returnString(&s_aVendorNames[idxVendor]);
189 return RTCString();
190 }
191
192 static RTCString findVendorAndProduct(uint16_t idVendor, uint16_t idProduct, RTCString *pstrProduct)
193 {
194 uint32_t idxVendor = lookupVendor(idVendor);
195 if (idxVendor != UINT32_MAX)
196 {
197 uint32_t idxProduct = lookupProduct(idProduct, s_aVendors[idxVendor].iProduct,
198 s_aVendors[idxVendor].iProduct + s_aVendors[idxVendor].cProducts);
199 if (idxProduct != UINT32_MAX)
200 *pstrProduct = returnString(&s_aProductNames[idxProduct]);
201 else
202 pstrProduct->setNull();
203 return returnString(&s_aVendorNames[idxVendor]);
204 }
205 pstrProduct->setNull();
206 return RTCString();
207 }
208
209};
210
211
212#endif
213
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette