NumLazyByteString (empty) → 0.0.0.1
raw patch · 4 files changed
+194/−0 lines, 4 filesdep +basedep +binarydep +bytestringsetup-changed
Dependencies added: base, binary, bytestring
Files
- Data/ByteString/Lazy/Num.hs +139/−0
- LICENSE +30/−0
- NumLazyByteString.cabal +23/−0
- Setup.hs +2/−0
+ Data/ByteString/Lazy/Num.hs view
@@ -0,0 +1,139 @@+module Data.ByteString.Lazy.Num+ ( numCompare+ , NumBS(..)+ ) where++import qualified Data.ByteString.Lazy as L+import Data.Bits+import Data.Binary (encode)+import Data.List (foldl', mapAccumL)+import Data.Word++data NumBS = NBS {unNBS :: L.ByteString}+ deriving (Eq, Ord, Show)++-- Little Endian ByteStrings+instance Num NumBS where+ a + b = byteStrOp (+) a b+ (*) = asInteger2 (*)+ a - b = byteStrOp (-) a b+ negate a = (NBS $ L.replicate (L.length (unNBS a)) 0) - a+ abs a = a+ signum a = a `seq` NBS (L.pack [1])+ fromInteger i = NBS $ L.pack $ go i []+ where+ go :: Integer -> [Word8] -> [Word8]+ go i acc | i < 0 = L.unpack $ unNBS $ (NBS $ L.pack [0]) - (NBS $ L.pack $ go (-i) acc)+ go 0 acc = reverse acc+ go i acc = go (i `shiftR` 8) (fromIntegral (i .&. 0xFF):acc)++instance Integral NumBS where+ quot = asInteger2 quot+ rem = asInteger2 rem+ div = asInteger2 div+ mod = asInteger2 mod+ quotRem a b =+ let (x,y) = quotRem (fromIntegral a) (fromIntegral b :: Integer)+ in (fromIntegral x, fromIntegral y)+ divMod a b =+ let (x,y) = divMod (fromIntegral a) (fromIntegral b :: Integer)+ in (fromIntegral x, fromIntegral y)+ toInteger (NBS a) = snd $ foldl' acc (0,0) (L.unpack a)+ where+ acc :: (Integer, Integer) -> Word8 -> (Integer, Integer)+ acc (i, tot) n = (i+1, tot + (fromIntegral n `shiftL` fromIntegral (i*8)))+ -- FIXME use of 'Int' in 'shiftL' causes a maxbound issue++instance Real NumBS where+ toRational = toRational . fromIntegral ++instance Enum NumBS where+ succ a = if isMaxBound a then error "succ maxBound" else a + 1+ pred a = if isMinBound a then error "pred minBound" else a - 1+ toEnum i = NBS $ encode i+ fromEnum a = fromIntegral a+ enumFrom a = if isMaxBound a then [a] else a : (enumFrom (succ a))+ enumFromThen start cnt = normalized go start cnt+ where+ go s c =+ if s > (NBS $ L.replicate (L.length (unNBS c)) 0xFF) - c+ then [s]+ else s : enumFromThen (s + c) c+ enumFromTo start end = normalized go start end+ where go s e | numCompare s e == GT = []+ | otherwise =+ if isMaxBound s then [s] else s : enumFromTo (succ s) e+ enumFromThenTo s c e = + takeWhile (\x -> numCompare x e /= GT) (enumFromThen s c)++isMaxBound :: NumBS -> Bool+isMaxBound = L.all (== 0xFF) . unNBS++isMinBound :: NumBS -> Bool+isMinBound = L.all (== 0x0) . unNBS++-- instance Ord L.ByteString where+numCompare a b = + let byteCmp = normalized (\(NBS x) (NBS y) -> reverse (L.zipWith compare x y)) a b+ in case dropWhile (== EQ) byteCmp of+ (LT:_) -> LT+ (GT:_) -> GT+ _ -> EQ++byteStrOp :: (Int -> Int -> Int) -> NumBS -> NumBS -> NumBS+byteStrOp op (NBS a) (NBS b) =+ let (c,ws) = mapAccumL (combWords op) 0 (L.zip a' b')+ in NBS (L.pack ws)+ where+ (a',b') = normalize a b++combWords :: (Int -> Int -> Int) -> Int -> (Word8,Word8) -> (Int, Word8)+combWords op carry (a,b) = (c, fromIntegral r)+ where+ p :: Int+ p = (fromIntegral a `op` fromIntegral b) + carry+ (c,r) = quotRem p 256++normalized :: (NumBS -> NumBS -> a) -> -- The op+ NumBS -> NumBS -> a -- lps to normalize+normalized op a b = let (a', b') = normalize (unNBS a) (unNBS b) in op (NBS a') (NBS b')++normalize :: L.ByteString -> L.ByteString -> (L.ByteString, L.ByteString)+normalize a b = (a',b')+ where+ aPad = L.replicate (L.length b - L.length a) 0+ bPad = L.replicate (L.length a - L.length b) 0+ a' = L.append a aPad+ b' = L.append b bPad++asInteger :: (Integer -> Integer) -> NumBS -> NumBS+asInteger op = fromIntegral . op . fromIntegral++asInteger2 :: (Integer -> Integer -> Integer) ->+ NumBS -> NumBS -> NumBS+asInteger2 op a b = fromIntegral $ fromIntegral a `op` fromIntegral b++instance Bits NumBS where+ (.&.) = normalized (byteStrOp (.&.))+ (.|.) = normalized (byteStrOp (.|.))+ xor = normalized (byteStrOp xor)+ complement (NBS a) = NBS $ L.map complement a+ a `shift` i = asInteger (`shift` i) a+ a `rotate` i = asInteger (`rotate` i) a+ bit i =+ let (d,m) = i `quotRem` 8 + in NBS $ L.snoc (L.replicate (fromIntegral d) 0) (bit m)+ setBit a i = asInteger (`setBit` i) a+ clearBit a i = asInteger (`clearBit` i) a+ complementBit a i = asInteger (`complementBit` i) a+ testBit a i =+ let (d, m) = i `quotRem` 8+ in case L.unpack (L.drop (fromIntegral d) (unNBS a)) of+ [] -> False+ (w:_) -> testBit w m+ bitSize = (*) 8 . fromIntegral . L.length . unNBS+ isSigned _ = False+ shiftL a i = shift a i+ shiftR a i = shift a (-i)+ rotateL a i = rotate a i+ rotateR a i = rotate a (-i)
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) Thomas DuBuisson++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions+are met:++1. Redistributions of source code must retain the above copyright+ notice, this list of conditions and the following disclaimer.++2. 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.++3. Neither the name of the author nor the names of his contributors+ may be used to endorse or promote products derived from this software+ without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE 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 AUTHORS 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.
+ NumLazyByteString.cabal view
@@ -0,0 +1,23 @@+name: NumLazyByteString+version: 0.0.0.1+license: BSD3+license-file: LICENSE+author: Thomas DuBuisson <thomas.dubuisson@gmail.com>+maintainer: Thomas DuBuisson+description: Num, Enum, Eq, Integral, Ord, Real, and Show instances for Lazy ByteStrings+synopsis: Num, Enum, Eq, Integral, Ord, Real, and Show instances for Lazy ByteStrings+category: Data+stability: stable+build-type: Simple+cabal-version: >= 1.6+tested-with: GHC == 6.12.1+extra-source-files: ++Flag small_base+ Description: Choose the split-up base package.++Library+ Build-Depends: base >= 3.0 && <= 6.0, bytestring, binary+ hs-source-dirs:+ exposed-modules: Data.ByteString.Lazy.Num+ ghc-options: -O2 -funfolding-use-threshold66 -funfolding-creation-threshold66 -fexcess-precision -funbox-strict-fields
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain