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

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1386 by schoenebeck, Fri Oct 5 17:41:49 2007 UTC revision 1499 by capela, Tue Nov 20 16:48:04 2007 UTC
# Line 2  Line 2 
2  //  //
3  /****************************************************************************  /****************************************************************************
4     Copyright (C) 2004-2007, rncbc aka Rui Nuno Capela. All rights reserved.     Copyright (C) 2004-2007, rncbc aka Rui Nuno Capela. All rights reserved.
5       Copyright (C) 2007, Christian Schoenebeck
6    
7     This program is free software; you can redistribute it and/or     This program is free software; you can redistribute it and/or
8     modify it under the terms of the GNU General Public License     modify it under the terms of the GNU General Public License
# Line 23  Line 24 
24    
25  #include "qsamplerMainForm.h"  #include "qsamplerMainForm.h"
26    
27  #include <stdio.h>  #include <QRegExp>
 #include <qregexp.h>  
28    
29  // converts the given file path into a path as expected by LSCP 1.2  
30  QString lscpEscapePath(QString path) {  using namespace QSampler;
31      // check if remote side supports LSCP escape sequences  
32    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();      const lscpVersion_t version = getRemoteLscpVersion();
72      if (version.major < 1 || version.minor < 2)      // LSCP v1.2 or younger required
73          return path; // LSCP v1.2 or younger required      return (version.major > 1 || (version.major == 1 && version.minor >= 2));
74    }
75    
76    // converts the given file path into a path as expected by LSCP 1.2
77    QString lscpEscapePath ( const QString& sPath )
78    {
79        if (!_remoteSupportsEscapeSequences()) return sPath;
80    
81        QString path(sPath);
82    
83      // replace POSIX path escape sequences (%HH) by LSCP escape sequences (\xHH)      // replace POSIX path escape sequences (%HH) by LSCP escape sequences (\xHH)
84      // TODO: missing code for other systems like Windows      // TODO: missing code for other systems like Windows
85      {      {
86          QRegExp regexp("%[0-9a-fA-F][0-9a-fA-F]");          QRegExp regexp("%[0-9a-fA-F][0-9a-fA-F]");
87          for (int i = path.find(regexp); i >= 0; i = path.find(regexp, i + 3))          for (int i = path.indexOf(regexp); i >= 0; i = path.indexOf(regexp, i + 4))
88              path.replace(i, 1, "\\x");              path.replace(i, 1, "\\x");
89      }      }
90        // replace POSIX path escape sequence (%%) by its raw character
91        for (int i = path.indexOf("%%"); i >= 0; i = path.indexOf("%%", ++i))
92            path.remove(i, 1);
93    
94      // replace all non-basic characters by LSCP escape sequences      // replace all non-basic characters by LSCP escape sequences
95      {      {
96          const char pathSeparator = '/';          const char pathSeparator = '/';
97          QRegExp regexp(QRegExp::escape("\\x") + "[0-9a-fA-F][0-9a-fA-F]");          QRegExp regexp(QRegExp::escape("\\x") + "[0-9a-fA-F][0-9a-fA-F]");
98          for (int i = 0; i < int(path.length()); i++) {          for (int i = 0; i < int(path.length()); i++) {
99              // first skip all previously added LSCP escape sequences              // first skip all previously added LSCP escape sequences
100              if (path.find(regexp, i) == i) {              if (path.indexOf(regexp, i) == i) {
101                  i += 3;                  i += 3;
102                  continue;                  continue;
103              }              }
104              // now match all non-alphanumerics              // now match all non-alphanumerics
105              // (we could exclude much more characters here, but that way              // (we could exclude much more characters here, but that way
106              // we're sure it just works^TM)              // we're sure it just works^TM)
107              const char c = path.at(i).latin1();              const char c = path.at(i).toLatin1();
108              if (              if (
109                  !(c >= '0' && c <= '9') &&                  !(c >= '0' && c <= '9') &&
110                  !(c >= 'a' && c <= 'z') &&                  !(c >= 'a' && c <= 'z') &&
111                  !(c >= 'A' && c <= 'Z') &&                  !(c >= 'A' && c <= 'Z') &&
112                    #if defined(WIN32)
113                    !(c == ':') &&
114                    #endif
115                  !(c == pathSeparator)                  !(c == pathSeparator)
116              ) {              ) {
117                  // convert the non-basic character into a LSCP escape sequence                  // convert the non-basic character into a LSCP escape sequence
118                  char buf[5];                  char buf[5];
119                  snprintf(buf, sizeof(buf), "\\x%2x", static_cast<unsigned char>(c));                  ::snprintf(buf, sizeof(buf), "\\x%02x", static_cast<unsigned char>(c));
120                  path.replace(i, 1, buf);                  path.replace(i, 1, buf);
121                  i += 3;                  i += 3;
122              }              }
123          }          }
124      }      }
125    
126        return path;
127    }
128    
129    // converts a path returned by a LSCP command (and may contain escape
130    // sequences) into the appropriate POSIX path
131    QString lscpEscapedPathToPosix(QString path) {
132        if (!_remoteSupportsEscapeSequences()) return path;
133    
134        // first escape all percent ('%') characters for POSIX
135        for (int i = path.indexOf('%'); i >= 0; i = path.indexOf('%', i+2))
136            path.replace(i, 1, "%%");
137    
138        // resolve LSCP hex escape sequences (\xHH)
139        QRegExp regexp(QRegExp::escape("\\x") + "[0-9a-fA-F][0-9a-fA-F]");
140        for (int i = path.indexOf(regexp); i >= 0; i = path.indexOf(regexp, i + 4)) {
141            const QString sHex = path.mid(i+2, 2).toLower();
142            // the slash has to be escaped for POSIX as well
143            if (sHex == "2f") {
144                path.replace(i, 4, "%2f");
145                continue;
146            }
147            // all other characters we simply decode
148            char cAscii = _hexsToNumber(sHex.at(1).toLatin1(), sHex.at(0).toLatin1());
149            path.replace(i, 4, cAscii);
150        }
151    
152      return path;      return path;
153  }  }
154    
155  lscpVersion_t getRemoteLscpVersion() {  // converts a text returned by a LSCP command and may contain escape
156    // sequences) into raw text, that is with all escape sequences decoded
157    QString lscpEscapedTextToRaw(QString txt) {
158        if (!_remoteSupportsEscapeSequences()) return txt;
159    
160        // resolve LSCP hex escape sequences (\xHH)
161        QRegExp regexp(QRegExp::escape("\\x") + "[0-9a-fA-F][0-9a-fA-F]");
162        for (int i = txt.indexOf(regexp); i >= 0; i = txt.indexOf(regexp, i + 4)) {
163            const QString sHex = txt.mid(i+2, 2).toLower();
164            // decode into raw ASCII character
165            char cAscii = _hexsToNumber(sHex.at(1).toLatin1(), sHex.at(0).toLatin1());
166            txt.replace(i, 4, cAscii);
167        }
168    
169        return txt;
170    }
171    
172    lscpVersion_t getRemoteLscpVersion (void)
173    {
174      lscpVersion_t result = { 0, 0 };      lscpVersion_t result = { 0, 0 };
175    
176      qsamplerMainForm *pMainForm = qsamplerMainForm::getInstance();      MainForm* pMainForm = MainForm::getInstance();
177      if (!pMainForm || !pMainForm->client()) return result;      if (pMainForm == NULL)
178            return result;
179        if (pMainForm->client() == NULL)
180            return result;
181    
182      lscp_server_info_t* pServerInfo =      lscp_server_info_t* pServerInfo =
183          ::lscp_get_server_info(pMainForm->client());          ::lscp_get_server_info(pMainForm->client());
184      if (!pServerInfo) return result;      if (pServerInfo && pServerInfo->protocol_version)
185            ::sscanf(pServerInfo->protocol_version, "%d.%d",
186                &result.major, &result.minor);
187    
     sscanf(pServerInfo->protocol_version, "%d.%d", &result.major, &result.minor);  
188      return result;      return result;
189  }  }
190    
191    } // namespace qsamplerUtilities
192    
193    
194    // end of qsamplerUtilities.cpp

Legend:
Removed from v.1386  
changed lines
  Added in v.1499

  ViewVC Help
Powered by ViewVC