-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathEOL.hs
71 lines (59 loc) · 2.68 KB
/
EOL.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
--------------------------------------------------------------------
-- |
-- Module : EOL
-- Copyright : (c) Nicolas Pouillard 2008, 2009, 2010, 2011
-- License : BSD3
--
-- Maintainer: Nicolas Pouillard <[email protected]>
-- Stability : provisional
-- Portability:
--
--------------------------------------------------------------------
{-# LANGUAGE PatternGuards, BangPatterns #-}
module EOL where
import qualified Data.ByteString.Lazy.Char8 as C
-- Make sure all lines are terminated by CRLF.
fixCrlfS :: String -> String
fixCrlfS ('\r':'\n':xs) = '\r' : '\n' : fixCrlfS xs
fixCrlfS ('\n':xs) = '\r' : '\n' : fixCrlfS xs
fixCrlfS (x:xs) = x : fixCrlfS xs
fixCrlfS [] = []
fixLfS :: String -> String
fixLfS ('\r':'\n':xs) = '\n' : fixLfS xs
fixLfS (x:xs) = x : fixLfS xs
fixLfS [] = []
fixCrlfB :: C.ByteString -> C.ByteString
fixCrlfB = C.unlines . map (`C.snoc` '\r') . C.lines
{-
fixCrlfB = go
where go !input = maybe C.empty f $ C.elemIndex '\n' input
where f !0 = crlf `C.append` go (C.tail input)
f !off | C.index input (off - 1) == '\r' =
let (a,b) = C.splitAt (off+1) input in a `C.append` go b
| otherwise =
let (a,b) = C.splitAt off input in a `C.append` (crlf `C.append` go (C.tail b))
By speed order:
fixCrlfB = go
where go input = maybe C.empty f $ C.elemIndex '\n' input
where f 0 = crlf `C.append` go (C.tail input)
f off | C.index input (off - 1) == '\r' =
uncurry C.append $ second go $ C.splitAt (off + 1) input
| otherwise =
uncurry C.append $ second (C.append crlf . go . C.tail) $ C.splitAt off input
fixCrlfB = go
where go input = maybe C.empty f $ C.elemIndex '\n' input
where f 0 = '\r' `C.cons` ('\n' `C.cons` go (C.tail input))
f off | C.index input (off - 1) == '\r' =
uncurry C.append $ second go $ C.splitAt (off + 1) input
| otherwise =
let (a, b) = C.splitAt off input in a `C.append` ('\r' `C.cons` ('\n' `C.cons` go (C.tail b)))
fixCrlfB = go
where go s1 =
case C.uncons s1 of
Just ('\r', s2) | Just ('\n', rest) <- C.uncons s2 -> '\r' `C.cons` ('\n' `C.cons` go rest)
Just ('\n', rest) -> '\r' `C.cons` ('\n' `C.cons` go rest)
Just (c, rest) -> c `C.cons` go rest
Nothing -> C.empty
-}
crlf :: C.ByteString
crlf = C.pack "\r\n"