/[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 3358 by capela, Wed Oct 18 08:57:21 2017 UTC
# Line 1  Line 1 
1  // qsamplerUtilities.cpp  // qsamplerUtilities.cpp
2  //  //
3  /****************************************************************************  /****************************************************************************
4     Copyright (C) 2004-2007, rncbc aka Rui Nuno Capela. All rights reserved.     Copyright (C) 2004-2017, 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    {
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    
49                    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    
56                    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    
63                    default:  return 0;
64            }
65    }
66    
67    static int _hexsToNumber ( char hex0, char hex1 )
68    {
69            return _hexToNumber(hex1) * 16 + _hexToNumber(hex0);
70    }
71    
72    
73    // returns true if the connected LSCP server supports escape sequences
74    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    }
80    
81    
82  // 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
83  QString lscpEscapePath ( const QString& sPath )  QString lscpEscapePath ( const QString& sPath )
84  {  {
85            if (!_remoteSupportsEscapeSequences()) return sPath;
86    
87            QString path(sPath);
88    
89            // 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    
100            // 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                            #if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
119                                    !(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    
132            return path;
133    }
134    
135    
136    // converts a path returned by a LSCP command (and may contain escape
137    // sequences) into the appropriate POSIX path
138    QString lscpEscapedPathToPosix ( const QString& sPath )
139    {
140            if (!_remoteSupportsEscapeSequences()) return sPath;
141    
142          QString path(sPath);          QString path(sPath);
143    
144      // check if remote side supports LSCP escape sequences          // first escape all percent ('%') characters for POSIX
145      const lscpVersion_t version = getRemoteLscpVersion();          for (int i = path.indexOf('%'); i >= 0; i = path.indexOf('%', i+2))
146      if (version.major < 1 || version.minor < 2)                  path.replace(i, 1, "%%");
147          return path; // LSCP v1.2 or younger required  
148            // resolve LSCP hex escape sequences (\xHH)
149      // replace POSIX path escape sequences (%HH) by LSCP escape sequences (\xHH)          QRegExp regexp(QRegExp::escape("\\x") + "[0-9a-fA-F][0-9a-fA-F]");
150      // TODO: missing code for other systems like Windows          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          QRegExp regexp("%[0-9a-fA-F][0-9a-fA-F]");                  // the slash has to be escaped for POSIX as well
153          for (int i = path.find(regexp); i >= 0; i = path.find(regexp, i + 3))                  if (sHex == "2f") {
154              path.replace(i, 1, "\\x");                          path.replace(i, 4, "%2f");
155      }                          continue;
156                    }
157      // replace all non-basic characters by LSCP escape sequences                  // all other characters we simply decode
158      {                  char cAscii = _hexsToNumber(sHex.at(1).toLatin1(), sHex.at(0).toLatin1());
159          const char pathSeparator = '/';                  path.replace(i, 4, cAscii);
160          QRegExp regexp(QRegExp::escape("\\x") + "[0-9a-fA-F][0-9a-fA-F]");          }
161          for (int i = 0; i < int(path.length()); i++) {  
162              // first skip all previously added LSCP escape sequences          return path;
163              if (path.find(regexp, i) == i) {  }
164                  i += 3;  
165                  continue;  
166              }  // converts the given text as expected by LSCP 1.2
167              // now match all non-alphanumerics  // (that is by encoding special characters with LSCP escape sequences)
168              // (we could exclude much more characters here, but that way  QString lscpEscapeText ( const QString& sText )
169              // we're sure it just works^TM)  {
170              const char c = path.at(i).latin1();          if (!_remoteSupportsEscapeSequences()) return sText;
171              if (  
172                  !(c >= '0' && c <= '9') &&          QString text(sText);
                 !(c >= 'a' && c <= 'z') &&  
                 !(c >= 'A' && c <= 'Z') &&  
                 !(c == pathSeparator)  
             ) {  
                 // convert the non-basic character into a LSCP escape sequence  
                 char buf[5];  
                 ::snprintf(buf, sizeof(buf), "\\x%2x", static_cast<unsigned char>(c));  
                 path.replace(i, 1, buf);  
                 i += 3;  
             }  
         }  
     }  
173    
174      return path;          // 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    
193            return text;
194  }  }
195    
196    
197    // 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    QString lscpEscapedTextToRaw ( const QString& sText )
200    {
201            if (!_remoteSupportsEscapeSequences()) return sText;
202    
203            QString text(sText);
204    
205            // 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    }
216    
217  lscpVersion_t getRemoteLscpVersion (void)  lscpVersion_t getRemoteLscpVersion (void)
218  {  {
219      lscpVersion_t result = { 0, 0 };      lscpVersion_t result = { 0, 0 };
220    
221      qsamplerMainForm *pMainForm = qsamplerMainForm::getInstance();      MainForm* pMainForm = MainForm::getInstance();
222      if (pMainForm == NULL)      if (pMainForm == NULL)
223                  return result;          return result;
224          if (pMainForm->client() == NULL)      if (pMainForm->client() == NULL)
225                  return result;          return result;
226    
227      lscp_server_info_t* pServerInfo =      lscp_server_info_t* pServerInfo =
228          ::lscp_get_server_info(pMainForm->client());          ::lscp_get_server_info(pMainForm->client());
229      if (pServerInfo && pServerInfo->protocol_version)      if (pServerInfo && pServerInfo->protocol_version)
230                  ::sscanf(pServerInfo->protocol_version, "%d.%d",          ::sscanf(pServerInfo->protocol_version, "%d.%d",
231                          &result.major, &result.minor);              &result.major, &result.minor);
232    
233      return result;      return result;
234  }  }
235    
236    } // namespace qsamplerUtilities
237    
238    
239    // end of qsamplerUtilities.cpp

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

  ViewVC Help
Powered by ViewVC