base16-bytestring-0.1.1.6/0000755000000000000000000000000012266334030013313 5ustar0000000000000000base16-bytestring-0.1.1.6/base16-bytestring.cabal0000644000000000000000000000221412266334030017547 0ustar0000000000000000name: base16-bytestring version: 0.1.1.6 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 license: BSD3 license-file: LICENSE copyright: Copyright 2011 MailRank, Inc. author: Bryan O'Sullivan maintainer: Bryan O'Sullivan copyright: 2010 Bryan O'Sullivan category: Data build-type: Simple extra-source-files: README.markdown Cabal-version: >=1.6 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 source-repository head type: git location: http://github.com/bos/base16-bytestring source-repository head type: mercurial location: http://bitbucket.org/bos/base16-bytestring base16-bytestring-0.1.1.6/LICENSE0000644000000000000000000000266612266334030014332 0ustar0000000000000000Copyright (c) 2011 MailRank, Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the author nor the names of his contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. base16-bytestring-0.1.1.6/README.markdown0000644000000000000000000000154312266334030016017 0ustar0000000000000000# 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, . base16-bytestring-0.1.1.6/Setup.hs0000644000000000000000000000005612266334030014750 0ustar0000000000000000import Distribution.Simple main = defaultMain base16-bytestring-0.1.1.6/Data/0000755000000000000000000000000012266334030014164 5ustar0000000000000000base16-bytestring-0.1.1.6/Data/ByteString/0000755000000000000000000000000012266334030016256 5ustar0000000000000000base16-bytestring-0.1.1.6/Data/ByteString/Base16.hs0000644000000000000000000001462612266334030017644 0ustar0000000000000000{-# LANGUAGE BangPatterns, MagicHash #-} -- | -- Module : Data.ByteString.Base16 -- Copyright : (c) 2011 MailRank, Inc. -- -- License : BSD -- Maintainer : bos@serpentine.com -- Stability : experimental -- Portability : GHC -- -- Fast and efficient encoding and decoding of base16-encoded strings. module Data.ByteString.Base16 ( encode , decode ) where import Data.ByteString.Char8 (empty) import Data.ByteString.Internal (ByteString(..), createAndTrim', unsafeCreate) import Data.Bits (shiftL) import Foreign.ForeignPtr (ForeignPtr, withForeignPtr) import Foreign.Ptr (Ptr, minusPtr, plusPtr) import Foreign.Storable (peek, poke) import System.IO.Unsafe (unsafePerformIO) import GHC.Prim import GHC.Types import GHC.Word -- | Encode a string into base16 form. The result will always be a -- multiple of 2 bytes in length. -- -- Example: -- -- > encode "foo" == "666f6f" encode :: ByteString -> ByteString encode (PS sfp soff slen) | slen > maxBound `div` 2 = error "Data.ByteString.Base16.encode: input too long" | otherwise = unsafeCreate (slen*2) $ \dptr -> withForeignPtr sfp $ \sptr -> enc (sptr `plusPtr` soff) dptr where enc sptr = go sptr where e = sptr `plusPtr` slen go s d | s == e = return () | otherwise = do x <- peek8 s poke d (tlookup tableHi x) poke (d `plusPtr` 1) (tlookup tableLo x) go (s `plusPtr` 1) (d `plusPtr` 2) tlookup :: Addr# -> Int -> Word8 tlookup table (I# index) = W8# (indexWord8OffAddr# table index) !tableLo = "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x61\x62\x63\x64\x65\x66\ \\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x61\x62\x63\x64\x65\x66\ \\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x61\x62\x63\x64\x65\x66\ \\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x61\x62\x63\x64\x65\x66\ \\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x61\x62\x63\x64\x65\x66\ \\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x61\x62\x63\x64\x65\x66\ \\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x61\x62\x63\x64\x65\x66\ \\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x61\x62\x63\x64\x65\x66\ \\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x61\x62\x63\x64\x65\x66\ \\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x61\x62\x63\x64\x65\x66\ \\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x61\x62\x63\x64\x65\x66\ \\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x61\x62\x63\x64\x65\x66\ \\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x61\x62\x63\x64\x65\x66\ \\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x61\x62\x63\x64\x65\x66\ \\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x61\x62\x63\x64\x65\x66\ \\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x61\x62\x63\x64\x65\x66"# !tableHi = "\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\ \\x31\x31\x31\x31\x31\x31\x31\x31\x31\x31\x31\x31\x31\x31\x31\x31\ \\x32\x32\x32\x32\x32\x32\x32\x32\x32\x32\x32\x32\x32\x32\x32\x32\ \\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33\ \\x34\x34\x34\x34\x34\x34\x34\x34\x34\x34\x34\x34\x34\x34\x34\x34\ \\x35\x35\x35\x35\x35\x35\x35\x35\x35\x35\x35\x35\x35\x35\x35\x35\ \\x36\x36\x36\x36\x36\x36\x36\x36\x36\x36\x36\x36\x36\x36\x36\x36\ \\x37\x37\x37\x37\x37\x37\x37\x37\x37\x37\x37\x37\x37\x37\x37\x37\ \\x38\x38\x38\x38\x38\x38\x38\x38\x38\x38\x38\x38\x38\x38\x38\x38\ \\x39\x39\x39\x39\x39\x39\x39\x39\x39\x39\x39\x39\x39\x39\x39\x39\ \\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\x61\ \\x62\x62\x62\x62\x62\x62\x62\x62\x62\x62\x62\x62\x62\x62\x62\x62\ \\x63\x63\x63\x63\x63\x63\x63\x63\x63\x63\x63\x63\x63\x63\x63\x63\ \\x64\x64\x64\x64\x64\x64\x64\x64\x64\x64\x64\x64\x64\x64\x64\x64\ \\x65\x65\x65\x65\x65\x65\x65\x65\x65\x65\x65\x65\x65\x65\x65\x65\ \\x66\x66\x66\x66\x66\x66\x66\x66\x66\x66\x66\x66\x66\x66\x66\x66"# -- | Decode a string from base16 form. The first element of the -- returned tuple contains the decoded data. The second element starts -- at the first invalid base16 sequence in the original string. -- -- Examples: -- -- > decode "666f6f" == ("foo", "") -- > decode "66quux" == ("f", "quux") -- > decode "666quux" == ("f", "6quux") decode :: ByteString -> (ByteString, ByteString) decode (PS sfp soff slen) = unsafePerformIO . createAndTrim' (slen `div` 2) $ \dptr -> withForeignPtr sfp $ \sptr -> dec (sptr `plusPtr` soff) dptr where dec sptr = go sptr where e = sptr `plusPtr` if odd slen then slen - 1 else slen go s d | s == e = let len = e `minusPtr` sptr in return (0, len `div` 2, ps sfp (soff+len) (slen-len)) | otherwise = do hi <- hex `fmap` peek8 s lo <- hex `fmap` peek8 (s `plusPtr` 1) if lo == 0xff || hi == 0xff then let len = s `minusPtr` sptr in return (0, len `div` 2, ps sfp (soff+len) (slen-len)) else do poke d . fromIntegral $ lo + (hi `shiftL` 4) go (s `plusPtr` 2) (d `plusPtr` 1) hex (I# index) = W8# (indexWord8OffAddr# table index) !table = "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\ \\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\ \\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\ \\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\xff\xff\xff\xff\xff\xff\ \\xff\x0a\x0b\x0c\x0d\x0e\x0f\xff\xff\xff\xff\xff\xff\xff\xff\xff\ \\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\ \\xff\x0a\x0b\x0c\x0d\x0e\x0f\xff\xff\xff\xff\xff\xff\xff\xff\xff\ \\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\ \\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\ \\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\ \\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\ \\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\ \\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\ \\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\ \\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\ \\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"# peek8 :: Ptr Word8 -> IO Int peek8 p = fromIntegral `fmap` peek p ps :: ForeignPtr Word8 -> Int -> Int -> ByteString ps fp off len | len <= 0 = empty | otherwise = PS fp off len base16-bytestring-0.1.1.6/Data/ByteString/Base16/0000755000000000000000000000000012266334030017277 5ustar0000000000000000base16-bytestring-0.1.1.6/Data/ByteString/Base16/Lazy.hs0000644000000000000000000000402612266334030020554 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} -- | -- Module : Data.ByteString.Base16.Lazy -- Copyright : (c) 2011 MailRank, Inc. -- -- License : BSD -- Maintainer : bos@serpentine.com -- Stability : experimental -- Portability : GHC -- -- Fast and efficient encoding and decoding of base16-encoded strings. module Data.ByteString.Base16.Lazy ( encode , decode ) where import Data.Word (Word8) import qualified Data.ByteString.Base16 as B16 import qualified Data.ByteString as B import qualified Data.ByteString.Unsafe as B import Data.ByteString.Lazy.Internal -- | Encode a string into base16 form. The result will always be a -- multiple of 2 bytes in length. -- -- Example: -- -- > encode "foo" == "666f6f" encode :: ByteString -> ByteString encode (Chunk c cs) = Chunk (B16.encode c) (encode cs) encode Empty = Empty -- | Decode a string from base16 form. The first element of the -- returned tuple contains the decoded data. The second element starts -- 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: -- -- > decode "666f6f" == ("foo", "") -- > 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) | 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) where (h,t) = B16.decode c len = B.length t isHex :: Word8 -> Bool isHex w = (w >= 48 && w <= 57) || (w >= 97 && w <= 102) || (w >= 65 && w <= 70)