Changeset 90010 in vbox for trunk/src/VBox/Devices/Audio
- Timestamp:
- Jul 4, 2021 7:37:45 PM (4 years ago)
- svn:sync-xref-src-repo-rev:
- 145499
- Location:
- trunk/src/VBox/Devices/Audio
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/AudioHlp.cpp
r89447 r90010 235 235 236 236 /** 237 * Sanitizes the file name component so that unsupported characters238 * will be replaced by an underscore ("_").239 *240 * @returns VBox status code.241 * @param pszPath Path to sanitize.242 * @param cbPath Size (in bytes) of path to sanitize.243 */244 int AudioHlpFileNameSanitize(char *pszPath, size_t cbPath)245 {246 RT_NOREF(cbPath);247 int rc = VINF_SUCCESS;248 #ifdef RT_OS_WINDOWS249 /* Filter out characters not allowed on Windows platforms, put in by250 RTTimeSpecToString(). */251 /** @todo Use something like RTPathSanitize() if available later some time. */252 static RTUNICP const s_uszValidRangePairs[] =253 {254 ' ', ' ',255 '(', ')',256 '-', '.',257 '0', '9',258 'A', 'Z',259 'a', 'z',260 '_', '_',261 0xa0, 0xd7af,262 '\0'263 };264 ssize_t cReplaced = RTStrPurgeComplementSet(pszPath, s_uszValidRangePairs, '_' /* Replacement */);265 if (cReplaced < 0)266 rc = VERR_INVALID_UTF8_ENCODING;267 #else268 RT_NOREF(pszPath);269 #endif270 return rc;271 }272 273 /**274 237 * Constructs an unique file name, based on the given path and the audio file type. 275 238 * 276 239 * @returns VBox status code. 277 * @param pszFile Where to store the constructed file name. 278 * @param cchFile Size (in characters) of the file name buffer. 279 * @param pszPath Base path to use. 280 * If NULL or empty, the system's temporary directory will be used. 281 * @param pszName A name for better identifying the file. 282 * @param uInstance Device / driver instance which is using this file. 283 * @param enmType Audio file type to construct file name for. 284 * @param fFlags File naming flags, AUDIOHLPFILENAME_FLAGS_XXX. 285 */ 286 int AudioHlpFileNameGet(char *pszFile, size_t cchFile, const char *pszPath, const char *pszName, 240 * @param pszDst Where to store the constructed file name. 241 * @param cbDst Size of the destination buffer (bytes; incl terminator). 242 * @param pszPath Base path to use. If NULL or empty, the user's 243 * temporary directory will be used. 244 * @param pszName A name for better identifying the file. 245 * @param uInstance Device / driver instance which is using this file. 246 * @param enmType Audio file type to construct file name for. 247 * @param fFlags File naming flags, AUDIOHLPFILENAME_FLAGS_XXX. 248 * @param chTweak Retry tweak character. 249 */ 250 static int audioHlpConstructPathWorker(char *pszDst, size_t cbDst, const char *pszPath, const char *pszName, 251 uint32_t uInstance, AUDIOHLPFILETYPE enmType, uint32_t fFlags, char chTweak) 252 { 253 /* 254 * Validate input. 255 */ 256 AssertPtrNullReturn(pszPath, VERR_INVALID_POINTER); 257 AssertPtrReturn(pszName, VERR_INVALID_POINTER); 258 AssertReturn(!(fFlags & ~AUDIOHLPFILENAME_FLAGS_VALID_MASK), VERR_INVALID_FLAGS); 259 260 /* Validate the type and translate it into a suffix. */ 261 const char *pszSuffix = NULL; 262 switch (enmType) 263 { 264 case AUDIOHLPFILETYPE_RAW: pszSuffix = ".pcm"; break; 265 case AUDIOHLPFILETYPE_WAV: pszSuffix = ".wav"; break; 266 case AUDIOHLPFILETYPE_INVALID: 267 case AUDIOHLPFILETYPE_32BIT_HACK: 268 break; /* no default */ 269 } 270 AssertMsgReturn(pszSuffix, ("enmType=%d\n", enmType), VERR_INVALID_PARAMETER); 271 272 /* 273 * The directory. Make sure it exists and ends with a path separator. 274 */ 275 int rc; 276 if (!pszPath || !*pszPath) 277 rc = RTPathTemp(pszDst, cbDst); 278 else 279 { 280 AssertPtrReturn(pszDst, VERR_INVALID_POINTER); 281 rc = RTStrCopy(pszDst, cbDst, pszPath); 282 } 283 AssertRCReturn(rc, rc); 284 285 if (!RTDirExists(pszDst)) 286 { 287 rc = RTDirCreateFullPath(pszDst, RTFS_UNIX_IRWXU); 288 AssertRCReturn(rc, rc); 289 } 290 291 size_t offDst = RTPathEnsureTrailingSeparator(pszDst, cbDst); 292 AssertReturn(offDst > 0, VERR_BUFFER_OVERFLOW); 293 Assert(offDst < cbDst); 294 295 /* 296 * The filename. 297 */ 298 /* Start with a ISO timestamp w/ colons replaced by dashes if requested. */ 299 if (fFlags & AUDIOHLPFILENAME_FLAGS_TS) 300 { 301 RTTIMESPEC NowTimeSpec; 302 RTTIME NowUtc; 303 AssertReturn(RTTimeToString(RTTimeExplode(&NowUtc, RTTimeNow(&NowTimeSpec)), &pszDst[offDst], cbDst - offDst), 304 VERR_BUFFER_OVERFLOW); 305 306 /* Change the two colons in the time part to dashes. */ 307 char *pchColon = &pszDst[offDst]; 308 while ((pchColon = strchr(pchColon, ':')) != NULL) 309 *pchColon++ = '-'; 310 311 offDst += strlen(&pszDst[offDst]); 312 Assert(pszDst[offDst - 1] == 'Z'); 313 314 /* Append a dash to separate the timestamp from the name. */ 315 AssertReturn(offDst + 2 <= cbDst, VERR_BUFFER_OVERFLOW); 316 pszDst[offDst++] = '-'; 317 pszDst[offDst] = '\0'; 318 } 319 320 /* Append the filename, instance, retry-tweak and suffix. */ 321 ssize_t cchTail; 322 if (chTweak == '\0') 323 cchTail = RTStrPrintf2(&pszDst[offDst], cbDst - offDst, "%s-%u%s", pszName, uInstance, pszSuffix); 324 else 325 cchTail = RTStrPrintf2(&pszDst[offDst], cbDst - offDst, "%s-%u%c%s", pszName, uInstance, chTweak, pszSuffix); 326 AssertReturn(cchTail > 0, VERR_BUFFER_OVERFLOW); 327 328 return VINF_SUCCESS; 329 } 330 331 /** 332 * Constructs an unique file name, based on the given path and the audio file type. 333 * 334 * @returns VBox status code. 335 * @param pszDst Where to store the constructed file name. 336 * @param cbDst Size of the destination buffer (bytes; incl terminator). 337 * @param pszPath Base path to use. If NULL or empty, the user's 338 * temporary directory will be used. 339 * @param pszName A name for better identifying the file. 340 * @param uInstance Device / driver instance which is using this file. 341 * @param enmType Audio file type to construct file name for. 342 * @param fFlags File naming flags, AUDIOHLPFILENAME_FLAGS_XXX. 343 */ 344 int AudioHlpFileNameGet(char *pszDst, size_t cbDst, const char *pszPath, const char *pszName, 287 345 uint32_t uInstance, AUDIOHLPFILETYPE enmType, uint32_t fFlags) 288 346 { 289 AssertPtrReturn(pszFile, VERR_INVALID_POINTER); 290 AssertReturn(cchFile, VERR_INVALID_PARAMETER); 291 /* pszPath can be NULL. */ 292 AssertPtrReturn(pszName, VERR_INVALID_POINTER); 293 /** @todo Validate fFlags. */ 294 295 int rc; 296 297 char *pszPathTmp = NULL; 298 299 do 300 { 301 if ( pszPath == NULL 302 || !strlen(pszPath)) 303 { 304 char szTemp[RTPATH_MAX]; 305 rc = RTPathTemp(szTemp, sizeof(szTemp)); 306 if (RT_SUCCESS(rc)) 307 { 308 pszPathTmp = RTStrDup(szTemp); 309 } 310 else 311 break; 312 } 313 else 314 pszPathTmp = RTStrDup(pszPath); 315 316 AssertPtrBreakStmt(pszPathTmp, rc = VERR_NO_MEMORY); 317 318 char szFilePath[RTPATH_MAX]; 319 rc = RTStrCopy(szFilePath, sizeof(szFilePath), pszPathTmp); 320 AssertRCBreak(rc); 321 322 /* Create it when necessary. */ 323 if (!RTDirExists(szFilePath)) 324 { 325 rc = RTDirCreateFullPath(szFilePath, RTFS_UNIX_IRWXU); 326 if (RT_FAILURE(rc)) 327 break; 328 } 329 330 char szFileName[RTPATH_MAX]; 331 szFileName[0] = '\0'; 332 333 if (fFlags & AUDIOHLPFILENAME_FLAGS_TS) 334 { 335 RTTIMESPEC time; 336 if (!RTTimeSpecToString(RTTimeNow(&time), szFileName, sizeof(szFileName))) 337 { 338 rc = VERR_BUFFER_OVERFLOW; 339 break; 340 } 341 342 rc = AudioHlpFileNameSanitize(szFileName, sizeof(szFileName)); 343 if (RT_FAILURE(rc)) 344 break; 345 346 rc = RTStrCat(szFileName, sizeof(szFileName), "-"); 347 if (RT_FAILURE(rc)) 348 break; 349 } 350 351 rc = RTStrCat(szFileName, sizeof(szFileName), pszName); 352 if (RT_FAILURE(rc)) 353 break; 354 355 rc = RTStrCat(szFileName, sizeof(szFileName), "-"); 356 if (RT_FAILURE(rc)) 357 break; 358 359 char szInst[16]; 360 RTStrPrintf2(szInst, sizeof(szInst), "%RU32", uInstance); 361 rc = RTStrCat(szFileName, sizeof(szFileName), szInst); 362 if (RT_FAILURE(rc)) 363 break; 364 365 switch (enmType) 366 { 367 case AUDIOHLPFILETYPE_RAW: 368 rc = RTStrCat(szFileName, sizeof(szFileName), ".pcm"); 369 break; 370 371 case AUDIOHLPFILETYPE_WAV: 372 rc = RTStrCat(szFileName, sizeof(szFileName), ".wav"); 373 break; 374 375 default: 376 AssertFailedStmt(rc = VERR_NOT_IMPLEMENTED); 377 break; 378 } 379 380 if (RT_FAILURE(rc)) 381 break; 382 383 rc = RTPathAppend(szFilePath, sizeof(szFilePath), szFileName); 384 if (RT_FAILURE(rc)) 385 break; 386 387 rc = RTStrCopy(pszFile, cchFile, szFilePath); 388 389 } while (0); 390 391 RTStrFree(pszPathTmp); 392 393 LogFlowFuncLeaveRC(rc); 394 return rc; 347 return audioHlpConstructPathWorker(pszDst, cbDst, pszPath, pszName, uInstance, enmType, fFlags, '\0'); 395 348 } 396 349 … … 564 517 PCPDMAUDIOPCMPROPS pProps, uint64_t fOpen) 565 518 { 566 char szFile[RTPATH_MAX]; 567 int rc = AudioHlpFileNameGet(szFile, sizeof(szFile), pszDir, pszName, iInstance, enmType, fFilename); 568 if (RT_SUCCESS(rc)) 569 { 519 *ppFile = NULL; 520 521 for (uint32_t iTry = 0; ; iTry++) 522 { 523 char szFile[RTPATH_MAX]; 524 int rc = audioHlpConstructPathWorker(szFile, sizeof(szFile), pszDir, pszName, iInstance, enmType, fFilename, 525 iTry == 0 ? '\0' : iTry + 'a'); 526 AssertRCReturn(rc, rc); 527 570 528 PAUDIOHLPFILE pFile = NULL; 571 529 rc = AudioHlpFileCreate(enmType, szFile, fCreate, &pFile); 530 AssertRCReturn(rc, rc); 531 532 rc = AudioHlpFileOpen(pFile, fOpen, pProps); 572 533 if (RT_SUCCESS(rc)) 573 534 { 574 rc = AudioHlpFileOpen(pFile, fOpen, pProps); 575 if (RT_SUCCESS(rc)) 576 { 577 *ppFile = pFile; 578 return rc; 579 } 580 AudioHlpFileDestroy(pFile); 535 *ppFile = pFile; 536 return rc; 581 537 } 582 } 583 *ppFile = NULL; 584 return rc; 538 AudioHlpFileDestroy(pFile); 539 540 AssertReturn(iTry < 16, rc); 541 } 585 542 } 586 543 -
trunk/src/VBox/Devices/Audio/AudioHlp.h
r89342 r90010 67 67 /** The customary invalid zero value. */ 68 68 AUDIOHLPFILETYPE_INVALID = 0, 69 /** Unknown type, do not use. */70 AUDIOHLPFILETYPE_UNKNOWN,71 69 /** Raw (PCM) file. */ 72 70 AUDIOHLPFILETYPE_RAW, … … 79 77 /** @name Audio file (name) helper methods. 80 78 * @{ */ 81 int AudioHlpFileNameSanitize(char *pszPath, size_t cbPath);82 79 int AudioHlpFileNameGet(char *pszFile, size_t cchFile, const char *pszPath, const char *pszName, 83 80 uint32_t uInstance, AUDIOHLPFILETYPE enmType, uint32_t fFlags); … … 89 86 #define AUDIOHLPFILENAME_FLAGS_NONE UINT32_C(0) 90 87 /** Adds an ISO timestamp to the file name. */ 91 #define AUDIOHLPFILENAME_FLAGS_TS RT_BIT(0) 88 #define AUDIOHLPFILENAME_FLAGS_TS RT_BIT_32(0) 89 /** Valid flag mask. */ 90 #define AUDIOHLPFILENAME_FLAGS_VALID_MASK AUDIOHLPFILENAME_FLAGS_TS 92 91 /** @} */ 93 92
Note:
See TracChangeset
for help on using the changeset viewer.