{-# LANGUAGE DeriveDataTypeable #-} {- oenc - command line utility for data encoding Copyright (C) 2008 Magnus Therning This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . -} 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-2011 Magnus Therning " data Codec = B64 | B64U | B32 | B32H | B16 | B85 | PS | QP | Url | Uu | Xx deriving(Show, Eq, Data, Typeable) 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) ] data MyArgs = MyArgs { argInput :: Maybe FilePath, argOutput :: Maybe FilePath, argCodec :: Codec } deriving(Show, Data, Typeable) 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 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 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