/[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 3913 by capela, Tue Jun 16 09:13:12 2020 UTC revision 3914 by capela, Fri Jun 4 22:22:41 2021 UTC
# Line 69  static int _hexsToNumber ( char hex0, ch Line 69  static int _hexsToNumber ( char hex0, ch
69          return _hexToNumber(hex1) * 16 + _hexToNumber(hex0);          return _hexToNumber(hex1) * 16 + _hexToNumber(hex0);
70  }  }
71    
72    static bool _isHex ( char hex_digit )
73    {
74            return _hexToNumber ( hex_digit ) || hex_digit == '0';
75    }
76    
77  // returns true if the connected LSCP server supports escape sequences  // returns true if the connected LSCP server supports escape sequences
78  static bool _remoteSupportsEscapeSequences (void)  static bool _remoteSupportsEscapeSequences (void)
# Line 80  static bool _remoteSupportsEscapeSequenc Line 84  static bool _remoteSupportsEscapeSequenc
84    
85    
86  // 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
87  QString lscpEscapePath ( const QString& sPath )  QByteArray lscpEscapePath ( const QString& sPath )
88  {  {
89          if (!_remoteSupportsEscapeSequences()) return sPath;          QByteArray path = sPath.toUtf8();
90            if (!_remoteSupportsEscapeSequences()) return path;
91    
92          QString path(sPath);          const char pathSeparator = '/';
93            int path_len = path.length();
94          // replace POSIX path escape sequences (%HH) by LSCP escape sequences (\xHH)          char buf[5];
95          // TODO: missing code for other systems like Windows  
96          {          // Trying single pass to avoid redundant checks on extra run
97                  QRegularExpression regexp("%[0-9a-fA-F][0-9a-fA-F]");          for ( int i = 0; i < path_len; i++ ) {
98                  for (int i = path.indexOf(regexp); i >= 0; i = path.indexOf(regexp, i + 4))                  // translate POSIX escape sequences
99                          path.replace(i, 1, "\\x");                  if (path[i] == '%') {
100          }                          // replace POSIX path escape sequences (%HH) by LSCP escape sequences (\xHH)
101          // replace POSIX path escape sequence (%%) by its raw character                          // TODO: missing code for other systems like Windows
102          for (int i = path.indexOf("%%"); i >= 0; i = path.indexOf("%%", ++i))                          if (_isHex(path[i+1]) && _isHex(path[i+2])) {
103                  path.remove(i, 1);                                  path.replace (i, 1, "\\x");
104                                    path_len++;
         // replace all non-basic characters by LSCP escape sequences  
         {  
                 const char pathSeparator = '/';  
                 QRegularExpression regexp(QRegularExpression::escape("\\x") + "[0-9a-fA-F][0-9a-fA-F]");  
                 for (int i = 0; i < int(path.length()); i++) {  
                         // first skip all previously added LSCP escape sequences  
                         if (path.indexOf(regexp, i) == i) {  
105                                  i += 3;                                  i += 3;
106                                  continue;                                  continue;
107                          }                          }
108                          // now match all non-alphanumerics                          // replace POSIX path escape sequence (%%) by its raw character
109                          // (we could exclude much more characters here, but that way                          if (path[i+1] == '%') {
110                          // we're sure it just works^TM)                                  path.remove (i, 1);
111                          const char c = path.at(i).toLatin1();                                  path_len--;
112                          if (                                  continue;
                                 !(c >= '0' && c <= '9') &&  
                                 !(c >= 'a' && c <= 'z') &&  
                                 !(c >= 'A' && c <= 'Z') &&  
                         #if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)  
                                 !(c == ':') &&  
                         #endif  
                                 !(c == pathSeparator)  
                         ) {  
                                 // convert the non-basic character into a LSCP escape sequence  
                                 char buf[5];  
                                 ::snprintf(buf, sizeof(buf), "\\x%02x", static_cast<unsigned char>(c));  
                                 path.replace(i, 1, buf);  
                                 i += 3;  
113                          }                          }
114                            continue;
115                    }
116                    // replace all non-basic characters by LSCP escape sequences
117                    //
118                    // match all non-alphanumerics
119                    // (we could exclude much more characters here, but that way
120                    // we're sure it just works^TM)
121                    const char c = path[i];
122                    if (
123                            !(c >= '0' && c <= '9') &&
124                            !(c >= 'a' && c <= 'z') &&
125                            !(c >= 'A' && c <= 'Z') &&
126                    #if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
127                            !(c == ':') &&
128                    #endif
129                            !(c == pathSeparator)
130                    ) {
131                            // convertion
132                            ::snprintf(buf, sizeof(buf), "\\x%02x", static_cast<unsigned char>(c));
133                            path = path.replace(i, 1, buf);
134                            path_len += 3;
135                            i += 3;
136                  }                  }
137          }          }
138    
# Line 135  QString lscpEscapePath ( const QString& Line 142  QString lscpEscapePath ( const QString&
142    
143  // converts a path returned by a LSCP command (and may contain escape  // converts a path returned by a LSCP command (and may contain escape
144  // sequences) into the appropriate POSIX path  // sequences) into the appropriate POSIX path
145  QString lscpEscapedPathToPosix ( const QString& sPath )  QString lscpEscapedPathToPosix ( const char* sPath )
146  {  {
147          if (!_remoteSupportsEscapeSequences()) return sPath;          if (!_remoteSupportsEscapeSequences()) return QString(sPath);
   
         QString path(sPath);  
148    
149          // first escape all percent ('%') characters for POSIX          QByteArray path(sPath);
150          for (int i = path.indexOf('%'); i >= 0; i = path.indexOf('%', i+2))          int path_len = path.length();
                 path.replace(i, 1, "%%");  
151    
152          // resolve LSCP hex escape sequences (\xHH)          char cAscii[2] = "\0";
153          QRegularExpression regexp(QRegularExpression::escape("\\x") + "[0-9a-fA-F][0-9a-fA-F]");          for ( int i = 0; i < path_len; i++) {
154          for (int i = path.indexOf(regexp); i >= 0; i = path.indexOf(regexp, i + 4)) {                  // first escape all percent ('%') characters for POSIX
155                  const QString sHex = path.mid(i + 2, 2).toLower();                  if (path[i] == '%') {
156                  // the slash has to be escaped for POSIX as well                          path.insert(i, '%');
157                  if (sHex == "2f") {                          path_len++;
158                          path.replace(i, 4, "%2f");                          i++;
159                            continue;
160                    }
161                    // resolve LSCP hex escape sequences (\xHH)
162                    if (path[i] == '\\' && path[i+1] == 'x' && _isHex(path[i+2]) && _isHex(path[i+3])) {
163                            const QByteArray sHex = path.mid(i + 2, 2).toLower();
164                            // the slash has to be escaped for POSIX as well
165                            if (sHex == "2f") {
166                                    path.replace(i, 4, "%2f");
167                            // all other characters we simply decode
168                            } else {
169                                    cAscii[0] = _hexsToNumber(sHex[1], sHex[0]);
170                                    path.replace(i, 4, cAscii);
171                            }
172                            path_len -= 3;
173                          continue;                          continue;
174                  }                  }
                 // all other characters we simply decode  
                 char cAscii = _hexsToNumber(sHex.at(1).toLatin1(), sHex.at(0).toLatin1());  
                 path.replace(i, 4, cAscii);  
175          }          }
176    
177          return path;          return QString(path);
178  }  }
179    
180    
181  // converts the given text as expected by LSCP 1.2  // converts the given text as expected by LSCP 1.2
182  // (that is by encoding special characters with LSCP escape sequences)  // (that is by encoding special characters with LSCP escape sequences)
183  QString lscpEscapeText ( const QString& sText )  QByteArray lscpEscapeText ( const QString& sText )
184  {  {
185          if (!_remoteSupportsEscapeSequences()) return sText;          QByteArray text = sText.toUtf8();
186            if (!_remoteSupportsEscapeSequences()) return text;
187    
188          QString text(sText);          int text_len = text.length();
189            char buf[5];
190    
191          // replace all non-basic characters by LSCP escape sequences          // replace all non-basic characters by LSCP escape sequences
192          for (int i = 0; i < int(text.length()); ++i) {          for (int i = 0; i < text_len; ++i) {
193                  // match all non-alphanumerics                  // match all non-alphanumerics
194                  // (we could exclude much more characters here, but that way                  // (we could exclude much more characters here, but that way
195                  // we're sure it just works^TM)                  // we're sure it just works^TM)
196                  const char c = text.at(i).toLatin1();                  const char c = text[i];
197                  if (                  if (
198                          !(c >= '0' && c <= '9') &&                          !(c >= '0' && c <= '9') &&
199                          !(c >= 'a' && c <= 'z') &&                          !(c >= 'a' && c <= 'z') &&
200                          !(c >= 'A' && c <= 'Z')                          !(c >= 'A' && c <= 'Z')
201                  ) {                  ) {
202                          // convert the non-basic character into a LSCP escape sequence                          // convert the non-basic character into a LSCP escape sequence
                         char buf[5];  
203                          ::snprintf(buf, sizeof(buf), "\\x%02x", static_cast<unsigned char>(c));                          ::snprintf(buf, sizeof(buf), "\\x%02x", static_cast<unsigned char>(c));
204                          text.replace(i, 1, buf);                          text.replace(i, 1, buf);
205                            text_len += 3;
206                          i += 3;                          i += 3;
207                  }                  }
208          }          }
# Line 196  QString lscpEscapeText ( const QString& Line 213  QString lscpEscapeText ( const QString&
213    
214  // converts a text returned by a LSCP command and may contain escape  // converts a text returned by a LSCP command and may contain escape
215  // sequences) into raw text, that is with all escape sequences decoded  // sequences) into raw text, that is with all escape sequences decoded
216  QString lscpEscapedTextToRaw ( const QString& sText )  QString lscpEscapedTextToRaw ( const char* sText )
217  {  {
218          if (!_remoteSupportsEscapeSequences()) return sText;          if (!_remoteSupportsEscapeSequences()) return QString(sText);
219    
220          QString text(sText);          QByteArray text(sText);
221            int text_len = text.length();
222            char sHex[2], cAscii[2] = "\0";
223    
224          // resolve LSCP hex escape sequences (\xHH)          // resolve LSCP hex escape sequences (\xHH)
225          QRegularExpression regexp(QRegularExpression::escape("\\x") + "[0-9a-fA-F][0-9a-fA-F]");          for (int i = 0; i < text_len; i++) {
226          for (int i = text.indexOf(regexp); i >= 0; i = text.indexOf(regexp, i + 4)) {                  if (text[i] != '\\' || text[i+1] != 'x') continue;
227                  const QString sHex = text.mid(i + 2, 2).toLower();  
228                  // decode into raw ASCII character                  sHex[0] = text[i+2], sHex[1] = text[i+3];
229                  char cAscii = _hexsToNumber(sHex.at(1).toLatin1(), sHex.at(0).toLatin1());                  if (_isHex(sHex[0]) && _isHex(sHex[1])) {
230                  text.replace(i, 4, cAscii);                          cAscii[0] = _hexsToNumber(sHex[1], sHex[0]);
231                            text.replace(i, 4, cAscii);
232                            text_len -= 3;
233                    }
234          }          }
235    
236          return text;          return QString(text);
237  }  }
238    
239  lscpVersion_t getRemoteLscpVersion (void)  lscpVersion_t getRemoteLscpVersion (void)

Legend:
Removed from v.3913  
changed lines
  Added in v.3914

  ViewVC Help
Powered by ViewVC