byteslice (empty) → 0.1.0.0
raw patch · 5 files changed
+146/−0 lines, 5 filesdep +basedep +primitivesetup-changed
Dependencies added: base, primitive
Files
- CHANGELOG.md +5/−0
- LICENSE +30/−0
- Setup.hs +2/−0
- byteslice.cabal +22/−0
- src/Data/Bytes/Types.hs +87/−0
+ CHANGELOG.md view
@@ -0,0 +1,5 @@+# Revision history for byteslice++## 0.1.0.0 -- YYYY-mm-dd++* First version.
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) 2019, Andrew Martin++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 Andrew Martin 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,2 @@+import Distribution.Simple+main = defaultMain
+ byteslice.cabal view
@@ -0,0 +1,22 @@+cabal-version: 2.2+name: byteslice+version: 0.1.0.0+synopsis: Slicing ByteArray and MutableByteArray+-- description:+homepage: https://github.com/andrewthad/byteslice+bug-reports: https://github.com/andrewthad/byteslice/issues+license: BSD-3-Clause+license-file: LICENSE+author: Andrew Martin+maintainer: andrew.thaddeus@gmail.com+copyright: 2019 Andrew Martin+category: Data+extra-source-files: CHANGELOG.md++library+ exposed-modules: Data.Bytes.Types+ build-depends:+ , base >=4.11.1.0 && <5+ , primitive >=0.6.4 && <0.7+ hs-source-dirs: src+ default-language: Haskell2010
+ src/Data/Bytes/Types.hs view
@@ -0,0 +1,87 @@+{-# language BangPatterns #-}+{-# language MagicHash #-}+{-# language TypeFamilies #-}++module Data.Bytes.Types+ ( Bytes(..)+ , MutableBytes(..)+ ) where++import Data.Primitive (ByteArray(..),MutableByteArray(..))+import Data.Bits ((.&.),unsafeShiftR)+import Data.Char (ord)+import Data.Word (Word8)+import GHC.Base (unsafeChr)+import GHC.Exts (Int(I#),unsafeCoerce#,sameMutableByteArray#)+import GHC.Exts (isTrue#,compareByteArrays#,IsList(..))++import qualified Data.List as L+import qualified Data.Primitive as PM++-- | A slice of a 'ByteArray'.+data Bytes = Bytes+ {-# UNPACK #-} !ByteArray -- payload+ {-# UNPACK #-} !Int -- offset+ {-# UNPACK #-} !Int -- length++-- | A slice of a 'MutableByteArray'.+data MutableBytes s = MutableBytes+ {-# UNPACK #-} !(MutableByteArray s) -- payload+ {-# UNPACK #-} !Int -- offset+ {-# UNPACK #-} !Int -- length++instance IsList Bytes where+ type Item Bytes = Word8+ fromListN n xs = Bytes (fromListN n xs) 0 n+ fromList xs = fromListN (L.length xs) xs+ toList (Bytes arr off len) = toListLoop off len arr++toListLoop :: Int -> Int -> ByteArray -> [Word8]+toListLoop !off !len !arr = if len > 0+ then PM.indexByteArray arr off : toListLoop (off + 1) (len - 1) arr+ else []++instance Show Bytes where+ showsPrec d (Bytes arr off len) s = if len == 0+ then showString "[]" s+ else showString "[0x"+ $ showHexDigits (PM.indexByteArray arr off)+ $ showLoop (off + 1) (len - 1) arr+ $ showChar ']'+ $ s++showLoop :: Int -> Int -> ByteArray -> String -> String+showLoop !ix !len !arr s = if len > 0+ then ',':'0':'x':showHexDigits (PM.indexByteArray arr ix) (showLoop (ix + 1) (len - 1) arr s)+ else s++showHexDigits :: Word8 -> String -> String+showHexDigits !w s = word4ToChar (unsafeShiftR w 4) : word4ToChar (0x0F .&. w) : s++word4ToChar :: Word8 -> Char+word4ToChar w = if w < 10+ then unsafeChr (ord '0' + fromIntegral w)+ else unsafeChr (ord 'a' + (fromIntegral w) - 10)++instance Eq Bytes where+ {-# INLINE (==) #-}+ Bytes arr1 off1 len1 == Bytes arr2 off2 len2+ | len1 /= len2 = False+ | sameByteArray arr1 arr2 && off1 == off2 = True+ | otherwise = compareByteArrays arr1 off1 arr2 off2 len1 == EQ++instance Ord Bytes where+ {-# INLINE compare #-}+ compare (Bytes arr1 off1 len1) (Bytes arr2 off2 len2)+ | sameByteArray arr1 arr2 && off1 == off2 && len1 == len2 = EQ+ | otherwise = compareByteArrays arr1 off1 arr2 off2 len1++compareByteArrays :: ByteArray -> Int -> ByteArray -> Int -> Int -> Ordering+{-# INLINE compareByteArrays #-}+compareByteArrays (ByteArray ba1#) (I# off1#) (ByteArray ba2#) (I# off2#) (I# n#) =+ compare (I# (compareByteArrays# ba1# off1# ba2# off2# n#)) 0++sameByteArray :: ByteArray -> ByteArray -> Bool+{-# INLINE sameByteArray #-}+sameByteArray (ByteArray ba1#) (ByteArray ba2#) =+ isTrue# (sameMutableByteArray# (unsafeCoerce# ba1#) (unsafeCoerce# ba2#))