module Happstack.Util.ByteStringCompat
(breakChar, breakCharEnd,
dropSpace, dropSpaceEnd,
rechunkLazy
) where
import Data.ByteString(ByteString)
import qualified Data.ByteString as B
import qualified Data.ByteString.Internal as B
import qualified Data.ByteString.Char8 as C
import qualified Data.ByteString.Lazy as L
import Data.Char(isSpace)
import Foreign
#define STRICT2(f) f a b | a `seq` b `seq` False = undefined
breakChar :: Char -> ByteString -> (ByteString, ByteString)
breakChar ch = B.break ((==) x) where x = B.c2w ch
breakCharEnd :: Char -> ByteString -> (ByteString, ByteString)
breakCharEnd c p = B.breakEnd ((==) x) p where x = B.c2w c
dropSpace :: ByteString -> ByteString
dropSpace = C.dropWhile isSpace
dropSpaceEnd :: ByteString -> ByteString
dropSpaceEnd (B.PS x s l) = B.inlinePerformIO $ withForeignPtr x $ \p -> do
i <- lastnonspace (p `plusPtr` s) (l1)
return $! if i == (1) then B.empty else B.PS x s (i+1)
lastnonspace :: Ptr Word8 -> Int -> IO Int
STRICT2(lastnonspace)
lastnonspace ptr n
| n < 0 = return n
| otherwise = do w <- peekElemOff ptr n
if B.isSpaceWord8 w then lastnonspace ptr (n1) else return n
rechunkLazy :: L.ByteString -> L.ByteString
rechunkLazy = L.fromChunks . norm . foldr w ([],[],0) . L.toChunks
where norm (acc, [], _) = acc
norm (acc, cur, _) = B.concat cur : acc
w chunk (acc,cur,len) = let bl = len + B.length chunk
in if bl > 0x100 then (B.concat (chunk : cur) : acc, [], 0) else (acc, chunk : cur, bl)