packages feed

base64-bytestring 1.0.0.0 → 1.0.0.1

raw patch · 3 files changed

+92/−69 lines, 3 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

Files

Data/ByteString/Base64/Internal.hs view
@@ -74,16 +74,16 @@                   twoMore    = sp `plusPtr` 2 == sEnd                   equals     = 0x3d :: Word8                   {-# INLINE equals #-}-              a <- peekSP 0 ((`shiftR` 2) . (.&. 0xfc))-              b <- peekSP 0 ((`shiftL` 4) . (.&. 0x03))+              !a <- peekSP 0 ((`shiftR` 2) . (.&. 0xfc))+              !b <- peekSP 0 ((`shiftL` 4) . (.&. 0x03))               !b' <- if twoMore                      then peekSP 1 ((.|. b) . (`shiftR` 4) . (.&. 0xf0))                      else return b               poke8 dp =<< aidx a               poke8 (dp `plusPtr` 1) =<< aidx b'-              c <- if twoMore-                   then aidx =<< peekSP 1 ((`shiftL` 2) . (.&. 0x0f))-                   else return equals+              !c <- if twoMore+                    then aidx =<< peekSP 1 ((`shiftL` 2) . (.&. 0x0f))+                    else return equals               poke8 (dp `plusPtr` 2) c               poke8 (dp `plusPtr` 3) equals         withForeignPtr dfp $ \dptr ->@@ -155,12 +155,12 @@     | dlen <= 0 = Right B.empty     | otherwise = unsafePerformIO $ do   dfp <- mallocByteString dlen-  withForeignPtr decodeFP $ \decptr -> do+  withForeignPtr decodeFP $ \ !decptr -> do     let finish dbytes = return . Right $! if dbytes > 0                                           then PS dfp 0 dbytes                                           else B.empty         bail = return . Left-    withForeignPtr sfp $ \sptr -> do+    withForeignPtr sfp $ \ !sptr -> do       let sEnd = sptr `plusPtr` (slen + soff)           look p = do             ix <- fromIntegral `fmap` peek8 p@@ -197,9 +197,6 @@   where (di,drem) = slen `divMod` 4         dlen = di * 3 -data D = D { dNext :: {-# UNPACK #-} !(Ptr Word8)-           , dValue :: {-# UNPACK #-} !Word32 }- -- | Decode a base64-encoded string.  This function is lenient in -- following the specification from RFC 4648, -- <http://www.apps.ietf.org/rfc/rfc4648.html>, and will not generate@@ -211,45 +208,49 @@     | dlen <= 0 = B.empty     | otherwise = unsafePerformIO $ do   dfp <- mallocByteString dlen-  dbytes <- withForeignPtr decodeFP $ \decptr ->-    withForeignPtr sfp $ \sptr -> do-      let sEnd = sptr `plusPtr` (slen + soff)+  withForeignPtr decodeFP $ \ !decptr ->+    withForeignPtr sfp $ \ !sptr -> do+      let finish dbytes+              | dbytes > 0 = return (PS dfp 0 dbytes)+              | otherwise  = return B.empty+          sEnd = sptr `plusPtr` (slen + soff)           fill !dp !sp !n-            | sp >= sEnd = return n-            | otherwise = {-# SCC "decodeLenientWithTable/fill" #-} do-            let look skipPad = go+            | sp >= sEnd = finish n+            | otherwise = {-# SCC "decodeLenientWithTable/fill" #-}+            let look :: Bool -> Ptr Word8+                     -> (Ptr Word8 -> Word32 -> IO ByteString)+                     -> IO ByteString+                {-# INLINE look #-}+                look skipPad p0 f = go p0                   where-                    go p | p >= sEnd = return $! D (sEnd `plusPtr` (-1)) done-                         | otherwise =  {-# SCC "decodeLenient/look" #-} do+                    go p | p >= sEnd = f (sEnd `plusPtr` (-1)) done+                         | otherwise = {-# SCC "decodeLenient/look" #-} do                       ix <- fromIntegral `fmap` peek8 p                       v <- peek8 (decptr `plusPtr` ix)                       if v == x || (v == done && skipPad)                         then go (p `plusPtr` 1)-                        else return $! D (p `plusPtr` 1) (fromIntegral v)-            !a <- look True  sp-            !b <- look True  (dNext a)-            !c <- look False (dNext b)-            !d <- look False (dNext c)-            let w = (dValue a `shiftL` 18) .|. (dValue b `shiftL` 12) .|.-                    (dValue c `shiftL` 6) .|. dValue d-            if dValue a == done || dValue b == done-              then return n-              else do-                poke8 dp $ fromIntegral (w `shiftR` 16)-                if dValue c == done-                  then return $! n + 1-                  else do-                    poke8 (dp `plusPtr` 1) $ fromIntegral (w `shiftR` 8)-                    if dValue d == done-                      then return $! n + 2-                      else do-                        poke8 (dp `plusPtr` 2) $ fromIntegral w-                        fill (dp `plusPtr` 3) (dNext d) (n+3)+                        else f (p `plusPtr` 1) (fromIntegral v)+            in look True sp $ \ !aNext !aValue ->+               look True aNext $ \ !bNext !bValue ->+                 if aValue == done || bValue == done+                 then finish n+                 else+                    look False bNext $ \ !cNext !cValue ->+                    look False cNext $ \ !dNext !dValue -> do+                      let w = (aValue `shiftL` 18) .|. (bValue `shiftL` 12) .|.+                              (cValue `shiftL` 6) .|. dValue+                      poke8 dp $ fromIntegral (w `shiftR` 16)+                      if cValue == done+                        then finish (n + 1)+                        else do+                          poke8 (dp `plusPtr` 1) $ fromIntegral (w `shiftR` 8)+                          if dValue == done+                            then finish (n + 2)+                            else do+                              poke8 (dp `plusPtr` 2) $ fromIntegral w+                              fill (dp `plusPtr` 3) dNext (n+3)       withForeignPtr dfp $ \dptr ->         fill dptr (sptr `plusPtr` soff) 0-  return $! if dbytes > 0-            then PS dfp 0 dbytes-            else B.empty   where dlen = ((slen + 3) `div` 4) * 3  x :: Integral a => a@@ -263,23 +264,21 @@ -- This takes a list of ByteStrings, and returns a list in which each -- (apart from possibly the last) has length that is a multiple of n reChunkIn :: Int -> [ByteString] -> [ByteString]-reChunkIn _ [] = []-reChunkIn _ [y] = [y]-reChunkIn n (y : ys) = case B.length y `divMod` n of-                       (_, 0) ->-                           y : reChunkIn n ys-                       (d, _) ->-                           case B.splitAt (d * n) y of-                           (prefix, suffix) -> prefix : fixup suffix ys-    where fixup acc [] = [acc]-          fixup acc (z : zs) = case B.splitAt (n - B.length acc) z of-                               (prefix, suffix) ->-                                   let acc' = acc `B.append` prefix-                                   in if B.length acc' == n-                                      then let zs' = if B.null suffix-                                                     then          zs-                                                     else suffix : zs-                                           in acc' : reChunkIn n zs'-                                      else -- suffix must be null-                                           fixup acc' zs-+reChunkIn !n = go+  where+    go [] = []+    go (y : ys) = case B.length y `divMod` n of+                    (_, 0) -> y : go ys+                    (d, _) -> case B.splitAt (d * n) y of+                                (prefix, suffix) -> prefix : fixup suffix ys+    fixup acc [] = [acc]+    fixup acc (z : zs) = case B.splitAt (n - B.length acc) z of+                           (prefix, suffix) ->+                             let acc' = acc `B.append` prefix+                             in if B.length acc' == n+                                then let zs' = if B.null suffix+                                               then          zs+                                               else suffix : zs+                                     in acc' : go zs'+                                else -- suffix must be null+                                    fixup acc' zs
base64-bytestring.cabal view
@@ -1,7 +1,7 @@ name:                base64-bytestring-version:             1.0.0.0-synopsis:            Fast base64 encoding and deconding for ByteStrings-description:         Fast base64 encoding and deconding for ByteStrings+version:             1.0.0.1+synopsis:            Fast base64 encoding and decoding for ByteStrings+description:         Fast base64 encoding and decoding for ByteStrings homepage:            https://github.com/bos/base64-bytestring bug-reports:         https://github.com/bos/base64-bytestring/issues license:             BSD3
benchmarks/BM.hs view
@@ -1,11 +1,15 @@ {-# LANGUAGE OverloadedStrings #-} +import Control.DeepSeq (NFData(rnf)) import Criterion.Main-import qualified Data.ByteString.Char8 as B import qualified Data.ByteString.Base64 as B+import qualified Data.ByteString.Base64.Lazy as L import qualified Data.ByteString.Base64.URL as U+import qualified Data.ByteString.Char8 as B+import qualified Data.ByteString.Lazy as L+import qualified Data.ByteString.Lazy.Internal as L -sized name orig =+strict name orig =     bgroup name [       bgroup "normal" [         bench "decode" $ whnf B.decode enc@@ -20,10 +24,30 @@     ]   where enc = U.encode orig +instance NFData L.ByteString where+    rnf L.Empty        = ()+    rnf (L.Chunk _ ps) = rnf ps++lazy name orig =+    bgroup name [+      bench "decode" $ nf L.decode enc+    , bench "encode" $ nf L.encode orig+    ]+  where enc = L.encode orig+ main :: IO () main = defaultMain [-         sized "small" input-       , sized "medium" (B.concat (replicate 100 input))-       , sized "large" (B.concat (replicate 10000 input))+         bgroup "lazy" [+           lazy "small" (L.fromChunks [input])+         , lazy "medium" (L.concat . replicate 16 . L.fromChunks . (:[]) .+                          B.concat $ replicate 8 input)+         , lazy "large" (L.concat . replicate 1280 . L.fromChunks . (:[]) .+                          B.concat $ replicate 8 input)+         ]+       , bgroup "strict" [+           strict "small" input+         , strict "medium" (B.concat (replicate 128 input))+         , strict "large" (B.concat (replicate 10240 input))+         ]        ]   where input = "abcdABCD0123[];'"