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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1461 - (hide annotations) (download)
Sun Oct 28 23:30:36 2007 UTC (12 years, 3 months ago) by schoenebeck
File size: 6318 byte(s)
* started to port QSampler to Qt4 (NOTE: this version is yet broken, use
  the latest tarball release 0.1.5 until the Qt4 port is completed)

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

  ViewVC Help
Powered by ViewVC