packages feed

base91 1.1.0 → 2.0.0

raw patch · 12 files changed

+89/−276 lines, 12 filesdep +mono-traversablePVP ok

version bump matches the API change (PVP)

Dependencies added: mono-traversable

API changes (from Hackage documentation)

- Codec.Binary.Base91.ByteString: decode :: [Char] -> ByteString
- Codec.Binary.Base91.ByteString: encode :: ByteString -> [Char]
- Codec.Binary.Base91.ByteString: instance Applicative' ByteString
- Codec.Binary.Base91.ByteString: instance Foldable' ByteString
- Codec.Binary.Base91.ByteString.Lazy: decode :: [Char] -> ByteString
- Codec.Binary.Base91.ByteString.Lazy: encode :: ByteString -> [Char]
- Codec.Binary.Base91.ByteString.Lazy: instance Applicative' ByteString
- Codec.Binary.Base91.ByteString.Lazy: instance Foldable' ByteString
- Codec.Binary.Base91.Control: class Monoid a => Applicative' a where type family Item a :: *
- Codec.Binary.Base91.Control: class Foldable' f where type family Element f :: *
- Codec.Binary.Base91.Control: fold' :: Foldable' f => (x -> Element f -> x) -> x -> f -> x
- Codec.Binary.Base91.Control: instance (Applicative a, Monoid (a i)) => Applicative' (a i)
- Codec.Binary.Base91.Control: instance Foldable f => Foldable' (f e)
- Codec.Binary.Base91.Control: pure' :: Applicative' a => Item a -> a
- Codec.Binary.Base91.Efficient: decode :: Text -> ByteString
- Codec.Binary.Base91.Efficient: encode :: ByteString -> Text
- Codec.Binary.Base91.Efficient.Lazy: decode :: Text -> ByteString
- Codec.Binary.Base91.Efficient.Lazy: encode :: ByteString -> Text
- Codec.Binary.Base91.String: decode :: String -> [Word8]
- Codec.Binary.Base91.String: encode :: [Word8] -> String
- Codec.Binary.Base91.Text: decode :: Text -> [Word8]
- Codec.Binary.Base91.Text: encode :: [Word8] -> Text
- Codec.Binary.Base91.Text: instance Applicative' Text
- Codec.Binary.Base91.Text: instance Foldable' Text
- Codec.Binary.Base91.Text.Lazy: decode :: Text -> [Word8]
- Codec.Binary.Base91.Text.Lazy: encode :: [Word8] -> Text
- Codec.Binary.Base91.Text.Lazy: instance Applicative' Text
- Codec.Binary.Base91.Text.Lazy: instance Foldable' Text
- Codec.Binary.Base91: decode :: (Foldable' i, Element i ~ Char, Applicative' o, Item o ~ Word8) => i -> o
+ Codec.Binary.Base91: decode :: (Input i Char, Output o Word8) => i -> o
- Codec.Binary.Base91: encode :: (Foldable' i, Element i ~ Word8, Applicative' o, Item o ~ Char) => i -> o
+ Codec.Binary.Base91: encode :: (Input i Word8, Output o Char) => i -> o

Files

