Complete except for throttling bug.
This commit is contained in:
@@ -23,6 +23,7 @@
|
||||
|
||||
import { pathConcat, pathParentDirectory, pathFileName } from "./FileUtils";
|
||||
import { PiPedalModel } from "./PiPedalModel";
|
||||
import { safeFilenameDecode } from "./SafeFilename";
|
||||
|
||||
export class ThumbnailType {
|
||||
static Unknown = 0;
|
||||
@@ -38,72 +39,6 @@ function getVersionSuffix(filePath: string): string | null {
|
||||
return match ? match[1] : null;
|
||||
}
|
||||
|
||||
export function safeFilenameDecode(filename: string): string {
|
||||
let originalFilename = filename;
|
||||
let pos = filename.indexOf('%');
|
||||
if (pos < 0) {
|
||||
return filename;
|
||||
}
|
||||
let result = "";
|
||||
while (true) {
|
||||
if (pos < 0) {
|
||||
result += filename;
|
||||
return result;
|
||||
}
|
||||
result += filename.substring(0, pos);
|
||||
if (pos+3 >= filename.length) {
|
||||
// invalid encoding. just use the original
|
||||
return originalFilename;
|
||||
}
|
||||
let hex = filename.charAt(pos+1) + filename.charAt(pos+2);
|
||||
let byte = parseInt(hex, 16);
|
||||
|
||||
// Handle UTF-8 to UTF-16 conversion
|
||||
if (byte < 0x80) {
|
||||
// Single-byte character (ASCII)
|
||||
result += String.fromCharCode(byte);
|
||||
filename = filename.substring(pos+3);
|
||||
} else if ((byte & 0xE0) === 0xC0) {
|
||||
// 2-byte sequence
|
||||
if (pos+6 > filename.length || filename.charAt(pos+3) !== '%') {
|
||||
return originalFilename; // invalid encoding
|
||||
}
|
||||
let byte2 = parseInt(filename.charAt(pos+4) + filename.charAt(pos+5), 16);
|
||||
let codePoint = ((byte & 0x1F) << 6) | (byte2 & 0x3F);
|
||||
result += String.fromCharCode(codePoint);
|
||||
filename = filename.substring(pos+6);
|
||||
} else if ((byte & 0xF0) === 0xE0) {
|
||||
// 3-byte sequence
|
||||
if (pos+9 > filename.length || filename.charAt(pos+3) !== '%' || filename.charAt(pos+6) !== '%') {
|
||||
return originalFilename; // invalid encoding
|
||||
}
|
||||
let byte2 = parseInt(filename.charAt(pos+4) + filename.charAt(pos+5), 16);
|
||||
let byte3 = parseInt(filename.charAt(pos+7) + filename.charAt(pos+8), 16);
|
||||
let codePoint = ((byte & 0x0F) << 12) | ((byte2 & 0x3F) << 6) | (byte3 & 0x3F);
|
||||
result += String.fromCharCode(codePoint);
|
||||
filename = filename.substring(pos+9);
|
||||
} else if ((byte & 0xF8) === 0xF0) {
|
||||
// 4-byte sequence (surrogate pair needed)
|
||||
if (pos+12 > filename.length || filename.charAt(pos+3) !== '%' || filename.charAt(pos+6) !== '%' || filename.charAt(pos+9) !== '%') {
|
||||
return originalFilename; // invalid encoding
|
||||
}
|
||||
let byte2 = parseInt(filename.charAt(pos+4) + filename.charAt(pos+5), 16);
|
||||
let byte3 = parseInt(filename.charAt(pos+7) + filename.charAt(pos+8), 16);
|
||||
let byte4 = parseInt(filename.charAt(pos+10) + filename.charAt(pos+11), 16);
|
||||
let codePoint = ((byte & 0x07) << 18) | ((byte2 & 0x3F) << 12) | ((byte3 & 0x3F) << 6) | (byte4 & 0x3F);
|
||||
// Convert to UTF-16 surrogate pair
|
||||
codePoint -= 0x10000;
|
||||
result += String.fromCharCode(0xD800 + (codePoint >> 10));
|
||||
result += String.fromCharCode(0xDC00 + (codePoint & 0x3FF));
|
||||
filename = filename.substring(pos+12);
|
||||
} else {
|
||||
// Invalid UTF-8 start byte
|
||||
return originalFilename;
|
||||
}
|
||||
pos = filename.indexOf('%');
|
||||
}
|
||||
}
|
||||
|
||||
export function getTrackTitle(pathname: string, metadata: AudioFileMetadata | null | undefined): string {
|
||||
if (!metadata) {
|
||||
return safeFilenameDecode(pathFileName(pathname));
|
||||
|
||||
Reference in New Issue
Block a user