@@ -26,6 +26,7 @@ module Data.Attoparsec.ByteString.Buffer
2626 , buffer
2727 , unbuffer
2828 , length
29+ , pappend
2930 , unsafeIndex
3031 , substring
3132 , unsafeDrop
@@ -72,30 +73,36 @@ instance Monoid Buffer where
7273 mempty = unsafePerformIO $ Buf nullForeignPtr 0 0 0 0 <$> newIORef 0
7374 {-# NOINLINE mempty #-}
7475
75− mappend (Buf _ _ _ 0 _ _) b = b
76− mappend a (Buf _ _ _ 0 _ _) = a
77− mappend (Buf fp0 off0 len0 cap0 gen ref) (Buf fp1 off1 len1 _ _ _) =
78− inlinePerformIO . withForeignPtr fp0 $ \ptr0 ->
79− withForeignPtr fp1 $ \ptr1 -> do
80− gen' <- atomicModifyIORef ref (\a -> let a' = a+1 in (a',a'))
81− let newlen = len0 + len1
82− if gen' == gen+1 && newlen <= cap0
83− then do
84− memcpy (ptr0 `plusPtr` (off0+len0))
85− (ptr1 `plusPtr` off1)
86− len1
87− return (Buf fp0 off0 newlen cap0 gen' ref)
88− else do
89− let newcap = newlen * 2
90− fp <- mallocPlainForeignPtrBytes newcap
91− withForeignPtr fp $ \ptr -> do
92− memcpy ptr (ptr0 `plusPtr` off0) len0
93− memcpy (ptr `plusPtr` len0) (ptr1 `plusPtr` off1) len1
94− return (Buf fp 0 newlen newcap gen' ref)
76+ mappend (Buf _ _ _ 0 _ _) b = b
77+ mappend a (Buf _ _ _ 0 _ _) = a
78+ mappend buf (Buf fp off len _ _ _) = append buf fp off len
9579
9680 mconcat [] = mempty
9781 mconcat xs = foldl1' mappend xs
9882
83+pappend :: Buffer -> ByteString -> Buffer
84+pappend buf (PS fp off len) = append buf fp off len
85+
86+append :: Buffer -> ForeignPtr a -> Int -> Int -> Buffer
87+append (Buf fp0 off0 len0 cap0 gen ref) fp1 off1 len1 =
88+ inlinePerformIO . withForeignPtr fp0 $ \ptr0 ->
89+ withForeignPtr fp1 $ \ptr1 -> do
90+ gen' <- atomicModifyIORef ref (\a -> let a' = a+1 in (a',a'))
91+ let newlen = len0 + len1
92+ if gen' == gen+1 && newlen <= cap0
93+ then do
94+ memcpy (ptr0 `plusPtr` (off0+len0))
95+ (ptr1 `plusPtr` off1)
96+ len1
97+ return (Buf fp0 off0 newlen cap0 gen' ref)
98+ else do
99+ let newcap = newlen * 2
100+ fp <- mallocPlainForeignPtrBytes newcap
101+ withForeignPtr fp $ \ptr -> do
102+ memcpy ptr (ptr0 `plusPtr` off0) len0
103+ memcpy (ptr `plusPtr` len0) (ptr1 `plusPtr` off1) len1
104+ return (Buf fp 0 newlen newcap gen' ref)
105+
99106length :: Buffer -> Int
100107length (Buf _ _ len _ _ _) = len
101108{-# INLINE length #-}