Codec/Binary/Base91.hs view
@@ -1,22 +1,45 @@ -- Copyright 2015 Alvaro J. Genial (http://alva.ro) -- see LICENSE.md for more. -- Informed by Mario Rodriguez's C++ implementation. +{-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeFamilies #-}  module Codec.Binary.Base91 (alphabet, decode, encode) where -import Codec.Binary.Base91.Control (Applicative' (..), Foldable' (..)) import Data.Bits ((.&.), (.|.), shiftL, shiftR) import Data.Char (ord)-import Data.Monoid (mappend, mconcat, mempty)+import Data.Monoid (Monoid, mappend, mconcat, mempty)+import Data.MonoTraversable (Element, MonoFoldable, MonoPointed, ofoldl', opoint) import Data.Word (Word8) +type Input i e = (MonoFoldable i, Element i ~ e)+type Output o e = (MonoPointed o, Element o ~ e, Monoid o) --- | Generically encodes a 'Word8' sequence to a 'Char' sequence in Base91 form.-encode :: forall i o. (Foldable' i, Element i ~ Word8, Applicative' o, Item o ~ Char) => i -> o-encode input = g . fold' f (0, 0, mempty) $ input where+{-+encodeToString :: Input i Word8 => i -> [Char]+encodeToString = encode +decodeToBytes :: Input i Char => i -> [Word8]+decodeToBytes = decode++encodeBytes :: Output o Char => [Word8] -> o+encodeBytes = encode++decodeString :: Output o Word8 => [Char] -> o+decodeString = decode++encodeBytesToString :: [Word8] -> [Char]+encodeBytesToString = encode++decodeStringToBytes :: [Char] -> [Word8]+decodeStringToBytes = decode+-}++-- | Encodes a 'Word8' input sequence to a 'Char' output sequence in Base91 form; the opposite of 'decode'.+encode :: forall i o. (Input i Word8, Output o Char) => i -> o+encode input = g . ofoldl' f (0, 0, mempty) $ input where+   f :: (Int, Int, o) -> Word8 -> (Int, Int, o)   f (queue, nbits, output) w =     let queue' = queue .|. (fromWord8 w `shiftL` nbits)@@ -27,20 +50,20 @@           (v, q, n)   = if value > 88             then (value,  queue' `shiftR` 13, nbits' - 13)             else (value', queue' `shiftR` 14, nbits' - 14)-          x = pure' $ alphabet !! (v `mod` 91)-          y = pure' $ alphabet !! (v `div` 91)+          x = opoint $ alphabet !! (v `mod` 91)+          y = opoint $ alphabet !! (v `div` 91)       in (q, n, mconcat [output, x, y])    g :: (Int, Int, o) -> o   g (_,     0,     output) = output   g (queue, nbits, output) = mconcat [output, x, y]-    where x                           = pure' $ alphabet !! (queue `mod` 91)-          y | nbits > 7 || queue > 90 = pure' $ alphabet !! (queue `div` 91)+    where x                           = opoint $ alphabet !! (queue `mod` 91)+          y | nbits > 7 || queue > 90 = opoint $ alphabet !! (queue `div` 91)             | otherwise               = mempty --- | Generically decodes a 'Word8' sequence from a 'Char' sequence in Base91 form.-decode :: forall i o. (Foldable' i, Element i ~ Char, Applicative' o, Item o ~ Word8) => i -> o-decode input = g . fold' f (0, 0, -1, mempty) $ input where+-- | Decodes a 'Word8' output sequence from a 'Char' input sequence in Base91 form; the opposite of 'encode'.+decode :: forall i o. (Input i Char, Output o Word8) => i -> o+decode input = g . ofoldl' f (0, 0, -1, mempty) $ input where    f :: (Int, Int, Int, o) -> Char -> (Int, Int, Int, o)   f (queue, nbits, value, output) c =@@ -51,14 +74,14 @@                 q = queue .|. (v `shiftL` nbits)                 n = nbits + (if (v .&. 8191) > 88 then 13 else 14)                 (queue', nbits', x, y) = if n - 8 > 7-                  then (q `shiftR` 16, n - 16, pure' $ toWord8 q, pure' $ toWord8 $ q `shiftR` 8)-                  else (q `shiftR` 8,  n - 8,  pure' $ toWord8 q, mempty)+                  then (q `shiftR` 16, n - 16, opoint $ toWord8 q, opoint $ toWord8 $ q `shiftR` 8)+                  else (q `shiftR` 8,  n - 8,  opoint $ toWord8 q, mempty)              in (queue', nbits', -1, mconcat [output, x, y])    g :: (Int, Int, Int, o) -> o   g (_,     _,     -1,  output) = output   g (queue, nbits, value, output) = mappend output x-    where x = pure' $ toWord8 $ queue .|. (value `shiftL` nbits)+    where x = opoint $ toWord8 $ queue .|. (value `shiftL` nbits)  toWord8 :: Int -> Word8 toWord8 = fromIntegral
− Codec/Binary/Base91/ByteString.hs
@@ -1,29 +0,0 @@--- Copyright 2015 Alvaro J. Genial (http://alva.ro) -- see LICENSE.md for more.--{-# LANGUAGE TypeFamilies #-}--module Codec.Binary.Base91.ByteString (decode, encode) where--import Codec.Binary.Base91.Control (Applicative' (..), Foldable' (..))-import Data.ByteString (ByteString)-import Data.Word (Word8)-import qualified Codec.Binary.Base91 as Base91-import qualified Data.ByteString     as BS----- | Encodes a 'ByteString' to ['Char'] in Base91; the opposite of 'decode'.-encode ::ByteString -> [Char]-encode = Base91.encode---- | Decodes a 'ByteString' from ['Char'] in Base91; the opposite of 'encode'.-decode :: [Char] -> ByteString-decode = Base91.decode---instance Applicative' ByteString where-    type Item ByteString = Word8-    pure' = BS.singleton--instance Foldable' ByteString where-    type Element ByteString = Word8-    fold' = BS.foldl'
− Codec/Binary/Base91/ByteString/Lazy.hs
@@ -1,29 +0,0 @@--- Copyright 2015 Alvaro J. Genial (http://alva.ro) -- see LICENSE.md for more.--{-# LANGUAGE TypeFamilies #-}--module Codec.Binary.Base91.ByteString.Lazy (decode, encode) where--import Codec.Binary.Base91.Control (Applicative' (..), Foldable' (..))-import Data.ByteString.Lazy (ByteString)-import Data.Word (Word8)-import qualified Codec.Binary.Base91  as Base91-import qualified Data.ByteString.Lazy as BSL----- | Encodes a (lazy) 'ByteString' to ['Char'] in Base91; the opposite of 'decode'.-encode ::ByteString -> [Char]-encode = Base91.encode---- | Decodes a (lazy) 'ByteString' from ['Char'] in Base91; the opposite of 'encode'.-decode :: [Char] -> ByteString-decode = Base91.decode---instance Applicative' ByteString where-    type Item ByteString = Word8-    pure' = BSL.singleton--instance Foldable' ByteString where-    type Element ByteString = Word8-    fold' = BSL.foldl'
− Codec/Binary/Base91/Control.hs
@@ -1,29 +0,0 @@--- Copyright 2015 Alvaro J. Genial (http://alva.ro) -- see LICENSE.md for more.--{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE UndecidableInstances #-}--module Codec.Binary.Base91.Control (Applicative' (..), Foldable' (..)) where--import Control.Applicative (Applicative, pure)-import Data.Foldable (Foldable, foldl')-import Data.Monoid (Monoid)---- A version of 'Applicative' compatible with monomorphic containers.-class (Monoid a) => Applicative' a where-    type Item a :: *-    pure' :: Item a -> a--instance (Applicative a, Monoid (a i)) => Applicative' (a i) where-  type Item (a i) = i-  pure' = pure---- A version of 'Foldable' compatible with monomorphic containers.-class Foldable' f where-    type Element f :: *-    fold' :: (x -> Element f -> x) -> x -> f -> x--instance (Foldable f) => Foldable' (f e) where-  type Element (f e) = e-  fold' = foldl'
− Codec/Binary/Base91/Efficient.hs
@@ -1,18 +0,0 @@--- Copyright 2015 Alvaro J. Genial (http://alva.ro) -- see LICENSE.md for more.--module Codec.Binary.Base91.Efficient (decode, encode) where--import Codec.Binary.Base91.ByteString hiding (decode, encode)-import Codec.Binary.Base91.Text       hiding (decode, encode)-import Data.ByteString (ByteString)-import Data.Text (Text)-import qualified Codec.Binary.Base91 as Base91----- | Encodes 'ByteString' to 'Text' in Base91; the opposite of 'decode'.-encode :: ByteString -> Text-encode = Base91.encode---- | Decodes 'ByteString' from 'Text' in Base91; the opposite of 'encode'.-decode :: Text -> ByteString-decode = Base91.decode
− Codec/Binary/Base91/Efficient/Lazy.hs
@@ -1,18 +0,0 @@--- Copyright 2015 Alvaro J. Genial (http://alva.ro) -- see LICENSE.md for more.--module Codec.Binary.Base91.Efficient.Lazy (decode, encode) where--import Codec.Binary.Base91.ByteString.Lazy hiding (decode, encode)-import Codec.Binary.Base91.Text.Lazy       hiding (decode, encode)-import Data.ByteString.Lazy (ByteString)-import Data.Text.Lazy (Text)-import qualified Codec.Binary.Base91 as Base91----- | Encodes 'ByteString' to 'Text' in Base91; the opposite of 'decode'.-encode :: ByteString -> Text-encode = Base91.encode---- | Decodes 'ByteString' from 'Text' in Base91; the opposite of 'encode'.-decode :: Text -> ByteString-decode = Base91.decode
− Codec/Binary/Base91/String.hs
@@ -1,15 +0,0 @@--- Copyright 2015 Alvaro J. Genial (http://alva.ro) -- see LICENSE.md for more.--module Codec.Binary.Base91.String (decode, encode) where--import Data.Word (Word8)-import qualified Codec.Binary.Base91 as Base91----- | Encodes ['Word8'] to a 'String' in Base91; the opposite of 'decode'.-encode :: [Word8] -> String-encode = Base91.encode---- | Decodes ['Word8'] from a 'String' in Base91; the opposite of 'encode'.-decode :: String -> [Word8]-decode = Base91.decode
− Codec/Binary/Base91/Text.hs
@@ -1,29 +0,0 @@--- Copyright 2015 Alvaro J. Genial (http://alva.ro) -- see LICENSE.md for more.--{-# LANGUAGE TypeFamilies #-}--module Codec.Binary.Base91.Text (decode, encode) where--import Codec.Binary.Base91.Control (Applicative' (..), Foldable' (..))-import Data.Text (Text)-import Data.Word (Word8)-import qualified Codec.Binary.Base91 as Base91-import qualified Data.Text           as T----- | Encodes ['Word8'] to 'Text' in Base91; the opposite of 'decode'.-encode :: [Word8] -> Text-encode = Base91.encode---- | Decodes ['Word8'] from 'Text' in Base91; the opposite of 'encode'.-decode :: Text -> [Word8]-decode = Base91.decode---instance Applicative' Text where-    type Item (Text) = Char-    pure' = T.singleton--instance Foldable' Text where-    type Element (Text) = Char-    fold' = T.foldl'
− Codec/Binary/Base91/Text/Lazy.hs
@@ -1,29 +0,0 @@--- Copyright 2015 Alvaro J. Genial (http://alva.ro) -- see LICENSE.md for more.--{-# LANGUAGE TypeFamilies #-}--module Codec.Binary.Base91.Text.Lazy (decode, encode) where--import Codec.Binary.Base91.Control (Applicative' (..), Foldable' (..))-import Data.Text.Lazy (Text)-import Data.Word (Word8)-import qualified Codec.Binary.Base91 as Base91-import qualified Data.Text.Lazy      as TL----- | Encodes ['Word8'] to (lazy) 'Text' in Base91; the opposite of 'decode'.-encode :: [Word8] -> Text-encode = Base91.encode---- | Decodes ['Word8'] from (lazy) 'Text' in Base91; the opposite of 'encode'.-decode :: Text -> [Word8]-decode = Base91.decode---instance Applicative' Text where-    type Item (Text) = Char-    pure' = TL.singleton--instance Foldable' Text where-    type Element (Text) = Char-    fold' = TL.foldl'
Main.hs view
@@ -2,11 +2,12 @@  module Main (main) where -import Codec.Binary.Base91.Efficient as Base91-import Data.ByteString as BS-import Data.Text.IO as T import System.Environment (getArgs, getProgName) +import qualified Codec.Binary.Base91 as Base91+import qualified Data.ByteString     as BS+import qualified Data.Text.IO        as T+ main :: IO () main = getProgName >>= \name -> getArgs >>= \args -> case name:args of     "b91enc":[]    -> encode@@ -18,5 +19,5 @@     _              -> error "missing or invalid arguments"    where-    encode  = BS.getContents >>= T.putStrLn . Base91.encode-    decode  = T.getContents >>= BS.putStr . Base91.decode+    encode = BS.getContents >>= T.putStrLn . Base91.encode+    decode = T.getContents >>= BS.putStr . Base91.decode
Test.hs view
@@ -1,17 +1,14 @@ -- Copyright 2015 Alvaro J. Genial (http://alva.ro) -- see LICENSE.md for more. -import qualified Codec.Binary.Base91.ByteString      as BS'  (decode, encode)-import qualified Codec.Binary.Base91.ByteString.Lazy as BSL' (decode, encode)-import qualified Codec.Binary.Base91.Efficient       as E'   (decode, encode)-import qualified Codec.Binary.Base91.Efficient.Lazy  as EL'  (decode, encode)-import qualified Codec.Binary.Base91.String          as S'   (decode, encode)-import qualified Codec.Binary.Base91.Text            as T'   (decode, encode)-import qualified Codec.Binary.Base91.Text.Lazy       as TL'  (decode, encode)+{-# LANGUAGE TypeFamilies #-}++import Codec.Binary.Base91 (decode, encode)+import Data.Word (Word8)+import Test.QuickCheck (quickCheck) import qualified Data.ByteString      as BS import qualified Data.ByteString.Lazy as BSL import qualified Data.Text            as T import qualified Data.Text.Lazy       as TL-import Test.QuickCheck  main :: IO () main = do@@ -20,8 +17,8 @@     testByteStringLazy     testText     testTextLazy-    testEfficient-    testEfficientLazy+    testByteString_Text+    testByteStringLazy_TextLazy   where    -- Note that the reverse identities, e.g. encode (decode cs) == cs, aren't true because not every@@ -30,58 +27,67 @@    testString = do       quickCheck $ prop_identity-      quickCheck $ example ([], [])+      quickCheck $ example empty       quickCheck $ example helloWorld     where-      prop_identity ws = S'.decode (S'.encode ws) == ws-      example (ws, cs) = S'.encode ws == cs && S'.decode cs == ws+      prop_identity :: [Word8] -> Bool+      prop_identity ws = decode (encode ws :: [Char]) == ws+      example (ws, cs) = (encode ws :: [Char]) == cs && decode cs == ws    testByteString = do       quickCheck $ prop_identity-      quickCheck $ example ([], [])+      quickCheck $ example empty       quickCheck $ example helloWorld     where-      prop_identity ws = BS'.decode (BS'.encode bs) == bs           where bs = BS.pack ws-      example (ws, cs) = BS'.encode bs == cs && BS'.decode cs == bs where bs = BS.pack ws+      prop_identity :: [Word8] -> Bool+      prop_identity ws = decode (encode bs :: [Char]) == bs             where bs = BS.pack ws+      example (ws, cs) = (encode bs :: [Char]) == cs && decode cs == bs where bs = BS.pack ws    testByteStringLazy = do       quickCheck $ prop_identity-      quickCheck $ example ([], [])+      quickCheck $ example empty       quickCheck $ example helloWorld     where-      prop_identity ws = BSL'.decode (BSL'.encode bs) == bs           where bs = BSL.pack ws-      example (ws, cs) = BSL'.encode bs == cs && BSL'.decode cs == bs where bs = BSL.pack ws+      prop_identity :: [Word8] -> Bool+      prop_identity ws = decode (encode bs :: [Char]) == bs             where bs = BSL.pack ws+      example (ws, cs) = (encode bs :: [Char]) == cs && decode cs == bs where bs = BSL.pack ws    testText = do       quickCheck $ prop_identity-      quickCheck $ example ([], [])+      quickCheck $ example empty       quickCheck $ example helloWorld     where-      prop_identity ws = T'.decode (T'.encode ws) == ws-      example (ws, cs) = T'.encode ws == t && T'.decode t == ws where t = T.pack cs+      prop_identity :: [Word8] -> Bool+      prop_identity ws = decode (encode ws :: T.Text) == ws+      example (ws, cs) = (encode ws :: T.Text) == t && decode t == ws where t = T.pack cs    testTextLazy = do       quickCheck $ prop_identity-      quickCheck $ example ([], [])+      quickCheck $ example empty       quickCheck $ example helloWorld     where-      prop_identity ws = TL'.decode (TL'.encode ws) == ws-      example (ws, cs) = TL'.encode ws == t && TL'.decode t == ws where t = TL.pack cs+      prop_identity :: [Word8] -> Bool+      prop_identity ws = decode (encode ws :: TL.Text) == ws+      example (ws, cs) = (encode ws :: TL.Text) == t && decode t == ws where t = TL.pack cs -  testEfficient = do+  testByteString_Text = do       quickCheck $ prop_identity-      quickCheck $ example ([], [])+      quickCheck $ example empty       quickCheck $ example helloWorld     where-      prop_identity ws = E'.decode (E'.encode bs) == bs          where bs = BS.pack ws-      example (ws, cs) = E'.encode bs == t && E'.decode t  == bs where (bs, t) = (BS.pack ws, T.pack cs)+      prop_identity :: [Word8] -> Bool+      prop_identity ws = decode (encode bs :: T.Text) == bs            where bs = BS.pack ws+      example (ws, cs) = (encode bs :: T.Text) == t && decode t  == bs where (bs, t) = (BS.pack ws, T.pack cs) -  testEfficientLazy = do+  testByteStringLazy_TextLazy = do       quickCheck $ prop_identity-      quickCheck $ example ([], [])+      quickCheck $ example empty       quickCheck $ example helloWorld     where-      prop_identity ws = EL'.decode (EL'.encode bs) == bs          where bs = BSL.pack ws-      example (ws, cs) = EL'.encode bs == t && EL'.decode t  == bs where (bs, t) = (BSL.pack ws, TL.pack cs)+      prop_identity :: [Word8] -> Bool+      prop_identity ws = decode (encode bs :: TL.Text) == bs            where bs = BSL.pack ws+      example (ws, cs) = (encode bs :: TL.Text) == t && decode t  == bs where (bs, t) = (BSL.pack ws, TL.pack cs) +  empty, helloWorld :: ([Word8], [Char])+  empty      = ([], "")   helloWorld = ([72,101,108,108,111,44,32,119,111,114,108,100,33,10], ">OwJh>}A\"=r@@Y?FF") -- "Hello, World!\n"
base91.cabal view
@@ -1,51 +1,30 @@ Name:                  base91-Version:               1.1.0+Version:               2.0.0 Author:                Alvaro J. Genial Maintainer:            ajg Homepage:              https://github.com/ajg/base91 Synopsis:              A Base91 Encoder & Decoder Description:           An implementation of Base91 encoding & decoding of arbitrary bytes (octets)-                       to/from characters (all in the ASCII printable range); it includes support-                       for plain Strings, as well as optional support for ByteString and/or Text and-                       their lazy variants; see the Flags section for details.+                       to/from characters (all in the ASCII printable range) License:               MIT License-File:          LICENSE.md Category:              Codec Build-Type:            Simple Cabal-Version:         >= 1.8 -Flag ByteString-  Description:         Enable support for Data.ByteString and Data.ByteString.Lazy.-  Default:             True--Flag Text-  Description:         Enable support for Data.Text and Data.Text.Lazy.-  Default:             True- Library-  Build-Depends:       base >= 4 && < 5-  Exposed-Modules:     Codec.Binary.Base91, Codec.Binary.Base91.Control, Codec.Binary.Base91.String--  if flag(ByteString)-    Build-Depends:     bytestring-    Exposed-Modules:   Codec.Binary.Base91.ByteString, Codec.Binary.Base91.ByteString.Lazy--  if flag(Text)-    Build-Depends:     text-    Exposed-Modules:   Codec.Binary.Base91.Text, Codec.Binary.Base91.Text.Lazy--  if flag(ByteString) && flag(Text)-    Exposed-Modules:   Codec.Binary.Base91.Efficient, Codec.Binary.Base91.Efficient.Lazy+  Build-Depends:       base >= 4 && < 5, mono-traversable+  Exposed-Modules:     Codec.Binary.Base91  Executable base91   Main-is:             Main.hs-  Build-Depends:       base, base91, bytestring, text+  Build-Depends:       base, base91, bytestring, mono-traversable, text  Test-Suite tests   Hs-Source-Dirs:      .   Main-Is:             Test.hs   Type:                exitcode-stdio-1.0-  Build-Depends:       base, base91, bytestring, text, QuickCheck+  Build-Depends:       base, base91, bytestring, mono-traversable, text, QuickCheck  Source-Repository head   type:                git