/[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 1394 by capela, Mon Oct 8 09:37:39 2007 UTC revision 1667 by schoenebeck, Mon Feb 4 23:24:19 2008 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, 2008 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 21  Line 22 
22    
23  #include "qsamplerUtilities.h"  #include "qsamplerUtilities.h"
24    
25    #include "qsamplerOptions.h"
26  #include "qsamplerMainForm.h"  #include "qsamplerMainForm.h"
27    
28  #include <stdio.h>  #include <QRegExp>
29  #include <qregexp.h>  
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  // converts the given file path into a path as expected by LSCP 1.2
78  QString lscpEscapePath ( const QString& sPath )  QString lscpEscapePath ( const QString& sPath )
79  {  {
80          QString path(sPath);      if (!_remoteSupportsEscapeSequences()) return sPath;
81    
82      // check if remote side supports LSCP escape sequences      QString path(sPath);
     const lscpVersion_t version = getRemoteLscpVersion();  
     if (version.major < 1 || version.minor < 2)  
         return path; // LSCP v1.2 or younger required  
83    
84      // replace POSIX path escape sequences (%HH) by LSCP escape sequences (\xHH)      // replace POSIX path escape sequences (%HH) by LSCP escape sequences (\xHH)
85      // TODO: missing code for other systems like Windows      // TODO: missing code for other systems like Windows
86      {      {
87          QRegExp regexp("%[0-9a-fA-F][0-9a-fA-F]");          QRegExp regexp("%[0-9a-fA-F][0-9a-fA-F]");
88          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))
89              path.replace(i, 1, "\\x");              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      // replace all non-basic characters by LSCP escape sequences
96      {      {
# Line 50  QString lscpEscapePath ( const QString& Line 98  QString lscpEscapePath ( const QString&
98          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]");
99          for (int i = 0; i < int(path.length()); i++) {          for (int i = 0; i < int(path.length()); i++) {
100              // first skip all previously added LSCP escape sequences              // first skip all previously added LSCP escape sequences
101              if (path.find(regexp, i) == i) {              if (path.indexOf(regexp, i) == i) {
102                  i += 3;                  i += 3;
103                  continue;                  continue;
104              }              }
105              // now match all non-alphanumerics              // now match all non-alphanumerics
106              // (we could exclude much more characters here, but that way              // (we could exclude much more characters here, but that way
107              // we're sure it just works^TM)              // we're sure it just works^TM)
108              const char c = path.at(i).latin1();              const char c = path.at(i).toLatin1();
109              if (              if (
110                  !(c >= '0' && c <= '9') &&                  !(c >= '0' && c <= '9') &&
111                  !(c >= 'a' && c <= 'z') &&                  !(c >= 'a' && c <= 'z') &&
112                  !(c >= 'A' && c <= 'Z') &&                  !(c >= 'A' && c <= 'Z') &&
113                    #if defined(WIN32)
114                    !(c == ':') &&
115                    #endif
116                  !(c == pathSeparator)                  !(c == pathSeparator)
117              ) {              ) {
118                  // convert the non-basic character into a LSCP escape sequence                  // convert the non-basic character into a LSCP escape sequence
119                  char buf[5];                  char buf[5];
120                  ::snprintf(buf, sizeof(buf), "\\x%2x", static_cast<unsigned char>(c));                  ::snprintf(buf, sizeof(buf), "\\x%02x", static_cast<unsigned char>(c));
121                  path.replace(i, 1, buf);                  path.replace(i, 1, buf);
122                  i += 3;                  i += 3;
123              }              }
# Line 76  QString lscpEscapePath ( const QString& Line 127  QString lscpEscapePath ( const QString&
127      return path;      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)  lscpVersion_t getRemoteLscpVersion (void)
203  {  {
204      lscpVersion_t result = { 0, 0 };      lscpVersion_t result = { 0, 0 };
205    
206      qsamplerMainForm *pMainForm = qsamplerMainForm::getInstance();      MainForm* pMainForm = MainForm::getInstance();
207      if (pMainForm == NULL)      if (pMainForm == NULL)
208                  return result;          return result;
209          if (pMainForm->client() == NULL)      if (pMainForm->client() == NULL)
210                  return result;          return result;
211    
212      lscp_server_info_t* pServerInfo =      lscp_server_info_t* pServerInfo =
213          ::lscp_get_server_info(pMainForm->client());          ::lscp_get_server_info(pMainForm->client());
214      if (pServerInfo && pServerInfo->protocol_version)      if (pServerInfo && pServerInfo->protocol_version)
215                  ::sscanf(pServerInfo->protocol_version, "%d.%d",          ::sscanf(pServerInfo->protocol_version, "%d.%d",
216                          &result.major, &result.minor);              &result.major, &result.minor);
217    
218      return result;      return result;
219  }  }
220    
221    } // namespace qsamplerUtilities
222    
223    
224    // end of qsamplerUtilities.cpp

Legend:
Removed from v.1394  
changed lines
  Added in v.1667

  ViewVC Help
Powered by ViewVC