svcore  1.9
StringBits.cpp
Go to the documentation of this file.
00001 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
00002 
00003 /*
00004     Sonic Visualiser
00005     An audio file viewer and annotation editor.
00006     Centre for Digital Music, Queen Mary, University of London.
00007     
00008     This program is free software; you can redistribute it and/or
00009     modify it under the terms of the GNU General Public License as
00010     published by the Free Software Foundation; either version 2 of the
00011     License, or (at your option) any later version.  See the file
00012     COPYING included with this distribution for more information.
00013 */
00014 
00015 /*
00016    This is a modified version of a source file from the 
00017    Rosegarden MIDI and audio sequencer and notation editor.
00018    This file copyright 2000-2010 Chris Cannam.
00019 */
00020 
00021 #include "StringBits.h"
00022 
00023 double
00024 StringBits::stringToDoubleLocaleFree(QString s, bool *ok)
00025 {
00026     int dp = 0;
00027     int sign = 1;
00028     int i = 0;
00029     double result = 0.0;
00030     int len = s.length();
00031 
00032     result = 0.0;
00033 
00034     if (ok) *ok = true;
00035 
00036     while (i < len && s[i].isSpace()) ++i;
00037     if (i < len && s[i] == '-') sign = -1;
00038 
00039     while (i < len) {
00040 
00041         QChar c = s[i];
00042 
00043         if (c.isDigit()) {
00044 
00045             double d = c.digitValue();
00046 
00047             if (dp > 0) {
00048                 for (int p = dp; p > 0; --p) d /= 10.0;
00049                 ++dp;
00050             } else {
00051                 result *= 10.0;
00052             }
00053 
00054             result += d;
00055 
00056         } else if (c == '.') {
00057 
00058             dp = 1;
00059 
00060         } else if (ok) {
00061             *ok = false;
00062         }
00063 
00064         ++i;
00065     }
00066 
00067     return result * sign;
00068 }
00069     
00070 QStringList
00071 StringBits::splitQuoted(QString s, QChar separator)
00072 {
00073     QStringList tokens;
00074     QString tok;
00075 
00076     enum { sep, unq, q1, q2 } mode = sep;
00077 
00078     for (int i = 0; i < s.length(); ++i) {
00079         
00080         QChar c = s[i];
00081 
00082         if (c == '\'') {
00083             switch (mode) {
00084             case sep: mode = q1; break;
00085             case unq: case q2: tok += c; break;
00086             case q1: mode = sep; tokens << tok; tok = ""; break;
00087             }
00088 
00089         } else if (c == '"') {
00090             switch (mode) {
00091             case sep: mode = q2; break;
00092             case unq: case q1: tok += c; break;
00093             case q2: mode = sep; tokens << tok; tok = ""; break;
00094             }
00095 
00096         } else if (c == separator || (separator == ' ' && c.isSpace())) {
00097             switch (mode) {
00098             case sep: if (separator != ' ') tokens << ""; break;
00099             case unq: mode = sep; tokens << tok; tok = ""; break;
00100             case q1: case q2: tok += c; break;
00101             }
00102 
00103         } else if (c == '\\') {
00104             if (++i < s.length()) {
00105                 c = s[i];
00106                 switch (mode) {
00107                 case sep: mode = unq; tok += c; break;
00108                 case unq: case q1: case q2: tok += c; break;
00109                 }
00110             }
00111 
00112         } else {
00113             switch (mode) {
00114             case sep: mode = unq; tok += c; break;
00115             case unq: case q1: case q2: tok += c; break;
00116             }
00117         }
00118     }
00119 
00120     if (tok != "" || mode != sep) tokens << tok;
00121     return tokens;
00122 }
00123 
00124 /*
00125 
00126 void testSplit()
00127 {
00128     QStringList tests;
00129     tests << "a b c d";
00130     tests << "a \"b c\" d";
00131     tests << "a 'b c' d";
00132     tests << "a \"b c\\\" d\"";
00133     tests << "a 'b c\\' d'";
00134     tests << "a \"b c' d\"";
00135     tests << "a 'b c\" d'";
00136     tests << "aa 'bb cc\" dd'";
00137     tests << "a'a 'bb' \\\"cc\" dd\\\"";
00138     tests << "  a'a \\\'         'bb'    \'     \\\"cc\" ' dd\\\" '";
00139 
00140     for (int j = 0; j < tests.size(); ++j) {
00141         cout << endl;
00142         cout << tests[j] << endl;
00143         cout << "->" << endl << "(";
00144         QStringList l = splitQuoted(tests[j], ' ');
00145         for (int i = 0; i < l.size(); ++i) {
00146             if (i > 0) cout << ";";
00147             cout << l[i];
00148         }
00149         cout << ")" << endl;
00150     }
00151 }
00152 
00153 */
00154 
00155 /* 
00156    Results:
00157 
00158 a b c d
00159 ->     
00160 (a;b;c;d)
00161 
00162 a "b c" d
00163 ->       
00164 (a;b c;d)
00165 
00166 a 'b c' d
00167 ->       
00168 (a;b c;d)
00169 
00170 a "b c\" d"
00171 ->         
00172 (a;b c" d) 
00173 
00174 a 'b c\' d'
00175 ->         
00176 (a;b c' d) 
00177 
00178 a "b c' d"
00179 ->        
00180 (a;b c' d)
00181 
00182 a 'b c" d'
00183 ->        
00184 (a;b c" d)
00185 
00186 aa 'bb cc" dd'
00187 ->            
00188 (aa;bb cc" dd)
00189 
00190 a'a 'bb' \"cc" dd\"
00191 ->                 
00192 (a'a;bb;"cc";dd")  
00193 
00194   a'a \'         'bb'    '      \"cc" ' dd\" '
00195 ->                                            
00196 (a'a;';bb;      "cc" ;dd";)
00197 
00198 */
00199 
00200 QStringList
00201 StringBits::split(QString line, QChar separator, bool quoted)
00202 {
00203     if (quoted) {
00204         return splitQuoted(line, separator);
00205     } else {
00206         return line.split(separator,
00207                           separator == ' ' ? QString::SkipEmptyParts :
00208                           QString::KeepEmptyParts);
00209     }
00210 }
00211