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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1667 - (show annotations) (download)
Mon Feb 4 23:24:19 2008 UTC (16 years, 1 month ago) by schoenebeck
File size: 7521 byte(s)
* added FX Sends dialog to channel strips
  (still under construction, so far one can only create, destroy and rename
  FX sends, the rest is still to do)
* bumped version to 0.2.1.3

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

  ViewVC Help
Powered by ViewVC