packages feed

base91 0.1.0 → 0.1.1

raw patch · 6 files changed

+87/−204 lines, 6 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Codec.Binary.Base91: alphabet :: [Char]
+ Codec.Binary.Base91: decodeBy :: LeftFold (Int, Int, Int, o) Char s -> (o -> [Word8] -> o) -> o -> s -> o
+ Codec.Binary.Base91: encodeBy :: LeftFold (Int, Int, o) Word8 s -> (o -> [Char] -> o) -> o -> s -> o

Files

Codec/Binary/Base91.hs view
@@ -1,12 +1,63 @@ -- Copyright 2015 Alvaro J. Genial (http://alva.ro) -- see LICENSE.md for more. -- Informed by Mario Rodriguez's C++ implementation. -module Codec.Binary.Base91 (decoding, encoding) where+module Codec.Binary.Base91 (alphabet, decodeBy, encodeBy) where +import Data.Bits ((.&.), (.|.), shiftL, shiftR)+import Data.Char (ord) import Data.Word (Word8) -encoding :: [Char]-encoding = [++type LeftFold a b c = (a -> b -> a) -> a -> c -> a+++encodeBy :: LeftFold (Int, Int, o) Word8 s -> (o -> [Char] -> o) -> o -> s -> o+encodeBy fold append empty source = g . fold f (0, 0, empty) $ source where++--f :: (Int, Int, o) -> Word8 -> (Int, Int, o)+  f (queue, nbits, output) w =+    let queue' = queue .|. (fromIntegral w `shiftL` nbits)+        nbits' = nbits + 8+    in if nbits' <= 13 then (queue', nbits', output) else+      let val  = queue' .&. 8191+          val' = queue' .&. 16383+          (v, q, n)   = if val > 88+            then (val,  queue' `shiftR` 13, nbits' - 13)+            else (val', queue' `shiftR` 14, nbits' - 14)+          trail       = [alphabet !! (v `mod` 91),+                         alphabet !! (v `div` 91)]+      in (q, n, append output trail)++--g :: (Int, Int, o) -> o+  g (_,     0,     output) = output+  g (queue, nbits, output) = append output (y:z)+    where y = alphabet !! (queue `mod` 91)+          z | nbits > 7 || queue > 90 = [alphabet !! (queue `div` 91)]+            | otherwise               = []++decodeBy :: LeftFold (Int, Int, Int, o) Char s -> (o -> [Word8] -> o) -> o -> s -> o+decodeBy fold append empty source = g . fold f (0, 0, -1, empty) $ source where++--f :: (Int, Int, Int, o) -> Char -> (Int, Int, Int, o)+  f (queue, nbits, val, output) c =+    let d = fromIntegral $ octets !! ord c+     in if d   == 91 then (queue, nbits, val, output) else+        if val == -1 then (queue, nbits, d,   output) else+            let v = val + (d * 91)+                q = queue .|. (v `shiftL` nbits)+                n = nbits + (if (v .&. 8191) > 88 then 13 else 14)+                (queue', nbits', trail) = if n - 8 > 7+                  then (q `shiftR` 16, n - 16, [q, q `shiftR` 8])+                  else (q `shiftR` 8,  n - 8,  [q])+             in (queue', nbits', -1, append output $ map fromIntegral trail)++--g :: (Int, Int, Int, o) -> o+  g (_,     _,     -1,  output) = output+  g (queue, nbits, val, output) = append output [fromIntegral $ queue .|. (val `shiftL` nbits)]++-- | The list of valid characters within a Base91-encoded string.+alphabet :: [Char]+alphabet = [   'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',   'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',   'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',@@ -15,8 +66,8 @@   '%', '&', '(', ')', '*', '+', ',', '.', '/', ':', ';', '<', '=',   '>', '?', '@', '[', ']', '^', '_', '`', '{', '|', '}', '~', '"'] -decoding :: [Word8]-decoding = [+octets :: [Word8]+octets = [   91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,   91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,   91, 62, 90, 63, 64, 65, 66, 91, 67, 68, 69, 70, 71, 91, 72, 73,
Codec/Binary/Base91/ByteString.hs view
@@ -1,58 +1,15 @@ -- Copyright 2015 Alvaro J. Genial (http://alva.ro) -- see LICENSE.md for more.--- Informed by Mario Rodriguez's C++ implementation.  module Codec.Binary.Base91.ByteString (decode, encode) where -import qualified Codec.Binary.Base91 as B91-import Data.Bits ((.&.), (.|.), shiftL, shiftR)-import Data.Char (ord)-import Data.List (foldl')-import Data.Word (Word8)-import Data.ByteString (ByteString)+import Codec.Binary.Base91 (decodeBy, encodeBy) import qualified Data.ByteString as BS+import qualified Data.List as L  -- | Encodes octets ('ByteString') to a '[Char]' in Base91; the opposite of 'decode'.-encode :: ByteString -> [Char]-encode = g . BS.foldl' f (0, 0, []) where--  f :: (Int, Int, [Char]) -> Word8 -> (Int, Int, [Char])-  f (queue, nbits, cs) w =-    let queue' = queue .|. (fromIntegral w `shiftL` nbits)-        nbits' = nbits + 8-    in if nbits' <= 13 then (queue', nbits', cs) else-      let val  = queue' .&. 8191-          val' = queue' .&. 16383-          (v, q, n)   = if val > 88-            then (val,  queue' `shiftR` 13, nbits' - 13)-            else (val', queue' `shiftR` 14, nbits' - 14)-          trail       = [B91.encoding !! (v `mod` 91),-                         B91.encoding !! (v `div` 91)]-      in (q, n, cs ++ trail)--  g :: (Int, Int, [Char]) -> [Char]-  g (_,     0,     cs) = cs-  g (queue, nbits, cs) = cs ++ [y] ++ z-    where y = B91.encoding !! (queue `mod` 91)-          z | nbits > 7 || queue > 90 = [B91.encoding !! (queue `div` 91)]-            | otherwise               = []+encode :: BS.ByteString -> [Char]+encode = encodeBy BS.foldl' (++) []  -- | Decodes octets ('ByteString') from a '[Char]' in Base91; the opposite of 'encode'.-decode :: [Char] -> ByteString-decode = g . foldl' f (0, 0, -1, BS.empty) where--  f :: (Int, Int, Int, ByteString) -> Char -> (Int, Int, Int, ByteString)-  f (queue, nbits, val, bs) c =-    let d = fromIntegral $ B91.decoding !! ord c-     in if d   == 91 then (queue, nbits, val, bs) else-        if val == -1 then (queue, nbits, d,   bs) else-            let v = val + (d * 91)-                q = queue .|. (v `shiftL` nbits)-                n = nbits + (if (v .&. 8191) > 88 then 13 else 14)-                (queue', nbits', trail) = if n - 8 > 7-                  then (q `shiftR` 16, n - 16, [q, q `shiftR` 8])-                  else (q `shiftR` 8,  n - 8,  [q])-             in (queue', nbits', -1, BS.append bs $ BS.pack (map fromIntegral trail))--  g :: (Int, Int, Int, ByteString) -> ByteString-  g (_,     _,     -1,  bs) = bs-  g (queue, nbits, val, bs) = BS.snoc bs (fromIntegral $ queue .|. (val `shiftL` nbits))+decode :: [Char] -> BS.ByteString+decode = decodeBy L.foldl' (\bs -> BS.append bs . BS.pack) BS.empty
Codec/Binary/Base91/Efficient.hs view
@@ -1,59 +1,15 @@ -- Copyright 2015 Alvaro J. Genial (http://alva.ro) -- see LICENSE.md for more.--- Informed by Mario Rodriguez's C++ implementation.  module Codec.Binary.Base91.Efficient (decode, encode) where -import qualified Codec.Binary.Base91 as B91-import Data.Bits ((.&.), (.|.), shiftL, shiftR)-import Data.Char (ord)-import Data.Word (Word8)-import Data.ByteString (ByteString)+import Codec.Binary.Base91 (decodeBy, encodeBy) import qualified Data.ByteString as BS-import Data.Text (Text) import qualified Data.Text as T  -- | Encodes octets ('ByteString') to 'Text' in Base91; the opposite of 'decode'.-encode :: ByteString -> Text-encode = g . BS.foldl' f (0, 0, T.empty) where--  f :: (Int, Int, Text) -> Word8 -> (Int, Int, Text)-  f (queue, nbits, t) w =-    let queue' = queue .|. (fromIntegral w `shiftL` nbits)-        nbits' = nbits + 8-    in if nbits' <= 13 then (queue', nbits', t) else-      let val  = queue' .&. 8191-          val' = queue' .&. 16383-          (v, q, n)   = if val > 88-            then (val,  queue' `shiftR` 13, nbits' - 13)-            else (val', queue' `shiftR` 14, nbits' - 14)-          trail       = [B91.encoding !! (v `mod` 91),-                         B91.encoding !! (v `div` 91)]-      in (q, n, T.append t (T.pack trail))--  g :: (Int, Int, Text) -> Text-  g (_,     0,     t) = t-  g (queue, nbits, t) = T.append t (T.pack $ [y] ++ z)-    where y = B91.encoding !! (queue `mod` 91)-          z | nbits > 7 || queue > 90 = [B91.encoding !! (queue `div` 91)]-            | otherwise               = []+encode :: BS.ByteString -> T.Text+encode = encodeBy BS.foldl' (\t -> T.append t . T.pack) T.empty  -- | Decodes octets ('ByteString') from 'Text' in Base91; the opposite of 'encode'.-decode :: Text -> ByteString-decode = g . T.foldl' f (0, 0, -1, BS.empty) where--  f :: (Int, Int, Int, ByteString) -> Char -> (Int, Int, Int, ByteString)-  f (queue, nbits, val, bs) c =-    let d = fromIntegral $ B91.decoding !! ord c-     in if d   == 91 then (queue, nbits, val, bs) else-        if val == -1 then (queue, nbits, d,   bs) else-            let v = val + (d * 91)-                q = queue .|. (v `shiftL` nbits)-                n = nbits + (if (v .&. 8191) > 88 then 13 else 14)-                (queue', nbits', trail) = if n - 8 > 7-                  then (q `shiftR` 16, n - 16, [q, q `shiftR` 8])-                  else (q `shiftR` 8,  n - 8,  [q])-             in (queue', nbits', -1, BS.append bs $ BS.pack (map fromIntegral trail))--  g :: (Int, Int, Int, ByteString) -> ByteString-  g (_,     _,     -1,  bs) = bs-  g (queue, nbits, val, bs) = BS.snoc bs (fromIntegral $ queue .|. (val `shiftL` nbits))+decode :: T.Text -> BS.ByteString+decode = decodeBy T.foldl' (\bs -> BS.append bs . BS.pack) BS.empty
Codec/Binary/Base91/String.hs view
@@ -1,56 +1,15 @@ -- Copyright 2015 Alvaro J. Genial (http://alva.ro) -- see LICENSE.md for more.--- Informed by Mario Rodriguez's C++ implementation.  module Codec.Binary.Base91.String (decode, encode) where -import qualified Codec.Binary.Base91 as B91-import Data.Bits ((.&.), (.|.), shiftL, shiftR)-import Data.Char (ord)-import Data.List (foldl')-import Data.Word (Word8)+import Codec.Binary.Base91 (decodeBy, encodeBy)+import qualified Data.List as L+import qualified Data.Word as W  -- | Encodes octets ('[Word8]') to a 'String' in Base91; the opposite of 'decode'.-encode :: [Word8] -> String-encode = g . foldl' f (0, 0, []) where--  f :: (Int, Int, [Char]) -> Word8 -> (Int, Int, [Char])-  f (queue, nbits, cs) w =-    let queue' = queue .|. (fromIntegral w `shiftL` nbits)-        nbits' = nbits + 8-    in if nbits' <= 13 then (queue', nbits', cs) else-      let val  = queue' .&. 8191-          val' = queue' .&. 16383-          (v, q, n)   = if val > 88-            then (val,  queue' `shiftR` 13, nbits' - 13)-            else (val', queue' `shiftR` 14, nbits' - 14)-          trail       = [B91.encoding !! (v `mod` 91),-                         B91.encoding !! (v `div` 91)]-      in (q, n, cs ++ trail)--  g :: (Int, Int, [Char]) -> [Char]-  g (_,     0,     cs) = cs-  g (queue, nbits, cs) = cs ++ [y] ++ z-    where y = B91.encoding !! (queue `mod` 91)-          z | nbits > 7 || queue > 90 = [B91.encoding !! (queue `div` 91)]-            | otherwise               = []+encode :: [W.Word8] -> String+encode = encodeBy L.foldl' (++) []  -- | Decodes octets ('[Word8]') from a 'String' in Base91; the opposite of 'encode'.-decode :: String -> [Word8]-decode = g . foldl' f (0, 0, -1, []) where--  f :: (Int, Int, Int, [Word8]) -> Char -> (Int, Int, Int, [Word8])-  f (queue, nbits, val, ws) c =-    let d = fromIntegral $ B91.decoding !! ord c-     in if d   == 91 then (queue, nbits, val, ws) else-        if val == -1 then (queue, nbits, d,   ws) else-            let v = val + (d * 91)-                q = queue .|. (v `shiftL` nbits)-                n = nbits + (if (v .&. 8191) > 88 then 13 else 14)-                (queue', nbits', trail) = if n - 8 > 7-                  then (q `shiftR` 16, n - 16, [q, q `shiftR` 8])-                  else (q `shiftR` 8,  n - 8,  [q])-             in (queue', nbits', -1, ws ++ map fromIntegral trail)--  g :: (Int, Int, Int, [Word8]) -> [Word8]-  g (_,     _,     -1,  ws) = ws-  g (queue, nbits, val, ws) = ws ++ [fromIntegral $ queue .|. (val `shiftL` nbits)]+decode :: String -> [W.Word8]+decode = decodeBy L.foldl' (++) []
Codec/Binary/Base91/Text.hs view
@@ -1,58 +1,16 @@ -- Copyright 2015 Alvaro J. Genial (http://alva.ro) -- see LICENSE.md for more.--- Informed by Mario Rodriguez's C++ implementation.  module Codec.Binary.Base91.Text (decode, encode) where -import qualified Codec.Binary.Base91 as B91-import Data.Bits ((.&.), (.|.), shiftL, shiftR)-import Data.Char (ord)-import Data.List (foldl')-import Data.Word (Word8)-import Data.Text (Text)+import Codec.Binary.Base91 (decodeBy, encodeBy)+import qualified Data.List as L import qualified Data.Text as T+import qualified Data.Word as W  -- | Encodes octets ('[Word8]') to 'Text' in Base91; the opposite of 'decode'.-encode :: [Word8] -> Text-encode = g . foldl' f (0, 0, T.empty) where--  f :: (Int, Int, Text) -> Word8 -> (Int, Int, Text)-  f (queue, nbits, t) w =-    let queue' = queue .|. (fromIntegral w `shiftL` nbits)-        nbits' = nbits + 8-    in if nbits' <= 13 then (queue', nbits', t) else-      let val  = queue' .&. 8191-          val' = queue' .&. 16383-          (v, q, n)   = if val > 88-            then (val,  queue' `shiftR` 13, nbits' - 13)-            else (val', queue' `shiftR` 14, nbits' - 14)-          trail       = [B91.encoding !! (v `mod` 91),-                         B91.encoding !! (v `div` 91)]-      in (q, n, T.append t (T.pack trail))--  g :: (Int, Int, Text) -> Text-  g (_,     0,     t) = t-  g (queue, nbits, t) = T.append t (T.pack $ [y] ++ z)-    where y = B91.encoding !! (queue `mod` 91)-          z | nbits > 7 || queue > 90 = [B91.encoding !! (queue `div` 91)]-            | otherwise               = []+encode :: [W.Word8] -> T.Text+encode = encodeBy L.foldl' (\t -> T.append t . T.pack) T.empty  -- | Decodes octets ('[Word8]') from 'Text' in Base91; the opposite of 'encode'.-decode :: Text -> [Word8]-decode = g . T.foldl' f (0, 0, -1, []) where--  f :: (Int, Int, Int, [Word8]) -> Char -> (Int, Int, Int, [Word8])-  f (queue, nbits, val, ws) c =-    let d = fromIntegral $ B91.decoding !! ord c-     in if d   == 91 then (queue, nbits, val, ws) else-        if val == -1 then (queue, nbits, d,   ws) else-            let v = val + (d * 91)-                q = queue .|. (v `shiftL` nbits)-                n = nbits + (if (v .&. 8191) > 88 then 13 else 14)-                (queue', nbits', trail) = if n - 8 > 7-                  then (q `shiftR` 16, n - 16, [q, q `shiftR` 8])-                  else (q `shiftR` 8,  n - 8,  [q])-             in (queue', nbits', -1, ws ++ map fromIntegral trail)--  g :: (Int, Int, Int, [Word8]) -> [Word8]-  g (_,     _,     -1,  ws) = ws-  g (queue, nbits, val, ws) = ws ++ [fromIntegral $ queue .|. (val `shiftL` nbits)]+decode :: T.Text -> [W.Word8]+decode = decodeBy T.foldl' (++) []
base91.cabal view
@@ -1,10 +1,13 @@ Name:                  base91-Version:               0.1.0+Version:               0.1.1 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 bytes to/from strings.+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; see+                       the Flags section for details. License:               MIT License-File:          LICENSE.md Category:              Codec@@ -21,8 +24,7 @@  Library   Build-Depends:       base >= 4 && < 5-  Exposed-Modules:     Codec.Binary.Base91.String-  Other-Modules:       Codec.Binary.Base91+  Exposed-Modules:     Codec.Binary.Base91, Codec.Binary.Base91.String    if flag(ByteString)     Build-Depends:     bytestring