packages feed

omnicodec 0.4.0 → 0.5

raw patch · 3 files changed

+206/−141 lines, 3 filesdep +cmdargsdep +mtldep −directorydep −filepathdep −haskell98dep ~basedep ~bytestringdep ~dataenc

Dependencies added: cmdargs, mtl

Dependencies removed: directory, filepath, haskell98

Dependency ranges changed: base, bytestring, dataenc

Files

omnicodec.cabal view
@@ -1,26 +1,24 @@ name: omnicodec-version: 0.4.0+version: 0.5 license: GPL license-file: COPYING author: Magnus Therning maintainer: magnus@therning.org-copyright: Magnus Therning, 2007-2010+copyright: Magnus Therning, 2007-2011 synopsis: data encoding and decoding command line utilities description: Two simple command line tools built on dataenc. build-type: Simple category: Codec-cabal-version: >= 1.2+cabal-version: >= 1.6  executable odec-  main-is: odec.hs-  hs-source-dirs: src-  build-depends: base >= 4.0.0 && < 4.3, dataenc >= 0.13, directory, filepath,-      haskell98, bytestring-  ghc-options: -Wall+    main-is: odec.hs+    hs-source-dirs: src+    build-depends: base ==4.2.*, cmdargs ==0.6.*, bytestring ==0.9.*,+        mtl ==1.1.*, dataenc ==0.14.*+    ghc-options: -Wall  executable oenc-  main-is: oenc.hs-  hs-source-dirs: src-  build-depends: base >= 4.0.0 && < 4.3, dataenc >= 0.13, directory, filepath,-      haskell98, bytestring-  ghc-options: -Wall+    main-is: oenc.hs+    hs-source-dirs: src+    ghc-options: -Wall
src/odec.hs view
@@ -1,3 +1,5 @@+{-# LANGUAGE DeriveDataTypeable #-}+ {- odec - command line utility for data decoding Copyright (C) 2008  Magnus Therning@@ -20,84 +22,121 @@     ( main     ) where -import Codec.Binary.DataEncoding-import Data.Maybe-import Data.Version (showVersion)-import Data.Word-import System-import System.Console.GetOpt-import Control.Exception as CE-import System.Directory-import qualified Data.ByteString as BS- import Paths_omnicodec (version) +import Codec.Binary.Base64 as B64+import qualified Codec.Binary.Base64Url as B64U+import qualified Codec.Binary.Base32 as B32+import qualified Codec.Binary.Base32Hex as B32H+import qualified Codec.Binary.Base16 as B16+import qualified Codec.Binary.Base85 as B85+import qualified Codec.Binary.PythonString as PS+import qualified Codec.Binary.QuotedPrintable as QP+import qualified Codec.Binary.Url as Url+import qualified Codec.Binary.Uu as Uu+import qualified Codec.Binary.Xx as Xx+import Data.ByteString.Iteratee+import Data.ByteString.Iteratee.Internals++import qualified Data.ByteString as BS+import qualified Data.ByteString.Char8 as BSC+import System.Console.CmdArgs+import Data.Version(showVersion)+import System.IO+import Data.Maybe++-- {{{1 command line options ver :: String ver = "omnicode decode (odec) " ++ (showVersion version)-    ++ "\nCopyright 2007-2010 Magnus Therning <magnus@therning.org>"---- {{{1 Options-data DecOptions = DecOptions {-    optDecode :: [String] -> [Maybe Word8],-    optRead :: IO String,-    optWrite :: BS.ByteString -> IO (),-    optFn :: Maybe String  -- needed in case we need to clean up later on-    }+    ++ "\nCopyright 2007-2011 Magnus Therning <magnus@therning.org>" -defaultOptions :: DecOptions-defaultOptions = DecOptions {-    optDecode = decode' uu . unchop uu,-    optRead = getContents,-    optWrite = BS.putStr,-    optFn = Nothing-    }+data Codec = B64 | B64U | B32 | B32H | B16 | B85 | PS | QP | Url | Uu | Xx+    deriving(Show, Eq, Data, Typeable) --- {{{2 Command line-options :: [OptDescr (DecOptions -> IO DecOptions)]-options = [-    Option "o" ["output"] (ReqArg setOptOutput "FILE") "output to file",-    Option "c" ["codec"] (ReqArg setOptCodec "CODEC") "use codec (uu,xx,qp,py,b85,b64,b64u,b32,b32h,b16)",-    Option "" ["version"] (NoArg optShowVersion) "",-    Option "h" ["help"] (NoArg optShowHelp) ""+codecMap :: [(Codec, DecIncData String -> DecIncRes String)]+codecMap =+    [ (B64, B64.decodeInc)+    , (B64U, B64U.decodeInc)+    , (B32, B32.decodeInc)+    , (B32H, B32H.decodeInc)+    , (B16, B16.decodeInc)+    , (B85, B85.decodeInc)+    , (PS, PS.decodeInc)+    , (QP, QP.decodeInc)+    , (Url, Url.decodeInc)+    , (Uu, Uu.decodeInc)+    , (Xx, Xx.decodeInc)     ] --- {{{2 Processing command line-setOptOutput :: FilePath -> DecOptions -> IO DecOptions-setOptOutput fn opts = return opts { optWrite = BS.writeFile fn, optFn = Just fn }--setOptCodec :: String -> DecOptions -> IO DecOptions-setOptCodec codec opts = case codec of-    "uu" -> return opts { optDecode = decode' uu . unchop uu }-    "xx" -> return opts { optDecode = decode' xx . unchop xx }-    "qp" -> return opts { optDecode = decode' qp . unchop qp }-    "py" -> return opts { optDecode = decode' py . unchop py }-    "b85" -> return opts { optDecode = decode' base85 . unchop base85 }-    "b64" -> return opts { optDecode = decode' base64 . unchop base64 }-    "b64u" -> return opts { optDecode = decode' base64Url . unchop base64Url }-    "b32" -> return opts { optDecode = decode' base32 . unchop base32 }-    "b32h" -> return opts { optDecode = decode' base32Hex . unchop base32Hex }-    "b16" -> return opts { optDecode = decode' base16 . unchop base16 }-    _ -> error "Unknown encoding."--optShowVersion :: a -> IO DecOptions-optShowVersion _ = putStrLn ver >> exitWith ExitSuccess+data MyArgs = MyArgs { argInput :: Maybe FilePath, argOutput :: Maybe FilePath, argCodec :: Codec }+    deriving(Show, Data, Typeable) -optShowHelp :: DecOptions -> IO DecOptions-optShowHelp _ = putStrLn (usageInfo "Usage:" options) >> exitWith ExitSuccess+myArgs :: MyArgs+myArgs = MyArgs+    { argInput = Nothing &= name "i" &= name "in" &= explicit &= typFile &= help "read encoded data from file"+    , argOutput = Nothing &= name "o" &= name "out" &= explicit &= typFile &= help "write decoded data to file"+    , argCodec = B64 &= name "c" &= name "codec" &= explicit &= typ "CODEC" &= help "codec b64, b64u, b32, b32h, b16, b85, ps, qp, url, uu, xx (b64)"+    } &= summary ver &= details+        [ "Decoder tool for multiple encodings:"+        , " b64  - base64 (default)"+        , " b64u - base64url"+        , " b32  - base32"+        , " b32h - base32hex"+        , " b16  - base16"+        , " b85  - base85"+        , " ps   - python string escaping"+        , " qp   - quoted printable"+        , " url  - url encoding"+        , " uu   - uu encoding"+        , " xx   - xx encoding"+        ] -processFileName :: [String] -> IO DecOptions-processFileName (fn:_) = return defaultOptions { optRead = readFile fn }-processFileName _ = return defaultOptions+-- {{{1 decode enumeratee+decEnumeratee :: Monad m => (DecIncData String -> DecIncRes String) -> Enumeratee m a+decEnumeratee decF iter = Iteratee $ step decF iter+    where+        step f i Eof = let+                d = f DDone+            in do+                case d of+                    DFinal dbs _ -> do+                        ir <- runIteratee i (Chunk $ BS.pack dbs)+                        case ir of+                            Done a _ -> return $ Done (Iteratee $ \ _ -> return $ Done a Eof) Eof+                            NeedAnotherChunk i' -> do+                                ir' <- runIteratee i' Eof+                                case ir' of+                                    Done a _ -> return $ Done (Iteratee $ \ _ -> return $ Done a Eof) Eof+                                    NeedAnotherChunk _ -> error "decEnumeratee: inner iteratee diverges on Eof"+                    DFail _ _ -> error "decEnumeratee: decoder failed on data"+                    DPart _ _ -> error "decEnumeratee: decoder didn't terminate on DDone" --- {{{1 decode'-_decode :: DecOptions -> String -> IO BS.ByteString-_decode opts = return .  BS.pack. map (fromMaybe (error "Illegal character")) . optDecode opts . lines+        step f i (Chunk bs) = let+                d = f (DChunk $ BSC.unpack bs)+            in do+                case d of+                    DFinal dbs r -> do+                        ir <- runIteratee i (Chunk $ BS.pack dbs)+                        case ir of+                            Done a _ -> return $ Done (Iteratee $ \ _ -> return $ Done a (Chunk $ BSC.pack r)) (Chunk $ BSC.pack r)+                            NeedAnotherChunk i' -> do+                                ir' <- runIteratee i' Eof+                                case ir' of+                                    Done a _ -> return $ Done (Iteratee $ \ _ -> return $ Done a Eof) Eof+                                    NeedAnotherChunk _ -> error "decEnumeratee: inner iteratee diverges on Eof"+                    DFail _ _ -> error "decEnumeratee: decoder failed on data"+                    DPart dbs f' -> do+                        ir <- runIteratee i (Chunk $ BS.pack dbs)+                        case ir of+                            Done a _ -> return $ Done (Iteratee $ \ _ -> return $ Done a (Chunk BS.empty)) (Chunk BS.empty)+                            NeedAnotherChunk i' -> return $ NeedAnotherChunk $ Iteratee $ step f' i'  -- {{{1 main main :: IO () main = do-    args <- getArgs-    let (actions, nonOpts, _) = getOpt RequireOrder options args-    opts <- foldl (>>=) (processFileName nonOpts) actions-    CE.catch (optRead opts >>= _decode opts >>= optWrite opts)-        (\ (CE.SomeException e) -> maybe (return ()) removeFile (optFn opts) >> throwIO e)+    cmdArgs myArgs >>= \ a -> do+    hIn <- maybe (return stdin) (\ fn -> openFile fn ReadMode) (argInput a)+    hOut <- maybe (return stdout) (\ fn -> openFile fn WriteMode) (argOutput a)+    let dI = fromJust $ lookup (argCodec a) codecMap+    (enumHandle hIn $ decEnumeratee dI (sinkHandle hOut)) >>= run >>= run+    hClose hOut
src/oenc.hs view
@@ -1,3 +1,5 @@+{-# LANGUAGE DeriveDataTypeable #-}+ {- oenc - command line utility for data encoding Copyright (C) 2008  Magnus Therning@@ -16,80 +18,106 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>. -} -module Main-    where--import Codec.Binary.DataEncoding-import Data.Version (showVersion)-import Data.Word-import System-import System.Console.GetOpt-import qualified Data.ByteString as BS+module Main where  import Paths_omnicodec (version) +import Codec.Binary.Base64 as B64+import qualified Codec.Binary.Base64Url as B64U+import qualified Codec.Binary.Base32 as B32+import qualified Codec.Binary.Base32Hex as B32H+import qualified Codec.Binary.Base16 as B16+import qualified Codec.Binary.Base85 as B85+import qualified Codec.Binary.PythonString as PS+import qualified Codec.Binary.QuotedPrintable as QP+import qualified Codec.Binary.Url as Url+import qualified Codec.Binary.Uu as Uu+import qualified Codec.Binary.Xx as Xx+import Data.ByteString.Iteratee+import Data.ByteString.Iteratee.Internals++import Data.Version(showVersion)+import System.Console.CmdArgs+import qualified Data.ByteString as BS+import qualified Data.ByteString.Char8 as BSC+import System.IO+import Data.Maybe++-- {{{1 command line options ver :: String ver = "omnicode encode (oenc) " ++ (showVersion version)-    ++ "\nCopyright 2007-2010 Magnus Therning <magnus@therning.org>"---- {{{1 Options-data EncOptions = EncOptions {-    optEncode :: [Word8] -> [String],-    optRead :: IO BS.ByteString,-    optWrite :: String -> IO ()-    }+    ++ "\nCopyright 2007-2011 Magnus Therning <magnus@therning.org>" -defaultOptions :: EncOptions-defaultOptions = EncOptions {-    optEncode = chop uu 61 . encode uu,-    optRead = BS.getContents,-    optWrite = putStr-    }+data Codec = B64 | B64U | B32 | B32H | B16 | B85 | PS | QP | Url | Uu | Xx+    deriving(Show, Eq, Data, Typeable) -options :: [OptDescr (EncOptions -> IO EncOptions)]-options = [-    Option "o" ["output"] (ReqArg setOptOutput "FILE") "output to file",-    Option "c" ["codec"] (ReqArg setOptCodec "CODEC") "use codec (uu,xx,qp,py,b85,b64,b64u,b32,b32h,b16)",-    Option "" ["version"] (NoArg optShowVersion) "",-    Option "h" ["help"] (NoArg optShowHelp) ""+codecMap :: [(Codec, EncIncData -> EncIncRes String)]+codecMap =+    [ (B64, B64.encodeInc)+    , (B64U, B64U.encodeInc)+    , (B32, B32.encodeInc)+    , (B32H, B32H.encodeInc)+    , (B16, B16.encodeInc)+    , (B85, B85.encodeInc)+    , (PS, PS.encodeInc)+    , (QP, QP.encodeInc)+    , (Url, Url.encodeInc)+    , (Uu, Uu.encodeInc)+    , (Xx, Xx.encodeInc)     ] --- {{{2 option actions-setOptCodec :: String -> EncOptions -> IO EncOptions-setOptCodec codec opts = case codec of-    "uu" -> return opts { optEncode = chop uu 61 . encode uu }-    "xx" -> return opts { optEncode = chop xx 61 . encode xx }-    "qp" -> return opts { optEncode = chop qp 60 . encode qp }-    "py" -> return opts { optEncode = chop py 60 . encode py }-    "b85" -> return opts { optEncode = chop base85 60 . encode base85 }-    "b64" -> return opts { optEncode = chop base64 60 . encode base64 }-    "b64u" -> return opts { optEncode = chop base64Url 60 . encode base64Url }-    "b32" -> return opts { optEncode = chop base32 60 . encode base32 }-    "b32h" -> return opts { optEncode = chop base32Hex 60 . encode base32Hex }-    "b16" -> return opts { optEncode = chop base16 60 . encode base16 }-    _ -> error "Unknown encoding."--setOptOutput :: FilePath -> EncOptions -> IO EncOptions-setOptOutput fn opts = return opts { optWrite = writeFile fn }--optShowVersion :: EncOptions -> IO EncOptions-optShowVersion _ = putStrLn ver >> exitWith ExitSuccess--optShowHelp :: EncOptions -> IO EncOptions-optShowHelp _ = putStr (usageInfo "Usage:" options) >> exitWith ExitSuccess+data MyArgs = MyArgs { argInput :: Maybe FilePath, argOutput :: Maybe FilePath, argCodec :: Codec }+    deriving(Show, Data, Typeable) -processFileName :: [String] -> IO EncOptions-processFileName (fn:_) = return defaultOptions { optRead = BS.readFile fn }-processFileName _ = return defaultOptions+myArgs :: MyArgs+myArgs = MyArgs+    { argInput = Nothing &= name "i" &= name "in" &= explicit &= typFile &= help "read data from file"+    , argOutput = Nothing &= name "o" &= name "out" &= explicit &= typFile &= help "write encoded data to file"+    , argCodec = B64 &= name "c" &= name "codec" &= explicit &= typ "CODEC" &= help "codec b64, b64u, b32, b32h, b16, b85, ps, qp, url, uu, xx (b64)"+    } &= summary ver &= details+        [ "Encoder tool for multiple encodings:"+        , " b64  - base64 (default)"+        , " b64u - base64url"+        , " b32  - base32"+        , " b32h - base32hex"+        , " b16  - base16"+        , " b85  - base85"+        , " ps   - python string escaping"+        , " qp   - quoted printable"+        , " url  - url encoding"+        , " uu   - uu encoding"+        , " xx   - xx encoding"+        ] --- {{{1 encode-_encode :: EncOptions -> BS.ByteString -> IO String-_encode opts = return . unlines . optEncode opts . BS.unpack+-- {{{1 encode enumeratee+encEnumeratee :: Monad m => (EncIncData -> EncIncRes String) -> Enumeratee m a+encEnumeratee encF iter = Iteratee $ step encF iter+    where+        step f i Eof = let+                EFinal ebs = f EDone+            in do+                ir <- runIteratee i (Chunk $ BSC.pack ebs)+                case ir of+                    Done a _ -> return $ Done (Iteratee $ \ _ -> return $ Done a Eof) Eof+                    NeedAnotherChunk i' -> do+                        ir' <- runIteratee i' Eof+                        case ir' of+                            Done a _ -> return $ Done (Iteratee $ \ _ -> return $ Done a Eof) Eof+                            NeedAnotherChunk _ -> error "encEnumeratee: inner iteratee diverges on Eof"+        step f i (Chunk bs) = let+                EPart ebs f' = f (EChunk $ BS.unpack bs)+            in do+                ir <- runIteratee i (Chunk $ BSC.pack ebs)+                case ir of+                    Done a _ -> return $ Done (Iteratee $ \ _ -> return $ Done a (Chunk BS.empty)) (Chunk BS.empty)+                    NeedAnotherChunk i' -> return $ NeedAnotherChunk $ Iteratee $ step f' i'  -- {{{1 main main :: IO () main = do-    args <- getArgs-    let (actions, nonOpts, _) = getOpt RequireOrder options args-    opts <- foldl (>>=) (processFileName nonOpts) actions-    optRead opts >>= _encode opts >>= optWrite opts+    cmdArgs myArgs >>= \ a -> do+    hIn <- maybe (return stdin) (\ fn -> openFile fn ReadMode) (argInput a)+    hOut <- maybe (return stdout) (\ fn -> openFile fn WriteMode) (argOutput a)+    let eI = fromJust $ lookup (argCodec a) codecMap+    (enumHandle hIn $ encEnumeratee eI (sinkHandle hOut)) >>= run >>= run+    hClose hOut