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

Legend:
Removed from v.3356  
changed lines
  Added in v.3357

  ViewVC Help
Powered by ViewVC