diff --git a/siphon/src/Siphon.hs b/siphon/src/Siphon.hs index 87af710..1c38e66 100644 --- a/siphon/src/Siphon.hs +++ b/siphon/src/Siphon.hs @@ -388,7 +388,11 @@ escapedField = do trailChar <- case mb of Just b | b == comma -> A.anyWord8 >> return TrailCharComma - | b == newline || b == cr -> A.anyWord8 >> return TrailCharNewline + | b == newline -> A.anyWord8 >> return TrailCharNewline + | b == cr -> do + _ <- A.anyWord8 + _ <- A.word8 newline + return TrailCharNewline | otherwise -> fail "encountered double quote after escaped field" Nothing -> return TrailCharEnd if doubleQuote `S.elem` s @@ -412,7 +416,11 @@ unescapedField !delim = do case mb of Just b | b == comma -> A.anyWord8 >> return (bs,TrailCharComma) - | b == newline || b == cr -> A.anyWord8 >> return (bs,TrailCharNewline) + | b == newline -> A.anyWord8 >> return (bs,TrailCharNewline) + | b == cr -> do + _ <- A.anyWord8 + _ <- A.word8 newline + return (bs,TrailCharNewline) | otherwise -> fail "encountered double quote in unescaped field" Nothing -> return (bs,TrailCharEnd) diff --git a/siphon/test/Test.hs b/siphon/test/Test.hs index 00ec697..06f7af2 100644 --- a/siphon/test/Test.hs +++ b/siphon/test/Test.hs @@ -108,6 +108,16 @@ tests = ] ) ) @?= (["drew","martin, drew"] :> Nothing) + , testCase "Headed Decoding (escaped characters, character per chunk, CRLF)" + $ ( runIdentity . SMP.toList ) + ( S.decodeCsvUtf8 decodingF + ( mapM_ (SMP.yield . BC8.singleton) $ concat + [ "name\r\n" + , "drew\r\n" + , "\"martin, drew\"\r\n" + ] + ) + ) @?= (["drew","martin, drew"] :> Nothing) , testProperty "Headed Isomorphism (int,char,bool)" $ propIsoStream BC8.unpack (S.decodeCsvUtf8 decodingB)