bytable (empty) → 0.0.0.0
raw patch · 5 files changed
+158/−0 lines, 5 filesdep +basedep +bytestringsetup-changed
Dependencies added: base, bytestring
Files
- LICENSE +27/−0
- Setup.hs +2/−0
- bytable.cabal +37/−0
- src/Codec/Bytable.hs +45/−0
- src/Codec/Bytable/BigEndian.hs +47/−0
+ LICENSE view
@@ -0,0 +1,27 @@+Copyright (c) 2014, Yoshikuni Jujo+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 the Yoshikuni Jujo nor the names of its+ 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 EVEN SHALL THE COPYRIGHT HOLDER 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,2 @@+import Distribution.Simple+main = defaultMain
+ bytable.cabal view
@@ -0,0 +1,37 @@+cabal-version: >= 1.6+build-type: Simple++name: bytable+version: 0.0.0.0+stability: Experimental+author: Yoshikuni Jujo <PAF01143@nifty.ne.jp>+maintainer: Yoshikuni Jujo <PAF01143@nifty.ne.jp>++license: BSD3+license-file: LICENSE++category: Codec+synopsis: data from/to ByteString+description:+ You can read data from ByteString.+ .+ > some = do+ > x <- take 4+ > y <- take 8+ > return (x :: Int, y :: Integer)+ .++source-repository head+ type: git+ location: git://github.com/YoshikuniJujo/forest++source-repository this+ type: git+ location: git://github.com/YoshikuniJujo/forest+ tag: bytable-0.0.0.0++library+ hs-source-dirs: src+ exposed-modules: Codec.Bytable, Codec.Bytable.BigEndian+ build-depends: base == 4.*, bytestring == 0.10.*+ ghc-options: -Wall
+ src/Codec/Bytable.hs view
@@ -0,0 +1,45 @@+{-# LANGUAGE TupleSections #-}++module Codec.Bytable (BytableM(..), Bytable(..), head, take, null) where++import Prelude hiding (take, head, null)+import Control.Applicative(Applicative(..), (<$>))+import Control.Monad (unless, liftM, ap)+import Data.Word (Word8)+import qualified Data.ByteString as BS++data BytableM a = BytableM {+ runBytableM :: BS.ByteString -> Either String (a, BS.ByteString) }++instance Monad BytableM where+ return x = BytableM $ \bs -> Right (x, bs)+ BytableM m1 >>= f = BytableM $ \bs -> do+ (x, bs') <- m1 bs+ runBytableM (f x) bs'+ fail = BytableM . const . Left++instance Functor BytableM where+ fmap = liftM++instance Applicative BytableM where+ pure = return+ (<*>) = ap++class Bytable b where+ fromByteString :: BS.ByteString -> Either String b+ toByteString :: b -> BS.ByteString++head :: BytableM Word8+head = BytableM $ \bs -> case BS.uncons bs of+ Just (h, t) -> Right (h, t)+ _ -> Left "Bytable.head: null"++take :: Bytable b => Int -> BytableM b+take n = BytableM $ \bs -> do+ unless (BS.length bs >= n) . Left $+ "Bytable.take: length shorter than " ++ show n+ let (x, bs') = BS.splitAt n bs+ (, bs') <$> fromByteString x++null :: BytableM Bool+null = BytableM $ \bs -> Right (BS.null bs, bs)
+ src/Codec/Bytable/BigEndian.hs view
@@ -0,0 +1,47 @@+{-# OPTIONS_GHC -fno-warn-orphans #-}++module Codec.Bytable.BigEndian () where++import Data.Bits+import Data.Word+import Codec.Bytable+import qualified Data.ByteString as BS++instance Bytable Int where+ fromByteString bs+ | BS.length bs <= 4 = Right $ byteStringToNum bs+ | otherwise = Left+ "Codec.Bytable.BigEndian: Bytable Int: too large"+ toByteString = integralToByteString++instance Bytable Integer where+ fromByteString bs = Right $ byteStringToNum bs+ toByteString = integralToByteString++instance Bytable Word16 where+ fromByteString bs+ | BS.length bs <= 2 = Right $ byteStringToNum bs+ | otherwise = Left+ "Codec.Bytable.BigEndian: Bytable Word16: too large"+ toByteString = integralToByteString++instance Bytable Word32 where+ fromByteString bs+ | BS.length bs <= 4 = Right $ byteStringToNum bs+ | otherwise = Left+ "Codec.Bytable.BigEndian: Bytable Word32: too large"+ toByteString = integralToByteString++byteStringToNum :: (Num n, Bits n) => BS.ByteString -> n+byteStringToNum = wordsToNum . reverse . BS.unpack++wordsToNum :: (Num n, Bits n) => [Word8] -> n+wordsToNum [] = 0+wordsToNum (w : ws) = fromIntegral w .|. wordsToNum ws `shiftL` 8++integralToByteString :: (Integral n, Bits n) => n -> BS.ByteString+integralToByteString = BS.pack . reverse . integralToWords++integralToWords :: (Integral n, Bits n) => n -> [Word8]+integralToWords 0 = []+integralToWords n = fromIntegral n : integralToWords (n `shiftR` 8)