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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3358 - (hide annotations) (download)
Wed Oct 18 08:57:21 2017 UTC (6 years, 6 months ago) by capela
File size: 6879 byte(s)
- Replace WIN32 with _WIN32 (as suggested by Kjetil Matheussen,
  thanks). (FIX)
1 schoenebeck 1386 // qsamplerUtilities.cpp
2     //
3     /****************************************************************************
4 capela 3357 Copyright (C) 2004-2017, rncbc aka Rui Nuno Capela. All rights reserved.
5 schoenebeck 1667 Copyright (C) 2007, 2008 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 capela 1513 #include "qsamplerOptions.h"
26 schoenebeck 1386 #include "qsamplerMainForm.h"
27    
28 capela 1499 #include <QRegExp>
29 schoenebeck 1386
30 capela 1499
31 schoenebeck 1461 using namespace QSampler;
32    
33 schoenebeck 1402 namespace qsamplerUtilities {
34    
35 capela 3357 static int _hexToNumber ( char hex_digit )
36     {
37     switch (hex_digit) {
38     case '0': return 0;
39     case '1': return 1;
40     case '2': return 2;
41     case '3': return 3;
42     case '4': return 4;
43     case '5': return 5;
44     case '6': return 6;
45     case '7': return 7;
46     case '8': return 8;
47     case '9': return 9;
48 schoenebeck 1402
49 capela 3357 case 'a': return 10;
50     case 'b': return 11;
51     case 'c': return 12;
52     case 'd': return 13;
53     case 'e': return 14;
54     case 'f': return 15;
55 schoenebeck 1402
56 capela 3357 case 'A': return 10;
57     case 'B': return 11;
58     case 'C': return 12;
59     case 'D': return 13;
60     case 'E': return 14;
61     case 'F': return 15;
62 schoenebeck 1402
63 capela 3357 default: return 0;
64     }
65 schoenebeck 1402 }
66    
67 capela 3357 static int _hexsToNumber ( char hex0, char hex1 )
68     {
69     return _hexToNumber(hex1) * 16 + _hexToNumber(hex0);
70 schoenebeck 1402 }
71    
72 capela 3357
73 schoenebeck 1402 // returns true if the connected LSCP server supports escape sequences
74 capela 3357 static bool _remoteSupportsEscapeSequences (void)
75     {
76     const lscpVersion_t version = getRemoteLscpVersion();
77     // LSCP v1.2 or younger required
78     return (version.major > 1 || (version.major == 1 && version.minor >= 2));
79 schoenebeck 1402 }
80    
81 capela 3357
82 schoenebeck 1386 // converts the given file path into a path as expected by LSCP 1.2
83 capela 1394 QString lscpEscapePath ( const QString& sPath )
84     {
85 capela 3357 if (!_remoteSupportsEscapeSequences()) return sPath;
86 capela 1394
87 capela 3357 QString path(sPath);
88 schoenebeck 1386
89 capela 3357 // replace POSIX path escape sequences (%HH) by LSCP escape sequences (\xHH)
90     // TODO: missing code for other systems like Windows
91     {
92     QRegExp regexp("%[0-9a-fA-F][0-9a-fA-F]");
93     for (int i = path.indexOf(regexp); i >= 0; i = path.indexOf(regexp, i + 4))
94     path.replace(i, 1, "\\x");
95     }
96     // replace POSIX path escape sequence (%%) by its raw character
97     for (int i = path.indexOf("%%"); i >= 0; i = path.indexOf("%%", ++i))
98     path.remove(i, 1);
99 capela 1394
100 capela 3357 // replace all non-basic characters by LSCP escape sequences
101     {
102     const char pathSeparator = '/';
103     QRegExp regexp(QRegExp::escape("\\x") + "[0-9a-fA-F][0-9a-fA-F]");
104     for (int i = 0; i < int(path.length()); i++) {
105     // first skip all previously added LSCP escape sequences
106     if (path.indexOf(regexp, i) == i) {
107     i += 3;
108     continue;
109     }
110     // now match all non-alphanumerics
111     // (we could exclude much more characters here, but that way
112     // we're sure it just works^TM)
113     const char c = path.at(i).toLatin1();
114     if (
115     !(c >= '0' && c <= '9') &&
116     !(c >= 'a' && c <= 'z') &&
117     !(c >= 'A' && c <= 'Z') &&
118 capela 3358 #if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
119 capela 3357 !(c == ':') &&
120     #endif
121     !(c == pathSeparator)
122     ) {
123     // convert the non-basic character into a LSCP escape sequence
124     char buf[5];
125     ::snprintf(buf, sizeof(buf), "\\x%02x", static_cast<unsigned char>(c));
126     path.replace(i, 1, buf);
127     i += 3;
128     }
129     }
130     }
131 capela 1394
132 capela 3357 return path;
133 schoenebeck 1386 }
134    
135 capela 3357
136 schoenebeck 1402 // converts a path returned by a LSCP command (and may contain escape
137     // sequences) into the appropriate POSIX path
138 capela 3357 QString lscpEscapedPathToPosix ( const QString& sPath )
139     {
140     if (!_remoteSupportsEscapeSequences()) return sPath;
141 capela 1394
142 capela 3357 QString path(sPath);
143 schoenebeck 1402
144 capela 3357 // first escape all percent ('%') characters for POSIX
145     for (int i = path.indexOf('%'); i >= 0; i = path.indexOf('%', i+2))
146     path.replace(i, 1, "%%");
147 schoenebeck 1402
148 capela 3357 // resolve LSCP hex escape sequences (\xHH)
149     QRegExp regexp(QRegExp::escape("\\x") + "[0-9a-fA-F][0-9a-fA-F]");
150     for (int i = path.indexOf(regexp); i >= 0; i = path.indexOf(regexp, i + 4)) {
151     const QString sHex = path.mid(i + 2, 2).toLower();
152     // the slash has to be escaped for POSIX as well
153     if (sHex == "2f") {
154     path.replace(i, 4, "%2f");
155     continue;
156     }
157     // all other characters we simply decode
158     char cAscii = _hexsToNumber(sHex.at(1).toLatin1(), sHex.at(0).toLatin1());
159     path.replace(i, 4, cAscii);
160     }
161    
162     return path;
163 schoenebeck 1402 }
164    
165 capela 3357
166 schoenebeck 1667 // converts the given text as expected by LSCP 1.2
167     // (that is by encoding special characters with LSCP escape sequences)
168 capela 3357 QString lscpEscapeText ( const QString& sText )
169     {
170     if (!_remoteSupportsEscapeSequences()) return sText;
171 schoenebeck 1667
172 capela 3357 QString text(sText);
173 schoenebeck 1667
174 capela 3357 // replace all non-basic characters by LSCP escape sequences
175     for (int i = 0; i < int(text.length()); ++i) {
176     // match all non-alphanumerics
177     // (we could exclude much more characters here, but that way
178     // we're sure it just works^TM)
179     const char c = text.at(i).toLatin1();
180     if (
181     !(c >= '0' && c <= '9') &&
182     !(c >= 'a' && c <= 'z') &&
183     !(c >= 'A' && c <= 'Z')
184     ) {
185     // convert the non-basic character into a LSCP escape sequence
186     char buf[5];
187     ::snprintf(buf, sizeof(buf), "\\x%02x", static_cast<unsigned char>(c));
188     text.replace(i, 1, buf);
189     i += 3;
190     }
191     }
192 schoenebeck 1667
193 capela 3357 return text;
194 schoenebeck 1667 }
195    
196 capela 3357
197 schoenebeck 1402 // converts a text returned by a LSCP command and may contain escape
198     // sequences) into raw text, that is with all escape sequences decoded
199 capela 3357 QString lscpEscapedTextToRaw ( const QString& sText )
200     {
201     if (!_remoteSupportsEscapeSequences()) return sText;
202 schoenebeck 1402
203 capela 3357 QString text(sText);
204 schoenebeck 1402
205 capela 3357 // resolve LSCP hex escape sequences (\xHH)
206     QRegExp regexp(QRegExp::escape("\\x") + "[0-9a-fA-F][0-9a-fA-F]");
207     for (int i = text.indexOf(regexp); i >= 0; i = text.indexOf(regexp, i + 4)) {
208     const QString sHex = text.mid(i + 2, 2).toLower();
209     // decode into raw ASCII character
210     char cAscii = _hexsToNumber(sHex.at(1).toLatin1(), sHex.at(0).toLatin1());
211     text.replace(i, 4, cAscii);
212     }
213    
214     return text;
215 schoenebeck 1402 }
216    
217 capela 1394 lscpVersion_t getRemoteLscpVersion (void)
218     {
219 schoenebeck 1386 lscpVersion_t result = { 0, 0 };
220    
221 schoenebeck 1461 MainForm* pMainForm = MainForm::getInstance();
222 capela 1394 if (pMainForm == NULL)
223 schoenebeck 1402 return result;
224     if (pMainForm->client() == NULL)
225     return result;
226 schoenebeck 1386
227     lscp_server_info_t* pServerInfo =
228     ::lscp_get_server_info(pMainForm->client());
229 capela 1394 if (pServerInfo && pServerInfo->protocol_version)
230 schoenebeck 1402 ::sscanf(pServerInfo->protocol_version, "%d.%d",
231     &result.major, &result.minor);
232 schoenebeck 1386
233     return result;
234     }
235 schoenebeck 1402
236     } // namespace qsamplerUtilities
237 capela 1464
238    
239     // end of qsamplerUtilities.cpp

  ViewVC Help
Powered by ViewVC