packages feed

include-file (empty) → 0.1.0.0

raw patch · 6 files changed

+220/−0 lines, 6 filesdep +basedep +bytestringdep +criterionbuild-type:Customsetup-changed

Dependencies added: base, bytestring, criterion, include-file, template-haskell

Files

+ Development/IncludeFile.hs view
@@ -0,0 +1,91 @@++-- | Inclusion of files in source code via Template Haskell.+--+--   When distributing executables, sometimes it is required to attach some other resources in+--   files. Using 'includeFileInSource' you avoid this problem by including those files inside+--   the executable at compile time.+--+-- = Example+--+--   A quick example. I want to include a small image (@foo.png@) in the executable. I would do:+--+-- > {-# LANGUAGE TemplateHaskell #-}+-- >+-- > import Development.IncludeFile+-- >+-- > $(includeFileInSource "foo.png" "myImage")+-- >+--+--   This defines the @myImage@ value with type 'S.ByteString' and with the content of the file @foo.png@.+--+-- = Using 'includeFileInSource'+--+--   The following entities must be in scope when calling 'includeFileInSource':+--+-- * A @ByteString@ type.+-- * A @Word8@ type, instance of the 'Num' class (at least with the 'fromInteger' method implemented).+-- * A @pack :: [Word8] -> ByteString@ function.+--+--   This module re-export these for convenience, but you can use your own types (for example, using+--   /lazy/ bytestrings instead of /strict/ bytestrings).+--+-- = Using lazy bytestrings+--+--   To use lazy bytestrings, instead of importing this full module, import it like this:+--+-- > import Data.ByteString.Lazy (ByteString,pack)+-- > import Development.IncludeFile (includeFileInSource,Word8)+--+--   Needless to say, if you have already imported any of those entities, you don't have to do it again.+--+-- = Performance impact+--+--   Benchmarks confirm that it is /much/ faster to use an included bytestring than reading it from a file.+--+-- > benchmarking include-file+-- > time                 1.814 ns   (1.799 ns .. 1.826 ns)+-- >                      1.000 R²   (0.999 R² .. 1.000 R²)+-- > mean                 1.808 ns   (1.797 ns .. 1.819 ns)+-- > std dev              37.48 ps   (31.27 ps .. 46.78 ps)+-- > +-- > benchmarking read-file+-- > time                 4.869 μs   (4.798 μs .. 4.938 μs)+-- >                      0.998 R²   (0.998 R² .. 0.999 R²)+-- > mean                 4.911 μs   (4.857 μs .. 4.968 μs)+-- > std dev              178.8 ns   (150.1 ns .. 212.5 ns)+--+-- = Large files+--+--   Do not use 'includeFileInSource' with large files. The limit between what /is/ and what is /not/ a large+--   file remains uncertain.+--+module Development.IncludeFile (+    -- * Including files+    includeFileInSource+    -- * Convenient re-exports+  , B.ByteString+  , Word8+  , B.pack+  ) where++import qualified Data.ByteString as B+import Data.Word (Word8)+import Language.Haskell.TH++-- | Define a value of type @ByteString@ (where @ByteString@ is whatever @ByteString@ type is in scope)+--   with the content of a file.+includeFileInSource :: FilePath -- ^ Path to file+                    -> String -- ^ Haskell value name+                    -> Q [Dec]+includeFileInSource fp n = do+  b <- runIO $ B.readFile fp+  let ws = B.unpack b+      wtype = ConT $ mkName "Word8"+      btype = ConT $ mkName "ByteString"+  return+    [ SigD (mkName n) btype+    , FunD (mkName n) [Clause [] (NormalB $+         AppE (SigE (VarE $ mkName "pack") $ ArrowT `AppT` (ListT `AppT` wtype) `AppT` btype)+           $ ListE $ fmap (LitE . IntegerL . fromIntegral) ws+                                   ) []]+      ]
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) 2014, Daniel Díaz++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 Daniel Díaz 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.
+ Setup.hs view
@@ -0,0 +1,19 @@++import Distribution.Simple+import System.Random (randomRIO, randomIO)+import qualified Data.ByteString as B+import Control.Monad (replicateM)++main :: IO ()+main = do+  defaultMainWithHooks $+    simpleUserHooks+      { preBuild = \_ _ -> do+          putStr "Generating random file for testing..."+          n <- randomRIO (10,1000)+          ws <- replicateM n randomIO+          let b = B.pack ws+          B.writeFile "test/random" b+          putStrLn " Done."+          return (Nothing,[])+        }
+ bench/Main.hs view
@@ -0,0 +1,14 @@++{-# LANGUAGE TemplateHaskell #-}++import Criterion.Main+import Development.IncludeFile+import qualified Data.ByteString as B++$(includeFileInSource "test/random" "random")++main :: IO ()+main = defaultMain+  [ bench "include-file" $ whnf (const random) (0 :: Int)+  , bench "read-file"    $ whnfIO $ B.readFile "test/random"+    ]
+ include-file.cabal view
@@ -0,0 +1,46 @@+name:                include-file+version:             0.1.0.0+synopsis:            Inclusion of files in executables at compile-time.+description:         Inclusion of files in source code via Template Haskell.+                     .+                     When distributing executables, sometimes it is required+                     to attach some other resources in files. Using this library+                     (together with the TemplateHaskell extension) you avoid this+                     problem by including those files inside the executable at+                     compile time.+license:             BSD3+license-file:        LICENSE+author:              Daniel Díaz+maintainer:          dhelta.diaz@gmail.com+category:            Development+build-type:          Custom+cabal-version:       >=1.10++library+  exposed-modules: Development.IncludeFile+  build-depends: base == 4.*+               , bytestring+               , template-haskell+  default-language: Haskell2010+  ghc-options: -Wall++test-suite include-file-test+  default-language: Haskell2010+  type: exitcode-stdio-1.0+  hs-source-dirs: test+  main-is: Main.hs+  build-depends: base == 4.*+               , include-file+               , bytestring+  ghc-options: -fforce-recomp++benchmark include-file-bench+  default-language: Haskell2010+  type: exitcode-stdio-1.0+  hs-source-dirs: bench+  main-is: Main.hs+  build-depends: base == 4.*+               , include-file+               , bytestring+               , criterion+  ghc-options: -fforce-recomp -O2 -Wall
+ test/Main.hs view
@@ -0,0 +1,20 @@++{-# LANGUAGE TemplateHaskell #-}++import System.Exit (exitSuccess, exitFailure)+import Development.IncludeFile+import qualified Data.ByteString as B++$(includeFileInSource "test/random" "test")++main :: IO ()+main = do+  b <- B.readFile "test/random"+  if b == test+     then exitSuccess+     else do putStrLn "Fail: inputs differ."+             putStrLn "Original:"+             print $ B.unpack b+             putStrLn "Included:"+             print $ B.unpack test+             exitFailure