Changeset 59734 in vbox for trunk/src/VBox/Main
- Timestamp:
- Feb 19, 2016 2:15:41 AM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/src-server/USBIdDatabaseGenerator.cpp
r59733 r59734 58 58 /** For verbose output. */ 59 59 static bool g_fVerbose = false; 60 /** Output prefix for informational output. */61 #define INFO_PREF "USBIdDatabaseGenerator: Info: "62 63 64 using namespace std;65 60 66 61 static const char * const header = … … 151 146 }; 152 147 153 154 namespace State 155 { 156 typedef int Value; 157 enum 158 { 159 lookForStartBlock, 160 lookForEndBlock, 161 finished 162 }; 163 } 164 165 typedef vector<ProductRecord> ProductsSet; 166 typedef vector<VendorRecord> VendorsSet; 148 typedef std::vector<ProductRecord> ProductsSet; 149 typedef std::vector<VendorRecord> VendorsSet; 167 150 168 151 … … 202 185 * Input file parsing. 203 186 */ 204 int ParseAlias(const string& src, size_t& id, string& desc) 205 { 206 unsigned int i = 0; 207 if (sscanf(src.c_str(), "%x", &i) != 1) 208 return ERROR_IN_PARSE_LINE; 209 210 /* skip the number and following whitespace. */ 211 size_t offNext = src.find_first_of(" \t", 1); 212 offNext = src.find_first_not_of(" \t", offNext); 213 if (offNext != string::npos) 214 { 215 size_t cchLength = src.length() - offNext; 216 if (cchLength <= USB_ID_DATABASE_MAX_STRING) 217 { 218 id = i; 219 desc = src.substr(offNext); 220 221 /* Check the string encoding. */ 222 int rc = RTStrValidateEncoding(desc.c_str()); 187 int ParseAlias(char *pszLine, size_t& id, std::string& desc) 188 { 189 /* First there's a hexadeciman number. */ 190 uint32_t uVal; 191 char *pszNext; 192 int rc = RTStrToUInt32Ex(pszLine, &pszNext, 16, &uVal); 193 if ( rc == VWRN_TRAILING_CHARS 194 || rc == VWRN_TRAILING_SPACES 195 || rc == VINF_SUCCESS) 196 { 197 /* Skip the whipespace following it and at the end of the line. */ 198 pszNext = RTStrStripL(pszNext); 199 if (*pszNext != '\0') 200 { 201 rc = RTStrValidateEncoding(pszNext); 223 202 if (RT_SUCCESS(rc)) 224 203 { 225 g_cbRawStrings += desc.length() + 1; 226 return RTEXITCODE_SUCCESS; 204 size_t cchDesc = strlen(pszNext); 205 if (cchDesc <= USB_ID_DATABASE_MAX_STRING) 206 { 207 id = uVal; 208 desc = pszNext; 209 g_cbRawStrings += cchDesc + 1; 210 return RTEXITCODE_SUCCESS; 211 } 212 RTMsgError("String to long: %zu", cchDesc); 227 213 } 228 229 RTMsgError("Invalid encoding: '%s' (rc=%Rrc)", desc.c_str(), rc);214 else 215 RTMsgError("Invalid encoding: '%s' (rc=%Rrc)", pszNext, rc); 230 216 } 231 217 else 232 RTMsgError(" String to long: %zu", cchLength);218 RTMsgError("Error parsing '%s'", pszLine); 233 219 } 234 220 else 235 RTMsgError("Error parsing '%s'", src.c_str());221 RTMsgError("Error converting number at the start of '%s': %Rrc", pszLine, rc); 236 222 return ERROR_IN_PARSE_LINE; 237 223 } 238 224 239 bool IsCommentOrEmptyLine(const string& str) 240 { 241 size_t index = str.find_first_not_of(" \t");// skip left spaces 242 return index == string::npos || str[index] == '#'; 243 } 244 245 bool getline(PRTSTREAM instream, string& resString) 246 { 247 const size_t szBuf = 4096; 248 char buf[szBuf] = { 0 }; 249 250 int rc = RTStrmGetLine(instream, buf, szBuf); 251 if (RT_SUCCESS(rc)) 252 { 253 resString = buf; 254 return true; 255 } 256 257 if (rc != VERR_EOF) 258 RTMsgWarning("RTStrmGetLine failed: %Rrc", rc); 259 return false; 225 bool IsCommentOrEmptyLine(const char *pszLine) 226 { 227 pszLine = RTStrStripL(pszLine); 228 return *pszLine == '#' || *pszLine == '\0'; 260 229 } 261 230 262 231 int ParseUsbIds(PRTSTREAM instream) 263 232 { 264 State::Value state = State::lookForStartBlock; 265 string line; 266 int res = 0; 233 /* 234 * State data. 235 * We check for a certain comment string before processing data. 236 */ 237 bool fLookingForData = false; 267 238 VendorRecord vendor = { 0, 0, 0, "" }; 268 239 269 while (state != State::finished && getline(instream, line)) 270 { 271 switch (state) 272 { 273 case State::lookForStartBlock: 240 /* 241 * Process the file line-by-line. 242 */ 243 for (;;) 244 { 245 char szLine[_4K]; 246 int rc = RTStrmGetLine(instream, szLine, sizeof(szLine)); 247 if (RT_SUCCESS(rc)) 248 { 249 if (!fLookingForData) 274 250 { 275 if (line.find(start_block) != string::npos) 276 state = State::lookForEndBlock; 277 break; 278 } 279 case State::lookForEndBlock: 280 { 281 if (line.find(end_block) != string::npos) 282 state = State::finished; 283 else 251 if (!strstr(szLine, end_block)) 284 252 { 285 if (!IsCommentOrEmptyLine( line))253 if (!IsCommentOrEmptyLine(szLine)) 286 254 { 287 if ( line[0] == '\t')255 if (szLine[0] == '\t') 288 256 { 289 257 // Parse Product line … … 291 259 if (vendor.vendorID == 0) 292 260 return RTMsgErrorExit((RTEXITCODE)ERROR_WRONG_FILE_FORMAT, 293 "Wrong file format. Product before vendor: '%s'", line.c_str());261 "Wrong file format. Product before vendor: '%s'", szLine); 294 262 ProductRecord product = { 0, vendor.vendorID, 0, "" }; 295 if (ParseAlias( line.substr(1), product.productID, product.str) != 0)263 if (ParseAlias(&szLine[1], product.productID, product.str) != 0) 296 264 return RTMsgErrorExit((RTEXITCODE)ERROR_IN_PARSE_LINE, 297 "Error in parsing product line: ' ", line.c_str());265 "Error in parsing product line: '%s'", szLine); 298 266 product.key = RT_MAKE_U32(product.productID, product.vendorID); 299 267 Assert(product.vendorID == vendor.vendorID); … … 303 271 { 304 272 // Parse vendor line 305 if (ParseAlias( line, vendor.vendorID, vendor.str) != 0)273 if (ParseAlias(szLine, vendor.vendorID, vendor.str) != 0) 306 274 return RTMsgErrorExit((RTEXITCODE)ERROR_IN_PARSE_LINE, 307 "Error in parsing vendor line: ' ", line.c_str());275 "Error in parsing vendor line: '%s'", szLine); 308 276 g_vendors.push_back(vendor); 309 277 } 310 278 } 311 279 } 312 break; 280 else 281 return RTEXITCODE_SUCCESS; 313 282 } 314 } 315 } 316 if (state == State::lookForStartBlock) 317 return RTMsgErrorExit((RTEXITCODE)ERROR_WRONG_FILE_FORMAT, 318 "wrong format of input file. Start line is not found."); 319 return 0; 283 else if (strstr(szLine, start_block)) 284 fLookingForData = false; 285 } 286 else if (rc == VERR_EOF) 287 return RTEXITCODE_SUCCESS; 288 else 289 return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTStrmGetLine failed: %Rrc", rc); 290 } 320 291 } 321 292 … … 442 413 443 414 /* 444 * Print stats. 415 * Print stats. Making a little extra effort to get it all on one line. 445 416 */ 446 417 size_t const cbVendorEntry = sizeof(USBIdDatabase::s_aVendors[0]) + sizeof(USBIdDatabase::s_aVendorNames[0]); … … 453 424 cbActual += sizeof(StrTab.aCompDict); 454 425 #endif 455 cout << INFO_PREF "Total " << dec << cbActual << " bytes"; 426 427 char szMsg1[32]; 428 RTStrPrintf(szMsg1, sizeof(szMsg1),"Total %zu bytes", cbActual); 429 char szMsg2[64]; 430 RTStrPrintf(szMsg2, sizeof(szMsg2)," old version %zu bytes + relocs (%zu%% save)", 431 cbOldRaw, (cbOldRaw - cbActual) * 100 / cbOldRaw); 456 432 if (cbActual < cbRaw) 457 cout << " saving " << dec << ((cbRaw - cbActual) * 100 / cbRaw) << "% (" << (cbRaw - cbActual) << " bytes)";433 RTMsgInfo("%s - saving %zu%% (%zu bytes);%s", szMsg1, (cbRaw - cbActual) * 100 / cbRaw, cbRaw - cbActual, szMsg2); 458 434 else 459 cout << " wasting " << dec << (cbActual - cbRaw) << " bytes"; 460 cout << "; old version " << cbOldRaw << " bytes + relocs (" 461 << ((cbOldRaw - cbActual) * 100 / cbOldRaw) << "% save)." << endl; 462 435 RTMsgInfo("%s - wasting %zu bytes;%s", szMsg1, cbActual - cbRaw, szMsg2); 463 436 464 437 /*
Note:
See TracChangeset
for help on using the changeset viewer.