diff options
Diffstat (limited to 'Sources/Cepis/CSV.swift')
| -rw-r--r-- | Sources/Cepis/CSV.swift | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/Sources/Cepis/CSV.swift b/Sources/Cepis/CSV.swift new file mode 100644 index 0000000..064ed05 --- /dev/null +++ b/Sources/Cepis/CSV.swift @@ -0,0 +1,63 @@ +import Foundation + +enum CSV { + static func parse(_ text: String) -> [[String]] { + var rows: [[String]] = [] + var row: [String] = [] + var field = "" + var inQuotes = false + + let scalars = Array(text.unicodeScalars) + var index = 0 + + while index < scalars.count { + let scalar = scalars[index] + + if inQuotes { + if scalar == "\"" { + if index + 1 < scalars.count && scalars[index + 1] == "\"" { + field.unicodeScalars.append("\"") + index += 2 + } else { + inQuotes = false + index += 1 + } + } else { + field.unicodeScalars.append(scalar) + index += 1 + } + continue + } + + switch scalar { + case "\"": + inQuotes = true + index += 1 + case ",": + row.append(field) + field = "" + index += 1 + case "\r", "\n": + row.append(field) + field = "" + rows.append(row) + row = [] + if scalar == "\r", index + 1 < scalars.count, scalars[index + 1] == "\n" { + index += 2 + } else { + index += 1 + } + default: + field.unicodeScalars.append(scalar) + index += 1 + } + } + + if !field.isEmpty || !row.isEmpty { + row.append(field) + rows.append(row) + } + + return rows + } +} |