base16-bytestring 0.1.1.6 → 0.1.1.7
raw patch · 6 files changed
+156/−64 lines, 6 filesdep +base16-bytestringdep ~basedep ~bytestringnew-uploader
Dependencies added: base16-bytestring
Dependency ranges changed: base, bytestring
Files
- CHANGELOG.md +8/−0
- Data/ByteString/Base16/Lazy.hs +15/−11
- README.markdown +0/−37
- README.md +34/−0
- base16-bytestring.cabal +31/−16
- tests/Tests.hs +68/−0
+ CHANGELOG.md view
@@ -0,0 +1,8 @@+# 0.1.1.7++* Fix some bugs in lazy decoding+ ([#8](https://github.com/haskell/base16-bytestring/pull/8)).++# 0.1.1.6++* Changelog not recorded up to this version.
Data/ByteString/Base16/Lazy.hs view
@@ -21,6 +21,7 @@ import qualified Data.ByteString.Base16 as B16 import qualified Data.ByteString as B import qualified Data.ByteString.Unsafe as B+import qualified Data.ByteString.Lazy as BL import Data.ByteString.Lazy.Internal -- | Encode a string into base16 form. The result will always be a@@ -38,8 +39,6 @@ -- at the first invalid base16 sequence in the original string. -- -- This function operates as lazily as possible over the input chunks.--- The only instance in which it is non-lazy is if an odd-length chunk--- ends with a byte that is valid base16. -- -- Examples: --@@ -47,16 +46,21 @@ -- > decode "66quux" == ("f", "quux") -- > decode "666quux" == ("f", "6quux") decode :: ByteString -> (ByteString, ByteString)-decode = foldrChunks go (Empty, Empty)- where go c ~(y,z)- | len == 0 = (chunk h y, z)+decode = go Nothing+ where+ go :: Maybe Word8 -> ByteString -> (ByteString, ByteString)+ go Nothing Empty = (Empty, Empty)+ go (Just w) Empty = (Empty, BL.singleton w)+ go (Just w) (Chunk c z) =+ go Nothing (chunk (B.pack [w, B.unsafeHead c]) (chunk (B.unsafeTail c) z))+ go Nothing (Chunk c z)+ | len == 0 =+ let ~(res,tail') = go Nothing z+ in (chunk h res, tail') | len == 1 && isHex (B.unsafeHead t) =- case z of- Chunk a as | isHex (B.unsafeHead a)- -> let (q,_) = B16.decode (t `B.snoc` B.unsafeHead a)- in (chunk h (chunk q y), chunk (B.unsafeTail a) as)- _ -> (chunk h y, chunk t z)- | otherwise = (chunk h y, chunk t z)+ let ~(res,tail') = go (Just (B.unsafeHead t)) z+ in (chunk h res, tail')+ | otherwise = (chunk h Empty, chunk t z) where (h,t) = B16.decode c len = B.length t
− README.markdown
@@ -1,37 +0,0 @@-# Fast base16 support--This package provides a Haskell library for working with base16-encoded-data quickly and efficiently, using the ByteString type.---# Performance--This library is written in pure Haskell, and it's fast:--* 250 MB/sec encoding--* 200 MB/sec strict decoding (per RFC 4648)--* 100 MB/sec lenient decoding---# Get involved!--Please report bugs via the-[github issue tracker](http://github.com/bos/base16-bytestring).--Master [github repository](http://github.com/bos/base16-bytestring):--* `git clone git://github.com/bos/base16-bytestring.git`--There's also a [Mercurial mirror](http://bitbucket.org/bos/base16-bytestring):--* `hg clone http://bitbucket.org/bos/base16-bytestring`--(You can create and contribute changes using either git or Mercurial.)---# Authors--This library is written and maintained by Bryan O'Sullivan,-<bos@serpentine.com>.
+ README.md view
@@ -0,0 +1,34 @@+# Fast base16 support [](https://hackage.haskell.org/package/base16-bytestring) [](https://www.stackage.org/package/base16-bytestring) [](http://travis-ci.org/haskell/base16-bytestring)++**Please refer to the [package description on Hackage](https://hackage.haskell.org/package/base16-bytestring#description) for more information.**++This package provides a Haskell library for working with base16-encoded+data quickly and efficiently, using the `ByteString` type.+++# Performance++This library is written in pure Haskell, and it's fast:++* 250 MB/sec encoding++* 200 MB/sec strict decoding (per RFC 4648)++* 100 MB/sec lenient decoding+++# Get involved!++Please report bugs via the+[GitHub issue tracker](http://github.com/haskell/base16-bytestring).++Master [Git repository](http://github.com/haskell/base16-bytestring):++* `git clone git://github.com/haskell/base16-bytestring.git`+++# Authors++This library is written by [Bryan O'Sullivan](mailto:bos@serpentine.com). It+is maintained by [Emily Pillmore](mailto:emilypi@cohomolo.gy), [Herbert Valerio Riedel](mailto:hvr@gnu.org) and [Mikhail+Glushenkov](mailto:mikhail.glushenkov@gmail.com).
base16-bytestring.cabal view
@@ -1,38 +1,53 @@+cabal-version: 1.12 name: base16-bytestring-version: 0.1.1.6+version: 0.1.1.7 synopsis: Fast base16 (hex) encoding and decoding for ByteStrings-description: Fast base16 (hex) encoding and decoding for ByteStrings-homepage: http://github.com/bos/base16-bytestring-bug-reports: http://github.com/bos/base16-bytestring/issues+description: This package provides support for encoding and decoding binary data according+ to @base16@ (see also <https://tools.ietf.org/html/rfc4648 RFC 4648>) for+ strict (see "Data.ByteString.Base16") and lazy @ByteString@s (see "Data.ByteString.Base16.Lazy").+ .+ See also the <https://hackage.haskell.org/package/base-encoding base-encoding> package which+ provides an uniform API providing conversion paths between more binary and textual types.+homepage: http://github.com/haskell/base16-bytestring+bug-reports: http://github.com/haskell/base16-bytestring/issues license: BSD3 license-file: LICENSE-copyright: Copyright 2011 MailRank, Inc.+copyright: Copyright 2011 MailRank, Inc.;+ Copyright 2010-2020 Bryan O'Sullivan et al. author: Bryan O'Sullivan <bos@serpentine.com>-maintainer: Bryan O'Sullivan <bos@serpentine.com>-copyright: 2010 Bryan O'Sullivan+maintainer: Herbert Valerio Riedel <hvr@gnu.org>,+ Mikhail Glushenkov <mikhail.glushenkov@gmail.com>,+ Emily Pillmore <emilypi@cohomolo.gy> category: Data build-type: Simple-extra-source-files: README.markdown--Cabal-version: >=1.6+extra-source-files: README.md CHANGELOG.md+tested-with: GHC==8.10.1, GHC==8.8.3, GHC==8.6.5,+ GHC==8.4.4, GHC==8.2.2, GHC==8.0.2,+ GHC==7.10.3, GHC==7.8.4, GHC==7.6.3,+ GHC==7.4.2, GHC==7.2.2, GHC==7.0.4 library exposed-modules: Data.ByteString.Base16 Data.ByteString.Base16.Lazy- + build-depends: base == 4.*, bytestring >= 0.9, ghc-prim ghc-options: -Wall -funbox-strict-fields- ghc-prof-options: -auto-all+ default-language: Haskell2010 source-repository head type: git- location: http://github.com/bos/base16-bytestring+ location: http://github.com/haskell/base16-bytestring -source-repository head- type: mercurial- location: http://bitbucket.org/bos/base16-bytestring+test-suite test+ type: exitcode-stdio-1.0+ hs-source-dirs: tests+ main-is: Tests.hs+ default-language: Haskell2010+ build-depends: base+ , base16-bytestring+ , bytestring
+ tests/Tests.hs view
@@ -0,0 +1,68 @@+import Data.Char (ord)+import Data.Word (Word8)+import qualified Data.ByteString as B+import qualified Data.ByteString.Lazy as BL+import qualified Data.ByteString.Base16 as Base16+import qualified Data.ByteString.Base16.Lazy as Base16L++-- Three-line "test framework" for Haskell. Crude, but at least it tells you+-- the line number of the failure without you having to specify it.+shouldBe :: (Eq a, Show a) => a -> a -> IO Bool+shouldBe a b = return (a == b)+infix 0 `shouldBe`++c2w :: Char -> Word8+c2w = fromIntegral . ord++main :: IO ()+main = do+ let hexL = map c2w "0123456789abcdef"+ hexU = map c2w "0123456789ABCDEF"+ hexUL = map c2w "0123456789ABCDEFabcdef"+ notHex = [c | c <- [0..255], c `notElem` hexUL]+ hexL2 = do a <- hexL; b <- hexL; [a,b]+ hexU2 = do a <- hexU; b <- hexU; [a,b]+ bytes = B.pack [0..255]++ -- Encode every byte+ True <- Base16.encode bytes `shouldBe` B.pack hexL2++ -- Decode every valid hex pair+ True <- Base16.decode (B.pack hexL2) `shouldBe` (bytes, B.empty)+ True <- Base16.decode (B.pack hexU2) `shouldBe` (bytes, B.empty)++ -- Decode every invalid byte paired with a correct byte+ let bads1 = [B.pack [a,b] | a <- notHex, b <- hexUL]+ let bads2 = [B.pack [a,b] | a <- hexUL, b <- notHex]+ True <- map Base16.decode bads1 `shouldBe` map (\s -> (B.empty, s)) bads1+ True <- map Base16.decode bads2 `shouldBe` map (\s -> (B.empty, s)) bads2++ -- Like above, but start with a correct byte+ let correctHex = B.pack [97,98]+ correctBytes = B.pack [171]+ True <- map (Base16.decode . (correctHex `B.append`)) bads1+ `shouldBe` map (\s -> (correctBytes, s)) bads1+ True <- map (Base16.decode . (correctHex `B.append`)) bads2+ `shouldBe` map (\s -> (correctBytes, s)) bads2++ -- Like above, but end with a correct byte+ True <- map (Base16.decode . (`B.append` correctHex)) bads1+ `shouldBe` map (\s -> (B.empty, s `B.append` correctHex)) bads1+ True <- map (Base16.decode . (`B.append` correctHex)) bads2+ `shouldBe` map (\s -> (B.empty, s `B.append` correctHex)) bads2++ -- Lazy decoding also works with odd length chunks+ let encodedLazy = BL.fromChunks $ map (B.pack . map c2w) ["614","239","6","142","39"]+ True <- Base16L.decode encodedLazy `shouldBe` (BL.pack . map c2w $ "aB9aB9",BL.empty)++ -- Lazy decoding is lazy on success+ let encodedLazy = BL.iterate id 48+ True <- (BL.unpack . BL.take 8 . fst . Base16L.decode $ encodedLazy)+ `shouldBe` [0,0,0,0,0,0,0,0]++ -- Lazy decoding is lazy on failure+ let encodedLazy = BL.iterate id 47+ True <- (BL.unpack . BL.take 8 . fst . Base16L.decode $ encodedLazy)+ `shouldBe` []++ return ()