/[svn]/qsampler/trunk/src/qsamplerUtilities.cpp
ViewVC logotype

Annotation of /qsampler/trunk/src/qsamplerUtilities.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1464 - (hide annotations) (download)
Thu Nov 1 17:14:21 2007 UTC (16 years, 5 months ago) by capela
File size: 6397 byte(s)
- Qt4 migration: missing copyright headers update.

1 schoenebeck 1386 // qsamplerUtilities.cpp
2     //
3     /****************************************************************************
4     Copyright (C) 2004-2007, rncbc aka Rui Nuno Capela. All rights reserved.
5 capela 1464 Copyright (C) 2007, Christian Schoenebeck
6 schoenebeck 1386
7     This program is free software; you can redistribute it and/or
8     modify it under the terms of the GNU General Public License
9     as published by the Free Software Foundation; either version 2
10     of the License, or (at your option) any later version.
11    
12     This program is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15     GNU General Public License for more details.
16    
17     You should have received a copy of the GNU General Public License along
18     with this program; if not, write to the Free Software Foundation, Inc.,
19     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20    
21     *****************************************************************************/
22    
23     #include "qsamplerUtilities.h"
24    
25     #include "qsamplerMainForm.h"
26    
27     #include <stdio.h>
28     #include <qregexp.h>
29    
30 schoenebeck 1461 using namespace QSampler;
31    
32 schoenebeck 1402 namespace qsamplerUtilities {
33    
34     static int _hexToNumber(char hex_digit) {
35     switch (hex_digit) {
36     case '0': return 0;
37     case '1': return 1;
38     case '2': return 2;
39     case '3': return 3;
40     case '4': return 4;
41     case '5': return 5;
42     case '6': return 6;
43     case '7': return 7;
44     case '8': return 8;
45     case '9': return 9;
46    
47     case 'a': return 10;
48     case 'b': return 11;
49     case 'c': return 12;
50     case 'd': return 13;
51     case 'e': return 14;
52     case 'f': return 15;
53    
54     case 'A': return 10;
55     case 'B': return 11;
56     case 'C': return 12;
57     case 'D': return 13;
58     case 'E': return 14;
59     case 'F': return 15;
60    
61     default: return 0;
62     }
63     }
64    
65     static int _hexsToNumber(char hex_digit0, char hex_digit1) {
66     return _hexToNumber(hex_digit1)*16 + _hexToNumber(hex_digit0);
67     }
68    
69     // returns true if the connected LSCP server supports escape sequences
70     static bool _remoteSupportsEscapeSequences() {
71     const lscpVersion_t version = getRemoteLscpVersion();
72     // LSCP v1.2 or younger required
73     return (version.major > 1 || (version.major == 1 && version.minor >= 2));
74     }
75    
76 schoenebeck 1386 // converts the given file path into a path as expected by LSCP 1.2
77 capela 1394 QString lscpEscapePath ( const QString& sPath )
78     {
79 schoenebeck 1402 if (!_remoteSupportsEscapeSequences()) return sPath;
80 capela 1394
81 schoenebeck 1402 QString path(sPath);
82 schoenebeck 1386
83     // replace POSIX path escape sequences (%HH) by LSCP escape sequences (\xHH)
84     // TODO: missing code for other systems like Windows
85     {
86     QRegExp regexp("%[0-9a-fA-F][0-9a-fA-F]");
87 schoenebeck 1402 for (int i = path.find(regexp); i >= 0; i = path.find(regexp, i + 4))
88 schoenebeck 1386 path.replace(i, 1, "\\x");
89     }
90 schoenebeck 1402 // replace POSIX path escape sequence (%%) by its raw character
91     for (int i = path.find("%%"); i >= 0; i = path.find("%%", ++i))
92     path.remove(i, 1);
93 capela 1394
94 schoenebeck 1386 // replace all non-basic characters by LSCP escape sequences
95     {
96     const char pathSeparator = '/';
97     QRegExp regexp(QRegExp::escape("\\x") + "[0-9a-fA-F][0-9a-fA-F]");
98     for (int i = 0; i < int(path.length()); i++) {
99     // first skip all previously added LSCP escape sequences
100     if (path.find(regexp, i) == i) {
101     i += 3;
102     continue;
103     }
104     // now match all non-alphanumerics
105     // (we could exclude much more characters here, but that way
106     // we're sure it just works^TM)
107     const char c = path.at(i).latin1();
108     if (
109     !(c >= '0' && c <= '9') &&
110     !(c >= 'a' && c <= 'z') &&
111     !(c >= 'A' && c <= 'Z') &&
112     !(c == pathSeparator)
113     ) {
114     // convert the non-basic character into a LSCP escape sequence
115     char buf[5];
116 schoenebeck 1402 ::snprintf(buf, sizeof(buf), "\\x%02x", static_cast<unsigned char>(c));
117 schoenebeck 1386 path.replace(i, 1, buf);
118     i += 3;
119     }
120     }
121     }
122 capela 1394
123 schoenebeck 1386 return path;
124     }
125    
126 schoenebeck 1402 // converts a path returned by a LSCP command (and may contain escape
127     // sequences) into the appropriate POSIX path
128     QString lscpEscapedPathToPosix(QString path) {
129     if (!_remoteSupportsEscapeSequences()) return path;
130 capela 1394
131 schoenebeck 1402 // first escape all percent ('%') characters for POSIX
132     for (int i = path.find('%'); i >= 0; i = path.find('%', i+2))
133     path.replace(i, 1, "%%");
134    
135     // resolve LSCP hex escape sequences (\xHH)
136     QRegExp regexp(QRegExp::escape("\\x") + "[0-9a-fA-F][0-9a-fA-F]");
137     for (int i = path.find(regexp); i >= 0; i = path.find(regexp, i + 4)) {
138     const QString sHex = path.mid(i+2, 2).lower();
139     // the slash has to be escaped for POSIX as well
140     if (sHex == "2f") {
141     path.replace(i, 4, "%2f");
142     continue;
143     }
144     // all other characters we simply decode
145     char cAscii = _hexsToNumber(sHex.at(1).latin1(), sHex.at(0).latin1());
146     path.replace(i, 4, cAscii);
147     }
148    
149     return path;
150     }
151    
152     // converts a text returned by a LSCP command and may contain escape
153     // sequences) into raw text, that is with all escape sequences decoded
154     QString lscpEscapedTextToRaw(QString txt) {
155     if (!_remoteSupportsEscapeSequences()) return txt;
156    
157     // resolve LSCP hex escape sequences (\xHH)
158     QRegExp regexp(QRegExp::escape("\\x") + "[0-9a-fA-F][0-9a-fA-F]");
159     for (int i = txt.find(regexp); i >= 0; i = txt.find(regexp, i + 4)) {
160     const QString sHex = txt.mid(i+2, 2).lower();
161     // decode into raw ASCII character
162     char cAscii = _hexsToNumber(sHex.at(1).latin1(), sHex.at(0).latin1());
163     txt.replace(i, 4, cAscii);
164     }
165    
166     return txt;
167     }
168    
169 capela 1394 lscpVersion_t getRemoteLscpVersion (void)
170     {
171 schoenebeck 1386 lscpVersion_t result = { 0, 0 };
172    
173 schoenebeck 1461 MainForm* pMainForm = MainForm::getInstance();
174 capela 1394 if (pMainForm == NULL)
175 schoenebeck 1402 return result;
176     if (pMainForm->client() == NULL)
177     return result;
178 schoenebeck 1386
179     lscp_server_info_t* pServerInfo =
180     ::lscp_get_server_info(pMainForm->client());
181 capela 1394 if (pServerInfo && pServerInfo->protocol_version)
182 schoenebeck 1402 ::sscanf(pServerInfo->protocol_version, "%d.%d",
183     &result.major, &result.minor);
184 schoenebeck 1386
185     return result;
186     }
187 schoenebeck 1402
188     } // namespace qsamplerUtilities
189 capela 1464
190    
191     // end of qsamplerUtilities.cpp

  ViewVC Help
Powered by ViewVC