/
MyListBuf.hs
60 lines (38 loc) · 1.28 KB
/
MyListBuf.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
{-# LANGUAGE OverloadedStrings, BangPatterns #-}
module MyListBuf (
ListBuf, empty, null, length, append, appendL, appendB, appendBL, pack, toByteString
) where
import Prelude hiding (null, length)
import Data.ByteString.Char8 (ByteString)
import qualified Data.ByteString.Char8 as B
import qualified Data.List as L
data ListBuf = LB {-# UNPACK #-} !Int ![ByteString]
empty :: ListBuf
empty = LB 0 []
{-# INLINE empty #-}
null :: ListBuf -> Bool
null (LB l _) = l <= 0
{-# INLINE null #-}
length :: ListBuf -> Int
length (LB l _) = l
{-# INLINE length #-}
append :: ListBuf -> ListBuf -> ListBuf
append (LB l1 ss1) (LB l2 ss2) = LB (l1 + l2) (foldr (\s2 s1 -> (s2:s1)) ss1 ss2)
{-# INLINE append #-}
appendL :: ListBuf -> [ListBuf] -> ListBuf
appendL lb lbs = foldr go lb $ reverse lbs
where go s lb = append lb s
{-# INLINE appendL #-}
appendB :: ListBuf -> ByteString -> ListBuf
appendB (LB l ss) s = LB (l + B.length s) (s:ss)
{-# INLINE appendB #-}
appendBL :: ListBuf -> [ByteString] -> ListBuf
appendBL lb ss = foldr go lb $ reverse ss
where go s lb = appendB lb s
{-# INLINE appendBL #-}
pack :: [ByteString] -> ListBuf
pack ss = appendBL empty ss
{-# INLINE pack #-}
toByteString :: ListBuf -> ByteString
toByteString (LB l ss) = B.concat $ L.reverse ss
{-# INLINE toByteString #-}