base64-bytestring 0.1.1.0 → 0.1.1.1
raw patch · 5 files changed
+58/−25 lines, 5 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
Files
- Data/ByteString/Base64.hs +6/−6
- Data/ByteString/Base64/Internal.hs +20/−17
- Data/ByteString/Base64/URL.hs +1/−1
- base64-bytestring.cabal +2/−1
- benchmarks/BM.hs +29/−0
Data/ByteString/Base64.hs view
@@ -28,29 +28,29 @@ -- | Encode a string into base64 form. The result will always be a -- multiple of 4 bytes in length. encode :: ByteString -> ByteString-encode = encodeWithAlphabet alphabet+encode s = encodeWith (mkEncodeTable alphabet) s -- | Decode a base64-encoded string. This function strictly follows -- the specification in RFC 4648, -- <http://www.apps.ietf.org/rfc/rfc4648.html>. decode :: ByteString -> Either String ByteString-decode = decodeWithTable decodeFP+decode s = decodeWithTable decodeFP s -- | 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 -- parse errors no matter how poor its input. decodeLenient :: ByteString -> ByteString-decodeLenient = decodeLenientWithTable decodeFP-+decodeLenient s = decodeLenientWithTable decodeFP s alphabet :: ByteString alphabet = B.pack $ [65..90] ++ [97..122] ++ [48..57] ++ [43,47] {-# NOINLINE alphabet #-} decodeFP :: ForeignPtr Word8-PS decodeFP _ _ = B.pack $ replicate 43 x ++ [62,x,x,x,63] ++ [52..61] ++ [x,x,- x,done,x,x,x] ++ [0..25] ++ [x,x,x,x,x,x] ++ [26..51] ++ replicate 133 x+PS decodeFP _ _ = B.pack $+ replicate 43 x ++ [62,x,x,x,63] ++ [52..61] ++ [x,x,x,done,x,x,x] +++ [0..25] ++ [x,x,x,x,x,x] ++ [26..51] ++ replicate 133 x {-# NOINLINE decodeFP #-} x :: Integral a => a
Data/ByteString/Base64/Internal.hs view
@@ -13,9 +13,10 @@ module Data.ByteString.Base64.Internal (- encodeWithAlphabet+ encodeWith , decodeWithTable , decodeLenientWithTable+ , mkEncodeTable , joinWith , done , peek8, poke8, peek8_32@@ -40,11 +41,10 @@ peek8_32 :: Ptr Word8 -> IO Word32 peek8_32 = fmap fromIntegral . peek8 --- | Encode a string into base64 form. The result will always be a--- multiple of 4 bytes in length. This function takes the encoding--- alphabet (for @base64@ or @base64url@) as the first paramert.-encodeWithAlphabet :: ByteString -> ByteString -> ByteString-encodeWithAlphabet alphabet@(PS alfaFP _ _) (PS sfp soff slen)+-- | Encode a string into base64 form. The result will always be a multiple+-- of 4 bytes in length.+encodeWith :: EncodeTable -> ByteString -> ByteString+encodeWith (ET alfaFP encodeTable) (PS sfp soff slen) | slen > maxBound `div` 4 = error "Data.ByteString.Base64.encode: input too long" | otherwise = unsafePerformIO $ do@@ -88,17 +88,20 @@ withForeignPtr dfp $ \dptr -> fill (castPtr dptr) (sptr `plusPtr` soff) return $! PS dfp 0 dlen- where -- The encoding table is constructed such that the expansion of a 12bit block- -- to a 16bit block can be done by a single Word16 copy from the correspoding- -- table entry to the target address. The 16bit blocks are stored in big-endian- -- order, as the indices into the table are built in big-endian order.- encodeTable :: ForeignPtr Word16- encodeTable = - case table of PS fp _ _ -> castForeignPtr fp- where- ix = fromIntegral . B.index alphabet- table = B.pack $ concat $ [ [ix j, ix k] | j <- [0..63], k <- [0..63] ]- {-# NOINLINE encodeTable #-}++data EncodeTable = ET (ForeignPtr Word8) (ForeignPtr Word16)++-- The encoding table is constructed such that the expansion of a 12-bit+-- block to a 16-bit block can be done by a single Word16 copy from the+-- correspoding table entry to the target address. The 16-bit blocks are+-- stored in big-endian order, as the indices into the table are built in+-- big-endian order.+mkEncodeTable :: ByteString -> EncodeTable+mkEncodeTable alphabet@(PS afp _ _) =+ case table of PS fp _ _ -> ET afp (castForeignPtr fp)+ where+ ix = fromIntegral . B.index alphabet+ table = B.pack $ concat $ [ [ix j, ix k] | j <- [0..63], k <- [0..63] ] -- | Efficiently intersperse a terminator string into another at -- regular intervals, and terminate the input with it.
Data/ByteString/Base64/URL.hs view
@@ -28,7 +28,7 @@ -- | Encode a string into base64url form. The result will always be a -- multiple of 4 bytes in length. encode :: ByteString -> ByteString-encode = encodeWithAlphabet alphabet+encode = encodeWith (mkEncodeTable alphabet) -- | Decode a base64url-encoded string. This function strictly follows -- the specification in RFC 4648,
base64-bytestring.cabal view
@@ -1,5 +1,5 @@ name: base64-bytestring-version: 0.1.1.0+version: 0.1.1.1 synopsis: Fast base64 encoding and deconding for ByteStrings description: Fast base64 encoding and deconding for ByteStrings homepage: https://github.com/bos/base64-bytestring@@ -15,6 +15,7 @@ extra-source-files: README.markdown+ benchmarks/BM.hs tests/Transcode.hs tests/transcode.py
+ benchmarks/BM.hs view
@@ -0,0 +1,29 @@+{-# LANGUAGE OverloadedStrings #-}++import Criterion.Main+import qualified Data.ByteString.Char8 as B+import qualified Data.ByteString.Base64 as B+import qualified Data.ByteString.Base64 as U++sized name orig =+ bgroup name [+ bgroup "normal" [+ bench "decode" $ whnf B.decode enc+ , bench "decodeLenient" $ whnf B.decodeLenient enc+ , bench "encode" $ whnf B.encode orig+ ]+ , bgroup "url" [+ bench "decode" $ whnf U.decode enc+ , bench "decodeLenient" $ whnf U.decodeLenient enc+ , bench "encode" $ whnf U.encode orig+ ]+ ]+ where enc = U.encode orig++main :: IO ()+main = defaultMain [+ sized "small" input+ , sized "medium" (B.concat (replicate 100 input))+ , sized "large" (B.concat (replicate 10000 input))+ ]+ where input = "abcdABCD0123[];'"