summaryrefslogtreecommitdiffstats
path: root/Sources/Cepis/CSV.swift
diff options
context:
space:
mode:
Diffstat (limited to 'Sources/Cepis/CSV.swift')
-rw-r--r--Sources/Cepis/CSV.swift63
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
+ }
+}