Mercurial > hg > svcore
diff base/StringBits.cpp @ 629:35499d48a5d1
* Start overhauling CSV parser to associate purposes with columns en route to its guesses; add some string manipulation code
author | Chris Cannam |
---|---|
date | Thu, 15 Jul 2010 15:27:21 +0000 |
parents | |
children | b4a8d8221eaf |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/base/StringBits.cpp Thu Jul 15 15:27:21 2010 +0000 @@ -0,0 +1,211 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Sonic Visualiser + An audio file viewer and annotation editor. + Centre for Digital Music, Queen Mary, University of London. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + +/* + This is a modified version of a source file from the + Rosegarden MIDI and audio sequencer and notation editor. + This file copyright 2000-2010 Chris Cannam. +*/ + +#include "StringBits.h" + +double +StringBits::stringToDoubleLocaleFree(QString s, bool *ok) +{ + int dp = 0; + int sign = 1; + int i = 0; + double result = 0.0; + int len = s.length(); + + result = 0.0; + + if (ok) *ok = true; + + while (i < len && s[i].isSpace()) ++i; + if (i < len && s[i] == '-') sign = -1; + + while (i < len) { + + QChar c = s[i]; + + if (c.isDigit()) { + + double d = c.digitValue(); + + if (dp > 0) { + for (int p = dp; p > 0; --p) d /= 10.0; + ++dp; + } else { + result *= 10.0; + } + + result += d; + + } else if (c == '.') { + + dp = 1; + + } else if (ok) { + *ok = false; + } + + ++i; + } + + return result * sign; +} + +QStringList +StringBits::splitQuoted(QString s, QChar separator) +{ + QStringList tokens; + QString tok; + + enum { sep, unq, q1, q2 } mode = sep; + + for (int i = 0; i < s.length(); ++i) { + + QChar c = s[i]; + + if (c == '\'') { + switch (mode) { + case sep: mode = q1; break; + case unq: case q2: tok += c; break; + case q1: mode = sep; tokens << tok; tok = ""; break; + } + + } else if (c == '"') { + switch (mode) { + case sep: mode = q2; break; + case unq: case q1: tok += c; break; + case q2: mode = sep; tokens << tok; tok = ""; break; + } + + } else if (c == separator || (separator == ' ' && c.isSpace())) { + switch (mode) { + case sep: if (separator != ' ') tokens << ""; break; + case unq: mode = sep; tokens << tok; tok = ""; break; + case q1: case q2: tok += c; break; + } + + } else if (c == '\\') { + if (++i < s.length()) { + c = s[i]; + switch (mode) { + case sep: mode = unq; tok += c; break; + default: tok += c; break; + } + } + + } else { + switch (mode) { + case sep: mode = unq; tok += c; break; + default: tok += c; break; + } + } + } + + if (tok != "" || mode != sep) tokens << tok; + return tokens; +} + +/* + +void testSplit() +{ + QStringList tests; + tests << "a b c d"; + tests << "a \"b c\" d"; + tests << "a 'b c' d"; + tests << "a \"b c\\\" d\""; + tests << "a 'b c\\' d'"; + tests << "a \"b c' d\""; + tests << "a 'b c\" d'"; + tests << "aa 'bb cc\" dd'"; + tests << "a'a 'bb' \\\"cc\" dd\\\""; + tests << " a'a \\\' 'bb' \' \\\"cc\" ' dd\\\" '"; + + for (int j = 0; j < tests.size(); ++j) { + cout << endl; + cout << tests[j].toStdString() << endl; + cout << "->" << endl << "("; + QStringList l = splitQuoted(tests[j], ' '); + for (int i = 0; i < l.size(); ++i) { + if (i > 0) cout << ";"; + cout << l[i].toStdString(); + } + cout << ")" << endl; + } +} + +*/ + +/* + Results: + +a b c d +-> +(a;b;c;d) + +a "b c" d +-> +(a;b c;d) + +a 'b c' d +-> +(a;b c;d) + +a "b c\" d" +-> +(a;b c" d) + +a 'b c\' d' +-> +(a;b c' d) + +a "b c' d" +-> +(a;b c' d) + +a 'b c" d' +-> +(a;b c" d) + +aa 'bb cc" dd' +-> +(aa;bb cc" dd) + +a'a 'bb' \"cc" dd\" +-> +(a'a;bb;"cc";dd") + + a'a \' 'bb' ' \"cc" ' dd\" ' +-> +(a'a;';bb; "cc" ;dd";) + +*/ + +QStringList +StringBits::split(QString line, QChar separator, bool quoted) +{ + if (quoted) { + return splitQuoted(line, separator); + } else { + return line.split(separator, + separator == ' ' ? QString::SkipEmptyParts : + QString::KeepEmptyParts); + } +} +