cbor-tool (empty) → 0.1.0.0
raw patch · 5 files changed
+205/−0 lines, 5 filesdep +aesondep +aeson-prettydep +basesetup-changed
Dependencies added: aeson, aeson-pretty, base, bytestring, cborg, cborg-json, filepath, scientific, text, unordered-containers, vector
Files
- ChangeLog.md +5/−0
- LICENSE.txt +30/−0
- Main.hs +133/−0
- Setup.hs +2/−0
- cbor-tool.cabal +35/−0
+ ChangeLog.md view
@@ -0,0 +1,5 @@+# Revision history for cbor-tool++## 0.1.0.0 -- YYYY-mm-dd++* First version. Released on an unsuspecting world.
+ LICENSE.txt view
@@ -0,0 +1,30 @@+Copyright (c) 2017, Duncan Coutts++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++ * Redistributions of source code must retain the above copyright+ notice, this list of conditions and the following disclaimer.++ * 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.++ * Neither the name of Duncan Coutts nor the names of other+ contributors may be used to endorse or promote products derived+ from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 COPYRIGHT+OWNER 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.
+ Main.hs view
@@ -0,0 +1,133 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE RankNTypes #-}+module Main+ ( main -- :: IO ()+ ) where++import Control.Monad+import System.FilePath+import System.Environment+import System.Exit ( exitFailure )+import System.IO ( hPutStrLn, stderr )+import Text.Printf ( printf )++#if !MIN_VERSION_base(4,8,0)+import Control.Applicative+#endif+import qualified Data.Aeson as Aeson+import Data.Aeson.Encode.Pretty as Aeson.Pretty+import qualified Data.ByteString.Lazy as LB++import qualified Data.Text.Lazy.IO as LT+import qualified Data.Text.Lazy.Builder as LT++import Codec.CBOR.JSON+import Codec.CBOR.Pretty+import Codec.CBOR.Read as Read+import qualified Codec.CBOR.Write as Write+import Codec.CBOR.Term ( decodeTerm, encodeTerm )++--------------------------------------------------------------------------------+-- JSON -> CBOR conversion++-- | Convert an arbitrary JSON file into CBOR format.+jsonToCbor :: FilePath -> IO ()+jsonToCbor file = do+ bs <- LB.readFile file+ case Aeson.decode bs of+ Nothing -> fail "invalid JSON file!"+ Just v -> do+ let encVal = encodeValue v+ cborFile = dropExtension file <.> "cbor"+ -- Now write the blob+ LB.writeFile cborFile (Write.toLazyByteString encVal)++--------------------------------------------------------------------------------+-- Dumping code++-- | Dump a CBOR file as JSON+dumpCborAsJson :: Bool -> FilePath -> IO ()+dumpCborAsJson lenient file = LB.readFile file >>= go+ where go :: LB.ByteString -> IO ()+ go bs =+ case deserialiseFromBytes (decodeValue lenient) bs of+ Left (Read.DeserialiseFailure off err) ->+ fail $ "deserialization error (at offset " ++ show off ++ "): " ++ err+ Right (trailing, v) -> do+ let builder = Aeson.Pretty.encodePrettyToTextBuilder v+ LT.putStrLn (LT.toLazyText builder)+ unless (LB.null trailing) (go trailing)++-- | Dump a CBOR file as a Term, or optionally as pretty hex+dumpCborFile :: Bool -> FilePath -> IO ()+dumpCborFile pretty file = LB.readFile file >>= go+ where go :: LB.ByteString -> IO ()+ go bs =+ case deserialiseFromBytes decodeTerm bs of+ Left (Read.DeserialiseFailure off err) ->+ fail $ "deserialization error (at offset " ++ show off ++ "): " ++ err+ Right (trailing, v) -> do+ if pretty+ then putStrLn (prettyHexEnc $ encodeTerm v)+ else print v+ unless (LB.null trailing) (go trailing)++dumpAsHex :: FilePath -> IO ()+dumpAsHex file = do+ bs <- LB.readFile file+ putStrLn (showHexString bs)++-- | Show a @'ByteString'@ as a hex string.+showHexString :: LB.ByteString -> String+showHexString = concat . toHex+ where+ toHex = map (printf "%02X ") . LB.unpack++--------------------------------------------------------------------------------+-- Driver code++-- | Main entry point.+main :: IO ()+main = do+ let help = unlines+ [ "usage: cbor-tool <action> [options] <file>"+ , ""+ , " Useful tool for dealing with and analyzing raw files containing"+ , " CBOR values. <action> and <file> are both mandatory options."+ , ""+ , " Actions:"+ , ""+ , " dump [--json|--hex|--pretty|--term] [--lenient] <file>"+ , " Read the CBOR values inside <file> and dump them in the"+ , " specified format. --json will dump JSON files, while --hex"+ , " will dump the output in hexadecimal format. --pretty will"+ , " use the internal 'Encoding' pretty-printer. --term is the"+ , " internal 'Term' format type. You must specify either"+ , " --json, --hex, --pretty, or --term (there is no default)."+ , ""+ , " When printing CBOR as JSON, the only valid type for JSON"+ , " object keys is a UTF8 string. If you have a CBOR map that"+ , " uses non-String types for keys, this will cause the decoder"+ , " to fail when creating JSON. Use the --lenient option to"+ , " remove this restriction -- this will allow numbers to also"+ , " be valid as CBOR keys, by printing them as strings. However,"+ , " this may risk collision of some keys as CBOR is more general,"+ , " resulting in invalid JSON -- so use it with caution."+ , ""+ , " encode [--json] <file>"+ , " Read the <file> in a specified format and dump a copy of"+ , " the input in CBOR form under <file>.cbor. --json reads"+ , " JSON files. You must specify --json (there is no default,"+ , " for future compatibility.)"+ ]++ args <- getArgs+ case args of+ ("dump" : "--json" : "--lenient" : file : _) -> dumpCborAsJson True file+ ("dump" : "--json" : file : _) -> dumpCborAsJson False file+ ("dump" : "--hex" : file : _) -> dumpAsHex file+ ("dump" : "--pretty" : file : _) -> dumpCborFile True file+ ("dump" : "--term" : file : _) -> dumpCborFile False file+ ("encode" : "--json" : file : _) -> jsonToCbor file+ _ -> hPutStrLn stderr help >> exitFailure
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ cbor-tool.cabal view
@@ -0,0 +1,35 @@+name: cbor-tool+version: 0.1.0.0+synopsis: A tool for manipulating CBOR.+description: A tool for dumping and converting CBOR-encoded data.+homepage: https://github.com/well-typed/cborg+license: BSD3+license-file: LICENSE.txt+author: Duncan Coutts+maintainer: duncan@community.haskell.org, ben@smart-cactus.org+copyright: 2015-2017 Duncan Coutts,+ 2015-2017 Well-Typed LLP,+ 2015 IRIS Connect Ltd+category: Codec+build-type: Simple+extra-source-files: ChangeLog.md+cabal-version: >=1.10++executable cbor-tool+ main-is: Main.hs+ other-extensions: CPP, BangPatterns+ ghc-options: -Wall+ build-depends:+ base >=4.6 && <5.0,+ filepath >=1.0 && <1.5,+ aeson >=0.7 && <1.3,+ aeson-pretty >=0.8 && <0.9,+ scientific >=0.3 && <0.4,+ bytestring >=0.10 && <0.11,+ unordered-containers >=0.2 && <0.3,+ text >=1.1 && <1.3,+ vector >=0.10 && <0.13,++ cborg ==0.1.*,+ cborg-json ==0.1.*+ default-language: Haskell2010