--- qsampler/trunk/src/qsamplerUtilities.cpp 2007/10/11 20:45:49 1401 +++ qsampler/trunk/src/qsamplerUtilities.cpp 2007/10/12 00:03:27 1402 @@ -26,23 +26,67 @@ #include #include +namespace qsamplerUtilities { + +static int _hexToNumber(char hex_digit) { + switch (hex_digit) { + case '0': return 0; + case '1': return 1; + case '2': return 2; + case '3': return 3; + case '4': return 4; + case '5': return 5; + case '6': return 6; + case '7': return 7; + case '8': return 8; + case '9': return 9; + + case 'a': return 10; + case 'b': return 11; + case 'c': return 12; + case 'd': return 13; + case 'e': return 14; + case 'f': return 15; + + case 'A': return 10; + case 'B': return 11; + case 'C': return 12; + case 'D': return 13; + case 'E': return 14; + case 'F': return 15; + + default: return 0; + } +} + +static int _hexsToNumber(char hex_digit0, char hex_digit1) { + return _hexToNumber(hex_digit1)*16 + _hexToNumber(hex_digit0); +} + +// returns true if the connected LSCP server supports escape sequences +static bool _remoteSupportsEscapeSequences() { + const lscpVersion_t version = getRemoteLscpVersion(); + // LSCP v1.2 or younger required + return (version.major > 1 || (version.major == 1 && version.minor >= 2)); +} + // converts the given file path into a path as expected by LSCP 1.2 QString lscpEscapePath ( const QString& sPath ) { - QString path(sPath); + if (!_remoteSupportsEscapeSequences()) return sPath; - // check if remote side supports LSCP escape sequences - const lscpVersion_t version = getRemoteLscpVersion(); - if (version.major < 1 || version.minor < 2) - return path; // LSCP v1.2 or younger required + QString path(sPath); // replace POSIX path escape sequences (%HH) by LSCP escape sequences (\xHH) // TODO: missing code for other systems like Windows { QRegExp regexp("%[0-9a-fA-F][0-9a-fA-F]"); - for (int i = path.find(regexp); i >= 0; i = path.find(regexp, i + 3)) + for (int i = path.find(regexp); i >= 0; i = path.find(regexp, i + 4)) path.replace(i, 1, "\\x"); } + // replace POSIX path escape sequence (%%) by its raw character + for (int i = path.find("%%"); i >= 0; i = path.find("%%", ++i)) + path.remove(i, 1); // replace all non-basic characters by LSCP escape sequences { @@ -66,7 +110,7 @@ ) { // convert the non-basic character into a LSCP escape sequence char buf[5]; - ::snprintf(buf, sizeof(buf), "\\x%2x", static_cast(c)); + ::snprintf(buf, sizeof(buf), "\\x%02x", static_cast(c)); path.replace(i, 1, buf); i += 3; } @@ -76,6 +120,48 @@ return path; } +// converts a path returned by a LSCP command (and may contain escape +// sequences) into the appropriate POSIX path +QString lscpEscapedPathToPosix(QString path) { + if (!_remoteSupportsEscapeSequences()) return path; + + // first escape all percent ('%') characters for POSIX + for (int i = path.find('%'); i >= 0; i = path.find('%', i+2)) + path.replace(i, 1, "%%"); + + // resolve LSCP hex escape sequences (\xHH) + QRegExp regexp(QRegExp::escape("\\x") + "[0-9a-fA-F][0-9a-fA-F]"); + for (int i = path.find(regexp); i >= 0; i = path.find(regexp, i + 4)) { + const QString sHex = path.mid(i+2, 2).lower(); + // the slash has to be escaped for POSIX as well + if (sHex == "2f") { + path.replace(i, 4, "%2f"); + continue; + } + // all other characters we simply decode + char cAscii = _hexsToNumber(sHex.at(1).latin1(), sHex.at(0).latin1()); + path.replace(i, 4, cAscii); + } + + return path; +} + +// converts a text returned by a LSCP command and may contain escape +// sequences) into raw text, that is with all escape sequences decoded +QString lscpEscapedTextToRaw(QString txt) { + if (!_remoteSupportsEscapeSequences()) return txt; + + // resolve LSCP hex escape sequences (\xHH) + QRegExp regexp(QRegExp::escape("\\x") + "[0-9a-fA-F][0-9a-fA-F]"); + for (int i = txt.find(regexp); i >= 0; i = txt.find(regexp, i + 4)) { + const QString sHex = txt.mid(i+2, 2).lower(); + // decode into raw ASCII character + char cAscii = _hexsToNumber(sHex.at(1).latin1(), sHex.at(0).latin1()); + txt.replace(i, 4, cAscii); + } + + return txt; +} lscpVersion_t getRemoteLscpVersion (void) { @@ -83,15 +169,17 @@ qsamplerMainForm *pMainForm = qsamplerMainForm::getInstance(); if (pMainForm == NULL) - return result; - if (pMainForm->client() == NULL) - return result; + return result; + if (pMainForm->client() == NULL) + return result; lscp_server_info_t* pServerInfo = ::lscp_get_server_info(pMainForm->client()); if (pServerInfo && pServerInfo->protocol_version) - ::sscanf(pServerInfo->protocol_version, "%d.%d", - &result.major, &result.minor); + ::sscanf(pServerInfo->protocol_version, "%d.%d", + &result.major, &result.minor); return result; } + +} // namespace qsamplerUtilities