Split string to elements @input: - line - string with data - separator - string or character that separate elements - textDelimiter - string that is used as text delimiter @output: - QList - list of elements
| 174 | // @output: |
| 175 | // - QList<QString> - list of elements |
| 176 | QList<QString> ReaderPrivate::splitElements( |
| 177 | const QString& line, |
| 178 | const QString& separator, |
| 179 | const QString& textDelimiter, |
| 180 | ElementInfo& elemInfo) |
| 181 | { |
| 182 | // If separator is empty, return whole line. Can't work in this |
| 183 | // conditions! |
| 184 | if (separator.isEmpty()) { |
| 185 | elemInfo.isEnded = true; |
| 186 | return (QList<QString>() << line); |
| 187 | } |
| 188 | |
| 189 | if (line.isEmpty()) { |
| 190 | // If previous row was ended, then return empty QList<QString>. |
| 191 | // Otherwise return list that contains one element - new line symbols |
| 192 | return elemInfo.isEnded ? QList<QString>() : (QList<QString>() << LF); |
| 193 | } |
| 194 | |
| 195 | QList<QString> result; |
| 196 | qsizetype pos = 0; |
| 197 | while (pos < line.size()) { |
| 198 | if (elemInfo.isEnded) { |
| 199 | // This line is a new line, not a continuation of the previous |
| 200 | // line. |
| 201 | // Check if element starts with the delimiter symbol |
| 202 | const auto delimiterPos = line.indexOf(textDelimiter, pos); |
| 203 | if (delimiterPos == pos) { |
| 204 | pos = delimiterPos + textDelimiter.size(); |
| 205 | |
| 206 | // Element starts with the delimiter symbol. It means that |
| 207 | // this element could contain any number of double |
| 208 | // delimiters and separator symbols. This element could: |
| 209 | // 1. Be the first or the middle element. Then it should end |
| 210 | // with delimiter and the seprator symbols standing next to each |
| 211 | // other. |
| 212 | const auto midElemEndPos = findMiddleElementPosition( |
| 213 | line, pos, separator, textDelimiter); |
| 214 | if (midElemEndPos > 0) { |
| 215 | const auto length = midElemEndPos - pos; |
| 216 | result << line.mid(pos, length); |
| 217 | pos = |
| 218 | midElemEndPos + textDelimiter.size() + separator.size(); |
| 219 | continue; |
| 220 | } |
| 221 | |
| 222 | // 2. Be The last element on the line. Then it should end with |
| 223 | // delimiter symbol. |
| 224 | if (isElementLast(line, pos, separator, textDelimiter)) { |
| 225 | const auto length = line.size() - textDelimiter.size() - pos; |
| 226 | result << line.mid(pos, length); |
| 227 | break; |
| 228 | } |
| 229 | |
| 230 | // 3. Not ends on this line |
| 231 | const auto length = line.size() - pos; |
| 232 | result << line.mid(pos, length); |
| 233 | elemInfo.isEnded = false; |