@@ -12,7 +12,7 @@ import Data.Char (ord, isUpper, isSpace)
1212import qualified Data.ByteString.Lazy as BS
1313import Data.Text.Encoding (decodeUtf8)
1414import qualified Data.Set as S
15−import Data.HashMap.Lazy as HM
15+import qualified Data.HashMap.Lazy as HM
1616import qualified Data.List as L
1717import qualified Data.Text as T
1818import qualified Data.Attoparsec.ByteString.Lazy as APBL
@@ -60,9 +60,9 @@ parseCSVAtomP :: AttributeName -> TypeConstructorMapping -> AtomType -> APT.Pars
6060parseCSVAtomP _ _ IntegerAtomType = (Right . IntegerAtom) <$> APT.decimal
6161parseCSVAtomP _ _ IntAtomType = Right . IntAtom <$> APT.decimal
6262parseCSVAtomP _ _ DoubleAtomType = Right . DoubleAtom <$> APT.double
63−parseCSVAtomP _ _ TextAtomType = Right . TextAtom <$>
64− (quotedString <|>
65− takeToEndOfData)
63+parseCSVAtomP _ _ TextAtomType = do
64+ s <- quotedString <|> takeToEndOfData
65+ pure (Right (TextAtom s))
6666parseCSVAtomP _ _ DayAtomType = do
6767 dString <- T.unpack <$> takeToEndOfData
6868 case readMaybe dString of
@@ -142,14 +142,18 @@ parens p = do
142142
143143quotedString :: APT.Parser T.Text
144144quotedString = do
145+ let escapeMap = [('"','"'), ('n', '\n'), ('r', '\r')]
145146 APT.skip (== '"')
146− v <- APT.scan False (\prevEscape nextChar -> if nextChar == '"' && not prevEscape then
147− Nothing
148− else if nextChar == '\\' then
149− Just True
150− else
151− Just False
152− )
147+ (_, s) <- APT.runScanner [] (\prevl nextChar -> case prevl of
148+ [] -> Just [nextChar]
149+ chars -> if last chars == '\\' then
150+ case lookup nextChar escapeMap of
151+ Nothing -> Just (chars ++ [nextChar]) --there is no escape sequence, so leave backslash + char
152+ Just escapeVal -> Just ((init chars) ++ [escapeVal]) -- nuke the backslash and add the escapeVal
153+ else if nextChar == '"' then
154+ Nothing
155+ else
156+ Just (chars ++ [nextChar]))
153157 APT.skip (== '"')
154− pure v
158+ pure (T.pack s)
155159