packages feed

haskus-binary 1.4 → 1.5

raw patch · 99 files changed

+9134/−7865 lines, 99 filesdep −primitivePVP ok

version bump matches the API change (PVP)

Dependencies removed: primitive

API changes (from Hackage documentation)

- Haskus.Format.Binary.BitField: BitField :: s -> BitField s
- Haskus.Format.Binary.BitField: BitFields :: b -> BitFields b
- Haskus.Format.Binary.BitField: bitFieldsBits :: BitFields b f -> b
- Haskus.Format.Binary.BitField: class Field f
- Haskus.Format.Binary.BitField: extractField :: forall (name :: Symbol) fields b. (KnownNat (Offset name fields), KnownNat (Size name fields), WholeSize fields ~ BitSize b, Bits b, Integral b, Field (Output name fields)) => BitFields b fields -> Output name fields
- Haskus.Format.Binary.BitField: extractField' :: forall (name :: Symbol) fields b. (KnownNat (Offset name fields), KnownNat (Size name fields), Bits b, Integral b, Field (Output name fields)) => BitFields b fields -> Output name fields
- Haskus.Format.Binary.BitField: instance (GHC.Real.Integral b, Haskus.Format.Binary.Enum.CEnum a) => Haskus.Format.Binary.BitField.Field (Haskus.Format.Binary.Enum.EnumField b a)
- Haskus.Format.Binary.BitField: instance (Haskus.Format.Binary.Bits.Finite.FiniteBits b, GHC.Real.Integral b, Haskus.Format.Binary.BitSet.CBitSet a) => Haskus.Format.Binary.BitField.Field (Haskus.Format.Binary.BitSet.BitSet b a)
- Haskus.Format.Binary.BitField: instance (bs Data.Type.Equality.~ Haskus.Format.Binary.BitField.BitFields w l, b Data.Type.Equality.~ Haskus.Format.Binary.BitField.BitField n name s, i Data.Type.Equality.~ (bs, Haskus.Utils.HList.HList l2), r Data.Type.Equality.~ (bs, Haskus.Utils.HList.HList (Haskus.Format.Binary.BitField.Output name l : l2)), Haskus.Format.Binary.Bits.Finite.BitSize w Data.Type.Equality.~ Haskus.Format.Binary.BitField.WholeSize l, GHC.Real.Integral w, Haskus.Format.Binary.Bits.Bits w, GHC.TypeNats.KnownNat (Haskus.Format.Binary.BitField.Offset name l), GHC.TypeNats.KnownNat (Haskus.Format.Binary.BitField.Size name l), Haskus.Format.Binary.BitField.Field (Haskus.Format.Binary.BitField.Output name l)) => Haskus.Utils.HList.Apply Haskus.Format.Binary.BitField.Extract (b, i) r
- Haskus.Format.Binary.BitField: instance (bs Data.Type.Equality.~ Haskus.Format.Binary.BitField.BitFields w l, b Data.Type.Equality.~ Haskus.Format.Binary.BitField.BitField n name s, i Data.Type.Equality.~ Haskus.Utils.HList.HList l2, r Data.Type.Equality.~ Haskus.Utils.HList.HList (GHC.Base.String : l2), GHC.TypeLits.KnownSymbol name) => Haskus.Utils.HList.Apply Haskus.Format.Binary.BitField.Name (b, i) r
- Haskus.Format.Binary.BitField: instance (bs Data.Type.Equality.~ Haskus.Format.Binary.BitField.BitFields w lt, Haskus.Utils.HList.HFoldr' Haskus.Format.Binary.BitField.Extract (bs, Haskus.Utils.HList.HList '[]) lt (bs, Haskus.Utils.HList.HList lt2), GHC.Classes.Eq (Haskus.Utils.HList.HList lt2), lt2 Data.Type.Equality.~ Haskus.Format.Binary.BitField.BitFieldTypes lt) => GHC.Classes.Eq (Haskus.Format.Binary.BitField.BitFields w lt)
- Haskus.Format.Binary.BitField: instance (bs Data.Type.Equality.~ Haskus.Format.Binary.BitField.BitFields w lt, ln Data.Type.Equality.~ Haskus.Utils.Types.List.Replicate (Haskus.Utils.Types.List.Length lt) GHC.Base.String, Haskus.Utils.HList.HFoldr' Haskus.Format.Binary.BitField.Extract (bs, Haskus.Utils.HList.HList '[]) lt (bs, Haskus.Utils.HList.HList (Haskus.Format.Binary.BitField.BitFieldTypes lt)), Haskus.Utils.HList.HFoldr' Haskus.Format.Binary.BitField.Name (Haskus.Utils.HList.HList '[]) lt (Haskus.Utils.HList.HList ln), Haskus.Utils.HList.HZipList ln (Haskus.Format.Binary.BitField.BitFieldTypes lt) lnv, GHC.Show.Show (Haskus.Utils.HList.HList lnv)) => GHC.Show.Show (Haskus.Format.Binary.BitField.BitFields w lt)
- Haskus.Format.Binary.BitField: instance Haskus.Format.Binary.BitField.Field GHC.Int.Int16
- Haskus.Format.Binary.BitField: instance Haskus.Format.Binary.BitField.Field GHC.Int.Int32
- Haskus.Format.Binary.BitField: instance Haskus.Format.Binary.BitField.Field GHC.Int.Int64
- Haskus.Format.Binary.BitField: instance Haskus.Format.Binary.BitField.Field GHC.Int.Int8
- Haskus.Format.Binary.BitField: instance Haskus.Format.Binary.BitField.Field GHC.Types.Bool
- Haskus.Format.Binary.BitField: instance Haskus.Format.Binary.BitField.Field GHC.Types.Int
- Haskus.Format.Binary.BitField: instance Haskus.Format.Binary.BitField.Field GHC.Types.Word
- Haskus.Format.Binary.BitField: instance Haskus.Format.Binary.BitField.Field GHC.Word.Word16
- Haskus.Format.Binary.BitField: instance Haskus.Format.Binary.BitField.Field GHC.Word.Word32
- Haskus.Format.Binary.BitField: instance Haskus.Format.Binary.BitField.Field GHC.Word.Word64
- Haskus.Format.Binary.BitField: instance Haskus.Format.Binary.BitField.Field GHC.Word.Word8
- Haskus.Format.Binary.BitField: instance Haskus.Format.Binary.Storable.Storable b => Haskus.Format.Binary.Storable.Storable (Haskus.Format.Binary.BitField.BitFields b f)
- Haskus.Format.Binary.BitField: instance Haskus.Format.Binary.Storable.Storable s => Haskus.Format.Binary.Storable.Storable (Haskus.Format.Binary.BitField.BitField n name s)
- Haskus.Format.Binary.BitField: matchFields :: forall l l2 w bs t. (bs ~ BitFields w l, HFoldr' Extract (bs, HList '[]) l (bs, HList l2), HTuple' l2 t) => bs -> t
- Haskus.Format.Binary.BitField: matchNamedFields :: forall lt lv ln lnv w bs t. (bs ~ BitFields w lt, HFoldr' Extract (bs, HList '[]) lt (bs, HList lv), HFoldr' Name (HList '[]) lt (HList ln), HZipList ln lv lnv, HTuple' lnv t) => bs -> t
- Haskus.Format.Binary.BitField: newtype BitField (n :: Nat) (name :: Symbol) s
- Haskus.Format.Binary.BitField: newtype BitFields b (f :: [*])
- Haskus.Format.Binary.BitField: updateField :: forall name fields b. (KnownNat (Offset name fields), KnownNat (Size name fields), WholeSize fields ~ BitSize b, Bits b, Integral b, Field (Output name fields)) => Output name fields -> BitFields b fields -> BitFields b fields
- Haskus.Format.Binary.BitField: updateField' :: forall name fields b. (KnownNat (Offset name fields), KnownNat (Size name fields), Bits b, Integral b, Field (Output name fields)) => Output name fields -> BitFields b fields -> BitFields b fields
- Haskus.Format.Binary.BitField: withField :: forall name fields b f. (KnownNat (Offset name fields), KnownNat (Size name fields), WholeSize fields ~ BitSize b, Bits b, Integral b, f ~ Output name fields, Field f) => (f -> f) -> BitFields b fields -> BitFields b fields
- Haskus.Format.Binary.BitField: withField' :: forall (name :: Symbol) fields b f. (KnownNat (Offset name fields), KnownNat (Size name fields), Bits b, Integral b, f ~ Output name fields, Field f) => (f -> f) -> BitFields b fields -> BitFields b fields
- Haskus.Format.Binary.BitSet: class CBitSet a
- Haskus.Format.Binary.BitSet: data BitSet b a
- Haskus.Format.Binary.BitSet: delete :: (IndexableBits b, CBitSet a) => BitSet b a -> a -> BitSet b a
- Haskus.Format.Binary.BitSet: elem :: (CBitSet a, FiniteBits b, IndexableBits b) => a -> BitSet b a -> Bool
- Haskus.Format.Binary.BitSet: elems :: (CBitSet a, FiniteBits b, IndexableBits b, Eq b) => BitSet b a -> [a]
- Haskus.Format.Binary.BitSet: empty :: FiniteBits b => BitSet b a
- Haskus.Format.Binary.BitSet: enumerateSetBits :: (CBitSet a, FiniteBits b, IndexableBits b, Eq b, Bounded a, Enum a) => b -> [a]
- Haskus.Format.Binary.BitSet: fromBitOffset :: (CBitSet a, Enum a) => Word -> a
- Haskus.Format.Binary.BitSet: fromBits :: (CBitSet a, FiniteBits b) => b -> BitSet b a
- Haskus.Format.Binary.BitSet: fromList :: (CBitSet a, IndexableBits b, FiniteBits b, Foldable m) => m a -> BitSet b a
- Haskus.Format.Binary.BitSet: fromListToBits :: (CBitSet a, FiniteBits b, IndexableBits b, Foldable m) => m a -> b
- Haskus.Format.Binary.BitSet: insert :: (IndexableBits b, CBitSet a) => BitSet b a -> a -> BitSet b a
- Haskus.Format.Binary.BitSet: instance (GHC.Show.Show a, Haskus.Format.Binary.BitSet.CBitSet a, Haskus.Format.Binary.Bits.Finite.FiniteBits b, Haskus.Format.Binary.Bits.Index.IndexableBits b, GHC.Classes.Eq b) => GHC.Show.Show (Haskus.Format.Binary.BitSet.BitSet b a)
- Haskus.Format.Binary.BitSet: instance (Haskus.Format.Binary.Bits.Finite.FiniteBits b, Haskus.Format.Binary.Bits.Index.IndexableBits b, Haskus.Format.Binary.BitSet.CBitSet a, GHC.Classes.Eq b) => GHC.Exts.IsList (Haskus.Format.Binary.BitSet.BitSet b a)
- Haskus.Format.Binary.BitSet: instance GHC.Classes.Eq b => GHC.Classes.Eq (Haskus.Format.Binary.BitSet.BitSet b a)
- Haskus.Format.Binary.BitSet: instance GHC.Classes.Ord b => GHC.Classes.Ord (Haskus.Format.Binary.BitSet.BitSet b a)
- Haskus.Format.Binary.BitSet: instance Haskus.Format.Binary.BitSet.CBitSet GHC.Types.Int
- Haskus.Format.Binary.BitSet: instance Haskus.Format.Binary.BitSet.CBitSet GHC.Types.Word
- Haskus.Format.Binary.BitSet: instance Haskus.Format.Binary.Storable.Storable b => Haskus.Format.Binary.Storable.Storable (Haskus.Format.Binary.BitSet.BitSet b a)
- Haskus.Format.Binary.BitSet: intersection :: (FiniteBits b, Bitwise b) => BitSet b a -> BitSet b a -> BitSet b a
- Haskus.Format.Binary.BitSet: member :: (CBitSet a, FiniteBits b, IndexableBits b) => BitSet b a -> a -> Bool
- Haskus.Format.Binary.BitSet: notMember :: (CBitSet a, FiniteBits b, IndexableBits b) => BitSet b a -> a -> Bool
- Haskus.Format.Binary.BitSet: null :: (FiniteBits b, Eq b) => BitSet b a -> Bool
- Haskus.Format.Binary.BitSet: singleton :: (IndexableBits b, CBitSet a) => a -> BitSet b a
- Haskus.Format.Binary.BitSet: toBitOffset :: (CBitSet a, Enum a) => a -> Word
- Haskus.Format.Binary.BitSet: toBits :: BitSet b a -> b
- Haskus.Format.Binary.BitSet: toList :: (CBitSet a, FiniteBits b, IndexableBits b, Eq b) => BitSet b a -> [a]
- Haskus.Format.Binary.BitSet: toListFromBits :: (CBitSet a, FiniteBits b, IndexableBits b, Eq b) => b -> [a]
- Haskus.Format.Binary.BitSet: union :: (FiniteBits b, Bitwise b) => BitSet b a -> BitSet b a -> BitSet b a
- Haskus.Format.Binary.BitSet: unions :: (FiniteBits b, Bitwise b) => [BitSet b a] -> BitSet b a
- Haskus.Format.Binary.Bits: (.&.) :: Bitwise a => a -> a -> a
- Haskus.Format.Binary.Bits: (.|.) :: Bitwise a => a -> a -> a
- Haskus.Format.Binary.Bits: -- | Number of bits
- Haskus.Format.Binary.Bits: bit :: (IndexableBits a, Num a, ShiftableBits a) => Word -> a
- Haskus.Format.Binary.Bits: bitOffset :: Word -> Word
- Haskus.Format.Binary.Bits: bitSize :: (FiniteBits a, Integral i, KnownNat (BitSize a)) => a -> i
- Haskus.Format.Binary.Bits: bitsFromString :: Bits a => String -> a
- Haskus.Format.Binary.Bits: bitsToString :: forall a. (FiniteBits a, IndexableBits a, KnownNat (BitSize a)) => a -> String
- Haskus.Format.Binary.Bits: bitsToStringN :: forall a. IndexableBits a => Word -> a -> String
- Haskus.Format.Binary.Bits: byteOffset :: Word -> Word
- Haskus.Format.Binary.Bits: class Bitwise a
- Haskus.Format.Binary.Bits: class FiniteBits a where {
- Haskus.Format.Binary.Bits: class IndexableBits a
- Haskus.Format.Binary.Bits: class MaskBits a
- Haskus.Format.Binary.Bits: class ReversableBits w
- Haskus.Format.Binary.Bits: class RotatableBits a
- Haskus.Format.Binary.Bits: class ShiftableBits a
- Haskus.Format.Binary.Bits: class SignedShiftableBits a
- Haskus.Format.Binary.Bits: clearBit :: (IndexableBits a, FiniteBits a, Bitwise a) => a -> Word -> a
- Haskus.Format.Binary.Bits: complement :: FiniteBits a => a -> a
- Haskus.Format.Binary.Bits: complementBit :: (IndexableBits a, Bitwise a) => a -> Word -> a
- Haskus.Format.Binary.Bits: countLeadingZeros :: FiniteBits a => a -> Word
- Haskus.Format.Binary.Bits: countTrailingZeros :: FiniteBits a => a -> Word
- Haskus.Format.Binary.Bits: getBitRange :: forall b. (ShiftableBits b, ReversableBits b, FiniteBits b, KnownNat (BitSize b), Bitwise b, MaskBits b) => BitOrder -> Word -> Word -> b -> b
- Haskus.Format.Binary.Bits: makeMaskDyn :: MaskBits a => Word -> a
- Haskus.Format.Binary.Bits: mask :: forall n a. Maskable n a => a -> a
- Haskus.Format.Binary.Bits: maskDyn :: (MaskBits a, Bitwise a) => Word -> a -> a
- Haskus.Format.Binary.Bits: oneBits :: FiniteBits a => a
- Haskus.Format.Binary.Bits: popCount :: (IndexableBits a, Bitwise a, Num a, Eq a) => a -> Word
- Haskus.Format.Binary.Bits: reverseBits :: ReversableBits w => w -> w
- Haskus.Format.Binary.Bits: reverseBitsGeneric :: (FiniteBits a, Integral a, ShiftableBits a, Bitwise a, KnownNat (BitSize a)) => a -> a
- Haskus.Format.Binary.Bits: reverseLeastBits :: (ShiftableBits a, FiniteBits a, ReversableBits a, KnownNat (BitSize a)) => Word -> a -> a
- Haskus.Format.Binary.Bits: rotate :: (RotatableBits a, FiniteBits a, KnownNat (BitSize a)) => a -> Int -> a
- Haskus.Format.Binary.Bits: rotateL :: (RotatableBits a, FiniteBits a, KnownNat (BitSize a)) => a -> Word -> a
- Haskus.Format.Binary.Bits: rotateR :: (RotatableBits a, FiniteBits a, KnownNat (BitSize a)) => a -> Word -> a
- Haskus.Format.Binary.Bits: setBit :: (IndexableBits a, Bitwise a) => a -> Word -> a
- Haskus.Format.Binary.Bits: shift :: ShiftableBits a => a -> Int -> a
- Haskus.Format.Binary.Bits: shiftL :: ShiftableBits a => a -> Word -> a
- Haskus.Format.Binary.Bits: shiftR :: ShiftableBits a => a -> Word -> a
- Haskus.Format.Binary.Bits: signedShift :: SignedShiftableBits a => a -> Int -> a
- Haskus.Format.Binary.Bits: signedShiftL :: SignedShiftableBits a => a -> Word -> a
- Haskus.Format.Binary.Bits: signedShiftR :: SignedShiftableBits a => a -> Word -> a
- Haskus.Format.Binary.Bits: testBit :: (IndexableBits a, Bitwise a, Num a, Eq a) => a -> Word -> Bool
- Haskus.Format.Binary.Bits: type Bits a = (Eq a, FiniteBits a, IndexableBits a, ShiftableBits a, Bitwise a, RotatableBits a, KnownNat (BitSize a), MaskBits a)
- Haskus.Format.Binary.Bits: type Maskable n a = (MaskBits a, Bitwise a, KnownNat n)
- Haskus.Format.Binary.Bits: type family BitSize a :: Nat;
- Haskus.Format.Binary.Bits: uncheckedRotate :: RotatableBits a => a -> Int -> a
- Haskus.Format.Binary.Bits: uncheckedRotateL :: (RotatableBits a, ShiftableBits a, FiniteBits a, KnownNat (BitSize a), Bitwise a) => a -> Word -> a
- Haskus.Format.Binary.Bits: uncheckedRotateR :: (RotatableBits a, ShiftableBits a, FiniteBits a, KnownNat (BitSize a), Bitwise a) => a -> Word -> a
- Haskus.Format.Binary.Bits: uncheckedShift :: ShiftableBits a => a -> Int -> a
- Haskus.Format.Binary.Bits: uncheckedShiftL :: ShiftableBits a => a -> Word -> a
- Haskus.Format.Binary.Bits: uncheckedShiftR :: ShiftableBits a => a -> Word -> a
- Haskus.Format.Binary.Bits: uncheckedSignedShift :: SignedShiftableBits a => a -> Int -> a
- Haskus.Format.Binary.Bits: uncheckedSignedShiftL :: SignedShiftableBits a => a -> Word -> a
- Haskus.Format.Binary.Bits: uncheckedSignedShiftR :: SignedShiftableBits a => a -> Word -> a
- Haskus.Format.Binary.Bits: xor :: Bitwise a => a -> a -> a
- Haskus.Format.Binary.Bits: zeroBits :: FiniteBits a => a
- Haskus.Format.Binary.Bits: }
- Haskus.Format.Binary.Bits.Bitwise: (.&.) :: Bitwise a => a -> a -> a
- Haskus.Format.Binary.Bits.Bitwise: (.|.) :: Bitwise a => a -> a -> a
- Haskus.Format.Binary.Bits.Bitwise: class Bitwise a
- Haskus.Format.Binary.Bits.Bitwise: instance Haskus.Format.Binary.Bits.Bitwise.Bitwise GHC.Int.Int16
- Haskus.Format.Binary.Bits.Bitwise: instance Haskus.Format.Binary.Bits.Bitwise.Bitwise GHC.Int.Int32
- Haskus.Format.Binary.Bits.Bitwise: instance Haskus.Format.Binary.Bits.Bitwise.Bitwise GHC.Int.Int64
- Haskus.Format.Binary.Bits.Bitwise: instance Haskus.Format.Binary.Bits.Bitwise.Bitwise GHC.Int.Int8
- Haskus.Format.Binary.Bits.Bitwise: instance Haskus.Format.Binary.Bits.Bitwise.Bitwise GHC.Integer.Type.Integer
- Haskus.Format.Binary.Bits.Bitwise: instance Haskus.Format.Binary.Bits.Bitwise.Bitwise GHC.Natural.Natural
- Haskus.Format.Binary.Bits.Bitwise: instance Haskus.Format.Binary.Bits.Bitwise.Bitwise GHC.Types.Int
- Haskus.Format.Binary.Bits.Bitwise: instance Haskus.Format.Binary.Bits.Bitwise.Bitwise GHC.Types.Word
- Haskus.Format.Binary.Bits.Bitwise: instance Haskus.Format.Binary.Bits.Bitwise.Bitwise GHC.Word.Word16
- Haskus.Format.Binary.Bits.Bitwise: instance Haskus.Format.Binary.Bits.Bitwise.Bitwise GHC.Word.Word32
- Haskus.Format.Binary.Bits.Bitwise: instance Haskus.Format.Binary.Bits.Bitwise.Bitwise GHC.Word.Word64
- Haskus.Format.Binary.Bits.Bitwise: instance Haskus.Format.Binary.Bits.Bitwise.Bitwise GHC.Word.Word8
- Haskus.Format.Binary.Bits.Bitwise: xor :: Bitwise a => a -> a -> a
- Haskus.Format.Binary.Bits.Finite: -- | Number of bits
- Haskus.Format.Binary.Bits.Finite: bitSize :: (FiniteBits a, Integral i, KnownNat (BitSize a)) => a -> i
- Haskus.Format.Binary.Bits.Finite: class FiniteBits a where {
- Haskus.Format.Binary.Bits.Finite: complement :: FiniteBits a => a -> a
- Haskus.Format.Binary.Bits.Finite: countLeadingZeros :: FiniteBits a => a -> Word
- Haskus.Format.Binary.Bits.Finite: countTrailingZeros :: FiniteBits a => a -> Word
- Haskus.Format.Binary.Bits.Finite: instance Haskus.Format.Binary.Bits.Finite.FiniteBits GHC.Int.Int16
- Haskus.Format.Binary.Bits.Finite: instance Haskus.Format.Binary.Bits.Finite.FiniteBits GHC.Int.Int32
- Haskus.Format.Binary.Bits.Finite: instance Haskus.Format.Binary.Bits.Finite.FiniteBits GHC.Int.Int64
- Haskus.Format.Binary.Bits.Finite: instance Haskus.Format.Binary.Bits.Finite.FiniteBits GHC.Int.Int8
- Haskus.Format.Binary.Bits.Finite: instance Haskus.Format.Binary.Bits.Finite.FiniteBits GHC.Types.Int
- Haskus.Format.Binary.Bits.Finite: instance Haskus.Format.Binary.Bits.Finite.FiniteBits GHC.Types.Word
- Haskus.Format.Binary.Bits.Finite: instance Haskus.Format.Binary.Bits.Finite.FiniteBits GHC.Word.Word16
- Haskus.Format.Binary.Bits.Finite: instance Haskus.Format.Binary.Bits.Finite.FiniteBits GHC.Word.Word32
- Haskus.Format.Binary.Bits.Finite: instance Haskus.Format.Binary.Bits.Finite.FiniteBits GHC.Word.Word64
- Haskus.Format.Binary.Bits.Finite: instance Haskus.Format.Binary.Bits.Finite.FiniteBits GHC.Word.Word8
- Haskus.Format.Binary.Bits.Finite: oneBits :: FiniteBits a => a
- Haskus.Format.Binary.Bits.Finite: type family BitSize a :: Nat;
- Haskus.Format.Binary.Bits.Finite: zeroBits :: FiniteBits a => a
- Haskus.Format.Binary.Bits.Finite: }
- Haskus.Format.Binary.Bits.Get: BitGetState :: {-# UNPACK #-} !Buffer -> {-# UNPACK #-} !Word -> !BitOrder -> BitGetState
- Haskus.Format.Binary.Bits.Get: [bitGetStateBitOffset] :: BitGetState -> {-# UNPACK #-} !Word
- Haskus.Format.Binary.Bits.Get: [bitGetStateBitOrder] :: BitGetState -> !BitOrder
- Haskus.Format.Binary.Bits.Get: [bitGetStateInput] :: BitGetState -> {-# UNPACK #-} !Buffer
- Haskus.Format.Binary.Bits.Get: changeBitGetOrder :: Monad m => BitOrder -> BitGetT m ()
- Haskus.Format.Binary.Bits.Get: data BitGetState
- Haskus.Format.Binary.Bits.Get: getBitBoolM :: Monad m => BitGetT m Bool
- Haskus.Format.Binary.Bits.Get: getBits :: (Integral a, Bits a) => Word -> BitGetState -> a
- Haskus.Format.Binary.Bits.Get: getBitsBSM :: Monad m => Word -> BitGetT m Buffer
- Haskus.Format.Binary.Bits.Get: getBitsBuffer :: Word -> BitGetState -> Buffer
- Haskus.Format.Binary.Bits.Get: getBitsChecked :: (Integral a, Bits a, ReversableBits a) => Word -> Word -> BitGetState -> a
- Haskus.Format.Binary.Bits.Get: getBitsCheckedM :: (Integral a, Bits a, ReversableBits a, Monad m) => Word -> Word -> BitGetT m a
- Haskus.Format.Binary.Bits.Get: getBitsM :: (Integral a, Bits a, Monad m) => Word -> BitGetT m a
- Haskus.Format.Binary.Bits.Get: instance GHC.Show.Show Haskus.Format.Binary.Bits.Get.BitGetState
- Haskus.Format.Binary.Bits.Get: isEmpty :: BitGetState -> Bool
- Haskus.Format.Binary.Bits.Get: isEmptyM :: Monad m => BitGetT m Bool
- Haskus.Format.Binary.Bits.Get: newBitGetState :: BitOrder -> Buffer -> BitGetState
- Haskus.Format.Binary.Bits.Get: resumeBitGetPartial :: BitGet a -> BitGetState -> (a, BitGetState)
- Haskus.Format.Binary.Bits.Get: resumeBitGetPartialT :: BitGetT m a -> BitGetState -> m (a, BitGetState)
- Haskus.Format.Binary.Bits.Get: runBitGet :: BitOrder -> BitGet a -> Buffer -> a
- Haskus.Format.Binary.Bits.Get: runBitGetPartial :: BitOrder -> BitGet a -> Buffer -> (a, BitGetState)
- Haskus.Format.Binary.Bits.Get: runBitGetPartialT :: BitOrder -> BitGetT m a -> Buffer -> m (a, BitGetState)
- Haskus.Format.Binary.Bits.Get: runBitGetT :: Monad m => BitOrder -> BitGetT m a -> Buffer -> m a
- Haskus.Format.Binary.Bits.Get: skipBits :: Word -> BitGetState -> BitGetState
- Haskus.Format.Binary.Bits.Get: skipBitsM :: Monad m => Word -> BitGetT m ()
- Haskus.Format.Binary.Bits.Get: skipBitsToAlignOnWord8 :: BitGetState -> BitGetState
- Haskus.Format.Binary.Bits.Get: skipBitsToAlignOnWord8M :: Monad m => BitGetT m ()
- Haskus.Format.Binary.Bits.Get: type BitGet a = BitGetT Identity a
- Haskus.Format.Binary.Bits.Get: type BitGetT m a = StateT BitGetState m a
- Haskus.Format.Binary.Bits.Get: withBitGetOrder :: Monad m => BitOrder -> BitGetT m a -> BitGetT m a
- Haskus.Format.Binary.Bits.Helper: bitOffset :: Word -> Word
- Haskus.Format.Binary.Bits.Helper: byteOffset :: Word -> Word
- Haskus.Format.Binary.Bits.Index: bit :: (IndexableBits a, Num a, ShiftableBits a) => Word -> a
- Haskus.Format.Binary.Bits.Index: class IndexableBits a
- Haskus.Format.Binary.Bits.Index: clearBit :: (IndexableBits a, FiniteBits a, Bitwise a) => a -> Word -> a
- Haskus.Format.Binary.Bits.Index: complementBit :: (IndexableBits a, Bitwise a) => a -> Word -> a
- Haskus.Format.Binary.Bits.Index: instance Haskus.Format.Binary.Bits.Index.IndexableBits GHC.Int.Int16
- Haskus.Format.Binary.Bits.Index: instance Haskus.Format.Binary.Bits.Index.IndexableBits GHC.Int.Int32
- Haskus.Format.Binary.Bits.Index: instance Haskus.Format.Binary.Bits.Index.IndexableBits GHC.Int.Int64
- Haskus.Format.Binary.Bits.Index: instance Haskus.Format.Binary.Bits.Index.IndexableBits GHC.Int.Int8
- Haskus.Format.Binary.Bits.Index: instance Haskus.Format.Binary.Bits.Index.IndexableBits GHC.Types.Int
- Haskus.Format.Binary.Bits.Index: instance Haskus.Format.Binary.Bits.Index.IndexableBits GHC.Types.Word
- Haskus.Format.Binary.Bits.Index: instance Haskus.Format.Binary.Bits.Index.IndexableBits GHC.Word.Word16
- Haskus.Format.Binary.Bits.Index: instance Haskus.Format.Binary.Bits.Index.IndexableBits GHC.Word.Word32
- Haskus.Format.Binary.Bits.Index: instance Haskus.Format.Binary.Bits.Index.IndexableBits GHC.Word.Word64
- Haskus.Format.Binary.Bits.Index: instance Haskus.Format.Binary.Bits.Index.IndexableBits GHC.Word.Word8
- Haskus.Format.Binary.Bits.Index: popCount :: (IndexableBits a, Bitwise a, Num a, Eq a) => a -> Word
- Haskus.Format.Binary.Bits.Index: setBit :: (IndexableBits a, Bitwise a) => a -> Word -> a
- Haskus.Format.Binary.Bits.Index: testBit :: (IndexableBits a, Bitwise a, Num a, Eq a) => a -> Word -> Bool
- Haskus.Format.Binary.Bits.Mask: class MaskBits a
- Haskus.Format.Binary.Bits.Mask: instance Haskus.Format.Binary.Bits.Mask.MaskBits GHC.Int.Int16
- Haskus.Format.Binary.Bits.Mask: instance Haskus.Format.Binary.Bits.Mask.MaskBits GHC.Int.Int32
- Haskus.Format.Binary.Bits.Mask: instance Haskus.Format.Binary.Bits.Mask.MaskBits GHC.Int.Int64
- Haskus.Format.Binary.Bits.Mask: instance Haskus.Format.Binary.Bits.Mask.MaskBits GHC.Int.Int8
- Haskus.Format.Binary.Bits.Mask: instance Haskus.Format.Binary.Bits.Mask.MaskBits GHC.Natural.Natural
- Haskus.Format.Binary.Bits.Mask: instance Haskus.Format.Binary.Bits.Mask.MaskBits GHC.Types.Int
- Haskus.Format.Binary.Bits.Mask: instance Haskus.Format.Binary.Bits.Mask.MaskBits GHC.Types.Word
- Haskus.Format.Binary.Bits.Mask: instance Haskus.Format.Binary.Bits.Mask.MaskBits GHC.Word.Word16
- Haskus.Format.Binary.Bits.Mask: instance Haskus.Format.Binary.Bits.Mask.MaskBits GHC.Word.Word32
- Haskus.Format.Binary.Bits.Mask: instance Haskus.Format.Binary.Bits.Mask.MaskBits GHC.Word.Word64
- Haskus.Format.Binary.Bits.Mask: instance Haskus.Format.Binary.Bits.Mask.MaskBits GHC.Word.Word8
- Haskus.Format.Binary.Bits.Mask: makeMask :: forall n a. (KnownNat n, MaskBits a) => a
- Haskus.Format.Binary.Bits.Mask: makeMaskDyn :: MaskBits a => Word -> a
- Haskus.Format.Binary.Bits.Mask: makeMaskFinite :: forall a. (ShiftableBits a, FiniteBits a, KnownNat (BitSize a), Bitwise a) => Word -> a
- Haskus.Format.Binary.Bits.Mask: mask :: forall n a. Maskable n a => a -> a
- Haskus.Format.Binary.Bits.Mask: maskDyn :: (MaskBits a, Bitwise a) => Word -> a -> a
- Haskus.Format.Binary.Bits.Mask: type Maskable n a = (MaskBits a, Bitwise a, KnownNat n)
- Haskus.Format.Binary.Bits.Order: BB :: BitOrder
- Haskus.Format.Binary.Bits.Order: BL :: BitOrder
- Haskus.Format.Binary.Bits.Order: LB :: BitOrder
- Haskus.Format.Binary.Bits.Order: LL :: BitOrder
- Haskus.Format.Binary.Bits.Order: data BitOrder
- Haskus.Format.Binary.Bits.Order: instance GHC.Classes.Eq Haskus.Format.Binary.Bits.Order.BitOrder
- Haskus.Format.Binary.Bits.Order: instance GHC.Show.Show Haskus.Format.Binary.Bits.Order.BitOrder
- Haskus.Format.Binary.Bits.Put: BitPutState :: !BufferBuilder -> !Word8 -> !Word -> !BitOrder -> BitPutState
- Haskus.Format.Binary.Bits.Put: [bitPutStateBitOrder] :: BitPutState -> !BitOrder
- Haskus.Format.Binary.Bits.Put: [bitPutStateBuilder] :: BitPutState -> !BufferBuilder
- Haskus.Format.Binary.Bits.Put: [bitPutStateCurrent] :: BitPutState -> !Word8
- Haskus.Format.Binary.Bits.Put: [bitPutStateOffset] :: BitPutState -> !Word
- Haskus.Format.Binary.Bits.Put: changeBitPutOrder :: Monad m => BitOrder -> BitPutT m ()
- Haskus.Format.Binary.Bits.Put: data BitPutState
- Haskus.Format.Binary.Bits.Put: getBitPutBuffer :: BitPutState -> Buffer
- Haskus.Format.Binary.Bits.Put: getBitPutBufferList :: BitPutState -> BufferList
- Haskus.Format.Binary.Bits.Put: newBitPutState :: BitOrder -> BitPutState
- Haskus.Format.Binary.Bits.Put: putBitBoolM :: Monad m => Bool -> BitPutT m ()
- Haskus.Format.Binary.Bits.Put: putBits :: (Integral a, Bits a, ReversableBits a) => Word -> a -> BitPutState -> BitPutState
- Haskus.Format.Binary.Bits.Put: putBitsBuffer :: Buffer -> BitPutState -> BitPutState
- Haskus.Format.Binary.Bits.Put: putBitsBufferM :: Monad m => Buffer -> BitPutT m ()
- Haskus.Format.Binary.Bits.Put: putBitsM :: (Monad m, Integral a, Bits a, ReversableBits a) => Word -> a -> BitPutT m ()
- Haskus.Format.Binary.Bits.Put: runBitPut :: BitOrder -> BitPut a -> Buffer
- Haskus.Format.Binary.Bits.Put: runBitPutT :: Monad m => BitOrder -> BitPutT m a -> m Buffer
- Haskus.Format.Binary.Bits.Put: type BitPut a = BitPutT Identity a
- Haskus.Format.Binary.Bits.Put: type BitPutT m a = StateT BitPutState m a
- Haskus.Format.Binary.Bits.Put: withBitPutOrder :: Monad m => BitOrder -> BitPutT m a -> BitPutT m a
- Haskus.Format.Binary.Bits.Reverse: class ReversableBits w
- Haskus.Format.Binary.Bits.Reverse: instance Haskus.Format.Binary.Bits.Reverse.ReversableBits GHC.Int.Int16
- Haskus.Format.Binary.Bits.Reverse: instance Haskus.Format.Binary.Bits.Reverse.ReversableBits GHC.Int.Int32
- Haskus.Format.Binary.Bits.Reverse: instance Haskus.Format.Binary.Bits.Reverse.ReversableBits GHC.Int.Int64
- Haskus.Format.Binary.Bits.Reverse: instance Haskus.Format.Binary.Bits.Reverse.ReversableBits GHC.Int.Int8
- Haskus.Format.Binary.Bits.Reverse: instance Haskus.Format.Binary.Bits.Reverse.ReversableBits GHC.Types.Int
- Haskus.Format.Binary.Bits.Reverse: instance Haskus.Format.Binary.Bits.Reverse.ReversableBits GHC.Types.Word
- Haskus.Format.Binary.Bits.Reverse: instance Haskus.Format.Binary.Bits.Reverse.ReversableBits GHC.Word.Word16
- Haskus.Format.Binary.Bits.Reverse: instance Haskus.Format.Binary.Bits.Reverse.ReversableBits GHC.Word.Word32
- Haskus.Format.Binary.Bits.Reverse: instance Haskus.Format.Binary.Bits.Reverse.ReversableBits GHC.Word.Word64
- Haskus.Format.Binary.Bits.Reverse: instance Haskus.Format.Binary.Bits.Reverse.ReversableBits GHC.Word.Word8
- Haskus.Format.Binary.Bits.Reverse: liftReverseBits :: (ShiftableBits a, Bitwise a, FiniteBits a, Integral a, KnownNat (BitSize a)) => (Word8 -> Word8) -> a -> a
- Haskus.Format.Binary.Bits.Reverse: reverseBits :: ReversableBits w => w -> w
- Haskus.Format.Binary.Bits.Reverse: reverseBits3Ops :: Word8 -> Word8
- Haskus.Format.Binary.Bits.Reverse: reverseBits4Ops :: Word8 -> Word8
- Haskus.Format.Binary.Bits.Reverse: reverseBits5LgN :: forall a. (FiniteBits a, ShiftableBits a, Bitwise a, KnownNat (BitSize a)) => a -> a
- Haskus.Format.Binary.Bits.Reverse: reverseBits7Ops :: Word8 -> Word8
- Haskus.Format.Binary.Bits.Reverse: reverseBitsGeneric :: (FiniteBits a, Integral a, ShiftableBits a, Bitwise a, KnownNat (BitSize a)) => a -> a
- Haskus.Format.Binary.Bits.Reverse: reverseBitsObvious :: forall a. (FiniteBits a, ShiftableBits a, IndexableBits a, Bitwise a, KnownNat (BitSize a), Eq a) => a -> a
- Haskus.Format.Binary.Bits.Reverse: reverseBitsTable :: Word8 -> Word8
- Haskus.Format.Binary.Bits.Rotate: class RotatableBits a
- Haskus.Format.Binary.Bits.Rotate: instance Haskus.Format.Binary.Bits.Rotate.RotatableBits GHC.Int.Int16
- Haskus.Format.Binary.Bits.Rotate: instance Haskus.Format.Binary.Bits.Rotate.RotatableBits GHC.Int.Int32
- Haskus.Format.Binary.Bits.Rotate: instance Haskus.Format.Binary.Bits.Rotate.RotatableBits GHC.Int.Int64
- Haskus.Format.Binary.Bits.Rotate: instance Haskus.Format.Binary.Bits.Rotate.RotatableBits GHC.Int.Int8
- Haskus.Format.Binary.Bits.Rotate: instance Haskus.Format.Binary.Bits.Rotate.RotatableBits GHC.Types.Int
- Haskus.Format.Binary.Bits.Rotate: instance Haskus.Format.Binary.Bits.Rotate.RotatableBits GHC.Types.Word
- Haskus.Format.Binary.Bits.Rotate: instance Haskus.Format.Binary.Bits.Rotate.RotatableBits GHC.Word.Word16
- Haskus.Format.Binary.Bits.Rotate: instance Haskus.Format.Binary.Bits.Rotate.RotatableBits GHC.Word.Word32
- Haskus.Format.Binary.Bits.Rotate: instance Haskus.Format.Binary.Bits.Rotate.RotatableBits GHC.Word.Word64
- Haskus.Format.Binary.Bits.Rotate: instance Haskus.Format.Binary.Bits.Rotate.RotatableBits GHC.Word.Word8
- Haskus.Format.Binary.Bits.Rotate: rotate :: (RotatableBits a, FiniteBits a, KnownNat (BitSize a)) => a -> Int -> a
- Haskus.Format.Binary.Bits.Rotate: rotateL :: (RotatableBits a, FiniteBits a, KnownNat (BitSize a)) => a -> Word -> a
- Haskus.Format.Binary.Bits.Rotate: rotateR :: (RotatableBits a, FiniteBits a, KnownNat (BitSize a)) => a -> Word -> a
- Haskus.Format.Binary.Bits.Rotate: uncheckedRotate :: RotatableBits a => a -> Int -> a
- Haskus.Format.Binary.Bits.Rotate: uncheckedRotateL :: (RotatableBits a, ShiftableBits a, FiniteBits a, KnownNat (BitSize a), Bitwise a) => a -> Word -> a
- Haskus.Format.Binary.Bits.Rotate: uncheckedRotateR :: (RotatableBits a, ShiftableBits a, FiniteBits a, KnownNat (BitSize a), Bitwise a) => a -> Word -> a
- Haskus.Format.Binary.Bits.Shift: class ShiftableBits a
- Haskus.Format.Binary.Bits.Shift: class SignedShiftableBits a
- Haskus.Format.Binary.Bits.Shift: instance Haskus.Format.Binary.Bits.Shift.ShiftableBits GHC.Int.Int16
- Haskus.Format.Binary.Bits.Shift: instance Haskus.Format.Binary.Bits.Shift.ShiftableBits GHC.Int.Int32
- Haskus.Format.Binary.Bits.Shift: instance Haskus.Format.Binary.Bits.Shift.ShiftableBits GHC.Int.Int64
- Haskus.Format.Binary.Bits.Shift: instance Haskus.Format.Binary.Bits.Shift.ShiftableBits GHC.Int.Int8
- Haskus.Format.Binary.Bits.Shift: instance Haskus.Format.Binary.Bits.Shift.ShiftableBits GHC.Integer.Type.Integer
- Haskus.Format.Binary.Bits.Shift: instance Haskus.Format.Binary.Bits.Shift.ShiftableBits GHC.Natural.Natural
- Haskus.Format.Binary.Bits.Shift: instance Haskus.Format.Binary.Bits.Shift.ShiftableBits GHC.Types.Int
- Haskus.Format.Binary.Bits.Shift: instance Haskus.Format.Binary.Bits.Shift.ShiftableBits GHC.Types.Word
- Haskus.Format.Binary.Bits.Shift: instance Haskus.Format.Binary.Bits.Shift.ShiftableBits GHC.Word.Word16
- Haskus.Format.Binary.Bits.Shift: instance Haskus.Format.Binary.Bits.Shift.ShiftableBits GHC.Word.Word32
- Haskus.Format.Binary.Bits.Shift: instance Haskus.Format.Binary.Bits.Shift.ShiftableBits GHC.Word.Word64
- Haskus.Format.Binary.Bits.Shift: instance Haskus.Format.Binary.Bits.Shift.ShiftableBits GHC.Word.Word8
- Haskus.Format.Binary.Bits.Shift: instance Haskus.Format.Binary.Bits.Shift.SignedShiftableBits GHC.Int.Int16
- Haskus.Format.Binary.Bits.Shift: instance Haskus.Format.Binary.Bits.Shift.SignedShiftableBits GHC.Int.Int32
- Haskus.Format.Binary.Bits.Shift: instance Haskus.Format.Binary.Bits.Shift.SignedShiftableBits GHC.Int.Int64
- Haskus.Format.Binary.Bits.Shift: instance Haskus.Format.Binary.Bits.Shift.SignedShiftableBits GHC.Int.Int8
- Haskus.Format.Binary.Bits.Shift: instance Haskus.Format.Binary.Bits.Shift.SignedShiftableBits GHC.Types.Int
- Haskus.Format.Binary.Bits.Shift: shift :: ShiftableBits a => a -> Int -> a
- Haskus.Format.Binary.Bits.Shift: shiftL :: ShiftableBits a => a -> Word -> a
- Haskus.Format.Binary.Bits.Shift: shiftR :: ShiftableBits a => a -> Word -> a
- Haskus.Format.Binary.Bits.Shift: signedShift :: SignedShiftableBits a => a -> Int -> a
- Haskus.Format.Binary.Bits.Shift: signedShiftL :: SignedShiftableBits a => a -> Word -> a
- Haskus.Format.Binary.Bits.Shift: signedShiftR :: SignedShiftableBits a => a -> Word -> a
- Haskus.Format.Binary.Bits.Shift: uncheckedShift :: ShiftableBits a => a -> Int -> a
- Haskus.Format.Binary.Bits.Shift: uncheckedShiftL :: ShiftableBits a => a -> Word -> a
- Haskus.Format.Binary.Bits.Shift: uncheckedShiftR :: ShiftableBits a => a -> Word -> a
- Haskus.Format.Binary.Bits.Shift: uncheckedSignedShift :: SignedShiftableBits a => a -> Int -> a
- Haskus.Format.Binary.Bits.Shift: uncheckedSignedShiftL :: SignedShiftableBits a => a -> Word -> a
- Haskus.Format.Binary.Bits.Shift: uncheckedSignedShiftR :: SignedShiftableBits a => a -> Word -> a
- Haskus.Format.Binary.Buffer: Buffer :: ByteString -> Buffer
- Haskus.Format.Binary.Buffer: bufferAppend :: Buffer -> Buffer -> Buffer
- Haskus.Format.Binary.Buffer: bufferCons :: Word8 -> Buffer -> Buffer
- Haskus.Format.Binary.Buffer: bufferDrop :: Word -> Buffer -> Buffer
- Haskus.Format.Binary.Buffer: bufferDup :: Buffer -> IO Buffer
- Haskus.Format.Binary.Buffer: bufferHead :: Buffer -> Word8
- Haskus.Format.Binary.Buffer: bufferIndex :: Buffer -> Word -> Word8
- Haskus.Format.Binary.Buffer: bufferInit :: Buffer -> Buffer
- Haskus.Format.Binary.Buffer: bufferMap :: (Word8 -> Word8) -> Buffer -> Buffer
- Haskus.Format.Binary.Buffer: bufferPackByteList :: [Word8] -> Buffer
- Haskus.Format.Binary.Buffer: bufferPackByteString :: ByteString -> Buffer
- Haskus.Format.Binary.Buffer: bufferPackPtr :: MonadIO m => Word -> Ptr () -> m Buffer
- Haskus.Format.Binary.Buffer: bufferPackStorable :: forall a. Storable a => a -> Buffer
- Haskus.Format.Binary.Buffer: bufferPackStorableList :: forall a. Storable a => [a] -> Buffer
- Haskus.Format.Binary.Buffer: bufferPeekStorable :: forall a. Storable a => Buffer -> a
- Haskus.Format.Binary.Buffer: bufferPeekStorableAt :: forall a. Storable a => Buffer -> Word -> a
- Haskus.Format.Binary.Buffer: bufferPoke :: Ptr a -> Buffer -> IO ()
- Haskus.Format.Binary.Buffer: bufferPopStorable :: forall a. Storable a => Buffer -> (Buffer, a)
- Haskus.Format.Binary.Buffer: bufferReadFile :: MonadIO m => FilePath -> m Buffer
- Haskus.Format.Binary.Buffer: bufferReverse :: Buffer -> Buffer
- Haskus.Format.Binary.Buffer: bufferSize :: Buffer -> Word
- Haskus.Format.Binary.Buffer: bufferSnoc :: Buffer -> Word8 -> Buffer
- Haskus.Format.Binary.Buffer: bufferSplitOn :: Word8 -> Buffer -> [Buffer]
- Haskus.Format.Binary.Buffer: bufferTail :: Buffer -> Buffer
- Haskus.Format.Binary.Buffer: bufferTake :: Word -> Buffer -> Buffer
- Haskus.Format.Binary.Buffer: bufferTakeAtMost :: Word -> Buffer -> Buffer
- Haskus.Format.Binary.Buffer: bufferTakeWhile :: (Word8 -> Bool) -> Buffer -> Buffer
- Haskus.Format.Binary.Buffer: bufferUnpackByteList :: Buffer -> [Word8]
- Haskus.Format.Binary.Buffer: bufferUnpackByteString :: Buffer -> ByteString
- Haskus.Format.Binary.Buffer: bufferUnsafeDrop :: Word -> Buffer -> Buffer
- Haskus.Format.Binary.Buffer: bufferUnsafeHead :: Buffer -> Word8
- Haskus.Format.Binary.Buffer: bufferUnsafeIndex :: Buffer -> Word -> Word8
- Haskus.Format.Binary.Buffer: bufferUnsafeInit :: Buffer -> Buffer
- Haskus.Format.Binary.Buffer: bufferUnsafeLast :: Buffer -> Word8
- Haskus.Format.Binary.Buffer: bufferUnsafeMapMemory :: MonadIO m => Word -> Ptr () -> m Buffer
- Haskus.Format.Binary.Buffer: bufferUnsafePackPtr :: MonadIO m => Word -> Ptr a -> m Buffer
- Haskus.Format.Binary.Buffer: bufferUnsafeTail :: Buffer -> Buffer
- Haskus.Format.Binary.Buffer: bufferUnsafeTake :: Word -> Buffer -> Buffer
- Haskus.Format.Binary.Buffer: bufferUnsafeUsePtr :: MonadInIO m => Buffer -> (Ptr () -> Word -> m a) -> m a
- Haskus.Format.Binary.Buffer: bufferWriteFile :: MonadIO m => FilePath -> Buffer -> m ()
- Haskus.Format.Binary.Buffer: bufferZero :: Word -> Buffer
- Haskus.Format.Binary.Buffer: bufferZipWith :: (Word8 -> Word8 -> Word8) -> Buffer -> Buffer -> Buffer
- Haskus.Format.Binary.Buffer: emptyBuffer :: Buffer
- Haskus.Format.Binary.Buffer: instance GHC.Classes.Eq Haskus.Format.Binary.Buffer.Buffer
- Haskus.Format.Binary.Buffer: instance GHC.Classes.Ord Haskus.Format.Binary.Buffer.Buffer
- Haskus.Format.Binary.Buffer: instance GHC.Show.Show Haskus.Format.Binary.Buffer.Buffer
- Haskus.Format.Binary.Buffer: instance Haskus.Format.Binary.Bits.Bitwise.Bitwise Haskus.Format.Binary.Buffer.Buffer
- Haskus.Format.Binary.Buffer: instance Haskus.Format.Binary.Bits.Index.IndexableBits Haskus.Format.Binary.Buffer.Buffer
- Haskus.Format.Binary.Buffer: isBufferEmpty :: Buffer -> Bool
- Haskus.Format.Binary.Buffer: newtype Buffer
- Haskus.Format.Binary.Buffer: withBufferPtr :: Buffer -> (Ptr b -> IO a) -> IO a
- Haskus.Format.Binary.BufferBuilder: data BufferBuilder
- Haskus.Format.Binary.BufferBuilder: emptyBufferBuilder :: BufferBuilder
- Haskus.Format.Binary.BufferBuilder: fromBuffer :: Buffer -> BufferBuilder
- Haskus.Format.Binary.BufferBuilder: fromWord8 :: Word8 -> BufferBuilder
- Haskus.Format.Binary.BufferBuilder: instance GHC.Base.Monoid Haskus.Format.Binary.BufferBuilder.BufferBuilder
- Haskus.Format.Binary.BufferBuilder: instance GHC.Base.Semigroup Haskus.Format.Binary.BufferBuilder.BufferBuilder
- Haskus.Format.Binary.BufferBuilder: toBuffer :: BufferBuilder -> Buffer
- Haskus.Format.Binary.BufferBuilder: toBufferList :: BufferBuilder -> BufferList
- Haskus.Format.Binary.BufferList: BufferList :: ByteString -> BufferList
- Haskus.Format.Binary.BufferList: newtype BufferList
- Haskus.Format.Binary.BufferList: toBuffer :: BufferList -> Buffer
- Haskus.Format.Binary.BufferList: toBufferList :: Buffer -> BufferList
- Haskus.Format.Binary.BufferList: toLazyByteString :: BufferList -> ByteString
- Haskus.Format.Binary.Char: Char8 :: Word8 -> Char8
- Haskus.Format.Binary.Char: instance GHC.Classes.Eq Haskus.Format.Binary.Char.Char8
- Haskus.Format.Binary.Char: instance GHC.Classes.Ord Haskus.Format.Binary.Char.Char8
- Haskus.Format.Binary.Char: instance GHC.Show.Show Haskus.Format.Binary.Char.Char8
- Haskus.Format.Binary.Char: instance Haskus.Format.Binary.Storable.Storable Haskus.Format.Binary.Char.Char8
- Haskus.Format.Binary.Char: newtype Char8
- Haskus.Format.Binary.Endianness: AsBigEndian :: a -> AsBigEndian a
- Haskus.Format.Binary.Endianness: AsLittleEndian :: a -> AsLittleEndian a
- Haskus.Format.Binary.Endianness: BigEndian :: Endianness
- Haskus.Format.Binary.Endianness: ExtendedWordGetters :: Get Word8 -> Get Word16 -> Get Word32 -> Get Word64 -> Get Word64 -> ExtendedWordGetters
- Haskus.Format.Binary.Endianness: ExtendedWordPutters :: (Word8 -> Put) -> (Word16 -> Put) -> (Word32 -> Put) -> (Word64 -> Put) -> (Word64 -> Put) -> ExtendedWordPutters
- Haskus.Format.Binary.Endianness: LittleEndian :: Endianness
- Haskus.Format.Binary.Endianness: WordGetters :: Get Word8 -> Get Word16 -> Get Word32 -> Get Word64 -> WordGetters
- Haskus.Format.Binary.Endianness: WordPutters :: (Word8 -> Put) -> (Word16 -> Put) -> (Word32 -> Put) -> (Word64 -> Put) -> WordPutters
- Haskus.Format.Binary.Endianness: WordSize32 :: WordSize
- Haskus.Format.Binary.Endianness: WordSize64 :: WordSize
- Haskus.Format.Binary.Endianness: [extwordGetter16] :: ExtendedWordGetters -> Get Word16
- Haskus.Format.Binary.Endianness: [extwordGetter32] :: ExtendedWordGetters -> Get Word32
- Haskus.Format.Binary.Endianness: [extwordGetter64] :: ExtendedWordGetters -> Get Word64
- Haskus.Format.Binary.Endianness: [extwordGetter8] :: ExtendedWordGetters -> Get Word8
- Haskus.Format.Binary.Endianness: [extwordGetterN] :: ExtendedWordGetters -> Get Word64
- Haskus.Format.Binary.Endianness: [extwordPutter16] :: ExtendedWordPutters -> Word16 -> Put
- Haskus.Format.Binary.Endianness: [extwordPutter32] :: ExtendedWordPutters -> Word32 -> Put
- Haskus.Format.Binary.Endianness: [extwordPutter64] :: ExtendedWordPutters -> Word64 -> Put
- Haskus.Format.Binary.Endianness: [extwordPutter8] :: ExtendedWordPutters -> Word8 -> Put
- Haskus.Format.Binary.Endianness: [extwordPutterN] :: ExtendedWordPutters -> Word64 -> Put
- Haskus.Format.Binary.Endianness: [wordGetter16] :: WordGetters -> Get Word16
- Haskus.Format.Binary.Endianness: [wordGetter32] :: WordGetters -> Get Word32
- Haskus.Format.Binary.Endianness: [wordGetter64] :: WordGetters -> Get Word64
- Haskus.Format.Binary.Endianness: [wordGetter8] :: WordGetters -> Get Word8
- Haskus.Format.Binary.Endianness: [wordPutter16] :: WordPutters -> Word16 -> Put
- Haskus.Format.Binary.Endianness: [wordPutter32] :: WordPutters -> Word32 -> Put
- Haskus.Format.Binary.Endianness: [wordPutter64] :: WordPutters -> Word64 -> Put
- Haskus.Format.Binary.Endianness: [wordPutter8] :: WordPutters -> Word8 -> Put
- Haskus.Format.Binary.Endianness: bigEndianToHost :: ByteReversable w => w -> w
- Haskus.Format.Binary.Endianness: class ByteReversable w
- Haskus.Format.Binary.Endianness: data Endianness
- Haskus.Format.Binary.Endianness: data ExtendedWordGetters
- Haskus.Format.Binary.Endianness: data ExtendedWordPutters
- Haskus.Format.Binary.Endianness: data WordGetters
- Haskus.Format.Binary.Endianness: data WordPutters
- Haskus.Format.Binary.Endianness: data WordSize
- Haskus.Format.Binary.Endianness: getExtendedWordGetters :: Endianness -> WordSize -> ExtendedWordGetters
- Haskus.Format.Binary.Endianness: getExtendedWordPutters :: Endianness -> WordSize -> ExtendedWordPutters
- Haskus.Format.Binary.Endianness: getHostEndianness :: IO Endianness
- Haskus.Format.Binary.Endianness: getWordGetters :: Endianness -> WordGetters
- Haskus.Format.Binary.Endianness: getWordPutters :: Endianness -> WordPutters
- Haskus.Format.Binary.Endianness: hostEndianness :: Endianness
- Haskus.Format.Binary.Endianness: hostToBigEndian :: ByteReversable w => w -> w
- Haskus.Format.Binary.Endianness: hostToLittleEndian :: ByteReversable w => w -> w
- Haskus.Format.Binary.Endianness: instance (Haskus.Format.Binary.Endianness.ByteReversable a, Haskus.Format.Binary.Storable.StaticStorable a) => Haskus.Format.Binary.Storable.StaticStorable (Haskus.Format.Binary.Endianness.AsBigEndian a)
- Haskus.Format.Binary.Endianness: instance (Haskus.Format.Binary.Endianness.ByteReversable a, Haskus.Format.Binary.Storable.StaticStorable a) => Haskus.Format.Binary.Storable.StaticStorable (Haskus.Format.Binary.Endianness.AsLittleEndian a)
- Haskus.Format.Binary.Endianness: instance (Haskus.Format.Binary.Endianness.ByteReversable a, Haskus.Format.Binary.Storable.Storable a) => Haskus.Format.Binary.Storable.Storable (Haskus.Format.Binary.Endianness.AsBigEndian a)
- Haskus.Format.Binary.Endianness: instance (Haskus.Format.Binary.Endianness.ByteReversable a, Haskus.Format.Binary.Storable.Storable a) => Haskus.Format.Binary.Storable.Storable (Haskus.Format.Binary.Endianness.AsLittleEndian a)
- Haskus.Format.Binary.Endianness: instance GHC.Classes.Eq Haskus.Format.Binary.Endianness.Endianness
- Haskus.Format.Binary.Endianness: instance GHC.Classes.Eq Haskus.Format.Binary.Endianness.WordSize
- Haskus.Format.Binary.Endianness: instance GHC.Classes.Eq a => GHC.Classes.Eq (Haskus.Format.Binary.Endianness.AsBigEndian a)
- Haskus.Format.Binary.Endianness: instance GHC.Classes.Eq a => GHC.Classes.Eq (Haskus.Format.Binary.Endianness.AsLittleEndian a)
- Haskus.Format.Binary.Endianness: instance GHC.Classes.Ord a => GHC.Classes.Ord (Haskus.Format.Binary.Endianness.AsBigEndian a)
- Haskus.Format.Binary.Endianness: instance GHC.Classes.Ord a => GHC.Classes.Ord (Haskus.Format.Binary.Endianness.AsLittleEndian a)
- Haskus.Format.Binary.Endianness: instance GHC.Enum.Enum Haskus.Format.Binary.Endianness.Endianness
- Haskus.Format.Binary.Endianness: instance GHC.Enum.Enum a => GHC.Enum.Enum (Haskus.Format.Binary.Endianness.AsBigEndian a)
- Haskus.Format.Binary.Endianness: instance GHC.Enum.Enum a => GHC.Enum.Enum (Haskus.Format.Binary.Endianness.AsLittleEndian a)
- Haskus.Format.Binary.Endianness: instance GHC.Num.Num a => GHC.Num.Num (Haskus.Format.Binary.Endianness.AsBigEndian a)
- Haskus.Format.Binary.Endianness: instance GHC.Num.Num a => GHC.Num.Num (Haskus.Format.Binary.Endianness.AsLittleEndian a)
- Haskus.Format.Binary.Endianness: instance GHC.Real.Integral a => GHC.Real.Integral (Haskus.Format.Binary.Endianness.AsBigEndian a)
- Haskus.Format.Binary.Endianness: instance GHC.Real.Integral a => GHC.Real.Integral (Haskus.Format.Binary.Endianness.AsLittleEndian a)
- Haskus.Format.Binary.Endianness: instance GHC.Real.Real a => GHC.Real.Real (Haskus.Format.Binary.Endianness.AsBigEndian a)
- Haskus.Format.Binary.Endianness: instance GHC.Real.Real a => GHC.Real.Real (Haskus.Format.Binary.Endianness.AsLittleEndian a)
- Haskus.Format.Binary.Endianness: instance GHC.Show.Show Haskus.Format.Binary.Endianness.Endianness
- Haskus.Format.Binary.Endianness: instance GHC.Show.Show Haskus.Format.Binary.Endianness.WordSize
- Haskus.Format.Binary.Endianness: instance GHC.Show.Show a => GHC.Show.Show (Haskus.Format.Binary.Endianness.AsBigEndian a)
- Haskus.Format.Binary.Endianness: instance GHC.Show.Show a => GHC.Show.Show (Haskus.Format.Binary.Endianness.AsLittleEndian a)
- Haskus.Format.Binary.Endianness: instance Haskus.Format.Binary.Bits.Bitwise.Bitwise a => Haskus.Format.Binary.Bits.Bitwise.Bitwise (Haskus.Format.Binary.Endianness.AsBigEndian a)
- Haskus.Format.Binary.Endianness: instance Haskus.Format.Binary.Bits.Bitwise.Bitwise a => Haskus.Format.Binary.Bits.Bitwise.Bitwise (Haskus.Format.Binary.Endianness.AsLittleEndian a)
- Haskus.Format.Binary.Endianness: instance Haskus.Format.Binary.Bits.Finite.FiniteBits a => Haskus.Format.Binary.Bits.Finite.FiniteBits (Haskus.Format.Binary.Endianness.AsBigEndian a)
- Haskus.Format.Binary.Endianness: instance Haskus.Format.Binary.Bits.Finite.FiniteBits a => Haskus.Format.Binary.Bits.Finite.FiniteBits (Haskus.Format.Binary.Endianness.AsLittleEndian a)
- Haskus.Format.Binary.Endianness: instance Haskus.Format.Binary.Bits.Index.IndexableBits a => Haskus.Format.Binary.Bits.Index.IndexableBits (Haskus.Format.Binary.Endianness.AsBigEndian a)
- Haskus.Format.Binary.Endianness: instance Haskus.Format.Binary.Bits.Index.IndexableBits a => Haskus.Format.Binary.Bits.Index.IndexableBits (Haskus.Format.Binary.Endianness.AsLittleEndian a)
- Haskus.Format.Binary.Endianness: instance Haskus.Format.Binary.Bits.Reverse.ReversableBits a => Haskus.Format.Binary.Bits.Reverse.ReversableBits (Haskus.Format.Binary.Endianness.AsBigEndian a)
- Haskus.Format.Binary.Endianness: instance Haskus.Format.Binary.Bits.Reverse.ReversableBits a => Haskus.Format.Binary.Bits.Reverse.ReversableBits (Haskus.Format.Binary.Endianness.AsLittleEndian a)
- Haskus.Format.Binary.Endianness: instance Haskus.Format.Binary.Bits.Rotate.RotatableBits a => Haskus.Format.Binary.Bits.Rotate.RotatableBits (Haskus.Format.Binary.Endianness.AsBigEndian a)
- Haskus.Format.Binary.Endianness: instance Haskus.Format.Binary.Bits.Rotate.RotatableBits a => Haskus.Format.Binary.Bits.Rotate.RotatableBits (Haskus.Format.Binary.Endianness.AsLittleEndian a)
- Haskus.Format.Binary.Endianness: instance Haskus.Format.Binary.Bits.Shift.ShiftableBits a => Haskus.Format.Binary.Bits.Shift.ShiftableBits (Haskus.Format.Binary.Endianness.AsBigEndian a)
- Haskus.Format.Binary.Endianness: instance Haskus.Format.Binary.Bits.Shift.ShiftableBits a => Haskus.Format.Binary.Bits.Shift.ShiftableBits (Haskus.Format.Binary.Endianness.AsLittleEndian a)
- Haskus.Format.Binary.Endianness: instance Haskus.Format.Binary.Endianness.ByteReversable GHC.Word.Word16
- Haskus.Format.Binary.Endianness: instance Haskus.Format.Binary.Endianness.ByteReversable GHC.Word.Word32
- Haskus.Format.Binary.Endianness: instance Haskus.Format.Binary.Endianness.ByteReversable GHC.Word.Word64
- Haskus.Format.Binary.Endianness: instance Haskus.Format.Binary.Endianness.ByteReversable GHC.Word.Word8
- Haskus.Format.Binary.Endianness: instance Haskus.Format.Binary.Enum.CEnum Haskus.Format.Binary.Endianness.Endianness
- Haskus.Format.Binary.Endianness: littleEndianToHost :: ByteReversable w => w -> w
- Haskus.Format.Binary.Endianness: newtype AsBigEndian a
- Haskus.Format.Binary.Endianness: newtype AsLittleEndian a
- Haskus.Format.Binary.Endianness: reverseBytes :: ByteReversable w => w -> w
- Haskus.Format.Binary.Enum: class CEnum a
- Haskus.Format.Binary.Enum: data EnumField b a
- Haskus.Format.Binary.Enum: dataToTag :: a -> Int
- Haskus.Format.Binary.Enum: fromCEnum :: (CEnum a, Integral b) => a -> b
- Haskus.Format.Binary.Enum: fromEnumField :: (CEnum a, Integral b) => EnumField b a -> a
- Haskus.Format.Binary.Enum: instance (GHC.Real.Integral b, Haskus.Format.Binary.Storable.StaticStorable b, Haskus.Format.Binary.Enum.CEnum a) => Haskus.Format.Binary.Storable.StaticStorable (Haskus.Format.Binary.Enum.EnumField b a)
- Haskus.Format.Binary.Enum: instance GHC.Classes.Eq b => GHC.Classes.Eq (Haskus.Format.Binary.Enum.EnumField b a)
- Haskus.Format.Binary.Enum: instance GHC.Show.Show b => GHC.Show.Show (Haskus.Format.Binary.Enum.EnumField b a)
- Haskus.Format.Binary.Enum: instance Haskus.Format.Binary.Storable.Storable b => Haskus.Format.Binary.Storable.Storable (Haskus.Format.Binary.Enum.EnumField b a)
- Haskus.Format.Binary.Enum: makeEnum :: forall a i. (Data a, Integral i) => i -> a
- Haskus.Format.Binary.Enum: makeEnumMaybe :: forall a i. (Data a, Integral i) => i -> Maybe a
- Haskus.Format.Binary.Enum: makeEnumWithCustom :: forall a i. (Data a, Integral i) => i -> a
- Haskus.Format.Binary.Enum: toCEnum :: (CEnum a, Enum a, Integral b) => b -> a
- Haskus.Format.Binary.Enum: toEnumField :: (CEnum a, Integral b) => a -> EnumField b a
- Haskus.Format.Binary.FixedPoint: data FixedPoint w (i :: Nat) (f :: Nat)
- Haskus.Format.Binary.FixedPoint: fromFixedPoint :: forall a w (n :: Nat) (d :: Nat). (RealFrac a, BitSize w ~ (n + d), KnownNat n, KnownNat d, Bits w, Field w, Num w, Integral w) => FixedPoint w n d -> a
- Haskus.Format.Binary.FixedPoint: instance (GHC.Real.Integral w, Haskus.Format.Binary.Bits.Bits w, Haskus.Format.Binary.BitField.Field w, Haskus.Format.Binary.Bits.Finite.BitSize w Data.Type.Equality.~ (n GHC.TypeNats.+ d), GHC.TypeNats.KnownNat n, GHC.TypeNats.KnownNat d) => GHC.Classes.Eq (Haskus.Format.Binary.FixedPoint.FixedPoint w n d)
- Haskus.Format.Binary.FixedPoint: instance (GHC.Real.Integral w, Haskus.Format.Binary.Bits.Bits w, Haskus.Format.Binary.BitField.Field w, Haskus.Format.Binary.Bits.Finite.BitSize w Data.Type.Equality.~ (n GHC.TypeNats.+ d), GHC.TypeNats.KnownNat n, GHC.TypeNats.KnownNat d, GHC.Show.Show w) => GHC.Show.Show (Haskus.Format.Binary.FixedPoint.FixedPoint w n d)
- Haskus.Format.Binary.FixedPoint: instance Haskus.Format.Binary.Storable.Storable w => Haskus.Format.Binary.Storable.Storable (Haskus.Format.Binary.FixedPoint.FixedPoint w i f)
- Haskus.Format.Binary.FixedPoint: toFixedPoint :: forall a w (n :: Nat) (d :: Nat). (RealFrac a, BitSize w ~ (n + d), KnownNat n, KnownNat d, Bits w, Field w, Num w, Integral w) => a -> FixedPoint w n d
- Haskus.Format.Binary.Get: alignAfter :: Word -> Get a -> Get a
- Haskus.Format.Binary.Get: consumeAtMost :: Word -> Get a -> Get a
- Haskus.Format.Binary.Get: consumeExactly :: Word -> Get a -> Get a
- Haskus.Format.Binary.Get: countBytes :: Get a -> Get (Word, a)
- Haskus.Format.Binary.Get: data Get a
- Haskus.Format.Binary.Get: getBitGet :: BitOrder -> BitGet a -> (a -> Get b) -> Get b
- Haskus.Format.Binary.Get: getBuffer :: Word -> Get Buffer
- Haskus.Format.Binary.Get: getBufferNul :: Get Buffer
- Haskus.Format.Binary.Get: getManyAtMost :: Word -> Get (Maybe a) -> Get [a]
- Haskus.Format.Binary.Get: getManyBounded :: Maybe Word -> Maybe Word -> Get (Maybe a) -> Get (Maybe [a])
- Haskus.Format.Binary.Get: getRemaining :: Get Buffer
- Haskus.Format.Binary.Get: getWhile :: (a -> Bool) -> Get a -> Get [a]
- Haskus.Format.Binary.Get: getWhole :: Get a -> Get [a]
- Haskus.Format.Binary.Get: getWord16be :: Get Word16
- Haskus.Format.Binary.Get: getWord16le :: Get Word16
- Haskus.Format.Binary.Get: getWord32be :: Get Word32
- Haskus.Format.Binary.Get: getWord32le :: Get Word32
- Haskus.Format.Binary.Get: getWord64be :: Get Word64
- Haskus.Format.Binary.Get: getWord64le :: Get Word64
- Haskus.Format.Binary.Get: getWord8 :: Get Word8
- Haskus.Format.Binary.Get: isEmpty :: Get Bool
- Haskus.Format.Binary.Get: lookAhead :: Get a -> Get a
- Haskus.Format.Binary.Get: lookAheadE :: Get (Either a b) -> Get (Either a b)
- Haskus.Format.Binary.Get: lookAheadM :: Get (Maybe a) -> Get (Maybe a)
- Haskus.Format.Binary.Get: remaining :: Get Word
- Haskus.Format.Binary.Get: runGet :: Get a -> Buffer -> Either String a
- Haskus.Format.Binary.Get: runGetOrFail :: Get a -> Buffer -> a
- Haskus.Format.Binary.Get: skip :: Word -> Get ()
- Haskus.Format.Binary.Get: skipAlign :: Word -> Word -> Get ()
- Haskus.Format.Binary.Get: uncheckedSkip :: Word -> Get ()
- Haskus.Format.Binary.Get: uncheckedSkipAlign :: Word -> Word -> Get ()
- Haskus.Format.Binary.Layout: LIndex :: Nat -> PathElem
- Haskus.Format.Binary.Layout: LPath :: LPath
- Haskus.Format.Binary.Layout: LSymbol :: Symbol -> PathElem
- Haskus.Format.Binary.Layout: data LPath (path :: [PathElem])
- Haskus.Format.Binary.Layout: data PathElem
- Haskus.Format.Binary.Layout: lPath :: forall e. LPath '[e]
- Haskus.Format.Binary.Layout: type LRoot = LPath '[]
- Haskus.Format.Binary.Layout: type family (:#>) p (n :: Nat)
- Haskus.Format.Binary.Posit: InfinityK :: PositKind
- Haskus.Format.Binary.Posit: NormalK :: PositKind
- Haskus.Format.Binary.Posit: Posit :: IntN nbits -> Posit
- Haskus.Format.Binary.Posit: PositEncoding :: PositFields -> PositEncoding
- Haskus.Format.Binary.Posit: PositFields :: Bool -> Word -> Word -> Word -> Int -> Word -> Word -> PositFields
- Haskus.Format.Binary.Posit: PositInfinity :: PositEncoding
- Haskus.Format.Binary.Posit: PositZero :: PositEncoding
- Haskus.Format.Binary.Posit: ZeroK :: PositKind
- Haskus.Format.Binary.Posit: [Infinity] :: PositK 'InfinityK nbits es
- Haskus.Format.Binary.Posit: [Value] :: Posit nbits es -> PositK 'NormalK nbits es
- Haskus.Format.Binary.Posit: [Zero] :: PositK 'ZeroK nbits es
- Haskus.Format.Binary.Posit: [positExponentBitCount] :: PositFields -> Word
- Haskus.Format.Binary.Posit: [positExponent] :: PositFields -> Word
- Haskus.Format.Binary.Posit: [positFractionBitCount] :: PositFields -> Word
- Haskus.Format.Binary.Posit: [positFraction] :: PositFields -> Word
- Haskus.Format.Binary.Posit: [positNegative] :: PositFields -> Bool
- Haskus.Format.Binary.Posit: [positRegimeBitCount] :: PositFields -> Word
- Haskus.Format.Binary.Posit: [positRegime] :: PositFields -> Int
- Haskus.Format.Binary.Posit: data PositEncoding
- Haskus.Format.Binary.Posit: data PositFields
- Haskus.Format.Binary.Posit: data PositK k nbits es
- Haskus.Format.Binary.Posit: data PositKind
- Haskus.Format.Binary.Posit: floatBinaryAccuracy :: forall f. (Fractional f, Real f) => Rational -> Double
- Haskus.Format.Binary.Posit: instance (Haskus.Format.Binary.Bits.Bits (Haskus.Format.Binary.Word.IntN n), Haskus.Format.Binary.Bits.Finite.FiniteBits (Haskus.Format.Binary.Word.IntN n), GHC.Classes.Ord (Haskus.Format.Binary.Word.IntN n), GHC.Num.Num (Haskus.Format.Binary.Word.IntN n), GHC.TypeNats.KnownNat n, GHC.TypeNats.KnownNat es, GHC.Real.Integral (Haskus.Format.Binary.Word.IntN n)) => GHC.Show.Show (Haskus.Format.Binary.Posit.Posit n es)
- Haskus.Format.Binary.Posit: instance GHC.Classes.Eq Haskus.Format.Binary.Posit.PositKind
- Haskus.Format.Binary.Posit: instance GHC.Show.Show Haskus.Format.Binary.Posit.PositEncoding
- Haskus.Format.Binary.Posit: instance GHC.Show.Show Haskus.Format.Binary.Posit.PositFields
- Haskus.Format.Binary.Posit: instance GHC.Show.Show Haskus.Format.Binary.Posit.PositKind
- Haskus.Format.Binary.Posit: isInfinity :: forall n es. (Bits (IntN n), Eq (IntN n), KnownNat n) => Posit n es -> Bool
- Haskus.Format.Binary.Posit: isNegative :: forall n es. (Bits (IntN n), Ord (IntN n), KnownNat n) => PositValue n es -> Bool
- Haskus.Format.Binary.Posit: isPositive :: forall n es. (Bits (IntN n), Ord (IntN n), KnownNat n) => PositValue n es -> Bool
- Haskus.Format.Binary.Posit: isZero :: forall n es. (Bits (IntN n), Eq (IntN n), KnownNat n) => Posit n es -> Bool
- Haskus.Format.Binary.Posit: newtype Posit (nbits :: Nat) (es :: Nat)
- Haskus.Format.Binary.Posit: positAbs :: forall n es. (Num (IntN n), KnownNat n) => PositValue n es -> PositValue n es
- Haskus.Format.Binary.Posit: positApproxFactor :: forall p n es. (Posit n es ~ p, Num (IntN n), Bits (IntN n), Integral (IntN n), KnownNat es, KnownNat n) => Rational -> Double
- Haskus.Format.Binary.Posit: positBinaryAccuracy :: forall p n es. (Posit n es ~ p, Num (IntN n), Bits (IntN n), Integral (IntN n), KnownNat es, KnownNat n) => Rational -> Double
- Haskus.Format.Binary.Posit: positBinaryError :: forall p n es. (Posit n es ~ p, Num (IntN n), Bits (IntN n), Integral (IntN n), KnownNat es, KnownNat n) => Rational -> Double
- Haskus.Format.Binary.Posit: positDecimalAccuracy :: forall p n es. (Posit n es ~ p, Num (IntN n), Bits (IntN n), Integral (IntN n), KnownNat es, KnownNat n) => Rational -> Double
- Haskus.Format.Binary.Posit: positDecimalError :: forall p n es. (Posit n es ~ p, Num (IntN n), Bits (IntN n), Integral (IntN n), KnownNat es, KnownNat n) => Rational -> Double
- Haskus.Format.Binary.Posit: positEncoding :: forall n es. (Bits (IntN n), Ord (IntN n), Num (IntN n), KnownNat n, KnownNat es, Integral (IntN n)) => Posit n es -> PositEncoding
- Haskus.Format.Binary.Posit: positFields :: forall n es. (Bits (IntN n), Ord (IntN n), Num (IntN n), KnownNat n, KnownNat es, Integral (IntN n)) => PositValue n es -> PositFields
- Haskus.Format.Binary.Posit: positFromRational :: forall p n es. (Posit n es ~ p, Num (IntN n), Bits (IntN n), KnownNat es, KnownNat n) => Rational -> Posit n es
- Haskus.Format.Binary.Posit: positKind :: forall n es. (Bits (IntN n), KnownNat n, Eq (IntN n)) => Posit n es -> SomePosit n es
- Haskus.Format.Binary.Posit: positToRational :: forall n es. (KnownNat n, KnownNat es, Eq (IntN n), Bits (IntN n), Integral (IntN n)) => Posit n es -> Rational
- Haskus.Format.Binary.Ptr: (-->) :: forall path l. (PtrLike p, KnownNat (LPathOffset path l)) => p l -> path -> p (LPathType path l)
- Haskus.Format.Binary.Ptr: FinalizedPtr :: {-# UNPACK #-} !ForeignPtr l -> {-# UNPACK #-} !Word -> FinalizedPtr l
- Haskus.Format.Binary.Ptr: Ptr :: Addr# -> Ptr a
- Haskus.Format.Binary.Ptr: castFunPtrToPtr :: () => FunPtr a -> Ptr b
- Haskus.Format.Binary.Ptr: castPtr :: PtrLike p => p a -> p b
- Haskus.Format.Binary.Ptr: castPtrToFunPtr :: () => Ptr a -> FunPtr b
- Haskus.Format.Binary.Ptr: class PtrLike (p :: * -> *)
- Haskus.Format.Binary.Ptr: data FinalizedPtr l
- Haskus.Format.Binary.Ptr: data ForeignPtr a
- Haskus.Format.Binary.Ptr: data FunPtr a
- Haskus.Format.Binary.Ptr: data Ptr a
- Haskus.Format.Binary.Ptr: data WordPtr
- Haskus.Format.Binary.Ptr: free :: MonadIO m => Ptr a -> m ()
- Haskus.Format.Binary.Ptr: indexPtr :: PtrLike p => p a -> Int -> p a
- Haskus.Format.Binary.Ptr: indexPtr' :: Integral b => Ptr a -> b -> Ptr a
- Haskus.Format.Binary.Ptr: instance GHC.Show.Show (Haskus.Format.Binary.Ptr.FinalizedPtr l)
- Haskus.Format.Binary.Ptr: instance Haskus.Format.Binary.Ptr.PtrLike GHC.Ptr.Ptr
- Haskus.Format.Binary.Ptr: instance Haskus.Format.Binary.Ptr.PtrLike Haskus.Format.Binary.Ptr.FinalizedPtr
- Haskus.Format.Binary.Ptr: mallocBytes :: (PtrLike p, MonadIO m) => Word -> m (p a)
- Haskus.Format.Binary.Ptr: mallocForeignPtrBytes :: MonadIO m => Word -> m (ForeignPtr a)
- Haskus.Format.Binary.Ptr: nullForeignPtr :: ForeignPtr a
- Haskus.Format.Binary.Ptr: nullFunPtr :: () => FunPtr a
- Haskus.Format.Binary.Ptr: nullPtr :: forall a. PtrLike p => p a
- Haskus.Format.Binary.Ptr: ptrDistance :: PtrLike p => p a -> p b -> Int
- Haskus.Format.Binary.Ptr: ptrToWordPtr :: () => Ptr a -> WordPtr
- Haskus.Format.Binary.Ptr: withFinalizedPtr :: FinalizedPtr a -> (Ptr a -> IO b) -> IO b
- Haskus.Format.Binary.Ptr: withForeignPtr :: MonadInIO m => ForeignPtr a -> (Ptr a -> m b) -> m b
- Haskus.Format.Binary.Ptr: withPtr :: PtrLike p => p a -> (Ptr a -> IO b) -> IO b
- Haskus.Format.Binary.Ptr: wordPtrToPtr :: () => WordPtr -> Ptr a
- Haskus.Format.Binary.Put: putBuffer :: Buffer -> Put
- Haskus.Format.Binary.Put: putByteString :: ByteString -> Put
- Haskus.Format.Binary.Put: putPadding :: Word -> Put
- Haskus.Format.Binary.Put: putPaddingAlign :: Word -> Word -> Put
- Haskus.Format.Binary.Put: putWord16be :: Word16 -> Put
- Haskus.Format.Binary.Put: putWord16le :: Word16 -> Put
- Haskus.Format.Binary.Put: putWord32be :: Word32 -> Put
- Haskus.Format.Binary.Put: putWord32le :: Word32 -> Put
- Haskus.Format.Binary.Put: putWord64be :: Word64 -> Put
- Haskus.Format.Binary.Put: putWord64le :: Word64 -> Put
- Haskus.Format.Binary.Put: putWord8 :: Word8 -> Put
- Haskus.Format.Binary.Put: runPut :: Put -> Buffer
- Haskus.Format.Binary.Put: type Put = PutM ()
- Haskus.Format.Binary.Record: data Field (name :: Symbol) typ
- Haskus.Format.Binary.Record: data Path (fs :: [Symbol])
- Haskus.Format.Binary.Record: data Record (fields :: [*])
- Haskus.Format.Binary.Record: instance (Haskus.Utils.HList.HFoldr' Haskus.Format.Binary.Record.Extract (Haskus.Format.Binary.Record.Record fs, Haskus.Utils.HList.HList '[]) fs (Haskus.Format.Binary.Record.Record fs, Haskus.Utils.HList.HList fs), GHC.Show.Show (Haskus.Utils.HList.HList fs)) => GHC.Show.Show (Haskus.Format.Binary.Record.Record fs)
- Haskus.Format.Binary.Record: instance (rec Data.Type.Equality.~ Haskus.Format.Binary.Record.Record fs, b Data.Type.Equality.~ Haskus.Format.Binary.Record.Field name typ, i Data.Type.Equality.~ (rec, Haskus.Utils.HList.HList l2), typ Data.Type.Equality.~ Haskus.Format.Binary.Record.FieldType name fs, GHC.TypeNats.KnownNat (Haskus.Format.Binary.Record.FieldOffset name fs 0), Haskus.Format.Binary.Storable.StaticStorable typ, GHC.TypeLits.KnownSymbol name, r Data.Type.Equality.~ (rec, Haskus.Utils.HList.HList ((GHC.Base.String, typ) : l2))) => Haskus.Utils.HList.Apply Haskus.Format.Binary.Record.Extract (b, i) r
- Haskus.Format.Binary.Record: instance (s Data.Type.Equality.~ Haskus.Format.Binary.Record.FullRecordSize fs, GHC.TypeNats.KnownNat s) => Haskus.Format.Binary.Storable.StaticStorable (Haskus.Format.Binary.Record.Record fs)
- Haskus.Format.Binary.Record: recordAlignment :: forall fs. KnownNat (RecordAlignment fs 1) => Record fs -> Word
- Haskus.Format.Binary.Record: recordField :: forall (name :: Symbol) a fs. (KnownNat (FieldOffset name fs 0), a ~ FieldType name fs, StaticStorable a) => Record fs -> a
- Haskus.Format.Binary.Record: recordFieldOffset :: forall (name :: Symbol) fs. KnownNat (FieldOffset name fs 0) => Record fs -> Int
- Haskus.Format.Binary.Record: recordFieldPath :: forall path a fs o. (o ~ FieldPathOffset fs path 0, a ~ FieldPathType fs path, KnownNat o, StaticStorable a) => Path path -> Record fs -> a
- Haskus.Format.Binary.Record: recordFieldPathOffset :: forall path fs o. (o ~ FieldPathOffset fs path 0, KnownNat o) => Path path -> Record fs -> Int
- Haskus.Format.Binary.Record: recordSize :: forall fs. KnownNat (FullRecordSize fs) => Record fs -> Word
- Haskus.Format.Binary.Record: recordToList :: forall fs. HFoldr' Extract (Record fs, HList '[]) fs (Record fs, HList fs) => Record fs -> HList fs
- Haskus.Format.Binary.Record: type family Alignment a :: Nat
- Haskus.Format.Binary.Serialize: -- | Sensible to endianness
- Haskus.Format.Binary.Serialize: AtLeast :: Nat -> Size
- Haskus.Format.Binary.Serialize: Dynamic :: Size
- Haskus.Format.Binary.Serialize: Exactly :: Nat -> Size
- Haskus.Format.Binary.Serialize: class Monad m => GetMonad m
- Haskus.Format.Binary.Serialize: class Monad m => PutMonad m
- Haskus.Format.Binary.Serialize: class Serializable a where {
- Haskus.Format.Binary.Serialize: data Size
- Haskus.Format.Binary.Serialize: get :: (Serializable a, GetMonad m) => Endianness -> Word -> m a
- Haskus.Format.Binary.Serialize: getBuffer :: GetMonad m => Word -> m BufferI
- Haskus.Format.Binary.Serialize: getBufferInto :: GetMonad m => Word -> Buffer 'Mutable pin gc heap -> m ()
- Haskus.Format.Binary.Serialize: getWord16 :: GetMonad m => m Word16
- Haskus.Format.Binary.Serialize: getWord16BE :: GetMonad m => m Word16
- Haskus.Format.Binary.Serialize: getWord16BEs :: GetMonad m => Word -> m [Word16]
- Haskus.Format.Binary.Serialize: getWord16LE :: GetMonad m => m Word16
- Haskus.Format.Binary.Serialize: getWord16LEs :: GetMonad m => Word -> m [Word16]
- Haskus.Format.Binary.Serialize: getWord16s :: GetMonad m => Word -> m [Word16]
- Haskus.Format.Binary.Serialize: getWord32 :: GetMonad m => m Word32
- Haskus.Format.Binary.Serialize: getWord32BE :: GetMonad m => m Word32
- Haskus.Format.Binary.Serialize: getWord32BEs :: GetMonad m => Word -> m [Word32]
- Haskus.Format.Binary.Serialize: getWord32LE :: GetMonad m => m Word32
- Haskus.Format.Binary.Serialize: getWord32LEs :: GetMonad m => Word -> m [Word32]
- Haskus.Format.Binary.Serialize: getWord32s :: GetMonad m => Word -> m [Word32]
- Haskus.Format.Binary.Serialize: getWord64 :: GetMonad m => m Word64
- Haskus.Format.Binary.Serialize: getWord64BE :: GetMonad m => m Word64
- Haskus.Format.Binary.Serialize: getWord64BEs :: GetMonad m => Word -> m [Word64]
- Haskus.Format.Binary.Serialize: getWord64LE :: GetMonad m => m Word64
- Haskus.Format.Binary.Serialize: getWord64LEs :: GetMonad m => Word -> m [Word64]
- Haskus.Format.Binary.Serialize: getWord64s :: GetMonad m => Word -> m [Word64]
- Haskus.Format.Binary.Serialize: getWord8 :: GetMonad m => m Word8
- Haskus.Format.Binary.Serialize: getWord8s :: GetMonad m => Word -> m [Word8]
- Haskus.Format.Binary.Serialize: instance Haskus.Format.Binary.Serialize.Serializable GHC.Int.Int16
- Haskus.Format.Binary.Serialize: instance Haskus.Format.Binary.Serialize.Serializable GHC.Int.Int32
- Haskus.Format.Binary.Serialize: instance Haskus.Format.Binary.Serialize.Serializable GHC.Int.Int64
- Haskus.Format.Binary.Serialize: instance Haskus.Format.Binary.Serialize.Serializable GHC.Int.Int8
- Haskus.Format.Binary.Serialize: instance Haskus.Format.Binary.Serialize.Serializable GHC.Word.Word16
- Haskus.Format.Binary.Serialize: instance Haskus.Format.Binary.Serialize.Serializable GHC.Word.Word32
- Haskus.Format.Binary.Serialize: instance Haskus.Format.Binary.Serialize.Serializable GHC.Word.Word64
- Haskus.Format.Binary.Serialize: instance Haskus.Format.Binary.Serialize.Serializable GHC.Word.Word8
- Haskus.Format.Binary.Serialize: instance Haskus.Format.Binary.Serialize.Serializable Haskus.Memory.Buffer.BufferI
- Haskus.Format.Binary.Serialize: instance Haskus.Format.Binary.Serialize.Serializable a => Haskus.Format.Binary.Serialize.Serializable (Haskus.Format.Binary.Endianness.AsBigEndian a)
- Haskus.Format.Binary.Serialize: instance Haskus.Format.Binary.Serialize.Serializable a => Haskus.Format.Binary.Serialize.Serializable (Haskus.Format.Binary.Endianness.AsLittleEndian a)
- Haskus.Format.Binary.Serialize: preAllocateAtLeast :: PutMonad m => Word -> m ()
- Haskus.Format.Binary.Serialize: put :: (Serializable a, PutMonad m) => Endianness -> a -> m ()
- Haskus.Format.Binary.Serialize: putBuffer :: PutMonad m => Buffer mut pin gc heap -> m ()
- Haskus.Format.Binary.Serialize: putWord16 :: PutMonad m => Word16 -> m ()
- Haskus.Format.Binary.Serialize: putWord16BE :: PutMonad m => Word16 -> m ()
- Haskus.Format.Binary.Serialize: putWord16BEs :: PutMonad m => [Word16] -> m ()
- Haskus.Format.Binary.Serialize: putWord16LE :: PutMonad m => Word16 -> m ()
- Haskus.Format.Binary.Serialize: putWord16LEs :: PutMonad m => [Word16] -> m ()
- Haskus.Format.Binary.Serialize: putWord16s :: PutMonad m => [Word16] -> m ()
- Haskus.Format.Binary.Serialize: putWord32 :: PutMonad m => Word32 -> m ()
- Haskus.Format.Binary.Serialize: putWord32BE :: PutMonad m => Word32 -> m ()
- Haskus.Format.Binary.Serialize: putWord32BEs :: PutMonad m => [Word32] -> m ()
- Haskus.Format.Binary.Serialize: putWord32LE :: PutMonad m => Word32 -> m ()
- Haskus.Format.Binary.Serialize: putWord32LEs :: PutMonad m => [Word32] -> m ()
- Haskus.Format.Binary.Serialize: putWord32s :: PutMonad m => [Word32] -> m ()
- Haskus.Format.Binary.Serialize: putWord64 :: PutMonad m => Word64 -> m ()
- Haskus.Format.Binary.Serialize: putWord64BE :: PutMonad m => Word64 -> m ()
- Haskus.Format.Binary.Serialize: putWord64BEs :: PutMonad m => [Word64] -> m ()
- Haskus.Format.Binary.Serialize: putWord64LE :: PutMonad m => Word64 -> m ()
- Haskus.Format.Binary.Serialize: putWord64LEs :: PutMonad m => [Word64] -> m ()
- Haskus.Format.Binary.Serialize: putWord64s :: PutMonad m => [Word64] -> m ()
- Haskus.Format.Binary.Serialize: putWord8 :: PutMonad m => Word8 -> m ()
- Haskus.Format.Binary.Serialize: putWord8s :: PutMonad m => [Word8] -> m ()
- Haskus.Format.Binary.Serialize: sizeOf :: Serializable a => a -> Word
- Haskus.Format.Binary.Serialize: type family Endian a :: Bool;
- Haskus.Format.Binary.Serialize: }
- Haskus.Format.Binary.Serialize.Buffer: BufferPutT :: StateT (BufferPutState b) m a -> BufferPutT b m a
- Haskus.Format.Binary.Serialize.Buffer: getPutBuffer :: Monad m => BufferPutT b m b
- Haskus.Format.Binary.Serialize.Buffer: getPutOffset :: Monad m => BufferPutT b m Word
- Haskus.Format.Binary.Serialize.Buffer: instance (Control.Monad.IO.Class.MonadIO m, Control.Monad.Fail.MonadFail m) => Haskus.Format.Binary.Serialize.PutMonad (Haskus.Format.Binary.Serialize.Buffer.BufferPutT (Haskus.Memory.Buffer.Buffer 'Haskus.Memory.Buffer.Mutable pin gc heap) m)
- Haskus.Format.Binary.Serialize.Buffer: instance Control.Monad.Fail.MonadFail m => Control.Monad.Fail.MonadFail (Haskus.Format.Binary.Serialize.Buffer.BufferPutT b m)
- Haskus.Format.Binary.Serialize.Buffer: instance Control.Monad.Fix.MonadFix m => Control.Monad.Fix.MonadFix (Haskus.Format.Binary.Serialize.Buffer.BufferPutT b m)
- Haskus.Format.Binary.Serialize.Buffer: instance Control.Monad.IO.Class.MonadIO m => Control.Monad.IO.Class.MonadIO (Haskus.Format.Binary.Serialize.Buffer.BufferPutT b m)
- Haskus.Format.Binary.Serialize.Buffer: instance Control.Monad.Trans.Class.MonadTrans (Haskus.Format.Binary.Serialize.Buffer.BufferPutT b)
- Haskus.Format.Binary.Serialize.Buffer: instance GHC.Base.Functor m => GHC.Base.Functor (Haskus.Format.Binary.Serialize.Buffer.BufferPutT b m)
- Haskus.Format.Binary.Serialize.Buffer: instance GHC.Base.Monad m => GHC.Base.Applicative (Haskus.Format.Binary.Serialize.Buffer.BufferPutT b m)
- Haskus.Format.Binary.Serialize.Buffer: instance GHC.Base.Monad m => GHC.Base.Monad (Haskus.Format.Binary.Serialize.Buffer.BufferPutT b m)
- Haskus.Format.Binary.Serialize.Buffer: newtype BufferPutT b m a
- Haskus.Format.Binary.Serialize.Buffer: runBufferPut :: Monad m => b -> Word -> BufferPutT b m a -> m (a, Word)
- Haskus.Format.Binary.Serialize.Buffer: setPutOffset :: Monad m => Word -> BufferPutT b m ()
- Haskus.Format.Binary.Serialize.Buffer: type BufferPut b a = BufferPutT b Identity a
- Haskus.Format.Binary.Storable: -- | Alignment requirement (in bytes)
- Haskus.Format.Binary.Storable: alignment :: (Storable a, Generic a, GStorable (Rep a)) => a -> Word
- Haskus.Format.Binary.Storable: alignment' :: (Integral b, Storable a) => a -> b
- Haskus.Format.Binary.Storable: alignmentT :: forall a. Storable a => Word
- Haskus.Format.Binary.Storable: alignmentT' :: forall a b. (Storable a, Integral b) => b
- Haskus.Format.Binary.Storable: alloca :: forall a b m. (MonadInIO m, Storable a) => (Ptr a -> m b) -> m b
- Haskus.Format.Binary.Storable: allocaArray :: forall a b m. (MonadInIO m, Storable a) => Word -> (Ptr a -> m b) -> m b
- Haskus.Format.Binary.Storable: allocaBytes :: MonadInIO m => Word -> (Ptr a -> m b) -> m b
- Haskus.Format.Binary.Storable: allocaBytesAligned :: MonadInIO m => Word -> Word -> (Ptr a -> m b) -> m b
- Haskus.Format.Binary.Storable: class StaticStorable a where {
- Haskus.Format.Binary.Storable: class Storable a
- Haskus.Format.Binary.Storable: instance (Haskus.Format.Binary.Storable.GStorable a, Haskus.Format.Binary.Storable.GStorable b) => Haskus.Format.Binary.Storable.GStorable (a GHC.Generics.:*: b)
- Haskus.Format.Binary.Storable: instance Haskus.Format.Binary.Storable.GStorable GHC.Generics.U1
- Haskus.Format.Binary.Storable: instance Haskus.Format.Binary.Storable.GStorable a => Haskus.Format.Binary.Storable.GStorable (GHC.Generics.M1 i c a)
- Haskus.Format.Binary.Storable: instance Haskus.Format.Binary.Storable.StaticStorable GHC.Int.Int16
- Haskus.Format.Binary.Storable: instance Haskus.Format.Binary.Storable.StaticStorable GHC.Int.Int32
- Haskus.Format.Binary.Storable: instance Haskus.Format.Binary.Storable.StaticStorable GHC.Int.Int64
- Haskus.Format.Binary.Storable: instance Haskus.Format.Binary.Storable.StaticStorable GHC.Int.Int8
- Haskus.Format.Binary.Storable: instance Haskus.Format.Binary.Storable.StaticStorable GHC.Word.Word16
- Haskus.Format.Binary.Storable: instance Haskus.Format.Binary.Storable.StaticStorable GHC.Word.Word32
- Haskus.Format.Binary.Storable: instance Haskus.Format.Binary.Storable.StaticStorable GHC.Word.Word64
- Haskus.Format.Binary.Storable: instance Haskus.Format.Binary.Storable.StaticStorable GHC.Word.Word8
- Haskus.Format.Binary.Storable: instance Haskus.Format.Binary.Storable.Storable (GHC.Ptr.Ptr a)
- Haskus.Format.Binary.Storable: instance Haskus.Format.Binary.Storable.Storable Foreign.C.Types.CChar
- Haskus.Format.Binary.Storable: instance Haskus.Format.Binary.Storable.Storable Foreign.C.Types.CInt
- Haskus.Format.Binary.Storable: instance Haskus.Format.Binary.Storable.Storable Foreign.C.Types.CLong
- Haskus.Format.Binary.Storable: instance Haskus.Format.Binary.Storable.Storable Foreign.C.Types.CShort
- Haskus.Format.Binary.Storable: instance Haskus.Format.Binary.Storable.Storable Foreign.C.Types.CSize
- Haskus.Format.Binary.Storable: instance Haskus.Format.Binary.Storable.Storable Foreign.C.Types.CUInt
- Haskus.Format.Binary.Storable: instance Haskus.Format.Binary.Storable.Storable Foreign.C.Types.CULong
- Haskus.Format.Binary.Storable: instance Haskus.Format.Binary.Storable.Storable Foreign.C.Types.CUShort
- Haskus.Format.Binary.Storable: instance Haskus.Format.Binary.Storable.Storable Foreign.Ptr.WordPtr
- Haskus.Format.Binary.Storable: instance Haskus.Format.Binary.Storable.Storable GHC.Int.Int16
- Haskus.Format.Binary.Storable: instance Haskus.Format.Binary.Storable.Storable GHC.Int.Int32
- Haskus.Format.Binary.Storable: instance Haskus.Format.Binary.Storable.Storable GHC.Int.Int64
- Haskus.Format.Binary.Storable: instance Haskus.Format.Binary.Storable.Storable GHC.Int.Int8
- Haskus.Format.Binary.Storable: instance Haskus.Format.Binary.Storable.Storable GHC.Types.Char
- Haskus.Format.Binary.Storable: instance Haskus.Format.Binary.Storable.Storable GHC.Types.Double
- Haskus.Format.Binary.Storable: instance Haskus.Format.Binary.Storable.Storable GHC.Types.Float
- Haskus.Format.Binary.Storable: instance Haskus.Format.Binary.Storable.Storable GHC.Types.Int
- Haskus.Format.Binary.Storable: instance Haskus.Format.Binary.Storable.Storable GHC.Types.Word
- Haskus.Format.Binary.Storable: instance Haskus.Format.Binary.Storable.Storable GHC.Word.Word16
- Haskus.Format.Binary.Storable: instance Haskus.Format.Binary.Storable.Storable GHC.Word.Word32
- Haskus.Format.Binary.Storable: instance Haskus.Format.Binary.Storable.Storable GHC.Word.Word64
- Haskus.Format.Binary.Storable: instance Haskus.Format.Binary.Storable.Storable GHC.Word.Word8
- Haskus.Format.Binary.Storable: instance Haskus.Format.Binary.Storable.Storable a => Haskus.Format.Binary.Storable.GStorable (GHC.Generics.K1 i a)
- Haskus.Format.Binary.Storable: malloc :: forall a m. (MonadIO m, Storable a) => m (Ptr a)
- Haskus.Format.Binary.Storable: mallocArray :: forall a m. (MonadIO m, Storable a) => Word -> m (Ptr a)
- Haskus.Format.Binary.Storable: peek :: (Storable a, MonadIO m) => Ptr a -> m a
- Haskus.Format.Binary.Storable: peekArray :: (MonadIO m, Storable a) => Word -> Ptr a -> m [a]
- Haskus.Format.Binary.Storable: peekByteOff :: (MonadIO m, Storable a) => Ptr a -> Int -> m a
- Haskus.Format.Binary.Storable: peekElemOff :: forall a m. (MonadIO m, Storable a) => Ptr a -> Int -> m a
- Haskus.Format.Binary.Storable: peekIO :: (Storable a, Generic a, GStorable (Rep a)) => Ptr a -> IO a
- Haskus.Format.Binary.Storable: poke :: (Storable a, MonadIO m) => Ptr a -> a -> m ()
- Haskus.Format.Binary.Storable: pokeArray :: (MonadIO m, Storable a) => Ptr a -> [a] -> m ()
- Haskus.Format.Binary.Storable: pokeByteOff :: (MonadIO m, Storable a) => Ptr a -> Int -> a -> m ()
- Haskus.Format.Binary.Storable: pokeElemOff :: (MonadIO m, Storable a) => Ptr a -> Int -> a -> m ()
- Haskus.Format.Binary.Storable: pokeIO :: (Storable a, Generic a, GStorable (Rep a)) => Ptr a -> a -> IO ()
- Haskus.Format.Binary.Storable: sizeOf :: (Storable a, Generic a, GStorable (Rep a)) => a -> Word
- Haskus.Format.Binary.Storable: sizeOf' :: (Integral b, Storable a) => a -> b
- Haskus.Format.Binary.Storable: sizeOfT :: forall a. Storable a => Word
- Haskus.Format.Binary.Storable: sizeOfT' :: forall a b. (Storable a, Integral b) => b
- Haskus.Format.Binary.Storable: staticAlignment :: forall a. KnownNat (Alignment a) => a -> Word
- Haskus.Format.Binary.Storable: staticPeek :: (StaticStorable a, MonadIO m) => Ptr a -> m a
- Haskus.Format.Binary.Storable: staticPeekIO :: StaticStorable a => Ptr a -> IO a
- Haskus.Format.Binary.Storable: staticPoke :: (StaticStorable a, MonadIO m) => Ptr a -> a -> m ()
- Haskus.Format.Binary.Storable: staticPokeIO :: StaticStorable a => Ptr a -> a -> IO ()
- Haskus.Format.Binary.Storable: staticSizeOf :: forall a. KnownNat (SizeOf a) => a -> Word
- Haskus.Format.Binary.Storable: type family PaddingEx (m :: Nat) (a :: Nat)
- Haskus.Format.Binary.Storable: with :: (MonadInIO m, Storable a) => a -> (Ptr a -> m b) -> m b
- Haskus.Format.Binary.Storable: withArray :: (MonadInIO m, Storable a) => [a] -> (Ptr a -> m b) -> m b
- Haskus.Format.Binary.Storable: withArrayLen :: (MonadInIO m, Storable a) => [a] -> (Word -> Ptr a -> m b) -> m b
- Haskus.Format.Binary.Storable: withMany :: (a -> (b -> res) -> res) -> [a] -> ([b] -> res) -> res
- Haskus.Format.Binary.Storable: wordBytes :: forall a. (Storable a, KnownNat (SizeOf a)) => a -> [Word8]
- Haskus.Format.Binary.Storable: }
- Haskus.Format.Binary.Union: data Union (x :: [*])
- Haskus.Format.Binary.Union: fromUnion :: (Storable a, Member a l) => Union l -> a
- Haskus.Format.Binary.Union: instance (GHC.TypeNats.KnownNat (Haskus.Utils.Types.List.ListMax (Haskus.Format.Binary.Union.MapSizeOf fs)), GHC.TypeNats.KnownNat (Haskus.Utils.Types.List.ListMax (Haskus.Format.Binary.Union.MapAlignment fs))) => Haskus.Format.Binary.Storable.StaticStorable (Haskus.Format.Binary.Union.Union fs)
- Haskus.Format.Binary.Union: instance (Haskus.Utils.HList.HFoldr' Haskus.Format.Binary.Union.FoldSizeOf GHC.Types.Word l GHC.Types.Word, Haskus.Utils.HList.HFoldr' Haskus.Format.Binary.Union.FoldAlignment GHC.Types.Word l GHC.Types.Word) => Foreign.Storable.Storable (Haskus.Format.Binary.Union.Union l)
- Haskus.Format.Binary.Union: instance (Haskus.Utils.HList.HFoldr' Haskus.Format.Binary.Union.FoldSizeOf GHC.Types.Word l GHC.Types.Word, Haskus.Utils.HList.HFoldr' Haskus.Format.Binary.Union.FoldAlignment GHC.Types.Word l GHC.Types.Word) => Haskus.Format.Binary.Storable.Storable (Haskus.Format.Binary.Union.Union l)
- Haskus.Format.Binary.Union: instance (r Data.Type.Equality.~ GHC.Types.Word, Haskus.Format.Binary.Storable.Storable a) => Haskus.Utils.HList.Apply Haskus.Format.Binary.Union.FoldAlignment (a, GHC.Types.Word) r
- Haskus.Format.Binary.Union: instance (r Data.Type.Equality.~ GHC.Types.Word, Haskus.Format.Binary.Storable.Storable a) => Haskus.Utils.HList.Apply Haskus.Format.Binary.Union.FoldSizeOf (a, GHC.Types.Word) r
- Haskus.Format.Binary.Union: instance GHC.Show.Show (Haskus.Format.Binary.Union.Union x)
- Haskus.Format.Binary.Union: toUnion :: forall a l. (Storable (Union l), Storable a, Member a l) => a -> Union l
- Haskus.Format.Binary.Union: toUnionZero :: forall a l. (Storable (Union l), Storable a, Member a l) => a -> Union l
- Haskus.Format.Binary.Unum: CSORN :: BitFields (CSORNBackingWord u) '[BitField (UnumSize u) "start" (BackingWord u), BitField (UnumSize u) "count" (BackingWord u)] -> CSORN u
- Haskus.Format.Binary.Unum: ExactNumber :: UBit
- Haskus.Format.Binary.Unum: Negative :: Sign
- Haskus.Format.Binary.Unum: NoSign :: Sign
- Haskus.Format.Binary.Unum: OpenInterval :: UBit
- Haskus.Format.Binary.Unum: Positive :: Sign
- Haskus.Format.Binary.Unum: U :: BackingWord u -> U u
- Haskus.Format.Binary.Unum: class SornAdd u
- Haskus.Format.Binary.Unum: class UnumNum a
- Haskus.Format.Binary.Unum: csornBits :: forall u s. (Bits (CSORNBackingWord u), KnownNat (UnumSize u), s ~ CSORNSize u, KnownNat s) => CSORN u -> String
- Haskus.Format.Binary.Unum: csornEmpty :: forall u. Bits (CSORNBackingWord u) => CSORN u
- Haskus.Format.Binary.Unum: csornFromTo :: forall u. (Num (BackingWord u), Bits (BackingWord u), KnownNat (UnumSize u), KnownNat (SORNSize u), Bits (BackingWord u), Integral (CSORNBackingWord u), Bits (CSORNBackingWord u), Field (BackingWord u), Integral (BackingWord u)) => U u -> U u -> CSORN u
- Haskus.Format.Binary.Unum: csornFull :: forall u. (Bits (CSORNBackingWord u), Integral (CSORNBackingWord u), Integral (BackingWord u), KnownNat (UnumSize u), Field (BackingWord u)) => CSORN u
- Haskus.Format.Binary.Unum: csornIsEmpty :: forall u. Bits (CSORNBackingWord u) => CSORN u -> Bool
- Haskus.Format.Binary.Unum: csornSingle :: forall u. (Bits (CSORNBackingWord u), Integral (CSORNBackingWord u), Integral (BackingWord u), KnownNat (UnumSize u), Field (BackingWord u)) => U u -> CSORN u
- Haskus.Format.Binary.Unum: csornSize :: forall u s. (s ~ CSORNSize u, KnownNat s) => Word
- Haskus.Format.Binary.Unum: csornToSorn :: forall u. (KnownNat (UnumSize u), Num (BackingWord u), Integral (BackingWord u), Integral (CSORNBackingWord u), Bits (CSORNBackingWord u), Bits (BackingWord u), Bits (SORNBackingWord u), Field (BackingWord u), KnownNat (SORNSize u), Bits (SORNBackingWord u)) => CSORN u -> SORN u
- Haskus.Format.Binary.Unum: data I (n :: Nat)
- Haskus.Format.Binary.Unum: data Neg a
- Haskus.Format.Binary.Unum: data Rcp a
- Haskus.Format.Binary.Unum: data SORN u
- Haskus.Format.Binary.Unum: data Sign
- Haskus.Format.Binary.Unum: data UBit
- Haskus.Format.Binary.Unum: data Unum (xs :: [Type])
- Haskus.Format.Binary.Unum: instance (GHC.TypeNats.KnownNat (Haskus.Format.Binary.Unum.SORNSize u), GHC.TypeNats.KnownNat (Haskus.Format.Binary.Unum.UnumSize u), Haskus.Format.Binary.Bits.Bits (Haskus.Format.Binary.Unum.BackingWord u), Haskus.Format.Binary.Bits.Bits (Haskus.Format.Binary.Unum.CSORNBackingWord u), GHC.Real.Integral (Haskus.Format.Binary.Unum.CSORNBackingWord u), GHC.Num.Num (Haskus.Format.Binary.Unum.BackingWord u), GHC.Real.Integral (Haskus.Format.Binary.Unum.BackingWord u), Haskus.Utils.HList.HFoldr' Haskus.Format.Binary.Unum.GetLabel [GHC.Base.String] v [GHC.Base.String], Haskus.Format.Binary.BitField.Field (Haskus.Format.Binary.Unum.BackingWord u), Haskus.Format.Binary.Bits.Bits (Haskus.Format.Binary.Unum.SORNBackingWord u), Haskus.Format.Binary.Bits.Bits (Haskus.Format.Binary.Unum.SORNBackingWord u), v Data.Type.Equality.~ Haskus.Format.Binary.Unum.UnumMembers u) => GHC.Show.Show (Haskus.Format.Binary.Unum.CSORN u)
- Haskus.Format.Binary.Unum: instance (GHC.TypeNats.KnownNat (Haskus.Format.Binary.Unum.SORNSize u), Haskus.Format.Binary.Bits.Bits (Haskus.Format.Binary.Unum.SORNBackingWord u), GHC.Num.Num (Haskus.Format.Binary.Unum.BackingWord u), GHC.Real.Integral (Haskus.Format.Binary.Unum.BackingWord u), Haskus.Utils.HList.HFoldr' Haskus.Format.Binary.Unum.GetLabel [GHC.Base.String] v [GHC.Base.String], v Data.Type.Equality.~ Haskus.Format.Binary.Unum.UnumMembers u) => GHC.Show.Show (Haskus.Format.Binary.Unum.SORN u)
- Haskus.Format.Binary.Unum: instance (Haskus.Format.Binary.Unum.UnumNum a, r Data.Type.Equality.~ [GHC.Base.String]) => Haskus.Utils.HList.Apply Haskus.Format.Binary.Unum.GetLabel (a, [GHC.Base.String]) r
- Haskus.Format.Binary.Unum: instance (Haskus.Utils.HList.HFoldr' Haskus.Format.Binary.Unum.GetLabel [GHC.Base.String] v [GHC.Base.String], v Data.Type.Equality.~ Haskus.Format.Binary.Unum.UnumMembers u, GHC.Real.Integral (Haskus.Format.Binary.Unum.BackingWord u)) => GHC.Show.Show (Haskus.Format.Binary.Unum.U u)
- Haskus.Format.Binary.Unum: instance GHC.Classes.Eq (Haskus.Format.Binary.Unum.BackingWord u) => GHC.Classes.Eq (Haskus.Format.Binary.Unum.U u)
- Haskus.Format.Binary.Unum: instance GHC.Classes.Eq Haskus.Format.Binary.Unum.Sign
- Haskus.Format.Binary.Unum: instance GHC.Classes.Eq Haskus.Format.Binary.Unum.UBit
- Haskus.Format.Binary.Unum: instance GHC.Show.Show Haskus.Format.Binary.Unum.Sign
- Haskus.Format.Binary.Unum: instance GHC.Show.Show Haskus.Format.Binary.Unum.UBit
- Haskus.Format.Binary.Unum: instance GHC.TypeNats.KnownNat n => Haskus.Format.Binary.Unum.UnumNum (Haskus.Format.Binary.Unum.I n)
- Haskus.Format.Binary.Unum: instance Haskus.Format.Binary.Unum.UnumNum x => Haskus.Format.Binary.Unum.UnumNum (Haskus.Format.Binary.Unum.Neg x)
- Haskus.Format.Binary.Unum: instance Haskus.Format.Binary.Unum.UnumNum x => Haskus.Format.Binary.Unum.UnumNum (Haskus.Format.Binary.Unum.Rcp x)
- Haskus.Format.Binary.Unum: instance Haskus.Format.Binary.Unum.UnumNum x => Haskus.Format.Binary.Unum.UnumNum (Haskus.Format.Binary.Unum.Uncertain x)
- Haskus.Format.Binary.Unum: newtype CSORN u
- Haskus.Format.Binary.Unum: newtype U u
- Haskus.Format.Binary.Unum: sornAdd :: (SornAdd u, KnownNat (SORNSize u), Bits (SORNBackingWord u), Num (BackingWord u)) => SORN u -> SORN u -> SORN u
- Haskus.Format.Binary.Unum: sornAddDep :: (SornAdd u, KnownNat (SORNSize u), Bits (SORNBackingWord u), Num (BackingWord u)) => SORN u -> SORN u
- Haskus.Format.Binary.Unum: sornAddU :: SornAdd u => U u -> U u -> SORN u
- Haskus.Format.Binary.Unum: sornBits :: forall u s. (Bits (SORNBackingWord u), KnownNat (UnumSize u), s ~ SORNSize u, KnownNat s) => SORN u -> String
- Haskus.Format.Binary.Unum: sornComplement :: Bits (SORNBackingWord u) => SORN u -> SORN u
- Haskus.Format.Binary.Unum: sornElems :: forall u s. (s ~ SORNSize u, KnownNat s, Bits (SORNBackingWord u), Num (BackingWord u)) => SORN u -> [U u]
- Haskus.Format.Binary.Unum: sornEmpty :: Bits (SORNBackingWord u) => SORN u
- Haskus.Format.Binary.Unum: sornFromElems :: (Integral (BackingWord u), Bits (SORNBackingWord u)) => [U u] -> SORN u
- Haskus.Format.Binary.Unum: sornFromTo :: forall u. (Integral (BackingWord u), Bits (SORNBackingWord u), Bits (BackingWord u), KnownNat (UnumSize u)) => U u -> U u -> SORN u
- Haskus.Format.Binary.Unum: sornFull :: forall u. (Bits (SORNBackingWord u), KnownNat (SORNSize u)) => SORN u
- Haskus.Format.Binary.Unum: sornInsert :: forall u. (Bits (SORNBackingWord u), Integral (BackingWord u)) => SORN u -> U u -> SORN u
- Haskus.Format.Binary.Unum: sornIntersect :: forall u. Bits (SORNBackingWord u) => SORN u -> SORN u -> SORN u
- Haskus.Format.Binary.Unum: sornMember :: forall u. (Bits (SORNBackingWord u), Integral (BackingWord u)) => SORN u -> U u -> Bool
- Haskus.Format.Binary.Unum: sornNegate :: forall u. (Bits (SORNBackingWord u), Bits (BackingWord u), Integral (BackingWord u), KnownNat (SORNSize u), KnownNat (UnumSize u)) => SORN u -> SORN u
- Haskus.Format.Binary.Unum: sornNonInfinite :: forall u. (Bits (SORNBackingWord u), Integral (BackingWord u), Bits (BackingWord u), Encodable Infinite u) => SORN u
- Haskus.Format.Binary.Unum: sornNonZero :: (Bits (SORNBackingWord u), Integral (BackingWord u), Bits (BackingWord u), Encodable (I 0) u) => SORN u
- Haskus.Format.Binary.Unum: sornRemove :: forall u. (Bits (SORNBackingWord u), Integral (BackingWord u)) => SORN u -> U u -> SORN u
- Haskus.Format.Binary.Unum: sornSingle :: (Integral (BackingWord u), Bits (SORNBackingWord u)) => U u -> SORN u
- Haskus.Format.Binary.Unum: sornSize :: forall u s. (s ~ SORNSize u, KnownNat s) => Word
- Haskus.Format.Binary.Unum: sornSub :: (SornAdd u, KnownNat (SORNSize u), Bits (SORNBackingWord u), Bits (BackingWord u), Num (BackingWord u), KnownNat (UnumSize u)) => SORN u -> SORN u -> SORN u
- Haskus.Format.Binary.Unum: sornSubDep :: (SornAdd u, KnownNat (SORNSize u), Bits (SORNBackingWord u), Bits (BackingWord u), Num (BackingWord u), KnownNat (UnumSize u)) => SORN u -> SORN u
- Haskus.Format.Binary.Unum: sornSubU :: (SornAdd u, Bits (BackingWord u), Num (BackingWord u), KnownNat (UnumSize u)) => U u -> U u -> SORN u
- Haskus.Format.Binary.Unum: sornUnion :: forall u. Bits (SORNBackingWord u) => SORN u -> SORN u -> SORN u
- Haskus.Format.Binary.Unum: type Infinite = Rcp (I 0)
- Haskus.Format.Binary.Unum: type family SORNBackingWord u
- Haskus.Format.Binary.Unum: unumBits :: forall u. (Bits (BackingWord u), KnownNat (UnumSize u)) => U u -> String
- Haskus.Format.Binary.Unum: unumEncode :: forall u x i. (i ~ IndexOf (Simplify x) (UnumIndexables u), KnownNat i, Num (BackingWord u), Bits (BackingWord u)) => UBit -> U u
- Haskus.Format.Binary.Unum: unumInfinite :: forall u. (Num (BackingWord u), Bits (BackingWord u), Encodable Infinite u) => U u
- Haskus.Format.Binary.Unum: unumLabel :: UnumNum a => a -> String
- Haskus.Format.Binary.Unum: unumLabels :: forall u v. (HFoldr' GetLabel [String] v [String], v ~ UnumMembers u) => [String]
- Haskus.Format.Binary.Unum: unumNegate :: forall u. (Bits (BackingWord u), Num (BackingWord u), KnownNat (UnumSize u)) => U u -> U u
- Haskus.Format.Binary.Unum: unumReciprocate :: forall u. (Bits (BackingWord u), Num (BackingWord u), KnownNat (UnumSize u)) => U u -> U u
- Haskus.Format.Binary.Unum: unumSign :: forall u. (Bits (BackingWord u), KnownNat (UnumSize u)) => U u -> Sign
- Haskus.Format.Binary.Unum: unumSize :: forall u. KnownNat (UnumSize u) => Word
- Haskus.Format.Binary.Unum: unumZero :: forall u. (Num (BackingWord u), Bits (BackingWord u), Encodable (I 0) u) => U u
- Haskus.Format.Binary.VariableLength: getLEB128Buffer :: BitOrder -> Get Buffer
- Haskus.Format.Binary.VariableLength: getSLEB128 :: (Integral a, Bits a) => Get a
- Haskus.Format.Binary.VariableLength: getULEB128 :: (Integral a, Bits a) => Get a
- Haskus.Format.Binary.VariableLength: putSLEB128 :: (Integral a, Bits a) => a -> Put
- Haskus.Format.Binary.VariableLength: putULEB128 :: (Integral a, Bits a) => a -> Put
- Haskus.Format.Binary.Vector: Vector :: Buffer -> Vector a
- Haskus.Format.Binary.Vector: concat :: forall l (n :: Nat) a. (n ~ WholeSize l, KnownNat n, Storable a, StaticStorable a, HFoldr StoreVector (IO (Ptr a)) l (IO (Ptr a))) => HList l -> Vector n a
- Haskus.Format.Binary.Vector: data Vector (n :: Nat) a
- Haskus.Format.Binary.Vector: drop :: forall n m a. KnownNat (SizeOf a * n) => Vector (m + n) a -> Vector m a
- Haskus.Format.Binary.Vector: fromFilledList :: forall a (n :: Nat). (KnownNat n, Storable a) => a -> [a] -> Vector n a
- Haskus.Format.Binary.Vector: fromFilledListZ :: forall a (n :: Nat). (KnownNat n, Storable a) => a -> [a] -> Vector n a
- Haskus.Format.Binary.Vector: fromList :: forall a (n :: Nat). (KnownNat n, Storable a) => [a] -> Maybe (Vector n a)
- Haskus.Format.Binary.Vector: index :: forall i a n. (KnownNat (ElemOffset a i n), Storable a) => Vector n a -> a
- Haskus.Format.Binary.Vector: instance (GHC.TypeNats.KnownNat (Haskus.Format.Binary.Bits.Finite.BitSize a), Haskus.Format.Binary.Bits.Finite.FiniteBits a, GHC.TypeNats.KnownNat n, Haskus.Format.Binary.Storable.Storable a) => Haskus.Format.Binary.Bits.Finite.FiniteBits (Haskus.Format.Binary.Vector.Vector n a)
- Haskus.Format.Binary.Vector: instance (GHC.TypeNats.KnownNat n, Haskus.Format.Binary.Bits.Bitwise.Bitwise a, Haskus.Format.Binary.Storable.Storable a) => Haskus.Format.Binary.Bits.Bitwise.Bitwise (Haskus.Format.Binary.Vector.Vector n a)
- Haskus.Format.Binary.Vector: instance (GHC.TypeNats.KnownNat n, Haskus.Format.Binary.Storable.Storable a) => Haskus.Format.Binary.Storable.Storable (Haskus.Format.Binary.Vector.Vector n a)
- Haskus.Format.Binary.Vector: instance (GHC.TypeNats.KnownNat n, Haskus.Format.Binary.Storable.Storable a, GHC.Classes.Eq a) => GHC.Classes.Eq (Haskus.Format.Binary.Vector.Vector n a)
- Haskus.Format.Binary.Vector: instance (Haskus.Format.Binary.Storable.Storable a, GHC.Show.Show a, GHC.TypeNats.KnownNat n) => GHC.Show.Show (Haskus.Format.Binary.Vector.Vector n a)
- Haskus.Format.Binary.Vector: instance (Haskus.Format.Binary.Storable.Storable a, Haskus.Format.Binary.Bits.Bits a, GHC.TypeNats.KnownNat n, GHC.TypeNats.KnownNat (n GHC.TypeNats.* Haskus.Format.Binary.Bits.Finite.BitSize a)) => Haskus.Format.Binary.Bits.Rotate.RotatableBits (Haskus.Format.Binary.Vector.Vector n a)
- Haskus.Format.Binary.Vector: instance (Haskus.Format.Binary.Storable.Storable a, Haskus.Format.Binary.Bits.Index.IndexableBits a, Haskus.Format.Binary.Bits.Finite.FiniteBits a, GHC.TypeNats.KnownNat (Haskus.Format.Binary.Bits.Finite.BitSize a), GHC.TypeNats.KnownNat n, Haskus.Format.Binary.Bits.Bitwise.Bitwise a) => Haskus.Format.Binary.Bits.Index.IndexableBits (Haskus.Format.Binary.Vector.Vector n a)
- Haskus.Format.Binary.Vector: instance (Haskus.Format.Binary.Storable.Storable a, Haskus.Format.Binary.Bits.Shift.ShiftableBits a, Haskus.Format.Binary.Bits.Bitwise.Bitwise a, Haskus.Format.Binary.Bits.Finite.FiniteBits a, GHC.TypeNats.KnownNat (Haskus.Format.Binary.Bits.Finite.BitSize a), GHC.TypeNats.KnownNat (n GHC.TypeNats.* Haskus.Format.Binary.Bits.Finite.BitSize a), GHC.TypeNats.KnownNat n) => Haskus.Format.Binary.Bits.Shift.ShiftableBits (Haskus.Format.Binary.Vector.Vector n a)
- Haskus.Format.Binary.Vector: instance (v Data.Type.Equality.~ Haskus.Format.Binary.Vector.Vector n a, r Data.Type.Equality.~ GHC.Types.IO (GHC.Ptr.Ptr a), GHC.TypeNats.KnownNat n, GHC.TypeNats.KnownNat (Haskus.Format.Binary.Storable.SizeOf a), Haskus.Format.Binary.Storable.StaticStorable a, Haskus.Format.Binary.Storable.Storable a) => Haskus.Utils.HList.Apply Haskus.Format.Binary.Vector.StoreVector (v, GHC.Types.IO (GHC.Ptr.Ptr a)) r
- Haskus.Format.Binary.Vector: instance GHC.TypeNats.KnownNat (Haskus.Format.Binary.Storable.SizeOf a GHC.TypeNats.* n) => Haskus.Format.Binary.Storable.StaticStorable (Haskus.Format.Binary.Vector.Vector n a)
- Haskus.Format.Binary.Vector: replicate :: forall a (n :: Nat). (KnownNat n, Storable a) => a -> Vector n a
- Haskus.Format.Binary.Vector: take :: forall n m a. KnownNat (SizeOf a * n) => Vector (m + n) a -> Vector n a
- Haskus.Format.Binary.Vector: toList :: forall a (n :: Nat). (KnownNat n, Storable a) => Vector n a -> [a]
- Haskus.Format.Binary.Vector: vectorBuffer :: Vector n a -> Buffer
- Haskus.Format.Binary.Vector: vectorReverse :: (KnownNat n, Storable a) => Vector n a -> Vector n a
- Haskus.Format.Binary.Vector: zipWith :: (KnownNat n, Storable a, Storable b, Storable c) => (a -> b -> c) -> Vector n a -> Vector n b -> Vector n c
- Haskus.Format.Binary.Word: (+#) :: Int# -> Int# -> Int#
- Haskus.Format.Binary.Word: (-#) :: Int# -> Int# -> Int#
- Haskus.Format.Binary.Word: (<#) :: Int# -> Int# -> Int#
- Haskus.Format.Binary.Word: (<=#) :: Int# -> Int# -> Int#
- Haskus.Format.Binary.Word: (==#) :: Int# -> Int# -> Int#
- Haskus.Format.Binary.Word: (>#) :: Int# -> Int# -> Int#
- Haskus.Format.Binary.Word: (>=#) :: Int# -> Int# -> Int#
- Haskus.Format.Binary.Word: CSize :: Word64 -> CSize
- Haskus.Format.Binary.Word: data CInt
- Haskus.Format.Binary.Word: data CLong
- Haskus.Format.Binary.Word: data CShort
- Haskus.Format.Binary.Word: data CUInt
- Haskus.Format.Binary.Word: data CULong
- Haskus.Format.Binary.Word: data CUShort
- Haskus.Format.Binary.Word: data Int# :: TYPE IntRep
- Haskus.Format.Binary.Word: data Word# :: TYPE WordRep
- Haskus.Format.Binary.Word: eqWord# :: Word# -> Word# -> Int#
- Haskus.Format.Binary.Word: geWord# :: Word# -> Word# -> Int#
- Haskus.Format.Binary.Word: gtWord# :: Word# -> Word# -> Int#
- Haskus.Format.Binary.Word: infix 4 <=#
- Haskus.Format.Binary.Word: infixl 6 -#
- Haskus.Format.Binary.Word: isTrue# :: Int# -> Bool
- Haskus.Format.Binary.Word: leWord# :: Word# -> Word# -> Int#
- Haskus.Format.Binary.Word: ltWord# :: Word# -> Word# -> Int#
- Haskus.Format.Binary.Word: minusWord# :: Word# -> Word# -> Word#
- Haskus.Format.Binary.Word: newtype CSize
- Haskus.Format.Binary.Word: plusWord# :: Word# -> Word# -> Word#
- Haskus.Format.Binary.Word: type family IntN (n :: Nat)
- Haskus.Format.Number.BitNat: (.*.) :: forall a b m. (m ~ (a + b), Widen a m, Widen b m, Num (BitNatWord m)) => BitNat a -> BitNat b -> BitNat m
- Haskus.Format.Number.BitNat: (.+.) :: forall a b m. (m ~ (Max a b + 1), Widen a m, Widen b m, Num (BitNatWord m)) => BitNat a -> BitNat b -> BitNat m
- Haskus.Format.Number.BitNat: (.-.) :: forall a b m. (m ~ Max a b, Widen a m, Widen b m, Num (BitNatWord m)) => BitNat a -> BitNat b -> Maybe (BitNat m)
- Haskus.Format.Number.BitNat: (./.) :: forall a b m. (m ~ Max a b, Widen a m, Widen b m, Num (BitNatWord (Min a b))) => BitNat a -> BitNat b -> Maybe (BitNat a, BitNat (Min a b))
- Haskus.Format.Number.BitNat: (.<<.) :: forall (s :: Nat) a. (ShiftableBits (BitNatWord (a + s)), KnownNat s, Widen a (a + s)) => BitNat a -> NatVal s -> BitNat (a + s)
- Haskus.Format.Number.BitNat: (.>>.) :: forall (s :: Nat) a. (ShiftableBits (BitNatWord a), KnownNat s, Narrow a (a - s)) => BitNat a -> NatVal s -> BitNat (a - s)
- Haskus.Format.Number.BitNat: NatVal :: NatVal
- Haskus.Format.Number.BitNat: compareW :: forall a b. (Ord (BitNatWord (Max a b)), Widen a (Max a b), Widen b (Max a b)) => BitNat a -> BitNat b -> Ordering
- Haskus.Format.Number.BitNat: data BitNat (b :: Nat)
- Haskus.Format.Number.BitNat: data NatVal (t :: Nat)
- Haskus.Format.Number.BitNat: extractW :: BitNat a -> BitNatWord a
- Haskus.Format.Number.BitNat: instance (GHC.TypeNats.KnownNat b, GHC.Real.Integral (Haskus.Format.Number.BitNat.BitNatWord b)) => GHC.Show.Show (Haskus.Format.Number.BitNat.BitNat b)
- Haskus.Format.Number.BitNat: instance GHC.Classes.Eq (Haskus.Format.Number.BitNat.BitNatWord a) => GHC.Classes.Eq (Haskus.Format.Number.BitNat.BitNat a)
- Haskus.Format.Number.BitNat: instance GHC.Classes.Ord (Haskus.Format.Number.BitNat.BitNatWord a) => GHC.Classes.Ord (Haskus.Format.Number.BitNat.BitNat a)
- Haskus.Format.Number.BitNat: narrow :: forall b a. Narrow a b => BitNat a -> BitNat b
- Haskus.Format.Number.BitNat: nat :: forall (v :: Nat) (n :: Nat). (n ~ NatBitCount v, Integral (BitNatWord n), MakeW n, KnownNat v) => BitNat n
- Haskus.Format.Number.BitNat: oneW :: Num (BitNatWord a) => BitNat a
- Haskus.Format.Number.BitNat: pattern BitNat :: forall (n :: Nat). (Integral (BitNatWord n), MakeW n) => Natural -> BitNat n
- Haskus.Format.Number.BitNat: safeMakeW :: forall a. MakeW a => Natural -> Maybe (BitNat a)
- Haskus.Format.Number.BitNat: toNaturalW :: Integral (BitNatWord a) => BitNat a -> Natural
- Haskus.Format.Number.BitNat: type MakeW a = (Maskable a (BitNatWord a), ShiftableBits (BitNatWord a), Show (BitNatWord a), Eq (BitNatWord a), Num (BitNatWord a))
- Haskus.Format.Number.BitNat: type Narrow a b = (Assert (b <=? a) (() :: Constraint) ( 'Text "Can't narrow a natural of " :<>: 'ShowType a :<>: 'Text " bits into a natural of " :<>: 'ShowType b :<>: 'Text " bits"), Integral (BitNatWord a), Integral (BitNatWord b), Maskable b (BitNatWord b))
- Haskus.Format.Number.BitNat: type Widen a b = (Assert (a <=? b) (() :: Constraint) ( 'Text "Can't widen a natural of " :<>: 'ShowType a :<>: 'Text " bits into a natural of " :<>: 'ShowType b :<>: 'Text " bits"), Integral (BitNatWord a), Integral (BitNatWord b))
- Haskus.Format.Number.BitNat: type family BitNatWord b
- Haskus.Format.Number.BitNat: unsafeMakeW :: forall a. Maskable a (BitNatWord a) => BitNatWord a -> BitNat a
- Haskus.Format.Number.BitNat: widen :: forall b a. Widen a b => BitNat a -> BitNat b
- Haskus.Format.Number.BitNat: zeroW :: Num (BitNatWord a) => BitNat a
- Haskus.Format.Number.NaturalRange: (.++.) :: (MakeNatRange f1 t1, MakeNatRange f2 t2, MakeNatRange (f1 + f2) (t1 + t2)) => NatRange f1 t1 -> NatRange f2 t2 -> NatRange (f1 + f2) (t1 + t2)
- Haskus.Format.Number.NaturalRange: data NatRange (f :: Nat) (t :: Nat)
- Haskus.Format.Number.NaturalRange: instance (GHC.TypeNats.KnownNat (t GHC.TypeNats.- f), GHC.TypeNats.KnownNat t, GHC.TypeNats.KnownNat f, GHC.Num.Num (Haskus.Format.Number.BitNat.BitNatWord (Haskus.Utils.Types.Nat.NatBitCount ((t GHC.TypeNats.- f) GHC.TypeNats.+ 1))), GHC.Real.Integral (Haskus.Format.Number.BitNat.BitNatWord (Haskus.Utils.Types.Nat.NatBitCount ((t GHC.TypeNats.- f) GHC.TypeNats.+ 1)))) => GHC.Show.Show (Haskus.Format.Number.NaturalRange.NatRange f t)
- Haskus.Format.Number.NaturalRange: makeNatRange :: forall f t. MakeNatRange f t => Natural -> NatRange f t
- Haskus.Format.Number.NaturalRange: natRange :: forall (n :: Nat) f t. (MakeNatRange f t, CheckInRange f t n, KnownNat n) => NatRange f t
- Haskus.Format.Number.NaturalRange: pattern NatRange :: forall (f :: Nat) (t :: Nat). MakeNatRange f t => Natural -> NatRange f t
- Haskus.Format.Number.NaturalRange: safeMakeNatRange :: forall f t. MakeNatRange f t => Natural -> Maybe (NatRange f t)
- Haskus.Format.Number.NaturalRange: unsafeMakeNatRange :: forall f t. MakeNatRange f t => Natural -> NatRange f t
- Haskus.Format.Number.NaturalRange: widenNatRange :: forall f2 t2 f1 t1. WidenNatRange f1 t1 f2 t2 => NatRange f1 t1 -> NatRange f2 t2
- Haskus.Memory.Buffer: TypedBuffer :: Buffer mut pin fin heap -> TypedBuffer mut pin fin heap
- Haskus.Memory.Buffer: instance GHC.Classes.Eq Haskus.Memory.Buffer.Finalization
- Haskus.Memory.Buffer: instance GHC.Classes.Eq Haskus.Memory.Buffer.Mutability
- Haskus.Memory.Buffer: instance GHC.Classes.Eq Haskus.Memory.Buffer.Pinning
- Haskus.Memory.Buffer: instance GHC.Show.Show Haskus.Memory.Buffer.Finalization
- Haskus.Memory.Buffer: instance GHC.Show.Show Haskus.Memory.Buffer.Mutability
- Haskus.Memory.Buffer: instance GHC.Show.Show Haskus.Memory.Buffer.Pinning
- Haskus.Memory.Buffer: instance Haskus.Memory.Buffer.Freezable (Haskus.Memory.Buffer.Buffer 'Haskus.Memory.Buffer.Mutable pin 'Haskus.Memory.Buffer.Collected heap) (Haskus.Memory.Buffer.Buffer 'Haskus.Memory.Buffer.Immutable pin 'Haskus.Memory.Buffer.Collected heap)
- Haskus.Memory.Buffer: instance Haskus.Memory.Buffer.Freezable (Haskus.Memory.Buffer.Buffer 'Haskus.Memory.Buffer.Mutable pin fin 'Haskus.Memory.Buffer.External) (Haskus.Memory.Buffer.Buffer 'Haskus.Memory.Buffer.Immutable pin fin 'Haskus.Memory.Buffer.External)
- Haskus.Memory.Buffer: instance Haskus.Memory.Buffer.Thawable (Haskus.Memory.Buffer.Buffer 'Haskus.Memory.Buffer.Immutable pin 'Haskus.Memory.Buffer.Collected heap) (Haskus.Memory.Buffer.Buffer 'Haskus.Memory.Buffer.Mutable pin 'Haskus.Memory.Buffer.Collected heap)
- Haskus.Memory.Buffer: instance Haskus.Memory.Buffer.Thawable (Haskus.Memory.Buffer.Buffer 'Haskus.Memory.Buffer.Immutable pin 'Haskus.Memory.Buffer.NotFinalized heap) (Haskus.Memory.Buffer.Buffer 'Haskus.Memory.Buffer.Mutable pin 'Haskus.Memory.Buffer.NotFinalized heap)
- Haskus.Memory.Buffer: newtype TypedBuffer (t :: k) mut pin fin heap
- Haskus.Utils.Memory: allocaArrays :: (MonadInIO m, Storable s, Integral a) => [a] -> ([Ptr s] -> m b) -> m b
- Haskus.Utils.Memory: memCopy :: MonadIO m => Ptr a -> Ptr b -> Word64 -> m ()
- Haskus.Utils.Memory: memSet :: MonadIO m => Ptr a -> Word64 -> Word8 -> m ()
- Haskus.Utils.Memory: peekArrays :: (MonadIO m, Storable s, Integral a) => [a] -> [Ptr s] -> m [[s]]
- Haskus.Utils.Memory: pokeArrays :: (MonadIO m, Storable s) => [Ptr s] -> [[s]] -> m ()
- Haskus.Utils.Memory: withArrays :: (MonadInIO m, Storable s) => [[s]] -> ([Ptr s] -> m b) -> m b
- Haskus.Utils.Memory: withMaybeOrNull :: (Storable a, MonadInIO m) => Maybe a -> (Ptr a -> m b) -> m b
+ Haskus.Binary.BitField: BitField :: s -> BitField s
+ Haskus.Binary.BitField: BitFields :: b -> BitFields b
+ Haskus.Binary.BitField: bitFieldsBits :: BitFields b f -> b
+ Haskus.Binary.BitField: class Field f
+ Haskus.Binary.BitField: extractField :: forall (name :: Symbol) fields b. (KnownNat (Offset name fields), KnownNat (Size name fields), WholeSize fields ~ BitSize b, Bits b, Integral b, Field (Output name fields)) => BitFields b fields -> Output name fields
+ Haskus.Binary.BitField: extractField' :: forall (name :: Symbol) fields b. (KnownNat (Offset name fields), KnownNat (Size name fields), Bits b, Integral b, Field (Output name fields)) => BitFields b fields -> Output name fields
+ Haskus.Binary.BitField: instance (GHC.Real.Integral b, Haskus.Binary.Enum.CEnum a) => Haskus.Binary.BitField.Field (Haskus.Binary.Enum.EnumField b a)
+ Haskus.Binary.BitField: instance (Haskus.Binary.Bits.Finite.FiniteBits b, GHC.Real.Integral b, Haskus.Binary.BitSet.BitOffset a) => Haskus.Binary.BitField.Field (Haskus.Binary.BitSet.BitSet b a)
+ Haskus.Binary.BitField: instance (bs Data.Type.Equality.~ Haskus.Binary.BitField.BitFields w l, b Data.Type.Equality.~ Haskus.Binary.BitField.BitField n name s, i Data.Type.Equality.~ (bs, Haskus.Utils.HList.HList l2), r Data.Type.Equality.~ (bs, Haskus.Utils.HList.HList (Haskus.Binary.BitField.Output name l : l2)), Haskus.Binary.Bits.Finite.BitSize w Data.Type.Equality.~ Haskus.Binary.BitField.WholeSize l, GHC.Real.Integral w, Haskus.Binary.Bits.Bits w, GHC.TypeNats.KnownNat (Haskus.Binary.BitField.Offset name l), GHC.TypeNats.KnownNat (Haskus.Binary.BitField.Size name l), Haskus.Binary.BitField.Field (Haskus.Binary.BitField.Output name l)) => Haskus.Utils.HList.Apply Haskus.Binary.BitField.Extract (b, i) r
+ Haskus.Binary.BitField: instance (bs Data.Type.Equality.~ Haskus.Binary.BitField.BitFields w l, b Data.Type.Equality.~ Haskus.Binary.BitField.BitField n name s, i Data.Type.Equality.~ Haskus.Utils.HList.HList l2, r Data.Type.Equality.~ Haskus.Utils.HList.HList (GHC.Base.String : l2), GHC.TypeLits.KnownSymbol name) => Haskus.Utils.HList.Apply Haskus.Binary.BitField.Name (b, i) r
+ Haskus.Binary.BitField: instance (bs Data.Type.Equality.~ Haskus.Binary.BitField.BitFields w lt, Haskus.Utils.HList.HFoldr' Haskus.Binary.BitField.Extract (bs, Haskus.Utils.HList.HList '[]) lt (bs, Haskus.Utils.HList.HList lt2), GHC.Classes.Eq (Haskus.Utils.HList.HList lt2), lt2 Data.Type.Equality.~ Haskus.Binary.BitField.BitFieldTypes lt) => GHC.Classes.Eq (Haskus.Binary.BitField.BitFields w lt)
+ Haskus.Binary.BitField: instance (bs Data.Type.Equality.~ Haskus.Binary.BitField.BitFields w lt, ln Data.Type.Equality.~ Haskus.Utils.Types.List.Replicate (Haskus.Utils.Types.List.Length lt) GHC.Base.String, Haskus.Utils.HList.HFoldr' Haskus.Binary.BitField.Extract (bs, Haskus.Utils.HList.HList '[]) lt (bs, Haskus.Utils.HList.HList (Haskus.Binary.BitField.BitFieldTypes lt)), Haskus.Utils.HList.HFoldr' Haskus.Binary.BitField.Name (Haskus.Utils.HList.HList '[]) lt (Haskus.Utils.HList.HList ln), Haskus.Utils.HList.HZipList ln (Haskus.Binary.BitField.BitFieldTypes lt) lnv, GHC.Show.Show (Haskus.Utils.HList.HList lnv)) => GHC.Show.Show (Haskus.Binary.BitField.BitFields w lt)
+ Haskus.Binary.BitField: instance Haskus.Binary.BitField.Field GHC.Int.Int16
+ Haskus.Binary.BitField: instance Haskus.Binary.BitField.Field GHC.Int.Int32
+ Haskus.Binary.BitField: instance Haskus.Binary.BitField.Field GHC.Int.Int64
+ Haskus.Binary.BitField: instance Haskus.Binary.BitField.Field GHC.Int.Int8
+ Haskus.Binary.BitField: instance Haskus.Binary.BitField.Field GHC.Types.Bool
+ Haskus.Binary.BitField: instance Haskus.Binary.BitField.Field GHC.Types.Int
+ Haskus.Binary.BitField: instance Haskus.Binary.BitField.Field GHC.Types.Word
+ Haskus.Binary.BitField: instance Haskus.Binary.BitField.Field GHC.Word.Word16
+ Haskus.Binary.BitField: instance Haskus.Binary.BitField.Field GHC.Word.Word32
+ Haskus.Binary.BitField: instance Haskus.Binary.BitField.Field GHC.Word.Word64
+ Haskus.Binary.BitField: instance Haskus.Binary.BitField.Field GHC.Word.Word8
+ Haskus.Binary.BitField: instance Haskus.Binary.Storable.Storable b => Haskus.Binary.Storable.Storable (Haskus.Binary.BitField.BitFields b f)
+ Haskus.Binary.BitField: instance Haskus.Binary.Storable.Storable s => Haskus.Binary.Storable.Storable (Haskus.Binary.BitField.BitField n name s)
+ Haskus.Binary.BitField: matchFields :: forall l l2 w bs t. (bs ~ BitFields w l, HFoldr' Extract (bs, HList '[]) l (bs, HList l2), HTuple l2, t ~ Tuple l2) => bs -> t
+ Haskus.Binary.BitField: matchNamedFields :: forall lt lv ln lnv w bs t. (bs ~ BitFields w lt, HFoldr' Extract (bs, HList '[]) lt (bs, HList lv), HFoldr' Name (HList '[]) lt (HList ln), HZipList ln lv lnv, HTuple lnv, t ~ Tuple lnv) => bs -> t
+ Haskus.Binary.BitField: newtype BitField (n :: Nat) (name :: Symbol) s
+ Haskus.Binary.BitField: newtype BitFields b (f :: [*])
+ Haskus.Binary.BitField: updateField :: forall name fields b. (KnownNat (Offset name fields), KnownNat (Size name fields), WholeSize fields ~ BitSize b, Bits b, Integral b, Field (Output name fields)) => Output name fields -> BitFields b fields -> BitFields b fields
+ Haskus.Binary.BitField: updateField' :: forall name fields b. (KnownNat (Offset name fields), KnownNat (Size name fields), Bits b, Integral b, Field (Output name fields)) => Output name fields -> BitFields b fields -> BitFields b fields
+ Haskus.Binary.BitField: withField :: forall name fields b f. (KnownNat (Offset name fields), KnownNat (Size name fields), WholeSize fields ~ BitSize b, Bits b, Integral b, f ~ Output name fields, Field f) => (f -> f) -> BitFields b fields -> BitFields b fields
+ Haskus.Binary.BitField: withField' :: forall (name :: Symbol) fields b f. (KnownNat (Offset name fields), KnownNat (Size name fields), Bits b, Integral b, f ~ Output name fields, Field f) => (f -> f) -> BitFields b fields -> BitFields b fields
+ Haskus.Binary.BitSet: class BitOffset a
+ Haskus.Binary.BitSet: data BitSet b a
+ Haskus.Binary.BitSet: delete :: (IndexableBits b, BitOffset a) => BitSet b a -> a -> BitSet b a
+ Haskus.Binary.BitSet: elem :: (BitOffset a, FiniteBits b, IndexableBits b) => a -> BitSet b a -> Bool
+ Haskus.Binary.BitSet: elems :: (BitOffset a, FiniteBits b, IndexableBits b, Eq b) => BitSet b a -> [a]
+ Haskus.Binary.BitSet: empty :: FiniteBits b => BitSet b a
+ Haskus.Binary.BitSet: enumerateSetBits :: (BitOffset a, FiniteBits b, IndexableBits b, Eq b, Bounded a, Enum a) => b -> [a]
+ Haskus.Binary.BitSet: fromBitOffset :: (BitOffset a, Enum a) => Word -> a
+ Haskus.Binary.BitSet: fromBits :: (BitOffset a, FiniteBits b) => b -> BitSet b a
+ Haskus.Binary.BitSet: fromList :: (BitOffset a, IndexableBits b, FiniteBits b, Foldable m) => m a -> BitSet b a
+ Haskus.Binary.BitSet: fromListToBits :: (BitOffset a, FiniteBits b, IndexableBits b, Foldable m) => m a -> b
+ Haskus.Binary.BitSet: insert :: (IndexableBits b, BitOffset a) => BitSet b a -> a -> BitSet b a
+ Haskus.Binary.BitSet: instance (GHC.Show.Show a, Haskus.Binary.BitSet.BitOffset a, Haskus.Binary.Bits.Finite.FiniteBits b, Haskus.Binary.Bits.Index.IndexableBits b, GHC.Classes.Eq b) => GHC.Show.Show (Haskus.Binary.BitSet.BitSet b a)
+ Haskus.Binary.BitSet: instance (Haskus.Binary.Bits.Finite.FiniteBits b, Haskus.Binary.Bits.Index.IndexableBits b, Haskus.Binary.BitSet.BitOffset a, GHC.Classes.Eq b) => GHC.Exts.IsList (Haskus.Binary.BitSet.BitSet b a)
+ Haskus.Binary.BitSet: instance GHC.Classes.Eq b => GHC.Classes.Eq (Haskus.Binary.BitSet.BitSet b a)
+ Haskus.Binary.BitSet: instance GHC.Classes.Ord b => GHC.Classes.Ord (Haskus.Binary.BitSet.BitSet b a)
+ Haskus.Binary.BitSet: instance Haskus.Binary.BitSet.BitOffset GHC.Types.Int
+ Haskus.Binary.BitSet: instance Haskus.Binary.BitSet.BitOffset GHC.Types.Word
+ Haskus.Binary.BitSet: instance Haskus.Binary.Storable.Storable b => Haskus.Binary.Storable.Storable (Haskus.Binary.BitSet.BitSet b a)
+ Haskus.Binary.BitSet: intersection :: (FiniteBits b, Bitwise b) => BitSet b a -> BitSet b a -> BitSet b a
+ Haskus.Binary.BitSet: member :: (BitOffset a, FiniteBits b, IndexableBits b) => BitSet b a -> a -> Bool
+ Haskus.Binary.BitSet: notMember :: (BitOffset a, FiniteBits b, IndexableBits b) => BitSet b a -> a -> Bool
+ Haskus.Binary.BitSet: null :: (FiniteBits b, Eq b) => BitSet b a -> Bool
+ Haskus.Binary.BitSet: singleton :: (IndexableBits b, BitOffset a) => a -> BitSet b a
+ Haskus.Binary.BitSet: toBitOffset :: (BitOffset a, Enum a) => a -> Word
+ Haskus.Binary.BitSet: toBits :: BitSet b a -> b
+ Haskus.Binary.BitSet: toList :: (BitOffset a, FiniteBits b, IndexableBits b, Eq b) => BitSet b a -> [a]
+ Haskus.Binary.BitSet: toListFromBits :: (BitOffset a, FiniteBits b, IndexableBits b, Eq b) => b -> [a]
+ Haskus.Binary.BitSet: union :: (FiniteBits b, Bitwise b) => BitSet b a -> BitSet b a -> BitSet b a
+ Haskus.Binary.BitSet: unions :: (FiniteBits b, Bitwise b) => [BitSet b a] -> BitSet b a
+ Haskus.Binary.Bits: (.&.) :: Bitwise a => a -> a -> a
+ Haskus.Binary.Bits: (.|.) :: Bitwise a => a -> a -> a
+ Haskus.Binary.Bits: -- | Number of bits
+ Haskus.Binary.Bits: bit :: (IndexableBits a, Num a, ShiftableBits a) => Word -> a
+ Haskus.Binary.Bits: bitOffset :: Word -> Word
+ Haskus.Binary.Bits: bitSize :: (FiniteBits a, Integral i, KnownNat (BitSize a)) => a -> i
+ Haskus.Binary.Bits: bitsFromString :: Bits a => String -> a
+ Haskus.Binary.Bits: bitsToString :: forall a. (FiniteBits a, IndexableBits a, KnownNat (BitSize a)) => a -> String
+ Haskus.Binary.Bits: bitsToStringN :: forall a. IndexableBits a => Word -> a -> String
+ Haskus.Binary.Bits: byteOffset :: Word -> Word
+ Haskus.Binary.Bits: class Bitwise a
+ Haskus.Binary.Bits: class FiniteBits a where {
+ Haskus.Binary.Bits: class IndexableBits a
+ Haskus.Binary.Bits: class MaskBits a
+ Haskus.Binary.Bits: class ReversableBits w
+ Haskus.Binary.Bits: class RotatableBits a
+ Haskus.Binary.Bits: class ShiftableBits a
+ Haskus.Binary.Bits: class SignedShiftableBits a
+ Haskus.Binary.Bits: clearBit :: (IndexableBits a, FiniteBits a, Bitwise a) => a -> Word -> a
+ Haskus.Binary.Bits: complement :: FiniteBits a => a -> a
+ Haskus.Binary.Bits: complementBit :: (IndexableBits a, Bitwise a) => a -> Word -> a
+ Haskus.Binary.Bits: countLeadingZeros :: FiniteBits a => a -> Word
+ Haskus.Binary.Bits: countTrailingZeros :: FiniteBits a => a -> Word
+ Haskus.Binary.Bits: getBitRange :: forall b. (ShiftableBits b, ReversableBits b, FiniteBits b, KnownNat (BitSize b), Bitwise b, MaskBits b) => BitOrder -> Word -> Word -> b -> b
+ Haskus.Binary.Bits: getPowerOfFour :: (IndexableBits a, FiniteBits a) => a -> Maybe Word
+ Haskus.Binary.Bits: getPowerOfTwo :: (IndexableBits a, FiniteBits a) => a -> Maybe Word
+ Haskus.Binary.Bits: isPowerOfFour :: (IndexableBits a, FiniteBits a) => a -> Bool
+ Haskus.Binary.Bits: isPowerOfTwo :: IndexableBits a => a -> Bool
+ Haskus.Binary.Bits: makeMaskDyn :: MaskBits a => Word -> a
+ Haskus.Binary.Bits: mask :: forall n a. Maskable n a => a -> a
+ Haskus.Binary.Bits: maskDyn :: (MaskBits a, Bitwise a) => Word -> a -> a
+ Haskus.Binary.Bits: oneBits :: FiniteBits a => a
+ Haskus.Binary.Bits: popCount :: (IndexableBits a, Bitwise a, Num a, Eq a) => a -> Word
+ Haskus.Binary.Bits: reverseBits :: ReversableBits w => w -> w
+ Haskus.Binary.Bits: reverseBitsGeneric :: (FiniteBits a, Integral a, ShiftableBits a, Bitwise a, KnownNat (BitSize a)) => a -> a
+ Haskus.Binary.Bits: reverseLeastBits :: (ShiftableBits a, FiniteBits a, ReversableBits a, KnownNat (BitSize a)) => Word -> a -> a
+ Haskus.Binary.Bits: rotate :: (RotatableBits a, FiniteBits a, KnownNat (BitSize a)) => a -> Int -> a
+ Haskus.Binary.Bits: rotateL :: (RotatableBits a, FiniteBits a, KnownNat (BitSize a)) => a -> Word -> a
+ Haskus.Binary.Bits: rotateR :: (RotatableBits a, FiniteBits a, KnownNat (BitSize a)) => a -> Word -> a
+ Haskus.Binary.Bits: setBit :: (IndexableBits a, Bitwise a) => a -> Word -> a
+ Haskus.Binary.Bits: shift :: ShiftableBits a => a -> Int -> a
+ Haskus.Binary.Bits: shiftL :: ShiftableBits a => a -> Word -> a
+ Haskus.Binary.Bits: shiftR :: ShiftableBits a => a -> Word -> a
+ Haskus.Binary.Bits: signedShift :: SignedShiftableBits a => a -> Int -> a
+ Haskus.Binary.Bits: signedShiftL :: SignedShiftableBits a => a -> Word -> a
+ Haskus.Binary.Bits: signedShiftR :: SignedShiftableBits a => a -> Word -> a
+ Haskus.Binary.Bits: testBit :: (IndexableBits a, Bitwise a, Num a, Eq a) => a -> Word -> Bool
+ Haskus.Binary.Bits: type Bits a = (Eq a, FiniteBits a, IndexableBits a, ShiftableBits a, Bitwise a, RotatableBits a, KnownNat (BitSize a), MaskBits a)
+ Haskus.Binary.Bits: type Maskable n a = (MaskBits a, Bitwise a, KnownNat n)
+ Haskus.Binary.Bits: type family BitSize a :: Nat;
+ Haskus.Binary.Bits: uncheckedRotate :: RotatableBits a => a -> Int -> a
+ Haskus.Binary.Bits: uncheckedRotateL :: (RotatableBits a, ShiftableBits a, FiniteBits a, KnownNat (BitSize a), Bitwise a) => a -> Word -> a
+ Haskus.Binary.Bits: uncheckedRotateR :: (RotatableBits a, ShiftableBits a, FiniteBits a, KnownNat (BitSize a), Bitwise a) => a -> Word -> a
+ Haskus.Binary.Bits: uncheckedShift :: ShiftableBits a => a -> Int -> a
+ Haskus.Binary.Bits: uncheckedShiftL :: ShiftableBits a => a -> Word -> a
+ Haskus.Binary.Bits: uncheckedShiftR :: ShiftableBits a => a -> Word -> a
+ Haskus.Binary.Bits: uncheckedSignedShift :: SignedShiftableBits a => a -> Int -> a
+ Haskus.Binary.Bits: uncheckedSignedShiftL :: SignedShiftableBits a => a -> Word -> a
+ Haskus.Binary.Bits: uncheckedSignedShiftR :: SignedShiftableBits a => a -> Word -> a
+ Haskus.Binary.Bits: xor :: Bitwise a => a -> a -> a
+ Haskus.Binary.Bits: zeroBits :: FiniteBits a => a
+ Haskus.Binary.Bits: }
+ Haskus.Binary.Bits.Bitwise: (.&.) :: Bitwise a => a -> a -> a
+ Haskus.Binary.Bits.Bitwise: (.|.) :: Bitwise a => a -> a -> a
+ Haskus.Binary.Bits.Bitwise: class Bitwise a
+ Haskus.Binary.Bits.Bitwise: instance Haskus.Binary.Bits.Bitwise.Bitwise GHC.Int.Int16
+ Haskus.Binary.Bits.Bitwise: instance Haskus.Binary.Bits.Bitwise.Bitwise GHC.Int.Int32
+ Haskus.Binary.Bits.Bitwise: instance Haskus.Binary.Bits.Bitwise.Bitwise GHC.Int.Int64
+ Haskus.Binary.Bits.Bitwise: instance Haskus.Binary.Bits.Bitwise.Bitwise GHC.Int.Int8
+ Haskus.Binary.Bits.Bitwise: instance Haskus.Binary.Bits.Bitwise.Bitwise GHC.Integer.Type.Integer
+ Haskus.Binary.Bits.Bitwise: instance Haskus.Binary.Bits.Bitwise.Bitwise GHC.Natural.Natural
+ Haskus.Binary.Bits.Bitwise: instance Haskus.Binary.Bits.Bitwise.Bitwise GHC.Types.Int
+ Haskus.Binary.Bits.Bitwise: instance Haskus.Binary.Bits.Bitwise.Bitwise GHC.Types.Word
+ Haskus.Binary.Bits.Bitwise: instance Haskus.Binary.Bits.Bitwise.Bitwise GHC.Word.Word16
+ Haskus.Binary.Bits.Bitwise: instance Haskus.Binary.Bits.Bitwise.Bitwise GHC.Word.Word32
+ Haskus.Binary.Bits.Bitwise: instance Haskus.Binary.Bits.Bitwise.Bitwise GHC.Word.Word64
+ Haskus.Binary.Bits.Bitwise: instance Haskus.Binary.Bits.Bitwise.Bitwise GHC.Word.Word8
+ Haskus.Binary.Bits.Bitwise: xor :: Bitwise a => a -> a -> a
+ Haskus.Binary.Bits.Finite: -- | Number of bits
+ Haskus.Binary.Bits.Finite: bitSize :: (FiniteBits a, Integral i, KnownNat (BitSize a)) => a -> i
+ Haskus.Binary.Bits.Finite: class FiniteBits a where {
+ Haskus.Binary.Bits.Finite: complement :: FiniteBits a => a -> a
+ Haskus.Binary.Bits.Finite: countLeadingZeros :: FiniteBits a => a -> Word
+ Haskus.Binary.Bits.Finite: countTrailingZeros :: FiniteBits a => a -> Word
+ Haskus.Binary.Bits.Finite: instance Haskus.Binary.Bits.Finite.FiniteBits GHC.Int.Int16
+ Haskus.Binary.Bits.Finite: instance Haskus.Binary.Bits.Finite.FiniteBits GHC.Int.Int32
+ Haskus.Binary.Bits.Finite: instance Haskus.Binary.Bits.Finite.FiniteBits GHC.Int.Int64
+ Haskus.Binary.Bits.Finite: instance Haskus.Binary.Bits.Finite.FiniteBits GHC.Int.Int8
+ Haskus.Binary.Bits.Finite: instance Haskus.Binary.Bits.Finite.FiniteBits GHC.Types.Int
+ Haskus.Binary.Bits.Finite: instance Haskus.Binary.Bits.Finite.FiniteBits GHC.Types.Word
+ Haskus.Binary.Bits.Finite: instance Haskus.Binary.Bits.Finite.FiniteBits GHC.Word.Word16
+ Haskus.Binary.Bits.Finite: instance Haskus.Binary.Bits.Finite.FiniteBits GHC.Word.Word32
+ Haskus.Binary.Bits.Finite: instance Haskus.Binary.Bits.Finite.FiniteBits GHC.Word.Word64
+ Haskus.Binary.Bits.Finite: instance Haskus.Binary.Bits.Finite.FiniteBits GHC.Word.Word8
+ Haskus.Binary.Bits.Finite: oneBits :: FiniteBits a => a
+ Haskus.Binary.Bits.Finite: type family BitSize a :: Nat;
+ Haskus.Binary.Bits.Finite: zeroBits :: FiniteBits a => a
+ Haskus.Binary.Bits.Finite: }
+ Haskus.Binary.Bits.Get: BitGetState :: {-# UNPACK #-} !Buffer -> {-# UNPACK #-} !Word -> !BitOrder -> BitGetState
+ Haskus.Binary.Bits.Get: [bitGetStateBitOffset] :: BitGetState -> {-# UNPACK #-} !Word
+ Haskus.Binary.Bits.Get: [bitGetStateBitOrder] :: BitGetState -> !BitOrder
+ Haskus.Binary.Bits.Get: [bitGetStateInput] :: BitGetState -> {-# UNPACK #-} !Buffer
+ Haskus.Binary.Bits.Get: changeBitGetOrder :: Monad m => BitOrder -> BitGetT m ()
+ Haskus.Binary.Bits.Get: data BitGetState
+ Haskus.Binary.Bits.Get: getBitBoolM :: Monad m => BitGetT m Bool
+ Haskus.Binary.Bits.Get: getBits :: (Integral a, Bits a) => Word -> BitGetState -> a
+ Haskus.Binary.Bits.Get: getBitsBSM :: Monad m => Word -> BitGetT m Buffer
+ Haskus.Binary.Bits.Get: getBitsBuffer :: Word -> BitGetState -> Buffer
+ Haskus.Binary.Bits.Get: getBitsChecked :: (Integral a, Bits a, ReversableBits a) => Word -> Word -> BitGetState -> a
+ Haskus.Binary.Bits.Get: getBitsCheckedM :: (Integral a, Bits a, ReversableBits a, Monad m) => Word -> Word -> BitGetT m a
+ Haskus.Binary.Bits.Get: getBitsM :: (Integral a, Bits a, Monad m) => Word -> BitGetT m a
+ Haskus.Binary.Bits.Get: instance GHC.Show.Show Haskus.Binary.Bits.Get.BitGetState
+ Haskus.Binary.Bits.Get: isEmpty :: BitGetState -> Bool
+ Haskus.Binary.Bits.Get: isEmptyM :: Monad m => BitGetT m Bool
+ Haskus.Binary.Bits.Get: newBitGetState :: BitOrder -> Buffer -> BitGetState
+ Haskus.Binary.Bits.Get: resumeBitGetPartial :: BitGet a -> BitGetState -> (a, BitGetState)
+ Haskus.Binary.Bits.Get: resumeBitGetPartialT :: BitGetT m a -> BitGetState -> m (a, BitGetState)
+ Haskus.Binary.Bits.Get: runBitGet :: BitOrder -> BitGet a -> Buffer -> a
+ Haskus.Binary.Bits.Get: runBitGetPartial :: BitOrder -> BitGet a -> Buffer -> (a, BitGetState)
+ Haskus.Binary.Bits.Get: runBitGetPartialT :: BitOrder -> BitGetT m a -> Buffer -> m (a, BitGetState)
+ Haskus.Binary.Bits.Get: runBitGetT :: Monad m => BitOrder -> BitGetT m a -> Buffer -> m a
+ Haskus.Binary.Bits.Get: skipBits :: Word -> BitGetState -> BitGetState
+ Haskus.Binary.Bits.Get: skipBitsM :: Monad m => Word -> BitGetT m ()
+ Haskus.Binary.Bits.Get: skipBitsToAlignOnWord8 :: BitGetState -> BitGetState
+ Haskus.Binary.Bits.Get: skipBitsToAlignOnWord8M :: Monad m => BitGetT m ()
+ Haskus.Binary.Bits.Get: type BitGet a = BitGetT Identity a
+ Haskus.Binary.Bits.Get: type BitGetT m a = StateT BitGetState m a
+ Haskus.Binary.Bits.Get: withBitGetOrder :: Monad m => BitOrder -> BitGetT m a -> BitGetT m a
+ Haskus.Binary.Bits.Helper: bitOffset :: Word -> Word
+ Haskus.Binary.Bits.Helper: byteOffset :: Word -> Word
+ Haskus.Binary.Bits.Index: bit :: (IndexableBits a, Num a, ShiftableBits a) => Word -> a
+ Haskus.Binary.Bits.Index: class IndexableBits a
+ Haskus.Binary.Bits.Index: clearBit :: (IndexableBits a, FiniteBits a, Bitwise a) => a -> Word -> a
+ Haskus.Binary.Bits.Index: complementBit :: (IndexableBits a, Bitwise a) => a -> Word -> a
+ Haskus.Binary.Bits.Index: instance Haskus.Binary.Bits.Index.IndexableBits GHC.Int.Int16
+ Haskus.Binary.Bits.Index: instance Haskus.Binary.Bits.Index.IndexableBits GHC.Int.Int32
+ Haskus.Binary.Bits.Index: instance Haskus.Binary.Bits.Index.IndexableBits GHC.Int.Int64
+ Haskus.Binary.Bits.Index: instance Haskus.Binary.Bits.Index.IndexableBits GHC.Int.Int8
+ Haskus.Binary.Bits.Index: instance Haskus.Binary.Bits.Index.IndexableBits GHC.Integer.Type.Integer
+ Haskus.Binary.Bits.Index: instance Haskus.Binary.Bits.Index.IndexableBits GHC.Natural.Natural
+ Haskus.Binary.Bits.Index: instance Haskus.Binary.Bits.Index.IndexableBits GHC.Types.Int
+ Haskus.Binary.Bits.Index: instance Haskus.Binary.Bits.Index.IndexableBits GHC.Types.Word
+ Haskus.Binary.Bits.Index: instance Haskus.Binary.Bits.Index.IndexableBits GHC.Word.Word16
+ Haskus.Binary.Bits.Index: instance Haskus.Binary.Bits.Index.IndexableBits GHC.Word.Word32
+ Haskus.Binary.Bits.Index: instance Haskus.Binary.Bits.Index.IndexableBits GHC.Word.Word64
+ Haskus.Binary.Bits.Index: instance Haskus.Binary.Bits.Index.IndexableBits GHC.Word.Word8
+ Haskus.Binary.Bits.Index: popCount :: (IndexableBits a, Bitwise a, Num a, Eq a) => a -> Word
+ Haskus.Binary.Bits.Index: setBit :: (IndexableBits a, Bitwise a) => a -> Word -> a
+ Haskus.Binary.Bits.Index: testBit :: (IndexableBits a, Bitwise a, Num a, Eq a) => a -> Word -> Bool
+ Haskus.Binary.Bits.Mask: class MaskBits a
+ Haskus.Binary.Bits.Mask: instance Haskus.Binary.Bits.Mask.MaskBits GHC.Int.Int16
+ Haskus.Binary.Bits.Mask: instance Haskus.Binary.Bits.Mask.MaskBits GHC.Int.Int32
+ Haskus.Binary.Bits.Mask: instance Haskus.Binary.Bits.Mask.MaskBits GHC.Int.Int64
+ Haskus.Binary.Bits.Mask: instance Haskus.Binary.Bits.Mask.MaskBits GHC.Int.Int8
+ Haskus.Binary.Bits.Mask: instance Haskus.Binary.Bits.Mask.MaskBits GHC.Natural.Natural
+ Haskus.Binary.Bits.Mask: instance Haskus.Binary.Bits.Mask.MaskBits GHC.Types.Int
+ Haskus.Binary.Bits.Mask: instance Haskus.Binary.Bits.Mask.MaskBits GHC.Types.Word
+ Haskus.Binary.Bits.Mask: instance Haskus.Binary.Bits.Mask.MaskBits GHC.Word.Word16
+ Haskus.Binary.Bits.Mask: instance Haskus.Binary.Bits.Mask.MaskBits GHC.Word.Word32
+ Haskus.Binary.Bits.Mask: instance Haskus.Binary.Bits.Mask.MaskBits GHC.Word.Word64
+ Haskus.Binary.Bits.Mask: instance Haskus.Binary.Bits.Mask.MaskBits GHC.Word.Word8
+ Haskus.Binary.Bits.Mask: makeMask :: forall n a. (KnownNat n, MaskBits a) => a
+ Haskus.Binary.Bits.Mask: makeMaskDyn :: MaskBits a => Word -> a
+ Haskus.Binary.Bits.Mask: makeMaskFinite :: forall a. (ShiftableBits a, FiniteBits a, KnownNat (BitSize a), Bitwise a) => Word -> a
+ Haskus.Binary.Bits.Mask: mask :: forall n a. Maskable n a => a -> a
+ Haskus.Binary.Bits.Mask: maskDyn :: (MaskBits a, Bitwise a) => Word -> a -> a
+ Haskus.Binary.Bits.Mask: type Maskable n a = (MaskBits a, Bitwise a, KnownNat n)
+ Haskus.Binary.Bits.Order: BB :: BitOrder
+ Haskus.Binary.Bits.Order: BL :: BitOrder
+ Haskus.Binary.Bits.Order: LB :: BitOrder
+ Haskus.Binary.Bits.Order: LL :: BitOrder
+ Haskus.Binary.Bits.Order: data BitOrder
+ Haskus.Binary.Bits.Order: instance GHC.Classes.Eq Haskus.Binary.Bits.Order.BitOrder
+ Haskus.Binary.Bits.Order: instance GHC.Show.Show Haskus.Binary.Bits.Order.BitOrder
+ Haskus.Binary.Bits.Put: BitPutState :: !BufferBuilder -> !Word8 -> !Word -> !BitOrder -> BitPutState
+ Haskus.Binary.Bits.Put: [bitPutStateBitOrder] :: BitPutState -> !BitOrder
+ Haskus.Binary.Bits.Put: [bitPutStateBuilder] :: BitPutState -> !BufferBuilder
+ Haskus.Binary.Bits.Put: [bitPutStateCurrent] :: BitPutState -> !Word8
+ Haskus.Binary.Bits.Put: [bitPutStateOffset] :: BitPutState -> !Word
+ Haskus.Binary.Bits.Put: changeBitPutOrder :: Monad m => BitOrder -> BitPutT m ()
+ Haskus.Binary.Bits.Put: data BitPutState
+ Haskus.Binary.Bits.Put: getBitPutBuffer :: BitPutState -> Buffer
+ Haskus.Binary.Bits.Put: getBitPutBufferList :: BitPutState -> BufferList
+ Haskus.Binary.Bits.Put: newBitPutState :: BitOrder -> BitPutState
+ Haskus.Binary.Bits.Put: putBitBoolM :: Monad m => Bool -> BitPutT m ()
+ Haskus.Binary.Bits.Put: putBits :: (Integral a, Bits a, ReversableBits a) => Word -> a -> BitPutState -> BitPutState
+ Haskus.Binary.Bits.Put: putBitsBuffer :: Buffer -> BitPutState -> BitPutState
+ Haskus.Binary.Bits.Put: putBitsBufferM :: Monad m => Buffer -> BitPutT m ()
+ Haskus.Binary.Bits.Put: putBitsM :: (Monad m, Integral a, Bits a, ReversableBits a) => Word -> a -> BitPutT m ()
+ Haskus.Binary.Bits.Put: runBitPut :: BitOrder -> BitPut a -> Buffer
+ Haskus.Binary.Bits.Put: runBitPutT :: Monad m => BitOrder -> BitPutT m a -> m Buffer
+ Haskus.Binary.Bits.Put: type BitPut a = BitPutT Identity a
+ Haskus.Binary.Bits.Put: type BitPutT m a = StateT BitPutState m a
+ Haskus.Binary.Bits.Put: withBitPutOrder :: Monad m => BitOrder -> BitPutT m a -> BitPutT m a
+ Haskus.Binary.Bits.Reverse: class ReversableBits w
+ Haskus.Binary.Bits.Reverse: instance Haskus.Binary.Bits.Reverse.ReversableBits GHC.Int.Int16
+ Haskus.Binary.Bits.Reverse: instance Haskus.Binary.Bits.Reverse.ReversableBits GHC.Int.Int32
+ Haskus.Binary.Bits.Reverse: instance Haskus.Binary.Bits.Reverse.ReversableBits GHC.Int.Int64
+ Haskus.Binary.Bits.Reverse: instance Haskus.Binary.Bits.Reverse.ReversableBits GHC.Int.Int8
+ Haskus.Binary.Bits.Reverse: instance Haskus.Binary.Bits.Reverse.ReversableBits GHC.Types.Int
+ Haskus.Binary.Bits.Reverse: instance Haskus.Binary.Bits.Reverse.ReversableBits GHC.Types.Word
+ Haskus.Binary.Bits.Reverse: instance Haskus.Binary.Bits.Reverse.ReversableBits GHC.Word.Word16
+ Haskus.Binary.Bits.Reverse: instance Haskus.Binary.Bits.Reverse.ReversableBits GHC.Word.Word32
+ Haskus.Binary.Bits.Reverse: instance Haskus.Binary.Bits.Reverse.ReversableBits GHC.Word.Word64
+ Haskus.Binary.Bits.Reverse: instance Haskus.Binary.Bits.Reverse.ReversableBits GHC.Word.Word8
+ Haskus.Binary.Bits.Reverse: liftReverseBits :: (ShiftableBits a, Bitwise a, FiniteBits a, Integral a, KnownNat (BitSize a)) => (Word8 -> Word8) -> a -> a
+ Haskus.Binary.Bits.Reverse: reverseBits :: ReversableBits w => w -> w
+ Haskus.Binary.Bits.Reverse: reverseBits3Ops :: Word8 -> Word8
+ Haskus.Binary.Bits.Reverse: reverseBits4Ops :: Word8 -> Word8
+ Haskus.Binary.Bits.Reverse: reverseBits5LgN :: forall a. (FiniteBits a, ShiftableBits a, Bitwise a, KnownNat (BitSize a)) => a -> a
+ Haskus.Binary.Bits.Reverse: reverseBits7Ops :: Word8 -> Word8
+ Haskus.Binary.Bits.Reverse: reverseBitsGeneric :: (FiniteBits a, Integral a, ShiftableBits a, Bitwise a, KnownNat (BitSize a)) => a -> a
+ Haskus.Binary.Bits.Reverse: reverseBitsObvious :: forall a. (FiniteBits a, ShiftableBits a, IndexableBits a, Bitwise a, KnownNat (BitSize a), Eq a) => a -> a
+ Haskus.Binary.Bits.Reverse: reverseBitsTable :: Word8 -> Word8
+ Haskus.Binary.Bits.Rotate: class RotatableBits a
+ Haskus.Binary.Bits.Rotate: instance Haskus.Binary.Bits.Rotate.RotatableBits GHC.Int.Int16
+ Haskus.Binary.Bits.Rotate: instance Haskus.Binary.Bits.Rotate.RotatableBits GHC.Int.Int32
+ Haskus.Binary.Bits.Rotate: instance Haskus.Binary.Bits.Rotate.RotatableBits GHC.Int.Int64
+ Haskus.Binary.Bits.Rotate: instance Haskus.Binary.Bits.Rotate.RotatableBits GHC.Int.Int8
+ Haskus.Binary.Bits.Rotate: instance Haskus.Binary.Bits.Rotate.RotatableBits GHC.Types.Int
+ Haskus.Binary.Bits.Rotate: instance Haskus.Binary.Bits.Rotate.RotatableBits GHC.Types.Word
+ Haskus.Binary.Bits.Rotate: instance Haskus.Binary.Bits.Rotate.RotatableBits GHC.Word.Word16
+ Haskus.Binary.Bits.Rotate: instance Haskus.Binary.Bits.Rotate.RotatableBits GHC.Word.Word32
+ Haskus.Binary.Bits.Rotate: instance Haskus.Binary.Bits.Rotate.RotatableBits GHC.Word.Word64
+ Haskus.Binary.Bits.Rotate: instance Haskus.Binary.Bits.Rotate.RotatableBits GHC.Word.Word8
+ Haskus.Binary.Bits.Rotate: rotate :: (RotatableBits a, FiniteBits a, KnownNat (BitSize a)) => a -> Int -> a
+ Haskus.Binary.Bits.Rotate: rotateL :: (RotatableBits a, FiniteBits a, KnownNat (BitSize a)) => a -> Word -> a
+ Haskus.Binary.Bits.Rotate: rotateR :: (RotatableBits a, FiniteBits a, KnownNat (BitSize a)) => a -> Word -> a
+ Haskus.Binary.Bits.Rotate: uncheckedRotate :: RotatableBits a => a -> Int -> a
+ Haskus.Binary.Bits.Rotate: uncheckedRotateL :: (RotatableBits a, ShiftableBits a, FiniteBits a, KnownNat (BitSize a), Bitwise a) => a -> Word -> a
+ Haskus.Binary.Bits.Rotate: uncheckedRotateR :: (RotatableBits a, ShiftableBits a, FiniteBits a, KnownNat (BitSize a), Bitwise a) => a -> Word -> a
+ Haskus.Binary.Bits.Shift: class ShiftableBits a
+ Haskus.Binary.Bits.Shift: class SignedShiftableBits a
+ Haskus.Binary.Bits.Shift: instance Haskus.Binary.Bits.Shift.ShiftableBits GHC.Int.Int16
+ Haskus.Binary.Bits.Shift: instance Haskus.Binary.Bits.Shift.ShiftableBits GHC.Int.Int32
+ Haskus.Binary.Bits.Shift: instance Haskus.Binary.Bits.Shift.ShiftableBits GHC.Int.Int64
+ Haskus.Binary.Bits.Shift: instance Haskus.Binary.Bits.Shift.ShiftableBits GHC.Int.Int8
+ Haskus.Binary.Bits.Shift: instance Haskus.Binary.Bits.Shift.ShiftableBits GHC.Integer.Type.Integer
+ Haskus.Binary.Bits.Shift: instance Haskus.Binary.Bits.Shift.ShiftableBits GHC.Natural.Natural
+ Haskus.Binary.Bits.Shift: instance Haskus.Binary.Bits.Shift.ShiftableBits GHC.Types.Int
+ Haskus.Binary.Bits.Shift: instance Haskus.Binary.Bits.Shift.ShiftableBits GHC.Types.Word
+ Haskus.Binary.Bits.Shift: instance Haskus.Binary.Bits.Shift.ShiftableBits GHC.Word.Word16
+ Haskus.Binary.Bits.Shift: instance Haskus.Binary.Bits.Shift.ShiftableBits GHC.Word.Word32
+ Haskus.Binary.Bits.Shift: instance Haskus.Binary.Bits.Shift.ShiftableBits GHC.Word.Word64
+ Haskus.Binary.Bits.Shift: instance Haskus.Binary.Bits.Shift.ShiftableBits GHC.Word.Word8
+ Haskus.Binary.Bits.Shift: instance Haskus.Binary.Bits.Shift.SignedShiftableBits GHC.Int.Int16
+ Haskus.Binary.Bits.Shift: instance Haskus.Binary.Bits.Shift.SignedShiftableBits GHC.Int.Int32
+ Haskus.Binary.Bits.Shift: instance Haskus.Binary.Bits.Shift.SignedShiftableBits GHC.Int.Int64
+ Haskus.Binary.Bits.Shift: instance Haskus.Binary.Bits.Shift.SignedShiftableBits GHC.Int.Int8
+ Haskus.Binary.Bits.Shift: instance Haskus.Binary.Bits.Shift.SignedShiftableBits GHC.Types.Int
+ Haskus.Binary.Bits.Shift: shift :: ShiftableBits a => a -> Int -> a
+ Haskus.Binary.Bits.Shift: shiftL :: ShiftableBits a => a -> Word -> a
+ Haskus.Binary.Bits.Shift: shiftR :: ShiftableBits a => a -> Word -> a
+ Haskus.Binary.Bits.Shift: signedShift :: SignedShiftableBits a => a -> Int -> a
+ Haskus.Binary.Bits.Shift: signedShiftL :: SignedShiftableBits a => a -> Word -> a
+ Haskus.Binary.Bits.Shift: signedShiftR :: SignedShiftableBits a => a -> Word -> a
+ Haskus.Binary.Bits.Shift: uncheckedShift :: ShiftableBits a => a -> Int -> a
+ Haskus.Binary.Bits.Shift: uncheckedShiftL :: ShiftableBits a => a -> Word -> a
+ Haskus.Binary.Bits.Shift: uncheckedShiftR :: ShiftableBits a => a -> Word -> a
+ Haskus.Binary.Bits.Shift: uncheckedSignedShift :: SignedShiftableBits a => a -> Int -> a
+ Haskus.Binary.Bits.Shift: uncheckedSignedShiftL :: SignedShiftableBits a => a -> Word -> a
+ Haskus.Binary.Bits.Shift: uncheckedSignedShiftR :: SignedShiftableBits a => a -> Word -> a
+ Haskus.Binary.Buffer: Buffer :: ByteString -> Buffer
+ Haskus.Binary.Buffer: bufferAppend :: Buffer -> Buffer -> Buffer
+ Haskus.Binary.Buffer: bufferCons :: Word8 -> Buffer -> Buffer
+ Haskus.Binary.Buffer: bufferDrop :: Word -> Buffer -> Buffer
+ Haskus.Binary.Buffer: bufferDup :: Buffer -> IO Buffer
+ Haskus.Binary.Buffer: bufferHead :: Buffer -> Word8
+ Haskus.Binary.Buffer: bufferIndex :: Buffer -> Word -> Word8
+ Haskus.Binary.Buffer: bufferInit :: Buffer -> Buffer
+ Haskus.Binary.Buffer: bufferMap :: (Word8 -> Word8) -> Buffer -> Buffer
+ Haskus.Binary.Buffer: bufferPackByteList :: [Word8] -> Buffer
+ Haskus.Binary.Buffer: bufferPackByteString :: ByteString -> Buffer
+ Haskus.Binary.Buffer: bufferPackPtr :: MonadIO m => Word -> Ptr () -> m Buffer
+ Haskus.Binary.Buffer: bufferPackStorable :: forall a. Storable a => a -> Buffer
+ Haskus.Binary.Buffer: bufferPackStorableList :: forall a. Storable a => [a] -> Buffer
+ Haskus.Binary.Buffer: bufferPeekStorable :: forall a. Storable a => Buffer -> a
+ Haskus.Binary.Buffer: bufferPeekStorableAt :: forall a. Storable a => Buffer -> Word -> a
+ Haskus.Binary.Buffer: bufferPoke :: Ptr a -> Buffer -> IO ()
+ Haskus.Binary.Buffer: bufferPopStorable :: forall a. Storable a => Buffer -> (Buffer, a)
+ Haskus.Binary.Buffer: bufferReadFile :: MonadIO m => FilePath -> m Buffer
+ Haskus.Binary.Buffer: bufferReverse :: Buffer -> Buffer
+ Haskus.Binary.Buffer: bufferSize :: Buffer -> Word
+ Haskus.Binary.Buffer: bufferSnoc :: Buffer -> Word8 -> Buffer
+ Haskus.Binary.Buffer: bufferSplitOn :: Word8 -> Buffer -> [Buffer]
+ Haskus.Binary.Buffer: bufferTail :: Buffer -> Buffer
+ Haskus.Binary.Buffer: bufferTake :: Word -> Buffer -> Buffer
+ Haskus.Binary.Buffer: bufferTakeAtMost :: Word -> Buffer -> Buffer
+ Haskus.Binary.Buffer: bufferTakeWhile :: (Word8 -> Bool) -> Buffer -> Buffer
+ Haskus.Binary.Buffer: bufferUnpackByteList :: Buffer -> [Word8]
+ Haskus.Binary.Buffer: bufferUnpackByteString :: Buffer -> ByteString
+ Haskus.Binary.Buffer: bufferUnsafeDrop :: Word -> Buffer -> Buffer
+ Haskus.Binary.Buffer: bufferUnsafeHead :: Buffer -> Word8
+ Haskus.Binary.Buffer: bufferUnsafeIndex :: Buffer -> Word -> Word8
+ Haskus.Binary.Buffer: bufferUnsafeInit :: Buffer -> Buffer
+ Haskus.Binary.Buffer: bufferUnsafeLast :: Buffer -> Word8
+ Haskus.Binary.Buffer: bufferUnsafeMapMemory :: MonadIO m => Word -> Ptr () -> m Buffer
+ Haskus.Binary.Buffer: bufferUnsafePackPtr :: MonadIO m => Word -> Ptr a -> m Buffer
+ Haskus.Binary.Buffer: bufferUnsafeTail :: Buffer -> Buffer
+ Haskus.Binary.Buffer: bufferUnsafeTake :: Word -> Buffer -> Buffer
+ Haskus.Binary.Buffer: bufferUnsafeUsePtr :: MonadInIO m => Buffer -> (Ptr () -> Word -> m a) -> m a
+ Haskus.Binary.Buffer: bufferWriteFile :: MonadIO m => FilePath -> Buffer -> m ()
+ Haskus.Binary.Buffer: bufferZero :: Word -> Buffer
+ Haskus.Binary.Buffer: bufferZipWith :: (Word8 -> Word8 -> Word8) -> Buffer -> Buffer -> Buffer
+ Haskus.Binary.Buffer: emptyBuffer :: Buffer
+ Haskus.Binary.Buffer: instance GHC.Classes.Eq Haskus.Binary.Buffer.Buffer
+ Haskus.Binary.Buffer: instance GHC.Classes.Ord Haskus.Binary.Buffer.Buffer
+ Haskus.Binary.Buffer: instance GHC.Show.Show Haskus.Binary.Buffer.Buffer
+ Haskus.Binary.Buffer: instance Haskus.Binary.Bits.Bitwise.Bitwise Haskus.Binary.Buffer.Buffer
+ Haskus.Binary.Buffer: instance Haskus.Binary.Bits.Index.IndexableBits Haskus.Binary.Buffer.Buffer
+ Haskus.Binary.Buffer: isBufferEmpty :: Buffer -> Bool
+ Haskus.Binary.Buffer: newtype Buffer
+ Haskus.Binary.Buffer: withBufferPtr :: Buffer -> (Ptr b -> IO a) -> IO a
+ Haskus.Binary.BufferBuilder: data BufferBuilder
+ Haskus.Binary.BufferBuilder: emptyBufferBuilder :: BufferBuilder
+ Haskus.Binary.BufferBuilder: fromBuffer :: Buffer -> BufferBuilder
+ Haskus.Binary.BufferBuilder: fromWord8 :: Word8 -> BufferBuilder
+ Haskus.Binary.BufferBuilder: instance GHC.Base.Monoid Haskus.Binary.BufferBuilder.BufferBuilder
+ Haskus.Binary.BufferBuilder: instance GHC.Base.Semigroup Haskus.Binary.BufferBuilder.BufferBuilder
+ Haskus.Binary.BufferBuilder: toBuffer :: BufferBuilder -> Buffer
+ Haskus.Binary.BufferBuilder: toBufferList :: BufferBuilder -> BufferList
+ Haskus.Binary.BufferList: BufferList :: ByteString -> BufferList
+ Haskus.Binary.BufferList: newtype BufferList
+ Haskus.Binary.BufferList: toBuffer :: BufferList -> Buffer
+ Haskus.Binary.BufferList: toBufferList :: Buffer -> BufferList
+ Haskus.Binary.BufferList: toLazyByteString :: BufferList -> ByteString
+ Haskus.Binary.CTypes: CSize :: Word64 -> CSize
+ Haskus.Binary.CTypes: data CInt
+ Haskus.Binary.CTypes: data CLong
+ Haskus.Binary.CTypes: data CShort
+ Haskus.Binary.CTypes: data CUInt
+ Haskus.Binary.CTypes: data CULong
+ Haskus.Binary.CTypes: data CUShort
+ Haskus.Binary.CTypes: newtype CSize
+ Haskus.Binary.Char: Char8 :: Word8 -> Char8
+ Haskus.Binary.Char: instance GHC.Classes.Eq Haskus.Binary.Char.Char8
+ Haskus.Binary.Char: instance GHC.Classes.Ord Haskus.Binary.Char.Char8
+ Haskus.Binary.Char: instance GHC.Show.Show Haskus.Binary.Char.Char8
+ Haskus.Binary.Char: instance Haskus.Binary.Storable.Storable Haskus.Binary.Char.Char8
+ Haskus.Binary.Char: newtype Char8
+ Haskus.Binary.Endianness: AsBigEndian :: a -> AsBigEndian a
+ Haskus.Binary.Endianness: AsLittleEndian :: a -> AsLittleEndian a
+ Haskus.Binary.Endianness: BigEndian :: Endianness
+ Haskus.Binary.Endianness: ExtendedWordGetters :: Get Word8 -> Get Word16 -> Get Word32 -> Get Word64 -> Get Word64 -> ExtendedWordGetters
+ Haskus.Binary.Endianness: ExtendedWordPutters :: (Word8 -> Put) -> (Word16 -> Put) -> (Word32 -> Put) -> (Word64 -> Put) -> (Word64 -> Put) -> ExtendedWordPutters
+ Haskus.Binary.Endianness: LittleEndian :: Endianness
+ Haskus.Binary.Endianness: WordGetters :: Get Word8 -> Get Word16 -> Get Word32 -> Get Word64 -> WordGetters
+ Haskus.Binary.Endianness: WordPutters :: (Word8 -> Put) -> (Word16 -> Put) -> (Word32 -> Put) -> (Word64 -> Put) -> WordPutters
+ Haskus.Binary.Endianness: WordSize32 :: WordSize
+ Haskus.Binary.Endianness: WordSize64 :: WordSize
+ Haskus.Binary.Endianness: [extwordGetter16] :: ExtendedWordGetters -> Get Word16
+ Haskus.Binary.Endianness: [extwordGetter32] :: ExtendedWordGetters -> Get Word32
+ Haskus.Binary.Endianness: [extwordGetter64] :: ExtendedWordGetters -> Get Word64
+ Haskus.Binary.Endianness: [extwordGetter8] :: ExtendedWordGetters -> Get Word8
+ Haskus.Binary.Endianness: [extwordGetterN] :: ExtendedWordGetters -> Get Word64
+ Haskus.Binary.Endianness: [extwordPutter16] :: ExtendedWordPutters -> Word16 -> Put
+ Haskus.Binary.Endianness: [extwordPutter32] :: ExtendedWordPutters -> Word32 -> Put
+ Haskus.Binary.Endianness: [extwordPutter64] :: ExtendedWordPutters -> Word64 -> Put
+ Haskus.Binary.Endianness: [extwordPutter8] :: ExtendedWordPutters -> Word8 -> Put
+ Haskus.Binary.Endianness: [extwordPutterN] :: ExtendedWordPutters -> Word64 -> Put
+ Haskus.Binary.Endianness: [wordGetter16] :: WordGetters -> Get Word16
+ Haskus.Binary.Endianness: [wordGetter32] :: WordGetters -> Get Word32
+ Haskus.Binary.Endianness: [wordGetter64] :: WordGetters -> Get Word64
+ Haskus.Binary.Endianness: [wordGetter8] :: WordGetters -> Get Word8
+ Haskus.Binary.Endianness: [wordPutter16] :: WordPutters -> Word16 -> Put
+ Haskus.Binary.Endianness: [wordPutter32] :: WordPutters -> Word32 -> Put
+ Haskus.Binary.Endianness: [wordPutter64] :: WordPutters -> Word64 -> Put
+ Haskus.Binary.Endianness: [wordPutter8] :: WordPutters -> Word8 -> Put
+ Haskus.Binary.Endianness: bigEndianToHost :: ByteReversable w => w -> w
+ Haskus.Binary.Endianness: class ByteReversable w
+ Haskus.Binary.Endianness: data Endianness
+ Haskus.Binary.Endianness: data ExtendedWordGetters
+ Haskus.Binary.Endianness: data ExtendedWordPutters
+ Haskus.Binary.Endianness: data WordGetters
+ Haskus.Binary.Endianness: data WordPutters
+ Haskus.Binary.Endianness: data WordSize
+ Haskus.Binary.Endianness: getExtendedWordGetters :: Endianness -> WordSize -> ExtendedWordGetters
+ Haskus.Binary.Endianness: getExtendedWordPutters :: Endianness -> WordSize -> ExtendedWordPutters
+ Haskus.Binary.Endianness: getHostEndianness :: IO Endianness
+ Haskus.Binary.Endianness: getWordGetters :: Endianness -> WordGetters
+ Haskus.Binary.Endianness: getWordPutters :: Endianness -> WordPutters
+ Haskus.Binary.Endianness: hostEndianness :: Endianness
+ Haskus.Binary.Endianness: hostToBigEndian :: ByteReversable w => w -> w
+ Haskus.Binary.Endianness: hostToLittleEndian :: ByteReversable w => w -> w
+ Haskus.Binary.Endianness: instance (Haskus.Binary.Endianness.ByteReversable a, Haskus.Binary.Storable.StaticStorable a) => Haskus.Binary.Storable.StaticStorable (Haskus.Binary.Endianness.AsBigEndian a)
+ Haskus.Binary.Endianness: instance (Haskus.Binary.Endianness.ByteReversable a, Haskus.Binary.Storable.StaticStorable a) => Haskus.Binary.Storable.StaticStorable (Haskus.Binary.Endianness.AsLittleEndian a)
+ Haskus.Binary.Endianness: instance (Haskus.Binary.Endianness.ByteReversable a, Haskus.Binary.Storable.Storable a) => Haskus.Binary.Storable.Storable (Haskus.Binary.Endianness.AsBigEndian a)
+ Haskus.Binary.Endianness: instance (Haskus.Binary.Endianness.ByteReversable a, Haskus.Binary.Storable.Storable a) => Haskus.Binary.Storable.Storable (Haskus.Binary.Endianness.AsLittleEndian a)
+ Haskus.Binary.Endianness: instance GHC.Classes.Eq Haskus.Binary.Endianness.Endianness
+ Haskus.Binary.Endianness: instance GHC.Classes.Eq Haskus.Binary.Endianness.WordSize
+ Haskus.Binary.Endianness: instance GHC.Classes.Eq a => GHC.Classes.Eq (Haskus.Binary.Endianness.AsBigEndian a)
+ Haskus.Binary.Endianness: instance GHC.Classes.Eq a => GHC.Classes.Eq (Haskus.Binary.Endianness.AsLittleEndian a)
+ Haskus.Binary.Endianness: instance GHC.Classes.Ord a => GHC.Classes.Ord (Haskus.Binary.Endianness.AsBigEndian a)
+ Haskus.Binary.Endianness: instance GHC.Classes.Ord a => GHC.Classes.Ord (Haskus.Binary.Endianness.AsLittleEndian a)
+ Haskus.Binary.Endianness: instance GHC.Enum.Enum Haskus.Binary.Endianness.Endianness
+ Haskus.Binary.Endianness: instance GHC.Enum.Enum a => GHC.Enum.Enum (Haskus.Binary.Endianness.AsBigEndian a)
+ Haskus.Binary.Endianness: instance GHC.Enum.Enum a => GHC.Enum.Enum (Haskus.Binary.Endianness.AsLittleEndian a)
+ Haskus.Binary.Endianness: instance GHC.Num.Num a => GHC.Num.Num (Haskus.Binary.Endianness.AsBigEndian a)
+ Haskus.Binary.Endianness: instance GHC.Num.Num a => GHC.Num.Num (Haskus.Binary.Endianness.AsLittleEndian a)
+ Haskus.Binary.Endianness: instance GHC.Real.Integral a => GHC.Real.Integral (Haskus.Binary.Endianness.AsBigEndian a)
+ Haskus.Binary.Endianness: instance GHC.Real.Integral a => GHC.Real.Integral (Haskus.Binary.Endianness.AsLittleEndian a)
+ Haskus.Binary.Endianness: instance GHC.Real.Real a => GHC.Real.Real (Haskus.Binary.Endianness.AsBigEndian a)
+ Haskus.Binary.Endianness: instance GHC.Real.Real a => GHC.Real.Real (Haskus.Binary.Endianness.AsLittleEndian a)
+ Haskus.Binary.Endianness: instance GHC.Show.Show Haskus.Binary.Endianness.Endianness
+ Haskus.Binary.Endianness: instance GHC.Show.Show Haskus.Binary.Endianness.WordSize
+ Haskus.Binary.Endianness: instance GHC.Show.Show a => GHC.Show.Show (Haskus.Binary.Endianness.AsBigEndian a)
+ Haskus.Binary.Endianness: instance GHC.Show.Show a => GHC.Show.Show (Haskus.Binary.Endianness.AsLittleEndian a)
+ Haskus.Binary.Endianness: instance Haskus.Binary.Bits.Bitwise.Bitwise a => Haskus.Binary.Bits.Bitwise.Bitwise (Haskus.Binary.Endianness.AsBigEndian a)
+ Haskus.Binary.Endianness: instance Haskus.Binary.Bits.Bitwise.Bitwise a => Haskus.Binary.Bits.Bitwise.Bitwise (Haskus.Binary.Endianness.AsLittleEndian a)
+ Haskus.Binary.Endianness: instance Haskus.Binary.Bits.Finite.FiniteBits a => Haskus.Binary.Bits.Finite.FiniteBits (Haskus.Binary.Endianness.AsBigEndian a)
+ Haskus.Binary.Endianness: instance Haskus.Binary.Bits.Finite.FiniteBits a => Haskus.Binary.Bits.Finite.FiniteBits (Haskus.Binary.Endianness.AsLittleEndian a)
+ Haskus.Binary.Endianness: instance Haskus.Binary.Bits.Index.IndexableBits a => Haskus.Binary.Bits.Index.IndexableBits (Haskus.Binary.Endianness.AsBigEndian a)
+ Haskus.Binary.Endianness: instance Haskus.Binary.Bits.Index.IndexableBits a => Haskus.Binary.Bits.Index.IndexableBits (Haskus.Binary.Endianness.AsLittleEndian a)
+ Haskus.Binary.Endianness: instance Haskus.Binary.Bits.Reverse.ReversableBits a => Haskus.Binary.Bits.Reverse.ReversableBits (Haskus.Binary.Endianness.AsBigEndian a)
+ Haskus.Binary.Endianness: instance Haskus.Binary.Bits.Reverse.ReversableBits a => Haskus.Binary.Bits.Reverse.ReversableBits (Haskus.Binary.Endianness.AsLittleEndian a)
+ Haskus.Binary.Endianness: instance Haskus.Binary.Bits.Rotate.RotatableBits a => Haskus.Binary.Bits.Rotate.RotatableBits (Haskus.Binary.Endianness.AsBigEndian a)
+ Haskus.Binary.Endianness: instance Haskus.Binary.Bits.Rotate.RotatableBits a => Haskus.Binary.Bits.Rotate.RotatableBits (Haskus.Binary.Endianness.AsLittleEndian a)
+ Haskus.Binary.Endianness: instance Haskus.Binary.Bits.Shift.ShiftableBits a => Haskus.Binary.Bits.Shift.ShiftableBits (Haskus.Binary.Endianness.AsBigEndian a)
+ Haskus.Binary.Endianness: instance Haskus.Binary.Bits.Shift.ShiftableBits a => Haskus.Binary.Bits.Shift.ShiftableBits (Haskus.Binary.Endianness.AsLittleEndian a)
+ Haskus.Binary.Endianness: instance Haskus.Binary.Endianness.ByteReversable GHC.Word.Word16
+ Haskus.Binary.Endianness: instance Haskus.Binary.Endianness.ByteReversable GHC.Word.Word32
+ Haskus.Binary.Endianness: instance Haskus.Binary.Endianness.ByteReversable GHC.Word.Word64
+ Haskus.Binary.Endianness: instance Haskus.Binary.Endianness.ByteReversable GHC.Word.Word8
+ Haskus.Binary.Endianness: instance Haskus.Binary.Enum.CEnum Haskus.Binary.Endianness.Endianness
+ Haskus.Binary.Endianness: littleEndianToHost :: ByteReversable w => w -> w
+ Haskus.Binary.Endianness: newtype AsBigEndian a
+ Haskus.Binary.Endianness: newtype AsLittleEndian a
+ Haskus.Binary.Endianness: reverseBytes :: ByteReversable w => w -> w
+ Haskus.Binary.Enum: class CEnum a
+ Haskus.Binary.Enum: data EnumField b a
+ Haskus.Binary.Enum: dataToTag :: a -> Int
+ Haskus.Binary.Enum: fromCEnum :: (CEnum a, Integral b) => a -> b
+ Haskus.Binary.Enum: fromEnumField :: (CEnum a, Integral b) => EnumField b a -> a
+ Haskus.Binary.Enum: instance (GHC.Real.Integral b, Haskus.Binary.Storable.StaticStorable b, Haskus.Binary.Enum.CEnum a) => Haskus.Binary.Storable.StaticStorable (Haskus.Binary.Enum.EnumField b a)
+ Haskus.Binary.Enum: instance GHC.Classes.Eq b => GHC.Classes.Eq (Haskus.Binary.Enum.EnumField b a)
+ Haskus.Binary.Enum: instance GHC.Show.Show b => GHC.Show.Show (Haskus.Binary.Enum.EnumField b a)
+ Haskus.Binary.Enum: instance Haskus.Binary.Storable.Storable b => Haskus.Binary.Storable.Storable (Haskus.Binary.Enum.EnumField b a)
+ Haskus.Binary.Enum: makeEnum :: forall a i. (Data a, Integral i) => i -> a
+ Haskus.Binary.Enum: makeEnumMaybe :: forall a i. (Data a, Integral i) => i -> Maybe a
+ Haskus.Binary.Enum: makeEnumWithCustom :: forall a i. (Data a, Integral i) => i -> a
+ Haskus.Binary.Enum: toCEnum :: (CEnum a, Enum a, Integral b) => b -> a
+ Haskus.Binary.Enum: toEnumField :: (CEnum a, Integral b) => a -> EnumField b a
+ Haskus.Binary.Get: alignAfter :: Word -> Get a -> Get a
+ Haskus.Binary.Get: consumeAtMost :: Word -> Get a -> Get a
+ Haskus.Binary.Get: consumeExactly :: Word -> Get a -> Get a
+ Haskus.Binary.Get: countBytes :: Get a -> Get (Word, a)
+ Haskus.Binary.Get: data Get a
+ Haskus.Binary.Get: getBitGet :: BitOrder -> BitGet a -> (a -> Get b) -> Get b
+ Haskus.Binary.Get: getBuffer :: Word -> Get Buffer
+ Haskus.Binary.Get: getBufferNul :: Get Buffer
+ Haskus.Binary.Get: getManyAtMost :: Word -> Get (Maybe a) -> Get [a]
+ Haskus.Binary.Get: getManyBounded :: Maybe Word -> Maybe Word -> Get (Maybe a) -> Get (Maybe [a])
+ Haskus.Binary.Get: getRemaining :: Get Buffer
+ Haskus.Binary.Get: getWhile :: (a -> Bool) -> Get a -> Get [a]
+ Haskus.Binary.Get: getWhole :: Get a -> Get [a]
+ Haskus.Binary.Get: getWord16be :: Get Word16
+ Haskus.Binary.Get: getWord16le :: Get Word16
+ Haskus.Binary.Get: getWord32be :: Get Word32
+ Haskus.Binary.Get: getWord32le :: Get Word32
+ Haskus.Binary.Get: getWord64be :: Get Word64
+ Haskus.Binary.Get: getWord64le :: Get Word64
+ Haskus.Binary.Get: getWord8 :: Get Word8
+ Haskus.Binary.Get: isEmpty :: Get Bool
+ Haskus.Binary.Get: lookAhead :: Get a -> Get a
+ Haskus.Binary.Get: lookAheadE :: Get (Either a b) -> Get (Either a b)
+ Haskus.Binary.Get: lookAheadM :: Get (Maybe a) -> Get (Maybe a)
+ Haskus.Binary.Get: remaining :: Get Word
+ Haskus.Binary.Get: runGet :: Get a -> Buffer -> Either String a
+ Haskus.Binary.Get: runGetOrFail :: Get a -> Buffer -> a
+ Haskus.Binary.Get: skip :: Word -> Get ()
+ Haskus.Binary.Get: skipAlign :: Word -> Word -> Get ()
+ Haskus.Binary.Get: uncheckedSkip :: Word -> Get ()
+ Haskus.Binary.Get: uncheckedSkipAlign :: Word -> Word -> Get ()
+ Haskus.Binary.Put: data PutM a
+ Haskus.Binary.Put: putBuffer :: Buffer -> Put
+ Haskus.Binary.Put: putByteString :: ByteString -> Put
+ Haskus.Binary.Put: putPadding :: Word -> Put
+ Haskus.Binary.Put: putPaddingAlign :: Word -> Word -> Put
+ Haskus.Binary.Put: putWord16be :: Word16 -> Put
+ Haskus.Binary.Put: putWord16le :: Word16 -> Put
+ Haskus.Binary.Put: putWord32be :: Word32 -> Put
+ Haskus.Binary.Put: putWord32le :: Word32 -> Put
+ Haskus.Binary.Put: putWord64be :: Word64 -> Put
+ Haskus.Binary.Put: putWord64le :: Word64 -> Put
+ Haskus.Binary.Put: putWord8 :: Word8 -> Put
+ Haskus.Binary.Put: runPut :: Put -> Buffer
+ Haskus.Binary.Put: runPutM :: PutM a -> (a, Buffer)
+ Haskus.Binary.Put: type Put = PutM ()
+ Haskus.Binary.Record: data Field (name :: Symbol) typ
+ Haskus.Binary.Record: data Path (fs :: [Symbol])
+ Haskus.Binary.Record: data Record (fields :: [*])
+ Haskus.Binary.Record: instance (Haskus.Utils.HList.HFoldr' Haskus.Binary.Record.Extract (Haskus.Binary.Record.Record fs, Haskus.Utils.HList.HList '[]) fs (Haskus.Binary.Record.Record fs, Haskus.Utils.HList.HList fs), GHC.Show.Show (Haskus.Utils.HList.HList fs)) => GHC.Show.Show (Haskus.Binary.Record.Record fs)
+ Haskus.Binary.Record: instance (rec Data.Type.Equality.~ Haskus.Binary.Record.Record fs, b Data.Type.Equality.~ Haskus.Binary.Record.Field name typ, i Data.Type.Equality.~ (rec, Haskus.Utils.HList.HList l2), typ Data.Type.Equality.~ Haskus.Binary.Record.FieldType name fs, GHC.TypeNats.KnownNat (Haskus.Binary.Record.FieldOffset name fs 0), Haskus.Binary.Storable.StaticStorable typ, GHC.TypeLits.KnownSymbol name, r Data.Type.Equality.~ (rec, Haskus.Utils.HList.HList ((GHC.Base.String, typ) : l2))) => Haskus.Utils.HList.Apply Haskus.Binary.Record.Extract (b, i) r
+ Haskus.Binary.Record: instance (s Data.Type.Equality.~ Haskus.Binary.Record.FullRecordSize fs, GHC.TypeNats.KnownNat s) => Haskus.Binary.Storable.StaticStorable (Haskus.Binary.Record.Record fs)
+ Haskus.Binary.Record: recordAlignment :: forall fs. KnownNat (RecordAlignment fs 1) => Record fs -> Word
+ Haskus.Binary.Record: recordField :: forall (name :: Symbol) a fs. (KnownNat (FieldOffset name fs 0), a ~ FieldType name fs, StaticStorable a) => Record fs -> a
+ Haskus.Binary.Record: recordFieldOffset :: forall (name :: Symbol) fs. KnownNat (FieldOffset name fs 0) => Record fs -> Int
+ Haskus.Binary.Record: recordFieldPath :: forall path a fs o. (o ~ FieldPathOffset fs path 0, a ~ FieldPathType fs path, KnownNat o, StaticStorable a) => Path path -> Record fs -> a
+ Haskus.Binary.Record: recordFieldPathOffset :: forall path fs o. (o ~ FieldPathOffset fs path 0, KnownNat o) => Path path -> Record fs -> Int
+ Haskus.Binary.Record: recordSize :: forall fs. KnownNat (FullRecordSize fs) => Record fs -> Word
+ Haskus.Binary.Record: recordToList :: forall fs. HFoldr' Extract (Record fs, HList '[]) fs (Record fs, HList fs) => Record fs -> HList fs
+ Haskus.Binary.Record: type family Alignment a :: Nat
+ Haskus.Binary.Serialize: -- | Sensible to endianness
+ Haskus.Binary.Serialize: Dynamic :: Size
+ Haskus.Binary.Serialize: Exactly :: Nat -> Size
+ Haskus.Binary.Serialize: class Serializable a where {
+ Haskus.Binary.Serialize: data Size
+ Haskus.Binary.Serialize: get :: (Serializable a, GetMonad m) => Endianness -> m a
+ Haskus.Binary.Serialize: instance Haskus.Binary.Serialize.Serializable GHC.Int.Int16
+ Haskus.Binary.Serialize: instance Haskus.Binary.Serialize.Serializable GHC.Int.Int32
+ Haskus.Binary.Serialize: instance Haskus.Binary.Serialize.Serializable GHC.Int.Int64
+ Haskus.Binary.Serialize: instance Haskus.Binary.Serialize.Serializable GHC.Int.Int8
+ Haskus.Binary.Serialize: instance Haskus.Binary.Serialize.Serializable GHC.Word.Word16
+ Haskus.Binary.Serialize: instance Haskus.Binary.Serialize.Serializable GHC.Word.Word32
+ Haskus.Binary.Serialize: instance Haskus.Binary.Serialize.Serializable GHC.Word.Word64
+ Haskus.Binary.Serialize: instance Haskus.Binary.Serialize.Serializable GHC.Word.Word8
+ Haskus.Binary.Serialize: instance Haskus.Binary.Serialize.Serializable a => Haskus.Binary.Serialize.Serializable (Haskus.Binary.Endianness.AsBigEndian a)
+ Haskus.Binary.Serialize: instance Haskus.Binary.Serialize.Serializable a => Haskus.Binary.Serialize.Serializable (Haskus.Binary.Endianness.AsLittleEndian a)
+ Haskus.Binary.Serialize: put :: (Serializable a, PutMonad m) => Endianness -> a -> m ()
+ Haskus.Binary.Serialize: sizeOf :: Serializable a => a -> Word
+ Haskus.Binary.Serialize: type family Endian a :: Bool;
+ Haskus.Binary.Serialize: }
+ Haskus.Binary.Serialize.Buffer: BufferGetT :: StateT (BufferGetState m b) m a -> BufferGetT b m a
+ Haskus.Binary.Serialize.Buffer: BufferOverflow :: b -> Word -> Word -> BufferOverflow b
+ Haskus.Binary.Serialize.Buffer: BufferPutT :: StateT (BufferPutState m b) m a -> BufferPutT b m a
+ Haskus.Binary.Serialize.Buffer: OverflowStrategy :: (BufferOverflow b -> m (b, Word)) -> OverflowStrategy m b
+ Haskus.Binary.Serialize.Buffer: [overflowBuffer] :: BufferOverflow b -> b
+ Haskus.Binary.Serialize.Buffer: [overflowOffset] :: BufferOverflow b -> Word
+ Haskus.Binary.Serialize.Buffer: [overflowRequired] :: BufferOverflow b -> Word
+ Haskus.Binary.Serialize.Buffer: data BufferOverflow b
+ Haskus.Binary.Serialize.Buffer: getGetBuffer :: Monad m => BufferGetT b m b
+ Haskus.Binary.Serialize.Buffer: getGetOffset :: Monad m => BufferGetT b m Word
+ Haskus.Binary.Serialize.Buffer: getGetOverflowStrategy :: Monad m => BufferGetT b m (OverflowStrategy m b)
+ Haskus.Binary.Serialize.Buffer: getPutBuffer :: Monad m => BufferPutT b m b
+ Haskus.Binary.Serialize.Buffer: getPutOffset :: Monad m => BufferPutT b m Word
+ Haskus.Binary.Serialize.Buffer: getPutOverflowStrategy :: Monad m => BufferPutT b m (OverflowStrategy m b)
+ Haskus.Binary.Serialize.Buffer: instance Control.Monad.Fail.MonadFail m => Control.Monad.Fail.MonadFail (Haskus.Binary.Serialize.Buffer.BufferGetT b m)
+ Haskus.Binary.Serialize.Buffer: instance Control.Monad.Fail.MonadFail m => Control.Monad.Fail.MonadFail (Haskus.Binary.Serialize.Buffer.BufferPutT b m)
+ Haskus.Binary.Serialize.Buffer: instance Control.Monad.Fix.MonadFix m => Control.Monad.Fix.MonadFix (Haskus.Binary.Serialize.Buffer.BufferGetT b m)
+ Haskus.Binary.Serialize.Buffer: instance Control.Monad.Fix.MonadFix m => Control.Monad.Fix.MonadFix (Haskus.Binary.Serialize.Buffer.BufferPutT b m)
+ Haskus.Binary.Serialize.Buffer: instance Control.Monad.IO.Class.MonadIO m => Control.Monad.IO.Class.MonadIO (Haskus.Binary.Serialize.Buffer.BufferGetT b m)
+ Haskus.Binary.Serialize.Buffer: instance Control.Monad.IO.Class.MonadIO m => Control.Monad.IO.Class.MonadIO (Haskus.Binary.Serialize.Buffer.BufferPutT b m)
+ Haskus.Binary.Serialize.Buffer: instance Control.Monad.IO.Class.MonadIO m => Haskus.Binary.Serialize.Get.GetMonad (Haskus.Binary.Serialize.Buffer.BufferGetT (Haskus.Memory.Buffer.Buffer mut pin gc heap) m)
+ Haskus.Binary.Serialize.Buffer: instance Control.Monad.IO.Class.MonadIO m => Haskus.Binary.Serialize.Put.PutMonad (Haskus.Binary.Serialize.Buffer.BufferPutT (Haskus.Memory.Buffer.Buffer 'Haskus.Memory.Property.Mutable pin gc heap) m)
+ Haskus.Binary.Serialize.Buffer: instance GHC.Base.Functor m => GHC.Base.Functor (Haskus.Binary.Serialize.Buffer.BufferGetT b m)
+ Haskus.Binary.Serialize.Buffer: instance GHC.Base.Functor m => GHC.Base.Functor (Haskus.Binary.Serialize.Buffer.BufferPutT b m)
+ Haskus.Binary.Serialize.Buffer: instance GHC.Base.Monad m => GHC.Base.Applicative (Haskus.Binary.Serialize.Buffer.BufferGetT b m)
+ Haskus.Binary.Serialize.Buffer: instance GHC.Base.Monad m => GHC.Base.Applicative (Haskus.Binary.Serialize.Buffer.BufferPutT b m)
+ Haskus.Binary.Serialize.Buffer: instance GHC.Base.Monad m => GHC.Base.Monad (Haskus.Binary.Serialize.Buffer.BufferGetT b m)
+ Haskus.Binary.Serialize.Buffer: instance GHC.Base.Monad m => GHC.Base.Monad (Haskus.Binary.Serialize.Buffer.BufferPutT b m)
+ Haskus.Binary.Serialize.Buffer: liftBufferGet :: Monad m => m a -> BufferGetT b m a
+ Haskus.Binary.Serialize.Buffer: liftBufferPut :: Monad m => m a -> BufferPutT b m a
+ Haskus.Binary.Serialize.Buffer: newtype BufferGetT b m a
+ Haskus.Binary.Serialize.Buffer: newtype BufferPutT b m a
+ Haskus.Binary.Serialize.Buffer: newtype OverflowStrategy m b
+ Haskus.Binary.Serialize.Buffer: overflowBufferAdd :: MonadIO m => Word -> OverflowStrategy m BufferM
+ Haskus.Binary.Serialize.Buffer: overflowBufferAddPinned :: MonadIO m => Maybe Word -> Word -> OverflowStrategy m BufferMP
+ Haskus.Binary.Serialize.Buffer: overflowBufferDouble :: MonadIO m => OverflowStrategy m BufferM
+ Haskus.Binary.Serialize.Buffer: overflowBufferDoublePinned :: MonadIO m => Maybe Word -> OverflowStrategy m BufferMP
+ Haskus.Binary.Serialize.Buffer: overflowBufferFail :: MonadFail m => OverflowStrategy m b
+ Haskus.Binary.Serialize.Buffer: runBufferGet :: Monad m => b -> Word -> OverflowStrategy m b -> BufferGetT b m a -> m (a, b, Word)
+ Haskus.Binary.Serialize.Buffer: runBufferPut :: Monad m => b -> Word -> OverflowStrategy m b -> BufferPutT b m a -> m (a, b, Word)
+ Haskus.Binary.Serialize.Buffer: setGetOffset :: Monad m => Word -> BufferGetT b m ()
+ Haskus.Binary.Serialize.Buffer: setPutOffset :: Monad m => Word -> BufferPutT b m ()
+ Haskus.Binary.Serialize.Buffer: type BufferGet b a = BufferGetT b Identity a
+ Haskus.Binary.Serialize.Buffer: type BufferPut b a = BufferPutT b Identity a
+ Haskus.Binary.Serialize.File: FileGetState :: !Handle -> FileGetState
+ Haskus.Binary.Serialize.File: FileGetT :: StateT FileGetState m a -> FileGetT m a
+ Haskus.Binary.Serialize.File: [fileGetHandle] :: FileGetState -> !Handle
+ Haskus.Binary.Serialize.File: data FileGetState
+ Haskus.Binary.Serialize.File: instance Control.Monad.Fail.MonadFail m => Control.Monad.Fail.MonadFail (Haskus.Binary.Serialize.File.FileGetT m)
+ Haskus.Binary.Serialize.File: instance Control.Monad.Fix.MonadFix m => Control.Monad.Fix.MonadFix (Haskus.Binary.Serialize.File.FileGetT m)
+ Haskus.Binary.Serialize.File: instance Control.Monad.IO.Class.MonadIO m => Control.Monad.IO.Class.MonadIO (Haskus.Binary.Serialize.File.FileGetT m)
+ Haskus.Binary.Serialize.File: instance Control.Monad.IO.Class.MonadIO m => Haskus.Binary.Serialize.Get.GetMonad (Haskus.Binary.Serialize.File.FileGetT m)
+ Haskus.Binary.Serialize.File: instance GHC.Base.Functor m => GHC.Base.Functor (Haskus.Binary.Serialize.File.FileGetT m)
+ Haskus.Binary.Serialize.File: instance GHC.Base.Monad m => GHC.Base.Applicative (Haskus.Binary.Serialize.File.FileGetT m)
+ Haskus.Binary.Serialize.File: instance GHC.Base.Monad m => GHC.Base.Monad (Haskus.Binary.Serialize.File.FileGetT m)
+ Haskus.Binary.Serialize.File: newtype FileGetT m a
+ Haskus.Binary.Serialize.File: runFileGet :: Handle -> FileGetT IO a -> IO a
+ Haskus.Binary.Serialize.File: runFilePathGet :: FilePath -> FileGetT IO a -> IO a
+ Haskus.Binary.Serialize.Get: class Monad m => GetMonad m
+ Haskus.Binary.Serialize.Get: getBuffer :: GetMonad m => Word -> m BufferI
+ Haskus.Binary.Serialize.Get: getBufferInto :: GetMonad m => Word -> Buffer 'Mutable pin gc heap -> Maybe Word -> m ()
+ Haskus.Binary.Serialize.Get: getFloat32 :: GetMonad m => m Float32
+ Haskus.Binary.Serialize.Get: getFloat32BE :: GetMonad m => m Float32
+ Haskus.Binary.Serialize.Get: getFloat32LE :: GetMonad m => m Float32
+ Haskus.Binary.Serialize.Get: getFloat64 :: GetMonad m => m Float64
+ Haskus.Binary.Serialize.Get: getFloat64BE :: GetMonad m => m Float64
+ Haskus.Binary.Serialize.Get: getFloat64LE :: GetMonad m => m Float64
+ Haskus.Binary.Serialize.Get: getSkipBytes :: GetMonad m => Word -> m ()
+ Haskus.Binary.Serialize.Get: getWord16 :: GetMonad m => m Word16
+ Haskus.Binary.Serialize.Get: getWord16BE :: GetMonad m => m Word16
+ Haskus.Binary.Serialize.Get: getWord16BEs :: GetMonad m => Word -> m [Word16]
+ Haskus.Binary.Serialize.Get: getWord16LE :: GetMonad m => m Word16
+ Haskus.Binary.Serialize.Get: getWord16LEs :: GetMonad m => Word -> m [Word16]
+ Haskus.Binary.Serialize.Get: getWord16s :: GetMonad m => Word -> m [Word16]
+ Haskus.Binary.Serialize.Get: getWord32 :: GetMonad m => m Word32
+ Haskus.Binary.Serialize.Get: getWord32BE :: GetMonad m => m Word32
+ Haskus.Binary.Serialize.Get: getWord32BEs :: GetMonad m => Word -> m [Word32]
+ Haskus.Binary.Serialize.Get: getWord32LE :: GetMonad m => m Word32
+ Haskus.Binary.Serialize.Get: getWord32LEs :: GetMonad m => Word -> m [Word32]
+ Haskus.Binary.Serialize.Get: getWord32s :: GetMonad m => Word -> m [Word32]
+ Haskus.Binary.Serialize.Get: getWord64 :: GetMonad m => m Word64
+ Haskus.Binary.Serialize.Get: getWord64BE :: GetMonad m => m Word64
+ Haskus.Binary.Serialize.Get: getWord64BEs :: GetMonad m => Word -> m [Word64]
+ Haskus.Binary.Serialize.Get: getWord64LE :: GetMonad m => m Word64
+ Haskus.Binary.Serialize.Get: getWord64LEs :: GetMonad m => Word -> m [Word64]
+ Haskus.Binary.Serialize.Get: getWord64s :: GetMonad m => Word -> m [Word64]
+ Haskus.Binary.Serialize.Get: getWord8 :: GetMonad m => m Word8
+ Haskus.Binary.Serialize.Get: getWord8s :: GetMonad m => Word -> m [Word8]
+ Haskus.Binary.Serialize.Put: class Monad m => PutMonad m
+ Haskus.Binary.Serialize.Put: preAllocateAtLeast :: PutMonad m => Word -> m ()
+ Haskus.Binary.Serialize.Put: putBuffer :: (PutMonad m, BufferSize (Buffer Immutable pin gc heap)) => Buffer Immutable pin gc heap -> m ()
+ Haskus.Binary.Serialize.Put: putFloat32 :: PutMonad m => Float32 -> m ()
+ Haskus.Binary.Serialize.Put: putFloat32BE :: PutMonad m => Float32 -> m ()
+ Haskus.Binary.Serialize.Put: putFloat32LE :: PutMonad m => Float32 -> m ()
+ Haskus.Binary.Serialize.Put: putFloat64 :: PutMonad m => Float64 -> m ()
+ Haskus.Binary.Serialize.Put: putFloat64BE :: PutMonad m => Float64 -> m ()
+ Haskus.Binary.Serialize.Put: putFloat64LE :: PutMonad m => Float64 -> m ()
+ Haskus.Binary.Serialize.Put: putWord16 :: PutMonad m => Word16 -> m ()
+ Haskus.Binary.Serialize.Put: putWord16BE :: PutMonad m => Word16 -> m ()
+ Haskus.Binary.Serialize.Put: putWord16BEs :: PutMonad m => [Word16] -> m ()
+ Haskus.Binary.Serialize.Put: putWord16LE :: PutMonad m => Word16 -> m ()
+ Haskus.Binary.Serialize.Put: putWord16LEs :: PutMonad m => [Word16] -> m ()
+ Haskus.Binary.Serialize.Put: putWord16s :: PutMonad m => [Word16] -> m ()
+ Haskus.Binary.Serialize.Put: putWord32 :: PutMonad m => Word32 -> m ()
+ Haskus.Binary.Serialize.Put: putWord32BE :: PutMonad m => Word32 -> m ()
+ Haskus.Binary.Serialize.Put: putWord32BEs :: PutMonad m => [Word32] -> m ()
+ Haskus.Binary.Serialize.Put: putWord32LE :: PutMonad m => Word32 -> m ()
+ Haskus.Binary.Serialize.Put: putWord32LEs :: PutMonad m => [Word32] -> m ()
+ Haskus.Binary.Serialize.Put: putWord32s :: PutMonad m => [Word32] -> m ()
+ Haskus.Binary.Serialize.Put: putWord64 :: PutMonad m => Word64 -> m ()
+ Haskus.Binary.Serialize.Put: putWord64BE :: PutMonad m => Word64 -> m ()
+ Haskus.Binary.Serialize.Put: putWord64BEs :: PutMonad m => [Word64] -> m ()
+ Haskus.Binary.Serialize.Put: putWord64LE :: PutMonad m => Word64 -> m ()
+ Haskus.Binary.Serialize.Put: putWord64LEs :: PutMonad m => [Word64] -> m ()
+ Haskus.Binary.Serialize.Put: putWord64s :: PutMonad m => [Word64] -> m ()
+ Haskus.Binary.Serialize.Put: putWord8 :: PutMonad m => Word8 -> m ()
+ Haskus.Binary.Serialize.Put: putWord8s :: PutMonad m => [Word8] -> m ()
+ Haskus.Binary.Serialize.Size: GetSize :: State Word a -> GetSize a
+ Haskus.Binary.Serialize.Size: instance GHC.Base.Applicative Haskus.Binary.Serialize.Size.GetSize
+ Haskus.Binary.Serialize.Size: instance GHC.Base.Functor Haskus.Binary.Serialize.Size.GetSize
+ Haskus.Binary.Serialize.Size: instance GHC.Base.Monad Haskus.Binary.Serialize.Size.GetSize
+ Haskus.Binary.Serialize.Size: instance Haskus.Binary.Serialize.Put.PutMonad Haskus.Binary.Serialize.Size.GetSize
+ Haskus.Binary.Serialize.Size: newtype GetSize a
+ Haskus.Binary.Serialize.Size: runGetSize :: GetSize a -> Word
+ Haskus.Binary.Storable: -- | Alignment requirement (in bytes)
+ Haskus.Binary.Storable: alignment :: (Storable a, Generic a, GStorable (Rep a)) => a -> Word
+ Haskus.Binary.Storable: alignment' :: (Integral b, Storable a) => a -> b
+ Haskus.Binary.Storable: alignmentT :: forall a. Storable a => Word
+ Haskus.Binary.Storable: alignmentT' :: forall a b. (Storable a, Integral b) => b
+ Haskus.Binary.Storable: alloca :: forall a b m. (MonadInIO m, Storable a) => (Ptr a -> m b) -> m b
+ Haskus.Binary.Storable: allocaArray :: forall a b m. (MonadInIO m, Storable a) => Word -> (Ptr a -> m b) -> m b
+ Haskus.Binary.Storable: allocaBytes :: MonadInIO m => Word -> (Ptr a -> m b) -> m b
+ Haskus.Binary.Storable: allocaBytesAligned :: MonadInIO m => Word -> Word -> (Ptr a -> m b) -> m b
+ Haskus.Binary.Storable: class StaticStorable a where {
+ Haskus.Binary.Storable: class Storable a
+ Haskus.Binary.Storable: instance (Haskus.Binary.Storable.GStorable a, Haskus.Binary.Storable.GStorable b) => Haskus.Binary.Storable.GStorable (a GHC.Generics.:*: b)
+ Haskus.Binary.Storable: instance Haskus.Binary.Storable.GStorable GHC.Generics.U1
+ Haskus.Binary.Storable: instance Haskus.Binary.Storable.GStorable a => Haskus.Binary.Storable.GStorable (GHC.Generics.M1 i c a)
+ Haskus.Binary.Storable: instance Haskus.Binary.Storable.StaticStorable GHC.Int.Int16
+ Haskus.Binary.Storable: instance Haskus.Binary.Storable.StaticStorable GHC.Int.Int32
+ Haskus.Binary.Storable: instance Haskus.Binary.Storable.StaticStorable GHC.Int.Int64
+ Haskus.Binary.Storable: instance Haskus.Binary.Storable.StaticStorable GHC.Int.Int8
+ Haskus.Binary.Storable: instance Haskus.Binary.Storable.StaticStorable GHC.Word.Word16
+ Haskus.Binary.Storable: instance Haskus.Binary.Storable.StaticStorable GHC.Word.Word32
+ Haskus.Binary.Storable: instance Haskus.Binary.Storable.StaticStorable GHC.Word.Word64
+ Haskus.Binary.Storable: instance Haskus.Binary.Storable.StaticStorable GHC.Word.Word8
+ Haskus.Binary.Storable: instance Haskus.Binary.Storable.Storable (GHC.Ptr.Ptr a)
+ Haskus.Binary.Storable: instance Haskus.Binary.Storable.Storable Foreign.C.Types.CChar
+ Haskus.Binary.Storable: instance Haskus.Binary.Storable.Storable Foreign.C.Types.CInt
+ Haskus.Binary.Storable: instance Haskus.Binary.Storable.Storable Foreign.C.Types.CLong
+ Haskus.Binary.Storable: instance Haskus.Binary.Storable.Storable Foreign.C.Types.CShort
+ Haskus.Binary.Storable: instance Haskus.Binary.Storable.Storable Foreign.C.Types.CSize
+ Haskus.Binary.Storable: instance Haskus.Binary.Storable.Storable Foreign.C.Types.CUInt
+ Haskus.Binary.Storable: instance Haskus.Binary.Storable.Storable Foreign.C.Types.CULong
+ Haskus.Binary.Storable: instance Haskus.Binary.Storable.Storable Foreign.C.Types.CUShort
+ Haskus.Binary.Storable: instance Haskus.Binary.Storable.Storable Foreign.Ptr.WordPtr
+ Haskus.Binary.Storable: instance Haskus.Binary.Storable.Storable GHC.Int.Int16
+ Haskus.Binary.Storable: instance Haskus.Binary.Storable.Storable GHC.Int.Int32
+ Haskus.Binary.Storable: instance Haskus.Binary.Storable.Storable GHC.Int.Int64
+ Haskus.Binary.Storable: instance Haskus.Binary.Storable.Storable GHC.Int.Int8
+ Haskus.Binary.Storable: instance Haskus.Binary.Storable.Storable GHC.Types.Char
+ Haskus.Binary.Storable: instance Haskus.Binary.Storable.Storable GHC.Types.Double
+ Haskus.Binary.Storable: instance Haskus.Binary.Storable.Storable GHC.Types.Float
+ Haskus.Binary.Storable: instance Haskus.Binary.Storable.Storable GHC.Types.Int
+ Haskus.Binary.Storable: instance Haskus.Binary.Storable.Storable GHC.Types.Word
+ Haskus.Binary.Storable: instance Haskus.Binary.Storable.Storable GHC.Word.Word16
+ Haskus.Binary.Storable: instance Haskus.Binary.Storable.Storable GHC.Word.Word32
+ Haskus.Binary.Storable: instance Haskus.Binary.Storable.Storable GHC.Word.Word64
+ Haskus.Binary.Storable: instance Haskus.Binary.Storable.Storable GHC.Word.Word8
+ Haskus.Binary.Storable: instance Haskus.Binary.Storable.Storable a => Haskus.Binary.Storable.GStorable (GHC.Generics.K1 i a)
+ Haskus.Binary.Storable: malloc :: forall a m. (MonadIO m, Storable a) => m (Ptr a)
+ Haskus.Binary.Storable: mallocArray :: forall a m. (MonadIO m, Storable a) => Word -> m (Ptr a)
+ Haskus.Binary.Storable: peek :: (Storable a, MonadIO m) => Ptr a -> m a
+ Haskus.Binary.Storable: peekArray :: (MonadIO m, Storable a) => Word -> Ptr a -> m [a]
+ Haskus.Binary.Storable: peekByteOff :: (MonadIO m, Storable a) => Ptr a -> Int -> m a
+ Haskus.Binary.Storable: peekElemOff :: forall a m. (MonadIO m, Storable a) => Ptr a -> Int -> m a
+ Haskus.Binary.Storable: peekIO :: (Storable a, Generic a, GStorable (Rep a)) => Ptr a -> IO a
+ Haskus.Binary.Storable: poke :: (Storable a, MonadIO m) => Ptr a -> a -> m ()
+ Haskus.Binary.Storable: pokeArray :: (MonadIO m, Storable a) => Ptr a -> [a] -> m ()
+ Haskus.Binary.Storable: pokeByteOff :: (MonadIO m, Storable a) => Ptr a -> Int -> a -> m ()
+ Haskus.Binary.Storable: pokeElemOff :: (MonadIO m, Storable a) => Ptr a -> Int -> a -> m ()
+ Haskus.Binary.Storable: pokeIO :: (Storable a, Generic a, GStorable (Rep a)) => Ptr a -> a -> IO ()
+ Haskus.Binary.Storable: sizeOf :: (Storable a, Generic a, GStorable (Rep a)) => a -> Word
+ Haskus.Binary.Storable: sizeOf' :: (Integral b, Storable a) => a -> b
+ Haskus.Binary.Storable: sizeOfT :: forall a. Storable a => Word
+ Haskus.Binary.Storable: sizeOfT' :: forall a b. (Storable a, Integral b) => b
+ Haskus.Binary.Storable: staticAlignment :: forall a. KnownNat (Alignment a) => a -> Word
+ Haskus.Binary.Storable: staticPeek :: (StaticStorable a, MonadIO m) => Ptr a -> m a
+ Haskus.Binary.Storable: staticPeekIO :: StaticStorable a => Ptr a -> IO a
+ Haskus.Binary.Storable: staticPoke :: (StaticStorable a, MonadIO m) => Ptr a -> a -> m ()
+ Haskus.Binary.Storable: staticPokeIO :: StaticStorable a => Ptr a -> a -> IO ()
+ Haskus.Binary.Storable: staticSizeOf :: forall a. KnownNat (SizeOf a) => a -> Word
+ Haskus.Binary.Storable: type family PaddingEx (m :: Nat) (a :: Nat)
+ Haskus.Binary.Storable: with :: (MonadInIO m, Storable a) => a -> (Ptr a -> m b) -> m b
+ Haskus.Binary.Storable: withArray :: (MonadInIO m, Storable a) => [a] -> (Ptr a -> m b) -> m b
+ Haskus.Binary.Storable: withArrayLen :: (MonadInIO m, Storable a) => [a] -> (Word -> Ptr a -> m b) -> m b
+ Haskus.Binary.Storable: withMany :: (a -> (b -> res) -> res) -> [a] -> ([b] -> res) -> res
+ Haskus.Binary.Storable: wordBytes :: forall a. (Storable a, KnownNat (SizeOf a)) => a -> [Word8]
+ Haskus.Binary.Storable: }
+ Haskus.Binary.Union: data Union (x :: [*])
+ Haskus.Binary.Union: fromUnion :: (Storable a, Member a l) => Union l -> a
+ Haskus.Binary.Union: instance (GHC.TypeNats.KnownNat (Haskus.Utils.Types.List.ListMax (Haskus.Binary.Union.MapSizeOf fs)), GHC.TypeNats.KnownNat (Haskus.Utils.Types.List.ListMax (Haskus.Binary.Union.MapAlignment fs))) => Haskus.Binary.Storable.StaticStorable (Haskus.Binary.Union.Union fs)
+ Haskus.Binary.Union: instance (Haskus.Utils.HList.HFoldr' Haskus.Binary.Union.FoldSizeOf GHC.Types.Word l GHC.Types.Word, Haskus.Utils.HList.HFoldr' Haskus.Binary.Union.FoldAlignment GHC.Types.Word l GHC.Types.Word) => Foreign.Storable.Storable (Haskus.Binary.Union.Union l)
+ Haskus.Binary.Union: instance (Haskus.Utils.HList.HFoldr' Haskus.Binary.Union.FoldSizeOf GHC.Types.Word l GHC.Types.Word, Haskus.Utils.HList.HFoldr' Haskus.Binary.Union.FoldAlignment GHC.Types.Word l GHC.Types.Word) => Haskus.Binary.Storable.Storable (Haskus.Binary.Union.Union l)
+ Haskus.Binary.Union: instance (r Data.Type.Equality.~ GHC.Types.Word, Haskus.Binary.Storable.Storable a) => Haskus.Utils.HList.Apply Haskus.Binary.Union.FoldAlignment (a, GHC.Types.Word) r
+ Haskus.Binary.Union: instance (r Data.Type.Equality.~ GHC.Types.Word, Haskus.Binary.Storable.Storable a) => Haskus.Utils.HList.Apply Haskus.Binary.Union.FoldSizeOf (a, GHC.Types.Word) r
+ Haskus.Binary.Union: instance GHC.Show.Show (Haskus.Binary.Union.Union x)
+ Haskus.Binary.Union: toUnion :: forall a l. (Storable (Union l), Storable a, Member a l) => a -> Union l
+ Haskus.Binary.Union: toUnionZero :: forall a l. (Storable (Union l), Storable a, Member a l) => a -> Union l
+ Haskus.Binary.Unum: CSORN :: BitFields (CSORNBackingWord u) '[BitField (UnumSize u) "start" (BackingWord u), BitField (UnumSize u) "count" (BackingWord u)] -> CSORN u
+ Haskus.Binary.Unum: ExactNumber :: UBit
+ Haskus.Binary.Unum: Negative :: Sign
+ Haskus.Binary.Unum: NoSign :: Sign
+ Haskus.Binary.Unum: OpenInterval :: UBit
+ Haskus.Binary.Unum: Positive :: Sign
+ Haskus.Binary.Unum: U :: BackingWord u -> U u
+ Haskus.Binary.Unum: class SornAdd u
+ Haskus.Binary.Unum: class UnumNum a
+ Haskus.Binary.Unum: csornBits :: forall u s. (Bits (CSORNBackingWord u), KnownNat (UnumSize u), s ~ CSORNSize u, KnownNat s) => CSORN u -> String
+ Haskus.Binary.Unum: csornEmpty :: forall u. Bits (CSORNBackingWord u) => CSORN u
+ Haskus.Binary.Unum: csornFromTo :: forall u. (Num (BackingWord u), Bits (BackingWord u), KnownNat (UnumSize u), KnownNat (SORNSize u), Bits (BackingWord u), Integral (CSORNBackingWord u), Bits (CSORNBackingWord u), Field (BackingWord u), Integral (BackingWord u)) => U u -> U u -> CSORN u
+ Haskus.Binary.Unum: csornFull :: forall u. (Bits (CSORNBackingWord u), Integral (CSORNBackingWord u), Integral (BackingWord u), KnownNat (UnumSize u), Field (BackingWord u)) => CSORN u
+ Haskus.Binary.Unum: csornIsEmpty :: forall u. Bits (CSORNBackingWord u) => CSORN u -> Bool
+ Haskus.Binary.Unum: csornSingle :: forall u. (Bits (CSORNBackingWord u), Integral (CSORNBackingWord u), Integral (BackingWord u), KnownNat (UnumSize u), Field (BackingWord u)) => U u -> CSORN u
+ Haskus.Binary.Unum: csornSize :: forall u s. (s ~ CSORNSize u, KnownNat s) => Word
+ Haskus.Binary.Unum: csornToSorn :: forall u. (KnownNat (UnumSize u), Num (BackingWord u), Integral (BackingWord u), Integral (CSORNBackingWord u), Bits (CSORNBackingWord u), Bits (BackingWord u), Bits (SORNBackingWord u), Field (BackingWord u), KnownNat (SORNSize u), Bits (SORNBackingWord u)) => CSORN u -> SORN u
+ Haskus.Binary.Unum: data I (n :: Nat)
+ Haskus.Binary.Unum: data Neg a
+ Haskus.Binary.Unum: data Rcp a
+ Haskus.Binary.Unum: data SORN u
+ Haskus.Binary.Unum: data Sign
+ Haskus.Binary.Unum: data UBit
+ Haskus.Binary.Unum: data Unum (xs :: [Type])
+ Haskus.Binary.Unum: instance (GHC.TypeNats.KnownNat (Haskus.Binary.Unum.SORNSize u), GHC.TypeNats.KnownNat (Haskus.Binary.Unum.UnumSize u), Haskus.Binary.Bits.Bits (Haskus.Binary.Unum.BackingWord u), Haskus.Binary.Bits.Bits (Haskus.Binary.Unum.CSORNBackingWord u), GHC.Real.Integral (Haskus.Binary.Unum.CSORNBackingWord u), GHC.Num.Num (Haskus.Binary.Unum.BackingWord u), GHC.Real.Integral (Haskus.Binary.Unum.BackingWord u), Haskus.Utils.HList.HFoldr' Haskus.Binary.Unum.GetLabel [GHC.Base.String] v [GHC.Base.String], Haskus.Binary.BitField.Field (Haskus.Binary.Unum.BackingWord u), Haskus.Binary.Bits.Bits (Haskus.Binary.Unum.SORNBackingWord u), Haskus.Binary.Bits.Bits (Haskus.Binary.Unum.SORNBackingWord u), v Data.Type.Equality.~ Haskus.Binary.Unum.UnumMembers u) => GHC.Show.Show (Haskus.Binary.Unum.CSORN u)
+ Haskus.Binary.Unum: instance (GHC.TypeNats.KnownNat (Haskus.Binary.Unum.SORNSize u), Haskus.Binary.Bits.Bits (Haskus.Binary.Unum.SORNBackingWord u), GHC.Num.Num (Haskus.Binary.Unum.BackingWord u), GHC.Real.Integral (Haskus.Binary.Unum.BackingWord u), Haskus.Utils.HList.HFoldr' Haskus.Binary.Unum.GetLabel [GHC.Base.String] v [GHC.Base.String], v Data.Type.Equality.~ Haskus.Binary.Unum.UnumMembers u) => GHC.Show.Show (Haskus.Binary.Unum.SORN u)
+ Haskus.Binary.Unum: instance (Haskus.Binary.Unum.UnumNum a, r Data.Type.Equality.~ [GHC.Base.String]) => Haskus.Utils.HList.Apply Haskus.Binary.Unum.GetLabel (a, [GHC.Base.String]) r
+ Haskus.Binary.Unum: instance (Haskus.Utils.HList.HFoldr' Haskus.Binary.Unum.GetLabel [GHC.Base.String] v [GHC.Base.String], v Data.Type.Equality.~ Haskus.Binary.Unum.UnumMembers u, GHC.Real.Integral (Haskus.Binary.Unum.BackingWord u)) => GHC.Show.Show (Haskus.Binary.Unum.U u)
+ Haskus.Binary.Unum: instance GHC.Classes.Eq (Haskus.Binary.Unum.BackingWord u) => GHC.Classes.Eq (Haskus.Binary.Unum.U u)
+ Haskus.Binary.Unum: instance GHC.Classes.Eq Haskus.Binary.Unum.Sign
+ Haskus.Binary.Unum: instance GHC.Classes.Eq Haskus.Binary.Unum.UBit
+ Haskus.Binary.Unum: instance GHC.Show.Show Haskus.Binary.Unum.Sign
+ Haskus.Binary.Unum: instance GHC.Show.Show Haskus.Binary.Unum.UBit
+ Haskus.Binary.Unum: instance GHC.TypeNats.KnownNat n => Haskus.Binary.Unum.UnumNum (Haskus.Binary.Unum.I n)
+ Haskus.Binary.Unum: instance Haskus.Binary.Unum.UnumNum x => Haskus.Binary.Unum.UnumNum (Haskus.Binary.Unum.Neg x)
+ Haskus.Binary.Unum: instance Haskus.Binary.Unum.UnumNum x => Haskus.Binary.Unum.UnumNum (Haskus.Binary.Unum.Rcp x)
+ Haskus.Binary.Unum: instance Haskus.Binary.Unum.UnumNum x => Haskus.Binary.Unum.UnumNum (Haskus.Binary.Unum.Uncertain x)
+ Haskus.Binary.Unum: newtype CSORN u
+ Haskus.Binary.Unum: newtype U u
+ Haskus.Binary.Unum: sornAdd :: (SornAdd u, KnownNat (SORNSize u), Bits (SORNBackingWord u), Num (BackingWord u)) => SORN u -> SORN u -> SORN u
+ Haskus.Binary.Unum: sornAddDep :: (SornAdd u, KnownNat (SORNSize u), Bits (SORNBackingWord u), Num (BackingWord u)) => SORN u -> SORN u
+ Haskus.Binary.Unum: sornAddU :: SornAdd u => U u -> U u -> SORN u
+ Haskus.Binary.Unum: sornBits :: forall u s. (Bits (SORNBackingWord u), KnownNat (UnumSize u), s ~ SORNSize u, KnownNat s) => SORN u -> String
+ Haskus.Binary.Unum: sornComplement :: Bits (SORNBackingWord u) => SORN u -> SORN u
+ Haskus.Binary.Unum: sornElems :: forall u s. (s ~ SORNSize u, KnownNat s, Bits (SORNBackingWord u), Num (BackingWord u)) => SORN u -> [U u]
+ Haskus.Binary.Unum: sornEmpty :: Bits (SORNBackingWord u) => SORN u
+ Haskus.Binary.Unum: sornFromElems :: (Integral (BackingWord u), Bits (SORNBackingWord u)) => [U u] -> SORN u
+ Haskus.Binary.Unum: sornFromTo :: forall u. (Integral (BackingWord u), Bits (SORNBackingWord u), Bits (BackingWord u), KnownNat (UnumSize u)) => U u -> U u -> SORN u
+ Haskus.Binary.Unum: sornFull :: forall u. (Bits (SORNBackingWord u), KnownNat (SORNSize u)) => SORN u
+ Haskus.Binary.Unum: sornInsert :: forall u. (Bits (SORNBackingWord u), Integral (BackingWord u)) => SORN u -> U u -> SORN u
+ Haskus.Binary.Unum: sornIntersect :: forall u. Bits (SORNBackingWord u) => SORN u -> SORN u -> SORN u
+ Haskus.Binary.Unum: sornMember :: forall u. (Bits (SORNBackingWord u), Integral (BackingWord u)) => SORN u -> U u -> Bool
+ Haskus.Binary.Unum: sornNegate :: forall u. (Bits (SORNBackingWord u), Bits (BackingWord u), Integral (BackingWord u), KnownNat (SORNSize u), KnownNat (UnumSize u)) => SORN u -> SORN u
+ Haskus.Binary.Unum: sornNonInfinite :: forall u. (Bits (SORNBackingWord u), Integral (BackingWord u), Bits (BackingWord u), Encodable Infinite u) => SORN u
+ Haskus.Binary.Unum: sornNonZero :: (Bits (SORNBackingWord u), Integral (BackingWord u), Bits (BackingWord u), Encodable (I 0) u) => SORN u
+ Haskus.Binary.Unum: sornRemove :: forall u. (Bits (SORNBackingWord u), Integral (BackingWord u)) => SORN u -> U u -> SORN u
+ Haskus.Binary.Unum: sornSingle :: (Integral (BackingWord u), Bits (SORNBackingWord u)) => U u -> SORN u
+ Haskus.Binary.Unum: sornSize :: forall u s. (s ~ SORNSize u, KnownNat s) => Word
+ Haskus.Binary.Unum: sornSub :: (SornAdd u, KnownNat (SORNSize u), Bits (SORNBackingWord u), Bits (BackingWord u), Num (BackingWord u), KnownNat (UnumSize u)) => SORN u -> SORN u -> SORN u
+ Haskus.Binary.Unum: sornSubDep :: (SornAdd u, KnownNat (SORNSize u), Bits (SORNBackingWord u), Bits (BackingWord u), Num (BackingWord u), KnownNat (UnumSize u)) => SORN u -> SORN u
+ Haskus.Binary.Unum: sornSubU :: (SornAdd u, Bits (BackingWord u), Num (BackingWord u), KnownNat (UnumSize u)) => U u -> U u -> SORN u
+ Haskus.Binary.Unum: sornUnion :: forall u. Bits (SORNBackingWord u) => SORN u -> SORN u -> SORN u
+ Haskus.Binary.Unum: type Infinite = Rcp (I 0)
+ Haskus.Binary.Unum: type family SORNBackingWord u
+ Haskus.Binary.Unum: unumBits :: forall u. (Bits (BackingWord u), KnownNat (UnumSize u)) => U u -> String
+ Haskus.Binary.Unum: unumEncode :: forall u x i. (i ~ IndexOf (Simplify x) (UnumIndexables u), KnownNat i, Num (BackingWord u), Bits (BackingWord u)) => UBit -> U u
+ Haskus.Binary.Unum: unumInfinite :: forall u. (Num (BackingWord u), Bits (BackingWord u), Encodable Infinite u) => U u
+ Haskus.Binary.Unum: unumLabel :: UnumNum a => a -> String
+ Haskus.Binary.Unum: unumLabels :: forall u v. (HFoldr' GetLabel [String] v [String], v ~ UnumMembers u) => [String]
+ Haskus.Binary.Unum: unumNegate :: forall u. (Bits (BackingWord u), Num (BackingWord u), KnownNat (UnumSize u)) => U u -> U u
+ Haskus.Binary.Unum: unumReciprocate :: forall u. (Bits (BackingWord u), Num (BackingWord u), KnownNat (UnumSize u)) => U u -> U u
+ Haskus.Binary.Unum: unumSign :: forall u. (Bits (BackingWord u), KnownNat (UnumSize u)) => U u -> Sign
+ Haskus.Binary.Unum: unumSize :: forall u. KnownNat (UnumSize u) => Word
+ Haskus.Binary.Unum: unumZero :: forall u. (Num (BackingWord u), Bits (BackingWord u), Encodable (I 0) u) => U u
+ Haskus.Binary.Vector: Vector :: Buffer -> Vector a
+ Haskus.Binary.Vector: concat :: forall l (n :: Nat) a. (n ~ WholeSize l, KnownNat n, Storable a, StaticStorable a, HFoldr StoreVector (IO (Ptr a)) l (IO (Ptr a))) => HList l -> Vector n a
+ Haskus.Binary.Vector: data Vector (n :: Nat) a
+ Haskus.Binary.Vector: drop :: forall n m a. KnownNat (SizeOf a * n) => Vector (m + n) a -> Vector m a
+ Haskus.Binary.Vector: fromFilledList :: forall a (n :: Nat). (KnownNat n, Storable a) => a -> [a] -> Vector n a
+ Haskus.Binary.Vector: fromFilledListZ :: forall a (n :: Nat). (KnownNat n, Storable a) => a -> [a] -> Vector n a
+ Haskus.Binary.Vector: fromList :: forall a (n :: Nat). (KnownNat n, Storable a) => [a] -> Maybe (Vector n a)
+ Haskus.Binary.Vector: index :: forall i a n. (KnownNat (ElemOffset a i n), Storable a) => Vector n a -> a
+ Haskus.Binary.Vector: instance (GHC.TypeNats.KnownNat (Haskus.Binary.Bits.Finite.BitSize a), Haskus.Binary.Bits.Finite.FiniteBits a, GHC.TypeNats.KnownNat n, Haskus.Binary.Storable.Storable a) => Haskus.Binary.Bits.Finite.FiniteBits (Haskus.Binary.Vector.Vector n a)
+ Haskus.Binary.Vector: instance (GHC.TypeNats.KnownNat n, Haskus.Binary.Bits.Bitwise.Bitwise a, Haskus.Binary.Storable.Storable a) => Haskus.Binary.Bits.Bitwise.Bitwise (Haskus.Binary.Vector.Vector n a)
+ Haskus.Binary.Vector: instance (GHC.TypeNats.KnownNat n, Haskus.Binary.Storable.Storable a) => Haskus.Binary.Storable.Storable (Haskus.Binary.Vector.Vector n a)
+ Haskus.Binary.Vector: instance (GHC.TypeNats.KnownNat n, Haskus.Binary.Storable.Storable a, GHC.Classes.Eq a) => GHC.Classes.Eq (Haskus.Binary.Vector.Vector n a)
+ Haskus.Binary.Vector: instance (Haskus.Binary.Storable.Storable a, GHC.Show.Show a, GHC.TypeNats.KnownNat n) => GHC.Show.Show (Haskus.Binary.Vector.Vector n a)
+ Haskus.Binary.Vector: instance (Haskus.Binary.Storable.Storable a, Haskus.Binary.Bits.Bits a, GHC.TypeNats.KnownNat n, GHC.TypeNats.KnownNat (n GHC.TypeNats.* Haskus.Binary.Bits.Finite.BitSize a)) => Haskus.Binary.Bits.Rotate.RotatableBits (Haskus.Binary.Vector.Vector n a)
+ Haskus.Binary.Vector: instance (Haskus.Binary.Storable.Storable a, Haskus.Binary.Bits.Index.IndexableBits a, Haskus.Binary.Bits.Finite.FiniteBits a, GHC.TypeNats.KnownNat (Haskus.Binary.Bits.Finite.BitSize a), GHC.TypeNats.KnownNat n, Haskus.Binary.Bits.Bitwise.Bitwise a) => Haskus.Binary.Bits.Index.IndexableBits (Haskus.Binary.Vector.Vector n a)
+ Haskus.Binary.Vector: instance (Haskus.Binary.Storable.Storable a, Haskus.Binary.Bits.Shift.ShiftableBits a, Haskus.Binary.Bits.Bitwise.Bitwise a, Haskus.Binary.Bits.Finite.FiniteBits a, GHC.TypeNats.KnownNat (Haskus.Binary.Bits.Finite.BitSize a), GHC.TypeNats.KnownNat (n GHC.TypeNats.* Haskus.Binary.Bits.Finite.BitSize a), GHC.TypeNats.KnownNat n) => Haskus.Binary.Bits.Shift.ShiftableBits (Haskus.Binary.Vector.Vector n a)
+ Haskus.Binary.Vector: instance (v Data.Type.Equality.~ Haskus.Binary.Vector.Vector n a, r Data.Type.Equality.~ GHC.Types.IO (GHC.Ptr.Ptr a), GHC.TypeNats.KnownNat n, GHC.TypeNats.KnownNat (Haskus.Binary.Storable.SizeOf a), Haskus.Binary.Storable.StaticStorable a, Haskus.Binary.Storable.Storable a) => Haskus.Utils.HList.Apply Haskus.Binary.Vector.StoreVector (v, GHC.Types.IO (GHC.Ptr.Ptr a)) r
+ Haskus.Binary.Vector: instance GHC.TypeNats.KnownNat (Haskus.Binary.Storable.SizeOf a GHC.TypeNats.* n) => Haskus.Binary.Storable.StaticStorable (Haskus.Binary.Vector.Vector n a)
+ Haskus.Binary.Vector: replicate :: forall a (n :: Nat). (KnownNat n, Storable a) => a -> Vector n a
+ Haskus.Binary.Vector: take :: forall n m a. KnownNat (SizeOf a * n) => Vector (m + n) a -> Vector n a
+ Haskus.Binary.Vector: toList :: forall a (n :: Nat). (KnownNat n, Storable a) => Vector n a -> [a]
+ Haskus.Binary.Vector: vectorBuffer :: Vector n a -> Buffer
+ Haskus.Binary.Vector: vectorReverse :: (KnownNat n, Storable a) => Vector n a -> Vector n a
+ Haskus.Binary.Vector: zipWith :: (KnownNat n, Storable a, Storable b, Storable c) => (a -> b -> c) -> Vector n a -> Vector n b -> Vector n c
+ Haskus.Memory.Buffer: instance Haskus.Memory.Buffer.Freezable (Haskus.Memory.Buffer.Buffer 'Haskus.Memory.Property.Mutable pin 'Haskus.Memory.Property.Collected heap) (Haskus.Memory.Buffer.Buffer 'Haskus.Memory.Property.Immutable pin 'Haskus.Memory.Property.Collected heap)
+ Haskus.Memory.Buffer: instance Haskus.Memory.Buffer.Freezable (Haskus.Memory.Buffer.Buffer 'Haskus.Memory.Property.Mutable pin fin 'Haskus.Memory.Property.External) (Haskus.Memory.Buffer.Buffer 'Haskus.Memory.Property.Immutable pin fin 'Haskus.Memory.Property.External)
+ Haskus.Memory.Buffer: instance Haskus.Memory.Buffer.Thawable (Haskus.Memory.Buffer.Buffer 'Haskus.Memory.Property.Immutable pin 'Haskus.Memory.Property.Collected heap) (Haskus.Memory.Buffer.Buffer 'Haskus.Memory.Property.Mutable pin 'Haskus.Memory.Property.Collected heap)
+ Haskus.Memory.Buffer: instance Haskus.Memory.Buffer.Thawable (Haskus.Memory.Buffer.Buffer 'Haskus.Memory.Property.Immutable pin 'Haskus.Memory.Property.NotFinalized heap) (Haskus.Memory.Buffer.Buffer 'Haskus.Memory.Property.Mutable pin 'Haskus.Memory.Property.NotFinalized heap)
+ Haskus.Memory.Buffer: touch :: MonadIO m => a -> m ()
+ Haskus.Memory.Layout: CArray :: CArray
+ Haskus.Memory.Layout: CPrimitive :: CPrimitive
+ Haskus.Memory.Layout: CStruct :: CStruct
+ Haskus.Memory.Layout: CUArray :: CUArray
+ Haskus.Memory.Layout: CUnion :: CUnion
+ Haskus.Memory.Layout: LIndex :: Nat -> PathElem
+ Haskus.Memory.Layout: LPath :: LPath
+ Haskus.Memory.Layout: LSymbol :: Symbol -> PathElem
+ Haskus.Memory.Layout: data CArray (n :: Nat) (a :: k)
+ Haskus.Memory.Layout: data CPrimitive (size :: Nat) (align :: Nat)
+ Haskus.Memory.Layout: data CStruct (fs :: [Field])
+ Haskus.Memory.Layout: data CUArray (a :: k)
+ Haskus.Memory.Layout: data CUnion (fs :: [Field])
+ Haskus.Memory.Layout: data LPath (path :: [PathElem])
+ Haskus.Memory.Layout: data PathElem
+ Haskus.Memory.Layout: lPath :: forall e. LPath '[e]
+ Haskus.Memory.Layout: type LRoot = LPath '[]
+ Haskus.Memory.Layout: type family (:#>) p (n :: Nat)
+ Haskus.Memory.Property: Collected :: Finalization
+ Haskus.Memory.Property: External :: Heap
+ Haskus.Memory.Property: Finalized :: Finalization
+ Haskus.Memory.Property: Immutable :: Mutability
+ Haskus.Memory.Property: Internal :: Heap
+ Haskus.Memory.Property: Mutable :: Mutability
+ Haskus.Memory.Property: NotFinalized :: Finalization
+ Haskus.Memory.Property: NotPinned :: Pinning
+ Haskus.Memory.Property: Pinned :: Pinning
+ Haskus.Memory.Property: data Finalization
+ Haskus.Memory.Property: data Heap
+ Haskus.Memory.Property: data Mutability
+ Haskus.Memory.Property: data Pinning
+ Haskus.Memory.Property: instance GHC.Classes.Eq Haskus.Memory.Property.Finalization
+ Haskus.Memory.Property: instance GHC.Classes.Eq Haskus.Memory.Property.Mutability
+ Haskus.Memory.Property: instance GHC.Classes.Eq Haskus.Memory.Property.Pinning
+ Haskus.Memory.Property: instance GHC.Show.Show Haskus.Memory.Property.Finalization
+ Haskus.Memory.Property: instance GHC.Show.Show Haskus.Memory.Property.Mutability
+ Haskus.Memory.Property: instance GHC.Show.Show Haskus.Memory.Property.Pinning
+ Haskus.Memory.Ptr: AnyPointer :: (forall mut fin. Pointer mut fin) -> AnyPointer
+ Haskus.Memory.Ptr: [PtrIF] :: {-# UNPACK #-} !FinPtr -> {-# UNPACK #-} !Int -> PtrIF
+ Haskus.Memory.Ptr: [PtrI] :: {-# UNPACK #-} !RawPtr -> PtrI
+ Haskus.Memory.Ptr: [PtrMF] :: {-# UNPACK #-} !FinPtr -> {-# UNPACK #-} !Int -> PtrMF
+ Haskus.Memory.Ptr: [PtrM] :: {-# UNPACK #-} !RawPtr -> PtrM
+ Haskus.Memory.Ptr: allocFinalizedPtr :: MonadIO m => Word -> m PtrMF
+ Haskus.Memory.Ptr: allocPtr :: MonadIO m => Word -> m PtrM
+ Haskus.Memory.Ptr: castFunPtrToPtr :: () => FunPtr a -> Ptr b
+ Haskus.Memory.Ptr: castPtrToFunPtr :: () => Ptr a -> FunPtr b
+ Haskus.Memory.Ptr: data FunPtr a
+ Haskus.Memory.Ptr: data Pointer (mut :: Mutability) (fin :: Finalization)
+ Haskus.Memory.Ptr: data WordPtr
+ Haskus.Memory.Ptr: distancePtr :: Pointer mut0 fin0 -> Pointer mut1 fin1 -> Int
+ Haskus.Memory.Ptr: freePtr :: MonadIO m => Pointer mut 'NotFinalized -> m ()
+ Haskus.Memory.Ptr: indexPtr :: Pointer mut fin -> Int -> Pointer mut fin
+ Haskus.Memory.Ptr: instance GHC.Show.Show (Haskus.Memory.Ptr.Pointer mut fin)
+ Haskus.Memory.Ptr: isNullPtr :: Pointer mut fin -> Bool
+ Haskus.Memory.Ptr: newtype AnyPointer
+ Haskus.Memory.Ptr: nullFunPtr :: () => FunPtr a
+ Haskus.Memory.Ptr: nullPtrI :: PtrI
+ Haskus.Memory.Ptr: nullPtrM :: PtrM
+ Haskus.Memory.Ptr: ptrToWordPtr :: () => Ptr a -> WordPtr
+ Haskus.Memory.Ptr: type FinPtr = ForeignPtr ()
+ Haskus.Memory.Ptr: type PtrI = Pointer 'Immutable 'NotFinalized
+ Haskus.Memory.Ptr: type PtrIF = Pointer 'Immutable 'Finalized
+ Haskus.Memory.Ptr: type PtrM = Pointer 'Mutable 'NotFinalized
+ Haskus.Memory.Ptr: type PtrMF = Pointer 'Mutable 'Finalized
+ Haskus.Memory.Ptr: type RawPtr = Ptr ()
+ Haskus.Memory.Ptr: withFinalizedPtr :: MonadInIO m => Pointer mut 'Finalized -> (Pointer mut 'NotFinalized -> m b) -> m b
+ Haskus.Memory.Ptr: withPtr :: MonadInIO m => Pointer mut fin -> (Pointer mut 'NotFinalized -> m b) -> m b
+ Haskus.Memory.Ptr: wordPtrToPtr :: () => WordPtr -> Ptr a
+ Haskus.Memory.Typed: BufferT :: Buffer mut pin fin heap -> BufferT mut pin fin heap
+ Haskus.Memory.Typed: PointerT :: Pointer mut fin -> PointerT mut fin
+ Haskus.Memory.Typed: PtrT :: Ptr () -> PtrT
+ Haskus.Memory.Typed: newtype BufferT (t :: k) mut pin fin heap
+ Haskus.Memory.Typed: newtype PointerT (t :: k) mut fin
+ Haskus.Memory.Typed: newtype PtrT (t :: k)
+ Haskus.Memory.Utils: allocaArrays :: (MonadInIO m, Storable s, Integral a) => [a] -> ([Ptr s] -> m b) -> m b
+ Haskus.Memory.Utils: memCopy :: MonadIO m => Ptr a -> Ptr b -> Word64 -> m ()
+ Haskus.Memory.Utils: memSet :: MonadIO m => Ptr a -> Word64 -> Word8 -> m ()
+ Haskus.Memory.Utils: memcpy# :: Addr# -> Addr# -> Int# -> IO ()
+ Haskus.Memory.Utils: peekArrays :: (MonadIO m, Storable s, Integral a) => [a] -> [Ptr s] -> m [[s]]
+ Haskus.Memory.Utils: pokeArrays :: (MonadIO m, Storable s) => [Ptr s] -> [[s]] -> m ()
+ Haskus.Memory.Utils: withArrays :: (MonadInIO m, Storable s) => [[s]] -> ([Ptr s] -> m b) -> m b
+ Haskus.Memory.Utils: withMaybeOrNull :: (Storable a, MonadInIO m) => Maybe a -> (Ptr a -> m b) -> m b
+ Haskus.Number.BitNat: (.*.) :: forall a b m. (m ~ (a + b), Widen a m, Widen b m, Num (BitNatWord m)) => BitNat a -> BitNat b -> BitNat m
+ Haskus.Number.BitNat: (.+.) :: forall a b m. (m ~ (Max a b + 1), Widen a m, Widen b m, Num (BitNatWord m)) => BitNat a -> BitNat b -> BitNat m
+ Haskus.Number.BitNat: (.-.) :: forall a b m. (m ~ Max a b, Widen a m, Widen b m, Num (BitNatWord m)) => BitNat a -> BitNat b -> Maybe (BitNat m)
+ Haskus.Number.BitNat: (./.) :: forall a b m. (m ~ Max a b, Widen a m, Widen b m, Num (BitNatWord (Min a b))) => BitNat a -> BitNat b -> Maybe (BitNat a, BitNat (Min a b))
+ Haskus.Number.BitNat: (.<<.) :: forall (s :: Nat) a. BitNatShiftLeft a s => BitNat a -> NatVal s -> BitNat (a + s)
+ Haskus.Number.BitNat: (.>>.) :: forall (s :: Nat) a. BitNatShiftRight a s => BitNat a -> NatVal s -> BitNat (a - s)
+ Haskus.Number.BitNat: NatVal :: NatVal
+ Haskus.Number.BitNat: bitNat :: forall (v :: Nat) (n :: Nat). (n ~ NatBitCount v, Integral (BitNatWord n), MakeBitNat n, KnownNat v) => BitNat n
+ Haskus.Number.BitNat: bitNatAnd :: forall a. IsBitNat a => BitNat a -> BitNat a -> BitNat a
+ Haskus.Number.BitNat: bitNatOne :: Num (BitNatWord a) => BitNat a
+ Haskus.Number.BitNat: bitNatOr :: forall a. IsBitNat a => BitNat a -> BitNat a -> BitNat a
+ Haskus.Number.BitNat: bitNatTestBit :: IndexableBits (BitNatWord a) => BitNat a -> Word -> Bool
+ Haskus.Number.BitNat: bitNatToNatural :: Integral (BitNatWord a) => BitNat a -> Natural
+ Haskus.Number.BitNat: bitNatXor :: forall a. IsBitNat a => BitNat a -> BitNat a -> BitNat a
+ Haskus.Number.BitNat: bitNatZero :: Num (BitNatWord a) => BitNat a
+ Haskus.Number.BitNat: compareW :: forall a b. (Ord (BitNatWord (Max a b)), Widen a (Max a b), Widen b (Max a b)) => BitNat a -> BitNat b -> Ordering
+ Haskus.Number.BitNat: data BitNat (b :: Nat)
+ Haskus.Number.BitNat: data NatVal (t :: Nat)
+ Haskus.Number.BitNat: extractW :: BitNat a -> BitNatWord a
+ Haskus.Number.BitNat: instance (GHC.TypeNats.KnownNat b, GHC.Real.Integral (Haskus.Number.BitNat.BitNatWord b)) => GHC.Show.Show (Haskus.Number.BitNat.BitNat b)
+ Haskus.Number.BitNat: instance GHC.Classes.Eq (Haskus.Number.BitNat.BitNatWord a) => GHC.Classes.Eq (Haskus.Number.BitNat.BitNat a)
+ Haskus.Number.BitNat: instance GHC.Classes.Ord (Haskus.Number.BitNat.BitNatWord a) => GHC.Classes.Ord (Haskus.Number.BitNat.BitNat a)
+ Haskus.Number.BitNat: narrow :: forall b a. Narrow a b => BitNat a -> BitNat b
+ Haskus.Number.BitNat: pattern BitNat :: forall (n :: Nat). (Integral (BitNatWord n), MakeBitNat n) => Natural -> BitNat n
+ Haskus.Number.BitNat: safeMakeBitNat :: forall a. MakeBitNat a => Natural -> Maybe (BitNat a)
+ Haskus.Number.BitNat: type BitNatShiftLeft a s = (ShiftableBits (BitNatWord (a + s)), KnownNat s, Widen a (a + s))
+ Haskus.Number.BitNat: type BitNatShiftRight a s = (ShiftableBits (BitNatWord a), KnownNat s, Narrow a (a - s))
+ Haskus.Number.BitNat: type IsBitNat b = (Num (BitNatWord b), Integral (BitNatWord b), Bitwise (BitNatWord b), IndexableBits (BitNatWord b))
+ Haskus.Number.BitNat: type MakeBitNat a = (Maskable a (BitNatWord a), ShiftableBits (BitNatWord a), Show (BitNatWord a), Eq (BitNatWord a), Num (BitNatWord a))
+ Haskus.Number.BitNat: type Narrow a b = (Assert (b <=? a) (() :: Constraint) ( 'Text "Can't narrow a natural of " :<>: 'ShowType a :<>: 'Text " bits into a natural of " :<>: 'ShowType b :<>: 'Text " bits"), Integral (BitNatWord a), Integral (BitNatWord b), Maskable b (BitNatWord b))
+ Haskus.Number.BitNat: type Widen a b = (Assert (a <=? b) (() :: Constraint) ( 'Text "Can't widen a natural of " :<>: 'ShowType a :<>: 'Text " bits into a natural of " :<>: 'ShowType b :<>: 'Text " bits"), Integral (BitNatWord a), Integral (BitNatWord b))
+ Haskus.Number.BitNat: type family BitNatWord b
+ Haskus.Number.BitNat: unsafeMakeBitNat :: forall a. Maskable a (BitNatWord a) => BitNatWord a -> BitNat a
+ Haskus.Number.BitNat: widen :: forall b a. Widen a b => BitNat a -> BitNat b
+ Haskus.Number.FixedPoint: FixedPoint :: BitFields w '[BitField i "integer" w, BitField f "fractional" w] -> FixedPoint w
+ Haskus.Number.FixedPoint: fromFixedPoint :: forall a w (n :: Nat) (d :: Nat). (RealFrac a, BitSize w ~ (n + d), KnownNat n, KnownNat d, Bits w, Field w, Num w, Integral w) => FixedPoint w n d -> a
+ Haskus.Number.FixedPoint: fromFixedPointBase :: forall w i f. w -> FixedPoint w i f
+ Haskus.Number.FixedPoint: getFixedPointBase :: FixedPoint w i f -> w
+ Haskus.Number.FixedPoint: instance (GHC.Real.Integral w, Haskus.Binary.Bits.Bits w, Haskus.Binary.BitField.Field w, Haskus.Binary.Bits.Finite.BitSize w Data.Type.Equality.~ (n GHC.TypeNats.+ d), GHC.TypeNats.KnownNat n, GHC.TypeNats.KnownNat d) => GHC.Classes.Eq (Haskus.Number.FixedPoint.FixedPoint w n d)
+ Haskus.Number.FixedPoint: instance (GHC.Real.Integral w, Haskus.Binary.Bits.Bits w, Haskus.Binary.BitField.Field w, Haskus.Binary.Bits.Finite.BitSize w Data.Type.Equality.~ (n GHC.TypeNats.+ d), GHC.TypeNats.KnownNat n, GHC.TypeNats.KnownNat d) => GHC.Classes.Ord (Haskus.Number.FixedPoint.FixedPoint w n d)
+ Haskus.Number.FixedPoint: instance (GHC.Real.Integral w, Haskus.Binary.Bits.Bits w, Haskus.Binary.BitField.Field w, Haskus.Binary.Bits.Finite.BitSize w Data.Type.Equality.~ (n GHC.TypeNats.+ d), GHC.TypeNats.KnownNat n, GHC.TypeNats.KnownNat d, GHC.Show.Show w) => GHC.Show.Show (Haskus.Number.FixedPoint.FixedPoint w n d)
+ Haskus.Number.FixedPoint: instance (Haskus.Binary.Bits.Finite.BitSize w Data.Type.Equality.~ (i GHC.TypeNats.+ f), GHC.Num.Num w, Haskus.Binary.Bits.Finite.FiniteBits w, Haskus.Binary.Bits.Bits w, GHC.TypeNats.KnownNat i, GHC.TypeNats.KnownNat f, Haskus.Binary.BitField.Field w, GHC.Real.Integral w) => GHC.Num.Num (Haskus.Number.FixedPoint.FixedPoint w i f)
+ Haskus.Number.FixedPoint: instance (Haskus.Binary.Bits.Finite.BitSize w Data.Type.Equality.~ (i GHC.TypeNats.+ f), GHC.Real.Integral w, Haskus.Binary.Bits.Finite.FiniteBits w, Haskus.Binary.Bits.Bits w, Haskus.Binary.BitField.Field w, GHC.TypeNats.KnownNat i, GHC.TypeNats.KnownNat f) => GHC.Real.Real (Haskus.Number.FixedPoint.FixedPoint w i f)
+ Haskus.Number.FixedPoint: instance Haskus.Binary.Storable.Storable w => Haskus.Binary.Storable.Storable (Haskus.Number.FixedPoint.FixedPoint w i f)
+ Haskus.Number.FixedPoint: newtype FixedPoint w (i :: Nat) (f :: Nat)
+ Haskus.Number.FixedPoint: toFixedPoint :: forall a w (n :: Nat) (d :: Nat). (RealFrac a, BitSize w ~ (n + d), KnownNat n, KnownNat d, Bits w, Field w, Num w, Integral w) => a -> FixedPoint w n d
+ Haskus.Number.Float: float32ToWord32 :: Float32 -> Word32
+ Haskus.Number.Float: float64ToWord64 :: Float64 -> Word64
+ Haskus.Number.Float: type Float32 = Float
+ Haskus.Number.Float: type Float64 = Double
+ Haskus.Number.Float: word32ToFloat32 :: Word32 -> Float32
+ Haskus.Number.Float: word64ToFloat64 :: Word64 -> Float64
+ Haskus.Number.Int: (+#) :: Int# -> Int# -> Int#
+ Haskus.Number.Int: (-#) :: Int# -> Int# -> Int#
+ Haskus.Number.Int: (<#) :: Int# -> Int# -> Int#
+ Haskus.Number.Int: (<=#) :: Int# -> Int# -> Int#
+ Haskus.Number.Int: (==#) :: Int# -> Int# -> Int#
+ Haskus.Number.Int: (>#) :: Int# -> Int# -> Int#
+ Haskus.Number.Int: (>=#) :: Int# -> Int# -> Int#
+ Haskus.Number.Int: data Int# :: TYPE IntRep
+ Haskus.Number.Int: infix 4 <=#
+ Haskus.Number.Int: infixl 6 -#
+ Haskus.Number.Int: isTrue# :: Int# -> Bool
+ Haskus.Number.Int: type family IntN (n :: Nat)
+ Haskus.Number.NaturalRange: (.++.) :: (MakeNatRange f1 t1, MakeNatRange f2 t2, MakeNatRange (f1 + f2) (t1 + t2)) => NatRange f1 t1 -> NatRange f2 t2 -> NatRange (f1 + f2) (t1 + t2)
+ Haskus.Number.NaturalRange: data NatRange (f :: Nat) (t :: Nat)
+ Haskus.Number.NaturalRange: instance (GHC.TypeNats.KnownNat (t GHC.TypeNats.- f), GHC.TypeNats.KnownNat t, GHC.TypeNats.KnownNat f, GHC.Num.Num (Haskus.Number.BitNat.BitNatWord (Haskus.Utils.Types.Nat.NatBitCount ((t GHC.TypeNats.- f) GHC.TypeNats.+ 1))), GHC.Real.Integral (Haskus.Number.BitNat.BitNatWord (Haskus.Utils.Types.Nat.NatBitCount ((t GHC.TypeNats.- f) GHC.TypeNats.+ 1)))) => GHC.Show.Show (Haskus.Number.NaturalRange.NatRange f t)
+ Haskus.Number.NaturalRange: makeNatRange :: forall f t. MakeNatRange f t => Natural -> NatRange f t
+ Haskus.Number.NaturalRange: natRange :: forall (n :: Nat) f t. (MakeNatRange f t, CheckInRange f t n, KnownNat n) => NatRange f t
+ Haskus.Number.NaturalRange: pattern NatRange :: forall (f :: Nat) (t :: Nat). MakeNatRange f t => Natural -> NatRange f t
+ Haskus.Number.NaturalRange: safeMakeNatRange :: forall f t. MakeNatRange f t => Natural -> Maybe (NatRange f t)
+ Haskus.Number.NaturalRange: unsafeMakeNatRange :: forall f t. MakeNatRange f t => Natural -> NatRange f t
+ Haskus.Number.NaturalRange: widenNatRange :: forall f2 t2 f1 t1. WidenNatRange f1 t1 f2 t2 => NatRange f1 t1 -> NatRange f2 t2
+ Haskus.Number.Posit: InfinityK :: PositKind
+ Haskus.Number.Posit: NormalK :: PositKind
+ Haskus.Number.Posit: Posit :: IntN nbits -> Posit
+ Haskus.Number.Posit: PositEncoding :: PositFields -> PositEncoding
+ Haskus.Number.Posit: PositFields :: Bool -> Word -> Word -> Word -> Int -> Word -> Word -> PositFields
+ Haskus.Number.Posit: PositInfinity :: PositEncoding
+ Haskus.Number.Posit: PositZero :: PositEncoding
+ Haskus.Number.Posit: ZeroK :: PositKind
+ Haskus.Number.Posit: [Infinity] :: PositK 'InfinityK nbits es
+ Haskus.Number.Posit: [Value] :: Posit nbits es -> PositK 'NormalK nbits es
+ Haskus.Number.Posit: [Zero] :: PositK 'ZeroK nbits es
+ Haskus.Number.Posit: [positExponentBitCount] :: PositFields -> Word
+ Haskus.Number.Posit: [positExponent] :: PositFields -> Word
+ Haskus.Number.Posit: [positFractionBitCount] :: PositFields -> Word
+ Haskus.Number.Posit: [positFraction] :: PositFields -> Word
+ Haskus.Number.Posit: [positNegative] :: PositFields -> Bool
+ Haskus.Number.Posit: [positRegimeBitCount] :: PositFields -> Word
+ Haskus.Number.Posit: [positRegime] :: PositFields -> Int
+ Haskus.Number.Posit: data PositEncoding
+ Haskus.Number.Posit: data PositFields
+ Haskus.Number.Posit: data PositK k nbits es
+ Haskus.Number.Posit: data PositKind
+ Haskus.Number.Posit: floatBinaryAccuracy :: forall f. (Fractional f, Real f) => Rational -> Double
+ Haskus.Number.Posit: instance (Haskus.Binary.Bits.Bits (Haskus.Number.Int.IntN n), Haskus.Binary.Bits.Finite.FiniteBits (Haskus.Number.Int.IntN n), GHC.Classes.Ord (Haskus.Number.Int.IntN n), GHC.Num.Num (Haskus.Number.Int.IntN n), GHC.TypeNats.KnownNat n, GHC.TypeNats.KnownNat es, GHC.Real.Integral (Haskus.Number.Int.IntN n)) => GHC.Show.Show (Haskus.Number.Posit.Posit n es)
+ Haskus.Number.Posit: instance GHC.Classes.Eq Haskus.Number.Posit.PositKind
+ Haskus.Number.Posit: instance GHC.Show.Show Haskus.Number.Posit.PositEncoding
+ Haskus.Number.Posit: instance GHC.Show.Show Haskus.Number.Posit.PositFields
+ Haskus.Number.Posit: instance GHC.Show.Show Haskus.Number.Posit.PositKind
+ Haskus.Number.Posit: isInfinity :: forall n es. (Bits (IntN n), Eq (IntN n), KnownNat n) => Posit n es -> Bool
+ Haskus.Number.Posit: isNegative :: forall n es. (Bits (IntN n), Ord (IntN n), KnownNat n) => PositValue n es -> Bool
+ Haskus.Number.Posit: isPositive :: forall n es. (Bits (IntN n), Ord (IntN n), KnownNat n) => PositValue n es -> Bool
+ Haskus.Number.Posit: isZero :: forall n es. (Bits (IntN n), Eq (IntN n), KnownNat n) => Posit n es -> Bool
+ Haskus.Number.Posit: newtype Posit (nbits :: Nat) (es :: Nat)
+ Haskus.Number.Posit: positAbs :: forall n es. (Num (IntN n), KnownNat n) => PositValue n es -> PositValue n es
+ Haskus.Number.Posit: positApproxFactor :: forall p n es. (Posit n es ~ p, Num (IntN n), Bits (IntN n), Integral (IntN n), KnownNat es, KnownNat n) => Rational -> Double
+ Haskus.Number.Posit: positBinaryAccuracy :: forall p n es. (Posit n es ~ p, Num (IntN n), Bits (IntN n), Integral (IntN n), KnownNat es, KnownNat n) => Rational -> Double
+ Haskus.Number.Posit: positBinaryError :: forall p n es. (Posit n es ~ p, Num (IntN n), Bits (IntN n), Integral (IntN n), KnownNat es, KnownNat n) => Rational -> Double
+ Haskus.Number.Posit: positDecimalAccuracy :: forall p n es. (Posit n es ~ p, Num (IntN n), Bits (IntN n), Integral (IntN n), KnownNat es, KnownNat n) => Rational -> Double
+ Haskus.Number.Posit: positDecimalError :: forall p n es. (Posit n es ~ p, Num (IntN n), Bits (IntN n), Integral (IntN n), KnownNat es, KnownNat n) => Rational -> Double
+ Haskus.Number.Posit: positEncoding :: forall n es. (Bits (IntN n), Ord (IntN n), Num (IntN n), KnownNat n, KnownNat es, Integral (IntN n)) => Posit n es -> PositEncoding
+ Haskus.Number.Posit: positFields :: forall n es. (Bits (IntN n), Ord (IntN n), Num (IntN n), KnownNat n, KnownNat es, Integral (IntN n)) => PositValue n es -> PositFields
+ Haskus.Number.Posit: positFromRational :: forall p n es. (Posit n es ~ p, Num (IntN n), Bits (IntN n), KnownNat es, KnownNat n) => Rational -> Posit n es
+ Haskus.Number.Posit: positKind :: forall n es. (Bits (IntN n), KnownNat n, Eq (IntN n)) => Posit n es -> SomePosit n es
+ Haskus.Number.Posit: positToRational :: forall n es. (KnownNat n, KnownNat es, Eq (IntN n), Bits (IntN n), Integral (IntN n)) => Posit n es -> Rational
+ Haskus.Number.Signed: Signed :: BitNat (b + 1) -> Signed
+ Haskus.Number.Signed: instance (GHC.TypeNats.KnownNat b, GHC.Real.Integral (Haskus.Number.BitNat.BitNatWord b), Haskus.Binary.Bits.Index.IndexableBits (Haskus.Number.BitNat.BitNatWord (b GHC.TypeNats.+ 1)), GHC.Num.Num (Haskus.Number.BitNat.BitNatWord (b GHC.TypeNats.+ 1)), GHC.Classes.Eq (Haskus.Number.BitNat.BitNatWord (b GHC.TypeNats.+ 1)), GHC.Real.Integral (Haskus.Number.BitNat.BitNatWord (b GHC.TypeNats.+ 1)), Haskus.Binary.Bits.Shift.ShiftableBits (Haskus.Number.BitNat.BitNatWord (b GHC.TypeNats.+ 1)), Haskus.Number.BitNat.Narrow (b GHC.TypeNats.+ 1) ((b GHC.TypeNats.+ 1) GHC.TypeNats.- 1)) => GHC.Show.Show (Haskus.Number.Signed.Signed b)
+ Haskus.Number.Signed: newtype Signed (b :: Nat)
+ Haskus.Number.Signed: signedFromBitNat :: forall b. SignedFromBitNat b => BitNat b -> Signed b
+ Haskus.Number.Signed: signedIsZero :: forall b. SignedIsZero b => Signed b -> Bool
+ Haskus.Number.Signed: signedNeg :: forall (v :: Nat) b. SignedNeg b v => Signed b
+ Haskus.Number.Signed: signedNegate :: SignedNegate b => Signed b -> Signed b
+ Haskus.Number.Signed: signedPos :: forall (v :: Nat) b. SignedPos b v => Signed b
+ Haskus.Number.Signed: type SignedFromBitNat b = (ShiftableBits (BitNatWord (b + 1)), Widen b (b + 1))
+ Haskus.Number.Signed: type SignedIsZero b = (BitNatShiftRight (b + 1) 1)
+ Haskus.Number.Signed: type SignedNeg b v = (SignedPos b v, SignedNegate b)
+ Haskus.Number.Signed: type SignedNegate b = (IsBitNat (b + 1))
+ Haskus.Number.Signed: type SignedPos b v = (b ~ NatBitCount v, MakeBitNat b, KnownNat v, BitNatShiftLeft b 1)
+ Haskus.Number.SignedSafe: Signed :: BitNat (b + 1) -> Signed
+ Haskus.Number.SignedSafe: instance (GHC.TypeNats.KnownNat b, GHC.Real.Integral (Haskus.Number.BitNat.BitNatWord b), Haskus.Binary.Bits.Index.IndexableBits (Haskus.Number.BitNat.BitNatWord (b GHC.TypeNats.+ 1)), GHC.Num.Num (Haskus.Number.BitNat.BitNatWord (b GHC.TypeNats.+ 1)), GHC.Classes.Eq (Haskus.Number.BitNat.BitNatWord (b GHC.TypeNats.+ 1)), GHC.Real.Integral (Haskus.Number.BitNat.BitNatWord (b GHC.TypeNats.+ 1)), Haskus.Binary.Bits.Shift.ShiftableBits (Haskus.Number.BitNat.BitNatWord (b GHC.TypeNats.+ 1)), Haskus.Number.BitNat.Narrow (b GHC.TypeNats.+ 1) ((b GHC.TypeNats.+ 1) GHC.TypeNats.- 1)) => GHC.Show.Show (Haskus.Number.SignedSafe.Signed b)
+ Haskus.Number.SignedSafe: newtype Signed (b :: Nat)
+ Haskus.Number.SignedSafe: signedFromBitNat :: (ShiftableBits (BitNatWord (b + 1)), Widen b (b + 1)) => BitNat b -> Signed b
+ Haskus.Number.SignedSafe: signedIsNaN :: (Num (BitNatWord (b + 1)), Eq (BitNatWord (b + 1))) => Signed b -> Bool
+ Haskus.Number.SignedSafe: signedIsZero :: (Num (BitNatWord (b + 1)), Eq (BitNatWord (b + 1))) => Signed b -> Bool
+ Haskus.Number.SignedSafe: signedNeg :: forall (v :: Nat) b. (b ~ NatBitCount v, MakeBitNat b, Bitwise (BitNatWord b), KnownNat v, Widen b (b + 1), ShiftableBits (BitNatWord (b + 1)), IsBitNat (b + 1)) => Signed b
+ Haskus.Number.SignedSafe: signedNegate :: IsBitNat (b + 1) => Signed b -> Signed b
+ Haskus.Number.SignedSafe: signedPos :: forall (v :: Nat) b. (b ~ NatBitCount v, MakeBitNat b, Bitwise (BitNatWord b), Integral (BitNatWord (b + 1)), KnownNat v, ShiftableBits (BitNatWord (b + 1)), Widen b (b + 1)) => Signed b
+ Haskus.Number.VariableLength: fromULEB128 :: (Bits a, Monad m, Integral a) => m Word8 -> m a
+ Haskus.Number.VariableLength: getLEB128Buffer :: BitOrder -> Get Buffer
+ Haskus.Number.VariableLength: getSLEB128 :: (Integral a, Bits a) => Get a
+ Haskus.Number.VariableLength: getULEB128 :: (Integral a, Bits a) => Get a
+ Haskus.Number.VariableLength: putSLEB128 :: (Integral a, Bits a) => a -> Put
+ Haskus.Number.VariableLength: putULEB128 :: (Integral a, Bits a) => a -> Put
+ Haskus.Number.VariableLength: toULEB128 :: (Bits a, Monad m, Integral a) => (Word8 -> m ()) -> a -> m ()
+ Haskus.Number.Word: data Word# :: TYPE WordRep
+ Haskus.Number.Word: eqWord# :: Word# -> Word# -> Int#
+ Haskus.Number.Word: geWord# :: Word# -> Word# -> Int#
+ Haskus.Number.Word: gtWord# :: Word# -> Word# -> Int#
+ Haskus.Number.Word: leWord# :: Word# -> Word# -> Int#
+ Haskus.Number.Word: ltWord# :: Word# -> Word# -> Int#
+ Haskus.Number.Word: minusWord# :: Word# -> Word# -> Word#
+ Haskus.Number.Word: plusWord# :: Word# -> Word# -> Word#
+ Haskus.Number.Word: type family WordN (n :: Nat)
- Haskus.Memory.Buffer: [BufferF] :: {-# UNPACK #-} !ByteArray -> {-# UNPACK #-} !Finalizers -> BufferF
+ Haskus.Memory.Buffer: [BufferF] :: !ByteArray# -> {-# UNPACK #-} !Finalizers -> BufferF
- Haskus.Memory.Buffer: [BufferMF] :: {-# UNPACK #-} !MutableByteArray RealWorld -> {-# UNPACK #-} !Finalizers -> BufferMF
+ Haskus.Memory.Buffer: [BufferMF] :: !MutableByteArray# RealWorld -> {-# UNPACK #-} !Finalizers -> BufferMF
- Haskus.Memory.Buffer: [BufferMPF] :: {-# UNPACK #-} !MutableByteArray RealWorld -> {-# UNPACK #-} !Finalizers -> BufferMPF
+ Haskus.Memory.Buffer: [BufferMPF] :: !MutableByteArray# RealWorld -> {-# UNPACK #-} !Finalizers -> BufferMPF
- Haskus.Memory.Buffer: [BufferMP] :: {-# UNPACK #-} !MutableByteArray RealWorld -> BufferMP
+ Haskus.Memory.Buffer: [BufferMP] :: !MutableByteArray# RealWorld -> BufferMP
- Haskus.Memory.Buffer: [BufferM] :: {-# UNPACK #-} !MutableByteArray RealWorld -> BufferM
+ Haskus.Memory.Buffer: [BufferM] :: !MutableByteArray# RealWorld -> BufferM
- Haskus.Memory.Buffer: [BufferPF] :: {-# UNPACK #-} !ByteArray -> {-# UNPACK #-} !Finalizers -> BufferPF
+ Haskus.Memory.Buffer: [BufferPF] :: !ByteArray# -> {-# UNPACK #-} !Finalizers -> BufferPF
- Haskus.Memory.Buffer: [BufferP] :: {-# UNPACK #-} !ByteArray -> BufferP
+ Haskus.Memory.Buffer: [BufferP] :: !ByteArray# -> BufferP
- Haskus.Memory.Buffer: [Buffer] :: {-# UNPACK #-} !ByteArray -> BufferI
+ Haskus.Memory.Buffer: [Buffer] :: !ByteArray# -> BufferI

Files

haskus-binary.cabal view
@@ -1,6 +1,6 @@ cabal-version:       2.4 name:                haskus-binary-version:             1.4+version:             1.5 synopsis:            Haskus binary format manipulation license:             BSD-3-Clause license-file:        LICENSE@@ -18,57 +18,68 @@  source-repository head   type: git-  location: git://github.com/haskus/haskus-packages.git+  location: git://github.com/haskus/packages.git  library   exposed-modules: -    Haskus.Format.Binary.Bits-    Haskus.Format.Binary.Bits.Finite-    Haskus.Format.Binary.Bits.Index-    Haskus.Format.Binary.Bits.Bitwise-    Haskus.Format.Binary.Bits.Reverse-    Haskus.Format.Binary.Bits.Rotate-    Haskus.Format.Binary.Bits.Shift-    Haskus.Format.Binary.Bits.Order-    Haskus.Format.Binary.Bits.Get-    Haskus.Format.Binary.Bits.Put-    Haskus.Format.Binary.Bits.Mask-    Haskus.Format.Binary.Bits.Helper+    Haskus.Binary.Bits+    Haskus.Binary.Bits.Finite+    Haskus.Binary.Bits.Index+    Haskus.Binary.Bits.Bitwise+    Haskus.Binary.Bits.Reverse+    Haskus.Binary.Bits.Rotate+    Haskus.Binary.Bits.Shift+    Haskus.Binary.Bits.Order+    Haskus.Binary.Bits.Get+    Haskus.Binary.Bits.Put+    Haskus.Binary.Bits.Mask+    Haskus.Binary.Bits.Helper -    Haskus.Format.Binary.BitSet-    Haskus.Format.Binary.BitField-    Haskus.Format.Binary.Buffer-    Haskus.Format.Binary.BufferList-    Haskus.Format.Binary.BufferBuilder-    Haskus.Format.Binary.Char-    Haskus.Format.Binary.Enum-    Haskus.Format.Binary.Endianness-    Haskus.Format.Binary.FixedPoint-    Haskus.Format.Binary.Get-    Haskus.Format.Binary.Put-    Haskus.Format.Binary.VariableLength-    Haskus.Format.Binary.Vector-    Haskus.Format.Binary.Union-    Haskus.Format.Binary.Unum-    Haskus.Format.Binary.Posit-    Haskus.Format.Binary.Record-    Haskus.Format.Binary.Storable-    Haskus.Format.Binary.Word-    Haskus.Format.Binary.Ptr-    Haskus.Format.Binary.Serialize-    Haskus.Format.Binary.Serialize.Buffer-    Haskus.Format.Binary.Layout+    Haskus.Binary.BitSet+    Haskus.Binary.BitField+    Haskus.Binary.Buffer+    Haskus.Binary.BufferList+    Haskus.Binary.BufferBuilder+    Haskus.Binary.Char+    Haskus.Binary.Enum+    Haskus.Binary.Endianness+    Haskus.Binary.Get+    Haskus.Binary.Put+    Haskus.Binary.Vector+    Haskus.Binary.Union+    Haskus.Binary.Unum+    Haskus.Binary.Record+    Haskus.Binary.Storable+    Haskus.Binary.Serialize+    Haskus.Binary.Serialize.Size+    Haskus.Binary.Serialize.Put+    Haskus.Binary.Serialize.Get+    Haskus.Binary.Serialize.Buffer+    Haskus.Binary.Serialize.File+    Haskus.Binary.CTypes -    Haskus.Format.Number-    Haskus.Format.Number.BitNat-    Haskus.Format.Number.NaturalRange+    Haskus.Number+    Haskus.Number.Word+    Haskus.Number.Int+    Haskus.Number.Float+    Haskus.Number.VariableLength+    Haskus.Number.Posit+    Haskus.Number.FixedPoint+    Haskus.Number.BitNat+    Haskus.Number.Signed+    Haskus.Number.SignedSafe+    Haskus.Number.NaturalRange -    Haskus.Utils.Memory+    Haskus.Memory.Utils     Haskus.Memory.Buffer     Haskus.Memory.Allocator.Malloc     Haskus.Memory.Embed+    Haskus.Memory.Layout     Haskus.Memory.View+    Haskus.Memory.Ptr+    Haskus.Memory.Property+    Haskus.Memory.Typed    other-modules: @@ -81,15 +92,13 @@       ,  cereal                    >= 0.5       ,  bytestring                >= 0.10       ,  mtl                       >= 2.2-      ,  primitive       ,  megaparsec       ,  template-haskell       ,  transformers       ,  directory       ,  filepath -  build-tools: -  ghc-options:          -Wall+  ghc-options:          -Wall -Wno-unticked-promoted-constructors   default-language:     Haskell2010   hs-source-dirs:       src/lib 
src/bench/BitReverse.hs view
@@ -1,7 +1,7 @@  import Criterion.Main-import Haskus.Format.Binary.Bits.Reverse-import Haskus.Format.Binary.Word+import Haskus.Binary.Bits.Reverse+import Haskus.Number.Word  main :: IO () main = do
+ src/lib/Haskus/Binary/BitField.hs view
@@ -0,0 +1,369 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE KindSignatures #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE MultiParamTypeClasses  #-}+{-# LANGUAGE AllowAmbiguousTypes #-}++-- | Bit fields (as in C)+--+-- This module allows you to define bit fields over words. For instance, you can+-- have a Word16 split into 3 fields X, Y and Z composed of 5, 9 and 2 bits+-- respectively.+--+-- @                  X             Y          Z   @+-- @ w :: Word16 |0 0 0 0 0|0 0 0 0 0 0 0 0 0|0 0| @+-- +-- You define it as follows:+--+-- @+-- {-# LANGUAGE DataKinds #-}+--+-- w :: BitFields Word16 '[ BitField 5 "X" Word8 +--                        , BitField 9 "Y" Word16+--                        , BitField 2 "Z" Word8+--                        ]+-- w = BitFields 0x0102+-- @+--+-- Note that each field has its own associated type (e.g. Word8 for X and Z)+-- that must be large enough to hold the number of bits for the field.+--+-- Operations on BitFields expect that the cumulated size of the fields is equal+-- to the whole word size: use a padding field if necessary. Otherwise you can+-- use unsafe versions of the functions: extractField', updateField',+-- withField'.+-- +-- You can extract and update the value of a field by its name:+--+-- @+-- x = extractField @"X" w+-- z = extractField @"Z" w+-- w' = updateField @"Y" 0x16 w+-- @+--+-- Fields can also be 'BitSet' or 'EnumField':+--+-- @+-- {-# LANGUAGE DataKinds #-}+--+-- data A = A0 | A1 | A2 | A3 deriving (Enum,CEnum)+--+-- data B = B0 | B1 deriving (Enum,BitOffset)+--+-- w :: BitFields Word16 '[ BitField 5 "X" (EnumField Word8 A)+--                        , BitField 9 "Y" Word16+--                        , BitField 2 "Z" (BitSet Word8 B)+--                        ]+-- w = BitFields 0x0102+-- @+--+module Haskus.Binary.BitField+   ( BitFields (..)+   , bitFieldsBits+   , BitField (..)+   , extractField+   , extractField'+   , updateField+   , updateField'+   , withField+   , withField'+   , matchFields+   , matchNamedFields+   , Field+   )+where++import Haskus.Binary.BitSet as BitSet+import Haskus.Binary.Enum+import Haskus.Number.Word+import Haskus.Number.Int+import Haskus.Binary.Bits+import Haskus.Binary.Storable+import Haskus.Utils.HList+import Haskus.Utils.Types+import Haskus.Utils.Tuple++-- | Bit fields on a base type b+newtype BitFields b (f :: [*]) = BitFields b deriving (Storable)++-- | Get backing word+bitFieldsBits :: BitFields b f -> b+{-# INLINABLE bitFieldsBits #-}+bitFieldsBits (BitFields b) = b+++-- | A field of n bits+newtype BitField (n :: Nat) (name :: Symbol) s = BitField s deriving (Storable)++-- | Get the bit offset of a field from its name+type family Offset (name :: Symbol) fs :: Nat where+   Offset name (BitField n name  s ': xs) = AddOffset xs+   Offset name (BitField n name2 s ': xs) = Offset name xs++type family AddOffset fs :: Nat where+   AddOffset '[]                        = 0+   AddOffset (BitField n name s ': xs)  = n + AddOffset xs++-- | Get the type of a field from its name+type family Output (name :: Symbol) fs :: * where+   Output name (BitField n name  s ': xs) = s+   Output name (BitField n name2 s ': xs) = Output name xs++-- | Get the size of a field from it name+type family Size (name :: Symbol) fs :: Nat where+   Size name (BitField n name  s ': xs) = n+   Size name (BitField n name2 s ': xs) = Size name xs++-- | Get the whole size of a BitFields+type family WholeSize fs :: Nat where+   WholeSize '[]                        = 0+   WholeSize (BitField n name s ': xs)  = n + WholeSize xs++type family BitFieldTypes xs where+   BitFieldTypes '[]                       = '[]+   BitFieldTypes (BitField n name s ': xs) = s ': BitFieldTypes xs++class Field f where+   fromField :: Integral b => f -> b+   toField   :: Integral b => b -> f++instance Field Bool where+   fromField True  = 1+   fromField False = 0+   toField 0  = False+   toField _  = True++instance Field Word where+   fromField = fromIntegral+   toField   = fromIntegral++instance Field Word8 where+   fromField = fromIntegral+   toField   = fromIntegral++instance Field Word16 where+   fromField = fromIntegral+   toField   = fromIntegral++instance Field Word32 where+   fromField = fromIntegral+   toField   = fromIntegral++instance Field Word64 where+   fromField = fromIntegral+   toField   = fromIntegral++instance Field Int where+   fromField = fromIntegral+   toField   = fromIntegral++instance Field Int8 where+   fromField = fromIntegral+   toField   = fromIntegral++instance Field Int16 where+   fromField = fromIntegral+   toField   = fromIntegral++instance Field Int32 where+   fromField = fromIntegral+   toField   = fromIntegral++instance Field Int64 where+   fromField = fromIntegral+   toField   = fromIntegral++instance (FiniteBits b, Integral b, BitOffset a) => Field (BitSet b a) where+   fromField = fromIntegral . BitSet.toBits+   toField   = BitSet.fromBits . fromIntegral++instance (Integral b, CEnum a) => Field (EnumField b a) where+   fromField = fromCEnum . fromEnumField+   toField   = toEnumField . toCEnum++-- | Get the value of a field+extractField :: forall (name :: Symbol) fields b .+   ( KnownNat (Offset name fields)+   , KnownNat (Size name fields)+   , WholeSize fields ~ BitSize b+   , Bits b, Integral b+   , Field (Output name fields)+   ) => BitFields b fields -> Output name fields+{-# INLINABLE extractField #-}+extractField = extractField' @name++-- | Get the value of a field (without checking sizes)+extractField' :: forall (name :: Symbol) fields b .+   ( KnownNat (Offset name fields)+   , KnownNat (Size name fields)+   , Bits b, Integral b+   , Field (Output name fields)+   ) => BitFields b fields -> Output name fields+{-# INLINABLE extractField' #-}+extractField' (BitFields w) = toField ((w `shiftR` off) .&. ((1 `shiftL` sz) - 1))+   where+      off = natValue @(Offset name fields)+      sz  = natValue @(Size name fields)+++-- | Set the value of a field+updateField :: forall name fields b .+   ( KnownNat (Offset name fields)+   , KnownNat (Size name fields)+   , WholeSize fields ~ BitSize b+   , Bits b, Integral b+   , Field (Output name fields)+   ) => Output name fields -> BitFields b fields -> BitFields b fields+{-# INLINABLE updateField #-}+updateField = updateField' @name++-- | Set the value of a field (without checking sizes)+updateField' :: forall name fields b .+   ( KnownNat (Offset name fields)+   , KnownNat (Size name fields)+   , Bits b, Integral b+   , Field (Output name fields)+   ) => Output name fields -> BitFields b fields -> BitFields b fields+{-# INLINABLE updateField' #-}+updateField' value (BitFields w) = BitFields $ ((fromField value `shiftL` off) .&. mask') .|. (w .&. complement mask')+   where+      off   = natValue @(Offset name fields)+      sz    = natValue @(Size name fields)+      mask' = ((1 `shiftL` sz) - 1) `shiftL` off+++-- | Modify the value of a field+withField :: forall name fields b f .+   ( KnownNat (Offset name fields)+   , KnownNat (Size name fields)+   , WholeSize fields ~ BitSize b+   , Bits b, Integral b+   , f ~ Output name fields+   , Field f+   ) => (f -> f) -> BitFields b fields -> BitFields b fields+{-# INLINABLE withField #-}+withField = withField' @name++-- | Modify the value of a field (without checking sizes)+withField' :: forall (name :: Symbol) fields b f .+   ( KnownNat (Offset name fields)+   , KnownNat (Size name fields)+   , Bits b, Integral b+   , f ~ Output name fields+   , Field f+   ) => (f -> f) -> BitFields b fields -> BitFields b fields+{-# INLINABLE withField' #-}+withField' f bs = updateField' @name (f v) bs+   where+      v = extractField' @name bs+++-------------------------------------------------------------------------------------+-- We use HFoldr' to extract each component and create a HList from it. Then we+-- convert it into a Tuple+-------------------------------------------------------------------------------------+data Extract = Extract+data Name    = Name++instance forall name bs b l l2 i (n :: Nat) s r w .+   ( bs ~ BitFields w l                    -- the bitfields+   , b ~ BitField n name s                 -- the current field+   , i ~ (bs, HList l2)                    -- input type+   , r ~ (bs, HList (Output name l ': l2)) -- result type+   , BitSize w ~ WholeSize l+   , Integral w, Bits w+   , KnownNat (Offset name l)+   , KnownNat (Size name l)+   , Field (Output name l)+   ) => Apply Extract (b, i) r where+      apply _ (_, (bs,xs)) =+         (bs, HCons (extractField @name bs) xs)++instance forall name bs b l l2 i (n :: Nat) s r w .+   ( bs ~ BitFields w l       -- the bitfields+   , b ~ BitField n name s    -- the current field+   , i ~ HList l2             -- input type+   , r ~ HList (String ': l2) -- result type+   , KnownSymbol name+   ) => Apply Name (b, i) r where+      apply _ (_, xs) = HCons (symbolValue @name) xs++fieldValues :: forall l l2 w bs .+   ( bs ~ BitFields w l+   , HFoldr' Extract (bs, HList '[]) l (bs, HList l2)+   ) => bs -> HList l2+fieldValues bs = snd res+   where+      res :: (bs, HList l2)+      res = hFoldr' Extract ((bs, HNil) :: (bs, HList '[])) (undefined :: HList l)++fieldNames :: forall l l2 w bs .+   ( bs ~ BitFields w l+   , HFoldr' Name (HList '[]) l (HList l2)+   ) => bs -> HList l2+fieldNames _ = hFoldr' Name (HNil :: HList '[]) (undefined :: HList l)++-- | Get values in a tuple+matchFields :: forall l l2 w bs t .+   ( bs ~ BitFields w l+   , HFoldr' Extract (bs, HList '[]) l (bs, HList l2)+   , HTuple l2+   , t ~ Tuple l2+   ) => bs -> t+matchFields = hToTuple @l2 . fieldValues+++-- | Get field names and values in a tuple+matchNamedFields ::forall lt lv ln lnv w bs t .+   ( bs ~ BitFields w lt+   , HFoldr' Extract (bs, HList '[]) lt (bs, HList lv)+   , HFoldr' Name (HList '[]) lt (HList ln)+   , HZipList ln lv lnv+   , HTuple lnv+   , t ~ Tuple lnv+   ) => bs -> t+matchNamedFields = hToTuple @lnv . matchNamedFields'++-- | Get field names and values in a tuple+matchNamedFields' ::forall lt lv ln lnv w bs .+   ( bs ~ BitFields w lt+   , HFoldr' Extract (bs, HList '[]) lt (bs, HList lv)+   , HFoldr' Name (HList '[]) lt (HList ln)+   , HZipList ln lv lnv+   ) => bs -> HList lnv+matchNamedFields' bs = hZipList names values+   where+      names  = fieldNames bs+      values = fieldValues bs++-- | Get field names and values in a tuple+instance forall lt ln lnv w bs.+   ( bs ~ BitFields w lt+   , ln ~ Replicate (Length lt) String+   , HFoldr' Extract (bs, HList '[]) lt (bs, HList (BitFieldTypes lt))+   , HFoldr' Name (HList '[]) lt (HList ln)+   , HZipList ln (BitFieldTypes lt) lnv+   , Show (HList lnv)+   ) => Show (BitFields w lt) where+      show bs = show (matchNamedFields' bs :: HList lnv)+++instance forall lt lt2 w bs.+   ( bs ~ BitFields w lt+   , HFoldr' Extract (bs, HList '[]) lt (bs, HList lt2)+   , Eq (HList lt2)+   , lt2 ~ BitFieldTypes lt+   ) => Eq (BitFields w lt) where+   (==) x y = x' == y'+      where+         x' :: HList lt2+         x' = fieldValues x+         y' :: HList lt2+         y' = fieldValues y
+ src/lib/Haskus/Binary/BitSet.hs view
@@ -0,0 +1,296 @@+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE DefaultSignatures #-}+{-# LANGUAGE FlexibleContexts #-}++-- | A bit set based on Enum to name the bits. Use bitwise operations and+-- minimal storage in a safer way.+--+-- Similar to Data.Bitset.Generic from bitset package, but+--+--     * We don't have the Num constraint+--     * We dont use the deprecated bitSize function+--     * We use countTrailingZeros instead of iterating on the+--     number of bits+--     * We add a typeclass BitOffset+--+-- Example:+--+-- @+-- {-# LANGUAGE DeriveAnyClass #-}+-- data Flag+--    = FlagXXX+--    | FlagYYY+--    | FlagWWW+--    deriving (Show,Eq,Enum,BitOffset)+--+-- -- Adapt the backing type, here we choose Word16+-- type Flags = 'BitSet' Word16 Flag+-- @+--+-- Then you can convert (for free) a Word16 into Flags with 'fromBits' and+-- convert back with 'toBits'.+--+-- You can check if a flag is set or not with 'member' and 'notMember' and get+-- a list of set flags with 'toList'. You can 'insert' or 'delete' flags. You+-- can also perform set operations such as 'union' and 'intersection'.+--+module Haskus.Binary.BitSet+   ( BitSet+   , BitOffset (..)+   , null+   , empty+   , singleton+   , insert+   , delete+   , toBits+   , fromBits+   , member+   , elem+   , notMember+   , elems+   , intersection+   , union+   , unions+   , fromListToBits+   , toListFromBits+   , enumerateSetBits+   , fromList+   , toList+   )+where++import Prelude hiding (null,elem)++import qualified GHC.Exts as Ext++import Data.Foldable (foldl')++import Haskus.Binary.Bits+import Haskus.Binary.Storable++-- | A bit set: use bitwise operations (fast!) and minimal storage (sizeOf+-- basetype)+--+-- * b is the base type (Bits b)+-- * a is the element type (Enum a)+--+-- The elements in the Enum a are flags corresponding to each bit of b starting+-- from the least-significant bit.+newtype BitSet b a = BitSet b deriving (Eq,Ord,Storable)++instance+   ( Show a+   , BitOffset a+   , FiniteBits b+   , IndexableBits b+   , Eq b+   ) => Show (BitSet b a)+   where+      show b = "fromList " ++ show (toList b)++-- | Indicate if the set is empty+null ::+   ( FiniteBits b+   , Eq b+   ) => BitSet b a -> Bool+{-# INLINABLE null #-}+null (BitSet b) = b == zeroBits+++-- | Empty bitset+empty :: (FiniteBits b) => BitSet b a+{-# INLINABLE empty #-}+empty = BitSet zeroBits+++-- | Create a BitSet from a single element+singleton :: (IndexableBits b, BitOffset a) => a -> BitSet b a+{-# INLINABLE singleton #-}+singleton e = BitSet $ bit (toBitOffset e)+++-- | Insert an element in the set+insert :: (IndexableBits b, BitOffset a) => BitSet b a -> a -> BitSet b a+{-# INLINABLE insert #-}+insert (BitSet b) e = BitSet $ setBit b (toBitOffset e)+++-- | Remove an element from the set+delete :: (IndexableBits b, BitOffset a) => BitSet b a -> a -> BitSet b a+{-# INLINABLE delete #-}+delete (BitSet b) e = BitSet $ clearBit b (toBitOffset e)+++-- | Unwrap the bitset+toBits :: BitSet b a -> b+toBits (BitSet b) = b++-- | Wrap a bitset+fromBits :: (BitOffset a, FiniteBits b) => b -> BitSet b a+fromBits = BitSet++-- | Test if an element is in the set+member ::+   ( BitOffset a+   , FiniteBits b+   , IndexableBits b+   ) => BitSet b a -> a -> Bool+{-# INLINABLE member #-}+member (BitSet b) e = testBit b (toBitOffset e)+++-- | Test if an element is in the set+elem ::+   ( BitOffset a+   , FiniteBits b+   , IndexableBits b+   ) => a -> BitSet b a -> Bool+{-# INLINABLE elem #-}+elem e (BitSet b) = testBit b (toBitOffset e)+++-- | Test if an element is not in the set+notMember ::+   ( BitOffset a+   , FiniteBits b+   , IndexableBits b+   ) => BitSet b a -> a -> Bool+{-# INLINABLE notMember #-}+notMember b e = not (member b e)+++-- | Retrieve elements in the set+elems ::+   ( BitOffset a+   , FiniteBits b+   , IndexableBits b+   , Eq b+   ) => BitSet b a -> [a]+elems (BitSet b) = go b+   where+      go !c+         | c == zeroBits = []+         | otherwise     = let e = countTrailingZeros c in fromBitOffset e : go (clearBit c e)++-- | Intersection of two sets+intersection ::+   ( FiniteBits b+   , Bitwise b+   ) => BitSet b a -> BitSet b a -> BitSet b a+{-# INLINABLE intersection #-}+intersection (BitSet b1) (BitSet b2) = BitSet (b1 .&. b2)+++-- | Intersection of two sets+union ::+   ( FiniteBits b+   , Bitwise b+   ) => BitSet b a -> BitSet b a -> BitSet b a+{-# INLINABLE union #-}+union (BitSet b1) (BitSet b2) = BitSet (b1 .|. b2)+++-- | Intersection of several sets+unions ::+   ( FiniteBits b+   , Bitwise b+   ) => [BitSet b a] -> BitSet b a+{-# INLINABLE unions #-}+unions = foldl' union empty+++-- | Bit set indexed with a+class BitOffset a where+   -- | Return the bit offset of an element+   toBitOffset         :: a -> Word+   default toBitOffset :: Enum a => a -> Word+   toBitOffset         = fromIntegral . fromEnum++   -- | Return the value associated with a bit offset+   fromBitOffset         :: Word -> a+   default fromBitOffset :: Enum a => Word -> a+   fromBitOffset         = toEnum . fromIntegral++-- | It can be useful to get the indexes of the set bits+instance BitOffset Int where+   toBitOffset   = fromIntegral+   fromBitOffset = fromIntegral++-- | It can be useful to get the indexes of the set bits+instance BitOffset Word where+   toBitOffset   = id+   fromBitOffset = id+   +++-- | Convert a list of enum elements into a bitset Warning: b+-- must have enough bits to store the given elements! (we don't+-- perform any check, for performance reason)+fromListToBits ::+   ( BitOffset a+   , FiniteBits b+   , IndexableBits b+   , Foldable m+   ) => m a -> b+fromListToBits = toBits . fromList++-- | Convert a bitset into a list of Enum elements+toListFromBits ::+   ( BitOffset a+   , FiniteBits b+   , IndexableBits b+   , Eq b+   ) => b -> [a]+toListFromBits = toList . BitSet++-- | Convert a bitset into a list of Enum elements by testing the Enum values+-- successively.+--+-- The difference with `toListFromBits` is that extra values in the BitSet will+-- be ignored.+enumerateSetBits ::+   ( BitOffset a+   , FiniteBits b+   , IndexableBits b+   , Eq b+   , Bounded a+   , Enum a+   ) => b -> [a]+enumerateSetBits b = go [] [minBound..]+   where+      go rs []     = rs+      go rs (x:xs)+         | member (BitSet b) x = go (x:rs) xs+         | otherwise           = go rs xs++-- | Convert a set into a list+toList ::+   ( BitOffset a+   , FiniteBits b+   , IndexableBits b+   , Eq b+   ) => BitSet b a -> [a]+toList = elems++-- | Convert a Foldable into a set+fromList ::+   ( BitOffset a+   , IndexableBits b+   , FiniteBits b+   , Foldable m+   ) => m a -> BitSet b a+fromList = foldl' insert (BitSet zeroBits)+++instance+   ( FiniteBits b+   , IndexableBits b+   , BitOffset a+   , Eq b+   ) => Ext.IsList (BitSet b a)+   where+      type Item (BitSet b a) = a+      fromList = fromList+      toList   = toList
+ src/lib/Haskus/Binary/Bits.hs view
@@ -0,0 +1,161 @@+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE DataKinds #-}++-- | Operations on bits+module Haskus.Binary.Bits+   ( Bits+   , FiniteBits (..)+   , IndexableBits (..)+   , ShiftableBits (..)+   , SignedShiftableBits (..)+   , RotatableBits (..)+   , Bitwise (..)+   -- * Bit reversal+   , ReversableBits (..)+   , reverseBitsGeneric+   , reverseLeastBits+   -- * Mask+   , MaskBits (..)+   , Maskable+   , maskDyn+   , mask+   -- * String conversion+   , bitsToString+   , bitsToStringN+   , bitsFromString+   -- * Shift+   , getBitRange+   -- * Various+   , bitOffset+   , byteOffset+   , isPowerOfTwo+   , isPowerOfFour+   , getPowerOfTwo+   , getPowerOfFour+   )+where++import Haskus.Utils.List (foldl')+import Haskus.Utils.Types+import Haskus.Utils.Maybe+import Haskus.Binary.Bits.Finite+import Haskus.Binary.Bits.Index+import Haskus.Binary.Bits.Reverse+import Haskus.Binary.Bits.Rotate+import Haskus.Binary.Bits.Shift+import Haskus.Binary.Bits.Bitwise+import Haskus.Binary.Bits.Order+import Haskus.Binary.Bits.Mask+import Haskus.Binary.Bits.Helper++type Bits a =+   ( Eq a+   , FiniteBits a+   , IndexableBits a+   , ShiftableBits a+   , Bitwise a+   , RotatableBits a+   , KnownNat (BitSize a)+   , MaskBits a+   )++-- | Check if a number is a power of two (2^n)+--+-- >>> isPowerOfTwo (10 :: Word)+-- False+-- >>> isPowerOfTwo (16 :: Word)+-- True+isPowerOfTwo :: IndexableBits a => a -> Bool+isPowerOfTwo x = popCount x == 1++-- | Check if a number is a power of two (2^n) and return `n`+--+-- >>> getPowerOfTwo (10 :: Word)+-- Nothing+-- >>> getPowerOfTwo (16 :: Word)+-- Just 4+getPowerOfTwo :: (IndexableBits a, FiniteBits a) => a -> Maybe Word+getPowerOfTwo x+   | isPowerOfTwo x = Just (countTrailingZeros x)+   | otherwise      = Nothing++-- | Check if a number is a power of four (4^n)+--+-- >>> isPowerOfFour (10 :: Word)+-- False+-- >>> isPowerOfFour (16 :: Word)+-- True+isPowerOfFour :: (IndexableBits a, FiniteBits a) => a -> Bool+isPowerOfFour x = isJust (getPowerOfFour x)++-- | Check if a number is a power of four (4^n) and return `n`+--+-- >>> getPowerOfFour (10 :: Word)+-- Nothing+-- >>> getPowerOfFour (16 :: Word)+-- Just 2+getPowerOfFour :: (IndexableBits a, FiniteBits a) => a -> Maybe Word+getPowerOfFour x+   | popCount x == 1                -- test that a single bit is set to 1+   , let c = countTrailingZeros x   -- and that it is followed by an even+   , testBit c 0 == False           -- number of zeros+   = Just (c `shiftR` 1)+   | otherwise       = Nothing++-- | Reverse the @n@ least important bits of the given value. The higher bits+-- are set to 0.+reverseLeastBits ::+   ( ShiftableBits a+   , FiniteBits a+   , ReversableBits a+   , KnownNat (BitSize a)+   ) => Word -> a -> a+reverseLeastBits n value = reverseBits value `uncheckedShiftR` ((bitSize value) - n)++-- | Convert bits into a string composed of '0' and '1' chars+bitsToString :: forall a.+   ( FiniteBits a+   , IndexableBits a+   , KnownNat (BitSize a)+   ) => a -> String+bitsToString = bitsToStringN (natValue @(BitSize a))++-- | Convert a specified amount of bits into a string composed of '0' and '1' chars+bitsToStringN :: forall a.+   ( IndexableBits a+   ) => Word -> a -> String+bitsToStringN n x = fmap b [n-1, n-2 .. 0]+   where+      b v = if testBit x v then '1' else '0'++-- | Convert a string of '0' and '1' chars into a word+bitsFromString :: Bits a => String -> a+bitsFromString xs = foldl' b zeroBits (reverse xs `zip` [0..])+   where+      b x ('0',i) = clearBit x i+      b x ('1',i) = setBit x i+      b _ (c,_)   = error $ "Invalid character in the string: " ++ [c]+++-- | `getBitRange bo offset n c` takes n bits at offset in c and put them in the+-- least-significant bits of the result+getBitRange :: forall b.+   ( ShiftableBits b+   , ReversableBits b+   , FiniteBits b+   , KnownNat (BitSize b)+   , Bitwise b+   , MaskBits b+   ) => BitOrder -> Word -> Word -> b -> b+{-# INLINABLE getBitRange #-}+getBitRange bo o n c = case bo of+      BB -> maskDyn n $ c             `uncheckedShiftR` d+      BL -> maskDyn n $ reverseBits c `uncheckedShiftR` o+      LB -> maskDyn n $ reverseBits c `uncheckedShiftR` d+      LL -> maskDyn n $ c             `uncheckedShiftR` o+   where +      d  = bitSize c - n - o+
+ src/lib/Haskus/Binary/Bits/Bitwise.hs view
@@ -0,0 +1,85 @@+{-# LANGUAGE MagicHash #-}+{-# LANGUAGE BangPatterns #-}++-- | Bitwise bit operations+module Haskus.Binary.Bits.Bitwise+   ( Bitwise (..)+   )+where++import Haskus.Number.Word+import Haskus.Number.Int+import GHC.Exts+import GHC.Num++-- | Bitwise bit operations+class Bitwise a where+   -- | Bitwise "and"+   (.&.) :: a -> a -> a++   -- | Bitwise "or"+   (.|.) :: a -> a -> a++   -- | Bitwise "xor"+   xor :: a -> a -> a+++instance Bitwise Word where+   (W# x#) .&.   (W# y#) = W# (x# `and#` y#)+   (W# x#) .|.   (W# y#) = W# (x# `or#` y#)+   (W# x#) `xor` (W# y#) = W# (x# `xor#` y#)++instance Bitwise Word8 where+   (W8# x#) .&.   (W8# y#) = W8# (x# `and#` y#)+   (W8# x#) .|.   (W8# y#) = W8# (x# `or#` y#)+   (W8# x#) `xor` (W8# y#) = W8# (x# `xor#` y#)++instance Bitwise Word16 where+   (W16# x#) .&.   (W16# y#) = W16# (x# `and#` y#)+   (W16# x#) .|.   (W16# y#) = W16# (x# `or#` y#)+   (W16# x#) `xor` (W16# y#) = W16# (x# `xor#` y#)++instance Bitwise Word32 where+   (W32# x#) .&.   (W32# y#) = W32# (x# `and#` y#)+   (W32# x#) .|.   (W32# y#) = W32# (x# `or#` y#)+   (W32# x#) `xor` (W32# y#) = W32# (x# `xor#` y#)++instance Bitwise Word64 where+   (W64# x#) .&.   (W64# y#) = W64# (x# `and#` y#)+   (W64# x#) .|.   (W64# y#) = W64# (x# `or#` y#)+   (W64# x#) `xor` (W64# y#) = W64# (x# `xor#` y#)++instance Bitwise Int where+   (I# x#) .&.   (I# y#) = I# (x# `andI#` y#)+   (I# x#) .|.   (I# y#) = I# (x# `orI#` y#)+   (I# x#) `xor` (I# y#) = I# (x# `xorI#` y#)++instance Bitwise Int8 where+   (I8# x#) .&.   (I8# y#) = I8# (word2Int# (int2Word# x# `and#` int2Word# y#))+   (I8# x#) .|.   (I8# y#) = I8# (word2Int# (int2Word# x# `or#`  int2Word# y#))+   (I8# x#) `xor` (I8# y#) = I8# (word2Int# (int2Word# x# `xor#` int2Word# y#))++instance Bitwise Int16 where+   (I16# x#) .&.   (I16# y#) = I16# (word2Int# (int2Word# x# `and#` int2Word# y#))+   (I16# x#) .|.   (I16# y#) = I16# (word2Int# (int2Word# x# `or#`  int2Word# y#))+   (I16# x#) `xor` (I16# y#) = I16# (word2Int# (int2Word# x# `xor#` int2Word# y#))++instance Bitwise Int32 where+   (I32# x#) .&.   (I32# y#) = I32# (word2Int# (int2Word# x# `and#` int2Word# y#))+   (I32# x#) .|.   (I32# y#) = I32# (word2Int# (int2Word# x# `or#`  int2Word# y#))+   (I32# x#) `xor` (I32# y#) = I32# (word2Int# (int2Word# x# `xor#` int2Word# y#))++instance Bitwise Int64 where+   (I64# x#) .&.   (I64# y#) = I64# (word2Int# (int2Word# x# `and#` int2Word# y#))+   (I64# x#) .|.   (I64# y#) = I64# (word2Int# (int2Word# x# `or#`  int2Word# y#))+   (I64# x#) `xor` (I64# y#) = I64# (word2Int# (int2Word# x# `xor#` int2Word# y#))++instance Bitwise Integer where+   (.&.)      = andInteger+   (.|.)      = orInteger+   xor        = xorInteger++instance Bitwise Natural where+   (.&.)      = andNatural+   (.|.)      = orNatural+   xor        = xorNatural
+ src/lib/Haskus/Binary/Bits/Finite.hs view
@@ -0,0 +1,136 @@+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE ConstrainedClassMethods #-}+{-# LANGUAGE MagicHash #-}+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE CPP #-}+{-# LANGUAGE DefaultSignatures #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE ScopedTypeVariables #-}++-- | Types with finite bit count+module Haskus.Binary.Bits.Finite+   ( FiniteBits (..)+   )+where++import Haskus.Utils.Types+import Haskus.Number.Word+import Haskus.Number.Int+import GHC.Exts++#include "MachDeps.h"++-- | Type representable by a fixed amount of bits+class FiniteBits a where++   -- | Number of bits+   type BitSize a :: Nat++   -- | Number of bits (the value is ignored)+   bitSize :: (Integral i, KnownNat (BitSize a)) => a -> i+   bitSize _ = natValue @(BitSize a)+   +   -- | All bits set to 0+   zeroBits :: a++   -- | All bits set to 1+   oneBits :: a+   oneBits = complement zeroBits++   -- | Count number of zero bits preceding the most significant set bit+   countLeadingZeros :: a -> Word++   -- | Count number of zero bits following the least significant set bit+   countTrailingZeros :: a -> Word++   -- | Complement+   complement :: a -> a+++instance FiniteBits Word where+   type BitSize Word          = WORD_SIZE_IN_BITS+   zeroBits                   = 0+   oneBits                    = maxBound+   countLeadingZeros  (W# x#) = W# (clz# x#)+   countTrailingZeros (W# x#) = W# (ctz# x#)+   complement (W# x#)         = W# (x# `xor#` mb#)+      where !(W# mb#) = maxBound++instance FiniteBits Word8 where+   type BitSize Word8          = 8+   zeroBits                    = 0+   oneBits                     = maxBound+   countLeadingZeros  (W8# x#) = W# (clz8# x#)+   countTrailingZeros (W8# x#) = W# (ctz8# x#)+   complement (W8# x#)         = W8# (x# `xor#` mb#)+      where !(W8# mb#) = maxBound++instance FiniteBits Word16 where+   type BitSize Word16          = 16+   zeroBits                     = 0+   oneBits                      = maxBound+   countLeadingZeros  (W16# x#) = W# (clz16# x#)+   countTrailingZeros (W16# x#) = W# (ctz16# x#)+   complement (W16# x#)         = W16# (x# `xor#` mb#)+      where !(W16# mb#) = maxBound++instance FiniteBits Word32 where+   type BitSize Word32          = 32+   zeroBits                     = 0+   oneBits                      = maxBound+   countLeadingZeros  (W32# x#) = W# (clz32# x#)+   countTrailingZeros (W32# x#) = W# (ctz32# x#)+   complement (W32# x#)         = W32# (x# `xor#` mb#)+      where !(W32# mb#) = maxBound++instance FiniteBits Word64 where+   type BitSize Word64          = 64+   zeroBits                     = 0+   oneBits                      = maxBound+   countLeadingZeros  (W64# x#) = W# (clz64# x#)+   countTrailingZeros (W64# x#) = W# (ctz64# x#)+   complement (W64# x#)         = W64# (x# `xor#` mb#)+      where !(W64# mb#) = maxBound+++instance FiniteBits Int where+   type BitSize Int           = WORD_SIZE_IN_BITS+   zeroBits                   = 0+   oneBits                    = (-1)+   countLeadingZeros  (I# x#) = W# (clz# (int2Word# x#))+   countTrailingZeros (I# x#) = W# (ctz# (int2Word# x#))+   complement (I# x#)         = I# (notI# x#)++instance FiniteBits Int8 where+   type BitSize Int8           = 8+   zeroBits                    = 0+   oneBits                     = (-1)+   countLeadingZeros  (I8# x#) = W# (clz8# (int2Word# x#))+   countTrailingZeros (I8# x#) = W# (ctz8# (int2Word# x#))+   complement (I8# x#)         = I8# (word2Int# (not# (int2Word# x#)))++instance FiniteBits Int16 where+   type BitSize Int16           = 16+   zeroBits                     = 0+   oneBits                      = (-1)+   countLeadingZeros  (I16# x#) = W# (clz16# (int2Word# x#))+   countTrailingZeros (I16# x#) = W# (ctz16# (int2Word# x#))+   complement (I16# x#)         = I16# (word2Int# (not# (int2Word# x#)))++instance FiniteBits Int32 where+   type BitSize Int32           = 32+   zeroBits                     = 0+   oneBits                      = (-1)+   countLeadingZeros  (I32# x#) = W# (clz32# (int2Word# x#))+   countTrailingZeros (I32# x#) = W# (ctz32# (int2Word# x#))+   complement (I32# x#)         = I32# (word2Int# (not# (int2Word# x#)))++instance FiniteBits Int64 where+   type BitSize Int64           = 64+   zeroBits                     = 0+   oneBits                      = (-1)+   countLeadingZeros  (I64# x#) = W# (clz64# (int2Word# x#))+   countTrailingZeros (I64# x#) = W# (ctz64# (int2Word# x#))+   complement (I64# x#)         = I64# (word2Int# (int2Word# x# `xor#` int2Word# (-1#)))
+ src/lib/Haskus/Binary/Bits/Get.hs view
@@ -0,0 +1,237 @@+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE FlexibleContexts #-}++-- | Bit getter+module Haskus.Binary.Bits.Get+   ( BitGetState(..)+   , newBitGetState+   , isEmpty+   , skipBits+   , skipBitsToAlignOnWord8+   , getBits+   , getBitsChecked+   , getBitsBuffer+   -- * Monadic+   , BitGet+   , BitGetT+   , runBitGet+   , runBitGetT+   , runBitGetPartialT+   , runBitGetPartial+   , resumeBitGetPartialT+   , resumeBitGetPartial+   , isEmptyM+   , skipBitsM+   , skipBitsToAlignOnWord8M+   , getBitsM+   , getBitsCheckedM+   , getBitBoolM+   , getBitsBSM+   , changeBitGetOrder+   , withBitGetOrder+   )+where++import System.IO.Unsafe (unsafePerformIO)+import Control.Monad.State+import Control.Monad.Identity+import Foreign.Marshal.Alloc (mallocBytes)+import Foreign.Ptr++import Haskus.Binary.Buffer+import Haskus.Binary.Bits.Order+import Haskus.Binary.Bits+import Haskus.Binary.Storable (poke)++-- | BitGet state+data BitGetState = BitGetState+   { bitGetStateInput      :: {-# UNPACK #-} !Buffer     -- ^ Input+   , bitGetStateBitOffset  :: {-# UNPACK #-} !Word       -- ^ Bit offset (0-7)+   , bitGetStateBitOrder   ::                !BitOrder   -- ^ Bit order+   } deriving (Show)++-- | Create a new BitGetState+newBitGetState :: BitOrder -> Buffer -> BitGetState+newBitGetState bo bs = BitGetState bs 0 bo++-- | Indicate that the source is empty+isEmpty :: BitGetState -> Bool+isEmpty (BitGetState bs o _) = o == 0 && isBufferEmpty bs++-- | Skip the given number of bits from the input+skipBits :: Word -> BitGetState -> BitGetState+skipBits o (BitGetState bs n bo) = BitGetState (bufferUnsafeDrop d bs) n' bo+   where+      !o' = n+o+      !d  = fromIntegral $ byteOffset o'+      !n' = bitOffset o'++-- | Skip the required number of bits to be aligned on 8-bits+skipBitsToAlignOnWord8 :: BitGetState -> BitGetState+skipBitsToAlignOnWord8 s = case bitGetStateBitOffset s of+   0 -> s+   n -> skipBits (8-n) s++-- | Read the given number of bits and put the result in a word+getBits :: (Integral a, Bits a) => Word -> BitGetState -> a+getBits nbits (BitGetState bs off bo) = rec zeroBits 0 bs off nbits+   where+      -- w   = current result+      -- n   = number of valid bits in w+      -- i   = input bytestring+      -- o   = bit offset in input bytestring+      -- r   = number of remaining bits to read+      rec w _ _ _ 0 = w+      rec w n i o r = rec nw (n+nb) (bufferTail i) o' (r-nb)+         where +            -- current Word8+            c  = bufferHead i+            -- number of bits to take from the current Word8+            nb = min (8-o) r+            -- bits taken from the current Word8 and put in correct order in least-significant bits+            tc = fromIntegral $ getBitRange bo o nb c+            -- mix new bits with the current result+            nw = case bo of+                  BB -> (w `shiftL` fromIntegral nb) .|. tc+                  LB -> (w `shiftL` fromIntegral nb) .|. tc+                  BL -> (tc `shiftL` fromIntegral n) .|. w+                  LL -> (tc `shiftL` fromIntegral n) .|. w+            -- new offset ((o + nb) `mod` 8)+            o' = bitOffset (o + nb)++-- | Perform some checks before calling getBits+--+-- Check that the number of bits to read is not greater than the first parameter+getBitsChecked :: (Integral a, Bits a, ReversableBits a) => Word -> Word -> BitGetState -> a+{-# INLINABLE getBitsChecked #-}+getBitsChecked m n s+   | n > m     = error $ "Tried to read more than " ++ show m ++ " bits (" ++ show n ++")"+   | otherwise = getBits n s++-- | Read the given number of Word8 and return them in a Buffer+--+-- Examples:+-- @  BB: xxxABCDE FGHIJKLM NOPxxxxx -> ABCDEFGH IJKLMNOP @+-- @  LL: LMNOPxxx DEFGHIJK xxxxxABC -> ABCDEFGH IJKLMNOP @+-- @  BL: xxxPONML KJIHGFED CBAxxxxx -> ABCDEFGH IJKLMNOP @+-- @  LB: EDCBAxxx MLKJIHGF xxxxxPON -> ABCDEFGH IJKLMNOP @+getBitsBuffer :: Word -> BitGetState -> Buffer+getBitsBuffer n (BitGetState bs o bo) =+   if n == 0+      then emptyBuffer+      else+         let +            bs'  = bufferUnsafeTake (n+1) bs+            bs'' = bufferUnsafeTake n     bs+            rev  = bufferMap reverseBits+         in case (o,bo) of+            (0,BB) ->                     bs''+            (0,LL) ->       bufferReverse bs''+            (0,LB) -> rev                 bs''+            (0,BL) -> rev $ bufferReverse bs''+            (_,LL) ->                     getBitsBuffer n (BitGetState (bufferReverse bs') (8-o)  BB)+            (_,BL) -> rev . bufferReverse $ getBitsBuffer n (BitGetState bs'               o     BB)+            (_,LB) -> rev . bufferReverse $ getBitsBuffer n (BitGetState bs'               o     LL)+            (_,BB) -> unsafePerformIO $ do+               let len = n+1+               ptr <- mallocBytes (fromIntegral len)+               let f r i = do+                     let+                        w  = bufferUnsafeIndex bs (len-i)+                        w' = (w `shiftL` fromIntegral o) .|. r+                        r' = w `shiftR` (8-fromIntegral o)+                     poke (castPtr ptr `plusPtr` fromIntegral (len-i)) w'+                     return r'+               foldM_ f 0 [1..len]+               bufferUnsafeInit <$> bufferPackPtr len ptr++++-- | BitGet monad transformer+type BitGetT m a = StateT BitGetState m a++-- | BitGet monad+type BitGet a    = BitGetT Identity a++-- | Evaluate a BitGet monad+runBitGetT :: Monad m => BitOrder -> BitGetT m a -> Buffer -> m a+runBitGetT bo m bs = evalStateT m (newBitGetState bo bs)++-- | Evaluate a BitGet monad+runBitGet :: BitOrder -> BitGet a -> Buffer -> a+runBitGet bo m bs = runIdentity (runBitGetT bo m bs)++-- | Evaluate a BitGet monad, return the remaining state+runBitGetPartialT :: BitOrder -> BitGetT m a -> Buffer -> m (a, BitGetState)+runBitGetPartialT bo m bs = runStateT m (newBitGetState bo bs)++-- | Evaluate a BitGet monad, return the remaining state+runBitGetPartial :: BitOrder -> BitGet a -> Buffer -> (a, BitGetState)+runBitGetPartial bo m bs = runIdentity (runBitGetPartialT bo m bs)++-- | Resume a BitGet evaluation+resumeBitGetPartialT :: BitGetT m a -> BitGetState -> m (a, BitGetState)+resumeBitGetPartialT = runStateT ++-- | Resume a BitGet evaluation+resumeBitGetPartial :: BitGet a -> BitGetState -> (a,BitGetState)+resumeBitGetPartial m s = runIdentity (resumeBitGetPartialT m s)++-- | Indicate if all bits have been read+isEmptyM :: Monad m => BitGetT m Bool+isEmptyM = gets isEmpty++-- | Skip the given number of bits from the input (monadic version)+skipBitsM :: Monad m => Word -> BitGetT m ()+skipBitsM = modify . skipBits+++-- | Skip the required number of bits to be aligned on 8-bits (monadic version)+skipBitsToAlignOnWord8M :: Monad m =>  BitGetT m ()+skipBitsToAlignOnWord8M = modify skipBitsToAlignOnWord8++-- | Read the given number of bits and put the result in a word+getBitsM :: (Integral a, Bits a, Monad m) => Word -> BitGetT m a+getBitsM n = do+   v <- gets (getBits n)+   skipBitsM n+   return v++-- | Perform some checks before calling getBitsM+getBitsCheckedM :: (Integral a, Bits a, ReversableBits a, Monad m) => Word -> Word -> BitGetT m a+getBitsCheckedM m n = do+   v <- gets (getBitsChecked m n)+   skipBitsM n+   return v++-- | Get a bit and convert it into a Bool+getBitBoolM :: (Monad m) => BitGetT m Bool+getBitBoolM = do+   v <- getBitsM 1+   return ((v :: Word) == 1)++-- | Get the given number of Word8+getBitsBSM :: (Monad m) => Word -> BitGetT m Buffer+getBitsBSM n = do+   bs <- gets (getBitsBuffer n)+   skipBitsM (8*n)+   return bs++-- | Change the current bit ordering+--+-- Be careful to change the outer bit ordering (B* to L* or the inverse) only+-- on bytes boundaries! Otherwise, you will read the same bits more than once.+changeBitGetOrder :: Monad m => BitOrder -> BitGetT m ()+changeBitGetOrder bo = modify (\s -> s { bitGetStateBitOrder = bo })++-- | Change the bit ordering for the wrapped BitGet+--+-- Be careful, this function uses changeBitGetOrder internally.+withBitGetOrder :: Monad m => BitOrder -> BitGetT m a -> BitGetT m a+withBitGetOrder bo m = do+   bo' <- gets bitGetStateBitOrder+   changeBitGetOrder bo+   v <- m+   changeBitGetOrder bo'+   return v+
+ src/lib/Haskus/Binary/Bits/Helper.hs view
@@ -0,0 +1,21 @@+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE DataKinds #-}++module Haskus.Binary.Bits.Helper+   ( bitOffset+   , byteOffset+   )+where++import Haskus.Binary.Bits.Shift+import Haskus.Binary.Bits.Mask++-- | Compute bit offset (equivalent to x `mod` 8 but faster)+bitOffset :: Word -> Word+{-# INLINABLE bitOffset #-}+bitOffset n = mask @3 n++-- | Compute byte offset (equivalent to x `div` 8 but faster)+byteOffset :: Word -> Word+{-# INLINABLE byteOffset #-}+byteOffset n = n `uncheckedShiftR` 3
+ src/lib/Haskus/Binary/Bits/Index.hs view
@@ -0,0 +1,100 @@+{-# LANGUAGE DefaultSignatures #-}+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE MagicHash #-}++-- | Bit indexable types+module Haskus.Binary.Bits.Index+   ( IndexableBits (..)+   )+where++import Haskus.Binary.Bits.Shift+import Haskus.Binary.Bits.Bitwise+import Haskus.Binary.Bits.Finite+import Haskus.Number.Word+import Haskus.Number.Int++import GHC.Exts+import qualified Data.Bits as BaseBits+import Numeric.Natural++-- | Type whose bits are indexable+class IndexableBits a where+   -- | @bit /i/@ is a value with the @/i/@th bit set and all other bits clear.+   bit :: Word -> a+   default bit :: (Num a, ShiftableBits a) => Word -> a+   bit i = 1 `shiftL` i++   -- | @x \`setBit\` i@ is the same as @x .|. bit i@+   setBit :: a -> Word -> a+   default setBit :: (Bitwise a) => a -> Word -> a+   setBit a i = a .|. bit i++   -- | @x \`clearBit\` i@ is the same as @x .&. complement (bit i)@+   clearBit :: a -> Word -> a+   default clearBit :: (FiniteBits a,Bitwise a) => a -> Word -> a+   clearBit a i = a .&. complement (bit i)++   -- | @x \`complementBit\` i@ is the same as @x \`xor\` bit i@+   complementBit :: a -> Word -> a+   default complementBit :: (Bitwise a) => a -> Word -> a+   complementBit a i = a `xor` bit i++   -- | Return 'True' if the @n@th bit of the argument is 1+   testBit :: a -> Word -> Bool+   default testBit :: (Bitwise a, Num a, Eq a) => a -> Word -> Bool+   testBit a i = (a .&. bit i) /= 0++   -- | Return the number of set bits+   popCount :: a -> Word+   default popCount :: (Bitwise a, Num a, Eq a) => a -> Word+   popCount = go 0+      where+         go !c 0 = c+         go c  w = go (c+1) (w .&. (w-1))+++instance IndexableBits Word where+   popCount (W# x#) = W# (popCnt# x#)++instance IndexableBits Word8 where+   popCount (W8# x#) = W# (popCnt8# x#)++instance IndexableBits Word16 where+   popCount (W16# x#) = W# (popCnt16# x#)++instance IndexableBits Word32 where+   popCount (W32# x#) = W# (popCnt32# x#)++instance IndexableBits Word64 where+   popCount (W64# x#) = W# (popCnt64# x#)++instance IndexableBits Int where+   popCount (I# x#) = W# (popCnt# (int2Word# x#))++instance IndexableBits Int8 where+   popCount (I8# x#) = W# (popCnt8# (int2Word# x#))++instance IndexableBits Int16 where+   popCount (I16# x#) = W# (popCnt16# (int2Word# x#))++instance IndexableBits Int32 where+   popCount (I32# x#) = W# (popCnt32# (int2Word# x#))++instance IndexableBits Int64 where+   popCount (I64# x#) = W# (popCnt64# (int2Word# x#))++instance IndexableBits Integer where+   -- we don't have access to Integer primitive (we would have to conditionally+   -- import integer-gmp or integer-simple like `base` does) so we use Data.Bits+   -- from `base` instead.+   testBit x i  = BaseBits.testBit x (fromIntegral i)+   bit i        = BaseBits.bit (fromIntegral i)+   popCount x   = fromIntegral (BaseBits.popCount x)+   clearBit x i = BaseBits.clearBit x (fromIntegral i)++instance IndexableBits Natural where+   testBit x i  = BaseBits.testBit x (fromIntegral i)+   bit i        = BaseBits.bit (fromIntegral i)+   popCount x   = fromIntegral (BaseBits.popCount x)+   clearBit x i = BaseBits.clearBit x (fromIntegral i)
+ src/lib/Haskus/Binary/Bits/Mask.hs view
@@ -0,0 +1,94 @@+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE ConstraintKinds #-}++module Haskus.Binary.Bits.Mask+   ( MaskBits (..)+   , makeMaskFinite+   , makeMask+   , maskDyn+   , Maskable+   , mask+   )+where++import Haskus.Binary.Bits.Finite+import Haskus.Binary.Bits.Shift+import Haskus.Binary.Bits.Bitwise+import Haskus.Number.Word+import Haskus.Number.Int+import Haskus.Utils.Types+import GHC.Natural++-- | makeMaskFinite 3 = 00000111+makeMaskFinite :: forall a.+   ( ShiftableBits a+   , FiniteBits a+   , KnownNat (BitSize a)+   , Bitwise a+   ) => Word -> a+{-# INLINABLE makeMaskFinite #-}+makeMaskFinite n = complement zeroBits `shiftR` off+   where+      off = natValue' @(BitSize a) - n++{-# SPECIALIZE makeMaskFinite :: Word -> Int #-}+{-# SPECIALIZE makeMaskFinite :: Word -> Int8 #-}+{-# SPECIALIZE makeMaskFinite :: Word -> Int16 #-}+{-# SPECIALIZE makeMaskFinite :: Word -> Int32 #-}+{-# SPECIALIZE makeMaskFinite :: Word -> Int64 #-}+{-# SPECIALIZE makeMaskFinite :: Word -> Word #-}+{-# SPECIALIZE makeMaskFinite :: Word -> Word8 #-}+{-# SPECIALIZE makeMaskFinite :: Word -> Word16 #-}+{-# SPECIALIZE makeMaskFinite :: Word -> Word32 #-}+{-# SPECIALIZE makeMaskFinite :: Word -> Word64 #-}++class MaskBits a where+   -- | Make a mask dynamically+   makeMaskDyn :: Word -> a++instance MaskBits Natural where+   makeMaskDyn n = mkNatural (replicate (fromIntegral q) c ++ [makeMaskFinite r])+      where+         c = complement zeroBits+         (q,r) = n `quotRem` 32++instance MaskBits Word   where makeMaskDyn = makeMaskFinite+instance MaskBits Word8  where makeMaskDyn = makeMaskFinite+instance MaskBits Word16 where makeMaskDyn = makeMaskFinite+instance MaskBits Word32 where makeMaskDyn = makeMaskFinite+instance MaskBits Word64 where makeMaskDyn = makeMaskFinite+instance MaskBits Int    where makeMaskDyn = makeMaskFinite+instance MaskBits Int8   where makeMaskDyn = makeMaskFinite+instance MaskBits Int16  where makeMaskDyn = makeMaskFinite+instance MaskBits Int32  where makeMaskDyn = makeMaskFinite+instance MaskBits Int64  where makeMaskDyn = makeMaskFinite++-- | Make a mask statically+makeMask :: forall n a.+   ( KnownNat n+   , MaskBits a+   ) => a+{-# INLINABLE makeMask #-}+makeMask = makeMaskDyn (natValue' @n)++-- | Keep only the n least-significant bits of the given value+maskDyn ::+   ( MaskBits a+   , Bitwise a+   ) => Word -> a -> a+{-# INLINABLE maskDyn #-}+maskDyn n v = v .&. makeMaskDyn n++-- | Keep only the n least-significant bits of the given value+mask :: forall n a. Maskable n a => a -> a+{-# INLINABLE mask #-}+mask v = v .&. makeMask @n++type Maskable n a =+   ( MaskBits a+   , Bitwise a+   , KnownNat n+   )
+ src/lib/Haskus/Binary/Bits/Order.hs view
@@ -0,0 +1,29 @@+-- | Bit orderings+module Haskus.Binary.Bits.Order+   ( BitOrder(..)+   )+where++-- | Bit order+--+-- The first letter indicates the outer bit ordering, i.e. how bytes are filled:+--  +--  * B?: from left to right (B is for BigEndian)+--  * L?: from right to left (L is for LittleEndian)+--+-- The second letter indicates the inner bit ordering, i.e. how words are stored:+--   +--  * ?B: the most significant bit is stored first (in the outer bit order!)+--  * ?L: the least-significant bit is stored first (in the outer bit order!)+--+-- E.g. two successive words of 5 bits: ABCDE, VWXYZ+-- @ BB: ABCDEVWX YZxxxxxx @  +-- @ BL: EDCBAZYX WVxxxxxx @+-- @ LB: XWVEDCBA xxxxxxZY @+-- @ LL: XYZABCDE xxxxxxVW @+data BitOrder+   = BB+   | LB+   | BL+   | LL+   deriving (Show,Eq)
+ src/lib/Haskus/Binary/Bits/Put.hs view
@@ -0,0 +1,175 @@+{-# LANGUAGE FlexibleContexts #-}++-- | Bit putter+module Haskus.Binary.Bits.Put+   ( BitPutState(..)+   , newBitPutState+   , putBits+   , putBitsBuffer+   , getBitPutBuffer+   , getBitPutBufferList+   -- * Monadic+   , BitPut+   , BitPutT+   , runBitPut+   , runBitPutT+   , putBitsM+   , putBitBoolM+   , putBitsBufferM+   , changeBitPutOrder+   , withBitPutOrder+   )+where++import Control.Monad.State+import Control.Monad.Identity++import Haskus.Binary.BufferBuilder as B+import Haskus.Binary.Buffer+import Haskus.Number.Word+import Haskus.Binary.BufferList (BufferList)+import Haskus.Binary.Bits.Order+import Haskus.Binary.Bits+++-- | BitPut state+data BitPutState = BitPutState+   { bitPutStateBuilder          :: !BufferBuilder -- ^ Builder+   , bitPutStateCurrent          :: !Word8         -- ^ Current byte+   , bitPutStateOffset           :: !Word          -- ^ Current offset+   , bitPutStateBitOrder         :: !BitOrder      -- ^ Bit order+   }++-- | Create a new BitPut state+newBitPutState :: BitOrder -> BitPutState+newBitPutState = BitPutState mempty 0 0++-- | Put bits+putBits ::+   ( Integral a+   , Bits a+   , ReversableBits a+   ) => Word -> a -> BitPutState -> BitPutState+putBits n w s@(BitPutState builder b o bo) = s'+   where+      -- number of bits that will be stored in the current byte+      cn = min (8-o) n++      -- new state+      s' = case n of+            0 -> s+            _ -> putBits (n-cn) w' (flush (BitPutState builder b' (o+cn) bo))+      +      -- new current byte+      b' = shl (selectBits w) .|. b++      -- Word containing the remaining (n-cn) bits to store in its LSB+      w' = case bo of+         BB -> w+         BL -> w `shiftR` fromIntegral cn+         LL -> w `shiftR` fromIntegral cn+         LB -> w++      -- Select bits to store in the current byte.+      -- Put them in the correct order and return them in the least-significant+      -- bits of the returned value+      selectBits :: (Bits a, ReversableBits a, Integral a) => a -> Word8+      selectBits x = fromIntegral $ case bo of+         BB ->                       maskDyn cn $ x `shiftR` fromIntegral (n-cn)+         LB -> reverseLeastBits cn $ maskDyn cn $ x `shiftR` fromIntegral (n-cn)+         LL ->                       maskDyn cn x+         BL -> reverseLeastBits cn $ maskDyn cn x++      -- shift left at the correct position+      shl :: Word8 -> Word8+      shl x = case bo of+         BB -> x `shiftL` (8 - fromIntegral o - fromIntegral cn)+         BL -> x `shiftL` (8 - fromIntegral o - fromIntegral cn)+         LL -> x `shiftL` fromIntegral o+         LB -> x `shiftL` fromIntegral o++      -- flush the current byte if it is full+      flush s2@(BitPutState b2 w2 o2 bo2)+        | o2 == 8   = BitPutState (b2 `mappend` B.fromWord8 w2) 0 0 bo2+        | otherwise = s2+++-- | Put a Buffer+--+-- Examples: 3 bits are already written in the current byte+-- @  BB: ABCDEFGH IJKLMNOP -> xxxABCDE FGHIJKLM NOPxxxxx @+-- @  LL: ABCDEFGH IJKLMNOP -> LMNOPxxx DEFGHIJK xxxxxABC @+-- @  BL: ABCDEFGH IJKLMNOP -> xxxPONML KJIHGFED CBAxxxxx @+-- @  LB: ABCDEFGH IJKLMNOP -> EDCBAxxx MLKJIHGF xxxxxPON @+putBitsBuffer :: Buffer -> BitPutState -> BitPutState+putBitsBuffer bs s+   | isBufferEmpty bs = s+   | otherwise  = case s of+      (BitPutState builder b 0 BB) -> BitPutState (builder `mappend` B.fromBuffer bs) b 0 BB+      (BitPutState builder b 0 LL) -> BitPutState (builder `mappend` B.fromBuffer (bufferReverse bs)) b 0 LL+      (BitPutState builder b 0 LB) -> BitPutState (builder `mappend` B.fromBuffer (rev bs)) b 0 LB+      (BitPutState builder b 0 BL) -> BitPutState (builder `mappend` B.fromBuffer (rev (bufferReverse bs))) b 0 BL+      (BitPutState _ _ _ BB)       -> putBitsBuffer (bufferUnsafeTail bs) (putBits 8 (bufferUnsafeHead bs) s)+      (BitPutState _ _ _ LL)       -> putBitsBuffer (bufferUnsafeInit bs) (putBits 8 (bufferUnsafeLast bs) s)+      (BitPutState _ _ _ BL)       -> putBitsBuffer (bufferUnsafeInit bs) (putBits 8 (bufferUnsafeLast bs) s)+      (BitPutState _ _ _ LB)       -> putBitsBuffer (bufferUnsafeTail bs) (putBits 8 (bufferUnsafeHead bs) s)+   where+      rev    = bufferMap reverseBits++-- | Flush the current byte+flushIncomplete :: BitPutState -> BitPutState+flushIncomplete s@(BitPutState b w o bo)+  | o == 0    = s+  | otherwise = BitPutState (b `mappend` B.fromWord8 w) 0 0 bo++-- | Get a buffer list+getBitPutBufferList :: BitPutState -> BufferList+getBitPutBufferList = toBufferList . bitPutStateBuilder . flushIncomplete ++-- | Get a Buffer+getBitPutBuffer :: BitPutState -> Buffer+getBitPutBuffer =  toBuffer . bitPutStateBuilder . flushIncomplete++-- | BitPut monad transformer+type BitPutT m a = StateT BitPutState m a++-- | BitPut monad+type BitPut a    = BitPutT Identity a++-- | Evaluate a BitPut monad+runBitPutT :: Monad m => BitOrder -> BitPutT m a -> m Buffer+runBitPutT bo m = getBitPutBuffer <$> execStateT m (newBitPutState bo)++-- | Evaluate a BitPut monad+runBitPut :: BitOrder -> BitPut a -> Buffer+runBitPut bo m = runIdentity (runBitPutT bo m)++-- | Put bits (monadic)+putBitsM :: (Monad m, Integral a, Bits a, ReversableBits a) => Word -> a -> BitPutT m ()+putBitsM n w = modify (putBits n w)++-- | Put a single bit (monadic)+putBitBoolM :: (Monad m) => Bool -> BitPutT m ()+putBitBoolM b = putBitsM 1 (if b then 1 else  0 :: Word)++-- | Put a Buffer (monadic)+putBitsBufferM :: Monad m => Buffer -> BitPutT m ()+putBitsBufferM bs = modify (putBitsBuffer bs)++-- | Change the current bit ordering+--+-- Be careful to change the outer bit ordering (B* to L* or the inverse) only+-- on bytes boundaries! Otherwise, you will write the same bits more than once.+changeBitPutOrder :: Monad m => BitOrder -> BitPutT m ()+changeBitPutOrder bo = modify (\s -> s { bitPutStateBitOrder = bo })++-- | Change the bit ordering for the wrapped BitPut+--+-- Be careful, this function uses changeBitPutOrder internally.+withBitPutOrder :: Monad m => BitOrder -> BitPutT m a -> BitPutT m a+withBitPutOrder bo m = do+   bo' <- gets bitPutStateBitOrder+   changeBitPutOrder bo+   v <- m+   changeBitPutOrder bo'+   return v
+ src/lib/Haskus/Binary/Bits/Reverse.hs view
@@ -0,0 +1,340 @@+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE ScopedTypeVariables #-}++-- | Reverse bits+--+-- There are several algorithms performing the same thing here (reversing bits+-- into words of different sizes). There are benchmarks for them in the +-- "bench" directory. The fastest one for the current architecture should be+-- selected below. If you find that another algorithm is faster on your+-- architecture, please report it.+module Haskus.Binary.Bits.Reverse+   ( +   -- * Generic+     ReversableBits (..)+   , reverseBitsGeneric+   -- * Algorithms+   , reverseBitsObvious+   , reverseBits3Ops+   , reverseBits4Ops+   , reverseBitsTable+   , reverseBits7Ops+   , reverseBits5LgN+   , liftReverseBits+   )+where++import Haskus.Binary.Buffer+import Haskus.Number.Word+import Haskus.Number.Int+import Haskus.Binary.Bits.Finite+import Haskus.Binary.Bits.Shift+import Haskus.Binary.Bits.Bitwise+import Haskus.Binary.Bits.Index+import Haskus.Utils.Types (KnownNat)++---------------------------------------------------+-- Generic and specialized reverseBits+---------------------------------------------------+++-- | Reverse bits in a Word+reverseBitsGeneric ::+   ( FiniteBits a+   , Integral a+   , ShiftableBits a+   , Bitwise a+   , KnownNat (BitSize a)+   ) => a -> a+reverseBitsGeneric = liftReverseBits reverseBits4Ops++-- | Data whose bits can be reversed+class ReversableBits w where+   reverseBits :: w -> w++instance ReversableBits Word8 where+   reverseBits = reverseBits4Ops++instance ReversableBits Word16 where+   reverseBits = reverseBits5LgN++instance ReversableBits Word32 where+   reverseBits = reverseBits5LgN++instance ReversableBits Word64 where+   reverseBits = reverseBits5LgN++instance ReversableBits Word where+   reverseBits = reverseBits5LgN++instance ReversableBits Int8 where+   reverseBits = fromIntegral . reverseBits4Ops . fromIntegral++instance ReversableBits Int16 where+   reverseBits = reverseBits5LgN++instance ReversableBits Int32 where+   reverseBits = reverseBits5LgN++instance ReversableBits Int64 where+   reverseBits = reverseBits5LgN++instance ReversableBits Int where+   reverseBits = reverseBits5LgN+++---------------------------------------------------+-- Bit reversal algorithms+---------------------------------------------------++-- Algorithms and explanations adapted from:+-- http://graphics.stanford.edu/~seander/bithacks.html#ReverseByteWith64Bits++-- Reverse the bits the obvious way+-- ================================+--+--+-- unsigned int v;     // input bits to be reversed+-- unsigned int r = v; // r will be reversed bits of v; first get LSB of v+-- int s = sizeof(v) * CHAR_BIT - 1; // extra shift needed at end+-- +-- for (v >>= 1; v; v >>= 1)+-- {   +--   r <<= 1;+--   r |= v & 1;+--   s--;+-- }+-- r <<= s; // shift when v's highest bits are zero+--+-- On October 15, 2004, Michael Hoisie pointed out a bug in the original+-- version. Randal E. Bryant suggested removing an extra operation on May 3,+-- 2005. Behdad Esfabod suggested a slight change that eliminated one iteration+-- of the loop on May 18, 2005. Then, on February 6, 2007, Liyong Zhou+-- suggested a better version that loops while v is not 0, so rather than+-- iterating over all bits it stops early. ++-- | Obvious recursive version+reverseBitsObvious :: forall a.+   ( FiniteBits a+   , ShiftableBits a+   , IndexableBits a+   , Bitwise a+   , KnownNat (BitSize a)+   , Eq a+   ) => a -> a+reverseBitsObvious x = rec x (x `shiftR` 1) (bitSize x - 1)+   where+      rec :: FiniteBits a => a -> a -> Word -> a+      rec !r !v !s +         | v == zeroBits = r `shiftL` s+         | otherwise     = rec ((r `shiftL` 1) .|. (v .&. bit 0)) (v `shiftR` 1) (s - 1)++{-# SPECIALIZE reverseBitsObvious :: Word8  -> Word8  #-}+{-# SPECIALIZE reverseBitsObvious :: Word16 -> Word16 #-}+{-# SPECIALIZE reverseBitsObvious :: Word32 -> Word32 #-}+{-# SPECIALIZE reverseBitsObvious :: Word64 -> Word64 #-}++-- Reverse the bits in a byte with 3 operations (64-bit multiply and modulus division) +-- ===================================================================================+-- +-- unsigned char b; // reverse this (8-bit) byte+--  +-- b = (b * 0x0202020202ULL & 0x010884422010ULL) % 1023;+-- +-- The multiply operation creates five separate copies of the 8-bit byte+-- pattern to fan-out into a 64-bit value. The AND operation selects the bits+-- that are in the correct (reversed) positions, relative to each 10-bit groups+-- of bits. The multiply and the AND operations copy the bits from the original+-- byte so they each appear in only one of the 10-bit sets. The reversed+-- positions of the bits from the original byte coincide with their relative+-- positions within any 10-bit set. The last step, which involves modulus+-- division by 2^10 - 1, has the effect of merging together each set of 10 bits+-- (from positions 0-9, 10-19, 20-29, ...) in the 64-bit value. They do not+-- overlap, so the addition steps underlying the modulus division behave like+-- or operations.+-- +-- This method was attributed to Rich Schroeppel in the Programming Hacks+-- section of Beeler, M., Gosper, R. W., and Schroeppel, R. HAKMEM. MIT AI Memo+-- 239, Feb. 29, 1972.++-- | Reverse bits in a Word8 (3 64-bit operations, modulus division)+reverseBits3Ops :: Word8 -> Word8+{-# INLINABLE reverseBits3Ops #-}+reverseBits3Ops x = fromIntegral x'+   where+      !x' = ((fromIntegral x * 0x0202020202 :: Word64) .&. 0x010884422010) `mod` 1023+++-- Reverse the bits in a byte with 4 operations (64-bit multiply, no division) +-- ===========================================================================+--+-- unsigned char b; // reverse this (8-bit) byte+--  +-- b = ((b * 0x80200802ULL) & 0x0884422110ULL) * 0x0101010101ULL >> 32;+-- +-- The following shows the flow of the bit values with the boolean variables a,+-- b, c, d, e, f, g, and h, which comprise an 8-bit byte. Notice how the first+-- multiply fans out the bit pattern to multiple copies, while the last+-- multiply combines them in the fifth byte from the right. +--+--+--                                                                                         abcd efgh (-> hgfe dcba)+-- *                                                      1000 0000  0010 0000  0000 1000  0000 0010 (0x80200802)+-- -------------------------------------------------------------------------------------------------+--                                             0abc defg  h00a bcde  fgh0 0abc  defg h00a  bcde fgh0+-- &                                           0000 1000  1000 0100  0100 0010  0010 0001  0001 0000 (0x0884422110)+-- -------------------------------------------------------------------------------------------------+--                                             0000 d000  h000 0c00  0g00 00b0  00f0 000a  000e 0000+-- *                                           0000 0001  0000 0001  0000 0001  0000 0001  0000 0001 (0x0101010101)+-- -------------------------------------------------------------------------------------------------+--                                             0000 d000  h000 0c00  0g00 00b0  00f0 000a  000e 0000+--                                  0000 d000  h000 0c00  0g00 00b0  00f0 000a  000e 0000+--                       0000 d000  h000 0c00  0g00 00b0  00f0 000a  000e 0000+--            0000 d000  h000 0c00  0g00 00b0  00f0 000a  000e 0000+-- 0000 d000  h000 0c00  0g00 00b0  00f0 000a  000e 0000+-- -------------------------------------------------------------------------------------------------+-- 0000 d000  h000 dc00  hg00 dcb0  hgf0 dcba  hgfe dcba  hgfe 0cba  0gfe 00ba  00fe 000a  000e 0000+-- >> 32+-- -------------------------------------------------------------------------------------------------+--                                             0000 d000  h000 dc00  hg00 dcb0  hgf0 dcba  hgfe dcba  +-- &                                                                                       1111 1111+-- -------------------------------------------------------------------------------------------------+--                                                                                         hgfe dcba+-- Note that the last two steps can be combined on some processors because the+-- registers can be accessed as bytes; just multiply so that a register stores+-- the upper 32 bits of the result and the take the low byte. Thus, it may take+-- only 6 operations.+-- +-- Devised by Sean Anderson, July 13, 2001. ++-- | Reverse bits in a Word8 (4 64-bit operations, no division)+reverseBits4Ops :: Word8 -> Word8+{-# INLINABLE reverseBits4Ops #-}+reverseBits4Ops x = fromIntegral x'+   where+      !x' = (((fromIntegral x * 0x80200802 :: Word64) .&. 0x0884422110) * 0x0101010101) `shiftR` 32+++-- Reverse bits using a lookup table+-- =================================++-- | Reverse bits using a lookup table+reverseBitsTable :: Word8 -> Word8+{-# INLINABLE reverseBitsTable #-}+reverseBitsTable x = bitsTable `bufferIndex` (fromIntegral x)+++-- fill the table by using another method+bitsTable :: Buffer+bitsTable = bufferPackByteList $ fmap reverseBits4Ops [0..255]++-- Reverse the bits in a byte with 7 operations (no 64-bit)+-- ========================================================+-- +-- b = ((b * 0x0802LU & 0x22110LU) | (b * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16; +-- +-- Make sure you assign or cast the result to an unsigned char to remove+-- garbage in the higher bits. Devised by Sean Anderson, July 13, 2001. Typo+-- spotted and correction supplied by Mike Keith, January 3, 2002. +++-- | Reverse bits in a Word8 (7 no 64-bit operations, no division)+reverseBits7Ops :: Word8 -> Word8+{-# INLINABLE reverseBits7Ops #-}+reverseBits7Ops b' = fromIntegral x'+   where+      b   = fromIntegral b' :: Word32+      !x' = ((((b * 0x0802) .&. 0x22110) .|. ((b * 0x8020) .&. 0x88440)) * 0x10101) `shiftR` 16+++-- Reverse an N-bit quantity in parallel in 5 * lg(N) operations+-- =============================================================+-- +-- unsigned int v; // 32-bit word to reverse bit order+-- +-- // swap odd and even bits+-- v = ((v >> 1) & 0x55555555) | ((v & 0x55555555) << 1);+-- // swap consecutive pairs+-- v = ((v >> 2) & 0x33333333) | ((v & 0x33333333) << 2);+-- // swap nibbles ... +-- v = ((v >> 4) & 0x0F0F0F0F) | ((v & 0x0F0F0F0F) << 4);+-- // swap bytes+-- v = ((v >> 8) & 0x00FF00FF) | ((v & 0x00FF00FF) << 8);+-- // swap 2-byte long pairs+-- v = ( v >> 16             ) | ( v               << 16);+-- +-- The following variation is also O(lg(N)), however it requires more+-- operations to reverse v. Its virtue is in taking less slightly memory by+-- computing the constants on the fly.+-- +-- unsigned int s = sizeof(v) * CHAR_BIT; // bit size; must be power of 2 +-- unsigned int mask = ~0;         +-- while ((s >>= 1) > 0) +-- {+--   mask ^= (mask << s);+--   v = ((v >> s) & mask) | ((v << s) & ~mask);+-- }+-- +-- These methods above are best suited to situations where N is large. If you+-- use the above with 64-bit ints (or larger), then you need to add more lines+-- (following the pattern); otherwise only the lower 32 bits will be reversed+-- and the result will be in the lower 32 bits.+-- +-- See Dr. Dobb's Journal 1983, Edwin Freed's article on Binary Magic Numbers+-- for more information. The second variation was suggested by Ken Raeburn on+-- September 13, 2005. Veldmeijer mentioned that the first version could do+-- without ANDS in the last line on March 19, 2006. ++-- | "Parallel" recursive version+reverseBits5LgN :: forall a.+   ( FiniteBits a+   , ShiftableBits a+   , Bitwise a+   , KnownNat (BitSize a)+   ) => a -> a+reverseBits5LgN x = rec (bitSize x `shiftR` 1) (complement zeroBits) x+   where+      rec :: FiniteBits a => Word -> a -> a -> a+      rec !s !mask !v+         | s <= 0        = v+         | otherwise     = rec (s `shiftR` 1) mask' v'+            where+               mask' = mask `xor` (mask `shiftL` s)+               v'    =      ((v `shiftR` s) .&. mask')+                        .|. ((v `shiftL` s) .&. complement mask')++{-# SPECIALIZE reverseBits5LgN :: Word8  -> Word8  #-}+{-# SPECIALIZE reverseBits5LgN :: Word16 -> Word16 #-}+{-# SPECIALIZE reverseBits5LgN :: Word32 -> Word32 #-}+{-# SPECIALIZE reverseBits5LgN :: Word64 -> Word64 #-}++++-- | Convert a function working on Word8 to one working on any Word+--+-- The number of bits in the Word must be a multiple of 8+liftReverseBits ::+   ( ShiftableBits a+   , Bitwise a+   , FiniteBits a+   , Integral a+   , KnownNat (BitSize a)+   ) => (Word8 -> Word8) -> a -> a+liftReverseBits f w = rec zeroBits 0+   where+      nb = bitSize w `shiftR` 3 -- div 8+      f' = fromIntegral . f . fromIntegral+      rec !v !o+         | o == nb    = v+         | otherwise = rec v' (o+1)+               where+                  -- multiplication by 8 replaced with (`shiftL` 3)+                  v' = v .|. ((f' (w `shiftR` (o `shiftL` 3))) `shiftL` ((nb-1-o) `shiftL` 3))++{-# SPECIALIZE liftReverseBits :: (Word8 -> Word8) -> Word8  -> Word8  #-}+{-# SPECIALIZE liftReverseBits :: (Word8 -> Word8) -> Word16 -> Word16 #-}+{-# SPECIALIZE liftReverseBits :: (Word8 -> Word8) -> Word32 -> Word32 #-}+{-# SPECIALIZE liftReverseBits :: (Word8 -> Word8) -> Word64 -> Word64 #-}+
+ src/lib/Haskus/Binary/Bits/Rotate.hs view
@@ -0,0 +1,90 @@+{-# LANGUAGE DefaultSignatures #-}+{-# LANGUAGE FlexibleContexts #-}++-- | Bit rotations+module Haskus.Binary.Bits.Rotate+   ( RotatableBits (..)+   )+where++import Haskus.Binary.Bits.Finite+import Haskus.Binary.Bits.Shift+import Haskus.Binary.Bits.Bitwise+import Haskus.Number.Word+import Haskus.Number.Int+import Haskus.Utils.Types++-- | Types whose bits can be rotated+class RotatableBits a where++   -- | Rotate left if positive, right if negative+   rotate :: a -> Int -> a+   default rotate ::+      ( FiniteBits a+      , KnownNat (BitSize a)+      ) => a -> Int -> a+   rotate a i+      | i' > 0     = rotateL a (fromIntegral i')+      | i' < 0     = rotateR a (fromIntegral (negate i'))+      | otherwise = a+      where+         i' = i `mod` bitSize a++   -- | Checked left bit rotation+   rotateL :: a -> Word -> a+   default rotateL ::+      ( FiniteBits a+      , KnownNat (BitSize a)+      ) => a -> Word -> a+   rotateL a n = uncheckedRotateL a (n `mod` bitSize a)++   -- | Checked right bit rotation+   rotateR :: a -> Word -> a+   default rotateR ::+      ( FiniteBits a+      , KnownNat (BitSize a)+      ) => a -> Word -> a+   rotateR a n = uncheckedRotateR a (n `mod` bitSize a)++   -- | Unchecked rotate left if positive, right if negative+   uncheckedRotate :: a -> Int -> a+   uncheckedRotate a i+      | i > 0     = uncheckedRotateL a (fromIntegral i)+      | i < 0     = uncheckedRotateR a (fromIntegral (negate i))+      | otherwise = a++   -- | Unchecked left bit rotation+   uncheckedRotateL :: a -> Word -> a+   default uncheckedRotateL ::+      ( ShiftableBits a+      , FiniteBits a+      , KnownNat (BitSize a)+      , Bitwise a+      ) => a -> Word -> a+   uncheckedRotateL a i = (a `uncheckedShiftL` i) .|. (a `uncheckedShiftR` (n-i))+      where n = bitSize a+      ++   -- | Unchecked right bit rotation+   uncheckedRotateR :: a -> Word -> a+   default uncheckedRotateR ::+      ( ShiftableBits a+      , FiniteBits a+      , KnownNat (BitSize a)+      , Bitwise a+      ) => a -> Word -> a+   uncheckedRotateR a i = (a `uncheckedShiftL` (n-i)) .|. (a `uncheckedShiftR` i)+      where n = bitSize a+++instance RotatableBits Word+instance RotatableBits Word8+instance RotatableBits Word16+instance RotatableBits Word32+instance RotatableBits Word64++instance RotatableBits Int+instance RotatableBits Int8+instance RotatableBits Int16+instance RotatableBits Int32+instance RotatableBits Int64
+ src/lib/Haskus/Binary/Bits/Shift.hs view
@@ -0,0 +1,324 @@+{-# LANGUAGE MagicHash #-}+{-# LANGUAGE CPP #-}++-- | Bit shifts+module Haskus.Binary.Bits.Shift+   ( ShiftableBits (..)+   , SignedShiftableBits (..)+   )+where++import Haskus.Number.Word+import Haskus.Number.Int+import GHC.Exts+import GHC.Num++#include "MachDeps.h"++-- | Bit shifts+--+-- "Checked" means that there is an additional test to ensure that the shift+-- offset is valid (less than the bit count). If you are sure that the offset is+-- valid, use the "unchecked" version which should be faster.+--+-- To shift signed numbers, see `SignedShiftableBits` class methods.+class ShiftableBits a where+   -- | Checked right shift+   shiftR :: a -> Word -> a++   -- | Checked left shift+   shiftL :: a -> Word -> a++   -- | Unchecked right shift+   uncheckedShiftR :: a -> Word -> a++   -- | Unchecked left shift+   uncheckedShiftL :: a -> Word -> a++   -- | Checked shift to the left if positive, to the right if negative+   shift :: a -> Int -> a+   shift a i+      | i > 0     = shiftL a (fromIntegral i)+      | i < 0     = shiftR a (fromIntegral (negate i))+      | otherwise = a++   -- | Unchecked shift to the left if positive, to the right if negative+   uncheckedShift :: a -> Int -> a+   uncheckedShift a i+      | i > 0     = uncheckedShiftL a (fromIntegral i)+      | i < 0     = uncheckedShiftR a (fromIntegral (negate i))+      | otherwise = a++-- | Signed bit shifts+--+-- "Signed" means that the sign bit (the higher order bit):+--    - propagates to the right during right shifts and +--    - keeps its value during left shifts (except when all other bits are 0)+--+-- "Checked" means that there is an additional test to ensure that the shift+-- offset is valid (less than the bit count). If you are sure that the offset is+-- valid, use the "unchecked" version which should be faster.+class SignedShiftableBits a where+   -- | Checked signed right shift+   signedShiftR :: a -> Word -> a++   -- | Checked signed left shift+   signedShiftL :: a -> Word -> a++   -- | Unchecked signed right shift+   uncheckedSignedShiftR :: a -> Word -> a++   -- | Unchecked signed left shift+   uncheckedSignedShiftL :: a -> Word -> a++   -- | Checked signed shift to the left if positive, to the right if negative+   signedShift :: a -> Int -> a+   signedShift a i+      | i > 0     = signedShiftL a (fromIntegral i)+      | i < 0     = signedShiftR a (fromIntegral (negate i))+      | otherwise = a++   -- | Unchecked signed shift to the left if positive, to the right if negative+   uncheckedSignedShift :: a -> Int -> a+   uncheckedSignedShift a i+      | i > 0     = uncheckedSignedShiftL a (fromIntegral i)+      | i < 0     = uncheckedSignedShiftR a (fromIntegral (negate i))+      | otherwise = a+++instance ShiftableBits Word where+   {-# INLINABLE shiftR #-}+   {-# INLINABLE shiftL #-}+   {-# INLINABLE uncheckedShiftL #-}+   {-# INLINABLE uncheckedShiftR #-}++   (W# x#) `shiftL`          (W# i#)+      | isTrue# (i# `geWord#` WORD_SIZE_IN_BITS##) = W# 0##+      | otherwise                                  = W# (x# `uncheckedShiftL#` word2Int# i#)+   (W# x#) `shiftR`          (W# i#)+      | isTrue# (i# `geWord#` WORD_SIZE_IN_BITS##) = W# 0##+      | otherwise                                  = W# (x# `uncheckedShiftRL#` word2Int# i#)+   (W# x#) `uncheckedShiftL` (W# i#) = W# (x# `uncheckedShiftL#` word2Int# i#)+   (W# x#) `uncheckedShiftR` (W# i#) = W# (x# `uncheckedShiftRL#` word2Int# i#)++instance ShiftableBits Word8 where+   {-# INLINABLE shiftR #-}+   {-# INLINABLE shiftL #-}+   {-# INLINABLE uncheckedShiftL #-}+   {-# INLINABLE uncheckedShiftR #-}++   (W8# x#) `shiftL` (W# i#)+      | isTrue# (i# `geWord#` 8##)    = W8# 0##+      | otherwise                     = W8# (narrow8Word# (x# `uncheckedShiftL#` word2Int# i#))++   (W8# x#) `uncheckedShiftL` (W# i#) = W8# (narrow8Word# (x# `uncheckedShiftL#` word2Int# i#))+   +   (W8# x#) `shiftR` (W# i#)+      | isTrue# (i# `geWord#` 8##)    = W8# 0##+      | otherwise                     = W8# (x# `uncheckedShiftRL#` word2Int# i#)+   +   (W8# x#) `uncheckedShiftR` (W# i#) = W8# (x# `uncheckedShiftRL#` word2Int# i#)++instance ShiftableBits Word16 where+   {-# INLINABLE shiftR #-}+   {-# INLINABLE shiftL #-}+   {-# INLINABLE uncheckedShiftL #-}+   {-# INLINABLE uncheckedShiftR #-}++   (W16# x#) `shiftL` (W# i#)+      | isTrue# (i# `geWord#` 16##)    = W16# 0##+      | otherwise                      = W16# (narrow16Word# (x# `uncheckedShiftL#` word2Int# i#))++   (W16# x#) `uncheckedShiftL` (W# i#) = W16# (narrow16Word# (x# `uncheckedShiftL#` word2Int# i#))+   +   (W16# x#) `shiftR` (W# i#)+      | isTrue# (i# `geWord#` 16##)    = W16# 0##+      | otherwise                      = W16# (x# `uncheckedShiftRL#` word2Int# i#)+   +   (W16# x#) `uncheckedShiftR` (W# i#) = W16# (x# `uncheckedShiftRL#` word2Int# i#)++instance ShiftableBits Word32 where+   {-# INLINABLE shiftR #-}+   {-# INLINABLE shiftL #-}+   {-# INLINABLE uncheckedShiftL #-}+   {-# INLINABLE uncheckedShiftR #-}++   (W32# x#) `shiftL` (W# i#)+      | isTrue# (i# `geWord#` 32##)    = W32# 0##+      | otherwise                      = W32# (narrow32Word# (x# `uncheckedShiftL#` word2Int# i#))++   (W32# x#) `uncheckedShiftL` (W# i#) = W32# (narrow32Word# (x# `uncheckedShiftL#` word2Int# i#))+   +   (W32# x#) `shiftR` (W# i#)+      | isTrue# (i# `geWord#` 32##)    = W32# 0##+      | otherwise                      = W32# (x# `uncheckedShiftRL#` word2Int# i#)+   +   (W32# x#) `uncheckedShiftR` (W# i#) = W32# (x# `uncheckedShiftRL#` word2Int# i#)++instance ShiftableBits Word64 where+   {-# INLINABLE shiftR #-}+   {-# INLINABLE shiftL #-}+   {-# INLINABLE uncheckedShiftL #-}+   {-# INLINABLE uncheckedShiftR #-}++   (W64# x#) `shiftL` (W# i#)+      | isTrue# (i# `geWord#` 64##)    = W64# 0##+      | otherwise                      = W64# (x# `uncheckedShiftL#` word2Int# i#)++   (W64# x#) `uncheckedShiftL` (W# i#) = W64# (x# `uncheckedShiftL#` word2Int# i#)+   +   (W64# x#) `shiftR` (W# i#)+      | isTrue# (i# `geWord#` 64##)    = W64# 0##+      | otherwise                      = W64# (x# `uncheckedShiftRL#` word2Int# i#)+   +   (W64# x#) `uncheckedShiftR` (W# i#) = W64# (x# `uncheckedShiftRL#` word2Int# i#)+++instance ShiftableBits Int where+   {-# INLINABLE shiftR #-}+   {-# INLINABLE shiftL #-}+   {-# INLINABLE uncheckedShiftL #-}+   {-# INLINABLE uncheckedShiftR #-}++   (I# x#) `shiftL`          (W# i#)+      | isTrue# (i# `geWord#` WORD_SIZE_IN_BITS##) = I# 0#+      | otherwise                                  = I# (x# `uncheckedIShiftL#` word2Int# i#)++   (I# x#) `uncheckedShiftL` (W# i#)               = I# (x# `uncheckedIShiftL#` word2Int# i#)+   +   (I# x#) `shiftR`          (W# i#)+      | isTrue# (i# `geWord#` WORD_SIZE_IN_BITS##) = I# 0#+      | otherwise                                  = I# (x# `uncheckedIShiftRL#` word2Int# i#)+   +   (I# x#) `uncheckedShiftR` (W# i#)               = I# (x# `uncheckedIShiftRL#` word2Int# i#)++instance ShiftableBits Int8 where+   {-# INLINABLE shiftR #-}+   {-# INLINABLE shiftL #-}+   {-# INLINABLE uncheckedShiftL #-}+   {-# INLINABLE uncheckedShiftR #-}++   (I8# x#) `shiftL`          (W# i#)+      | isTrue# (i# `geWord#` 8##)    = I8# 0#+      | otherwise                     = I8# (narrow8Int# (x# `uncheckedIShiftL#` word2Int# i#))++   (I8# x#) `uncheckedShiftL` (W# i#) = I8# (narrow8Int# (x# `uncheckedIShiftL#` word2Int# i#))+   +   (I8# x#) `shiftR`          (W# i#)+      | isTrue# (i# `geWord#` 8##)    = I8# 0#+      | otherwise                     = I8# (word2Int# (narrow8Word# (int2Word# x#) `uncheckedShiftRL#` word2Int# i#))++   (I8# x#) `uncheckedShiftR` (W# i#) = I8# (word2Int# (narrow8Word# (int2Word# x#) `uncheckedShiftRL#` word2Int# i#))+   ++instance ShiftableBits Int16 where+   {-# INLINABLE shiftR #-}+   {-# INLINABLE shiftL #-}+   {-# INLINABLE uncheckedShiftL #-}+   {-# INLINABLE uncheckedShiftR #-}++   (I16# x#) `shiftL`          (W# i#)+      | isTrue# (i# `geWord#` 16##)    = I16# 0#+      | otherwise                      = I16# (narrow16Int# (x# `uncheckedIShiftL#` word2Int# i#))++   (I16# x#) `uncheckedShiftL` (W# i#) = I16# (narrow16Int# (x# `uncheckedIShiftL#` word2Int# i#))+   +   (I16# x#) `shiftR`          (W# i#)+      | isTrue# (i# `geWord#` 16##)    = I16# 0#+      | otherwise                      = I16# (word2Int# (narrow16Word# (int2Word# x#) `uncheckedShiftRL#` word2Int# i#))++   (I16# x#) `uncheckedShiftR` (W# i#) = I16# (word2Int# (narrow16Word# (int2Word# x#) `uncheckedShiftRL#` word2Int# i#))+++instance ShiftableBits Int32 where+   {-# INLINABLE shiftR #-}+   {-# INLINABLE shiftL #-}+   {-# INLINABLE uncheckedShiftL #-}+   {-# INLINABLE uncheckedShiftR #-}++   (I32# x#) `shiftL`          (W# i#)+      | isTrue# (i# `geWord#` 32##)    = I32# 0#+      | otherwise                      = I32# (narrow32Int# (x# `uncheckedIShiftL#` word2Int# i#))++   (I32# x#) `uncheckedShiftL` (W# i#) = I32# (narrow32Int# (x# `uncheckedIShiftL#` word2Int# i#))+   +   (I32# x#) `shiftR`          (W# i#)+      | isTrue# (i# `geWord#` 32##)    = I32# 0#+      | otherwise                      = I32# (word2Int# (narrow32Word# (int2Word# x#) `uncheckedShiftRL#` word2Int# i#))++   (I32# x#) `uncheckedShiftR` (W# i#) = I32# (word2Int# (narrow32Word# (int2Word# x#) `uncheckedShiftRL#` word2Int# i#))++instance ShiftableBits Int64 where+   {-# INLINABLE shiftR #-}+   {-# INLINABLE shiftL #-}+   {-# INLINABLE uncheckedShiftL #-}+   {-# INLINABLE uncheckedShiftR #-}++   (I64# x#) `shiftL`          (W# i#)+      | isTrue# (i# `geWord#` 64##)    = I64# 0#+      | otherwise                      = I64# (x# `uncheckedIShiftL#` word2Int# i#)++   (I64# x#) `uncheckedShiftL` (W# i#) = I64# (x# `uncheckedIShiftL#` word2Int# i#)+   +   (I64# x#) `shiftR`          (W# i#)+      | isTrue# (i# `geWord#` 64##)    = I64# 0#+      | otherwise                      = I64# (word2Int# (int2Word# x# `uncheckedShiftRL#` word2Int# i#))++   (I64# x#) `uncheckedShiftR` (W# i#) = I64# (word2Int# (int2Word# x# `uncheckedShiftRL#` word2Int# i#))+++instance SignedShiftableBits Int where+   (I# x#) `signedShiftL`          (W# i#) = I# (x# `iShiftL#` word2Int# i#)+   (I# x#) `signedShiftR`          (W# i#) = I# (x# `iShiftRA#` word2Int# i#)+   (I# x#) `uncheckedSignedShiftL` (W# i#) = I# (x# `uncheckedIShiftL#` word2Int# i#)+   (I# x#) `uncheckedSignedShiftR` (W# i#) = I# (x# `uncheckedIShiftRA#` word2Int# i#)++instance SignedShiftableBits Int8 where+   (I8# x#) `signedShiftL`          (W# i#) = I8# (narrow8Int# (x# `iShiftL#` word2Int# i#))+   (I8# x#) `signedShiftR`          (W# i#) = I8# (x# `iShiftRA#` word2Int# i#)+   (I8# x#) `uncheckedSignedShiftL` (W# i#) = I8# (narrow8Int# (x# `uncheckedIShiftL#` word2Int# i#))+   (I8# x#) `uncheckedSignedShiftR` (W# i#) = I8# (x# `uncheckedIShiftRA#` word2Int# i#)++instance SignedShiftableBits Int16 where+   (I16# x#) `signedShiftL`          (W# i#) = I16# (narrow16Int# (x# `iShiftL#` word2Int# i#))+   (I16# x#) `signedShiftR`          (W# i#) = I16# (x# `iShiftRA#` word2Int# i#)+   (I16# x#) `uncheckedSignedShiftL` (W# i#) = I16# (narrow16Int# (x# `uncheckedIShiftL#` word2Int# i#))+   (I16# x#) `uncheckedSignedShiftR` (W# i#) = I16# (x# `uncheckedIShiftRA#` word2Int# i#)++instance SignedShiftableBits Int32 where+   (I32# x#) `signedShiftL`          (W# i#) = I32# (narrow32Int# (x# `iShiftL#` word2Int# i#))+   (I32# x#) `signedShiftR`          (W# i#) = I32# (x# `iShiftRA#` word2Int# i#)+   (I32# x#) `uncheckedSignedShiftL` (W# i#) = I32# (narrow32Int# (x# `uncheckedIShiftL#` word2Int# i#))+   (I32# x#) `uncheckedSignedShiftR` (W# i#) = I32# (x# `uncheckedIShiftRA#` word2Int# i#)++instance SignedShiftableBits Int64 where+   (I64# x#) `signedShiftL`          (W# i#) = I64# (x# `iShiftL#` word2Int# i#)+   (I64# x#) `signedShiftR`          (W# i#) = I64# (x# `iShiftRA#` word2Int# i#)+   (I64# x#) `uncheckedSignedShiftL` (W# i#) = I64# (x# `uncheckedIShiftL#` word2Int# i#)+   (I64# x#) `uncheckedSignedShiftR` (W# i#) = I64# (x# `uncheckedIShiftRA#` word2Int# i#)++++instance ShiftableBits Integer where+   {-# INLINABLE shiftR #-}+   {-# INLINABLE shiftL #-}+   {-# INLINABLE uncheckedShiftL #-}+   {-# INLINABLE uncheckedShiftR #-}++   x `shiftL` (W# i#) = shiftLInteger x (word2Int# i#)+   x `shiftR` (W# i#) = shiftRInteger x (word2Int# i#)++   uncheckedShiftL = shiftL+   uncheckedShiftR = shiftR++instance ShiftableBits Natural where+   {-# INLINABLE shiftR #-}+   {-# INLINABLE shiftL #-}+   {-# INLINABLE uncheckedShiftL #-}+   {-# INLINABLE uncheckedShiftR #-}++   x `shiftL` (W# i#) = shiftLNatural x (I# (word2Int# i#))+   x `shiftR` (W# i#) = shiftRNatural x (I# (word2Int# i#))++   uncheckedShiftL = shiftL+   uncheckedShiftR = shiftR
+ src/lib/Haskus/Binary/Buffer.hs view
@@ -0,0 +1,353 @@+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE TypeApplications #-}++-- | A memory buffer with a fixed address+--+-- A buffer is a strict ByteString but with:+--+--   * a better interface: use Word instead of Int for sizes+--   * a better name: "string" is misleading+--   * some additional primitives+module Haskus.Binary.Buffer+   ( Buffer (..)+   , withBufferPtr+   , bufferSize+   , isBufferEmpty+   , emptyBuffer+   , bufferZero+   , bufferMap+   , bufferReverse+   , bufferDrop+   , bufferTail+   , bufferAppend+   , bufferCons+   , bufferSnoc+   , bufferInit+   , bufferSplitOn+   , bufferHead+   , bufferIndex+   , bufferTake+   , bufferTakeWhile+   , bufferTakeAtMost+   , bufferZipWith+   , bufferDup+   -- * Peek / Poke+   , bufferPeekStorable+   , bufferPeekStorableAt+   , bufferPopStorable+   , bufferPoke+   -- * Packing / Unpacking+   , bufferPackByteString+   , bufferPackByteList+   , bufferPackStorable+   , bufferPackStorableList+   , bufferPackPtr+   , bufferUnpackByteList+   , bufferUnpackByteString+   -- * Unsafe+   , bufferUnsafeDrop+   , bufferUnsafeTake+   , bufferUnsafeTail+   , bufferUnsafeHead+   , bufferUnsafeLast+   , bufferUnsafeInit+   , bufferUnsafeIndex+   , bufferUnsafeMapMemory+   , bufferUnsafeUsePtr+   , bufferUnsafePackPtr+   -- * IO+   , bufferReadFile+   , bufferWriteFile+   )+where++import Prelude hiding (length)++import System.IO.Unsafe+import Data.ByteString (ByteString)+import qualified Data.ByteString as BS+import qualified Data.ByteString.Unsafe as BS+import Foreign.Ptr+import Foreign.Marshal.Alloc (mallocBytes)++import Haskus.Number.Word+import Haskus.Binary.Storable+import Haskus.Binary.Bits.Helper+import Haskus.Binary.Bits.Bitwise+import Haskus.Binary.Bits.Index+import Haskus.Binary.Bits.Shift+import Haskus.Memory.Utils (memCopy,memSet)+import Haskus.Utils.List as List+import Haskus.Utils.Flow++-- | A buffer+newtype Buffer = Buffer ByteString deriving (Eq,Ord)++instance Show Buffer where+   show b = concatMap bToHex (bufferUnpackByteList b)+      where+         bToHex x = toHex (x `shiftR` 4) ++ toHex (x .&. 0x0F)+         toHex 0xA = "A"+         toHex 0xB = "B"+         toHex 0xC = "C"+         toHex 0xD = "D"+         toHex 0xE = "E"+         toHex 0xF = "F"+         toHex x   = show x++instance Bitwise Buffer where+   (.&.)      = bufferZipWith (.&.)+   (.|.)      = bufferZipWith (.|.)+   xor        = bufferZipWith xor++instance IndexableBits Buffer where+   bit i = bufferPackByteList +         (bit r : List.replicate (fromIntegral n) 0)+      where+         n = byteOffset i+         r = bitOffset i+   +   testBit b i = testBit p r+      where+         p = bufferIndex b (bufferSize b - n)+         n = byteOffset i+         r = bitOffset i++   setBit   = error "Can't set Buffer bit"+   clearBit = error "Can't clear Buffer bit"++   popCount b  = sum (fmap popCount (bufferUnpackByteList b))++++-- | Duplicate a buffer+bufferDup :: Buffer -> IO Buffer+bufferDup b = withBufferPtr b $ bufferPackPtr (bufferSize b)++-- | Buffer filled with zero+bufferZero :: Word -> Buffer+bufferZero n = unsafePerformIO $ do+   p <- mallocBytes (fromIntegral n)+   memSet p (fromIntegral n) 0+   bufferUnsafePackPtr n p++-- | Zip two buffers with the given function+bufferZipWith :: (Word8 -> Word8 -> Word8) -> Buffer -> Buffer -> Buffer+bufferZipWith f a b+      | bufferSize a /= bufferSize b = error "Non matching buffer sizes"+      | otherwise = unsafePerformIO $ do+            let sz = fromIntegral (bufferSize a)+            pc <- mallocBytes sz+            withBufferPtr a $ \pa ->+               withBufferPtr b $ \pb ->+                  forM_ [0..fromIntegral sz-1] $ \off -> do+                     v <- f <$> peekByteOff pa off+                            <*> peekByteOff pb off+                     pokeByteOff pc off (v :: Word8)+            bufferUnsafePackPtr (bufferSize a) pc++-- | Unsafe: be careful if you modify the buffer contents or you may break+-- referential transparency+withBufferPtr :: Buffer -> (Ptr b -> IO a) -> IO a+withBufferPtr (Buffer bs) f = BS.unsafeUseAsCString bs (f . castPtr)++-- | Test if the buffer is empty+isBufferEmpty :: Buffer -> Bool+isBufferEmpty (Buffer bs) = BS.null bs++-- | Empty buffer+emptyBuffer :: Buffer+emptyBuffer = Buffer BS.empty++-- | Buffer size+bufferSize :: Buffer -> Word+bufferSize (Buffer bs) = +      if s < 0+         then error "ByteString with size < 0"+         else fromIntegral s+   where+      s = BS.length bs++-- | Peek a storable+bufferPeekStorable :: forall a. Storable a => Buffer -> a+bufferPeekStorable = snd . bufferPopStorable++-- | Peek a storable at the given offset+bufferPeekStorableAt :: forall a.+   ( Storable a+   )+   => Buffer -> Word -> a+bufferPeekStorableAt b n+   | n + sizeOfT' @a > bufferSize b = error "Invalid buffer index"+   | otherwise                      = unsafePerformIO $ withBufferPtr b $ \p ->+                                        peekByteOff p (fromIntegral n)+   ++-- | Pop a Storable and return the new buffer+bufferPopStorable :: forall a. Storable a => Buffer -> (Buffer,a)+bufferPopStorable buf+   | bufferSize buf < sza = error "bufferRead: out of bounds"+   | otherwise            = unsafePerformIO $ do+         a <- withBufferPtr buf peek+         return (bufferDrop sza buf, a)+   where+      sza = sizeOfT' @a++-- | Poke a buffer+bufferPoke :: Ptr a -> Buffer -> IO ()+bufferPoke dest b = bufferUnsafeUsePtr b $ \src sz ->+   memCopy dest src (fromIntegral sz)++-- | Map+bufferMap :: (Word8 -> Word8) -> Buffer -> Buffer+bufferMap f (Buffer bs) = Buffer (BS.map f bs)++-- | Reverse+bufferReverse :: Buffer -> Buffer+bufferReverse (Buffer bs) = Buffer (BS.reverse bs)++-- | Drop some bytes O(1)+bufferDrop :: Word -> Buffer -> Buffer+bufferDrop n (Buffer bs) = Buffer $ BS.drop (fromIntegral n) bs++-- | Split on the given Byte values+bufferSplitOn :: Word8 -> Buffer -> [Buffer]+bufferSplitOn n (Buffer bs) = fmap Buffer (BS.split n bs)++-- | Tail+bufferTail :: Buffer -> Buffer+bufferTail (Buffer bs) = Buffer $ BS.tail bs++-- | Append+bufferAppend :: Buffer -> Buffer -> Buffer+bufferAppend (Buffer a) (Buffer b) = Buffer $ BS.append a b++-- | Cons+bufferCons :: Word8 -> Buffer -> Buffer+bufferCons w (Buffer bs) = Buffer $ BS.cons w bs++-- | Snoc+bufferSnoc :: Buffer -> Word8 -> Buffer+bufferSnoc (Buffer bs) w = Buffer $ BS.snoc bs w+++-- | Init+bufferInit :: Buffer -> Buffer+bufferInit (Buffer bs) = Buffer $ BS.init bs++-- | Head+bufferHead :: Buffer -> Word8+{-# INLINABLE bufferHead #-}+bufferHead (Buffer bs) = BS.head bs++-- | Index+bufferIndex :: Buffer -> Word -> Word8+{-# INLINABLE bufferIndex #-}+bufferIndex (Buffer bs) n = BS.index bs (fromIntegral n)++-- | Unpack+bufferUnpackByteList :: Buffer -> [Word8]+bufferUnpackByteList (Buffer bs) = BS.unpack bs++-- | Unpack+bufferUnpackByteString :: Buffer -> ByteString+bufferUnpackByteString (Buffer bs) = bs++-- | Take some bytes O(1)+bufferTake :: Word -> Buffer -> Buffer+bufferTake n (Buffer bs) = Buffer $ BS.take (fromIntegral n) bs++-- | Take some bytes O(n)+bufferTakeWhile :: (Word8 -> Bool) -> Buffer -> Buffer+bufferTakeWhile f (Buffer bs) = Buffer $ BS.takeWhile f bs++-- | Take some bytes O(1)+bufferTakeAtMost :: Word -> Buffer -> Buffer+bufferTakeAtMost n buf+   | bufferSize buf < n = buf+   | otherwise          = bufferTake n buf+++-- | Pack a ByteString+bufferPackByteString :: BS.ByteString -> Buffer+bufferPackByteString = Buffer++-- | Pack a list of bytes+bufferPackByteList :: [Word8] -> Buffer+bufferPackByteList = Buffer . BS.pack++-- | Pack a Storable+bufferPackStorable :: forall a. Storable a => a -> Buffer+bufferPackStorable x = Buffer $ unsafePerformIO $ do+   p <- malloc+   poke p x+   BS.unsafePackMallocCStringLen (castPtr p, sizeOfT' @a)++-- | Pack a list of Storable+bufferPackStorableList :: forall a. Storable a => [a] -> Buffer+bufferPackStorableList xs = Buffer $ unsafePerformIO $ do+   let lxs = length xs+   p <- mallocArray lxs+   forM_ (xs `zip` [0..]) $ \(x,o) ->+      pokeElemOff p o x+   BS.unsafePackMallocCStringLen (castPtr p, sizeOfT' @a * fromIntegral lxs)++-- | Pack from a pointer (copy)+bufferPackPtr :: MonadIO m => Word -> Ptr () -> m Buffer+bufferPackPtr sz ptr = do+   p <- liftIO (mallocBytes (fromIntegral sz))+   memCopy p ptr (fromIntegral sz)+   bufferUnsafePackPtr sz p++-- | Pack from a pointer (add finalizer)+bufferUnsafePackPtr :: MonadIO m => Word -> Ptr a -> m Buffer+bufferUnsafePackPtr sz p =+   Buffer <$> liftIO (BS.unsafePackMallocCStringLen (castPtr p, fromIntegral sz))++-- | Unsafe drop (don't check the size)+bufferUnsafeDrop :: Word -> Buffer -> Buffer+bufferUnsafeDrop n (Buffer bs) = Buffer (BS.unsafeDrop (fromIntegral n) bs)++-- | Unsafe take (don't check the size)+bufferUnsafeTake :: Word -> Buffer -> Buffer+bufferUnsafeTake n (Buffer bs) = Buffer (BS.unsafeTake (fromIntegral n) bs)++-- | Unsafe tail (don't check the size)+bufferUnsafeTail :: Buffer -> Buffer+bufferUnsafeTail (Buffer bs) = Buffer (BS.unsafeTail bs)++-- | Unsafe head (don't check the size)+bufferUnsafeHead :: Buffer -> Word8+bufferUnsafeHead (Buffer bs) = BS.unsafeHead bs++-- | Unsafe last (don't check the size)+bufferUnsafeLast :: Buffer -> Word8+bufferUnsafeLast (Buffer bs) = BS.unsafeLast bs++-- | Unsafe init (don't check the size)+bufferUnsafeInit :: Buffer -> Buffer+bufferUnsafeInit (Buffer bs) = Buffer (BS.unsafeInit bs)++-- | Unsafe index (don't check the size)+bufferUnsafeIndex :: Buffer -> Word -> Word8+bufferUnsafeIndex (Buffer bs) n = BS.unsafeIndex bs (fromIntegral n)++-- | Map memory+bufferUnsafeMapMemory :: MonadIO m => Word -> Ptr () -> m Buffer+bufferUnsafeMapMemory sz ptr =+   Buffer <$> liftIO (BS.unsafePackCStringLen (castPtr ptr, fromIntegral sz))++-- | Use buffer pointer+bufferUnsafeUsePtr :: MonadInIO m => Buffer -> (Ptr () -> Word -> m a) -> m a+bufferUnsafeUsePtr bu@(Buffer b) f =+   liftWith (BS.unsafeUseAsCString b) $ \p ->+      f (castPtr p) (bufferSize bu)++-- | Read file+bufferReadFile :: MonadIO m => FilePath -> m Buffer+bufferReadFile path = Buffer <$> liftIO (BS.readFile path)++-- | Write file+bufferWriteFile :: MonadIO m => FilePath -> Buffer -> m ()+bufferWriteFile path (Buffer bs) = liftIO (BS.writeFile path bs)
+ src/lib/Haskus/Binary/BufferBuilder.hs view
@@ -0,0 +1,47 @@+{-# LANGUAGE StandaloneDeriving #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}++-- | Buffer builder+module Haskus.Binary.BufferBuilder+   ( BufferBuilder+   , emptyBufferBuilder+   , toBufferList+   , toBuffer+   , fromBuffer+   , fromWord8+   )+where++import qualified Data.ByteString.Builder as B++import Haskus.Number.Word+import Haskus.Binary.Buffer+import qualified Haskus.Binary.BufferList as BL++-- | Buffer builder+newtype BufferBuilder+   = BufferBuilder B.Builder+   deriving (Semigroup,Monoid)++-- | Empty buffer builder+emptyBufferBuilder :: BufferBuilder+emptyBufferBuilder = BufferBuilder mempty++-- | Create a Builder denoting the same sequence of bytes as a strict+-- ByteString. The Builder inserts large ByteStrings directly, but copies small+-- ones to ensure that the generated chunks are large on average.+fromBuffer :: Buffer -> BufferBuilder+fromBuffer (Buffer bs) = BufferBuilder (B.byteString bs)++-- | Encode a single unsigned byte as-is.+fromWord8 :: Word8 -> BufferBuilder+fromWord8 w = BufferBuilder (B.word8 w)++-- | Execute a Builder and return the generated chunks as a BufferList. The work+-- is performed lazily, i.e., only when a chunk of the BufferList is forced.+toBufferList :: BufferBuilder -> BL.BufferList+toBufferList (BufferBuilder b) = BL.BufferList (B.toLazyByteString b)++-- | Execute a Builder and return the generated chunks as a Buffer.+toBuffer :: BufferBuilder -> Buffer+toBuffer = BL.toBuffer . toBufferList
+ src/lib/Haskus/Binary/BufferList.hs view
@@ -0,0 +1,29 @@+-- | Buffer list+--+-- BufferList is a lazy ByteString+module Haskus.Binary.BufferList+   ( BufferList (..)+   , toBuffer+   , toBufferList+   , toLazyByteString+   )+where++import qualified Data.ByteString.Lazy as LBS++import Haskus.Binary.Buffer++-- | BufferList+newtype BufferList = BufferList LBS.ByteString++-- | Convert to a buffer+toBuffer :: BufferList -> Buffer+toBuffer (BufferList b) = Buffer (LBS.toStrict b)++-- | Convert from a buffer+toBufferList :: Buffer -> BufferList+toBufferList (Buffer b) = BufferList (LBS.fromStrict b)++-- | Convert to a lazy ByteString+toLazyByteString :: BufferList -> LBS.ByteString+toLazyByteString (BufferList b) = b
+ src/lib/Haskus/Binary/CTypes.hs view
@@ -0,0 +1,13 @@+-- | Some C types+module Haskus.Binary.CTypes+   ( CSize(..)+   , CUShort+   , CShort+   , CUInt+   , CInt+   , CULong+   , CLong+   )+where++import Foreign.C.Types
+ src/lib/Haskus/Binary/Char.hs view
@@ -0,0 +1,15 @@+{-# LANGUAGE GeneralizedNewtypeDeriving #-}++-- | Character+module Haskus.Binary.Char+   ( Char8 (..)+   )+where++import Haskus.Number.Word+import Haskus.Binary.Storable++-- | 8-bit character (ASCII, etc.)+newtype Char8+   = Char8 Word8+   deriving (Show,Eq,Ord,Storable)
+ src/lib/Haskus/Binary/Endianness.hs view
@@ -0,0 +1,222 @@+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE FlexibleContexts #-}++-- | Byte order ("endianness")+--+-- Indicate in which order bytes are stored in memory for multi-bytes types.+-- Big-endian means that most-significant bytes come first. Little-endian means+-- that least-significant bytes come first.+module Haskus.Binary.Endianness+   ( Endianness(..)+   , WordGetters (..)+   , WordPutters (..)+   , getWordGetters+   , getWordPutters+   , WordSize (..)+   , ExtendedWordGetters (..)+   , ExtendedWordPutters (..)+   , getExtendedWordGetters+   , getExtendedWordPutters+   , getHostEndianness+   , hostEndianness+   , ByteReversable (..)+   , AsBigEndian (..)+   , AsLittleEndian (..)+   )+where++import Haskus.Binary.Get+import Haskus.Binary.Put+import Haskus.Binary.Enum+import Haskus.Binary.Storable+import Haskus.Number.Word+import Haskus.Binary.Bits++import System.IO.Unsafe+import Foreign.Ptr++-- | Endianness+data Endianness +   = LittleEndian    -- ^ Less significant bytes first+   | BigEndian       -- ^ Most significant bytes first+   deriving (Eq,Show,Enum)++instance CEnum Endianness++-- | Word getter+data WordGetters = WordGetters+   { wordGetter8  :: Get Word8   -- ^ Read a Word8+   , wordGetter16 :: Get Word16  -- ^ Read a Word16+   , wordGetter32 :: Get Word32  -- ^ Read a Word32+   , wordGetter64 :: Get Word64  -- ^ Read a Word64+   }++-- | Word putters+data WordPutters = WordPutters+   { wordPutter8  :: Word8  -> Put -- ^ Write a Word8+   , wordPutter16 :: Word16 -> Put -- ^ Write a Word16+   , wordPutter32 :: Word32 -> Put -- ^ Write a Word32+   , wordPutter64 :: Word64 -> Put -- ^ Write a Word64+   }++-- | Get getters for the given endianness+getWordGetters :: Endianness -> WordGetters+getWordGetters e = case e of+   LittleEndian -> WordGetters getWord8 getWord16le getWord32le getWord64le+   BigEndian    -> WordGetters getWord8 getWord16be getWord32be getWord64be++-- | Get putters for the given endianness+getWordPutters :: Endianness -> WordPutters+getWordPutters e = case e of+   LittleEndian -> WordPutters putWord8 putWord16le putWord32le putWord64le+   BigEndian    -> WordPutters putWord8 putWord16be putWord32be putWord64be++++-- | Size of a machine word+data WordSize+   = WordSize32      -- ^ 32-bit+   | WordSize64      -- ^ 64-bit+   deriving (Show, Eq)++-- | Extended word getters+data ExtendedWordGetters = ExtendedWordGetters+   { extwordGetter8  :: Get Word8   -- ^ Read a Word8+   , extwordGetter16 :: Get Word16  -- ^ Read a Word16+   , extwordGetter32 :: Get Word32  -- ^ Read a Word32+   , extwordGetter64 :: Get Word64  -- ^ Read a Word64+   , extwordGetterN  :: Get Word64  -- ^ Read a native size word into a Word64+   }++-- | Extended word putters+data ExtendedWordPutters = ExtendedWordPutters+   { extwordPutter8  :: Word8  -> Put -- ^ Write a Word8+   , extwordPutter16 :: Word16 -> Put -- ^ Write a Word16+   , extwordPutter32 :: Word32 -> Put -- ^ Write a Word32+   , extwordPutter64 :: Word64 -> Put -- ^ Write a Word64+   , extwordPutterN  :: Word64 -> Put -- ^ Write a Word64 into a native size word+   }++-- | Return extended getters+getExtendedWordGetters :: Endianness -> WordSize -> ExtendedWordGetters+getExtendedWordGetters endian ws = ExtendedWordGetters gw8 gw16 gw32 gw64 gwN+   where+      WordGetters gw8 gw16 gw32 gw64 = getWordGetters endian+      gwN = case ws of+         WordSize64 -> gw64+         WordSize32 -> fromIntegral <$> gw32++-- | Return extended putters+getExtendedWordPutters :: Endianness -> WordSize -> ExtendedWordPutters+getExtendedWordPutters endian ws = ExtendedWordPutters pw8 pw16 pw32 pw64 pwN+   where+      WordPutters pw8 pw16 pw32 pw64 = getWordPutters endian+      pwN x = case ws of+         WordSize64 -> pw64 x+         WordSize32 -> if x > 0xffffffff+            then error $ "Number too big to be stored in 32-bit word ("++show x++")"+            else pw32 (fromIntegral x)++-- | Detect the endianness of the host memory+getHostEndianness :: IO Endianness+getHostEndianness = do+   -- Write a 32 bit word and check byte ordering+   let magic = 0x01020304 :: Word32+   alloca $ \p -> do+      poke p magic+      rs <- peekArray 4 (castPtr p :: Ptr Word8)+      return $ if rs == [1,2,3,4] then BigEndian else LittleEndian++-- | Detected host endianness+--+-- TODO: use targetByteOrder in GHC.ByteOrder (should be introduced in GHC 8.4)+hostEndianness :: Endianness+{-# NOINLINE hostEndianness #-}+hostEndianness = unsafePerformIO getHostEndianness++-- | Reverse bytes in a word+class ByteReversable w where+   reverseBytes       :: w -> w++   hostToBigEndian    :: w -> w+   hostToBigEndian w = case hostEndianness of+      BigEndian    -> w+      LittleEndian -> reverseBytes w++   bigEndianToHost    :: w -> w+   bigEndianToHost w = case hostEndianness of+      BigEndian    -> w+      LittleEndian -> reverseBytes w+++   hostToLittleEndian :: w -> w+   hostToLittleEndian w = case hostEndianness of+      BigEndian    -> reverseBytes w+      LittleEndian -> w++   littleEndianToHost :: w -> w+   littleEndianToHost w = case hostEndianness of+      BigEndian    -> reverseBytes w+      LittleEndian -> w++instance ByteReversable Word8 where+   reverseBytes = id++instance ByteReversable Word16 where+   reverseBytes = byteSwap16+                  +instance ByteReversable Word32 where+   reverseBytes = byteSwap32++instance ByteReversable Word64 where+   reverseBytes = byteSwap64++++-- | Force a data to be read/stored as big-endian+newtype AsBigEndian a+   = AsBigEndian a+   deriving (Eq,Ord,Enum,Num,Integral,Real,Bitwise,FiniteBits,ReversableBits,RotatableBits,ShiftableBits,IndexableBits)++instance Show a => Show (AsBigEndian a) where+   show (AsBigEndian a) = show a++-- | Force a data to be read/stored as little-endian+newtype AsLittleEndian a+   = AsLittleEndian a+   deriving (Eq,Ord,Enum,Num,Integral,Real,Bitwise,FiniteBits,ReversableBits,RotatableBits,ShiftableBits,IndexableBits)++instance Show a => Show (AsLittleEndian a) where+   show (AsLittleEndian a) = show a++instance (ByteReversable a, StaticStorable a) => StaticStorable (AsBigEndian a) where+   type SizeOf (AsBigEndian a)    = SizeOf a+   type Alignment (AsBigEndian a) = Alignment a++   staticPeekIO ptr                 = AsBigEndian . bigEndianToHost <$> staticPeek (castPtr ptr)+   staticPokeIO ptr (AsBigEndian v) = staticPoke (castPtr ptr) (hostToBigEndian v)+++instance (ByteReversable a, Storable a) => Storable (AsBigEndian a) where+   sizeOf _    = sizeOfT    @a+   alignment _ = alignmentT @a++   peekIO ptr                 = AsBigEndian . bigEndianToHost <$> peek (castPtr ptr)+   pokeIO ptr (AsBigEndian v) = poke (castPtr ptr) (hostToBigEndian v)++instance (ByteReversable a, StaticStorable a) => StaticStorable (AsLittleEndian a) where+   type SizeOf (AsLittleEndian a)    = SizeOf a+   type Alignment (AsLittleEndian a) = Alignment a++   staticPeekIO ptr                    = AsLittleEndian . bigEndianToHost <$> staticPeekIO (castPtr ptr)+   staticPokeIO ptr (AsLittleEndian v) = staticPokeIO (castPtr ptr) (hostToLittleEndian v)++instance (ByteReversable a, Storable a) => Storable (AsLittleEndian a) where+   sizeOf _    = sizeOfT    @a+   alignment _ = alignmentT @a++   peekIO ptr                    = AsLittleEndian . bigEndianToHost <$> peek (castPtr ptr)+   pokeIO ptr (AsLittleEndian v) = poke (castPtr ptr) (hostToLittleEndian v)
+ src/lib/Haskus/Binary/Enum.hs view
@@ -0,0 +1,144 @@+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE DefaultSignatures #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE MagicHash #-}++-- | Store an Enum in the given backing word type+module Haskus.Binary.Enum+   ( EnumField+   , CEnum (..)+   , fromEnumField+   , toEnumField+   , makeEnum+   , makeEnumMaybe+   , makeEnumWithCustom+   , dataToTag+   )+where++import Haskus.Binary.Storable++import Foreign.Ptr+import Data.Data+import GHC.Prim+import GHC.Int++-----------------------------------------------------------------------------+-- EnumField b a: directly store the value of enum "a" as a "b"+-----------------------------------------------------------------------------++-- | Store enum `a` as a `b`+newtype EnumField b a+   = EnumField b+   deriving (Show,Eq,Storable)++instance+      ( Integral b+      , StaticStorable b+      , CEnum a+      ) => StaticStorable (EnumField b a)+   where+      type SizeOf (EnumField b a)    = SizeOf b+      type Alignment (EnumField b a) = Alignment b+      staticPeekIO p                 = EnumField  <$> staticPeek (castPtr p :: Ptr b)+      staticPokeIO p (EnumField v)   = staticPoke (castPtr p :: Ptr b) v++-- | Read an enum field+fromEnumField :: (CEnum a, Integral b) => EnumField b a -> a+{-# INLINABLE fromEnumField #-}+fromEnumField (EnumField b) = toCEnum b++-- | Create an enum field+toEnumField :: (CEnum a, Integral b) => a -> EnumField b a+{-# INLINABLE toEnumField #-}+toEnumField = EnumField . fromCEnum+++-----------------------------------------------------------------------------+-- Extended Enum+-----------------------------------------------------------------------------++-- | Extended Enum+--+-- By default, use dataToTag and toEnum to convert from and to an Integral.+--+-- But it can be overloaded to perform transformation before using+-- fromEnum/toEnum. E.g. if values are shifted by 1 compared to Enum values,+-- define fromCEnum = (+1) . fromIntegral . dataToTag+--+class CEnum a where+   fromCEnum       :: Integral b => a -> b+   fromCEnum       = fromIntegral . dataToTag++   toCEnum         :: Integral b => b -> a+   default toCEnum :: (Enum a, Integral b) => b -> a+   toCEnum         = toEnum . fromIntegral++-- | Make an enum with the last constructor taking a parameter for the rest of+-- the range+--+-- @+-- data T = A | B | C | D Word8+--+-- makeEnumWithCustom :: Int -> T+-- makeEnumWithCustom x = case x of+--    0 -> A+--    1 -> B+--    2 -> C+--    n -> D (n - 3)+-- @+--+makeEnumWithCustom :: forall a i. (Data a,Integral i) => i -> a+{-# INLINABLE makeEnumWithCustom #-}+makeEnumWithCustom x =+   if x' < maxConstrIndex t+      then fromConstr (indexConstr t x')+      else fromConstrB (fromConstr (toConstr (x' - m)))+               (indexConstr t m)+   where+      m   = maxConstrIndex t+      x'  = fromIntegral x + 1+      t   = dataTypeOf (undefined :: a)++-- | Make an enum with the last constructor taking a parameter for the rest of+-- the range, but don't build the last constructor+--+-- @+-- data T = A | B | C | D Word8+--+-- makeEnumMaybe :: Int -> T+-- makeEnumMaybe x = case x of+--    0 -> Just A+--    1 -> Just B+--    2 -> Just C+--    n -> Nothing+-- @+--+makeEnumMaybe :: forall a i. (Data a,Integral i) => i -> Maybe a+{-# INLINABLE makeEnumMaybe #-}+makeEnumMaybe x =+   if x' < maxConstrIndex t+      then Just (fromConstr (indexConstr t x'))+      else Nothing+   where+      x'  = fromIntegral x + 1+      t   = dataTypeOf (undefined :: a)++-- | Make an enum from a number (0 indexed)+makeEnum :: forall a i. (Data a,Integral i) => i -> a+{-# INLINABLE makeEnum #-}+makeEnum x =fromConstr (indexConstr t x')+   where+      x'  = fromIntegral x + 1+      t   = dataTypeOf (undefined :: a)+++-- | Retrieve data tag+--+-- >>> data D = A | B | C+-- >>> dataToTag B+-- 1+dataToTag :: a -> Int+dataToTag a = I# (dataToTag# a)
+ src/lib/Haskus/Binary/Get.hs view
@@ -0,0 +1,237 @@+{-# lANGUAGE LambdaCase #-}++-- | Get utilities+module Haskus.Binary.Get+   ( Get+   , runGet+   , runGetOrFail+   -- * Size & alignment+   , isEmpty+   , remaining+   , skip+   , uncheckedSkip+   , skipAlign+   , uncheckedSkipAlign+   , countBytes+   , alignAfter+   -- * Isolation+   , consumeExactly+   , consumeAtMost+   -- * Look-ahead+   , lookAhead+   , lookAheadM+   , lookAheadE+   -- * Read+   , getRemaining+   , getBuffer+   , getBufferNul+   , getWord8+   , getWord16le+   , getWord16be+   , getWord32le+   , getWord32be+   , getWord64le+   , getWord64be+   -- * Utilities+   , getWhile+   , getWhole+   , getBitGet+   , getManyAtMost+   , getManyBounded+   )+where++import qualified Data.Serialize.Get as BG+import Data.Serialize.Get (Get)++import Haskus.Binary.Buffer+import Haskus.Number.Word+import Haskus.Binary.Bits.Order+import Haskus.Binary.Bits.Get (BitGet, runBitGetPartial, skipBitsToAlignOnWord8M, bitGetStateInput)+import Haskus.Utils.Maybe+++-- | Test whether all input *in the current chunk* has been consumed+isEmpty :: Get Bool+isEmpty = BG.isEmpty++-- | Get the number of remaining unparsed bytes *in the current chunk*+remaining :: Get Word+remaining = fromIntegral <$> BG.remaining++-- | Skip ahead n bytes. Fails if fewer than n bytes are available.+skip :: Word -> Get ()+skip = BG.skip . fromIntegral++-- | Skip ahead n bytes. No error if there isn't enough bytes.+uncheckedSkip :: Word -> Get ()+uncheckedSkip = BG.uncheckedSkip . fromIntegral++-- | Skip to align n to al. Fails if fewer than n bytes are available.+skipAlign :: Word -> Word -> Get ()+skipAlign n al = skip n'+   where+      n' = case n `mod` al of+               0 -> 0+               x -> al - fromIntegral x++-- | Skip to align n to al. Fails if fewer than n bytes are available.+uncheckedSkipAlign :: Word -> Word -> Get ()+uncheckedSkipAlign n al = uncheckedSkip n'+   where+      n' = case n `mod` al of+               0 -> 0+               x -> al - fromIntegral x++-- | Run the getter without consuming its input. Fails if it fails+lookAhead :: Get a -> Get a+lookAhead = BG.lookAhead++-- | Run the getter. Consume its input if Just _ returned. Fails if it fails+lookAheadM :: Get (Maybe a) -> Get (Maybe a)+lookAheadM = BG.lookAheadM++-- | Run the getter. Consume its input if Right _ returned. Fails if it fails+lookAheadE :: Get (Either a b) -> Get (Either a b)+lookAheadE = BG.lookAheadE++-- | Require an action to consume exactly the given number of bytes, fail+-- otherwise+consumeExactly :: Word -> Get a -> Get a+consumeExactly sz = BG.isolate (fromIntegral sz)++-- | Require an action to consume at most the given number of bytes, fail+-- otherwise+consumeAtMost :: Word -> Get a -> Get a+consumeAtMost sz f = do+   sz' <- remaining+   (r,res) <- BG.lookAhead $ BG.isolate (fromIntegral (min sz sz')) $ do+      res <- f+      r <- remaining+      skip r -- skip remaining bytes, to make isolate happy+      return (r,res)+   skip (min sz' sz - r)+   return res++-- | Pull n bytes from the input, as a Buffer+getBuffer :: Word -> Get Buffer+getBuffer sz = Buffer <$> BG.getBytes (fromIntegral sz)++-- | Get Word8+getWord8 :: Get Word8+getWord8 = BG.getWord8++-- | Get Word16 little-endian+getWord16le :: Get Word16+getWord16le = BG.getWord16le++-- | Get Word16 big-endian+getWord16be :: Get Word16+getWord16be = BG.getWord16be++-- | Get Word32 little-endian+getWord32le :: Get Word32+getWord32le = BG.getWord32le++-- | Get Word32 big-endian+getWord32be :: Get Word32+getWord32be = BG.getWord32be++-- | Get Word64 little-endian+getWord64le :: Get Word64+getWord64le = BG.getWord64le++-- | Get Word64 big-endian+getWord64be :: Get Word64+getWord64be = BG.getWord64be++-- | Get while True (read and discard the ending element)+getWhile :: (a -> Bool) -> Get a -> Get [a]+getWhile cond getter = rec []+   where+      rec xs = do+         x <- getter+         if cond x+            then rec (x:xs)+            else return (reverse xs)++-- | Repeat the getter to read the whole bytestring+getWhole :: Get a -> Get [a]+getWhole getter = rec []+   where+      rec xs = do+         cond <- isEmpty+         if cond+            then return (reverse xs)+            else do+               x <- getter+               rec (x:xs)++-- | Get remaining bytes+getRemaining :: Get Buffer+getRemaining = do+   r <- remaining+   getBuffer r+++-- | Count the number of bytes consumed by a getter+countBytes :: Get a -> Get (Word, a)+countBytes g = do+   cnt0 <- remaining+   r <- g+   cnt1 <- remaining+   return (cnt0 - cnt1, r)++-- | Execute the getter and align on the given number of Word8+alignAfter :: Word -> Get a -> Get a+alignAfter alignment getter = do+   (cnt,r) <- countBytes getter+   uncheckedSkipAlign cnt alignment+   return r++-- | Get Buffer terminated with \0 (consume \0)+getBufferNul :: Get Buffer+getBufferNul = do+   bs <- lookAhead getRemaining+   let v = bufferTakeWhile (/= 0) bs+   uncheckedSkip (bufferSize v + 1)+   return v++-- | Run the Get monad+runGet :: Get a -> Buffer -> Either String a+runGet g (Buffer bs) = BG.runGet g bs++-- | Run a getter and throw an exception on error+runGetOrFail :: Get a -> Buffer -> a+runGetOrFail g bs = case runGet g bs of+   Left err -> error err+   Right x  -> x+++-- | Get bits from a BitGet. +--+-- Discard last bits to align on a Word8 boundary+--+-- FIXME: we use a continuation because Data.Serialize.Get doesn't export "put"+getBitGet :: BitOrder -> BitGet a -> (a -> Get b) -> Get b+getBitGet bo bg cont = do+   bs <- getRemaining+   let (v,s) = runBitGetPartial bo (bg <* skipBitsToAlignOnWord8M) bs+   return $ runGetOrFail (cont v) (bitGetStateInput s)++-- | Apply the getter at most 'max' times+getManyAtMost :: Word -> Get (Maybe a) -> Get [a]+getManyAtMost mx f = fromMaybe [] <$> getManyBounded Nothing (Just mx) f++-- | Apply the getter at least 'min' times and at most 'max' times+getManyBounded :: Maybe Word -> Maybe Word -> Get (Maybe a) -> Get (Maybe [a])+getManyBounded _ (Just 0) _  = return (Just [])+getManyBounded (Just 0) mx f = getManyBounded Nothing mx f+getManyBounded mn mx f       = lookAheadM $ f >>= \case+      Nothing -> case mn of+         Just n | n > 0 -> return Nothing+         _              -> return (Just [])+      Just x -> fmap (x:) <$> getManyBounded (minus1 mn) (minus1 mx) f+   where+      minus1 = fmap (\k -> k - 1)+
+ src/lib/Haskus/Binary/Put.hs view
@@ -0,0 +1,89 @@+-- | Put monad+--+-- FIXME: PutM uses slow ByteString builder... We need to replace it with a+-- fast one+module Haskus.Binary.Put+   ( Put+   , PutM+   , runPut+   , runPutM+   -- * Put+   , putBuffer+   , putByteString+   , putPadding+   , putPaddingAlign+   , putWord8+   , putWord16le+   , putWord16be+   , putWord32le+   , putWord32be+   , putWord64le+   , putWord64be+   )+where++import qualified Data.ByteString as BS+import qualified Data.Serialize.Put as BP+import Data.Serialize.Put (Put,PutM)+import Data.Bifunctor++import Haskus.Utils.Flow (replicateM_)+import Haskus.Binary.Buffer+import Haskus.Number.Word++-- | Execute Put+runPut :: Put -> Buffer+runPut = Buffer . BP.runPut++-- | Execute PutM+runPutM :: PutM a -> (a,Buffer)+runPutM = second Buffer . BP.runPutM+++-- | Put a buffer+putBuffer :: Buffer -> Put+putBuffer (Buffer bs) = BP.putByteString bs++-- | Put a ByteString+putByteString :: BS.ByteString -> Put+putByteString = BP.putByteString++-- | Put null bytes+putPadding :: Word -> Put+putPadding n = replicateM_ (fromIntegral n) (BP.putWord8 0x00)++-- | Put null bytes to align the given value to the second+putPaddingAlign :: Word -> Word -> Put+putPaddingAlign n al = putPadding n'+   where+      n' = case n `mod` al of+               0 -> 0+               x -> al - fromIntegral x++-- | Put a Word8+putWord8 :: Word8 -> Put+putWord8 = BP.putWord8++-- | Put a Word16 little-endian+putWord16le :: Word16 -> Put+putWord16le = BP.putWord16le++-- | Put a Word16 big-endian+putWord16be :: Word16 -> Put+putWord16be = BP.putWord16be++-- | Put a Word32 little-endian+putWord32le :: Word32 -> Put+putWord32le = BP.putWord32le++-- | Put a Word32 big-endian+putWord32be :: Word32 -> Put+putWord32be = BP.putWord32be++-- | Put a Word64 little-endian+putWord64le :: Word64 -> Put+putWord64le = BP.putWord64le++-- | Put a Word64 big-endian+putWord64be :: Word64 -> Put+putWord64be = BP.putWord64be
+ src/lib/Haskus/Binary/Record.hs view
@@ -0,0 +1,208 @@+{-# LANGUAGE KindSignatures #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE InstanceSigs #-}+{-# LANGUAGE ExistentialQuantification #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE AllowAmbiguousTypes #-}++-- | Record (similar to C struct)+module Haskus.Binary.Record+   ( Record+   , Field+   , RecordSize+   , Alignment+   , Path+   , recordSize+   , recordAlignment+   , recordField+   , recordFieldOffset+   , recordFieldPath+   , recordFieldPathOffset+   , recordToList+   )+where++import System.IO.Unsafe+import Foreign.ForeignPtr+import Foreign.Ptr++import Haskus.Memory.Utils+import Haskus.Binary.Storable+import Haskus.Utils.HList+import Haskus.Utils.Types++-- | Record+newtype Record (fields :: [*]) = Record (ForeignPtr ())++-- | Field+data Field (name :: Symbol) typ++-- | Get record size without the ending padding bytes+type family RecordSize (fs :: [*]) (sz :: Nat) where+   RecordSize '[] sz                    = sz+   RecordSize (Field name typ ': fs) sz = +      RecordSize fs+         (sz+         -- padding bytes+         + Padding sz typ+         -- field size+         + SizeOf typ+         )++type family FieldOffset (name :: Symbol) (fs :: [*]) (sz :: Nat) where+   -- Found+   FieldOffset name (Field name typ ': fs) sz =+      sz + Padding sz typ+   -- Not found yet+   FieldOffset name (Field xx typ ': fs) sz =+      FieldOffset name fs+         (sz + Padding sz typ + SizeOf typ)++type family FieldType (name :: Symbol) (fs :: [*]) where+   FieldType name (Field name typ ': fs) = typ+   FieldType name (Field xx typ ': fs)   = FieldType name fs++-- | Record size (with ending padding bytes)+type family FullRecordSize fs where+   FullRecordSize fs =+      RecordSize fs 0+      + PaddingEx (Mod (RecordSize fs 0) (RecordAlignment fs 1))+         (RecordAlignment fs 1)++-- | Record alignment+type family RecordAlignment (fs :: [*]) a where+   RecordAlignment '[]                    a = a+   RecordAlignment (Field name typ ': fs) a =+      RecordAlignment fs+         (If (a <=? Alignment typ) (Alignment typ) a)++-- | Return offset from a field path+type family FieldPathOffset (fs :: [*]) (path :: [Symbol]) (off :: Nat) where+   FieldPathOffset fs '[p] off = off + FieldOffset p fs 0+   FieldPathOffset fs (p ': ps) off+      = FieldPathOffset (ExtractRecord (FieldType p fs))+            ps (off + FieldOffset p fs 0)++-- | Return type from a field path+type family FieldPathType (fs :: [*]) (path :: [Symbol]) where+   FieldPathType fs '[p] = FieldType p fs++   FieldPathType fs (p ': ps)+      = FieldPathType (ExtractRecord (FieldType p fs)) ps+   +type family ExtractRecord x where+   ExtractRecord (Record fs) = fs++-- | Get record size+recordSize :: forall fs.+   ( KnownNat (FullRecordSize fs)+   ) => Record fs -> Word+recordSize _ = natValue' @(FullRecordSize fs)++-- | Get record alignment+recordAlignment :: forall fs.+   ( KnownNat (RecordAlignment fs 1)+   ) => Record fs -> Word+recordAlignment _ = natValue' @(RecordAlignment fs 1)++-- | Get a field offset+recordFieldOffset :: forall (name :: Symbol) fs.+   ( KnownNat (FieldOffset name fs 0)+   ) => Record fs -> Int+recordFieldOffset _ = natValue @(FieldOffset name fs 0)++-- | Get a field+recordField :: forall (name :: Symbol) a fs.+   ( KnownNat (FieldOffset name fs 0)+   , a ~ FieldType name fs+   , StaticStorable a+   ) => Record fs -> a+recordField r@(Record fp) = unsafePerformIO $+   withForeignPtr fp $ \ptr ->do+      let ptr' = ptr `plusPtr` recordFieldOffset @name r+      staticPeek (castPtr ptr')++data Path (fs :: [Symbol])++-- | Get a field offset from its path+recordFieldPathOffset :: forall path fs o.+   ( o ~ FieldPathOffset fs path 0+   , KnownNat o+   ) => Path path -> Record fs -> Int+recordFieldPathOffset _ _ = natValue @o++-- | Get a field from its path+recordFieldPath :: forall path a fs o.+   ( o ~ FieldPathOffset fs path 0+   , a ~ FieldPathType fs path+   , KnownNat o+   , StaticStorable a+   ) => Path path -> Record fs -> a+recordFieldPath _ (Record fp) = unsafePerformIO $+   withForeignPtr fp $ \ptr -> do+      let+         ptr' = ptr `plusPtr` natValue @o+      staticPeek (castPtr ptr')+++instance forall fs s.+      ( s ~ FullRecordSize fs+      , KnownNat s+      )+      => StaticStorable (Record fs)+   where+      type SizeOf (Record fs)    = FullRecordSize fs+      type Alignment (Record fs) = RecordAlignment fs 1++      staticPeekIO ptr = do+         let sz = recordSize (undefined :: Record fs)+         fp <- mallocForeignPtrBytes (fromIntegral sz)+         withForeignPtr fp $ \p ->+            memCopy p ptr (fromIntegral sz)+         return (Record fp)++      staticPokeIO ptr (Record fp) = do+         let sz = recordSize (undefined :: Record fs)+         withForeignPtr fp $ \p ->+            memCopy ptr p (fromIntegral sz)+++data Extract = Extract++instance forall fs typ name rec b l2 i r.+   ( rec ~ Record fs                        -- the record+   , b ~ Field name typ                     -- the current field+   , i ~ (rec, HList l2)                    -- input type+   , typ ~ FieldType name fs+   , KnownNat (FieldOffset name fs 0)+   , StaticStorable typ+   , KnownSymbol name+   , r ~ (rec, HList ((String,typ) ': l2))  -- result type+   ) => Apply Extract (b, i) r where+      apply _ (_, (rec,xs)) =+         (rec, HCons (symbolValue @name, recordField @name rec) xs)++-- | Convert a record into a HList+recordToList :: forall fs.+   ( HFoldr' Extract (Record fs, HList '[]) fs (Record fs, HList fs)+   ) => Record fs -> HList fs+recordToList rec = snd res+   where+      res :: (Record fs, HList fs)+      res = hFoldr' Extract ((rec,HNil) :: (Record fs, HList '[])) (undefined :: HList fs)+++instance forall fs.+      ( HFoldr' Extract (Record fs, HList '[]) fs (Record fs, HList fs)+      , Show (HList fs)+      )+      => Show (Record fs)+   where+      show rec = show (recordToList rec :: HList fs)
+ src/lib/Haskus/Binary/Serialize.hs view
@@ -0,0 +1,135 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE TypeSynonymInstances #-}+{-# LANGUAGE ScopedTypeVariables #-}++-- | Binary serialization of Haskell values+module Haskus.Binary.Serialize+   ( Serializable (..)+   , Size (..)+   )+where++import Haskus.Binary.Serialize.Put+import Haskus.Binary.Serialize.Size+import Haskus.Binary.Serialize.Get+import Haskus.Number.Word+import Haskus.Number.Int+import Haskus.Binary.Endianness+import Haskus.Utils.Types++-- | Size in bytes+data Size+   = Exactly Nat   -- ^ Exactly the given size+   | Dynamic       -- ^ Dynamically known size (the size is stored with the object)++-- | Binary serializable data+class Serializable a where++   -- | Size of the data in bytes+   type SizeOf a :: Size++   -- | Sensible to endianness+   type Endian a :: Bool++   -- | Dynamic size of the data in bytes+   --+   -- The default implementation execute the put method with a PutMonad that+   -- only stores the size in bytes. Overload this function if possible!+   sizeOf :: a -> Word+   sizeOf a = runGetSize (put LittleEndian a)++   -- | Serialize a value+   put :: PutMonad m => Endianness -> a -> m ()++   -- | Deserialize a value+   get :: GetMonad m => Endianness -> m a++--------------------------------------------+-- Instances+--------------------------------------------++instance Serializable Word8 where+   type SizeOf Word8  = 'Exactly 1+   type Endian Word8  = 'False+   sizeOf _           = 1+   put _ x            = putWord8 x+   get _              = getWord8++instance Serializable Word16 where+   type SizeOf Word16 = 'Exactly 2+   type Endian Word16 = 'True+   sizeOf _           = 2+   put LittleEndian x = putWord16LE x+   put BigEndian    x = putWord16BE x+   get LittleEndian   = getWord16LE+   get BigEndian      = getWord16BE++instance Serializable Word32 where+   type SizeOf Word32 = 'Exactly 4+   type Endian Word32 = 'True+   sizeOf _           = 4+   put LittleEndian x = putWord32LE x+   put BigEndian    x = putWord32BE x+   get LittleEndian   = getWord32LE+   get BigEndian      = getWord32BE++instance Serializable Word64 where+   type SizeOf Word64 = 'Exactly 8+   type Endian Word64 = 'True+   sizeOf _           = 8+   put LittleEndian x = putWord64LE x+   put BigEndian    x = putWord64BE x+   get LittleEndian   = getWord64LE+   get BigEndian      = getWord64BE++instance Serializable Int8 where+   type SizeOf Int8   = 'Exactly 1+   type Endian Int8   = 'False+   sizeOf _           = 1+   put _ x            = putWord8 (fromIntegral x)+   get _              = fromIntegral <$> getWord8++instance Serializable Int16 where+   type SizeOf Int16  = 'Exactly 2+   type Endian Int16  = 'True+   sizeOf _           = 2+   put LittleEndian x = putWord16LE (fromIntegral x)+   put BigEndian    x = putWord16BE (fromIntegral x)+   get LittleEndian   = fromIntegral <$> getWord16LE+   get BigEndian      = fromIntegral <$> getWord16BE++instance Serializable Int32 where+   type SizeOf Int32  = 'Exactly 4+   type Endian Int32  = 'True+   sizeOf _           = 4+   put LittleEndian x = putWord32LE (fromIntegral x)+   put BigEndian    x = putWord32BE (fromIntegral x)+   get LittleEndian   = fromIntegral <$> getWord32LE+   get BigEndian      = fromIntegral <$> getWord32BE++instance Serializable Int64 where+   type SizeOf Int64  = 'Exactly 8+   type Endian Int64  = 'True+   sizeOf _           = 8+   put LittleEndian x = putWord64LE (fromIntegral x)+   put BigEndian    x = putWord64BE (fromIntegral x)+   get LittleEndian   = fromIntegral <$> getWord64LE+   get BigEndian      = fromIntegral <$> getWord64BE++instance Serializable a => Serializable (AsBigEndian a) where+   type SizeOf (AsBigEndian a) = SizeOf a+   type Endian (AsBigEndian a) = 'False+   sizeOf (AsBigEndian b)      = sizeOf b+   put _ (AsBigEndian x)       = put BigEndian x+   get _                       = AsBigEndian <$> get BigEndian++instance Serializable a => Serializable (AsLittleEndian a) where+   type SizeOf (AsLittleEndian a) = SizeOf a+   type Endian (AsLittleEndian a) = 'False+   sizeOf (AsLittleEndian b)      = sizeOf b+   put _ (AsLittleEndian x)       = put LittleEndian x+   get _                          = AsLittleEndian <$> get LittleEndian
+ src/lib/Haskus/Binary/Serialize/Buffer.hs view
@@ -0,0 +1,368 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE DerivingStrategies #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE BlockArguments #-}++-- | Serializer into a mutable buffer+--+-- >>> let w = do putWord8 0x01 ; putWord32BE 0x23456789 ; putWord32BE 0xAABBCCDD+-- >>> b <- newBuffer 10+-- >>> void $ runBufferPut b 0 overflowBufferFail w+-- >>> xs <- forM [0..4] (bufferReadWord8IO b)+-- >>> xs == [0x01,0x23,0x45,0x67,0x89]+-- True+--+-- >>> b <- newBuffer 2 -- small buffer+-- >>> (_,b',_) <- runBufferPut b 0 overflowBufferDouble w+-- >>> xs <- forM [0..4] (bufferReadWord8IO b')+-- >>> xs == [0x01,0x23,0x45,0x67,0x89]+-- True+-- >>> bufferSizeIO b'+-- 16+--+module Haskus.Binary.Serialize.Buffer+   ( -- * Put+   BufferPutT (..)+   , BufferPut+   , getPutOffset+   , getPutBuffer+   , setPutOffset+   , runBufferPut+   , liftBufferPut+     -- * Get+   , BufferGetT (..)+   , BufferGet+   , getGetOffset+   , getGetBuffer+   , setGetOffset+   , runBufferGet+   , liftBufferGet+   -- * Buffer overflow+   , OverflowStrategy (..)+   , BufferOverflow (..)+   , getPutOverflowStrategy+   , getGetOverflowStrategy+   , overflowBufferFail+   , overflowBufferDouble+   , overflowBufferDoublePinned+   , overflowBufferAdd+   , overflowBufferAddPinned+   )+where++import Haskus.Binary.Serialize.Put+import Haskus.Binary.Serialize.Get+import Haskus.Memory.Buffer+import Haskus.Utils.Monad+import Haskus.Utils.Flow+import Haskus.Utils.Maybe++import Data.Functor.Identity+import Control.Monad.Trans.State.Strict as S+import Control.Monad.Fail as F+import Control.Monad.Fix++-- | Action to perform when the buffer isn't large enough to contain the+-- required data (extend the buffer, flush the data, etc.)+--+-- The returned buffer and offset replace the current ones.+newtype OverflowStrategy m b = OverflowStrategy (BufferOverflow b -> m (b,Word))++-- | Buffer overflow strategy: fails when there isn't enough space left+overflowBufferFail :: MonadFail m => OverflowStrategy m b+overflowBufferFail = OverflowStrategy \ex -> do+   F.fail $ "Not enough space in the buffer (requiring "+          ++ show (overflowRequired ex) ++ " bytes)"++-- | Buffer extend strategy: double the buffer size each time and copy the+-- original contents in it+overflowBufferDouble :: MonadIO m => OverflowStrategy m BufferM+overflowBufferDouble = OverflowStrategy \ex -> do+   sz <- bufferSizeIO (overflowBuffer ex)+   let off = overflowOffset   ex+       req = overflowRequired ex+       b   = overflowBuffer   ex+       makeSzs i = i*i : makeSzs (i*i) -- infinite list of doubling sizes+       newSz = head <| filter (> req+off) (makeSzs sz)+   newB <- newBuffer newSz+   copyBuffer b 0 newB 0 off+   pure (newB,off)++-- | Buffer extend strategy: double the buffer size each time and copy the+-- original contents in it+overflowBufferDoublePinned :: MonadIO m => Maybe Word -> OverflowStrategy m BufferMP+overflowBufferDoublePinned malignment = OverflowStrategy \ex -> do+   sz <- bufferSizeIO (overflowBuffer ex)+   let off = overflowOffset   ex+       req = overflowRequired ex+       b   = overflowBuffer   ex+       makeSzs i = i*i : makeSzs (i*i) -- infinite list of doubling sizes+       newSz = head <| filter (> req+off) (makeSzs sz)+   newB <- case malignment of+      Nothing -> newPinnedBuffer newSz+      Just al -> newAlignedPinnedBuffer newSz al+   copyBuffer b 0 newB 0 off+   pure (newB,off)++-- | Buffer extend strategy: add the given size each time and copy the+-- original contents in it+overflowBufferAdd :: MonadIO m => Word -> OverflowStrategy m BufferM+overflowBufferAdd addSz = OverflowStrategy \ex -> do+   sz <- bufferSizeIO (overflowBuffer ex)+   let off = overflowOffset   ex+       req = overflowRequired ex+       b   = overflowBuffer   ex+       makeSzs i = i+addSz : makeSzs (i+addSz) -- infinite list of added sizes+       newSz = head <| filter (> req+off) (makeSzs sz)+   newB <- newBuffer newSz+   copyBuffer b 0 newB 0 off+   pure (newB,off)++-- | Buffer extend strategy: add the given size each time and copy the+-- original contents in it+overflowBufferAddPinned :: MonadIO m => Maybe Word -> Word -> OverflowStrategy m BufferMP+overflowBufferAddPinned malignment addSz = OverflowStrategy \ex -> do+   sz <- bufferSizeIO (overflowBuffer ex)+   let off = overflowOffset   ex+       req = overflowRequired ex+       b   = overflowBuffer   ex+       makeSzs i = i+addSz : makeSzs (i+addSz) -- infinite list of added sizes+       newSz = head <| filter (> req+off) (makeSzs sz)+   newB <- case malignment of+      Nothing -> newPinnedBuffer newSz+      Just al -> newAlignedPinnedBuffer newSz al+   copyBuffer b 0 newB 0 off+   pure (newB,off)++++-- | Buffer extension information+data BufferOverflow b = BufferOverflow+   { overflowBuffer   :: b     -- ^ Current buffer+   , overflowOffset   :: Word  -- ^ Current offset in buffer+   , overflowRequired :: Word  -- ^ Required size in bytes (don't take into account leftover bytes in the current buffer)+   }++----------------------------------------------------------------------+-- BufferPut+----------------------------------------------------------------------++-- | BufferPutT state+data BufferPutState m b = BufferPutState+   { bufferPutBuffer :: !b                      -- ^ Buffer used for writing+   , bufferPutOffset :: !Word                   -- ^ Current offset+   , bufferPutStrat  :: !(OverflowStrategy m b) -- ^ Extension strategy+   }++-- | A Put monad than fails when there is not enough space in the target buffer+newtype BufferPutT b m a+   = BufferPutT (StateT (BufferPutState m b) m a)+   deriving newtype (Functor, Applicative, Monad, MonadFail, MonadFix, MonadIO)++type BufferPut b a = BufferPutT b Identity a++-- | Lift into BufferPutT+liftBufferPut :: Monad m => m a -> BufferPutT b m a+liftBufferPut act = BufferPutT (lift act)++-- | Run a buffer put+runBufferPut :: Monad m => b -> Word -> OverflowStrategy m b -> BufferPutT b m a -> m (a,b,Word)+runBufferPut b off strat (BufferPutT s) = do+   (a,s') <- runStateT s (BufferPutState b off strat)+   return (a,bufferPutBuffer s',bufferPutOffset s')++-- | Get current offset+getPutOffset :: Monad m => BufferPutT b m Word+getPutOffset = BufferPutT (bufferPutOffset <$> S.get)++-- | Get buffer+getPutBuffer :: Monad m => BufferPutT b m b+getPutBuffer = BufferPutT (bufferPutBuffer <$> S.get)++-- | Set buffer+setPutBuffer :: Monad m => b -> BufferPutT b m ()+setPutBuffer v = BufferPutT do+   S.modify \s -> s { bufferPutBuffer = v }+++-- | Get current offset+setPutOffset :: Monad m => Word -> BufferPutT b m ()+setPutOffset v = BufferPutT do+   S.modify \s -> s { bufferPutOffset = v }++-- | Get extend strategy+getPutOverflowStrategy :: Monad m => BufferPutT b m (OverflowStrategy m b)+getPutOverflowStrategy = BufferPutT (bufferPutStrat <$> S.get)+++-- | Helper to put something+putSomething+   :: MonadIO m+   => Word+   -> (Buffer 'Mutable pin fin heap -> Word -> t -> m ())+   -> t+   -> BufferPutT (Buffer 'Mutable pin fin heap) m ()+{-# INLINABLE putSomething #-}+putSomething sz act v = putSomeThings sz $ Just \b off -> act b off v++-- | Helper to put some things+putSomeThings+   :: MonadIO m+   => Word+   -> Maybe (Buffer 'Mutable pin fin heap -> Word -> m ())+   -> BufferPutT (Buffer 'Mutable pin fin heap) m ()+{-# INLINABLE putSomeThings #-}+putSomeThings sz mact = do+   off <- getPutOffset+   b   <- getPutBuffer+   bs  <- liftIO (bufferSizeIO b)+   let !newOff = off+sz++   if (newOff > bs)+      then do -- we need to extend/flush the buffer+         OverflowStrategy strat <- getPutOverflowStrategy+         (upB,upOff) <- liftBufferPut <| strat <| BufferOverflow+                              { overflowBuffer   = b+                              , overflowOffset   = off+                              , overflowRequired = sz+                              }+         setPutBuffer upB+         setPutOffset upOff+         putSomeThings sz mact++      else case mact of+            Nothing  -> return () -- we only preallocate+            Just act -> do        -- we write something for real+               liftBufferPut (act b off)+               setPutOffset newOff+   ++instance+   ( MonadIO m+   ) => PutMonad (BufferPutT (Buffer 'Mutable pin gc heap) m)+   where+      putWord8  = putSomething 1 bufferWriteWord8IO+      putWord16 = putSomething 2 bufferWriteWord16IO+      putWord32 = putSomething 4 bufferWriteWord32IO+      putWord64 = putSomething 8 bufferWriteWord64IO++      putWord8s xs = putSomeThings (fromIntegral (length xs)) $ Just \b off -> do+         forM_ ([off,(off+1)..] `zip` xs) $ \(boff,v) -> do+            bufferWriteWord8IO b boff v++      putWord16s xs = putSomeThings (2*fromIntegral (length xs)) $ Just \b off -> do+         forM_ ([off,(off+2)..] `zip` xs) $ \(boff,v) -> do+            bufferWriteWord16IO b boff v++      putWord32s xs = putSomeThings (4*fromIntegral (length xs)) $ Just \b off -> do+         forM_ ([off,(off+4)..] `zip` xs) $ \(boff,v) -> do+            bufferWriteWord32IO b boff v++      putWord64s xs = putSomeThings (8*fromIntegral (length xs)) $ Just \b off -> do+         forM_ ([off,(off+8)..] `zip` xs) $ \(boff,v) -> do+            bufferWriteWord64IO b boff v++      preAllocateAtLeast l = putSomeThings l Nothing++      putBuffer x = do+         sz <- liftIO (bufferSizeIO x)+         putSomeThings sz $ Just \b off -> copyBuffer x 0 b off sz++----------------------------------------------------------------------+-- BufferGet+----------------------------------------------------------------------++-- | BufferGetT state+data BufferGetState m b = BufferGetState+   { bufferGetBuffer :: !b                      -- ^ Buffer used for reading+   , bufferGetOffset :: !Word                   -- ^ Current offset+   , bufferGetStrat  :: !(OverflowStrategy m b) -- ^ Extension stretegy+   }++-- | A Get monad over a Buffer+newtype BufferGetT b m a+   = BufferGetT (StateT (BufferGetState m b) m a)+   deriving newtype (Functor, Applicative, Monad, MonadFail, MonadFix, MonadIO)++type BufferGet b a = BufferGetT b Identity a++instance+   ( MonadIO m+   ) => GetMonad (BufferGetT (Buffer mut pin gc heap) m)+   where+      getSkipBytes n = getSomething n \_ _ -> return ()+      getWord8       = getSomething 1 bufferReadWord8IO+      getWord16      = getSomething 2 bufferReadWord16IO+      getWord32      = getSomething 4 bufferReadWord32IO+      getWord64      = getSomething 8 bufferReadWord64IO+      getBuffer sz   = getSomething sz \b off -> do+         dest <- newBuffer sz+         copyBuffer b off dest 0 sz+         unsafeBufferFreeze dest+      getBufferInto sz dest mdoff = getSomething sz \b off -> do+         copyBuffer b off dest (fromMaybe 0 mdoff) sz++-- | Lift into BufferGetT+liftBufferGet :: Monad m => m a -> BufferGetT b m a+liftBufferGet act = BufferGetT (lift act)++-- | Run a buffer get+runBufferGet :: Monad m => b -> Word -> OverflowStrategy m b -> BufferGetT b m a -> m (a,b,Word)+runBufferGet b off strat (BufferGetT s) = do+   (a,s') <- runStateT s (BufferGetState b off strat)+   return (a,bufferGetBuffer s',bufferGetOffset s')++-- | Get current offset+getGetOffset :: Monad m => BufferGetT b m Word+getGetOffset = BufferGetT (bufferGetOffset <$> S.get)++-- | Get buffer+getGetBuffer :: Monad m => BufferGetT b m b+getGetBuffer = BufferGetT (bufferGetBuffer <$> S.get)++-- | Set buffer+setGetBuffer :: Monad m => b -> BufferGetT b m ()+setGetBuffer v = BufferGetT do+   S.modify \s -> s { bufferGetBuffer = v }+++-- | Get current offset+setGetOffset :: Monad m => Word -> BufferGetT b m ()+setGetOffset v = BufferGetT do+   S.modify \s -> s { bufferGetOffset = v }++-- | Get extend strategy+getGetOverflowStrategy :: Monad m => BufferGetT b m (OverflowStrategy m b)+getGetOverflowStrategy = BufferGetT (bufferGetStrat <$> S.get)++-- | Helper to get some things+getSomething ::+   ( Monad m+   , MonadIO m+   ) => Word+     -> (Buffer mut pin gc heap -> Word -> m a)+     -> BufferGetT (Buffer mut pin gc heap) m a+getSomething sz act = do+   off <- getGetOffset+   b   <- getGetBuffer+   bsz <- bufferSizeIO b++   let !newOff = off+sz++   if newOff > bsz+      then do -- we need to extend the buffer or fail+         OverflowStrategy strat <- getGetOverflowStrategy+         (upB,upOff) <- liftBufferGet <| strat <| BufferOverflow+                              { overflowBuffer   = b+                              , overflowOffset   = off+                              , overflowRequired = sz+                              }+         setGetBuffer upB+         setGetOffset upOff+         getSomething sz act++      else do+         setGetOffset newOff+         liftBufferGet (act b off)
+ src/lib/Haskus/Binary/Serialize/File.hs view
@@ -0,0 +1,75 @@+{-# LANGUAGE DerivingStrategies #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE BlockArguments #-}+{-# LANGUAGE ScopedTypeVariables #-}++module Haskus.Binary.Serialize.File+   ( FileGetState (..)+   , FileGetT (..)+   , runFileGet+   , runFilePathGet+   )+where++import Haskus.Binary.Serialize.Get+import Haskus.Binary.Storable+import Haskus.Memory.Buffer+import Haskus.Utils.Monad+import Haskus.Utils.Maybe++import GHC.Exts (Ptr (..))+import System.IO+import Control.Monad.Trans.State.Strict as S+import Control.Monad.Fail as F+import Control.Monad.Fix++-- | FileGetT state+data FileGetState = FileGetState+   { fileGetHandle :: !Handle+   }++-- | A Get monad over a File+newtype FileGetT m a+   = FileGetT (StateT FileGetState m a)+   deriving newtype (Functor, Applicative, Monad, MonadFail, MonadFix, MonadIO)++-- | Get file handle+getHandle :: Monad m => FileGetT m (Handle)+getHandle = FileGetT (gets fileGetHandle)++-- | Helper to get some things+getSomething :: forall a m.+   ( MonadIO m+   ) => Word -> (Ptr a -> IO a) -> FileGetT m a+getSomething sz act = do+   hdl <- getHandle+   liftIO $ allocaBytes sz \p -> do+      -- FIXME: handle EOF+      _n <- hGetBuf hdl p (fromIntegral sz)+      act p+++instance (MonadIO m) => GetMonad (FileGetT m) where+      getSkipBytes n = do+         hdl <- getHandle+         liftIO $ hSeek hdl RelativeSeek (fromIntegral n)++      getWord8       = getSomething 1 peek+      getWord16      = getSomething 2 peek+      getWord32      = getSomething 4 peek+      getWord64      = getSomething 8 peek++      getBufferInto sz dest mdoff = getSomething sz \(Ptr addr) -> do+         let b = BufferE addr sz+         copyBuffer b 0 dest (fromMaybe 0 mdoff) sz+++-- | Run a getter on a file+runFileGet :: Handle -> FileGetT IO a -> IO a+runFileGet hdl (FileGetT s) = do+   (a,_s') <- runStateT s (FileGetState hdl)+   return a++-- | Run a getter on a file+runFilePathGet :: FilePath -> FileGetT IO a -> IO a+runFilePathGet path s = withBinaryFile path ReadMode (\hdl -> runFileGet hdl s)
+ src/lib/Haskus/Binary/Serialize/Get.hs view
@@ -0,0 +1,142 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE TypeSynonymInstances #-}+{-# LANGUAGE ScopedTypeVariables #-}++-- | Binary deserialization of Haskell values+module Haskus.Binary.Serialize.Get+   ( GetMonad (..)+   , getFloat32+   , getFloat32LE+   , getFloat32BE+   , getFloat64+   , getFloat64LE+   , getFloat64BE+   , getWord16BE+   , getWord32BE+   , getWord64BE+   , getWord16LE+   , getWord32LE+   , getWord64LE+   , getWord16BEs+   , getWord32BEs+   , getWord64BEs+   , getWord16LEs+   , getWord32LEs+   , getWord64LEs+   )+where++import Haskus.Memory.Buffer+import Haskus.Number.Word+import Haskus.Binary.Endianness+import Haskus.Number.Float+import Haskus.Utils.Flow++import GHC.Exts (IsList(..))+++-- | Monad which can read a sequence of bytes+class Monad m => GetMonad m where+   -- | Read a Word8+   getWord8    :: m Word8+   -- | Read a Word16 with host endianness+   getWord16   :: m Word16+   -- | Read a Word32 with host endianness+   getWord32   :: m Word32+   -- | Read a Word64 with host endianness+   getWord64   :: m Word64++   -- | Read some Word8+   getWord8s     :: Word -> m [Word8]+   getWord8s n = replicateM (fromIntegral n) getWord8+   -- | Read some Word16 with host endianness+   getWord16s    :: Word -> m [Word16]+   getWord16s n = replicateM (fromIntegral n) getWord16+   -- | Read some Word32 with host endianness+   getWord32s    :: Word -> m [Word32]+   getWord32s n = replicateM (fromIntegral n) getWord32+   -- | Read some Word64 with host endianness+   getWord64s    :: Word -> m [Word64]+   getWord64s n = replicateM (fromIntegral n) getWord64++   -- | Read the given amount of bytes into a new buffer+   getBuffer     :: Word -> m BufferI+   getBuffer n = do+      xs <- replicateM (fromIntegral n) getWord8+      return (fromListN (fromIntegral n) xs)++   -- | Read the given amount of bytes into the specified buffer at the+   -- optionally specified offset+   getBufferInto :: Word -> Buffer 'Mutable pin gc heap -> Maybe Word -> m ()++   -- | Skip the given amount of bytes+   getSkipBytes :: Word -> m ()+++-- | Get a Float64 with host order+getFloat64 :: GetMonad m => m Float64+getFloat64 = getWord64 ||> word64ToFloat64++-- | Get a Float64 with little-endian order+getFloat64LE :: GetMonad m => m Float64+getFloat64LE = getWord64LE ||> word64ToFloat64++-- | Get a Float64 with big-endian order+getFloat64BE :: GetMonad m => m Float64+getFloat64BE = getWord64BE ||> word64ToFloat64++-- | Get a Float32 with host order+getFloat32 :: GetMonad m => m Float32+getFloat32 = getWord32 ||> word32ToFloat32++-- | Get a Float32 with little-endian order+getFloat32LE :: GetMonad m => m Float32+getFloat32LE = getWord32LE ||> word32ToFloat32++-- | Get a Float32 with big-endian order+getFloat32BE :: GetMonad m => m Float32+getFloat32BE = getWord32BE ||> word32ToFloat32++-- | Read a Word16 with little-endian order+getWord16LE   :: GetMonad m => m Word16+getWord16LE = littleEndianToHost <$> getWord16+-- | Read a Word32 with little-endian order+getWord32LE   :: GetMonad m => m Word32+getWord32LE = littleEndianToHost <$> getWord32+-- | Read a Word64 with little-endian order+getWord64LE   :: GetMonad m => m Word64+getWord64LE = littleEndianToHost <$> getWord64+-- | Read a Word16 with big-endian order+getWord16BE   :: GetMonad m => m Word16+getWord16BE = bigEndianToHost <$> getWord16+-- | Read a Word32 with big-endian order+getWord32BE   :: GetMonad m => m Word32+getWord32BE = bigEndianToHost <$> getWord32+-- | Read a Word64 with big-endian order+getWord64BE   :: GetMonad m => m Word64+getWord64BE = bigEndianToHost <$> getWord64+++-- | Read some Word16 with little-endian order+getWord16LEs    :: GetMonad m => Word -> m [Word16]+getWord16LEs n = fmap littleEndianToHost <$> getWord16s n+-- | Read some Word32 with little-endian order+getWord32LEs    :: GetMonad m => Word -> m [Word32]+getWord32LEs n =  fmap littleEndianToHost <$> getWord32s n+-- | Read some Word64 with little-endian order+getWord64LEs    :: GetMonad m => Word -> m [Word64]+getWord64LEs n =  fmap littleEndianToHost <$> getWord64s n++-- | Read some Word16 with big-endian order+getWord16BEs    :: GetMonad m => Word -> m [Word16]+getWord16BEs n = fmap bigEndianToHost <$> getWord16s n+-- | Read some Word32 with big-endian order+getWord32BEs    :: GetMonad m => Word -> m [Word32]+getWord32BEs n = fmap bigEndianToHost <$> getWord32s n+-- | Read some Word64 with big-endian order+getWord64BEs    :: GetMonad m => Word -> m [Word64]+getWord64BEs n = fmap bigEndianToHost <$> getWord64s n
+ src/lib/Haskus/Binary/Serialize/Put.hs view
@@ -0,0 +1,138 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE TypeSynonymInstances #-}+{-# LANGUAGE ScopedTypeVariables #-}++-- | Binary serialization of Haskell values+module Haskus.Binary.Serialize.Put+   ( PutMonad (..)+   , putFloat32+   , putFloat32LE+   , putFloat32BE+   , putFloat64+   , putFloat64LE+   , putFloat64BE+   , putWord16BE+   , putWord32BE+   , putWord64BE+   , putWord16LE+   , putWord32LE+   , putWord64LE+   , putWord16BEs+   , putWord32BEs+   , putWord64BEs+   , putWord16LEs+   , putWord32LEs+   , putWord64LEs+   )+where++import Haskus.Memory.Buffer+import Haskus.Number.Word+import Haskus.Binary.Endianness+import Haskus.Number.Float+import Haskus.Utils.Flow++-- | Monad which can build a sequence of bytes+class Monad m => PutMonad m where+   -- | Write a Word8+   putWord8 :: Word8 -> m ()+   -- | Write a Word16+   putWord16 :: Word16 -> m ()+   -- | Write a Word32+   putWord32 :: Word32 -> m ()+   -- | Write a Word64+   putWord64 :: Word64 -> m ()++   -- | Write some Word8+   putWord8s   :: [Word8]  -> m ()+   putWord8s xs = forM_ xs putWord8++   -- | Write some Word16+   putWord16s  :: [Word16] -> m ()+   putWord16s xs = forM_ xs putWord16++   -- | Write some Word32+   putWord32s  :: [Word32] -> m ()+   putWord32s xs = forM_ xs putWord32++   -- | Write some Word64+   putWord64s  :: [Word64] -> m ()+   putWord64s xs = forM_ xs putWord64++   -- | Write the contents of a buffer+   putBuffer   :: BufferSize (Buffer Immutable pin gc heap) => Buffer Immutable pin gc heap -> m ()++   -- | Pre-allocate at least the given amount of bytes+   --+   -- This is a hint for the putter to speed up the allocation of memory+   preAllocateAtLeast :: Word -> m ()+   preAllocateAtLeast _ = return ()++-- | Write a Float64 with host order+putFloat64 :: PutMonad m => Float64 -> m ()+putFloat64 d = putWord64 (float64ToWord64 d)++-- | Write a Float64 with little-endian order+putFloat64LE :: PutMonad m => Float64 -> m ()+putFloat64LE d = putWord64LE (float64ToWord64 d)++-- | Write a Float64 with big-endian order+putFloat64BE :: PutMonad m => Float64 -> m ()+putFloat64BE d = putWord64BE (float64ToWord64 d)++-- | Write a Float32 with host order+putFloat32 :: PutMonad m => Float32 -> m ()+putFloat32 d = putWord32 (float32ToWord32 d)++-- | Write a Float32 with little-endian order+putFloat32LE :: PutMonad m => Float32 -> m ()+putFloat32LE d = putWord32LE (float32ToWord32 d)++-- | Write a Float32 with big-endian order+putFloat32BE :: PutMonad m => Float32 -> m ()+putFloat32BE d = putWord32BE (float32ToWord32 d)+++-- | Write a Word16 with little-endian order+putWord16LE :: PutMonad m => Word16 -> m ()+putWord16LE x = putWord16 (hostToLittleEndian x)+-- | Write a Word32 with little-endian order+putWord32LE :: PutMonad m => Word32 -> m ()+putWord32LE x = putWord32 (hostToLittleEndian x)+-- | Write a Word64 with little-endian order+putWord64LE :: PutMonad m => Word64 -> m ()+putWord64LE x = putWord64 (hostToLittleEndian x)++-- | Write a Word16 with big-endian order+putWord16BE :: PutMonad m => Word16 -> m ()+putWord16BE x = putWord16 (hostToBigEndian x)+-- | Write a Word32 with big-endian order+putWord32BE :: PutMonad m => Word32 -> m ()+putWord32BE x = putWord32 (hostToBigEndian x)+-- | Write a Word64 with big-endian order+putWord64BE :: PutMonad m => Word64 -> m ()+putWord64BE x = putWord64 (hostToBigEndian x)++-- | Write some Word16 with little-endian order+putWord16LEs  :: PutMonad m => [Word16] -> m ()+putWord16LEs xs = putWord16s (fmap hostToLittleEndian xs)+-- | Write some Word32 with little-endian order+putWord32LEs  :: PutMonad m => [Word32] -> m ()+putWord32LEs xs = putWord32s (fmap hostToLittleEndian xs)+-- | Write some Word64 with little-endian order+putWord64LEs :: PutMonad m => [Word64] -> m ()+putWord64LEs xs = putWord64s (fmap hostToLittleEndian xs)+-- | Write some Word16 with big-endian order+putWord16BEs  :: PutMonad m => [Word16] -> m ()+putWord16BEs xs = putWord16s (fmap hostToBigEndian xs)+-- | Write some Word32 with big-endian order+putWord32BEs  :: PutMonad m => [Word32] -> m ()+putWord32BEs xs = putWord32s (fmap hostToBigEndian xs)+-- | Write some Word64 with big-endian order+putWord64BEs :: PutMonad m => [Word64] -> m ()+putWord64BEs xs = putWord64s (fmap hostToBigEndian xs)+
+ src/lib/Haskus/Binary/Serialize/Size.hs view
@@ -0,0 +1,35 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE DerivingStrategies #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE BlockArguments #-}++module Haskus.Binary.Serialize.Size+   ( GetSize (..)+   , runGetSize+   )+where++import Haskus.Binary.Serialize.Put+import Haskus.Memory.Buffer+import Control.Monad.Trans.State.Strict as S++newtype GetSize a+   = GetSize (State Word a) +   deriving newtype (Functor, Applicative, Monad)++-- | Increment the current size+incSize :: Word -> GetSize ()+incSize x = GetSize (state (\s -> ((),s+x)))++-- | Get the total size+runGetSize :: GetSize a -> Word+runGetSize (GetSize s) = execState s 0++instance PutMonad GetSize where+   putWord8 _  = incSize 1+   putWord16 _ = incSize 2+   putWord32 _ = incSize 4+   putWord64 _ = incSize 8+   putBuffer b = incSize (bufferSize b)
+ src/lib/Haskus/Binary/Storable.hs view
@@ -0,0 +1,544 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE DefaultSignatures #-}+{-# LANGUAGE AllowAmbiguousTypes #-}++-- | Storable class+module Haskus.Binary.Storable+   ( StaticStorable (..)+   , staticPeek+   , staticPoke+   , staticSizeOf+   , staticAlignment+   , wordBytes+   -- * Storable+   , Storable (..)+   , peek+   , poke+   , sizeOf'+   , sizeOfT+   , sizeOfT'+   , alignment'+   , alignmentT+   , alignmentT'+   , peekByteOff+   , pokeByteOff+   , peekElemOff+   , pokeElemOff+   , alloca+   , allocaBytes+   , allocaBytesAligned+   , malloc+   , with+   , withMany+   , allocaArray+   , mallocArray+   , withArray+   , withArrayLen+   , peekArray+   , pokeArray+   -- * Padding+   , RequiredPadding+   , Padding+   , PaddingEx+   )+where++import qualified Foreign.Storable as FS+import Foreign.C.Types (CSize,CChar,CULong,CLong,CUInt,CInt,CUShort,CShort)+import qualified Foreign.Marshal.Alloc as P+import System.IO.Unsafe++import Haskus.Number.Word+import Haskus.Number.Int+import Haskus.Memory.Ptr+import Haskus.Utils.Types+import Haskus.Utils.Types.Generics+import Haskus.Utils.Flow+import Foreign.Ptr++-- | A storable data in constant space whose size is known at compile time+class StaticStorable a where+   -- | Size of the stored data (in bytes)+   type SizeOf a    :: Nat++   -- | Alignment requirement (in bytes)+   type Alignment a :: Nat++   -- | Peek (read) a value from a memory address+   staticPeekIO :: Ptr a -> IO a++   -- | Poke (write) a value at the given memory address+   staticPokeIO :: Ptr a -> a -> IO ()++-- | Peek (read) a value from a memory address+staticPeek :: (StaticStorable a, MonadIO m) => Ptr a -> m a+staticPeek p = liftIO (staticPeekIO p)++-- | Poke (write) a value at the given memory address+staticPoke :: (StaticStorable a, MonadIO m) => Ptr a -> a -> m ()+staticPoke p a = liftIO (staticPokeIO p a)+++-- | Get statically known size+staticSizeOf :: forall a.+   ( KnownNat (SizeOf a)+   ) => a -> Word+staticSizeOf _ = natValue' @(SizeOf a)++-- | Get statically known alignment+staticAlignment :: forall a.+   ( KnownNat (Alignment a)+   ) => a -> Word+staticAlignment _ = natValue' @(Alignment a)+++-- | Get bytes in host-endianness order+wordBytes :: forall a.+   ( Storable a+   , KnownNat (SizeOf a)+   ) => a -> [Word8]+{-# INLINABLE wordBytes #-}+wordBytes x = unsafePerformIO $+   with x $ \p -> mapM (peekByteOff (castPtr p)) [0..natValue @(SizeOf a) - 1]++++-- | Storable data-types+--+-- Currently we cannot automatically derive a Storable class with type-level+-- naturals for "alignment" and "sizeOf". Instead we define a Storable class+-- isomorphic to the Foreign.Storable's one but with default methods using+-- DefaultSignatures (i.e., the Storable instance can be automatically derived+-- from a Generic instance).+class Storable a where+  peekIO            :: Ptr a -> IO a+  default peekIO    :: (Generic a, GStorable (Rep a)) => Ptr a -> IO a+  peekIO p          = fmap to $ gcPeek 0 (castPtr p)++  pokeIO            :: Ptr a -> a -> IO ()+  default pokeIO    :: (Generic a, GStorable (Rep a)) => Ptr a -> a -> IO ()+  pokeIO p x        = gcPoke 0 (castPtr p) $ from x++  alignment         :: a -> Word+  default alignment :: (Generic a, GStorable (Rep a)) => a -> Word+  alignment         = gcAlignment . from++  sizeOf            :: a -> Word+  default sizeOf    :: (Generic a, GStorable (Rep a)) => a -> Word+  sizeOf            = gcSizeOf 0 . from++-- | Peek a value from a pointer+peek :: (Storable a, MonadIO m) => Ptr a -> m a+peek p = liftIO (peekIO p)++-- | Poke a value to a pointer+poke :: (Storable a, MonadIO m) => Ptr a -> a -> m ()+poke p v = liftIO (pokeIO p v)++-- | Generalized 'sizeOf'+sizeOf' :: (Integral b, Storable a) => a -> b+{-# INLINABLE sizeOf' #-}+sizeOf' = fromIntegral . sizeOf++-- | SizeOf (for type-application)+sizeOfT :: forall a. (Storable a) => Word+{-# INLINABLE sizeOfT #-}+sizeOfT = sizeOf (undefined :: a)++-- | SizeOf' (for type-application)+sizeOfT' :: forall a b. (Storable a, Integral b) => b+{-# INLINABLE sizeOfT' #-}+sizeOfT' = sizeOf' (undefined :: a)++-- | Generalized 'alignment'+alignment' :: (Integral b, Storable a) => a -> b+{-# INLINABLE alignment' #-}+alignment' = fromIntegral . alignment++-- | Alignment (for type-application)+alignmentT :: forall a. (Storable a) => Word+{-# INLINABLE alignmentT #-}+alignmentT = alignment (undefined :: a)++-- | Alignment' (for type-application)+alignmentT' :: forall a b. (Storable a, Integral b) => b+{-# INLINABLE alignmentT' #-}+alignmentT' = alignment' (undefined :: a)++-- | Peek with byte offset+peekByteOff :: (MonadIO m, Storable a) => Ptr a -> Int -> m a+{-# INLINABLE peekByteOff #-}+peekByteOff ptr off = peek (ptr `plusPtr` off)++-- | Poke with byte offset+pokeByteOff :: (MonadIO m, Storable a) => Ptr a -> Int -> a -> m ()+{-# INLINABLE pokeByteOff #-}+pokeByteOff ptr off = poke (ptr `plusPtr` off)++-- | Peek with element size offset+peekElemOff :: forall a m. (MonadIO m, Storable a) => Ptr a -> Int -> m a+peekElemOff ptr off = peekByteOff ptr (off * sizeOfT' @a)++-- | Poke with element size offset+pokeElemOff :: (MonadIO m, Storable a) => Ptr a -> Int -> a -> m ()+pokeElemOff ptr off val = pokeByteOff ptr (off * sizeOf' val) val++-- | Allocate some bytes+allocaBytes :: MonadInIO m => Word -> (Ptr a -> m b) -> m b+allocaBytes sz = liftWith (P.allocaBytes (fromIntegral sz))++-- | Allocate some aligned bytes+allocaBytesAligned :: MonadInIO m => Word -> Word -> (Ptr a -> m b) -> m b+allocaBytesAligned sz align = liftWith (P.allocaBytesAligned (fromIntegral sz) (fromIntegral align))++-- | @'alloca' f@ executes the computation @f@, passing as argument+-- a pointer to a temporarily allocated block of memory sufficient to+-- hold values of type @a@.+--+-- The memory is freed when @f@ terminates (either normally or via an+-- exception), so the pointer passed to @f@ must /not/ be used after this.+--+alloca :: forall a b m. (MonadInIO m, Storable a) => (Ptr a -> m b) -> m b+{-# INLINABLE alloca #-}+alloca = allocaBytesAligned (sizeOfT' @a) (alignmentT' @a)++-- | Allocate a block of memory that is sufficient to hold values of type+-- @a@. The size of the area allocated is determined by the 'sizeOf'+-- method from the instance of 'Storable' for the appropriate type.+--+-- The memory may be deallocated using 'free' or 'finalizerFree' when+-- no longer required.+malloc :: forall a m. (MonadIO m, Storable a) => m (Ptr a)+{-# INLINABLE malloc #-}+malloc = liftIO (P.mallocBytes (fromIntegral (sizeOfT @a)))++-- | @'with' val f@ executes the computation @f@, passing as argument+-- a pointer to a temporarily allocated block of memory into which+-- @val@ has been marshalled (the combination of 'alloca' and 'poke').+--+-- The memory is freed when @f@ terminates (either normally or via an+-- exception), so the pointer passed to @f@ must /not/ be used after this.+with :: (MonadInIO m, Storable a) => a -> (Ptr a -> m b) -> m b+{-# INLINABLE with #-}+with val f =+   alloca $ \ptr -> do+      poke ptr val+      f ptr++-- | Temporarily allocate space for the given number of elements+-- (like 'alloca', but for multiple elements).+allocaArray :: forall a b m. (MonadInIO m, Storable a) => Word -> (Ptr a -> m b) -> m b+allocaArray size = liftWith (allocaBytesAligned (size * sizeOfT' @a) (alignmentT' @a))++-- | Allocate space for the given number of elements+-- (like 'malloc', but for multiple elements).+mallocArray :: forall a m. (MonadIO m, Storable a) => Word -> m (Ptr a)+mallocArray size = liftIO $ P.mallocBytes (fromIntegral (size * sizeOfT @a))++-- | Convert an array of given length into a Haskell list.  The implementation+-- is tail-recursive and so uses constant stack space.+peekArray :: (MonadIO m, Storable a) => Word -> Ptr a -> m [a]+peekArray size ptr+   | size <= 0 = return []+   | otherwise = f (size-1) []+  where+    f 0 acc = (:acc) <$> peekElemOff ptr 0+    f n acc = f (n-1) =<< ((:acc) <$> peekElemOff ptr (fromIntegral n))++-- | Write the list elements consecutive into memory+pokeArray :: (MonadIO m, Storable a) => Ptr a -> [a] -> m ()+pokeArray ptr vals0 = go vals0 0+  where go [] _         = return ()+        go (val:vals) n = do pokeElemOff ptr n val; go vals (n+1)++-- | Temporarily store a list of storable values in memory+-- (like 'with', but for multiple elements).+withArray :: (MonadInIO m, Storable a) => [a] -> (Ptr a -> m b) -> m b+withArray vals = withArrayLen vals . const++-- | Like 'withArray', but the action gets the number of values+-- as an additional parameter+withArrayLen :: (MonadInIO m, Storable a) => [a] -> (Word -> Ptr a -> m b) -> m b+withArrayLen vals f  =+  allocaArray len $ \ptr -> do+      pokeArray ptr vals+      f len ptr+  where+    len = fromIntegral (length vals)++-- | Replicates a @withXXX@ combinator over a list of objects, yielding a list of+-- marshalled objects+withMany :: (a -> (b -> res) -> res)  -- withXXX combinator for one object+         -> [a]                       -- storable objects+         -> ([b] -> res)              -- action on list of marshalled obj.s+         -> res+withMany _       []     f = f []+withMany withFoo (x:xs) f = withFoo x $ \x' ->+                              withMany withFoo xs (\xs' -> f (x':xs'))++class GStorable a where+  gcAlignment :: a x -> Word+  gcPeek      :: Word -> Ptr (a x)-> IO (a x)+  gcPoke      :: Word -> Ptr (a x) -> a x -> IO ()+  gcSizeOf    :: Word -> a x -> Word++  -- padding before the field to align from the given offset+  gcPadding   :: Word -> a x -> Word+  gcPadding off a = (gcAlignment a - off) `mod` gcAlignment a++instance GStorable U1 where+  gcAlignment _ = 0+  gcPeek _ _    = return U1+  gcPoke _ _ _  = return ()+  gcSizeOf _ _  = 0+  gcPadding _ _ = 0++instance (GStorable a, GStorable b) => GStorable (a :*: b) where+  gcAlignment _ = lcm (gcAlignment (undefined :: a x))+                      (gcAlignment (undefined :: b y))++  gcPeek off p = do+    a <- gcPeek off                    $ castPtr p+    b <- gcPeek (off + gcSizeOf off a) $ castPtr p+    return $ a :*: b++  gcPoke off p (a :*: b) = do+    gcPoke off                    (castPtr p) a+    gcPoke (off + gcSizeOf off a) (castPtr p) b++  gcSizeOf off _    = let+    a = undefined :: a x+    b = undefined :: b y+    off2 = off + gcSizeOf off a+    in gcSizeOf off a + gcSizeOf off2 b++instance (GStorable a) => GStorable (M1 i c a) where+  gcAlignment (M1 x)     = gcAlignment x+  gcPeek off p           = fmap M1 $ gcPeek off (castPtr p)+  gcPoke off p (M1 x)    = gcPoke off (castPtr p) x+  gcSizeOf off (M1 x)    = gcSizeOf off x+  gcPadding off (M1 x)   = gcPadding off x++instance (Storable a) => GStorable (K1 i a) where+  gcAlignment (K1 x)     = alignment x+  gcPeek off p           = fmap K1 $ peek (castPtr p `plusPtr` fromIntegral (off + gcPadding off (undefined :: K1 i a x)))+  gcPoke off p (K1 x)    = poke (castPtr p `plusPtr` fromIntegral (off + gcPadding off (undefined :: K1 i a x))) x+  gcSizeOf off (K1 x)    = gcPadding off (undefined :: K1 i a x) + sizeOf x+++-- | Generalize FS.peek+fsPeek :: (FS.Storable a, MonadIO m) => Ptr a -> m a+fsPeek = liftIO . FS.peek++-- | Generalize FS.poke+fsPoke :: (FS.Storable a, MonadIO m) => Ptr a -> a -> m ()+fsPoke ptr a = liftIO (FS.poke ptr a)++instance StaticStorable Word8 where+   type SizeOf    Word8 = 1+   type Alignment Word8 = 1+   staticPeekIO         = fsPeek+   staticPokeIO         = fsPoke++instance StaticStorable Word16 where+   type SizeOf    Word16 = 2+   type Alignment Word16 = 2+   staticPeekIO          = fsPeek+   staticPokeIO          = fsPoke++instance StaticStorable Word32 where+   type SizeOf    Word32 = 4+   type Alignment Word32 = 4+   staticPeekIO          = fsPeek+   staticPokeIO          = fsPoke++instance StaticStorable Word64 where+   type SizeOf    Word64 = 8+   type Alignment Word64 = 8+   staticPeekIO          = fsPeek+   staticPokeIO          = fsPoke++instance StaticStorable Int8 where+   type SizeOf    Int8 = 1+   type Alignment Int8 = 1+   staticPeekIO        = fsPeek+   staticPokeIO        = fsPoke++instance StaticStorable Int16 where+   type SizeOf    Int16 = 2+   type Alignment Int16 = 2+   staticPeekIO         = fsPeek+   staticPokeIO         = fsPoke++instance StaticStorable Int32 where+   type SizeOf    Int32 = 4+   type Alignment Int32 = 4+   staticPeekIO         = fsPeek+   staticPokeIO         = fsPoke++instance StaticStorable Int64 where+   type SizeOf    Int64 = 8+   type Alignment Int64 = 8+   staticPeekIO         = fsPeek+   staticPokeIO         = fsPoke+++instance Storable Word8 where+   sizeOf    _ = 1+   alignment _ = 1+   peekIO      = fsPeek+   pokeIO      = fsPoke++instance Storable Word16 where+   sizeOf    _ = 2+   alignment _ = 2+   peekIO      = fsPeek+   pokeIO      = fsPoke++instance Storable Word32 where+   sizeOf    _ = 4+   alignment _ = 4+   peekIO      = fsPeek+   pokeIO      = fsPoke++instance Storable Word64 where+   sizeOf    _ = 8+   alignment _ = 8+   peekIO      = fsPeek+   pokeIO      = fsPoke++instance Storable Int8 where+   sizeOf    _ = 1+   alignment _ = 1+   peekIO      = fsPeek+   pokeIO      = fsPoke++instance Storable Int16 where+   sizeOf    _ = 2+   alignment _ = 2+   peekIO      = fsPeek+   pokeIO      = fsPoke++instance Storable Int32 where+   sizeOf    _ = 4+   alignment _ = 4+   peekIO      = fsPeek+   pokeIO      = fsPoke++instance Storable Int64 where+   sizeOf    _ = 8+   alignment _ = 8+   peekIO      = fsPeek+   pokeIO      = fsPoke++instance Storable Float where+   sizeOf    _ = 4+   alignment _ = 4+   peekIO      = fsPeek+   pokeIO      = fsPoke++instance Storable Double where+   sizeOf    _ = 8+   alignment _ = 8+   peekIO      = fsPeek+   pokeIO      = fsPoke++instance Storable Char where+   sizeOf      = fromIntegral . FS.sizeOf+   alignment   = fromIntegral . FS.alignment+   peekIO      = fsPeek+   pokeIO      = fsPoke++instance Storable Word where+   sizeOf      = fromIntegral . FS.sizeOf+   alignment   = fromIntegral . FS.alignment+   peekIO      = fsPeek+   pokeIO      = fsPoke++instance Storable Int where+   sizeOf      = fromIntegral . FS.sizeOf+   alignment   = fromIntegral . FS.alignment+   peekIO      = fsPeek+   pokeIO      = fsPoke++instance Storable (Ptr a) where+   sizeOf      = fromIntegral . FS.sizeOf+   alignment   = fromIntegral . FS.alignment+   peekIO      = fsPeek+   pokeIO      = fsPoke++instance Storable CSize where+   sizeOf      = fromIntegral . FS.sizeOf+   alignment   = fromIntegral . FS.alignment+   peekIO      = fsPeek+   pokeIO      = fsPoke++instance Storable CChar where+   sizeOf      = fromIntegral . FS.sizeOf+   alignment   = fromIntegral . FS.alignment+   peekIO      = fsPeek+   pokeIO      = fsPoke++instance Storable CULong where+   sizeOf      = fromIntegral . FS.sizeOf+   alignment   = fromIntegral . FS.alignment+   peekIO      = fsPeek+   pokeIO      = fsPoke++instance Storable CLong where+   sizeOf      = fromIntegral . FS.sizeOf+   alignment   = fromIntegral . FS.alignment+   peekIO      = fsPeek+   pokeIO      = fsPoke++instance Storable CUInt where+   sizeOf      = fromIntegral . FS.sizeOf+   alignment   = fromIntegral . FS.alignment+   peekIO      = fsPeek+   pokeIO      = fsPoke++instance Storable CInt where+   sizeOf      = fromIntegral . FS.sizeOf+   alignment   = fromIntegral . FS.alignment+   peekIO      = fsPeek+   pokeIO      = fsPoke++instance Storable CUShort where+   sizeOf      = fromIntegral . FS.sizeOf+   alignment   = fromIntegral . FS.alignment+   peekIO      = fsPeek+   pokeIO      = fsPoke++instance Storable CShort where+   sizeOf      = fromIntegral . FS.sizeOf+   alignment   = fromIntegral . FS.alignment+   peekIO      = fsPeek+   pokeIO      = fsPoke++instance Storable WordPtr where+   sizeOf      = fromIntegral . FS.sizeOf+   alignment   = fromIntegral . FS.alignment+   peekIO      = fsPeek+   pokeIO      = fsPoke++---------------------------+-- Padding+---------------------------++-- | Compute the required padding between a and b to respect b's alignment+type family RequiredPadding a b where+   RequiredPadding a b = Padding (SizeOf a) b++-- | Compute the required padding between the size sz and b to respect b's alignment+type family Padding (sz :: Nat) b where+   Padding sz b = PaddingEx (Mod sz (Alignment b)) (Alignment b)++type family PaddingEx (m :: Nat) (a :: Nat) where+   PaddingEx 0 a = 0+   PaddingEx m a = a - m
+ src/lib/Haskus/Binary/Union.hs view
@@ -0,0 +1,186 @@+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}++-- | Union (as in C)+--+-- Unions are storable and can contain any storable data.+-- +-- Use 'fromUnion' to read an alternative:+--+-- @+-- {-# LANGUAGE DataKinds #-}+--+-- getUnion :: IO (Union '[Word16, Word32, Word64])+-- getUnion = ...+--+-- test = do+--    u <- getUnion+--+--    -- to get one of the member+--    let v = fromUnion u :: Word16+--    let v = fromUnion u :: Word32+--    let v = fromUnion u :: Word64+--+--    -- This won't compile (Word8 is not a member of the union)+--    let v = fromUnion u :: Word8+-- @+--+-- Use 'toUnion' to create a new union:+--+-- @+-- let+--    u2 :: Union '[Word32, Vector 4 Word8]+--    u2 = toUnion (0x12345678 :: Word32)+-- @+--+module Haskus.Binary.Union+   ( Union+   , fromUnion+   , toUnion+   , toUnionZero+   )+where++import Haskus.Utils.Types hiding (Union)+import Haskus.Utils.HList+import Haskus.Utils.Flow (when)+import Haskus.Binary.Storable+import Haskus.Memory.Utils (memCopy, memSet)++import System.IO.Unsafe (unsafePerformIO)++import Foreign.ForeignPtr+import Foreign.Ptr+import qualified Foreign.Storable as FS+++-- TODO: rewrite rules+-- poke p (toUnion x) = poke (castPtr p) x+--+-- (fromUnion <$> peek p) :: IO a  = peek (castPtr p) :: IO a++++-- | An union +--+-- We use a list of types as a parameter.+--+-- The union is just a pointer to a buffer containing the value(s). The size of+-- the buffer is implicitly known from the types in the list.+newtype Union (x :: [*]) = Union (ForeignPtr ()) deriving (Show)++-- | Retrieve a union member from its type+fromUnion :: (Storable a, Member a l) => Union l -> a+fromUnion (Union fp) = unsafePerformIO $ withForeignPtr fp (peek . castPtr)++-- | Create a new union from one of the union types+toUnion :: forall a l . (Storable (Union l), Storable a, Member a l) => a -> Union l+toUnion = toUnion' False++-- | Like 'toUnion' but set the remaining bytes to 0+toUnionZero :: forall a l . (Storable (Union l), Storable a, Member a l) => a -> Union l+toUnionZero = toUnion' True+++-- | Create a new union from one of the union types+toUnion' :: forall a l . (Storable (Union l), Storable a, Member a l) => Bool -> a -> Union l+toUnion' zero v = unsafePerformIO $ do+   let sz = sizeOfT @(Union l)+   fp <- mallocForeignPtrBytes (fromIntegral sz)+   withForeignPtr fp $ \p -> do+      -- set bytes after the object to 0+      when zero $ do+         let psz = sizeOfT @a+         memSet (p `plusPtr` fromIntegral psz) (fromIntegral (sz - psz)) 0+      poke (castPtr p) v+   return $ Union fp++type family MapSizeOf fs where+   MapSizeOf '[]       = '[]+   MapSizeOf (x ': xs) = SizeOf x ': MapSizeOf xs++type family MapAlignment fs where+   MapAlignment '[]       = '[]+   MapAlignment (x ': xs) = Alignment x ': MapAlignment xs+++instance forall fs.+      ( KnownNat (ListMax (MapSizeOf fs))+      , KnownNat (ListMax (MapAlignment fs))+      )+      => StaticStorable (Union fs)+   where+      type SizeOf (Union fs)    = ListMax (MapSizeOf fs)+      type Alignment (Union fs) = ListMax (MapAlignment fs)++      staticPeekIO ptr = do+         let sz = natValue @(SizeOf (Union fs))+         fp <- mallocForeignPtrBytes sz+         withForeignPtr fp $ \p -> +            memCopy p (castPtr ptr) (fromIntegral sz)+         return (Union fp)++      staticPokeIO ptr (Union fp) = do+         withForeignPtr fp $ \p ->+            memCopy (castPtr ptr) p (natValue @(SizeOf (Union fs)))++-------------------------------------------------------------------------------------+-- We use HFoldr' to get the maximum size and alignment of the types in the union+-------------------------------------------------------------------------------------++data FoldSizeOf    = FoldSizeOf+data FoldAlignment = FoldAlignment++instance (r ~ Word, Storable a) => Apply FoldSizeOf (a, Word) r where+   apply _ (_,r) = max r (sizeOfT @a)++instance (r ~ Word, Storable a) => Apply FoldAlignment (a, Word) r where+   apply _ (_,r) = max r (alignmentT @a)++-- | Get the union size (i.e. the maximum of the types in the union)+unionSize :: forall l . HFoldr' FoldSizeOf Word l Word => Union l -> Word+unionSize _ = hFoldr' FoldSizeOf (0 :: Word) (undefined :: HList l)++-- | Get the union alignment (i.e. the maximum of the types in the union)+unionAlignment :: forall l . HFoldr' FoldAlignment Word l Word => Union l -> Word+unionAlignment _ = hFoldr' FoldAlignment (0 :: Word) (undefined :: HList l)+++-------------------------------------------------------------------------------------+-- Finally we can write the Storable instance+-------------------------------------------------------------------------------------++instance+   ( HFoldr' FoldSizeOf Word l Word+   , HFoldr' FoldAlignment Word l Word+   ) => Storable (Union l) where+   sizeOf     = unionSize+   alignment  = unionAlignment+   peekIO ptr = do+      let sz = sizeOfT' @(Union l)+      fp <- mallocForeignPtrBytes sz+      withForeignPtr fp $ \p -> +         memCopy p (castPtr ptr) (fromIntegral sz)+      return (Union fp)++   pokeIO ptr (Union fp) = withForeignPtr fp $ \p ->+      memCopy (castPtr ptr) p (sizeOfT' @(Union l))+++-- compatibility instance with Foreign.Storable+instance+   ( HFoldr' FoldSizeOf Word l Word+   , HFoldr' FoldAlignment Word l Word+   ) => FS.Storable (Union l) where+   sizeOf     = fromIntegral . unionSize+   alignment  = fromIntegral . unionAlignment+   peek       = peekIO+   poke       = pokeIO
+ src/lib/Haskus/Binary/Unum.hs view
@@ -0,0 +1,737 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE KindSignatures #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE CPP #-}+#if MIN_VERSION_GLASGOW_HASKELL (8,6,0,0)+{-# LANGUAGE NoStarIsType #-}+#endif++module Haskus.Binary.Unum+   ( Unum+   , UnumNum (..)+   , I+   , U (..)+   , Neg+   , Rcp+   , Infinite+   , Log2+   , UnumNumbers+   , UnumSize+   , BackingWord+   , UBit (..)+   , unumSize+   , unumZero+   , unumInfinite+   , unumEncode+   , unumBits+   , unumNegate+   , unumReciprocate+   , unumLabels+   , Sign (..)+   , unumSign+   -- * SORN (bit-sets)+   , SORN+   , SORNBackingWord+   , sornBits+   , sornSize+   , sornEmpty+   , sornFull+   , sornNonInfinite+   , sornNonZero+   , sornSingle+   , sornInsert+   , sornMember+   , sornRemove+   , sornUnion+   , sornIntersect+   , sornComplement+   , sornNegate+   , sornElems+   , sornFromElems+   , sornFromTo+   , SornAdd (..)+   -- * Contiguous SORN+   , CSORN (..)+   , csornSize+   , csornBits+   , csornToSorn+   , csornEmpty+   , csornIsEmpty+   , csornFromTo+   , csornFull+   , csornSingle+   )+where++import Haskus.Number.Word+import Haskus.Binary.Bits+import Haskus.Binary.BitField+import Haskus.Utils.Types hiding (Log2)+import Haskus.Utils.HList+import Haskus.Utils.Flow++import Data.Kind (Type)++-- | An Unum+--+-- 0 (and its reciprocal) is always included.+-- Numbers have to be >= 1 and sorted.+--+-- e.g., Unum '[] => /0 .. 0 .. /0+--       Unum '[I 1] => /0 .. -1 .. 0 .. 1 .. /0+--       Unum '[I 1, I 2] => /0 .. -2 .. -1 .. -/2 .. 0 .. /2 .. 1 .. 2 .. /0+--       Unum '[I 1, PI]  => /0 .. -PI .. -1 .. -/PI .. 0 .. /PI .. 1 .. PI .. /0+data Unum (xs :: [Type])+++class UnumNum a where+   unumLabel :: a -> String++data I (n :: Nat)+data Neg a+data Rcp a+data Uncertain a++instance KnownNat n => UnumNum (I n) where+   unumLabel _ = show (natValue' @n)++instance UnumNum x => UnumNum (Rcp x) where+   unumLabel _ = "/" ++ unumLabel (undefined :: x)++instance UnumNum x => UnumNum (Neg x) where+   unumLabel _ = "-" ++ unumLabel (undefined :: x)++instance UnumNum x => UnumNum (Uncertain x) where+   unumLabel _ = unumLabel (undefined :: x) ++ ".."++type Infinite = Rcp (I 0)++type family Simplify a where+   Simplify a = Simplify' 'True a++type family Simplify' loop a where+   Simplify' l (Rcp (Rcp x))  = Simplify x+   Simplify' l (Neg (Neg x))  = Simplify x+   Simplify' l (Neg (I 0))    = I 0+   Simplify' l (Rcp (I 1))    = I 1+   Simplify' l (Neg Infinite) = Infinite -- infinite is special+   Simplify' l (Rcp (Neg x))  = Simplify (Neg (Rcp x)) -- Neg are outer+   Simplify' 'True (Rcp x)    = Simplify' 'False (Rcp (Simplify x))+   Simplify' 'True (Neg x)    = Simplify' 'False (Neg (Simplify x))+   Simplify' 'False (Rcp x)   = Rcp (Simplify x)+   Simplify' 'False (Neg x)   = Neg (Simplify x)+   Simplify' l x              = x++-- | Compute the precise numbers set+type family UnumNumbers x where+   -- add /0 (infinite), add reciprocals, add negations, nub+   UnumNumbers (Unum xs) = Nub (AddNeg (AddRcp (Snoc xs Infinite)))++-- | Positive numbers in the unums+type family UnumPositives x where+   UnumPositives (Unum xs) = Nub (AddRcp (Snoc xs Infinite))++-- | Indexable numbers+type family UnumIndexables x where+   UnumIndexables u =+      Nub (Concat (UnumPositives u) (Reverse (MapNeg (UnumPositives u))))++-- | All unum members+type family UnumMembers x where+   UnumMembers u = MakeMembers (UnumIndexables u)++type family MakeMembers xs where+   MakeMembers '[]       = '[]+   MakeMembers (x ': xs) = x ': Uncertain x ': MakeMembers xs+ ++data GetLabel = GetLabel++instance  forall a r.+   ( UnumNum a+   , r ~ [String]+   ) => Apply GetLabel (a, [String]) r where+   apply _ (x,xs) = unumLabel x : xs++-- | Unum labels+unumLabels :: forall u v.+   ( HFoldr' GetLabel [String] v [String]+   , v ~ UnumMembers u+   ) => [String]+unumLabels = hFoldr' GetLabel ([] :: [String]) (undefined :: HList v)++-- | Compute the number of bits required+type family UnumSize x where+   UnumSize x = 1 + Log2 (Length (UnumNumbers x)) -- add 1 for ubit++-- | Size of an unum in bits+unumSize :: forall u.+   ( KnownNat (UnumSize u)+   ) => Word+unumSize = natValue @(UnumSize u)++-- | Zero+unumZero :: forall u.+   ( Num (BackingWord u)+   , Bits (BackingWord u)+   , Encodable (I 0) u+   ) => U u+unumZero = unumEncode @u @(I 0) ExactNumber++-- | Infinite+unumInfinite :: forall u.+   ( Num (BackingWord u)+   , Bits (BackingWord u)+   , Encodable Infinite u+   ) => U u+unumInfinite = unumEncode @u @Infinite ExactNumber++type family Div2 n where+  Div2 0 = 0+  Div2 1 = 0+  Div2 n = Div2 (n - 2) + 1++type family Log2 n where+  Log2 0 = 0+  Log2 1 = 0+  Log2 n = Log2 (Div2 n) + 1++-- | Backing word for the unum+type family BackingWord x where+   BackingWord x = WordAtLeast (UnumSize x)++type family MapRcp xs where+   MapRcp '[] = '[]+   MapRcp (x ': xs) = Simplify (Rcp x) ': MapRcp xs++type family MapNeg xs where+   MapNeg '[] = '[]+   MapNeg (x ': xs) = Simplify (Neg x) ': MapNeg xs++type family AddRcp xs where+   AddRcp xs = Concat (Reverse (MapRcp xs)) xs++type family AddNeg xs where+   AddNeg xs = Concat (Reverse (MapNeg xs)) xs++newtype U u = U (BackingWord u)++instance Eq (BackingWord u) => Eq (U u) where+   U x == U y = x == y++instance forall u v.+   ( HFoldr' GetLabel [String] v [String]+   , v ~ UnumMembers u+   , Integral (BackingWord u)+   ) => Show (U u) where+   show (U w) = unumLabels @u !! fromIntegral w++unumBits :: forall u.+   ( Bits (BackingWord u)+   , KnownNat (UnumSize u)+   ) => U u -> String+unumBits (U w) = drop (fromIntegral (bitSize w - unumSize @u)) (bitsToString w)++type Encodable x u =+   ( KnownNat (IndexOf (Simplify x) (UnumIndexables u)))+++-- | Uncertainty bit+data UBit+   = ExactNumber   -- ^ Exact number+   | OpenInterval  -- ^ OpenInterval above the exact number+   deriving (Show,Eq)++-- | Encode a number+unumEncode :: forall u x i.+   ( i ~ IndexOf (Simplify x) (UnumIndexables u)+   , KnownNat i+   , Num (BackingWord u)+   , Bits (BackingWord u)+   ) => UBit -> U u+{-# INLINABLE unumEncode #-}+unumEncode b = case b of+      ExactNumber  -> U w+      OpenInterval -> U (setBit w 0)+   where+      w = natValue @i `shiftL` 1+++-- | Negate a number+unumNegate :: forall u.+   ( Bits (BackingWord u)+   , Num (BackingWord u)+   , KnownNat (UnumSize u)+   ) => U u -> U u+{-# INLINABLE unumNegate #-}+unumNegate (U w) = U (maskDyn s (complement w + 1))+   where+      s = unumSize @u+++-- | Reciprocate a number+unumReciprocate :: forall u.+   ( Bits (BackingWord u)+   , Num (BackingWord u)+   , KnownNat (UnumSize u)+   ) => U u -> U u+{-# INLINABLE unumReciprocate #-}+unumReciprocate (U w) = U (w `xor` m + 1)+   where+      s = unumSize @u+      m = makeMaskDyn (s-1)+++data Sign+   = Positive+   | Negative+   | NoSign+   deriving (Show,Eq)++-- | Get unum sign+unumSign :: forall u.+   ( Bits (BackingWord u)+   , KnownNat (UnumSize u)+   ) => U u -> Sign+unumSign (U w) =+      if clearBit w n == zeroBits -- infinity or zero+         then NoSign+         else if testBit w n +            then Negative +            else Positive+   where+      n = fromIntegral (unumSize @u - 1)++++--------------------------------------------------------------------------------+-- SORN implementation as bit-sets+-- -------------------------------+--  +-- We use one bit per unum in the set.+--+-- E.g., 2-bit  unum means 4-bit          SORN+--       8-bit  unum means 256-bit        SORN (32 B)+--       16-bit unum means 65536-bit      SORN (8 kB)+--       24-bit unum means 16777216-bit   SORN (2 MB)+--       32-bit unum means 4294967296-bit SORN (512 MB)+--+--------------------------------------------------------------------------------+++type family SORNSize u where+   SORNSize u = Length (UnumMembers u)++type family SORNBackingWord u where+   SORNBackingWord u = WordAtLeast (SORNSize u)++newtype SORN u = SORN (SORNBackingWord u)++instance forall u v.+   ( KnownNat (SORNSize u)+   , Bits (SORNBackingWord u)+   , Num (BackingWord u)+   , Integral (BackingWord u)+   , HFoldr' GetLabel [String] v [String]+   , v ~ UnumMembers u+   ) => Show (SORN u) where+   show = show . sornElems+   ++-- | Show SORN bits+sornBits :: forall u s.+   ( Bits (SORNBackingWord u)+   , KnownNat (UnumSize u)+   , s ~ SORNSize u+   , KnownNat s+   ) => SORN u -> String+sornBits (SORN w) = drop (bitSize w - natValue @s) (bitsToString w)++++-- | Size of a SORN in bits+sornSize :: forall u s.+   ( s ~ SORNSize u+   , KnownNat s+   ) => Word+sornSize = natValue @s++-- | Empty SORN+sornEmpty :: (Bits (SORNBackingWord u)) => SORN u+sornEmpty = SORN zeroBits++-- | Full SORN+sornFull :: forall u.+   ( Bits (SORNBackingWord u)+   , KnownNat (SORNSize u)+   ) => SORN u+sornFull = SORN (maskDyn s (complement zeroBits))+   where+      s = sornSize @u++-- | Full SORN without infinite+sornNonInfinite :: forall u.+   ( Bits (SORNBackingWord u)+   , Integral (BackingWord u)+   , Bits (BackingWord u)+   , Encodable Infinite u+   ) => SORN u+sornNonInfinite = sornRemove (SORN (complement zeroBits)) inf+   where+      inf = unumEncode @u @Infinite ExactNumber++-- | Full SORN without infinite+sornNonZero ::+   ( Bits (SORNBackingWord u)+   , Integral (BackingWord u)+   , Bits (BackingWord u)+   , Encodable (I 0) u+   ) => SORN u+sornNonZero = sornRemove (SORN (complement zeroBits)) unumZero++-- | SORN singleton+sornSingle ::+   ( Integral (BackingWord u)+   , Bits (SORNBackingWord u)+   ) => U u -> SORN u+sornSingle = sornInsert sornEmpty++-- | Insert in a SORN+sornInsert :: forall u.+   ( Bits (SORNBackingWord u)+   , Integral (BackingWord u)+   ) => SORN u -> U u -> SORN u+sornInsert (SORN w) (U v) = SORN (setBit w (fromIntegral v))++-- | Remove in a SORN+sornRemove :: forall u.+   ( Bits (SORNBackingWord u)+   , Integral (BackingWord u)+   ) => SORN u -> U u -> SORN u+sornRemove (SORN w) (U v) = SORN (clearBit w (fromIntegral v))++-- | Test membership in a SORN+sornMember :: forall u.+   ( Bits (SORNBackingWord u)+   , Integral (BackingWord u)+   ) => SORN u -> U u -> Bool+sornMember (SORN w) (U x) = testBit w (fromIntegral x)++-- | Union of two SORNs+sornUnion :: forall u.+   ( Bits (SORNBackingWord u)+   ) => SORN u -> SORN u -> SORN u+sornUnion (SORN w) (SORN v) = SORN (w .|. v)++-- | Intersection of two SORNs+sornIntersect :: forall u.+   ( Bits (SORNBackingWord u)+   ) => SORN u -> SORN u -> SORN u+sornIntersect (SORN w) (SORN v) = SORN (w .&. v)++-- | Complement the SORN+sornComplement ::+   ( Bits (SORNBackingWord u)+   ) => SORN u -> SORN u+sornComplement (SORN x) = SORN (complement x)++-- | Negate a SORN+sornNegate :: forall u.+   ( Bits (SORNBackingWord u)+   , Bits (BackingWord u)+   , Integral (BackingWord u)+   , KnownNat (SORNSize u)+   , KnownNat (UnumSize u)+   ) => SORN u -> SORN u+sornNegate = sornFromElems . fmap unumNegate . sornElems++-- | Elements in the SORN+sornElems :: forall u s.+   ( s ~ SORNSize u+   , KnownNat s+   , Bits (SORNBackingWord u)+   , Num (BackingWord u)+   ) => SORN u -> [U u]+sornElems (SORN x) = foldl b [] (reverse ([s `shiftR` 1 .. s-1]+                                  ++ [0 .. (s-1) `shiftR` 1]))+   where+      s      = natValue @s+      b us i = if testBit x i+                  then U (fromIntegral i) : us+                  else us++-- | Create a SORN from its elements+sornFromElems ::+   ( Integral (BackingWord u)+   , Bits (SORNBackingWord u)+   ) => [U u] -> SORN u+sornFromElems = foldl sornInsert sornEmpty++-- | Create a contiguous SORN from two elements+sornFromTo :: forall u.+   ( Integral (BackingWord u)+   , Bits (SORNBackingWord u)+   , Bits (BackingWord u)+   , KnownNat (UnumSize u)+   ) => U u -> U u -> SORN u+sornFromTo (U a) (U b) = go sornEmpty a+   where+      go w x +         | x == b    = sornInsert w (U x)+         | otherwise = go (sornInsert w (U x)) (maskDyn s (x+1))+      s = unumSize @u+++class SornAdd u where+   -- | Add two Unums+   sornAddU :: U u -> U u -> SORN u++   -- | Add two SORNs+   sornAdd ::+      ( KnownNat (SORNSize u)+      , Bits (SORNBackingWord u)+      , Num (BackingWord u)+      ) => SORN u -> SORN u -> SORN u+   sornAdd a b =+      foldl sornUnion sornEmpty [ sornAddU x y+                                | x <- sornElems a+                                , y <- sornElems b+                                ]++   -- | Add a SORN with itself+   sornAddDep ::+      ( KnownNat (SORNSize u)+      , Bits (SORNBackingWord u)+      , Num (BackingWord u)+      ) => SORN u -> SORN u+   sornAddDep a =+      foldl sornUnion sornEmpty [ sornAddU x x+                                | x <- sornElems a+                                ]++   -- | Subtract two Unums+   sornSubU :: +      ( Bits (BackingWord u)+      , Num (BackingWord u)+      , KnownNat (UnumSize u)+      ) => U u -> U u -> SORN u+   sornSubU a b = sornAddU a (unumNegate b)++   -- | Subtract two SORNS+   sornSub ::+      ( KnownNat (SORNSize u)+      , Bits (SORNBackingWord u)+      , Bits (BackingWord u)+      , Num (BackingWord u)+      , KnownNat (UnumSize u)+      ) => SORN u -> SORN u -> SORN u+   sornSub a b =+      foldl sornUnion sornEmpty [ sornSubU x y+                                | x <- sornElems a+                                , y <- sornElems b+                                ]++   -- | Subtract a SORN with itself+   sornSubDep ::+      ( KnownNat (SORNSize u)+      , Bits (SORNBackingWord u)+      , Bits (BackingWord u)+      , Num (BackingWord u)+      , KnownNat (UnumSize u)+      ) => SORN u -> SORN u+   sornSubDep a =+      foldl sornUnion sornEmpty [ sornSubU x x+                                | x <- sornElems a+                                ]++++--------------------------------------------------------------------------------+-- Contiguous SORN implementation+-- -------------------------------+--  +-- We encode contiguous SORN with two values:+--    * start: the starting unum+--    * count: the number of unums from start upwards+--+-- If count == 0+--    If start == 0+--       then empty SORN+--       else full SORN+--+-- Pros:+--    * size is much smaller (2 * unum size),  especially for look-up tables because+--    connected sets remain connected under addition, subtraction, multiplication+--    and division.+--    * trivial logic for negate and reciprocate (i.e., operate on bounds only)+--------------------------------------------------------------------------------++type family CSORNSize u where+   CSORNSize u = 2 * UnumSize u++type family CSORNBackingWord u where+   CSORNBackingWord u = WordAtLeast (CSORNSize u)++newtype CSORN u+   = CSORN (BitFields (CSORNBackingWord u)+      '[ BitField (UnumSize u) "start" (BackingWord u)+       , BitField (UnumSize u) "count" (BackingWord u)+       ])++csornStart :: forall u.+   ( Integral (BackingWord u)+   , Integral (CSORNBackingWord u)+   , KnownNat (UnumSize u)+   , Bits (CSORNBackingWord u)+   , Field (BackingWord u)+   ) => CSORN u -> U u+csornStart c = U (csornStart' c)++csornStart' :: forall u.+   ( Integral (BackingWord u)+   , Integral (CSORNBackingWord u)+   , KnownNat (UnumSize u)+   , Bits (CSORNBackingWord u)+   , Field (BackingWord u)+   ) => CSORN u -> BackingWord u+csornStart' (CSORN c) = extractField' @"start" c++csornCount ::+   ( Integral (BackingWord u)+   , Integral (CSORNBackingWord u)+   , KnownNat (UnumSize u)+   , Bits (CSORNBackingWord u)+   , Field (BackingWord u)+   ) => CSORN u -> BackingWord u+csornCount (CSORN c) = extractField' @"count" c++instance forall u v.+   ( KnownNat (SORNSize u)+   , KnownNat (UnumSize u)+   , Bits (BackingWord u)+   , Bits (CSORNBackingWord u)+   , Integral (CSORNBackingWord u)+   , Num (BackingWord u)+   , Integral (BackingWord u)+   , HFoldr' GetLabel [String] v [String]+   , Field (BackingWord u)+   , Bits (SORNBackingWord u)+   , Bits (SORNBackingWord u)+   , v ~ UnumMembers u+   ) => Show (CSORN u) where+   show = show . csornToSorn ++-- | Convert a contiguous SORN into a SORN+csornToSorn :: forall u.+   ( KnownNat (UnumSize u)+   , Num (BackingWord u)+   , Integral (BackingWord u)+   , Integral (CSORNBackingWord u)+   , Bits (CSORNBackingWord u)+   , Bits (BackingWord u)+   , Bits (SORNBackingWord u)+   , Field (BackingWord u)+   , KnownNat (SORNSize u)+   , Bits (SORNBackingWord u)+   ) => CSORN u -> SORN u+csornToSorn c =+   if csornCount c == 0+      then if start == 0+         then sornEmpty+         else sornFull+      else sornFromTo (csornStart c) (U x')+   where+      start = csornStart' c+      x'    = maskDyn s (start + csornCount c - 1)+      s     = unumSize @u++-- | Size of a contiguous SORN in bits+csornSize :: forall u s.+   ( s ~ CSORNSize u+   , KnownNat s+   ) => Word+csornSize = natValue @s++-- | Show contiguous SORN bits+csornBits :: forall u s.+   ( Bits (CSORNBackingWord u)+   , KnownNat (UnumSize u)+   , s ~ CSORNSize u+   , KnownNat s+   ) => CSORN u -> String+csornBits (CSORN (BitFields w)) = drop (bitSize w - natValue @s) (bitsToString w)+++-- | Empty contigiuous SORN+csornEmpty :: forall u.+   ( Bits (CSORNBackingWord u)+   ) => CSORN u+csornEmpty = CSORN (BitFields zeroBits)++-- | Test if a contigiuous SORN is empty+csornIsEmpty :: forall u.+   ( Bits (CSORNBackingWord u)+   ) => CSORN u -> Bool+{-# INLINABLE csornIsEmpty #-}+csornIsEmpty (CSORN (BitFields b)) = b == zeroBits++-- | Contiguous SORN build+csornFromTo :: forall u.+   ( Num (BackingWord u)+   , Bits (BackingWord u)+   , KnownNat (UnumSize u)+   , KnownNat (SORNSize u)+   , Bits (BackingWord u)+   , Integral (CSORNBackingWord u)+   , Bits (CSORNBackingWord u)+   , Field (BackingWord u)+   , Integral (BackingWord u)+   ) => U u -> U u -> CSORN u+csornFromTo start stop =+      if fromIntegral count == unumSize @u+         then csornFull+         else CSORN b+   where+      U x   = start+      U y   = stop+      s     = unumSize @u+      count = maskDyn s (y-x+1)+      b     = BitFields 0+              |> updateField' @"start" x+              |> updateField' @"count" count+++-- | Full contiguous SORN+csornFull :: forall u. +   ( Bits (CSORNBackingWord u)+   , Integral (CSORNBackingWord u)+   , Integral (BackingWord u)+   , KnownNat (UnumSize u)+   , Field (BackingWord u)+   ) => CSORN u+csornFull = CSORN (BitFields zeroBits+  |> updateField' @"start" 1 -- dummy /= 0+  |> updateField' @"count" 0)+++-- | Contiguous SORN singleton+csornSingle :: forall u.+   ( Bits (CSORNBackingWord u)+   , Integral (CSORNBackingWord u)+   , Integral (BackingWord u)+   , KnownNat (UnumSize u)+   , Field (BackingWord u)+   ) => U u -> CSORN u+csornSingle (U u) = CSORN (BitFields zeroBits+  |> updateField' @"start" u+  |> updateField' @"count" 1)+
+ src/lib/Haskus/Binary/Vector.hs view
@@ -0,0 +1,354 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE KindSignatures #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE MultiWayIf #-}+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE CPP #-}+#if MIN_VERSION_GLASGOW_HASKELL (8,6,0,0)+{-# LANGUAGE NoStarIsType #-}+#endif+++-- | Vector with size in the type+module Haskus.Binary.Vector+   ( Vector (..)+   , vectorBuffer+   , vectorReverse+   , take+   , drop+   , index+   , fromList+   , fromFilledList+   , fromFilledListZ+   , toList+   , replicate+   , concat+   , zipWith+   )+where++import Prelude hiding ( replicate, head, last+                      , tail, init, map, length, drop, take, concat+                      , zipWith )+import System.IO.Unsafe (unsafePerformIO)++import qualified Haskus.Utils.List as List+import Haskus.Utils.Types+import Haskus.Utils.HList+import Haskus.Utils.Maybe+import Haskus.Utils.Flow+import Haskus.Binary.Storable+import Haskus.Binary.Buffer+import Haskus.Binary.Bits++import Foreign.Ptr+import Foreign.Marshal.Alloc (mallocBytes)++-- | Vector with type-checked size+data Vector (n :: Nat) a = Vector Buffer++instance (Storable a, Show a, KnownNat n) => Show (Vector n a) where+   show v = "fromList " ++ show (toList v)++-- | Return the buffer backing the vector+vectorBuffer :: Vector n a -> Buffer+vectorBuffer (Vector b) = b++-- | Reverse a vector+vectorReverse :: (KnownNat n, Storable a) => Vector n a -> Vector n a+vectorReverse = fromJust . fromList . reverse . toList++-- | Offset of the i-th element in a stored vector+type family ElemOffset a i n where+   ElemOffset a i n = Assert (i+1 <=? n)+      (i * (SizeOf a))+      (('Text "Invalid vector index: " ':<>: 'ShowType i+       ':$$: 'Text "Vector size: "     ':<>: 'ShowType n))++instance forall a n.+   ( KnownNat (SizeOf a * n)+   ) => StaticStorable (Vector n a) where++   type SizeOf (Vector n a)    = SizeOf a * n+   type Alignment (Vector n a) = Alignment a++   staticPeekIO ptr =+      Vector <$> bufferPackPtr (natValue @(SizeOf a * n)) (castPtr ptr)++   staticPokeIO ptr (Vector b) = bufferPoke ptr b++instance forall a n.+   ( KnownNat n+   , Storable a+   ) => Storable (Vector n a) where+   sizeOf _    = natValue @n * sizeOfT @a+   alignment _ = alignmentT @a+   peekIO ptr  = +      Vector <$> bufferPackPtr (sizeOfT' @(Vector n a)) (castPtr ptr)++   pokeIO ptr (Vector b) = bufferPoke ptr b++-- | Yield the first n elements+take :: forall n m a.+   ( KnownNat (SizeOf a * n)+   ) => Vector (m+n) a -> Vector n a+{-# INLINABLE take #-}+take (Vector b) = Vector (bufferTake (natValue @(SizeOf a * n)) b)++-- | Drop the first n elements+drop :: forall n m a.+   ( KnownNat (SizeOf a * n)+   ) => Vector (m+n) a -> Vector m a+{-# INLINABLE drop #-}+drop (Vector b) = Vector (bufferDrop (natValue @(SizeOf a * n)) b)++-- | /O(1)/ Index safely into the vector using a type level index.+index :: forall i a n.+   ( KnownNat (ElemOffset a i n)+   , Storable a+   ) => Vector n a -> a+{-# INLINABLE index #-}+index (Vector b) = bufferPeekStorableAt b (natValue @(ElemOffset a i n))++-- | Convert a list into a vector if the number of elements matches+fromList :: forall a (n :: Nat) .+   ( KnownNat n+   , Storable a+   ) => [a] -> Maybe (Vector n a)+{-# INLINABLE fromList #-}+fromList v+   | n' /= n   = Nothing+   | n' == 0   = Just $ Vector $ emptyBuffer+   | otherwise = Just $ Vector $ bufferPackStorableList v+   where+      n' = natValue' @n+      n  = fromIntegral (List.length v)++-- | Take at most n element from the list, then use z+fromFilledList :: forall a (n :: Nat) .+   ( KnownNat n+   , Storable a+   ) => a -> [a] -> Vector n a+{-# INLINABLE fromFilledList #-}+fromFilledList z v = Vector $ bufferPackStorableList v'+   where+      v' = List.take (natValue @n) (v ++ repeat z)++-- | Take at most (n-1) element from the list, then use z+fromFilledListZ :: forall a (n :: Nat) .+   ( KnownNat n+   , Storable a+   ) => a -> [a] -> Vector n a+{-# INLINABLE fromFilledListZ #-}+fromFilledListZ z v = fromFilledList z v'+   where+      v' = List.take (natValue @n - 1) v++-- | Convert a vector into a list+toList :: forall a (n :: Nat) .+   ( KnownNat n+   , Storable a+   ) => Vector n a -> [a]+{-# INLINABLE toList #-}+toList (Vector b)+   | n == 0    = []+   | otherwise = fmap (bufferPeekStorableAt b . (sza*)) [0..n-1]+   where+      n   = natValue @n+      sza = sizeOfT' @a++-- | Create a vector by replicating a value+replicate :: forall a (n :: Nat) .+   ( KnownNat n+   , Storable a+   ) => a -> Vector n a+{-# INLINABLE replicate #-}+replicate v = fromFilledList v []+++data StoreVector = StoreVector -- Store a vector at the right offset++instance forall n v a r.+   ( v ~ Vector n a+   , r ~ IO (Ptr a)+   , KnownNat n+   , KnownNat (SizeOf a)+   , StaticStorable a+   , Storable a+   ) => Apply StoreVector (v, IO (Ptr a)) r where+      apply _ (v, getP) = do+         p <- getP+         let+            vsz = natValue @n+            p'  = p `plusPtr` (-1 * vsz * fromIntegral (sizeOfT @a))+         poke (castPtr p') v +         return p'++type family WholeSize fs :: Nat where+   WholeSize '[]                 = 0+   WholeSize (Vector n s ': xs)  = n + WholeSize xs++-- | Concat several vectors into a single one+concat :: forall l (n :: Nat) a .+   ( n ~ WholeSize l+   , KnownNat n+   , Storable a+   , StaticStorable a+   , HFoldr StoreVector (IO (Ptr a)) l (IO (Ptr a))+   )+   => HList l -> Vector n a+concat vs = unsafePerformIO $ do+   let sz = sizeOfT @a * natValue @n+   p <- mallocBytes (fromIntegral sz) :: IO (Ptr ())+   _ <- hFoldr StoreVector (return (castPtr p `plusPtr` fromIntegral sz) :: IO (Ptr a)) vs :: IO (Ptr a)+   Vector <$> bufferUnsafePackPtr (fromIntegral sz) p+++-- | Zip two vectors+zipWith ::+   ( KnownNat n+   , Storable a+   , Storable b+   , Storable c+   ) => (a -> b -> c) -> Vector n a -> Vector n b -> Vector n c+zipWith f u v = fromJust . fromList <| List.zipWith f (toList u) (toList v)++-- | map+map ::+   ( KnownNat n+   , Storable a+   , Storable b+   ) => (a -> b) -> Vector n a -> Vector n b+map f = fromJust . fromList . fmap f . toList++instance+   ( KnownNat n+   , Storable a+   , Eq a+   )+   => Eq (Vector n a)+   where+      u == v = toList u == toList v+++instance+   ( KnownNat n+   , Bitwise a+   , Storable a+   ) => Bitwise (Vector n a)+   where+      u .&. v        = zipWith (.&.) u v+      u .|. v        = zipWith (.|.) u v+      u `xor` v      = zipWith xor u v+++instance+   ( KnownNat (BitSize a)+   , FiniteBits a+   , KnownNat n+   , Storable a+   ) => FiniteBits (Vector n a)+   where+      type BitSize (Vector n a) = n * BitSize a+      zeroBits = fromJust (fromList (List.replicate (natValue @n) zeroBits))+      oneBits  = fromJust (fromList (List.replicate (natValue @n) oneBits))+      complement u = map complement u+      countLeadingZeros = go 0 . toList+         where+            go !n []     = n+            go !n (x:xs) = let c = countLeadingZeros x+                           in if c == natValue @(BitSize a)+                                 then go (n+c) xs+                                 else n+c++      countTrailingZeros = go 0 . reverse . toList+         where+            go !n []     = n+            go !n (x:xs) = let c = countTrailingZeros x+                           in if c == natValue @(BitSize a)+                                 then go (n+c) xs+                                 else n+c++instance+   ( Storable a+   , ShiftableBits a+   , Bitwise a+   , FiniteBits a+   , KnownNat (BitSize a)+   , KnownNat (n * BitSize a)+   , KnownNat n+   ) => ShiftableBits (Vector n a)+   where+      shiftL u c = uncheckedShiftL u (c `mod` natValue @(BitSize (Vector n a)))+      shiftR u c = uncheckedShiftR u (c `mod` natValue @(BitSize (Vector n a)))++      uncheckedShiftL u c =+         let n  = natValue @n+             sa = natValue @(BitSize a)+             go _ 0 _       = []+             go 0 k xs      = List.take k xs+             go s k xs+                | s >= sa   = go (s-sa) k (List.tail xs)+                | otherwise =+                   let (x:y:zs) = xs+                   in ((x `shiftL` s) .|. (y `shiftR` (sa-s))) : go s (k-1) (y:zs)+         in fromJust (fromList (go c n (toList u ++ List.repeat zeroBits)))++      uncheckedShiftR u c  =+         let n  = natValue @n+             sa = natValue @(BitSize a)+             go _ 0 _       = []+             go 0 k xs      = List.take k (List.tail xs)+             go s k xs+                | s >= sa   = zeroBits : go (s-sa) (k-1) xs+                | otherwise =+                   let (x:y:zs) = xs+                   in ((x `shiftL` (sa-s)) .|. (y `shiftR` s)) : go s (k-1) (y:zs)+         in fromJust (fromList (go c n (zeroBits : toList u)))+++instance+   ( Storable a+   , IndexableBits a+   , FiniteBits a+   , KnownNat (BitSize a)+   , KnownNat n+   , Bitwise a+   ) => IndexableBits (Vector n a) where++      popCount = sum . fmap popCount . toList++      bit i    = let n     = natValue @n+                     sa    = natValue @(BitSize a)+                     (f,r) = i `divMod` sa+                     toRep = fromIntegral (n - f - 1)+                     xs    = List.replicate toRep zeroBits+                              ++ [bit r]+                              ++ List.replicate (fromIntegral f) zeroBits+                 in fromJust <| fromList <| if i >= n * sa+                     then List.replicate (fromIntegral n) zeroBits+                     else xs++      testBit u i = let n      = natValue @n+                        sa     = natValue @(BitSize a)+                        (f,r)  = i `divMod` sa+                        toDrop = fromIntegral (n - f - 1)+                    in if i >= n * sa+                        then False+                        else testBit (List.head (List.drop toDrop (toList u))) r+++instance+   ( Storable a+   , Bits a+   , KnownNat n+   , KnownNat (n * BitSize a)+   ) => RotatableBits (Vector n a)
− src/lib/Haskus/Format/Binary/BitField.hs
@@ -1,365 +0,0 @@-{-# LANGUAGE DataKinds #-}-{-# LANGUAGE KindSignatures #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE TypeOperators #-}-{-# LANGUAGE TypeApplications #-}-{-# LANGUAGE UndecidableInstances #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE GeneralizedNewtypeDeriving #-}-{-# LANGUAGE MultiParamTypeClasses  #-}-{-# LANGUAGE AllowAmbiguousTypes #-}---- | Bit fields (as in C)------ This module allows you to define bit fields over words. For instance, you can--- have a Word16 split into 3 fields X, Y and Z composed of 5, 9 and 2 bits--- respectively.------ @                  X             Y          Z   @--- @ w :: Word16 |0 0 0 0 0|0 0 0 0 0 0 0 0 0|0 0| @--- --- You define it as follows:------ @--- {-# LANGUAGE DataKinds #-}------ w :: BitFields Word16 '[ BitField 5 "X" Word8 ---                        , BitField 9 "Y" Word16---                        , BitField 2 "Z" Word8---                        ]--- w = BitFields 0x0102--- @------ Note that each field has its own associated type (e.g. Word8 for X and Z)--- that must be large enough to hold the number of bits for the field.------ Operations on BitFields expect that the cumulated size of the fields is equal--- to the whole word size: use a padding field if necessary. Otherwise you can--- use unsafe versions of the functions: extractField', updateField',--- withField'.--- --- You can extract and update the value of a field by its name:------ @--- x = extractField @"X" w--- z = extractField @"Z" w--- w' = updateField @"Y" 0x16 w--- @------ Fields can also be 'BitSet' or 'EnumField':------ @--- {-# LANGUAGE DataKinds #-}------ data A = A0 | A1 | A2 | A3 deriving (Enum,CEnum)------ data B = B0 | B1 deriving (Enum,CBitSet)------ w :: BitFields Word16 '[ BitField 5 "X" (EnumField Word8 A)---                        , BitField 9 "Y" Word16---                        , BitField 2 "Z" (BitSet Word8 B)---                        ]--- w = BitFields 0x0102--- @----module Haskus.Format.Binary.BitField-   ( BitFields (..)-   , bitFieldsBits-   , BitField (..)-   , extractField-   , extractField'-   , updateField-   , updateField'-   , withField-   , withField'-   , matchFields-   , matchNamedFields-   , Field-   )-where--import Haskus.Format.Binary.BitSet as BitSet-import Haskus.Format.Binary.Enum-import Haskus.Format.Binary.Word-import Haskus.Format.Binary.Bits-import Haskus.Format.Binary.Storable-import Haskus.Utils.HList-import Haskus.Utils.Types---- | Bit fields on a base type b-newtype BitFields b (f :: [*]) = BitFields b deriving (Storable)---- | Get backing word-bitFieldsBits :: BitFields b f -> b-{-# INLINABLE bitFieldsBits #-}-bitFieldsBits (BitFields b) = b----- | A field of n bits-newtype BitField (n :: Nat) (name :: Symbol) s = BitField s deriving (Storable)---- | Get the bit offset of a field from its name-type family Offset (name :: Symbol) fs :: Nat where-   Offset name (BitField n name  s ': xs) = AddOffset xs-   Offset name (BitField n name2 s ': xs) = Offset name xs--type family AddOffset fs :: Nat where-   AddOffset '[]                        = 0-   AddOffset (BitField n name s ': xs)  = n + AddOffset xs---- | Get the type of a field from its name-type family Output (name :: Symbol) fs :: * where-   Output name (BitField n name  s ': xs) = s-   Output name (BitField n name2 s ': xs) = Output name xs---- | Get the size of a field from it name-type family Size (name :: Symbol) fs :: Nat where-   Size name (BitField n name  s ': xs) = n-   Size name (BitField n name2 s ': xs) = Size name xs---- | Get the whole size of a BitFields-type family WholeSize fs :: Nat where-   WholeSize '[]                        = 0-   WholeSize (BitField n name s ': xs)  = n + WholeSize xs--type family BitFieldTypes xs where-   BitFieldTypes '[]                       = '[]-   BitFieldTypes (BitField n name s ': xs) = s ': BitFieldTypes xs--class Field f where-   fromField :: Integral b => f -> b-   toField   :: Integral b => b -> f--instance Field Bool where-   fromField True  = 1-   fromField False = 0-   toField 0  = False-   toField _  = True--instance Field Word where-   fromField = fromIntegral-   toField   = fromIntegral--instance Field Word8 where-   fromField = fromIntegral-   toField   = fromIntegral--instance Field Word16 where-   fromField = fromIntegral-   toField   = fromIntegral--instance Field Word32 where-   fromField = fromIntegral-   toField   = fromIntegral--instance Field Word64 where-   fromField = fromIntegral-   toField   = fromIntegral--instance Field Int where-   fromField = fromIntegral-   toField   = fromIntegral--instance Field Int8 where-   fromField = fromIntegral-   toField   = fromIntegral--instance Field Int16 where-   fromField = fromIntegral-   toField   = fromIntegral--instance Field Int32 where-   fromField = fromIntegral-   toField   = fromIntegral--instance Field Int64 where-   fromField = fromIntegral-   toField   = fromIntegral--instance (FiniteBits b, Integral b, CBitSet a) => Field (BitSet b a) where-   fromField = fromIntegral . BitSet.toBits-   toField   = BitSet.fromBits . fromIntegral--instance (Integral b, CEnum a) => Field (EnumField b a) where-   fromField = fromCEnum . fromEnumField-   toField   = toEnumField . toCEnum---- | Get the value of a field-extractField :: forall (name :: Symbol) fields b .-   ( KnownNat (Offset name fields)-   , KnownNat (Size name fields)-   , WholeSize fields ~ BitSize b-   , Bits b, Integral b-   , Field (Output name fields)-   ) => BitFields b fields -> Output name fields-{-# INLINABLE extractField #-}-extractField = extractField' @name---- | Get the value of a field (without checking sizes)-extractField' :: forall (name :: Symbol) fields b .-   ( KnownNat (Offset name fields)-   , KnownNat (Size name fields)-   , Bits b, Integral b-   , Field (Output name fields)-   ) => BitFields b fields -> Output name fields-{-# INLINABLE extractField' #-}-extractField' (BitFields w) = toField ((w `shiftR` off) .&. ((1 `shiftL` sz) - 1))-   where-      off = natValue @(Offset name fields)-      sz  = natValue @(Size name fields)----- | Set the value of a field-updateField :: forall name fields b .-   ( KnownNat (Offset name fields)-   , KnownNat (Size name fields)-   , WholeSize fields ~ BitSize b-   , Bits b, Integral b-   , Field (Output name fields)-   ) => Output name fields -> BitFields b fields -> BitFields b fields-{-# INLINABLE updateField #-}-updateField = updateField' @name---- | Set the value of a field (without checking sizes)-updateField' :: forall name fields b .-   ( KnownNat (Offset name fields)-   , KnownNat (Size name fields)-   , Bits b, Integral b-   , Field (Output name fields)-   ) => Output name fields -> BitFields b fields -> BitFields b fields-{-# INLINABLE updateField' #-}-updateField' value (BitFields w) = BitFields $ ((fromField value `shiftL` off) .&. mask') .|. (w .&. complement mask')-   where-      off   = natValue @(Offset name fields)-      sz    = natValue @(Size name fields)-      mask' = ((1 `shiftL` sz) - 1) `shiftL` off----- | Modify the value of a field-withField :: forall name fields b f .-   ( KnownNat (Offset name fields)-   , KnownNat (Size name fields)-   , WholeSize fields ~ BitSize b-   , Bits b, Integral b-   , f ~ Output name fields-   , Field f-   ) => (f -> f) -> BitFields b fields -> BitFields b fields-{-# INLINABLE withField #-}-withField = withField' @name---- | Modify the value of a field (without checking sizes)-withField' :: forall (name :: Symbol) fields b f .-   ( KnownNat (Offset name fields)-   , KnownNat (Size name fields)-   , Bits b, Integral b-   , f ~ Output name fields-   , Field f-   ) => (f -> f) -> BitFields b fields -> BitFields b fields-{-# INLINABLE withField' #-}-withField' f bs = updateField' @name (f v) bs-   where-      v = extractField' @name bs------------------------------------------------------------------------------------------- We use HFoldr' to extract each component and create a HList from it. Then we--- convert it into a Tuple---------------------------------------------------------------------------------------data Extract = Extract-data Name    = Name--instance forall name bs b l l2 i (n :: Nat) s r w .-   ( bs ~ BitFields w l                    -- the bitfields-   , b ~ BitField n name s                 -- the current field-   , i ~ (bs, HList l2)                    -- input type-   , r ~ (bs, HList (Output name l ': l2)) -- result type-   , BitSize w ~ WholeSize l-   , Integral w, Bits w-   , KnownNat (Offset name l)-   , KnownNat (Size name l)-   , Field (Output name l)-   ) => Apply Extract (b, i) r where-      apply _ (_, (bs,xs)) =-         (bs, HCons (extractField @name bs) xs)--instance forall name bs b l l2 i (n :: Nat) s r w .-   ( bs ~ BitFields w l       -- the bitfields-   , b ~ BitField n name s    -- the current field-   , i ~ HList l2             -- input type-   , r ~ HList (String ': l2) -- result type-   , KnownSymbol name-   ) => Apply Name (b, i) r where-      apply _ (_, xs) = HCons (symbolValue @name) xs--fieldValues :: forall l l2 w bs .-   ( bs ~ BitFields w l-   , HFoldr' Extract (bs, HList '[]) l (bs, HList l2)-   ) => bs -> HList l2-fieldValues bs = snd res-   where-      res :: (bs, HList l2)-      res = hFoldr' Extract ((bs, HNil) :: (bs, HList '[])) (undefined :: HList l)--fieldNames :: forall l l2 w bs .-   ( bs ~ BitFields w l-   , HFoldr' Name (HList '[]) l (HList l2)-   ) => bs -> HList l2-fieldNames _ = hFoldr' Name (HNil :: HList '[]) (undefined :: HList l)---- | Get values in a tuple-matchFields :: forall l l2 w bs t .-   ( bs ~ BitFields w l-   , HFoldr' Extract (bs, HList '[]) l (bs, HList l2)-   , HTuple' l2 t-   ) => bs -> t-matchFields = hToTuple' . fieldValues----- | Get field names and values in a tuple-matchNamedFields ::forall lt lv ln lnv w bs t .-   ( bs ~ BitFields w lt-   , HFoldr' Extract (bs, HList '[]) lt (bs, HList lv)-   , HFoldr' Name (HList '[]) lt (HList ln)-   , HZipList ln lv lnv-   , HTuple' lnv t-   ) => bs -> t-matchNamedFields = hToTuple' . matchNamedFields'---- | Get field names and values in a tuple-matchNamedFields' ::forall lt lv ln lnv w bs .-   ( bs ~ BitFields w lt-   , HFoldr' Extract (bs, HList '[]) lt (bs, HList lv)-   , HFoldr' Name (HList '[]) lt (HList ln)-   , HZipList ln lv lnv-   ) => bs -> HList lnv-matchNamedFields' bs = hZipList names values-   where-      names  = fieldNames bs-      values = fieldValues bs---- | Get field names and values in a tuple-instance forall lt ln lnv w bs.-   ( bs ~ BitFields w lt-   , ln ~ Replicate (Length lt) String-   , HFoldr' Extract (bs, HList '[]) lt (bs, HList (BitFieldTypes lt))-   , HFoldr' Name (HList '[]) lt (HList ln)-   , HZipList ln (BitFieldTypes lt) lnv-   , Show (HList lnv)-   ) => Show (BitFields w lt) where-      show bs = show (matchNamedFields' bs :: HList lnv)---instance forall lt lt2 w bs.-   ( bs ~ BitFields w lt-   , HFoldr' Extract (bs, HList '[]) lt (bs, HList lt2)-   , Eq (HList lt2)-   , lt2 ~ BitFieldTypes lt-   ) => Eq (BitFields w lt) where-   (==) x y = x' == y'-      where-         x' :: HList lt2-         x' = fieldValues x-         y' :: HList lt2-         y' = fieldValues y
− src/lib/Haskus/Format/Binary/BitSet.hs
@@ -1,296 +0,0 @@-{-# LANGUAGE GeneralizedNewtypeDeriving #-}-{-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE BangPatterns #-}-{-# LANGUAGE DefaultSignatures #-}-{-# LANGUAGE FlexibleContexts #-}---- | A bit set based on Enum to name the bits. Use bitwise operations and--- minimal storage in a safer way.------ Similar to Data.Bitset.Generic from bitset package, but------     * We don't have the Num constraint---     * We dont use the deprecated bitSize function---     * We use countTrailingZeros instead of iterating on the---     number of bits---     * We add a typeclass CBitSet------ Example:------ @--- {-# LANGUAGE DeriveAnyClass #-}--- data Flag---    = FlagXXX---    | FlagYYY---    | FlagWWW---    deriving (Show,Eq,Enum,CBitSet)------ -- Adapt the backing type, here we choose Word16--- type Flags = 'BitSet' Word16 Flag--- @------ Then you can convert (for free) a Word16 into Flags with 'fromBits' and--- convert back with 'toBits'.------ You can check if a flag is set or not with 'member' and 'notMember' and get--- a list of set flags with 'toList'. You can 'insert' or 'delete' flags. You--- can also perform set operations such as 'union' and 'intersection'.----module Haskus.Format.Binary.BitSet-   ( BitSet-   , CBitSet (..)-   , null-   , empty-   , singleton-   , insert-   , delete-   , toBits-   , fromBits-   , member-   , elem-   , notMember-   , elems-   , intersection-   , union-   , unions-   , fromListToBits-   , toListFromBits-   , enumerateSetBits-   , fromList-   , toList-   )-where--import Prelude hiding (null,elem)--import qualified GHC.Exts as Ext--import Data.Foldable (foldl')--import Haskus.Format.Binary.Bits-import Haskus.Format.Binary.Storable---- | A bit set: use bitwise operations (fast!) and minimal storage (sizeOf--- basetype)------ * b is the base type (Bits b)--- * a is the element type (Enum a)------ The elements in the Enum a are flags corresponding to each bit of b starting--- from the least-significant bit.-newtype BitSet b a = BitSet b deriving (Eq,Ord,Storable)--instance-   ( Show a-   , CBitSet a-   , FiniteBits b-   , IndexableBits b-   , Eq b-   ) => Show (BitSet b a)-   where-      show b = "fromList " ++ show (toList b)---- | Indicate if the set is empty-null ::-   ( FiniteBits b-   , Eq b-   ) => BitSet b a -> Bool-{-# INLINABLE null #-}-null (BitSet b) = b == zeroBits----- | Empty bitset-empty :: (FiniteBits b) => BitSet b a-{-# INLINABLE empty #-}-empty = BitSet zeroBits----- | Create a BitSet from a single element-singleton :: (IndexableBits b, CBitSet a) => a -> BitSet b a-{-# INLINABLE singleton #-}-singleton e = BitSet $ bit (toBitOffset e)----- | Insert an element in the set-insert :: (IndexableBits b, CBitSet a) => BitSet b a -> a -> BitSet b a-{-# INLINABLE insert #-}-insert (BitSet b) e = BitSet $ setBit b (toBitOffset e)----- | Remove an element from the set-delete :: (IndexableBits b, CBitSet a) => BitSet b a -> a -> BitSet b a-{-# INLINABLE delete #-}-delete (BitSet b) e = BitSet $ clearBit b (toBitOffset e)----- | Unwrap the bitset-toBits :: BitSet b a -> b-toBits (BitSet b) = b---- | Wrap a bitset-fromBits :: (CBitSet a, FiniteBits b) => b -> BitSet b a-fromBits = BitSet---- | Test if an element is in the set-member ::-   ( CBitSet a-   , FiniteBits b-   , IndexableBits b-   ) => BitSet b a -> a -> Bool-{-# INLINABLE member #-}-member (BitSet b) e = testBit b (toBitOffset e)----- | Test if an element is in the set-elem ::-   ( CBitSet a-   , FiniteBits b-   , IndexableBits b-   ) => a -> BitSet b a -> Bool-{-# INLINABLE elem #-}-elem e (BitSet b) = testBit b (toBitOffset e)----- | Test if an element is not in the set-notMember ::-   ( CBitSet a-   , FiniteBits b-   , IndexableBits b-   ) => BitSet b a -> a -> Bool-{-# INLINABLE notMember #-}-notMember b e = not (member b e)----- | Retrieve elements in the set-elems ::-   ( CBitSet a-   , FiniteBits b-   , IndexableBits b-   , Eq b-   ) => BitSet b a -> [a]-elems (BitSet b) = go b-   where-      go !c-         | c == zeroBits = []-         | otherwise     = let e = countTrailingZeros c in fromBitOffset e : go (clearBit c e)---- | Intersection of two sets-intersection ::-   ( FiniteBits b-   , Bitwise b-   ) => BitSet b a -> BitSet b a -> BitSet b a-{-# INLINABLE intersection #-}-intersection (BitSet b1) (BitSet b2) = BitSet (b1 .&. b2)----- | Intersection of two sets-union ::-   ( FiniteBits b-   , Bitwise b-   ) => BitSet b a -> BitSet b a -> BitSet b a-{-# INLINABLE union #-}-union (BitSet b1) (BitSet b2) = BitSet (b1 .|. b2)----- | Intersection of several sets-unions ::-   ( FiniteBits b-   , Bitwise b-   ) => [BitSet b a] -> BitSet b a-{-# INLINABLE unions #-}-unions = foldl' union empty----- | Bit set indexed with a-class CBitSet a where-   -- | Return the bit offset of an element-   toBitOffset         :: a -> Word-   default toBitOffset :: Enum a => a -> Word-   toBitOffset         = fromIntegral . fromEnum--   -- | Return the value associated with a bit offset-   fromBitOffset         :: Word -> a-   default fromBitOffset :: Enum a => Word -> a-   fromBitOffset         = toEnum . fromIntegral---- | It can be useful to get the indexes of the set bits-instance CBitSet Int where-   toBitOffset   = fromIntegral-   fromBitOffset = fromIntegral---- | It can be useful to get the indexes of the set bits-instance CBitSet Word where-   toBitOffset   = id-   fromBitOffset = id-   ----- | Convert a list of enum elements into a bitset Warning: b--- must have enough bits to store the given elements! (we don't--- perform any check, for performance reason)-fromListToBits ::-   ( CBitSet a-   , FiniteBits b-   , IndexableBits b-   , Foldable m-   ) => m a -> b-fromListToBits = toBits . fromList---- | Convert a bitset into a list of Enum elements-toListFromBits ::-   ( CBitSet a-   , FiniteBits b-   , IndexableBits b-   , Eq b-   ) => b -> [a]-toListFromBits = toList . BitSet---- | Convert a bitset into a list of Enum elements by testing the Enum values--- successively.------ The difference with `toListFromBits` is that extra values in the BitSet will--- be ignored.-enumerateSetBits ::-   ( CBitSet a-   , FiniteBits b-   , IndexableBits b-   , Eq b-   , Bounded a-   , Enum a-   ) => b -> [a]-enumerateSetBits b = go [] [minBound..]-   where-      go rs []     = rs-      go rs (x:xs)-         | member (BitSet b) x = go (x:rs) xs-         | otherwise           = go rs xs---- | Convert a set into a list-toList ::-   ( CBitSet a-   , FiniteBits b-   , IndexableBits b-   , Eq b-   ) => BitSet b a -> [a]-toList = elems---- | Convert a Foldable into a set-fromList ::-   ( CBitSet a-   , IndexableBits b-   , FiniteBits b-   , Foldable m-   ) => m a -> BitSet b a-fromList = foldl' insert (BitSet zeroBits)---instance-   ( FiniteBits b-   , IndexableBits b-   , CBitSet a-   , Eq b-   ) => Ext.IsList (BitSet b a)-   where-      type Item (BitSet b a) = a-      fromList = fromList-      toList   = toList
− src/lib/Haskus/Format/Binary/Bits.hs
@@ -1,113 +0,0 @@-{-# LANGUAGE TypeApplications #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE ConstraintKinds #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE DataKinds #-}---- | Operations on bits-module Haskus.Format.Binary.Bits-   ( Bits-   , FiniteBits (..)-   , IndexableBits (..)-   , ShiftableBits (..)-   , SignedShiftableBits (..)-   , RotatableBits (..)-   , Bitwise (..)-   -- * Bit reversal-   , ReversableBits (..)-   , reverseBitsGeneric-   , reverseLeastBits-   -- * Mask-   , MaskBits (..)-   , Maskable-   , maskDyn-   , mask-   -- * String conversion-   , bitsToString-   , bitsToStringN-   , bitsFromString-   -- * Shift-   , getBitRange-   -- * Various-   , bitOffset-   , byteOffset-   )-where--import Haskus.Utils.List (foldl')-import Haskus.Utils.Types-import Haskus.Format.Binary.Bits.Finite-import Haskus.Format.Binary.Bits.Index-import Haskus.Format.Binary.Bits.Reverse-import Haskus.Format.Binary.Bits.Rotate-import Haskus.Format.Binary.Bits.Shift-import Haskus.Format.Binary.Bits.Bitwise-import Haskus.Format.Binary.Bits.Order-import Haskus.Format.Binary.Bits.Mask-import Haskus.Format.Binary.Bits.Helper--type Bits a =-   ( Eq a-   , FiniteBits a-   , IndexableBits a-   , ShiftableBits a-   , Bitwise a-   , RotatableBits a-   , KnownNat (BitSize a)-   , MaskBits a-   )---- | Reverse the @n@ least important bits of the given value. The higher bits--- are set to 0.-reverseLeastBits ::-   ( ShiftableBits a-   , FiniteBits a-   , ReversableBits a-   , KnownNat (BitSize a)-   ) => Word -> a -> a-reverseLeastBits n value = reverseBits value `uncheckedShiftR` ((bitSize value) - n)---- | Convert bits into a string composed of '0' and '1' chars-bitsToString :: forall a.-   ( FiniteBits a-   , IndexableBits a-   , KnownNat (BitSize a)-   ) => a -> String-bitsToString = bitsToStringN (natValue @(BitSize a))---- | Convert a specified amount of bits into a string composed of '0' and '1' chars-bitsToStringN :: forall a.-   ( IndexableBits a-   ) => Word -> a -> String-bitsToStringN n x = fmap b [n-1, n-2 .. 0]-   where-      b v = if testBit x v then '1' else '0'---- | Convert a string of '0' and '1' chars into a word-bitsFromString :: Bits a => String -> a-bitsFromString xs = foldl' b zeroBits (reverse xs `zip` [0..])-   where-      b x ('0',i) = clearBit x i-      b x ('1',i) = setBit x i-      b _ (c,_)   = error $ "Invalid character in the string: " ++ [c]----- | `getBitRange bo offset n c` takes n bits at offset in c and put them in the--- least-significant bits of the result-getBitRange :: forall b.-   ( ShiftableBits b-   , ReversableBits b-   , FiniteBits b-   , KnownNat (BitSize b)-   , Bitwise b-   , MaskBits b-   ) => BitOrder -> Word -> Word -> b -> b-{-# INLINABLE getBitRange #-}-getBitRange bo o n c = case bo of-      BB -> maskDyn n $ c             `uncheckedShiftR` d-      BL -> maskDyn n $ reverseBits c `uncheckedShiftR` o-      LB -> maskDyn n $ reverseBits c `uncheckedShiftR` d-      LL -> maskDyn n $ c             `uncheckedShiftR` o-   where -      d  = bitSize c - n - o-
− src/lib/Haskus/Format/Binary/Bits/Bitwise.hs
@@ -1,84 +0,0 @@-{-# LANGUAGE MagicHash #-}-{-# LANGUAGE BangPatterns #-}---- | Bitwise bit operations-module Haskus.Format.Binary.Bits.Bitwise-   ( Bitwise (..)-   )-where--import Haskus.Format.Binary.Word-import GHC.Exts-import GHC.Num---- | Bitwise bit operations-class Bitwise a where-   -- | Bitwise "and"-   (.&.) :: a -> a -> a--   -- | Bitwise "or"-   (.|.) :: a -> a -> a--   -- | Bitwise "xor"-   xor :: a -> a -> a---instance Bitwise Word where-   (W# x#) .&.   (W# y#) = W# (x# `and#` y#)-   (W# x#) .|.   (W# y#) = W# (x# `or#` y#)-   (W# x#) `xor` (W# y#) = W# (x# `xor#` y#)--instance Bitwise Word8 where-   (W8# x#) .&.   (W8# y#) = W8# (x# `and#` y#)-   (W8# x#) .|.   (W8# y#) = W8# (x# `or#` y#)-   (W8# x#) `xor` (W8# y#) = W8# (x# `xor#` y#)--instance Bitwise Word16 where-   (W16# x#) .&.   (W16# y#) = W16# (x# `and#` y#)-   (W16# x#) .|.   (W16# y#) = W16# (x# `or#` y#)-   (W16# x#) `xor` (W16# y#) = W16# (x# `xor#` y#)--instance Bitwise Word32 where-   (W32# x#) .&.   (W32# y#) = W32# (x# `and#` y#)-   (W32# x#) .|.   (W32# y#) = W32# (x# `or#` y#)-   (W32# x#) `xor` (W32# y#) = W32# (x# `xor#` y#)--instance Bitwise Word64 where-   (W64# x#) .&.   (W64# y#) = W64# (x# `and#` y#)-   (W64# x#) .|.   (W64# y#) = W64# (x# `or#` y#)-   (W64# x#) `xor` (W64# y#) = W64# (x# `xor#` y#)--instance Bitwise Int where-   (I# x#) .&.   (I# y#) = I# (x# `andI#` y#)-   (I# x#) .|.   (I# y#) = I# (x# `orI#` y#)-   (I# x#) `xor` (I# y#) = I# (x# `xorI#` y#)--instance Bitwise Int8 where-   (I8# x#) .&.   (I8# y#) = I8# (word2Int# (int2Word# x# `and#` int2Word# y#))-   (I8# x#) .|.   (I8# y#) = I8# (word2Int# (int2Word# x# `or#`  int2Word# y#))-   (I8# x#) `xor` (I8# y#) = I8# (word2Int# (int2Word# x# `xor#` int2Word# y#))--instance Bitwise Int16 where-   (I16# x#) .&.   (I16# y#) = I16# (word2Int# (int2Word# x# `and#` int2Word# y#))-   (I16# x#) .|.   (I16# y#) = I16# (word2Int# (int2Word# x# `or#`  int2Word# y#))-   (I16# x#) `xor` (I16# y#) = I16# (word2Int# (int2Word# x# `xor#` int2Word# y#))--instance Bitwise Int32 where-   (I32# x#) .&.   (I32# y#) = I32# (word2Int# (int2Word# x# `and#` int2Word# y#))-   (I32# x#) .|.   (I32# y#) = I32# (word2Int# (int2Word# x# `or#`  int2Word# y#))-   (I32# x#) `xor` (I32# y#) = I32# (word2Int# (int2Word# x# `xor#` int2Word# y#))--instance Bitwise Int64 where-   (I64# x#) .&.   (I64# y#) = I64# (word2Int# (int2Word# x# `and#` int2Word# y#))-   (I64# x#) .|.   (I64# y#) = I64# (word2Int# (int2Word# x# `or#`  int2Word# y#))-   (I64# x#) `xor` (I64# y#) = I64# (word2Int# (int2Word# x# `xor#` int2Word# y#))--instance Bitwise Integer where-   (.&.)      = andInteger-   (.|.)      = orInteger-   xor        = xorInteger--instance Bitwise Natural where-   (.&.)      = andNatural-   (.|.)      = orNatural-   xor        = xorNatural
− src/lib/Haskus/Format/Binary/Bits/Finite.hs
@@ -1,135 +0,0 @@-{-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE TypeApplications #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE ConstrainedClassMethods #-}-{-# LANGUAGE MagicHash #-}-{-# LANGUAGE BangPatterns #-}-{-# LANGUAGE CPP #-}-{-# LANGUAGE DefaultSignatures #-}-{-# LANGUAGE DataKinds #-}-{-# LANGUAGE ScopedTypeVariables #-}---- | Types with finite bit count-module Haskus.Format.Binary.Bits.Finite-   ( FiniteBits (..)-   )-where--import Haskus.Utils.Types-import Haskus.Format.Binary.Word-import GHC.Exts--#include "MachDeps.h"---- | Type representable by a fixed amount of bits-class FiniteBits a where--   -- | Number of bits-   type BitSize a :: Nat--   -- | Number of bits (the value is ignored)-   bitSize :: (Integral i, KnownNat (BitSize a)) => a -> i-   bitSize _ = natValue @(BitSize a)-   -   -- | All bits set to 0-   zeroBits :: a--   -- | All bits set to 1-   oneBits :: a-   oneBits = complement zeroBits--   -- | Count number of zero bits preceding the most significant set bit-   countLeadingZeros :: a -> Word--   -- | Count number of zero bits following the least significant set bit-   countTrailingZeros :: a -> Word--   -- | Complement-   complement :: a -> a---instance FiniteBits Word where-   type BitSize Word          = WORD_SIZE_IN_BITS-   zeroBits                   = 0-   oneBits                    = maxBound-   countLeadingZeros  (W# x#) = W# (clz# x#)-   countTrailingZeros (W# x#) = W# (ctz# x#)-   complement (W# x#)         = W# (x# `xor#` mb#)-      where !(W# mb#) = maxBound--instance FiniteBits Word8 where-   type BitSize Word8          = 8-   zeroBits                    = 0-   oneBits                     = maxBound-   countLeadingZeros  (W8# x#) = W# (clz8# x#)-   countTrailingZeros (W8# x#) = W# (ctz8# x#)-   complement (W8# x#)         = W8# (x# `xor#` mb#)-      where !(W8# mb#) = maxBound--instance FiniteBits Word16 where-   type BitSize Word16          = 16-   zeroBits                     = 0-   oneBits                      = maxBound-   countLeadingZeros  (W16# x#) = W# (clz16# x#)-   countTrailingZeros (W16# x#) = W# (ctz16# x#)-   complement (W16# x#)         = W16# (x# `xor#` mb#)-      where !(W16# mb#) = maxBound--instance FiniteBits Word32 where-   type BitSize Word32          = 32-   zeroBits                     = 0-   oneBits                      = maxBound-   countLeadingZeros  (W32# x#) = W# (clz32# x#)-   countTrailingZeros (W32# x#) = W# (ctz32# x#)-   complement (W32# x#)         = W32# (x# `xor#` mb#)-      where !(W32# mb#) = maxBound--instance FiniteBits Word64 where-   type BitSize Word64          = 64-   zeroBits                     = 0-   oneBits                      = maxBound-   countLeadingZeros  (W64# x#) = W# (clz64# x#)-   countTrailingZeros (W64# x#) = W# (ctz64# x#)-   complement (W64# x#)         = W64# (x# `xor#` mb#)-      where !(W64# mb#) = maxBound---instance FiniteBits Int where-   type BitSize Int           = WORD_SIZE_IN_BITS-   zeroBits                   = 0-   oneBits                    = (-1)-   countLeadingZeros  (I# x#) = W# (clz# (int2Word# x#))-   countTrailingZeros (I# x#) = W# (ctz# (int2Word# x#))-   complement (I# x#)         = I# (notI# x#)--instance FiniteBits Int8 where-   type BitSize Int8           = 8-   zeroBits                    = 0-   oneBits                     = (-1)-   countLeadingZeros  (I8# x#) = W# (clz8# (int2Word# x#))-   countTrailingZeros (I8# x#) = W# (ctz8# (int2Word# x#))-   complement (I8# x#)         = I8# (word2Int# (not# (int2Word# x#)))--instance FiniteBits Int16 where-   type BitSize Int16           = 16-   zeroBits                     = 0-   oneBits                      = (-1)-   countLeadingZeros  (I16# x#) = W# (clz16# (int2Word# x#))-   countTrailingZeros (I16# x#) = W# (ctz16# (int2Word# x#))-   complement (I16# x#)         = I16# (word2Int# (not# (int2Word# x#)))--instance FiniteBits Int32 where-   type BitSize Int32           = 32-   zeroBits                     = 0-   oneBits                      = (-1)-   countLeadingZeros  (I32# x#) = W# (clz32# (int2Word# x#))-   countTrailingZeros (I32# x#) = W# (ctz32# (int2Word# x#))-   complement (I32# x#)         = I32# (word2Int# (not# (int2Word# x#)))--instance FiniteBits Int64 where-   type BitSize Int64           = 64-   zeroBits                     = 0-   oneBits                      = (-1)-   countLeadingZeros  (I64# x#) = W# (clz64# (int2Word# x#))-   countTrailingZeros (I64# x#) = W# (ctz64# (int2Word# x#))-   complement (I64# x#)         = I64# (word2Int# (int2Word# x# `xor#` int2Word# (-1#)))
− src/lib/Haskus/Format/Binary/Bits/Get.hs
@@ -1,236 +0,0 @@-{-# LANGUAGE BangPatterns #-}-{-# LANGUAGE FlexibleContexts #-}---- | Bit getter-module Haskus.Format.Binary.Bits.Get-   ( BitGetState(..)-   , newBitGetState-   , isEmpty-   , skipBits-   , skipBitsToAlignOnWord8-   , getBits-   , getBitsChecked-   , getBitsBuffer-   -- * Monadic-   , BitGet-   , BitGetT-   , runBitGet-   , runBitGetT-   , runBitGetPartialT-   , runBitGetPartial-   , resumeBitGetPartialT-   , resumeBitGetPartial-   , isEmptyM-   , skipBitsM-   , skipBitsToAlignOnWord8M-   , getBitsM-   , getBitsCheckedM-   , getBitBoolM-   , getBitsBSM-   , changeBitGetOrder-   , withBitGetOrder-   )-where--import System.IO.Unsafe (unsafePerformIO)-import Control.Monad.State-import Control.Monad.Identity--import Haskus.Format.Binary.Ptr-import Haskus.Format.Binary.Buffer-import Haskus.Format.Binary.Bits.Order-import Haskus.Format.Binary.Bits-import Haskus.Format.Binary.Storable (poke)---- | BitGet state-data BitGetState = BitGetState-   { bitGetStateInput      :: {-# UNPACK #-} !Buffer     -- ^ Input-   , bitGetStateBitOffset  :: {-# UNPACK #-} !Word       -- ^ Bit offset (0-7)-   , bitGetStateBitOrder   ::                !BitOrder   -- ^ Bit order-   } deriving (Show)---- | Create a new BitGetState-newBitGetState :: BitOrder -> Buffer -> BitGetState-newBitGetState bo bs = BitGetState bs 0 bo---- | Indicate that the source is empty-isEmpty :: BitGetState -> Bool-isEmpty (BitGetState bs o _) = o == 0 && isBufferEmpty bs---- | Skip the given number of bits from the input-skipBits :: Word -> BitGetState -> BitGetState-skipBits o (BitGetState bs n bo) = BitGetState (bufferUnsafeDrop d bs) n' bo-   where-      !o' = n+o-      !d  = fromIntegral $ byteOffset o'-      !n' = bitOffset o'---- | Skip the required number of bits to be aligned on 8-bits-skipBitsToAlignOnWord8 :: BitGetState -> BitGetState-skipBitsToAlignOnWord8 s = case bitGetStateBitOffset s of-   0 -> s-   n -> skipBits (8-n) s---- | Read the given number of bits and put the result in a word-getBits :: (Integral a, Bits a) => Word -> BitGetState -> a-getBits nbits (BitGetState bs off bo) = rec zeroBits 0 bs off nbits-   where-      -- w   = current result-      -- n   = number of valid bits in w-      -- i   = input bytestring-      -- o   = bit offset in input bytestring-      -- r   = number of remaining bits to read-      rec w _ _ _ 0 = w-      rec w n i o r = rec nw (n+nb) (bufferTail i) o' (r-nb)-         where -            -- current Word8-            c  = bufferHead i-            -- number of bits to take from the current Word8-            nb = min (8-o) r-            -- bits taken from the current Word8 and put in correct order in least-significant bits-            tc = fromIntegral $ getBitRange bo o nb c-            -- mix new bits with the current result-            nw = case bo of-                  BB -> (w `shiftL` fromIntegral nb) .|. tc-                  LB -> (w `shiftL` fromIntegral nb) .|. tc-                  BL -> (tc `shiftL` fromIntegral n) .|. w-                  LL -> (tc `shiftL` fromIntegral n) .|. w-            -- new offset ((o + nb) `mod` 8)-            o' = bitOffset (o + nb)---- | Perform some checks before calling getBits------ Check that the number of bits to read is not greater than the first parameter-getBitsChecked :: (Integral a, Bits a, ReversableBits a) => Word -> Word -> BitGetState -> a-{-# INLINABLE getBitsChecked #-}-getBitsChecked m n s-   | n > m     = error $ "Tried to read more than " ++ show m ++ " bits (" ++ show n ++")"-   | otherwise = getBits n s---- | Read the given number of Word8 and return them in a Buffer------ Examples:--- @  BB: xxxABCDE FGHIJKLM NOPxxxxx -> ABCDEFGH IJKLMNOP @--- @  LL: LMNOPxxx DEFGHIJK xxxxxABC -> ABCDEFGH IJKLMNOP @--- @  BL: xxxPONML KJIHGFED CBAxxxxx -> ABCDEFGH IJKLMNOP @--- @  LB: EDCBAxxx MLKJIHGF xxxxxPON -> ABCDEFGH IJKLMNOP @-getBitsBuffer :: Word -> BitGetState -> Buffer-getBitsBuffer n (BitGetState bs o bo) =-   if n == 0-      then emptyBuffer-      else-         let -            bs'  = bufferUnsafeTake (n+1) bs-            bs'' = bufferUnsafeTake n     bs-            rev  = bufferMap reverseBits-         in case (o,bo) of-            (0,BB) ->                     bs''-            (0,LL) ->       bufferReverse bs''-            (0,LB) -> rev                 bs''-            (0,BL) -> rev $ bufferReverse bs''-            (_,LL) ->                     getBitsBuffer n (BitGetState (bufferReverse bs') (8-o)  BB)-            (_,BL) -> rev . bufferReverse $ getBitsBuffer n (BitGetState bs'               o     BB)-            (_,LB) -> rev . bufferReverse $ getBitsBuffer n (BitGetState bs'               o     LL)-            (_,BB) -> unsafePerformIO $ do-               let len = n+1-               ptr <- mallocBytes (fromIntegral len)-               let f r i = do-                     let-                        w  = bufferUnsafeIndex bs (len-i)-                        w' = (w `shiftL` fromIntegral o) .|. r-                        r' = w `shiftR` (8-fromIntegral o)-                     poke (castPtr ptr `indexPtr` fromIntegral (len-i)) w'-                     return r'-               foldM_ f 0 [1..len]-               bufferUnsafeInit <$> bufferPackPtr len ptr------ | BitGet monad transformer-type BitGetT m a = StateT BitGetState m a---- | BitGet monad-type BitGet a    = BitGetT Identity a---- | Evaluate a BitGet monad-runBitGetT :: Monad m => BitOrder -> BitGetT m a -> Buffer -> m a-runBitGetT bo m bs = evalStateT m (newBitGetState bo bs)---- | Evaluate a BitGet monad-runBitGet :: BitOrder -> BitGet a -> Buffer -> a-runBitGet bo m bs = runIdentity (runBitGetT bo m bs)---- | Evaluate a BitGet monad, return the remaining state-runBitGetPartialT :: BitOrder -> BitGetT m a -> Buffer -> m (a, BitGetState)-runBitGetPartialT bo m bs = runStateT m (newBitGetState bo bs)---- | Evaluate a BitGet monad, return the remaining state-runBitGetPartial :: BitOrder -> BitGet a -> Buffer -> (a, BitGetState)-runBitGetPartial bo m bs = runIdentity (runBitGetPartialT bo m bs)---- | Resume a BitGet evaluation-resumeBitGetPartialT :: BitGetT m a -> BitGetState -> m (a, BitGetState)-resumeBitGetPartialT = runStateT ---- | Resume a BitGet evaluation-resumeBitGetPartial :: BitGet a -> BitGetState -> (a,BitGetState)-resumeBitGetPartial m s = runIdentity (resumeBitGetPartialT m s)---- | Indicate if all bits have been read-isEmptyM :: Monad m => BitGetT m Bool-isEmptyM = gets isEmpty---- | Skip the given number of bits from the input (monadic version)-skipBitsM :: Monad m => Word -> BitGetT m ()-skipBitsM = modify . skipBits----- | Skip the required number of bits to be aligned on 8-bits (monadic version)-skipBitsToAlignOnWord8M :: Monad m =>  BitGetT m ()-skipBitsToAlignOnWord8M = modify skipBitsToAlignOnWord8---- | Read the given number of bits and put the result in a word-getBitsM :: (Integral a, Bits a, Monad m) => Word -> BitGetT m a-getBitsM n = do-   v <- gets (getBits n)-   skipBitsM n-   return v---- | Perform some checks before calling getBitsM-getBitsCheckedM :: (Integral a, Bits a, ReversableBits a, Monad m) => Word -> Word -> BitGetT m a-getBitsCheckedM m n = do-   v <- gets (getBitsChecked m n)-   skipBitsM n-   return v---- | Get a bit and convert it into a Bool-getBitBoolM :: (Monad m) => BitGetT m Bool-getBitBoolM = do-   v <- getBitsM 1-   return ((v :: Word) == 1)---- | Get the given number of Word8-getBitsBSM :: (Monad m) => Word -> BitGetT m Buffer-getBitsBSM n = do-   bs <- gets (getBitsBuffer n)-   skipBitsM (8*n)-   return bs---- | Change the current bit ordering------ Be careful to change the outer bit ordering (B* to L* or the inverse) only--- on bytes boundaries! Otherwise, you will read the same bits more than once.-changeBitGetOrder :: Monad m => BitOrder -> BitGetT m ()-changeBitGetOrder bo = modify (\s -> s { bitGetStateBitOrder = bo })---- | Change the bit ordering for the wrapped BitGet------ Be careful, this function uses changeBitGetOrder internally.-withBitGetOrder :: Monad m => BitOrder -> BitGetT m a -> BitGetT m a-withBitGetOrder bo m = do-   bo' <- gets bitGetStateBitOrder-   changeBitGetOrder bo-   v <- m-   changeBitGetOrder bo'-   return v-
− src/lib/Haskus/Format/Binary/Bits/Helper.hs
@@ -1,21 +0,0 @@-{-# LANGUAGE TypeApplications #-}-{-# LANGUAGE DataKinds #-}--module Haskus.Format.Binary.Bits.Helper-   ( bitOffset-   , byteOffset-   )-where--import Haskus.Format.Binary.Bits.Shift-import Haskus.Format.Binary.Bits.Mask---- | Compute bit offset (equivalent to x `mod` 8 but faster)-bitOffset :: Word -> Word-{-# INLINABLE bitOffset #-}-bitOffset n = mask @3 n---- | Compute byte offset (equivalent to x `div` 8 but faster)-byteOffset :: Word -> Word-{-# INLINABLE byteOffset #-}-byteOffset n = n `uncheckedShiftR` 3
− src/lib/Haskus/Format/Binary/Bits/Index.hs
@@ -1,82 +0,0 @@-{-# LANGUAGE DefaultSignatures #-}-{-# LANGUAGE BangPatterns #-}-{-# LANGUAGE MagicHash #-}---- | Bit indexable types-module Haskus.Format.Binary.Bits.Index-   ( IndexableBits (..)-   )-where--import Haskus.Format.Binary.Bits.Shift-import Haskus.Format.Binary.Bits.Bitwise-import Haskus.Format.Binary.Bits.Finite-import Haskus.Format.Binary.Word-import GHC.Exts---- | Type whose bits are indexable-class IndexableBits a where-   -- | @bit /i/@ is a value with the @/i/@th bit set and all other bits clear.-   bit :: Word -> a-   default bit :: (Num a, ShiftableBits a) => Word -> a-   bit i = 1 `shiftL` i--   -- | @x \`setBit\` i@ is the same as @x .|. bit i@-   setBit :: a -> Word -> a-   default setBit :: (Bitwise a) => a -> Word -> a-   setBit a i = a .|. bit i--   -- | @x \`clearBit\` i@ is the same as @x .&. complement (bit i)@-   clearBit :: a -> Word -> a-   default clearBit :: (FiniteBits a,Bitwise a) => a -> Word -> a-   clearBit a i = a .&. complement (bit i)--   -- | @x \`complementBit\` i@ is the same as @x \`xor\` bit i@-   complementBit :: a -> Word -> a-   default complementBit :: (Bitwise a) => a -> Word -> a-   complementBit a i = a `xor` bit i--   -- | Return 'True' if the @n@th bit of the argument is 1-   testBit :: a -> Word -> Bool-   default testBit :: (Bitwise a, Num a, Eq a) => a -> Word -> Bool-   testBit a i = (a .&. bit i) /= 0--   -- | Return the number of set bits-   popCount :: a -> Word-   default popCount :: (Bitwise a, Num a, Eq a) => a -> Word-   popCount = go 0-      where-         go !c 0 = c-         go c  w = go (c+1) (w .&. (w-1))---instance IndexableBits Word where-   popCount (W# x#) = W# (popCnt# x#)--instance IndexableBits Word8 where-   popCount (W8# x#) = W# (popCnt8# x#)--instance IndexableBits Word16 where-   popCount (W16# x#) = W# (popCnt16# x#)--instance IndexableBits Word32 where-   popCount (W32# x#) = W# (popCnt32# x#)--instance IndexableBits Word64 where-   popCount (W64# x#) = W# (popCnt64# x#)--instance IndexableBits Int where-   popCount (I# x#) = W# (popCnt# (int2Word# x#))--instance IndexableBits Int8 where-   popCount (I8# x#) = W# (popCnt8# (int2Word# x#))--instance IndexableBits Int16 where-   popCount (I16# x#) = W# (popCnt16# (int2Word# x#))--instance IndexableBits Int32 where-   popCount (I32# x#) = W# (popCnt32# (int2Word# x#))--instance IndexableBits Int64 where-   popCount (I64# x#) = W# (popCnt64# (int2Word# x#))-
− src/lib/Haskus/Format/Binary/Bits/Mask.hs
@@ -1,93 +0,0 @@-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE TypeApplications #-}-{-# LANGUAGE AllowAmbiguousTypes #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE ConstraintKinds #-}--module Haskus.Format.Binary.Bits.Mask-   ( MaskBits (..)-   , makeMaskFinite-   , makeMask-   , maskDyn-   , Maskable-   , mask-   )-where--import Haskus.Format.Binary.Bits.Finite-import Haskus.Format.Binary.Bits.Shift-import Haskus.Format.Binary.Bits.Bitwise-import Haskus.Format.Binary.Word-import Haskus.Utils.Types-import GHC.Natural---- | makeMaskFinite 3 = 00000111-makeMaskFinite :: forall a.-   ( ShiftableBits a-   , FiniteBits a-   , KnownNat (BitSize a)-   , Bitwise a-   ) => Word -> a-{-# INLINABLE makeMaskFinite #-}-makeMaskFinite n = complement zeroBits `shiftR` off-   where-      off = natValue' @(BitSize a) - n--{-# SPECIALIZE makeMaskFinite :: Word -> Int #-}-{-# SPECIALIZE makeMaskFinite :: Word -> Int8 #-}-{-# SPECIALIZE makeMaskFinite :: Word -> Int16 #-}-{-# SPECIALIZE makeMaskFinite :: Word -> Int32 #-}-{-# SPECIALIZE makeMaskFinite :: Word -> Int64 #-}-{-# SPECIALIZE makeMaskFinite :: Word -> Word #-}-{-# SPECIALIZE makeMaskFinite :: Word -> Word8 #-}-{-# SPECIALIZE makeMaskFinite :: Word -> Word16 #-}-{-# SPECIALIZE makeMaskFinite :: Word -> Word32 #-}-{-# SPECIALIZE makeMaskFinite :: Word -> Word64 #-}--class MaskBits a where-   -- | Make a mask dynamically-   makeMaskDyn :: Word -> a--instance MaskBits Natural where-   makeMaskDyn n = mkNatural (replicate (fromIntegral q) c ++ [makeMaskFinite r])-      where-         c = complement zeroBits-         (q,r) = n `quotRem` 32--instance MaskBits Word   where makeMaskDyn = makeMaskFinite-instance MaskBits Word8  where makeMaskDyn = makeMaskFinite-instance MaskBits Word16 where makeMaskDyn = makeMaskFinite-instance MaskBits Word32 where makeMaskDyn = makeMaskFinite-instance MaskBits Word64 where makeMaskDyn = makeMaskFinite-instance MaskBits Int    where makeMaskDyn = makeMaskFinite-instance MaskBits Int8   where makeMaskDyn = makeMaskFinite-instance MaskBits Int16  where makeMaskDyn = makeMaskFinite-instance MaskBits Int32  where makeMaskDyn = makeMaskFinite-instance MaskBits Int64  where makeMaskDyn = makeMaskFinite---- | Make a mask statically-makeMask :: forall n a.-   ( KnownNat n-   , MaskBits a-   ) => a-{-# INLINABLE makeMask #-}-makeMask = makeMaskDyn (natValue' @n)---- | Keep only the n least-significant bits of the given value-maskDyn ::-   ( MaskBits a-   , Bitwise a-   ) => Word -> a -> a-{-# INLINABLE maskDyn #-}-maskDyn n v = v .&. makeMaskDyn n---- | Keep only the n least-significant bits of the given value-mask :: forall n a. Maskable n a => a -> a-{-# INLINABLE mask #-}-mask v = v .&. makeMask @n--type Maskable n a =-   ( MaskBits a-   , Bitwise a-   , KnownNat n-   )
− src/lib/Haskus/Format/Binary/Bits/Order.hs
@@ -1,29 +0,0 @@--- | Bit orderings-module Haskus.Format.Binary.Bits.Order-   ( BitOrder(..)-   )-where---- | Bit order------ The first letter indicates the outer bit ordering, i.e. how bytes are filled:---  ---  * B?: from left to right (B is for BigEndian)---  * L?: from right to left (L is for LittleEndian)------ The second letter indicates the inner bit ordering, i.e. how words are stored:---   ---  * ?B: the most significant bit is stored first (in the outer bit order!)---  * ?L: the least-significant bit is stored first (in the outer bit order!)------ E.g. two successive words of 5 bits: ABCDE, VWXYZ--- @ BB: ABCDEVWX YZxxxxxx @  --- @ BL: EDCBAZYX WVxxxxxx @--- @ LB: XWVEDCBA xxxxxxZY @--- @ LL: XYZABCDE xxxxxxVW @-data BitOrder-   = BB-   | LB-   | BL-   | LL-   deriving (Show,Eq)
− src/lib/Haskus/Format/Binary/Bits/Put.hs
@@ -1,175 +0,0 @@-{-# LANGUAGE FlexibleContexts #-}---- | Bit putter-module Haskus.Format.Binary.Bits.Put-   ( BitPutState(..)-   , newBitPutState-   , putBits-   , putBitsBuffer-   , getBitPutBuffer-   , getBitPutBufferList-   -- * Monadic-   , BitPut-   , BitPutT-   , runBitPut-   , runBitPutT-   , putBitsM-   , putBitBoolM-   , putBitsBufferM-   , changeBitPutOrder-   , withBitPutOrder-   )-where--import Control.Monad.State-import Control.Monad.Identity--import Haskus.Format.Binary.BufferBuilder as B-import Haskus.Format.Binary.Buffer-import Haskus.Format.Binary.Word-import Haskus.Format.Binary.BufferList (BufferList)-import Haskus.Format.Binary.Bits.Order-import Haskus.Format.Binary.Bits----- | BitPut state-data BitPutState = BitPutState-   { bitPutStateBuilder          :: !BufferBuilder -- ^ Builder-   , bitPutStateCurrent          :: !Word8         -- ^ Current byte-   , bitPutStateOffset           :: !Word          -- ^ Current offset-   , bitPutStateBitOrder         :: !BitOrder      -- ^ Bit order-   }---- | Create a new BitPut state-newBitPutState :: BitOrder -> BitPutState-newBitPutState = BitPutState mempty 0 0---- | Put bits-putBits ::-   ( Integral a-   , Bits a-   , ReversableBits a-   ) => Word -> a -> BitPutState -> BitPutState-putBits n w s@(BitPutState builder b o bo) = s'-   where-      -- number of bits that will be stored in the current byte-      cn = min (8-o) n--      -- new state-      s' = case n of-            0 -> s-            _ -> putBits (n-cn) w' (flush (BitPutState builder b' (o+cn) bo))-      -      -- new current byte-      b' = shl (selectBits w) .|. b--      -- Word containing the remaining (n-cn) bits to store in its LSB-      w' = case bo of-         BB -> w-         BL -> w `shiftR` fromIntegral cn-         LL -> w `shiftR` fromIntegral cn-         LB -> w--      -- Select bits to store in the current byte.-      -- Put them in the correct order and return them in the least-significant-      -- bits of the returned value-      selectBits :: (Bits a, ReversableBits a, Integral a) => a -> Word8-      selectBits x = fromIntegral $ case bo of-         BB ->                       maskDyn cn $ x `shiftR` fromIntegral (n-cn)-         LB -> reverseLeastBits cn $ maskDyn cn $ x `shiftR` fromIntegral (n-cn)-         LL ->                       maskDyn cn x-         BL -> reverseLeastBits cn $ maskDyn cn x--      -- shift left at the correct position-      shl :: Word8 -> Word8-      shl x = case bo of-         BB -> x `shiftL` (8 - fromIntegral o - fromIntegral cn)-         BL -> x `shiftL` (8 - fromIntegral o - fromIntegral cn)-         LL -> x `shiftL` fromIntegral o-         LB -> x `shiftL` fromIntegral o--      -- flush the current byte if it is full-      flush s2@(BitPutState b2 w2 o2 bo2)-        | o2 == 8   = BitPutState (b2 `mappend` B.fromWord8 w2) 0 0 bo2-        | otherwise = s2----- | Put a Buffer------ Examples: 3 bits are already written in the current byte--- @  BB: ABCDEFGH IJKLMNOP -> xxxABCDE FGHIJKLM NOPxxxxx @--- @  LL: ABCDEFGH IJKLMNOP -> LMNOPxxx DEFGHIJK xxxxxABC @--- @  BL: ABCDEFGH IJKLMNOP -> xxxPONML KJIHGFED CBAxxxxx @--- @  LB: ABCDEFGH IJKLMNOP -> EDCBAxxx MLKJIHGF xxxxxPON @-putBitsBuffer :: Buffer -> BitPutState -> BitPutState-putBitsBuffer bs s-   | isBufferEmpty bs = s-   | otherwise  = case s of-      (BitPutState builder b 0 BB) -> BitPutState (builder `mappend` B.fromBuffer bs) b 0 BB-      (BitPutState builder b 0 LL) -> BitPutState (builder `mappend` B.fromBuffer (bufferReverse bs)) b 0 LL-      (BitPutState builder b 0 LB) -> BitPutState (builder `mappend` B.fromBuffer (rev bs)) b 0 LB-      (BitPutState builder b 0 BL) -> BitPutState (builder `mappend` B.fromBuffer (rev (bufferReverse bs))) b 0 BL-      (BitPutState _ _ _ BB)       -> putBitsBuffer (bufferUnsafeTail bs) (putBits 8 (bufferUnsafeHead bs) s)-      (BitPutState _ _ _ LL)       -> putBitsBuffer (bufferUnsafeInit bs) (putBits 8 (bufferUnsafeLast bs) s)-      (BitPutState _ _ _ BL)       -> putBitsBuffer (bufferUnsafeInit bs) (putBits 8 (bufferUnsafeLast bs) s)-      (BitPutState _ _ _ LB)       -> putBitsBuffer (bufferUnsafeTail bs) (putBits 8 (bufferUnsafeHead bs) s)-   where-      rev    = bufferMap reverseBits---- | Flush the current byte-flushIncomplete :: BitPutState -> BitPutState-flushIncomplete s@(BitPutState b w o bo)-  | o == 0    = s-  | otherwise = BitPutState (b `mappend` B.fromWord8 w) 0 0 bo---- | Get a buffer list-getBitPutBufferList :: BitPutState -> BufferList-getBitPutBufferList = toBufferList . bitPutStateBuilder . flushIncomplete ---- | Get a Buffer-getBitPutBuffer :: BitPutState -> Buffer-getBitPutBuffer =  toBuffer . bitPutStateBuilder . flushIncomplete---- | BitPut monad transformer-type BitPutT m a = StateT BitPutState m a---- | BitPut monad-type BitPut a    = BitPutT Identity a---- | Evaluate a BitPut monad-runBitPutT :: Monad m => BitOrder -> BitPutT m a -> m Buffer-runBitPutT bo m = getBitPutBuffer <$> execStateT m (newBitPutState bo)---- | Evaluate a BitPut monad-runBitPut :: BitOrder -> BitPut a -> Buffer-runBitPut bo m = runIdentity (runBitPutT bo m)---- | Put bits (monadic)-putBitsM :: (Monad m, Integral a, Bits a, ReversableBits a) => Word -> a -> BitPutT m ()-putBitsM n w = modify (putBits n w)---- | Put a single bit (monadic)-putBitBoolM :: (Monad m) => Bool -> BitPutT m ()-putBitBoolM b = putBitsM 1 (if b then 1 else  0 :: Word)---- | Put a Buffer (monadic)-putBitsBufferM :: Monad m => Buffer -> BitPutT m ()-putBitsBufferM bs = modify (putBitsBuffer bs)---- | Change the current bit ordering------ Be careful to change the outer bit ordering (B* to L* or the inverse) only--- on bytes boundaries! Otherwise, you will write the same bits more than once.-changeBitPutOrder :: Monad m => BitOrder -> BitPutT m ()-changeBitPutOrder bo = modify (\s -> s { bitPutStateBitOrder = bo })---- | Change the bit ordering for the wrapped BitPut------ Be careful, this function uses changeBitPutOrder internally.-withBitPutOrder :: Monad m => BitOrder -> BitPutT m a -> BitPutT m a-withBitPutOrder bo m = do-   bo' <- gets bitPutStateBitOrder-   changeBitPutOrder bo-   v <- m-   changeBitPutOrder bo'-   return v
− src/lib/Haskus/Format/Binary/Bits/Reverse.hs
@@ -1,339 +0,0 @@-{-# LANGUAGE BangPatterns #-}-{-# LANGUAGE TemplateHaskell #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE ScopedTypeVariables #-}---- | Reverse bits------ There are several algorithms performing the same thing here (reversing bits--- into words of different sizes). There are benchmarks for them in the --- "bench" directory. The fastest one for the current architecture should be--- selected below. If you find that another algorithm is faster on your--- architecture, please report it.-module Haskus.Format.Binary.Bits.Reverse-   ( -   -- * Generic-     ReversableBits (..)-   , reverseBitsGeneric-   -- * Algorithms-   , reverseBitsObvious-   , reverseBits3Ops-   , reverseBits4Ops-   , reverseBitsTable-   , reverseBits7Ops-   , reverseBits5LgN-   , liftReverseBits-   )-where--import Haskus.Format.Binary.Buffer-import Haskus.Format.Binary.Word-import Haskus.Format.Binary.Bits.Finite-import Haskus.Format.Binary.Bits.Shift-import Haskus.Format.Binary.Bits.Bitwise-import Haskus.Format.Binary.Bits.Index-import Haskus.Utils.Types (KnownNat)-------------------------------------------------------- Generic and specialized reverseBits--------------------------------------------------------- | Reverse bits in a Word-reverseBitsGeneric ::-   ( FiniteBits a-   , Integral a-   , ShiftableBits a-   , Bitwise a-   , KnownNat (BitSize a)-   ) => a -> a-reverseBitsGeneric = liftReverseBits reverseBits4Ops---- | Data whose bits can be reversed-class ReversableBits w where-   reverseBits :: w -> w--instance ReversableBits Word8 where-   reverseBits = reverseBits4Ops--instance ReversableBits Word16 where-   reverseBits = reverseBits5LgN--instance ReversableBits Word32 where-   reverseBits = reverseBits5LgN--instance ReversableBits Word64 where-   reverseBits = reverseBits5LgN--instance ReversableBits Word where-   reverseBits = reverseBits5LgN--instance ReversableBits Int8 where-   reverseBits = fromIntegral . reverseBits4Ops . fromIntegral--instance ReversableBits Int16 where-   reverseBits = reverseBits5LgN--instance ReversableBits Int32 where-   reverseBits = reverseBits5LgN--instance ReversableBits Int64 where-   reverseBits = reverseBits5LgN--instance ReversableBits Int where-   reverseBits = reverseBits5LgN--------------------------------------------------------- Bit reversal algorithms-------------------------------------------------------- Algorithms and explanations adapted from:--- http://graphics.stanford.edu/~seander/bithacks.html#ReverseByteWith64Bits---- Reverse the bits the obvious way--- ================================--------- unsigned int v;     // input bits to be reversed--- unsigned int r = v; // r will be reversed bits of v; first get LSB of v--- int s = sizeof(v) * CHAR_BIT - 1; // extra shift needed at end--- --- for (v >>= 1; v; v >>= 1)--- {   ---   r <<= 1;---   r |= v & 1;---   s--;--- }--- r <<= s; // shift when v's highest bits are zero------ On October 15, 2004, Michael Hoisie pointed out a bug in the original--- version. Randal E. Bryant suggested removing an extra operation on May 3,--- 2005. Behdad Esfabod suggested a slight change that eliminated one iteration--- of the loop on May 18, 2005. Then, on February 6, 2007, Liyong Zhou--- suggested a better version that loops while v is not 0, so rather than--- iterating over all bits it stops early. ---- | Obvious recursive version-reverseBitsObvious :: forall a.-   ( FiniteBits a-   , ShiftableBits a-   , IndexableBits a-   , Bitwise a-   , KnownNat (BitSize a)-   , Eq a-   ) => a -> a-reverseBitsObvious x = rec x (x `shiftR` 1) (bitSize x - 1)-   where-      rec :: FiniteBits a => a -> a -> Word -> a-      rec !r !v !s -         | v == zeroBits = r `shiftL` s-         | otherwise     = rec ((r `shiftL` 1) .|. (v .&. bit 0)) (v `shiftR` 1) (s - 1)--{-# SPECIALIZE reverseBitsObvious :: Word8  -> Word8  #-}-{-# SPECIALIZE reverseBitsObvious :: Word16 -> Word16 #-}-{-# SPECIALIZE reverseBitsObvious :: Word32 -> Word32 #-}-{-# SPECIALIZE reverseBitsObvious :: Word64 -> Word64 #-}---- Reverse the bits in a byte with 3 operations (64-bit multiply and modulus division) --- ===================================================================================--- --- unsigned char b; // reverse this (8-bit) byte---  --- b = (b * 0x0202020202ULL & 0x010884422010ULL) % 1023;--- --- The multiply operation creates five separate copies of the 8-bit byte--- pattern to fan-out into a 64-bit value. The AND operation selects the bits--- that are in the correct (reversed) positions, relative to each 10-bit groups--- of bits. The multiply and the AND operations copy the bits from the original--- byte so they each appear in only one of the 10-bit sets. The reversed--- positions of the bits from the original byte coincide with their relative--- positions within any 10-bit set. The last step, which involves modulus--- division by 2^10 - 1, has the effect of merging together each set of 10 bits--- (from positions 0-9, 10-19, 20-29, ...) in the 64-bit value. They do not--- overlap, so the addition steps underlying the modulus division behave like--- or operations.--- --- This method was attributed to Rich Schroeppel in the Programming Hacks--- section of Beeler, M., Gosper, R. W., and Schroeppel, R. HAKMEM. MIT AI Memo--- 239, Feb. 29, 1972.---- | Reverse bits in a Word8 (3 64-bit operations, modulus division)-reverseBits3Ops :: Word8 -> Word8-{-# INLINABLE reverseBits3Ops #-}-reverseBits3Ops x = fromIntegral x'-   where-      !x' = ((fromIntegral x * 0x0202020202 :: Word64) .&. 0x010884422010) `mod` 1023----- Reverse the bits in a byte with 4 operations (64-bit multiply, no division) --- ===========================================================================------ unsigned char b; // reverse this (8-bit) byte---  --- b = ((b * 0x80200802ULL) & 0x0884422110ULL) * 0x0101010101ULL >> 32;--- --- The following shows the flow of the bit values with the boolean variables a,--- b, c, d, e, f, g, and h, which comprise an 8-bit byte. Notice how the first--- multiply fans out the bit pattern to multiple copies, while the last--- multiply combines them in the fifth byte from the right. ---------                                                                                         abcd efgh (-> hgfe dcba)--- *                                                      1000 0000  0010 0000  0000 1000  0000 0010 (0x80200802)--- ----------------------------------------------------------------------------------------------------                                             0abc defg  h00a bcde  fgh0 0abc  defg h00a  bcde fgh0--- &                                           0000 1000  1000 0100  0100 0010  0010 0001  0001 0000 (0x0884422110)--- ----------------------------------------------------------------------------------------------------                                             0000 d000  h000 0c00  0g00 00b0  00f0 000a  000e 0000--- *                                           0000 0001  0000 0001  0000 0001  0000 0001  0000 0001 (0x0101010101)--- ----------------------------------------------------------------------------------------------------                                             0000 d000  h000 0c00  0g00 00b0  00f0 000a  000e 0000---                                  0000 d000  h000 0c00  0g00 00b0  00f0 000a  000e 0000---                       0000 d000  h000 0c00  0g00 00b0  00f0 000a  000e 0000---            0000 d000  h000 0c00  0g00 00b0  00f0 000a  000e 0000--- 0000 d000  h000 0c00  0g00 00b0  00f0 000a  000e 0000--- ---------------------------------------------------------------------------------------------------- 0000 d000  h000 dc00  hg00 dcb0  hgf0 dcba  hgfe dcba  hgfe 0cba  0gfe 00ba  00fe 000a  000e 0000--- >> 32--- ----------------------------------------------------------------------------------------------------                                             0000 d000  h000 dc00  hg00 dcb0  hgf0 dcba  hgfe dcba  --- &                                                                                       1111 1111--- ----------------------------------------------------------------------------------------------------                                                                                         hgfe dcba--- Note that the last two steps can be combined on some processors because the--- registers can be accessed as bytes; just multiply so that a register stores--- the upper 32 bits of the result and the take the low byte. Thus, it may take--- only 6 operations.--- --- Devised by Sean Anderson, July 13, 2001. ---- | Reverse bits in a Word8 (4 64-bit operations, no division)-reverseBits4Ops :: Word8 -> Word8-{-# INLINABLE reverseBits4Ops #-}-reverseBits4Ops x = fromIntegral x'-   where-      !x' = (((fromIntegral x * 0x80200802 :: Word64) .&. 0x0884422110) * 0x0101010101) `shiftR` 32----- Reverse bits using a lookup table--- =================================---- | Reverse bits using a lookup table-reverseBitsTable :: Word8 -> Word8-{-# INLINABLE reverseBitsTable #-}-reverseBitsTable x = bitsTable `bufferIndex` (fromIntegral x)----- fill the table by using another method-bitsTable :: Buffer-bitsTable = bufferPackByteList $ fmap reverseBits4Ops [0..255]---- Reverse the bits in a byte with 7 operations (no 64-bit)--- ========================================================--- --- b = ((b * 0x0802LU & 0x22110LU) | (b * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16; --- --- Make sure you assign or cast the result to an unsigned char to remove--- garbage in the higher bits. Devised by Sean Anderson, July 13, 2001. Typo--- spotted and correction supplied by Mike Keith, January 3, 2002. ----- | Reverse bits in a Word8 (7 no 64-bit operations, no division)-reverseBits7Ops :: Word8 -> Word8-{-# INLINABLE reverseBits7Ops #-}-reverseBits7Ops b' = fromIntegral x'-   where-      b   = fromIntegral b' :: Word32-      !x' = ((((b * 0x0802) .&. 0x22110) .|. ((b * 0x8020) .&. 0x88440)) * 0x10101) `shiftR` 16----- Reverse an N-bit quantity in parallel in 5 * lg(N) operations--- =============================================================--- --- unsigned int v; // 32-bit word to reverse bit order--- --- // swap odd and even bits--- v = ((v >> 1) & 0x55555555) | ((v & 0x55555555) << 1);--- // swap consecutive pairs--- v = ((v >> 2) & 0x33333333) | ((v & 0x33333333) << 2);--- // swap nibbles ... --- v = ((v >> 4) & 0x0F0F0F0F) | ((v & 0x0F0F0F0F) << 4);--- // swap bytes--- v = ((v >> 8) & 0x00FF00FF) | ((v & 0x00FF00FF) << 8);--- // swap 2-byte long pairs--- v = ( v >> 16             ) | ( v               << 16);--- --- The following variation is also O(lg(N)), however it requires more--- operations to reverse v. Its virtue is in taking less slightly memory by--- computing the constants on the fly.--- --- unsigned int s = sizeof(v) * CHAR_BIT; // bit size; must be power of 2 --- unsigned int mask = ~0;         --- while ((s >>= 1) > 0) --- {---   mask ^= (mask << s);---   v = ((v >> s) & mask) | ((v << s) & ~mask);--- }--- --- These methods above are best suited to situations where N is large. If you--- use the above with 64-bit ints (or larger), then you need to add more lines--- (following the pattern); otherwise only the lower 32 bits will be reversed--- and the result will be in the lower 32 bits.--- --- See Dr. Dobb's Journal 1983, Edwin Freed's article on Binary Magic Numbers--- for more information. The second variation was suggested by Ken Raeburn on--- September 13, 2005. Veldmeijer mentioned that the first version could do--- without ANDS in the last line on March 19, 2006. ---- | "Parallel" recursive version-reverseBits5LgN :: forall a.-   ( FiniteBits a-   , ShiftableBits a-   , Bitwise a-   , KnownNat (BitSize a)-   ) => a -> a-reverseBits5LgN x = rec (bitSize x `shiftR` 1) (complement zeroBits) x-   where-      rec :: FiniteBits a => Word -> a -> a -> a-      rec !s !mask !v-         | s <= 0        = v-         | otherwise     = rec (s `shiftR` 1) mask' v'-            where-               mask' = mask `xor` (mask `shiftL` s)-               v'    =      ((v `shiftR` s) .&. mask')-                        .|. ((v `shiftL` s) .&. complement mask')--{-# SPECIALIZE reverseBits5LgN :: Word8  -> Word8  #-}-{-# SPECIALIZE reverseBits5LgN :: Word16 -> Word16 #-}-{-# SPECIALIZE reverseBits5LgN :: Word32 -> Word32 #-}-{-# SPECIALIZE reverseBits5LgN :: Word64 -> Word64 #-}------ | Convert a function working on Word8 to one working on any Word------ The number of bits in the Word must be a multiple of 8-liftReverseBits ::-   ( ShiftableBits a-   , Bitwise a-   , FiniteBits a-   , Integral a-   , KnownNat (BitSize a)-   ) => (Word8 -> Word8) -> a -> a-liftReverseBits f w = rec zeroBits 0-   where-      nb = bitSize w `shiftR` 3 -- div 8-      f' = fromIntegral . f . fromIntegral-      rec !v !o-         | o == nb    = v-         | otherwise = rec v' (o+1)-               where-                  -- multiplication by 8 replaced with (`shiftL` 3)-                  v' = v .|. ((f' (w `shiftR` (o `shiftL` 3))) `shiftL` ((nb-1-o) `shiftL` 3))--{-# SPECIALIZE liftReverseBits :: (Word8 -> Word8) -> Word8  -> Word8  #-}-{-# SPECIALIZE liftReverseBits :: (Word8 -> Word8) -> Word16 -> Word16 #-}-{-# SPECIALIZE liftReverseBits :: (Word8 -> Word8) -> Word32 -> Word32 #-}-{-# SPECIALIZE liftReverseBits :: (Word8 -> Word8) -> Word64 -> Word64 #-}-
− src/lib/Haskus/Format/Binary/Bits/Rotate.hs
@@ -1,89 +0,0 @@-{-# LANGUAGE DefaultSignatures #-}-{-# LANGUAGE FlexibleContexts #-}---- | Bit rotations-module Haskus.Format.Binary.Bits.Rotate-   ( RotatableBits (..)-   )-where--import Haskus.Format.Binary.Bits.Finite-import Haskus.Format.Binary.Bits.Shift-import Haskus.Format.Binary.Bits.Bitwise-import Haskus.Format.Binary.Word-import Haskus.Utils.Types---- | Types whose bits can be rotated-class RotatableBits a where--   -- | Rotate left if positive, right if negative-   rotate :: a -> Int -> a-   default rotate ::-      ( FiniteBits a-      , KnownNat (BitSize a)-      ) => a -> Int -> a-   rotate a i-      | i' > 0     = rotateL a (fromIntegral i')-      | i' < 0     = rotateR a (fromIntegral (negate i'))-      | otherwise = a-      where-         i' = i `mod` bitSize a--   -- | Checked left bit rotation-   rotateL :: a -> Word -> a-   default rotateL ::-      ( FiniteBits a-      , KnownNat (BitSize a)-      ) => a -> Word -> a-   rotateL a n = uncheckedRotateL a (n `mod` bitSize a)--   -- | Checked right bit rotation-   rotateR :: a -> Word -> a-   default rotateR ::-      ( FiniteBits a-      , KnownNat (BitSize a)-      ) => a -> Word -> a-   rotateR a n = uncheckedRotateR a (n `mod` bitSize a)--   -- | Unchecked rotate left if positive, right if negative-   uncheckedRotate :: a -> Int -> a-   uncheckedRotate a i-      | i > 0     = uncheckedRotateL a (fromIntegral i)-      | i < 0     = uncheckedRotateR a (fromIntegral (negate i))-      | otherwise = a--   -- | Unchecked left bit rotation-   uncheckedRotateL :: a -> Word -> a-   default uncheckedRotateL ::-      ( ShiftableBits a-      , FiniteBits a-      , KnownNat (BitSize a)-      , Bitwise a-      ) => a -> Word -> a-   uncheckedRotateL a i = (a `uncheckedShiftL` i) .|. (a `uncheckedShiftR` (n-i))-      where n = bitSize a-      --   -- | Unchecked right bit rotation-   uncheckedRotateR :: a -> Word -> a-   default uncheckedRotateR ::-      ( ShiftableBits a-      , FiniteBits a-      , KnownNat (BitSize a)-      , Bitwise a-      ) => a -> Word -> a-   uncheckedRotateR a i = (a `uncheckedShiftL` (n-i)) .|. (a `uncheckedShiftR` i)-      where n = bitSize a---instance RotatableBits Word-instance RotatableBits Word8-instance RotatableBits Word16-instance RotatableBits Word32-instance RotatableBits Word64--instance RotatableBits Int-instance RotatableBits Int8-instance RotatableBits Int16-instance RotatableBits Int32-instance RotatableBits Int64
− src/lib/Haskus/Format/Binary/Bits/Shift.hs
@@ -1,323 +0,0 @@-{-# LANGUAGE MagicHash #-}-{-# LANGUAGE CPP #-}---- | Bit shifts-module Haskus.Format.Binary.Bits.Shift-   ( ShiftableBits (..)-   , SignedShiftableBits (..)-   )-where--import Haskus.Format.Binary.Word-import GHC.Exts-import GHC.Num--#include "MachDeps.h"---- | Bit shifts------ "Checked" means that there is an additional test to ensure that the shift--- offset is valid (less than the bit count). If you are sure that the offset is--- valid, use the "unchecked" version which should be faster.------ To shift signed numbers, see `SignedShiftableBits` class methods.-class ShiftableBits a where-   -- | Checked right shift-   shiftR :: a -> Word -> a--   -- | Checked left shift-   shiftL :: a -> Word -> a--   -- | Unchecked right shift-   uncheckedShiftR :: a -> Word -> a--   -- | Unchecked left shift-   uncheckedShiftL :: a -> Word -> a--   -- | Checked shift to the left if positive, to the right if negative-   shift :: a -> Int -> a-   shift a i-      | i > 0     = shiftL a (fromIntegral i)-      | i < 0     = shiftR a (fromIntegral (negate i))-      | otherwise = a--   -- | Unchecked shift to the left if positive, to the right if negative-   uncheckedShift :: a -> Int -> a-   uncheckedShift a i-      | i > 0     = uncheckedShiftL a (fromIntegral i)-      | i < 0     = uncheckedShiftR a (fromIntegral (negate i))-      | otherwise = a---- | Signed bit shifts------ "Signed" means that the sign bit (the higher order bit):---    - propagates to the right during right shifts and ---    - keeps its value during left shifts (except when all other bits are 0)------ "Checked" means that there is an additional test to ensure that the shift--- offset is valid (less than the bit count). If you are sure that the offset is--- valid, use the "unchecked" version which should be faster.-class SignedShiftableBits a where-   -- | Checked signed right shift-   signedShiftR :: a -> Word -> a--   -- | Checked signed left shift-   signedShiftL :: a -> Word -> a--   -- | Unchecked signed right shift-   uncheckedSignedShiftR :: a -> Word -> a--   -- | Unchecked signed left shift-   uncheckedSignedShiftL :: a -> Word -> a--   -- | Checked signed shift to the left if positive, to the right if negative-   signedShift :: a -> Int -> a-   signedShift a i-      | i > 0     = signedShiftL a (fromIntegral i)-      | i < 0     = signedShiftR a (fromIntegral (negate i))-      | otherwise = a--   -- | Unchecked signed shift to the left if positive, to the right if negative-   uncheckedSignedShift :: a -> Int -> a-   uncheckedSignedShift a i-      | i > 0     = uncheckedSignedShiftL a (fromIntegral i)-      | i < 0     = uncheckedSignedShiftR a (fromIntegral (negate i))-      | otherwise = a---instance ShiftableBits Word where-   {-# INLINABLE shiftR #-}-   {-# INLINABLE shiftL #-}-   {-# INLINABLE uncheckedShiftL #-}-   {-# INLINABLE uncheckedShiftR #-}--   (W# x#) `shiftL`          (W# i#)-      | isTrue# (i# `geWord#` WORD_SIZE_IN_BITS##) = W# 0##-      | otherwise                                  = W# (x# `uncheckedShiftL#` word2Int# i#)-   (W# x#) `shiftR`          (W# i#)-      | isTrue# (i# `geWord#` WORD_SIZE_IN_BITS##) = W# 0##-      | otherwise                                  = W# (x# `uncheckedShiftRL#` word2Int# i#)-   (W# x#) `uncheckedShiftL` (W# i#) = W# (x# `uncheckedShiftL#` word2Int# i#)-   (W# x#) `uncheckedShiftR` (W# i#) = W# (x# `uncheckedShiftRL#` word2Int# i#)--instance ShiftableBits Word8 where-   {-# INLINABLE shiftR #-}-   {-# INLINABLE shiftL #-}-   {-# INLINABLE uncheckedShiftL #-}-   {-# INLINABLE uncheckedShiftR #-}--   (W8# x#) `shiftL` (W# i#)-      | isTrue# (i# `geWord#` 8##)    = W8# 0##-      | otherwise                     = W8# (narrow8Word# (x# `uncheckedShiftL#` word2Int# i#))--   (W8# x#) `uncheckedShiftL` (W# i#) = W8# (narrow8Word# (x# `uncheckedShiftL#` word2Int# i#))-   -   (W8# x#) `shiftR` (W# i#)-      | isTrue# (i# `geWord#` 8##)    = W8# 0##-      | otherwise                     = W8# (x# `uncheckedShiftRL#` word2Int# i#)-   -   (W8# x#) `uncheckedShiftR` (W# i#) = W8# (x# `uncheckedShiftRL#` word2Int# i#)--instance ShiftableBits Word16 where-   {-# INLINABLE shiftR #-}-   {-# INLINABLE shiftL #-}-   {-# INLINABLE uncheckedShiftL #-}-   {-# INLINABLE uncheckedShiftR #-}--   (W16# x#) `shiftL` (W# i#)-      | isTrue# (i# `geWord#` 16##)    = W16# 0##-      | otherwise                      = W16# (narrow16Word# (x# `uncheckedShiftL#` word2Int# i#))--   (W16# x#) `uncheckedShiftL` (W# i#) = W16# (narrow16Word# (x# `uncheckedShiftL#` word2Int# i#))-   -   (W16# x#) `shiftR` (W# i#)-      | isTrue# (i# `geWord#` 16##)    = W16# 0##-      | otherwise                      = W16# (x# `uncheckedShiftRL#` word2Int# i#)-   -   (W16# x#) `uncheckedShiftR` (W# i#) = W16# (x# `uncheckedShiftRL#` word2Int# i#)--instance ShiftableBits Word32 where-   {-# INLINABLE shiftR #-}-   {-# INLINABLE shiftL #-}-   {-# INLINABLE uncheckedShiftL #-}-   {-# INLINABLE uncheckedShiftR #-}--   (W32# x#) `shiftL` (W# i#)-      | isTrue# (i# `geWord#` 32##)    = W32# 0##-      | otherwise                      = W32# (narrow32Word# (x# `uncheckedShiftL#` word2Int# i#))--   (W32# x#) `uncheckedShiftL` (W# i#) = W32# (narrow32Word# (x# `uncheckedShiftL#` word2Int# i#))-   -   (W32# x#) `shiftR` (W# i#)-      | isTrue# (i# `geWord#` 32##)    = W32# 0##-      | otherwise                      = W32# (x# `uncheckedShiftRL#` word2Int# i#)-   -   (W32# x#) `uncheckedShiftR` (W# i#) = W32# (x# `uncheckedShiftRL#` word2Int# i#)--instance ShiftableBits Word64 where-   {-# INLINABLE shiftR #-}-   {-# INLINABLE shiftL #-}-   {-# INLINABLE uncheckedShiftL #-}-   {-# INLINABLE uncheckedShiftR #-}--   (W64# x#) `shiftL` (W# i#)-      | isTrue# (i# `geWord#` 64##)    = W64# 0##-      | otherwise                      = W64# (x# `uncheckedShiftL#` word2Int# i#)--   (W64# x#) `uncheckedShiftL` (W# i#) = W64# (x# `uncheckedShiftL#` word2Int# i#)-   -   (W64# x#) `shiftR` (W# i#)-      | isTrue# (i# `geWord#` 64##)    = W64# 0##-      | otherwise                      = W64# (x# `uncheckedShiftRL#` word2Int# i#)-   -   (W64# x#) `uncheckedShiftR` (W# i#) = W64# (x# `uncheckedShiftRL#` word2Int# i#)---instance ShiftableBits Int where-   {-# INLINABLE shiftR #-}-   {-# INLINABLE shiftL #-}-   {-# INLINABLE uncheckedShiftL #-}-   {-# INLINABLE uncheckedShiftR #-}--   (I# x#) `shiftL`          (W# i#)-      | isTrue# (i# `geWord#` WORD_SIZE_IN_BITS##) = I# 0#-      | otherwise                                  = I# (x# `uncheckedIShiftL#` word2Int# i#)--   (I# x#) `uncheckedShiftL` (W# i#)               = I# (x# `uncheckedIShiftL#` word2Int# i#)-   -   (I# x#) `shiftR`          (W# i#)-      | isTrue# (i# `geWord#` WORD_SIZE_IN_BITS##) = I# 0#-      | otherwise                                  = I# (x# `uncheckedIShiftRL#` word2Int# i#)-   -   (I# x#) `uncheckedShiftR` (W# i#)               = I# (x# `uncheckedIShiftRL#` word2Int# i#)--instance ShiftableBits Int8 where-   {-# INLINABLE shiftR #-}-   {-# INLINABLE shiftL #-}-   {-# INLINABLE uncheckedShiftL #-}-   {-# INLINABLE uncheckedShiftR #-}--   (I8# x#) `shiftL`          (W# i#)-      | isTrue# (i# `geWord#` 8##)    = I8# 0#-      | otherwise                     = I8# (narrow8Int# (x# `uncheckedIShiftL#` word2Int# i#))--   (I8# x#) `uncheckedShiftL` (W# i#) = I8# (narrow8Int# (x# `uncheckedIShiftL#` word2Int# i#))-   -   (I8# x#) `shiftR`          (W# i#)-      | isTrue# (i# `geWord#` 8##)    = I8# 0#-      | otherwise                     = I8# (word2Int# (narrow8Word# (int2Word# x#) `uncheckedShiftRL#` word2Int# i#))--   (I8# x#) `uncheckedShiftR` (W# i#) = I8# (word2Int# (narrow8Word# (int2Word# x#) `uncheckedShiftRL#` word2Int# i#))-   --instance ShiftableBits Int16 where-   {-# INLINABLE shiftR #-}-   {-# INLINABLE shiftL #-}-   {-# INLINABLE uncheckedShiftL #-}-   {-# INLINABLE uncheckedShiftR #-}--   (I16# x#) `shiftL`          (W# i#)-      | isTrue# (i# `geWord#` 16##)    = I16# 0#-      | otherwise                      = I16# (narrow16Int# (x# `uncheckedIShiftL#` word2Int# i#))--   (I16# x#) `uncheckedShiftL` (W# i#) = I16# (narrow16Int# (x# `uncheckedIShiftL#` word2Int# i#))-   -   (I16# x#) `shiftR`          (W# i#)-      | isTrue# (i# `geWord#` 16##)    = I16# 0#-      | otherwise                      = I16# (word2Int# (narrow16Word# (int2Word# x#) `uncheckedShiftRL#` word2Int# i#))--   (I16# x#) `uncheckedShiftR` (W# i#) = I16# (word2Int# (narrow16Word# (int2Word# x#) `uncheckedShiftRL#` word2Int# i#))---instance ShiftableBits Int32 where-   {-# INLINABLE shiftR #-}-   {-# INLINABLE shiftL #-}-   {-# INLINABLE uncheckedShiftL #-}-   {-# INLINABLE uncheckedShiftR #-}--   (I32# x#) `shiftL`          (W# i#)-      | isTrue# (i# `geWord#` 32##)    = I32# 0#-      | otherwise                      = I32# (narrow32Int# (x# `uncheckedIShiftL#` word2Int# i#))--   (I32# x#) `uncheckedShiftL` (W# i#) = I32# (narrow32Int# (x# `uncheckedIShiftL#` word2Int# i#))-   -   (I32# x#) `shiftR`          (W# i#)-      | isTrue# (i# `geWord#` 32##)    = I32# 0#-      | otherwise                      = I32# (word2Int# (narrow32Word# (int2Word# x#) `uncheckedShiftRL#` word2Int# i#))--   (I32# x#) `uncheckedShiftR` (W# i#) = I32# (word2Int# (narrow32Word# (int2Word# x#) `uncheckedShiftRL#` word2Int# i#))--instance ShiftableBits Int64 where-   {-# INLINABLE shiftR #-}-   {-# INLINABLE shiftL #-}-   {-# INLINABLE uncheckedShiftL #-}-   {-# INLINABLE uncheckedShiftR #-}--   (I64# x#) `shiftL`          (W# i#)-      | isTrue# (i# `geWord#` 64##)    = I64# 0#-      | otherwise                      = I64# (x# `uncheckedIShiftL#` word2Int# i#)--   (I64# x#) `uncheckedShiftL` (W# i#) = I64# (x# `uncheckedIShiftL#` word2Int# i#)-   -   (I64# x#) `shiftR`          (W# i#)-      | isTrue# (i# `geWord#` 64##)    = I64# 0#-      | otherwise                      = I64# (word2Int# (int2Word# x# `uncheckedShiftRL#` word2Int# i#))--   (I64# x#) `uncheckedShiftR` (W# i#) = I64# (word2Int# (int2Word# x# `uncheckedShiftRL#` word2Int# i#))---instance SignedShiftableBits Int where-   (I# x#) `signedShiftL`          (W# i#) = I# (x# `iShiftL#` word2Int# i#)-   (I# x#) `signedShiftR`          (W# i#) = I# (x# `iShiftRA#` word2Int# i#)-   (I# x#) `uncheckedSignedShiftL` (W# i#) = I# (x# `uncheckedIShiftL#` word2Int# i#)-   (I# x#) `uncheckedSignedShiftR` (W# i#) = I# (x# `uncheckedIShiftRA#` word2Int# i#)--instance SignedShiftableBits Int8 where-   (I8# x#) `signedShiftL`          (W# i#) = I8# (narrow8Int# (x# `iShiftL#` word2Int# i#))-   (I8# x#) `signedShiftR`          (W# i#) = I8# (x# `iShiftRA#` word2Int# i#)-   (I8# x#) `uncheckedSignedShiftL` (W# i#) = I8# (narrow8Int# (x# `uncheckedIShiftL#` word2Int# i#))-   (I8# x#) `uncheckedSignedShiftR` (W# i#) = I8# (x# `uncheckedIShiftRA#` word2Int# i#)--instance SignedShiftableBits Int16 where-   (I16# x#) `signedShiftL`          (W# i#) = I16# (narrow16Int# (x# `iShiftL#` word2Int# i#))-   (I16# x#) `signedShiftR`          (W# i#) = I16# (x# `iShiftRA#` word2Int# i#)-   (I16# x#) `uncheckedSignedShiftL` (W# i#) = I16# (narrow16Int# (x# `uncheckedIShiftL#` word2Int# i#))-   (I16# x#) `uncheckedSignedShiftR` (W# i#) = I16# (x# `uncheckedIShiftRA#` word2Int# i#)--instance SignedShiftableBits Int32 where-   (I32# x#) `signedShiftL`          (W# i#) = I32# (narrow32Int# (x# `iShiftL#` word2Int# i#))-   (I32# x#) `signedShiftR`          (W# i#) = I32# (x# `iShiftRA#` word2Int# i#)-   (I32# x#) `uncheckedSignedShiftL` (W# i#) = I32# (narrow32Int# (x# `uncheckedIShiftL#` word2Int# i#))-   (I32# x#) `uncheckedSignedShiftR` (W# i#) = I32# (x# `uncheckedIShiftRA#` word2Int# i#)--instance SignedShiftableBits Int64 where-   (I64# x#) `signedShiftL`          (W# i#) = I64# (x# `iShiftL#` word2Int# i#)-   (I64# x#) `signedShiftR`          (W# i#) = I64# (x# `iShiftRA#` word2Int# i#)-   (I64# x#) `uncheckedSignedShiftL` (W# i#) = I64# (x# `uncheckedIShiftL#` word2Int# i#)-   (I64# x#) `uncheckedSignedShiftR` (W# i#) = I64# (x# `uncheckedIShiftRA#` word2Int# i#)----instance ShiftableBits Integer where-   {-# INLINABLE shiftR #-}-   {-# INLINABLE shiftL #-}-   {-# INLINABLE uncheckedShiftL #-}-   {-# INLINABLE uncheckedShiftR #-}--   x `shiftL` (W# i#) = shiftLInteger x (word2Int# i#)-   x `shiftR` (W# i#) = shiftRInteger x (word2Int# i#)--   uncheckedShiftL = shiftL-   uncheckedShiftR = shiftR--instance ShiftableBits Natural where-   {-# INLINABLE shiftR #-}-   {-# INLINABLE shiftL #-}-   {-# INLINABLE uncheckedShiftL #-}-   {-# INLINABLE uncheckedShiftR #-}--   x `shiftL` (W# i#) = shiftLNatural x (I# (word2Int# i#))-   x `shiftR` (W# i#) = shiftRNatural x (I# (word2Int# i#))--   uncheckedShiftL = shiftL-   uncheckedShiftR = shiftR
− src/lib/Haskus/Format/Binary/Buffer.hs
@@ -1,350 +0,0 @@-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE TypeApplications #-}---- | A memory buffer with a fixed address------ A buffer is a strict ByteString but with:------   * a better interface: use Word instead of Int for sizes---   * a better name: "string" is misleading---   * some additional primitives-module Haskus.Format.Binary.Buffer-   ( Buffer (..)-   , withBufferPtr-   , bufferSize-   , isBufferEmpty-   , emptyBuffer-   , bufferZero-   , bufferMap-   , bufferReverse-   , bufferDrop-   , bufferTail-   , bufferAppend-   , bufferCons-   , bufferSnoc-   , bufferInit-   , bufferSplitOn-   , bufferHead-   , bufferIndex-   , bufferTake-   , bufferTakeWhile-   , bufferTakeAtMost-   , bufferZipWith-   , bufferDup-   -- * Peek / Poke-   , bufferPeekStorable-   , bufferPeekStorableAt-   , bufferPopStorable-   , bufferPoke-   -- * Packing / Unpacking-   , bufferPackByteString-   , bufferPackByteList-   , bufferPackStorable-   , bufferPackStorableList-   , bufferPackPtr-   , bufferUnpackByteList-   , bufferUnpackByteString-   -- * Unsafe-   , bufferUnsafeDrop-   , bufferUnsafeTake-   , bufferUnsafeTail-   , bufferUnsafeHead-   , bufferUnsafeLast-   , bufferUnsafeInit-   , bufferUnsafeIndex-   , bufferUnsafeMapMemory-   , bufferUnsafeUsePtr-   , bufferUnsafePackPtr-   -- * IO-   , bufferReadFile-   , bufferWriteFile-   )-where--import System.IO.Unsafe-import Data.ByteString (ByteString)-import qualified Data.ByteString as BS-import qualified Data.ByteString.Unsafe as BS--import Haskus.Format.Binary.Ptr-import Haskus.Format.Binary.Word-import Haskus.Format.Binary.Storable-import Haskus.Format.Binary.Bits.Helper-import Haskus.Format.Binary.Bits.Bitwise-import Haskus.Format.Binary.Bits.Index-import Haskus.Format.Binary.Bits.Shift-import Haskus.Utils.Memory (memCopy,memSet)-import Haskus.Utils.List as List-import Haskus.Utils.Flow---- | A buffer-newtype Buffer = Buffer ByteString deriving (Eq,Ord)--instance Show Buffer where-   show b = concatMap bToHex (bufferUnpackByteList b)-      where-         bToHex x = toHex (x `shiftR` 4) ++ toHex (x .&. 0x0F)-         toHex 0xA = "A"-         toHex 0xB = "B"-         toHex 0xC = "C"-         toHex 0xD = "D"-         toHex 0xE = "E"-         toHex 0xF = "F"-         toHex x   = show x--instance Bitwise Buffer where-   (.&.)      = bufferZipWith (.&.)-   (.|.)      = bufferZipWith (.|.)-   xor        = bufferZipWith xor--instance IndexableBits Buffer where-   bit i = bufferPackByteList -         (bit r : List.replicate (fromIntegral n) 0)-      where-         n = byteOffset i-         r = bitOffset i-   -   testBit b i = testBit p r-      where-         p = bufferIndex b (bufferSize b - n)-         n = byteOffset i-         r = bitOffset i--   setBit   = error "Can't set Buffer bit"-   clearBit = error "Can't clear Buffer bit"--   popCount b  = sum (fmap popCount (bufferUnpackByteList b))------ | Duplicate a buffer-bufferDup :: Buffer -> IO Buffer-bufferDup b = withBufferPtr b $ bufferPackPtr (bufferSize b)---- | Buffer filled with zero-bufferZero :: Word -> Buffer-bufferZero n = unsafePerformIO $ do-   p <- mallocBytes (fromIntegral n)-   memSet p (fromIntegral n) 0-   bufferUnsafePackPtr n p---- | Zip two buffers with the given function-bufferZipWith :: (Word8 -> Word8 -> Word8) -> Buffer -> Buffer -> Buffer-bufferZipWith f a b-      | bufferSize a /= bufferSize b = error "Non matching buffer sizes"-      | otherwise = unsafePerformIO $ do-            let sz = fromIntegral (bufferSize a)-            pc <- mallocBytes sz-            withBufferPtr a $ \pa ->-               withBufferPtr b $ \pb ->-                  forM_ [0..fromIntegral sz-1] $ \off -> do-                     v <- f <$> peekByteOff pa off-                            <*> peekByteOff pb off-                     pokeByteOff pc off (v :: Word8)-            bufferUnsafePackPtr (bufferSize a) pc---- | Unsafe: be careful if you modify the buffer contents or you may break--- referential transparency-withBufferPtr :: Buffer -> (Ptr b -> IO a) -> IO a-withBufferPtr (Buffer bs) f = BS.unsafeUseAsCString bs (f . castPtr)---- | Test if the buffer is empty-isBufferEmpty :: Buffer -> Bool-isBufferEmpty (Buffer bs) = BS.null bs---- | Empty buffer-emptyBuffer :: Buffer-emptyBuffer = Buffer BS.empty---- | Buffer size-bufferSize :: Buffer -> Word-bufferSize (Buffer bs) = -      if s < 0-         then error "ByteString with size < 0"-         else fromIntegral s-   where-      s = BS.length bs---- | Peek a storable-bufferPeekStorable :: forall a. Storable a => Buffer -> a-bufferPeekStorable = snd . bufferPopStorable---- | Peek a storable at the given offset-bufferPeekStorableAt :: forall a.-   ( Storable a-   )-   => Buffer -> Word -> a-bufferPeekStorableAt b n-   | n + sizeOfT' @a > bufferSize b = error "Invalid buffer index"-   | otherwise                      = unsafePerformIO $ withBufferPtr b $ \p ->-                                        peekByteOff p (fromIntegral n)-   ---- | Pop a Storable and return the new buffer-bufferPopStorable :: forall a. Storable a => Buffer -> (Buffer,a)-bufferPopStorable buf-   | bufferSize buf < sza = error "bufferRead: out of bounds"-   | otherwise            = unsafePerformIO $ do-         a <- withBufferPtr buf peek-         return (bufferDrop sza buf, a)-   where-      sza = sizeOfT' @a---- | Poke a buffer-bufferPoke :: Ptr a -> Buffer -> IO ()-bufferPoke dest b = bufferUnsafeUsePtr b $ \src sz ->-   memCopy dest src (fromIntegral sz)---- | Map-bufferMap :: (Word8 -> Word8) -> Buffer -> Buffer-bufferMap f (Buffer bs) = Buffer (BS.map f bs)---- | Reverse-bufferReverse :: Buffer -> Buffer-bufferReverse (Buffer bs) = Buffer (BS.reverse bs)---- | Drop some bytes O(1)-bufferDrop :: Word -> Buffer -> Buffer-bufferDrop n (Buffer bs) = Buffer $ BS.drop (fromIntegral n) bs---- | Split on the given Byte values-bufferSplitOn :: Word8 -> Buffer -> [Buffer]-bufferSplitOn n (Buffer bs) = fmap Buffer (BS.split n bs)---- | Tail-bufferTail :: Buffer -> Buffer-bufferTail (Buffer bs) = Buffer $ BS.tail bs---- | Append-bufferAppend :: Buffer -> Buffer -> Buffer-bufferAppend (Buffer a) (Buffer b) = Buffer $ BS.append a b---- | Cons-bufferCons :: Word8 -> Buffer -> Buffer-bufferCons w (Buffer bs) = Buffer $ BS.cons w bs---- | Snoc-bufferSnoc :: Buffer -> Word8 -> Buffer-bufferSnoc (Buffer bs) w = Buffer $ BS.snoc bs w----- | Init-bufferInit :: Buffer -> Buffer-bufferInit (Buffer bs) = Buffer $ BS.init bs---- | Head-bufferHead :: Buffer -> Word8-{-# INLINABLE bufferHead #-}-bufferHead (Buffer bs) = BS.head bs---- | Index-bufferIndex :: Buffer -> Word -> Word8-{-# INLINABLE bufferIndex #-}-bufferIndex (Buffer bs) n = BS.index bs (fromIntegral n)---- | Unpack-bufferUnpackByteList :: Buffer -> [Word8]-bufferUnpackByteList (Buffer bs) = BS.unpack bs---- | Unpack-bufferUnpackByteString :: Buffer -> ByteString-bufferUnpackByteString (Buffer bs) = bs---- | Take some bytes O(1)-bufferTake :: Word -> Buffer -> Buffer-bufferTake n (Buffer bs) = Buffer $ BS.take (fromIntegral n) bs---- | Take some bytes O(n)-bufferTakeWhile :: (Word8 -> Bool) -> Buffer -> Buffer-bufferTakeWhile f (Buffer bs) = Buffer $ BS.takeWhile f bs---- | Take some bytes O(1)-bufferTakeAtMost :: Word -> Buffer -> Buffer-bufferTakeAtMost n buf-   | bufferSize buf < n = buf-   | otherwise          = bufferTake n buf----- | Pack a ByteString-bufferPackByteString :: BS.ByteString -> Buffer-bufferPackByteString = Buffer---- | Pack a list of bytes-bufferPackByteList :: [Word8] -> Buffer-bufferPackByteList = Buffer . BS.pack---- | Pack a Storable-bufferPackStorable :: forall a. Storable a => a -> Buffer-bufferPackStorable x = Buffer $ unsafePerformIO $ do-   p <- malloc-   poke p x-   BS.unsafePackMallocCStringLen (castPtr p, sizeOfT' @a)---- | Pack a list of Storable-bufferPackStorableList :: forall a. Storable a => [a] -> Buffer-bufferPackStorableList xs = Buffer $ unsafePerformIO $ do-   let lxs = length xs-   p <- mallocArray (fromIntegral lxs)-   forM_ (xs `zip` [0..]) $ \(x,o) ->-      pokeElemOff p o x-   BS.unsafePackMallocCStringLen (castPtr p, sizeOfT' @a * lxs)---- | Pack from a pointer (copy)-bufferPackPtr :: MonadIO m => Word -> Ptr () -> m Buffer-bufferPackPtr sz ptr = do-   p <- mallocBytes (fromIntegral sz)-   memCopy p ptr (fromIntegral sz)-   bufferUnsafePackPtr sz p---- | Pack from a pointer (add finalizer)-bufferUnsafePackPtr :: MonadIO m => Word -> Ptr a -> m Buffer-bufferUnsafePackPtr sz p =-   Buffer <$> liftIO (BS.unsafePackMallocCStringLen (castPtr p, fromIntegral sz))---- | Unsafe drop (don't check the size)-bufferUnsafeDrop :: Word -> Buffer -> Buffer-bufferUnsafeDrop n (Buffer bs) = Buffer (BS.unsafeDrop (fromIntegral n) bs)---- | Unsafe take (don't check the size)-bufferUnsafeTake :: Word -> Buffer -> Buffer-bufferUnsafeTake n (Buffer bs) = Buffer (BS.unsafeTake (fromIntegral n) bs)---- | Unsafe tail (don't check the size)-bufferUnsafeTail :: Buffer -> Buffer-bufferUnsafeTail (Buffer bs) = Buffer (BS.unsafeTail bs)---- | Unsafe head (don't check the size)-bufferUnsafeHead :: Buffer -> Word8-bufferUnsafeHead (Buffer bs) = BS.unsafeHead bs---- | Unsafe last (don't check the size)-bufferUnsafeLast :: Buffer -> Word8-bufferUnsafeLast (Buffer bs) = BS.unsafeLast bs---- | Unsafe init (don't check the size)-bufferUnsafeInit :: Buffer -> Buffer-bufferUnsafeInit (Buffer bs) = Buffer (BS.unsafeInit bs)---- | Unsafe index (don't check the size)-bufferUnsafeIndex :: Buffer -> Word -> Word8-bufferUnsafeIndex (Buffer bs) n = BS.unsafeIndex bs (fromIntegral n)---- | Map memory-bufferUnsafeMapMemory :: MonadIO m => Word -> Ptr () -> m Buffer-bufferUnsafeMapMemory sz ptr =-   Buffer <$> liftIO (BS.unsafePackCStringLen (castPtr ptr, fromIntegral sz))---- | Use buffer pointer-bufferUnsafeUsePtr :: MonadInIO m => Buffer -> (Ptr () -> Word -> m a) -> m a-bufferUnsafeUsePtr bu@(Buffer b) f =-   liftWith (BS.unsafeUseAsCString b) $ \p ->-      f (castPtr p) (bufferSize bu)---- | Read file-bufferReadFile :: MonadIO m => FilePath -> m Buffer-bufferReadFile path = Buffer <$> liftIO (BS.readFile path)---- | Write file-bufferWriteFile :: MonadIO m => FilePath -> Buffer -> m ()-bufferWriteFile path (Buffer bs) = liftIO (BS.writeFile path bs)
− src/lib/Haskus/Format/Binary/BufferBuilder.hs
@@ -1,47 +0,0 @@-{-# LANGUAGE StandaloneDeriving #-}-{-# LANGUAGE GeneralizedNewtypeDeriving #-}---- | Buffer builder-module Haskus.Format.Binary.BufferBuilder-   ( BufferBuilder-   , emptyBufferBuilder-   , toBufferList-   , toBuffer-   , fromBuffer-   , fromWord8-   )-where--import qualified Data.ByteString.Builder as B--import Haskus.Format.Binary.Word-import Haskus.Format.Binary.Buffer-import qualified Haskus.Format.Binary.BufferList as BL---- | Buffer builder-newtype BufferBuilder-   = BufferBuilder B.Builder-   deriving (Semigroup,Monoid)---- | Empty buffer builder-emptyBufferBuilder :: BufferBuilder-emptyBufferBuilder = BufferBuilder mempty---- | Create a Builder denoting the same sequence of bytes as a strict--- ByteString. The Builder inserts large ByteStrings directly, but copies small--- ones to ensure that the generated chunks are large on average.-fromBuffer :: Buffer -> BufferBuilder-fromBuffer (Buffer bs) = BufferBuilder (B.byteString bs)---- | Encode a single unsigned byte as-is.-fromWord8 :: Word8 -> BufferBuilder-fromWord8 w = BufferBuilder (B.word8 w)---- | Execute a Builder and return the generated chunks as a BufferList. The work--- is performed lazily, i.e., only when a chunk of the BufferList is forced.-toBufferList :: BufferBuilder -> BL.BufferList-toBufferList (BufferBuilder b) = BL.BufferList (B.toLazyByteString b)---- | Execute a Builder and return the generated chunks as a Buffer.-toBuffer :: BufferBuilder -> Buffer-toBuffer = BL.toBuffer . toBufferList
− src/lib/Haskus/Format/Binary/BufferList.hs
@@ -1,29 +0,0 @@--- | Buffer list------ BufferList is a lazy ByteString-module Haskus.Format.Binary.BufferList-   ( BufferList (..)-   , toBuffer-   , toBufferList-   , toLazyByteString-   )-where--import qualified Data.ByteString.Lazy as LBS--import Haskus.Format.Binary.Buffer---- | BufferList-newtype BufferList = BufferList LBS.ByteString---- | Convert to a buffer-toBuffer :: BufferList -> Buffer-toBuffer (BufferList b) = Buffer (LBS.toStrict b)---- | Convert from a buffer-toBufferList :: Buffer -> BufferList-toBufferList (Buffer b) = BufferList (LBS.fromStrict b)---- | Convert to a lazy ByteString-toLazyByteString :: BufferList -> LBS.ByteString-toLazyByteString (BufferList b) = b
− src/lib/Haskus/Format/Binary/Char.hs
@@ -1,15 +0,0 @@-{-# LANGUAGE GeneralizedNewtypeDeriving #-}---- | Character-module Haskus.Format.Binary.Char-   ( Char8 (..)-   )-where--import Haskus.Format.Binary.Word-import Haskus.Format.Binary.Storable---- | 8-bit character (ASCII, etc.)-newtype Char8-   = Char8 Word8-   deriving (Show,Eq,Ord,Storable)
− src/lib/Haskus/Format/Binary/Endianness.hs
@@ -1,222 +0,0 @@-{-# LANGUAGE GeneralizedNewtypeDeriving #-}-{-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE TypeApplications #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE FlexibleContexts #-}---- | Byte order ("endianness")------ Indicate in which order bytes are stored in memory for multi-bytes types.--- Big-endian means that most-significant bytes come first. Little-endian means--- that least-significant bytes come first.-module Haskus.Format.Binary.Endianness-   ( Endianness(..)-   , WordGetters (..)-   , WordPutters (..)-   , getWordGetters-   , getWordPutters-   , WordSize (..)-   , ExtendedWordGetters (..)-   , ExtendedWordPutters (..)-   , getExtendedWordGetters-   , getExtendedWordPutters-   , getHostEndianness-   , hostEndianness-   , ByteReversable (..)-   , AsBigEndian (..)-   , AsLittleEndian (..)-   )-where--import Haskus.Format.Binary.Get-import Haskus.Format.Binary.Put-import Haskus.Format.Binary.Enum-import Haskus.Format.Binary.Ptr-import Haskus.Format.Binary.Storable-import Haskus.Format.Binary.Word-import Haskus.Format.Binary.Bits--import System.IO.Unsafe---- | Endianness-data Endianness -   = LittleEndian    -- ^ Less significant bytes first-   | BigEndian       -- ^ Most significant bytes first-   deriving (Eq,Show,Enum)--instance CEnum Endianness---- | Word getter-data WordGetters = WordGetters-   { wordGetter8  :: Get Word8   -- ^ Read a Word8-   , wordGetter16 :: Get Word16  -- ^ Read a Word16-   , wordGetter32 :: Get Word32  -- ^ Read a Word32-   , wordGetter64 :: Get Word64  -- ^ Read a Word64-   }---- | Word putters-data WordPutters = WordPutters-   { wordPutter8  :: Word8  -> Put -- ^ Write a Word8-   , wordPutter16 :: Word16 -> Put -- ^ Write a Word16-   , wordPutter32 :: Word32 -> Put -- ^ Write a Word32-   , wordPutter64 :: Word64 -> Put -- ^ Write a Word64-   }---- | Get getters for the given endianness-getWordGetters :: Endianness -> WordGetters-getWordGetters e = case e of-   LittleEndian -> WordGetters getWord8 getWord16le getWord32le getWord64le-   BigEndian    -> WordGetters getWord8 getWord16be getWord32be getWord64be---- | Get putters for the given endianness-getWordPutters :: Endianness -> WordPutters-getWordPutters e = case e of-   LittleEndian -> WordPutters putWord8 putWord16le putWord32le putWord64le-   BigEndian    -> WordPutters putWord8 putWord16be putWord32be putWord64be------ | Size of a machine word-data WordSize-   = WordSize32      -- ^ 32-bit-   | WordSize64      -- ^ 64-bit-   deriving (Show, Eq)---- | Extended word getters-data ExtendedWordGetters = ExtendedWordGetters-   { extwordGetter8  :: Get Word8   -- ^ Read a Word8-   , extwordGetter16 :: Get Word16  -- ^ Read a Word16-   , extwordGetter32 :: Get Word32  -- ^ Read a Word32-   , extwordGetter64 :: Get Word64  -- ^ Read a Word64-   , extwordGetterN  :: Get Word64  -- ^ Read a native size word into a Word64-   }---- | Extended word putters-data ExtendedWordPutters = ExtendedWordPutters-   { extwordPutter8  :: Word8  -> Put -- ^ Write a Word8-   , extwordPutter16 :: Word16 -> Put -- ^ Write a Word16-   , extwordPutter32 :: Word32 -> Put -- ^ Write a Word32-   , extwordPutter64 :: Word64 -> Put -- ^ Write a Word64-   , extwordPutterN  :: Word64 -> Put -- ^ Write a Word64 into a native size word-   }---- | Return extended getters-getExtendedWordGetters :: Endianness -> WordSize -> ExtendedWordGetters-getExtendedWordGetters endian ws = ExtendedWordGetters gw8 gw16 gw32 gw64 gwN-   where-      WordGetters gw8 gw16 gw32 gw64 = getWordGetters endian-      gwN = case ws of-         WordSize64 -> gw64-         WordSize32 -> fromIntegral <$> gw32---- | Return extended putters-getExtendedWordPutters :: Endianness -> WordSize -> ExtendedWordPutters-getExtendedWordPutters endian ws = ExtendedWordPutters pw8 pw16 pw32 pw64 pwN-   where-      WordPutters pw8 pw16 pw32 pw64 = getWordPutters endian-      pwN x = case ws of-         WordSize64 -> pw64 x-         WordSize32 -> if x > 0xffffffff-            then error $ "Number too big to be stored in 32-bit word ("++show x++")"-            else pw32 (fromIntegral x)---- | Detect the endianness of the host memory-getHostEndianness :: IO Endianness-getHostEndianness = do-   -- Write a 32 bit word and check byte ordering-   let magic = 0x01020304 :: Word32-   alloca $ \p -> do-      poke p magic-      rs <- peekArray 4 (castPtr p :: Ptr Word8)-      return $ if rs == [1,2,3,4] then BigEndian else LittleEndian---- | Detected host endianness------ TODO: use targetByteOrder in GHC.ByteOrder (should be introduced in GHC 8.4)-hostEndianness :: Endianness-{-# NOINLINE hostEndianness #-}-hostEndianness = unsafePerformIO getHostEndianness---- | Reverse bytes in a word-class ByteReversable w where-   reverseBytes       :: w -> w--   hostToBigEndian    :: w -> w-   hostToBigEndian w = case hostEndianness of-      BigEndian    -> w-      LittleEndian -> reverseBytes w--   bigEndianToHost    :: w -> w-   bigEndianToHost w = case hostEndianness of-      BigEndian    -> w-      LittleEndian -> reverseBytes w---   hostToLittleEndian :: w -> w-   hostToLittleEndian w = case hostEndianness of-      BigEndian    -> reverseBytes w-      LittleEndian -> w--   littleEndianToHost :: w -> w-   littleEndianToHost w = case hostEndianness of-      BigEndian    -> reverseBytes w-      LittleEndian -> w--instance ByteReversable Word8 where-   reverseBytes = id--instance ByteReversable Word16 where-   reverseBytes = byteSwap16-                  -instance ByteReversable Word32 where-   reverseBytes = byteSwap32--instance ByteReversable Word64 where-   reverseBytes = byteSwap64------ | Force a data to be read/stored as big-endian-newtype AsBigEndian a-   = AsBigEndian a-   deriving (Eq,Ord,Enum,Num,Integral,Real,Bitwise,FiniteBits,ReversableBits,RotatableBits,ShiftableBits,IndexableBits)--instance Show a => Show (AsBigEndian a) where-   show (AsBigEndian a) = show a---- | Force a data to be read/stored as little-endian-newtype AsLittleEndian a-   = AsLittleEndian a-   deriving (Eq,Ord,Enum,Num,Integral,Real,Bitwise,FiniteBits,ReversableBits,RotatableBits,ShiftableBits,IndexableBits)--instance Show a => Show (AsLittleEndian a) where-   show (AsLittleEndian a) = show a--instance (ByteReversable a, StaticStorable a) => StaticStorable (AsBigEndian a) where-   type SizeOf (AsBigEndian a)    = SizeOf a-   type Alignment (AsBigEndian a) = Alignment a--   staticPeekIO ptr                 = AsBigEndian . bigEndianToHost <$> staticPeek (castPtr ptr)-   staticPokeIO ptr (AsBigEndian v) = staticPoke (castPtr ptr) (hostToBigEndian v)---instance (ByteReversable a, Storable a) => Storable (AsBigEndian a) where-   sizeOf _    = sizeOfT    @a-   alignment _ = alignmentT @a--   peekIO ptr                 = AsBigEndian . bigEndianToHost <$> peek (castPtr ptr)-   pokeIO ptr (AsBigEndian v) = poke (castPtr ptr) (hostToBigEndian v)--instance (ByteReversable a, StaticStorable a) => StaticStorable (AsLittleEndian a) where-   type SizeOf (AsLittleEndian a)    = SizeOf a-   type Alignment (AsLittleEndian a) = Alignment a--   staticPeekIO ptr                    = AsLittleEndian . bigEndianToHost <$> staticPeekIO (castPtr ptr)-   staticPokeIO ptr (AsLittleEndian v) = staticPokeIO (castPtr ptr) (hostToLittleEndian v)--instance (ByteReversable a, Storable a) => Storable (AsLittleEndian a) where-   sizeOf _    = sizeOfT    @a-   alignment _ = alignmentT @a--   peekIO ptr                    = AsLittleEndian . bigEndianToHost <$> peek (castPtr ptr)-   pokeIO ptr (AsLittleEndian v) = poke (castPtr ptr) (hostToLittleEndian v)
− src/lib/Haskus/Format/Binary/Enum.hs
@@ -1,144 +0,0 @@-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE DefaultSignatures #-}-{-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE TypeApplications #-}-{-# LANGUAGE GeneralizedNewtypeDeriving #-}-{-# LANGUAGE MagicHash #-}---- | Store an Enum in the given backing word type-module Haskus.Format.Binary.Enum-   ( EnumField-   , CEnum (..)-   , fromEnumField-   , toEnumField-   , makeEnum-   , makeEnumMaybe-   , makeEnumWithCustom-   , dataToTag-   )-where--import Haskus.Format.Binary.Storable-import Haskus.Format.Binary.Ptr--import Data.Data-import GHC.Prim-import GHC.Int---------------------------------------------------------------------------------- EnumField b a: directly store the value of enum "a" as a "b"---------------------------------------------------------------------------------- | Store enum `a` as a `b`-newtype EnumField b a-   = EnumField b-   deriving (Show,Eq,Storable)--instance-      ( Integral b-      , StaticStorable b-      , CEnum a-      ) => StaticStorable (EnumField b a)-   where-      type SizeOf (EnumField b a)    = SizeOf b-      type Alignment (EnumField b a) = Alignment b-      staticPeekIO p                 = EnumField  <$> staticPeek (castPtr p :: Ptr b)-      staticPokeIO p (EnumField v)   = staticPoke (castPtr p :: Ptr b) v---- | Read an enum field-fromEnumField :: (CEnum a, Integral b) => EnumField b a -> a-{-# INLINABLE fromEnumField #-}-fromEnumField (EnumField b) = toCEnum b---- | Create an enum field-toEnumField :: (CEnum a, Integral b) => a -> EnumField b a-{-# INLINABLE toEnumField #-}-toEnumField = EnumField . fromCEnum----------------------------------------------------------------------------------- Extended Enum---------------------------------------------------------------------------------- | Extended Enum------ By default, use dataToTag and toEnum to convert from and to an Integral.------ But it can be overloaded to perform transformation before using--- fromEnum/toEnum. E.g. if values are shifted by 1 compared to Enum values,--- define fromCEnum = (+1) . fromIntegral . dataToTag----class CEnum a where-   fromCEnum       :: Integral b => a -> b-   fromCEnum       = fromIntegral . dataToTag--   toCEnum         :: Integral b => b -> a-   default toCEnum :: (Enum a, Integral b) => b -> a-   toCEnum         = toEnum . fromIntegral---- | Make an enum with the last constructor taking a parameter for the rest of--- the range------ @--- data T = A | B | C | D Word8------ makeEnumWithCustom :: Int -> T--- makeEnumWithCustom x = case x of---    0 -> A---    1 -> B---    2 -> C---    n -> D (n - 3)--- @----makeEnumWithCustom :: forall a i. (Data a,Integral i) => i -> a-{-# INLINABLE makeEnumWithCustom #-}-makeEnumWithCustom x =-   if x' < maxConstrIndex t-      then fromConstr (indexConstr t x')-      else fromConstrB (fromConstr (toConstr (x' - m)))-               (indexConstr t m)-   where-      m   = maxConstrIndex t-      x'  = fromIntegral x + 1-      t   = dataTypeOf (undefined :: a)---- | Make an enum with the last constructor taking a parameter for the rest of--- the range, but don't build the last constructor------ @--- data T = A | B | C | D Word8------ makeEnumMaybe :: Int -> T--- makeEnumMaybe x = case x of---    0 -> Just A---    1 -> Just B---    2 -> Just C---    n -> Nothing--- @----makeEnumMaybe :: forall a i. (Data a,Integral i) => i -> Maybe a-{-# INLINABLE makeEnumMaybe #-}-makeEnumMaybe x =-   if x' < maxConstrIndex t-      then Just (fromConstr (indexConstr t x'))-      else Nothing-   where-      x'  = fromIntegral x + 1-      t   = dataTypeOf (undefined :: a)---- | Make an enum from a number (0 indexed)-makeEnum :: forall a i. (Data a,Integral i) => i -> a-{-# INLINABLE makeEnum #-}-makeEnum x =fromConstr (indexConstr t x')-   where-      x'  = fromIntegral x + 1-      t   = dataTypeOf (undefined :: a)----- | Retrieve data tag------ >>> data D = A | B | C--- >>> dataToTag B--- 1-dataToTag :: a -> Int-dataToTag a = I# (dataToTag# a)
− src/lib/Haskus/Format/Binary/FixedPoint.hs
@@ -1,81 +0,0 @@-{-# LANGUAGE DataKinds #-}-{-# LANGUAGE GeneralizedNewtypeDeriving #-}-{-# LANGUAGE KindSignatures #-}-{-# LANGUAGE StandaloneDeriving #-}-{-# LANGUAGE TypeOperators #-}-{-# LANGUAGE TypeApplications #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE ExistentialQuantification #-}-{-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE UndecidableInstances #-}---- | Fixed-point numbers-module Haskus.Format.Binary.FixedPoint-   ( FixedPoint-   , toFixedPoint-   , fromFixedPoint-   )-where--import Haskus.Format.Binary.BitField-import Haskus.Format.Binary.Bits-import Haskus.Format.Binary.Storable-import Haskus.Utils.Types---- | Fixed-point number--- * `w` is the backing type--- * `i` is the number of bits for the integer part (before the radix point)--- * `f` is the number of bits for the fractional part (after the radix point)-newtype FixedPoint w (i :: Nat) (f :: Nat) = FixedPoint (BitFields w-   '[ BitField i "integer"    w-    , BitField f "fractional" w-    ])-   deriving (Storable)--deriving instance forall w n d.-   ( Integral w-   , Bits w-   , Field w-   , BitSize w ~ (n + d)-   , KnownNat n-   , KnownNat d-   ) => Eq (FixedPoint w n d)--deriving instance forall w n d.-   ( Integral w-   , Bits w-   , Field w-   , BitSize w ~ (n + d)-   , KnownNat n-   , KnownNat d-   , Show w-   ) => Show (FixedPoint w n d)---- | Convert to a fixed point value-toFixedPoint :: forall a w (n :: Nat) (d :: Nat).-   ( RealFrac a-   , BitSize w ~ (n + d)-   , KnownNat n-   , KnownNat d-   , Bits w-   , Field w-   , Num w-   , Integral w-   ) => a -> FixedPoint w n d-toFixedPoint a = FixedPoint $ BitFields (round (a * 2^natValue' @d))---- | Convert from a fixed-point value-fromFixedPoint :: forall a w (n :: Nat) (d :: Nat).-   ( RealFrac a-   , BitSize w ~ (n + d)-   , KnownNat n-   , KnownNat d-   , Bits w-   , Field w-   , Num w-   , Integral w-   ) => FixedPoint w n d -> a-fromFixedPoint (FixedPoint bf) = w / 2^(natValue' @d)-   where-      w = fromIntegral (bitFieldsBits bf)
− src/lib/Haskus/Format/Binary/Get.hs
@@ -1,237 +0,0 @@-{-# lANGUAGE LambdaCase #-}---- | Get utilities-module Haskus.Format.Binary.Get-   ( Get-   , runGet-   , runGetOrFail-   -- * Size & alignment-   , isEmpty-   , remaining-   , skip-   , uncheckedSkip-   , skipAlign-   , uncheckedSkipAlign-   , countBytes-   , alignAfter-   -- * Isolation-   , consumeExactly-   , consumeAtMost-   -- * Look-ahead-   , lookAhead-   , lookAheadM-   , lookAheadE-   -- * Read-   , getRemaining-   , getBuffer-   , getBufferNul-   , getWord8-   , getWord16le-   , getWord16be-   , getWord32le-   , getWord32be-   , getWord64le-   , getWord64be-   -- * Utilities-   , getWhile-   , getWhole-   , getBitGet-   , getManyAtMost-   , getManyBounded-   )-where--import qualified Data.Serialize.Get as BG-import Data.Serialize.Get (Get)--import Haskus.Format.Binary.Buffer-import Haskus.Format.Binary.Word-import Haskus.Format.Binary.Bits.Order-import Haskus.Format.Binary.Bits.Get (BitGet, runBitGetPartial, skipBitsToAlignOnWord8M, bitGetStateInput)-import Haskus.Utils.Maybe----- | Test whether all input *in the current chunk* has been consumed-isEmpty :: Get Bool-isEmpty = BG.isEmpty---- | Get the number of remaining unparsed bytes *in the current chunk*-remaining :: Get Word-remaining = fromIntegral <$> BG.remaining---- | Skip ahead n bytes. Fails if fewer than n bytes are available.-skip :: Word -> Get ()-skip = BG.skip . fromIntegral---- | Skip ahead n bytes. No error if there isn't enough bytes.-uncheckedSkip :: Word -> Get ()-uncheckedSkip = BG.uncheckedSkip . fromIntegral---- | Skip to align n to al. Fails if fewer than n bytes are available.-skipAlign :: Word -> Word -> Get ()-skipAlign n al = skip n'-   where-      n' = case n `mod` al of-               0 -> 0-               x -> al - fromIntegral x---- | Skip to align n to al. Fails if fewer than n bytes are available.-uncheckedSkipAlign :: Word -> Word -> Get ()-uncheckedSkipAlign n al = uncheckedSkip n'-   where-      n' = case n `mod` al of-               0 -> 0-               x -> al - fromIntegral x---- | Run the getter without consuming its input. Fails if it fails-lookAhead :: Get a -> Get a-lookAhead = BG.lookAhead---- | Run the getter. Consume its input if Just _ returned. Fails if it fails-lookAheadM :: Get (Maybe a) -> Get (Maybe a)-lookAheadM = BG.lookAheadM---- | Run the getter. Consume its input if Right _ returned. Fails if it fails-lookAheadE :: Get (Either a b) -> Get (Either a b)-lookAheadE = BG.lookAheadE---- | Require an action to consume exactly the given number of bytes, fail--- otherwise-consumeExactly :: Word -> Get a -> Get a-consumeExactly sz = BG.isolate (fromIntegral sz)---- | Require an action to consume at most the given number of bytes, fail--- otherwise-consumeAtMost :: Word -> Get a -> Get a-consumeAtMost sz f = do-   sz' <- remaining-   (r,res) <- BG.lookAhead $ BG.isolate (fromIntegral (min sz sz')) $ do-      res <- f-      r <- remaining-      skip r -- skip remaining bytes, to make isolate happy-      return (r,res)-   skip (min sz' sz - r)-   return res---- | Pull n bytes from the input, as a Buffer-getBuffer :: Word -> Get Buffer-getBuffer sz = Buffer <$> BG.getBytes (fromIntegral sz)---- | Get Word8-getWord8 :: Get Word8-getWord8 = BG.getWord8---- | Get Word16 little-endian-getWord16le :: Get Word16-getWord16le = BG.getWord16le---- | Get Word16 big-endian-getWord16be :: Get Word16-getWord16be = BG.getWord16be---- | Get Word32 little-endian-getWord32le :: Get Word32-getWord32le = BG.getWord32le---- | Get Word32 big-endian-getWord32be :: Get Word32-getWord32be = BG.getWord32be---- | Get Word64 little-endian-getWord64le :: Get Word64-getWord64le = BG.getWord64le---- | Get Word64 big-endian-getWord64be :: Get Word64-getWord64be = BG.getWord64be---- | Get while True (read and discard the ending element)-getWhile :: (a -> Bool) -> Get a -> Get [a]-getWhile cond getter = rec []-   where-      rec xs = do-         x <- getter-         if cond x-            then rec (x:xs)-            else return (reverse xs)---- | Repeat the getter to read the whole bytestring-getWhole :: Get a -> Get [a]-getWhole getter = rec []-   where-      rec xs = do-         cond <- isEmpty-         if cond-            then return (reverse xs)-            else do-               x <- getter-               rec (x:xs)---- | Get remaining bytes-getRemaining :: Get Buffer-getRemaining = do-   r <- remaining-   getBuffer r----- | Count the number of bytes consumed by a getter-countBytes :: Get a -> Get (Word, a)-countBytes g = do-   cnt0 <- remaining-   r <- g-   cnt1 <- remaining-   return (cnt0 - cnt1, r)---- | Execute the getter and align on the given number of Word8-alignAfter :: Word -> Get a -> Get a-alignAfter alignment getter = do-   (cnt,r) <- countBytes getter-   uncheckedSkipAlign cnt alignment-   return r---- | Get Buffer terminated with \0 (consume \0)-getBufferNul :: Get Buffer-getBufferNul = do-   bs <- lookAhead getRemaining-   let v = bufferTakeWhile (/= 0) bs-   uncheckedSkip (bufferSize v + 1)-   return v---- | Run the Get monad-runGet :: Get a -> Buffer -> Either String a-runGet g (Buffer bs) = BG.runGet g bs---- | Run a getter and throw an exception on error-runGetOrFail :: Get a -> Buffer -> a-runGetOrFail g bs = case runGet g bs of-   Left err -> error err-   Right x  -> x----- | Get bits from a BitGet. ------ Discard last bits to align on a Word8 boundary------ FIXME: we use a continuation because Data.Serialize.Get doesn't export "put"-getBitGet :: BitOrder -> BitGet a -> (a -> Get b) -> Get b-getBitGet bo bg cont = do-   bs <- getRemaining-   let (v,s) = runBitGetPartial bo (bg <* skipBitsToAlignOnWord8M) bs-   return $ runGetOrFail (cont v) (bitGetStateInput s)---- | Apply the getter at most 'max' times-getManyAtMost :: Word -> Get (Maybe a) -> Get [a]-getManyAtMost mx f = fromMaybe [] <$> getManyBounded Nothing (Just mx) f---- | Apply the getter at least 'min' times and at most 'max' times-getManyBounded :: Maybe Word -> Maybe Word -> Get (Maybe a) -> Get (Maybe [a])-getManyBounded _ (Just 0) _  = return (Just [])-getManyBounded (Just 0) mx f = getManyBounded Nothing mx f-getManyBounded mn mx f       = lookAheadM $ f >>= \case-      Nothing -> case mn of-         Just n | n > 0 -> return Nothing-         _              -> return (Just [])-      Just x -> fmap (x:) <$> getManyBounded (minus1 mn) (minus1 mx) f-   where-      minus1 = fmap (\k -> k - 1)-
− src/lib/Haskus/Format/Binary/Layout.hs
@@ -1,57 +0,0 @@-{-# LANGUAGE DataKinds #-}-{-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE TypeOperators #-}-{-# LANGUAGE UndecidableInstances #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE AllowAmbiguousTypes #-}---- | Memory layout------ Describe a memory region-module Haskus.Format.Binary.Layout-   ( LPath (..)-   , PathElem (..)-   , lPath-   , LPathType-   , LPathOffset-   , LRoot-   , (:->)-   , (:#>)-   )-where--import Haskus.Utils.Types---- | Path in a layout-data LPath (path :: [PathElem])   = LPath---- | Layout path element-data PathElem-   = LIndex Nat      -- ^ Addressing via a numeric index-   | LSymbol Symbol  -- ^ Addressing via a symbol---- | Layout path root-type LRoot = LPath '[]---- | Index in the layout path------ Helper for ``ptr --> lPath @p``--- until-lPath :: forall e. LPath '[e]-lPath = LPath---- | Type obtained when following path p-type family LPathType p l :: *-type instance LPathType (LPath '[]) l  = l---- | Offset obtained when following path p-type family LPathOffset p l :: Nat-type instance LPathOffset (LPath '[]) l  = 0---type family (:->) p (s :: Symbol) where-   (:->) (LPath xs) s = LPath (Snoc xs ('LSymbol s))--type family (:#>) p (n :: Nat) where-   (:#>) (LPath xs) n = LPath (Snoc xs ('LIndex n))
− src/lib/Haskus/Format/Binary/Posit.hs
@@ -1,423 +0,0 @@-{-# LANGUAGE DataKinds #-}-{-# LANGUAGE GADTs #-}-{-# LANGUAGE TypeApplications #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE RankNTypes #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE KindSignatures #-}-{-# LANGUAGE UndecidableInstances #-}-{-# LANGUAGE MultiWayIf #-}-{-# LANGUAGE AllowAmbiguousTypes #-}---- | Posit (type III unum)-module Haskus.Format.Binary.Posit-   ( Posit (..)-   , PositKind (..)-   , PositK (..)-   , positKind-   , isZero-   , isInfinity-   , isPositive-   , isNegative-   , positAbs-   , PositEncoding (..)-   , PositFields (..)-   , positEncoding-   , positFields-   , positToRational-   , positFromRational-   , positApproxFactor-   , positDecimalError-   , positDecimalAccuracy-   , positBinaryError-   , positBinaryAccuracy-   , floatBinaryAccuracy-   )-where--import Haskus.Format.Binary.Word-import Haskus.Format.Binary.Bits-import Haskus.Utils.Types-import Haskus.Utils.Tuple-import Haskus.Utils.Flow--import Data.Ratio-import qualified GHC.Real as Ratio--newtype Posit (nbits :: Nat) (es :: Nat) = Posit (IntN nbits)---- | Show posit-instance-   ( Bits (IntN n)-   , FiniteBits (IntN n)-   , Ord (IntN n)-   , Num (IntN n)-   , KnownNat n-   , KnownNat es-   , Integral (IntN n)-   ) => Show (Posit n es)-   where-   show p = case positKind p of-      SomePosit Zero      -> "0"-      SomePosit Infinity  -> "Infinity"-      SomePosit (Value v) -> show (positToRational v)--data PositKind-   = ZeroK-   | InfinityK-   | NormalK-   deriving (Show,Eq)---- | Kinded Posit------ GADT that can be used to ensure at the type level that we deal with--- non-infinite/non-zero Posit values-data PositK k nbits es where-   Zero     :: PositK 'ZeroK nbits es-   Infinity :: PositK 'InfinityK nbits es-   Value    :: Posit nbits es -> PositK 'NormalK nbits es--data SomePosit n es where-   SomePosit :: PositK k n es -> SomePosit n es--type PositValue n es = PositK 'NormalK n es---- | Get the kind of the posit at the type level-positKind :: forall n es.-   ( Bits (IntN n)-   , KnownNat n-   , Eq (IntN n)-   ) => Posit n es -> SomePosit n es-positKind p-   | isZero p     = SomePosit Zero-   | isInfinity p = SomePosit Infinity-   | otherwise    = SomePosit (Value p)---- | Check if a posit is zero-isZero :: forall n es.-   ( Bits (IntN n)-   , Eq (IntN n)-   , KnownNat n-   ) => Posit n es -> Bool-{-# INLINABLE isZero #-}-isZero (Posit i) = i == zeroBits---- | Check if a posit is infinity-isInfinity :: forall n es.-   ( Bits (IntN n)-   , Eq (IntN n)-   , KnownNat n-   ) => Posit n es -> Bool-{-# INLINABLE isInfinity #-}-isInfinity (Posit i) = i == bit (natValue @n - 1)---- | Check if a posit is positive-isPositive :: forall n es.-   ( Bits (IntN n)-   , Ord (IntN n)-   , KnownNat n-   ) => PositValue n es -> Bool-{-# INLINABLE isPositive #-}-isPositive (Value (Posit i)) = i > zeroBits---- | Check if a posit is negative-isNegative :: forall n es.-   ( Bits (IntN n)-   , Ord (IntN n)-   , KnownNat n-   ) => PositValue n es -> Bool-{-# INLINABLE isNegative #-}-isNegative (Value (Posit i)) = i < zeroBits---- | Posit absolute value-positAbs :: forall n es.-   ( Num (IntN n)-   , KnownNat n-   ) => PositValue n es -> PositValue n es-positAbs (Value (Posit i)) = Value (Posit (abs i))---data PositFields = PositFields-   { positNegative         :: Bool-   , positRegimeBitCount   :: Word-   , positExponentBitCount :: Word-   , positFractionBitCount :: Word-   , positRegime           :: Int-   , positExponent         :: Word-   , positFraction         :: Word-   }-   deriving (Show)--data PositEncoding-   = PositInfinity-   | PositZero-   | PositEncoding PositFields-   deriving (Show)--positEncoding :: forall n es.-   ( Bits (IntN n)-   , Ord (IntN n)-   , Num (IntN n)-   , KnownNat n-   , KnownNat es-   , Integral (IntN n)-   ) => Posit n es -> PositEncoding-positEncoding p = case positKind p of-   SomePosit Zero        -> PositZero-   SomePosit Infinity    -> PositInfinity-   SomePosit v@(Value _) -> PositEncoding (positFields v)---- | Decode posit fields-positFields :: forall n es.-   ( Bits (IntN n)-   , Ord (IntN n)-   , Num (IntN n)-   , KnownNat n-   , KnownNat es-   , Integral (IntN n)-   ) => PositValue n es -> PositFields-positFields p = PositFields-      { positNegative         = isNegative p-      , positRegimeBitCount   = rs-      , positExponentBitCount = es-      , positFractionBitCount = fs-      , positRegime           = regime-      , positExponent         = expo-      , positFraction         = frac-      }-   where-      -- get absolute value-      Value (Posit v) = positAbs p--      (negativeRegime,regimeLen) = -         if v `testBit` (natValue @n - 2)-            -- regime has shape 111...[0|end of word], subtract 1 for sign bit-            then (False, countLeadingZeros (complement v `clearBit` (natValue @n - 1)) - 1)-            -- regime has shape 00000...[1|end of word], subtract 1 for sign bit-            else (True, countLeadingZeros v - 1)--      regime = if negativeRegime-         then negate (fromIntegral regimeLen)-         else fromIntegral regimeLen - 1 -- we encode the 0 regime--      -- length of regime bits (with stop bit)-      rs = min (natValue @n - 1) (regimeLen + 1)--      -- real exponent size (regime bits can reduce the size of the exponent)-      es = min (natValue @n - rs - 1) (natValue @es)--      -- fraction size-      fs = natValue @n - es - rs - 1--      expo = fromIntegral (maskDyn es (v `shiftR` fs))-      frac = fromIntegral (maskDyn fs v)----- | Convert a Posit into a Rational-positToRational :: forall n es.-   ( KnownNat n-   , KnownNat es-   , Eq (IntN n)-   , Bits (IntN n)-   , Integral (IntN n)-   ) => Posit n es -> Rational-positToRational p-   | isZero p     = 0 Ratio.:% 1-   | isInfinity p = Ratio.infinity-   | otherwise    = (fromIntegral useed ^^ r) * (2 ^^ e) * (1 + (f % fd))-      where-         fields = positFields (Value p)-         r      = positRegime fields-         e      = positExponent fields-         f      = fromIntegral (positFraction fields)-         fd     = 1 `shiftL` positFractionBitCount fields-         useed  = 1 `shiftL` (1 `shiftL` natValue @es) :: Integer -- 2^(2^es)---- | Convert a rational into the approximate Posit-positFromRational :: forall p n es.-   ( Posit n es ~ p-   , Num (IntN n)-   , Bits (IntN n)-   , KnownNat es-   , KnownNat n-   ) => Rational -> Posit n es-positFromRational x = if-      | x == 0              -> Posit 0-      | x == Ratio.infinity -> Posit (bit (natValue @n - 1))-      | otherwise           -> computeRegime-                              |> uncurry3 computeExponent-                              |> uncurry3 computeFraction-                              |> uncurry  computeRounding-                              |> computeSign-                              |> Posit-   where-      useed = fromIntegral (1 `shiftL` (1 `shiftL` es) :: Integer) -- 2^(2^es)--      nbits = natValue @n-      es    = natValue @es--      -- compute regime bits of the posit, return (y,p,i)-      --    y: remaining value to convert, in [1,useed) if there are enough available bits-      --    p: current posit bits-      --    i: number of set bits in p-      computeRegime-         | absx >= 1 = regime111 absx 1 2-         | otherwise = regime000 absx 1-         where-            absx = abs x--            -- push regime bits 111..1110-            regime111 y p i-               | y >= useed && i < nbits = regime111 (y / useed) ((p `uncheckedShiftL` 1) .|. 1) (i+1)-               | otherwise               = (y, p `uncheckedShiftL` 1, i+1)--            -- push regime bits 000..0001 (or 000...00010 if the full word-            -- (including the sign bit) is set)-            regime000 y i-               | y < 1 && i <= nbits = regime000 (y*useed) (i+1)-               | i >= nbits          = (y,2,nbits+1)-               | otherwise           = (y,1,i+1)--      -- compute exponent bits; return (y,p,i)-      --    y: remaining value to convert, in [1,2) if there are enough available bits-      --    p: current posit bits-      --    i: number of set bits in p-      computeExponent-            | es == 0   = (,,)-            | otherwise = go (1 `shiftL` (es - 1))-         where-            go e y p i-               | i > nbits || e == 0 = (y,p,i)-               | y >= pow2e          = go (e `uncheckedShiftR` 1) (y / pow2e) ((p `uncheckedShiftL` 1) .|. 1) (i+1)-               | otherwise           = go (e `uncheckedShiftR` 1) y            (p `uncheckedShiftL` 1)        (i+1)-               where-                  pow2e = fromIntegral (1 `shiftL` e :: Integer)--      -- compute fraction bits; return (y,p)-      --    y: remaining value to convert-      --    p: current posit bits-      computeFraction y' = go (y'-1) -- subtract hidden bit. Now y is in [0,1) if there are enough available bits-         where-            go y p i-               | i > nbits = (y,p)-               | y <= 0    = (y, p `shiftL` (nbits+1-i)) -- add remaining 0s fraction bits-               | y2 > 1    = go (y2-1) (p `shiftL` 1 + 1) (i+1)-               | otherwise = go y2     (p `shiftL` 1)     (i+1)-               where-                  y2 = 2*y--      -- at this stage, p contains an additional fraction bit.-      -- We remove it and we round accordingly.-      computeRounding y p =-         let p' = p `uncheckedShiftR` 1-         in if | not (p `testBit` 0) -> p'                                     -- closer to lower value-               | y == 1 || y == 0    -> p' + (if p' `testBit` 0 then 1 else 0) -- tie goes to nearest even-               | otherwise           -> p' + 1                                 -- closer to upper value---      -- fixup the sign bit (and use 2's complement for the other bits)-      computeSign p-         | x < 0     = negate p-         | otherwise = p----- | Factor of approximation for a given Rational when encoded as a Posit.--- The closer to 1, the better.------ Usage:------    positApproxFactor @(Posit 8 2) (52 % 137)----positApproxFactor :: forall p n es.-   ( Posit n es ~ p-   , Num (IntN n)-   , Bits (IntN n)-   , Integral (IntN n)-   , KnownNat es-   , KnownNat n-   ) => Rational -> Double-positApproxFactor r = fromRational ((positToRational (positFromRational r ::  p)) / r)---- | Compute the decimal error if the given Rational is encoded as a Posit.------ Usage:------    positDecimalError @(Posit 8 2) (52 % 137)----positDecimalError :: forall p n es.-   ( Posit n es ~ p-   , Num (IntN n)-   , Bits (IntN n)-   , Integral (IntN n)-   , KnownNat es-   , KnownNat n-   ) => Rational -> Double-positDecimalError r = abs (logBase 10 (positApproxFactor @p r))---- | Compute the number of decimals of accuracy if the given Rational is encoded--- as a Posit.------ Usage:------    positDecimalAccuracy @(Posit 8 2) (52 % 137)----positDecimalAccuracy :: forall p n es.-   ( Posit n es ~ p-   , Num (IntN n)-   , Bits (IntN n)-   , Integral (IntN n)-   , KnownNat es-   , KnownNat n-   ) => Rational -> Double-positDecimalAccuracy r = -1 * logBase 10 (positDecimalError @p r)----- | Compute the binary error if the given Rational is encoded as a Posit.------ Usage:------    positBinaryError @(Posit 8 2) (52 % 137)----positBinaryError :: forall p n es.-   ( Posit n es ~ p-   , Num (IntN n)-   , Bits (IntN n)-   , Integral (IntN n)-   , KnownNat es-   , KnownNat n-   ) => Rational -> Double-positBinaryError r = abs (logBase 2 (positApproxFactor @p r))---- | Compute the number of bits of accuracy if the given Rational is encoded--- as a Posit.------ Usage:------    positBinaryAccuracy @(Posit 8 2) (52 % 137)----positBinaryAccuracy :: forall p n es.-   ( Posit n es ~ p-   , Num (IntN n)-   , Bits (IntN n)-   , Integral (IntN n)-   , KnownNat es-   , KnownNat n-   ) => Rational -> Double-positBinaryAccuracy r = -1 * logBase 2 (positBinaryError @p r)----- | Compute the number of bits of accuracy if the given Rational is encoded--- as a Float/Double.------ Usage:------    floatBinaryAccuracy @Double (52 % 137)----floatBinaryAccuracy :: forall f.-   ( Fractional f-   , Real f-   ) => Rational -> Double-floatBinaryAccuracy r = -1 * logBase 2 floatError-   where-      floatApprox = fromRational (toRational (fromRational r :: f) / r)-      floatError  = abs (logBase 2 floatApprox)
− src/lib/Haskus/Format/Binary/Ptr.hs
@@ -1,186 +0,0 @@-{-# LANGUAGE KindSignatures #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE RoleAnnotations #-}-{-# LANGUAGE DataKinds #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE TypeApplications #-}---- | Pointers------ A pointer is a number: an offset into a memory. This is the `Addr#` type.------ We want the type-system to help us avoid errors when we use pointers, hence--- we decorate them with phantom types describing the memory layout at the--- pointed address. This is the `Ptr a` data type that wraps an `Addr#`.------ We often want to associate finalizers to pointers, i.e., actions to be run--- when the pointer is collected by the GC. These actions take the pointer as a--- parameter. This is the `ForeignPtr a` data type.------ A `ForeignPtr a` cannot be manipulated like a number because somehow we need--- to keep the pointer value that will be passed to the finalizers. Moreover we--- don't want finalizers to be executed too early, so we can't easily create a--- new ForeignPtr from another (it would require a way to disable the existing--- finalizers of a ForeignPtr, which would in turn open a whole can of worms).--- Hence we use the `FinalizedPtr a` pointer type, which has an additional--- offset field.-module Haskus.Format.Binary.Ptr-   ( PtrLike (..)-   , indexPtr'-   -- * Pointer-   , Ptr (..)-   , free-   -- * Finalized pointer-   , FinalizedPtr (..)-   , withFinalizedPtr-   -- * Foreign pointer-   , ForeignPtr-   , withForeignPtr-   , mallocForeignPtrBytes-   , nullForeignPtr-   -- * Function pointer-   , Ptr.FunPtr-   , Ptr.nullFunPtr-   , Ptr.castPtrToFunPtr-   , Ptr.castFunPtrToPtr-   -- * Pointer as a Word-   , Ptr.WordPtr-   , Ptr.wordPtrToPtr-   , Ptr.ptrToWordPtr-   )-where--import qualified Foreign.Ptr               as Ptr-import qualified Foreign.Marshal.Alloc     as Ptr-import qualified Foreign.ForeignPtr        as FP-import qualified Foreign.ForeignPtr.Unsafe as FP--- we import GHC.Ptr instead of Foreign.Ptr to have access to Ptr constructors-import GHC.Ptr (Ptr (..))-import Foreign.ForeignPtr (ForeignPtr)-import Data.Coerce-import System.IO.Unsafe--import Haskus.Format.Binary.Layout-import Haskus.Utils.Types-import Haskus.Utils.Monad----- | A finalized pointer------ We use an offset because we can't modify the pointer directly (it is--- passed to the foreign pointer destructors)-data FinalizedPtr l = FinalizedPtr {-# UNPACK #-} !(ForeignPtr l)-                                   {-# UNPACK #-} !Word  -- offset--type role FinalizedPtr phantom--instance Show (FinalizedPtr l) where-   show (FinalizedPtr fp o) = show (FP.unsafeForeignPtrToPtr fp -                                    `indexPtr` fromIntegral o)---- | Null foreign pointer-nullForeignPtr :: ForeignPtr a-{-# NOINLINE nullForeignPtr #-}-nullForeignPtr = unsafePerformIO $ FP.newForeignPtr_ nullPtr---- | Null finalized pointer-nullFinalizedPtr :: FinalizedPtr a-nullFinalizedPtr = FinalizedPtr nullForeignPtr 0---- | Use a finalized pointer-withFinalizedPtr :: FinalizedPtr a -> (Ptr a -> IO b) -> IO b-{-# INLINABLE withFinalizedPtr #-}-withFinalizedPtr (FinalizedPtr fp o) f =-   FP.withForeignPtr fp (f . (`indexPtr` fromIntegral o))---- | Pointer operations-class PtrLike (p :: * -> *) where-   -- | Cast a pointer from one type to another-   castPtr :: p a -> p b--   -- | Null pointer (offset is 0)-   nullPtr :: forall a. p a--   -- | Advance a pointer by the given amount of bytes (may be negative)-   indexPtr :: p a -> Int -> p a--   -- | Distance between two pointers in bytes (p2 - p1)-   ptrDistance :: p a -> p b -> Int--   -- | Use the pointer-   withPtr :: p a -> (Ptr a -> IO b) -> IO b--   -- | Malloc the given number of bytes-   mallocBytes :: MonadIO m => Word -> m (p a)--   -- | Add offset to the given layout field-   (-->) :: forall path l.-      ( KnownNat (LPathOffset path l)-      ) => p l -> path -> p (LPathType path l)-   {-# INLINABLE (-->) #-}-   (-->) p _ = castPtr (p `indexPtr` natValue @(LPathOffset path l))---- | Generalized version of 'indexPtr'-indexPtr' :: Integral b => Ptr a -> b -> Ptr a-indexPtr' p a = indexPtr p (fromIntegral a)---instance PtrLike Ptr where-   {-# INLINABLE castPtr #-}-   castPtr = coerce--   {-# INLINABLE nullPtr #-}-   nullPtr = Ptr.nullPtr--   {-# INLINABLE indexPtr #-}-   indexPtr = Ptr.plusPtr--   {-# INLINABLE ptrDistance #-}-   ptrDistance = Ptr.minusPtr--   {-# INLINABLE withPtr #-}-   withPtr p f = f p--   {-# INLINABLE mallocBytes #-}-   mallocBytes = liftIO . Ptr.mallocBytes . fromIntegral---instance PtrLike FinalizedPtr where-   {-# INLINABLE castPtr #-}-   castPtr = coerce--   {-# INLINABLE nullPtr #-}-   nullPtr = nullFinalizedPtr--   {-# INLINABLE indexPtr #-}-   indexPtr (FinalizedPtr fp o) n-      | n >= 0    = FinalizedPtr fp (o+fromIntegral n)-      | otherwise = FinalizedPtr fp (o-fromIntegral (abs n))--   {-# INLINABLE ptrDistance #-}-   ptrDistance (FinalizedPtr fp1 o1) (FinalizedPtr fp2 o2)-      | o2 > o1   = d + fromIntegral (o2 - o1)-      | otherwise = d - fromIntegral (o1 - o2)-      where-         d = ptrDistance (FP.unsafeForeignPtrToPtr fp1)-                         (FP.unsafeForeignPtrToPtr fp2)--   {-# INLINABLE withPtr #-}-   withPtr = withFinalizedPtr--   {-# INLINABLE mallocBytes #-}-   mallocBytes n = do-      fp <- mallocForeignPtrBytes (fromIntegral n)-      return (FinalizedPtr fp 0)---- | Malloc a foreign pointer-mallocForeignPtrBytes :: MonadIO m => Word -> m (ForeignPtr a)-mallocForeignPtrBytes = liftIO . FP.mallocForeignPtrBytes . fromIntegral---- | Use a foreign pointer-withForeignPtr :: (MonadInIO m) => ForeignPtr a -> (Ptr a -> m b) -> m b-withForeignPtr p = liftWith (FP.withForeignPtr p)---- | Free a malloced memory-free :: MonadIO m => Ptr a -> m ()-free = liftIO . Ptr.free
− src/lib/Haskus/Format/Binary/Put.hs
@@ -1,78 +0,0 @@--- | Put monad-module Haskus.Format.Binary.Put-   ( Put-   , runPut-   -- * Put-   , putBuffer-   , putByteString-   , putPadding-   , putPaddingAlign-   , putWord8-   , putWord16le-   , putWord16be-   , putWord32le-   , putWord32be-   , putWord64le-   , putWord64be-   )-where--import qualified Data.ByteString as BS-import qualified Data.Serialize.Put as BP-import Data.Serialize.Put (Put)--import Haskus.Utils.Flow (replicateM_)-import Haskus.Format.Binary.Buffer-import Haskus.Format.Binary.Word---- | Execute Put-runPut :: Put -> Buffer-runPut = Buffer . BP.runPut---- | Put a buffer-putBuffer :: Buffer -> Put-putBuffer (Buffer bs) = BP.putByteString bs---- | Put a ByteString-putByteString :: BS.ByteString -> Put-putByteString = BP.putByteString---- | Put null bytes-putPadding :: Word -> Put-putPadding n = replicateM_ (fromIntegral n) (BP.putWord8 0x00)---- | Put null bytes to align the given value to the second-putPaddingAlign :: Word -> Word -> Put-putPaddingAlign n al = putPadding n'-   where-      n' = case n `mod` al of-               0 -> 0-               x -> al - fromIntegral x---- | Put a Word8-putWord8 :: Word8 -> Put-putWord8 = BP.putWord8---- | Put a Word16 little-endian-putWord16le :: Word16 -> Put-putWord16le = BP.putWord16le---- | Put a Word16 big-endian-putWord16be :: Word16 -> Put-putWord16be = BP.putWord16be---- | Put a Word32 little-endian-putWord32le :: Word32 -> Put-putWord32le = BP.putWord32le---- | Put a Word32 big-endian-putWord32be :: Word32 -> Put-putWord32be = BP.putWord32be---- | Put a Word64 little-endian-putWord64le :: Word64 -> Put-putWord64le = BP.putWord64le---- | Put a Word64 big-endian-putWord64be :: Word64 -> Put-putWord64be = BP.putWord64be
− src/lib/Haskus/Format/Binary/Record.hs
@@ -1,207 +0,0 @@-{-# LANGUAGE KindSignatures #-}-{-# LANGUAGE DataKinds #-}-{-# LANGUAGE TypeOperators #-}-{-# LANGUAGE TypeApplications #-}-{-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE UndecidableInstances #-}-{-# LANGUAGE InstanceSigs #-}-{-# LANGUAGE ExistentialQuantification #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE AllowAmbiguousTypes #-}---- | Record (similar to C struct)-module Haskus.Format.Binary.Record-   ( Record-   , Field-   , RecordSize-   , Alignment-   , Path-   , recordSize-   , recordAlignment-   , recordField-   , recordFieldOffset-   , recordFieldPath-   , recordFieldPathOffset-   , recordToList-   )-where--import System.IO.Unsafe--import Haskus.Format.Binary.Ptr-import Haskus.Format.Binary.Storable-import Haskus.Utils.HList-import Haskus.Utils.Memory-import Haskus.Utils.Types---- | Record-newtype Record (fields :: [*]) = Record (ForeignPtr ())---- | Field-data Field (name :: Symbol) typ---- | Get record size without the ending padding bytes-type family RecordSize (fs :: [*]) (sz :: Nat) where-   RecordSize '[] sz                    = sz-   RecordSize (Field name typ ': fs) sz = -      RecordSize fs-         (sz-         -- padding bytes-         + Padding sz typ-         -- field size-         + SizeOf typ-         )--type family FieldOffset (name :: Symbol) (fs :: [*]) (sz :: Nat) where-   -- Found-   FieldOffset name (Field name typ ': fs) sz =-      sz + Padding sz typ-   -- Not found yet-   FieldOffset name (Field xx typ ': fs) sz =-      FieldOffset name fs-         (sz + Padding sz typ + SizeOf typ)--type family FieldType (name :: Symbol) (fs :: [*]) where-   FieldType name (Field name typ ': fs) = typ-   FieldType name (Field xx typ ': fs)   = FieldType name fs---- | Record size (with ending padding bytes)-type family FullRecordSize fs where-   FullRecordSize fs =-      RecordSize fs 0-      + PaddingEx (Mod (RecordSize fs 0) (RecordAlignment fs 1))-         (RecordAlignment fs 1)---- | Record alignment-type family RecordAlignment (fs :: [*]) a where-   RecordAlignment '[]                    a = a-   RecordAlignment (Field name typ ': fs) a =-      RecordAlignment fs-         (If (a <=? Alignment typ) (Alignment typ) a)---- | Return offset from a field path-type family FieldPathOffset (fs :: [*]) (path :: [Symbol]) (off :: Nat) where-   FieldPathOffset fs '[p] off = off + FieldOffset p fs 0-   FieldPathOffset fs (p ': ps) off-      = FieldPathOffset (ExtractRecord (FieldType p fs))-            ps (off + FieldOffset p fs 0)---- | Return type from a field path-type family FieldPathType (fs :: [*]) (path :: [Symbol]) where-   FieldPathType fs '[p] = FieldType p fs--   FieldPathType fs (p ': ps)-      = FieldPathType (ExtractRecord (FieldType p fs)) ps-   -type family ExtractRecord x where-   ExtractRecord (Record fs) = fs---- | Get record size-recordSize :: forall fs.-   ( KnownNat (FullRecordSize fs)-   ) => Record fs -> Word-recordSize _ = natValue' @(FullRecordSize fs)---- | Get record alignment-recordAlignment :: forall fs.-   ( KnownNat (RecordAlignment fs 1)-   ) => Record fs -> Word-recordAlignment _ = natValue' @(RecordAlignment fs 1)---- | Get a field offset-recordFieldOffset :: forall (name :: Symbol) fs.-   ( KnownNat (FieldOffset name fs 0)-   ) => Record fs -> Int-recordFieldOffset _ = natValue @(FieldOffset name fs 0)---- | Get a field-recordField :: forall (name :: Symbol) a fs.-   ( KnownNat (FieldOffset name fs 0)-   , a ~ FieldType name fs-   , StaticStorable a-   ) => Record fs -> a-recordField r@(Record fp) = unsafePerformIO $-   withForeignPtr fp $ \ptr ->do-      let ptr' = ptr `indexPtr` recordFieldOffset @name r-      staticPeek (castPtr ptr')--data Path (fs :: [Symbol])---- | Get a field offset from its path-recordFieldPathOffset :: forall path fs o.-   ( o ~ FieldPathOffset fs path 0-   , KnownNat o-   ) => Path path -> Record fs -> Int-recordFieldPathOffset _ _ = natValue @o---- | Get a field from its path-recordFieldPath :: forall path a fs o.-   ( o ~ FieldPathOffset fs path 0-   , a ~ FieldPathType fs path-   , KnownNat o-   , StaticStorable a-   ) => Path path -> Record fs -> a-recordFieldPath _ (Record fp) = unsafePerformIO $-   withForeignPtr fp $ \ptr -> do-      let-         ptr' = ptr `indexPtr` natValue @o-      staticPeek (castPtr ptr')---instance forall fs s.-      ( s ~ FullRecordSize fs-      , KnownNat s-      )-      => StaticStorable (Record fs)-   where-      type SizeOf (Record fs)    = FullRecordSize fs-      type Alignment (Record fs) = RecordAlignment fs 1--      staticPeekIO ptr = do-         let sz = recordSize (undefined :: Record fs)-         fp <- mallocForeignPtrBytes sz-         withForeignPtr fp $ \p ->-            memCopy p ptr (fromIntegral sz)-         return (Record fp)--      staticPokeIO ptr (Record fp) = do-         let sz = recordSize (undefined :: Record fs)-         withForeignPtr fp $ \p ->-            memCopy ptr p (fromIntegral sz)---data Extract = Extract--instance forall fs typ name rec b l2 i r.-   ( rec ~ Record fs                        -- the record-   , b ~ Field name typ                     -- the current field-   , i ~ (rec, HList l2)                    -- input type-   , typ ~ FieldType name fs-   , KnownNat (FieldOffset name fs 0)-   , StaticStorable typ-   , KnownSymbol name-   , r ~ (rec, HList ((String,typ) ': l2))  -- result type-   ) => Apply Extract (b, i) r where-      apply _ (_, (rec,xs)) =-         (rec, HCons (symbolValue @name, recordField @name rec) xs)---- | Convert a record into a HList-recordToList :: forall fs.-   ( HFoldr' Extract (Record fs, HList '[]) fs (Record fs, HList fs)-   ) => Record fs -> HList fs-recordToList rec = snd res-   where-      res :: (Record fs, HList fs)-      res = hFoldr' Extract ((rec,HNil) :: (Record fs, HList '[])) (undefined :: HList fs)---instance forall fs.-      ( HFoldr' Extract (Record fs, HList '[]) fs (Record fs, HList fs)-      , Show (HList fs)-      )-      => Show (Record fs)-   where-      show rec = show (recordToList rec :: HList fs)
− src/lib/Haskus/Format/Binary/Serialize.hs
@@ -1,320 +0,0 @@-{-# LANGUAGE DataKinds #-}-{-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE AllowAmbiguousTypes #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE TypeSynonymInstances #-}-{-# LANGUAGE ScopedTypeVariables #-}---- | Binary serialization of Haskell values-module Haskus.Format.Binary.Serialize-   ( PutMonad (..)-   , GetMonad (..)-   , Serializable (..)-   , Size (..)-   -- * Endianness helpers-   , putWord16BE-   , putWord32BE-   , putWord64BE-   , putWord16LE-   , putWord32LE-   , putWord64LE-   , putWord16BEs-   , putWord32BEs-   , putWord64BEs-   , putWord16LEs-   , putWord32LEs-   , putWord64LEs-   , getWord16BE-   , getWord32BE-   , getWord64BE-   , getWord16LE-   , getWord32LE-   , getWord64LE-   , getWord16BEs-   , getWord32BEs-   , getWord64BEs-   , getWord16LEs-   , getWord32LEs-   , getWord64LEs-   )-where--import Haskus.Memory.Buffer-import Haskus.Format.Binary.Word-import Haskus.Format.Binary.Endianness-import Haskus.Utils.Types-import Haskus.Utils.Monad--import GHC.Exts (IsList(..))---- | Monad which can build a sequence of bytes-class Monad m => PutMonad m where-   -- | Write a Word8-   putWord8 :: Word8 -> m ()-   -- | Write a Word16-   putWord16 :: Word16 -> m ()-   -- | Write a Word32-   putWord32 :: Word32 -> m ()-   -- | Write a Word64-   putWord64 :: Word64 -> m ()--   -- | Write some Word8-   putWord8s   :: [Word8]  -> m ()-   putWord8s xs = forM_ xs putWord8--   -- | Write some Word16-   putWord16s  :: [Word16] -> m ()-   putWord16s xs = forM_ xs putWord16--   -- | Write some Word32-   putWord32s  :: [Word32] -> m ()-   putWord32s xs = forM_ xs putWord32--   -- | Write some Word64-   putWord64s  :: [Word64] -> m ()-   putWord64s xs = forM_ xs putWord64--   -- | Write the contents of a buffer-   putBuffer   :: Buffer mut pin gc heap -> m ()--   -- | Pre-allocate at least the given amount of bytes-   ---   -- This is a hint for the putter to speed up the allocation of memory-   preAllocateAtLeast :: Word -> m ()-   preAllocateAtLeast _ = return ()---- | Monad which can read a sequence of bytes-class Monad m => GetMonad m where-   -- | Read a Word8-   getWord8    :: m Word8-   -- | Read a Word16 with host endianness-   getWord16   :: m Word16-   -- | Read a Word32 with host endianness-   getWord32   :: m Word32-   -- | Read a Word64 with host endianness-   getWord64   :: m Word64--   -- | Read some Word8-   getWord8s     :: Word -> m [Word8]-   getWord8s n = replicateM (fromIntegral n) getWord8-   -- | Read some Word16 with host endianness-   getWord16s    :: Word -> m [Word16]-   getWord16s n = replicateM (fromIntegral n) getWord16-   -- | Read some Word32 with host endianness-   getWord32s    :: Word -> m [Word32]-   getWord32s n = replicateM (fromIntegral n) getWord32-   -- | Read some Word64 with host endianness-   getWord64s    :: Word -> m [Word64]-   getWord64s n = replicateM (fromIntegral n) getWord64--   -- | Read the given amount of bytes into a new buffer-   getBuffer     :: Word -> m BufferI-   getBuffer n = do-      xs <- replicateM (fromIntegral n) getWord8-      return (fromListN (fromIntegral n) xs)--   -- | Read the given amount of bytes into the specified buffer-   getBufferInto :: Word -> Buffer 'Mutable pin gc heap -> m ()---- | Size in bytes-data Size-   = Exactly Nat  -- ^ Exactly the given size-   | AtLeast Nat  -- ^ At least the given size-   | Dynamic      -- ^ Dynamically known size---- | Binary serializable data-class Serializable a where--   -- | Size of the data in bytes-   type SizeOf a :: Size--   -- | Sensible to endianness-   type Endian a :: Bool--   -- | Dynamic size of the data in bytes-   sizeOf :: a -> Word--   -- | Serialize a value-   put :: PutMonad m => Endianness -> a -> m ()--   -- | Deserialize a value-   get :: GetMonad m => Endianness -> Word -> m a-------------------------------------------------- Helpers for endianness------------------------------------------------- | Write a Word16 with little-endian order-putWord16LE :: PutMonad m => Word16 -> m ()-putWord16LE x = putWord16 (hostToLittleEndian x)--- | Write a Word32 with little-endian order-putWord32LE :: PutMonad m => Word32 -> m ()-putWord32LE x = putWord32 (hostToLittleEndian x)--- | Write a Word64 with little-endian order-putWord64LE :: PutMonad m => Word64 -> m ()-putWord64LE x = putWord64 (hostToLittleEndian x)---- | Write a Word16 with big-endian order-putWord16BE :: PutMonad m => Word16 -> m ()-putWord16BE x = putWord16 (hostToBigEndian x)--- | Write a Word32 with big-endian order-putWord32BE :: PutMonad m => Word32 -> m ()-putWord32BE x = putWord32 (hostToBigEndian x)--- | Write a Word64 with big-endian order-putWord64BE :: PutMonad m => Word64 -> m ()-putWord64BE x = putWord64 (hostToBigEndian x)---- | Write some Word16 with little-endian order-putWord16LEs  :: PutMonad m => [Word16] -> m ()-putWord16LEs xs = putWord16s (fmap hostToLittleEndian xs)--- | Write some Word32 with little-endian order-putWord32LEs  :: PutMonad m => [Word32] -> m ()-putWord32LEs xs = putWord32s (fmap hostToLittleEndian xs)--- | Write some Word64 with little-endian order-putWord64LEs :: PutMonad m => [Word64] -> m ()-putWord64LEs xs = putWord64s (fmap hostToLittleEndian xs)--- | Write some Word16 with big-endian order-putWord16BEs  :: PutMonad m => [Word16] -> m ()-putWord16BEs xs = putWord16s (fmap hostToBigEndian xs)--- | Write some Word32 with big-endian order-putWord32BEs  :: PutMonad m => [Word32] -> m ()-putWord32BEs xs = putWord32s (fmap hostToBigEndian xs)--- | Write some Word64 with big-endian order-putWord64BEs :: PutMonad m => [Word64] -> m ()-putWord64BEs xs = putWord64s (fmap hostToBigEndian xs)---- | Read a Word16 with little-endian order-getWord16LE   :: GetMonad m => m Word16-getWord16LE = littleEndianToHost <$> getWord16--- | Read a Word32 with little-endian order-getWord32LE   :: GetMonad m => m Word32-getWord32LE = littleEndianToHost <$> getWord32--- | Read a Word64 with little-endian order-getWord64LE   :: GetMonad m => m Word64-getWord64LE = littleEndianToHost <$> getWord64--- | Read a Word16 with big-endian order-getWord16BE   :: GetMonad m => m Word16-getWord16BE = bigEndianToHost <$> getWord16--- | Read a Word32 with big-endian order-getWord32BE   :: GetMonad m => m Word32-getWord32BE = bigEndianToHost <$> getWord32--- | Read a Word64 with big-endian order-getWord64BE   :: GetMonad m => m Word64-getWord64BE = bigEndianToHost <$> getWord64----- | Read some Word16 with little-endian order-getWord16LEs    :: GetMonad m => Word -> m [Word16]-getWord16LEs n = fmap littleEndianToHost <$> getWord16s n--- | Read some Word32 with little-endian order-getWord32LEs    :: GetMonad m => Word -> m [Word32]-getWord32LEs n =  fmap littleEndianToHost <$> getWord32s n--- | Read some Word64 with little-endian order-getWord64LEs    :: GetMonad m => Word -> m [Word64]-getWord64LEs n =  fmap littleEndianToHost <$> getWord64s n---- | Read some Word16 with big-endian order-getWord16BEs    :: GetMonad m => Word -> m [Word16]-getWord16BEs n = fmap bigEndianToHost <$> getWord16s n--- | Read some Word32 with big-endian order-getWord32BEs    :: GetMonad m => Word -> m [Word32]-getWord32BEs n = fmap bigEndianToHost <$> getWord32s n--- | Read some Word64 with big-endian order-getWord64BEs    :: GetMonad m => Word -> m [Word64]-getWord64BEs n = fmap bigEndianToHost <$> getWord64s n-------------------------------------------------- Instances-----------------------------------------------instance Serializable Word8 where-   type SizeOf Word8  = 'Exactly 1-   type Endian Word8  = 'False-   sizeOf _           = 1-   put _ x            = putWord8 x-   get _ _            = getWord8--instance Serializable Word16 where-   type SizeOf Word16 = 'Exactly 2-   type Endian Word16 = 'True-   sizeOf _           = 2-   put LittleEndian x = putWord16LE x-   put BigEndian    x = putWord16BE x-   get LittleEndian _ = getWord16LE-   get BigEndian    _ = getWord16BE--instance Serializable Word32 where-   type SizeOf Word32 = 'Exactly 4-   type Endian Word32 = 'True-   sizeOf _           = 4-   put LittleEndian x = putWord32LE x-   put BigEndian    x = putWord32BE x-   get LittleEndian _ = getWord32LE-   get BigEndian    _ = getWord32BE--instance Serializable Word64 where-   type SizeOf Word64 = 'Exactly 8-   type Endian Word64 = 'True-   sizeOf _           = 8-   put LittleEndian x = putWord64LE x-   put BigEndian    x = putWord64BE x-   get LittleEndian _ = getWord64LE-   get BigEndian    _ = getWord64BE--instance Serializable Int8 where-   type SizeOf Int8   = 'Exactly 1-   type Endian Int8   = 'False-   sizeOf _           = 1-   put _ x            = putWord8 (fromIntegral x)-   get _ _            = fromIntegral <$> getWord8--instance Serializable Int16 where-   type SizeOf Int16  = 'Exactly 2-   type Endian Int16  = 'True-   sizeOf _           = 2-   put LittleEndian x = putWord16LE (fromIntegral x)-   put BigEndian    x = putWord16BE (fromIntegral x)-   get LittleEndian _ = fromIntegral <$> getWord16LE-   get BigEndian    _ = fromIntegral <$> getWord16BE--instance Serializable Int32 where-   type SizeOf Int32  = 'Exactly 4-   type Endian Int32  = 'True-   sizeOf _           = 4-   put LittleEndian x = putWord32LE (fromIntegral x)-   put BigEndian    x = putWord32BE (fromIntegral x)-   get LittleEndian _ = fromIntegral <$> getWord32LE-   get BigEndian    _ = fromIntegral <$> getWord32BE--instance Serializable Int64 where-   type SizeOf Int64  = 'Exactly 8-   type Endian Int64  = 'True-   sizeOf _           = 8-   put LittleEndian x = putWord64LE (fromIntegral x)-   put BigEndian    x = putWord64BE (fromIntegral x)-   get LittleEndian _ = fromIntegral <$> getWord64LE-   get BigEndian    _ = fromIntegral <$> getWord64BE--instance Serializable BufferI where-   type SizeOf BufferI = 'Dynamic-   type Endian BufferI = 'False-   sizeOf b            = bufferSize b-   put _ x             = putBuffer x-   get _ sz            = getBuffer sz--instance Serializable a => Serializable (AsBigEndian a) where-   type SizeOf (AsBigEndian a) = SizeOf a-   type Endian (AsBigEndian a) = 'False-   sizeOf (AsBigEndian b)      = sizeOf b-   put _ (AsBigEndian x)       = put BigEndian x-   get _ sz                    = AsBigEndian <$> get BigEndian sz--instance Serializable a => Serializable (AsLittleEndian a) where-   type SizeOf (AsLittleEndian a) = SizeOf a-   type Endian (AsLittleEndian a) = 'False-   sizeOf (AsLittleEndian b)      = sizeOf b-   put _ (AsLittleEndian x)       = put LittleEndian x-   get _ sz                       = AsLittleEndian <$> get LittleEndian sz
− src/lib/Haskus/Format/Binary/Serialize/Buffer.hs
@@ -1,142 +0,0 @@-{-# LANGUAGE DataKinds #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE DerivingStrategies #-}-{-# LANGUAGE GeneralizedNewtypeDeriving #-}-{-# LANGUAGE BangPatterns #-}---- | Serializer into a mutable buffer------ >>> let w = do putWord8 0x01 ; putWord32BE 0x23456789--- >>> b <- newBuffer 10--- >>> void $ runBufferPut b 0 w--- >>> xs <- forM [0..4] (bufferReadWord8IO b)--- >>> xs == [0x01,0x23,0x45,0x67,0x89]--- True----module Haskus.Format.Binary.Serialize.Buffer-   ( BufferPutT (..)-   , BufferPut-   , getPutOffset-   , getPutBuffer-   , setPutOffset-   , runBufferPut-   )-where--import Haskus.Format.Binary.Serialize-import Haskus.Memory.Buffer-import Haskus.Utils.Monad--import Data.Functor.Identity-import Control.Monad.Trans.State as S-import Control.Monad.Fail as F-import Control.Monad.Fix--data BufferPutState b = BufferPutState-   { bufferPutBuffer :: b    -- ^ Buffer used for writing-   , bufferPutOffset :: Word -- ^ Current offset-   } ---- | A Put monad than fails when there is not enough space in the target buffer-newtype BufferPutT b m a-   = BufferPutT (StateT (BufferPutState b) m a) -   deriving newtype-      (Functor, Applicative, Monad, MonadFail, MonadFix, MonadIO, MonadTrans)--type BufferPut b a    = BufferPutT b Identity a---- | Run a buffer put-runBufferPut :: Monad m => b -> Word -> BufferPutT b m a -> m (a,Word)-runBufferPut b off (BufferPutT s) = do-   (a,s') <- runStateT s (BufferPutState b off)-   return (a,bufferPutOffset s')---- | Get current offset-getPutOffset :: Monad m => BufferPutT b m Word-getPutOffset = BufferPutT (bufferPutOffset <$> S.get)---- | Get buffer-getPutBuffer :: Monad m => BufferPutT b m b-getPutBuffer = BufferPutT (bufferPutBuffer <$> S.get)---- | Get current offset-setPutOffset :: Monad m => Word -> BufferPutT b m ()-setPutOffset v = BufferPutT $ do-   S.modify (\s -> s { bufferPutOffset = v })----- | Called when there is not enough space left in the buffer-bufferPutNotEnoughSpace :: (MonadFail m, MonadIO m) => Word -> BufferPutT b m ()-bufferPutNotEnoughSpace reqSize = do-   F.fail $ "Not enough space in the target buffer (requiring "-          ++ show reqSize ++ " bytes)"-   --- | Helper to put something-putSomething-   :: (MonadIO m, MonadFail m)-   => Word-   -> (Buffer mut pin fin heap -> Word -> t -> m ())-   -> t-   -> BufferPutT (Buffer mut pin fin heap) m ()-{-# INLINABLE putSomething #-}-putSomething sz act v = do-   off <- getPutOffset-   b   <- getPutBuffer-   bs  <- liftIO (bufferSizeIO b)-   let !newOff = off+sz-   when (newOff > bs) $ bufferPutNotEnoughSpace sz-   lift (act b off v)-   setPutOffset newOff---- | Helper to put some things-putSomeThings-   :: (MonadIO m, MonadFail m)-   => Word-   -> (Buffer mut pin fin heap -> Word -> m ())-   -> BufferPutT (Buffer mut pin fin heap) m ()-{-# INLINABLE putSomeThings #-}-putSomeThings sz act = do-   off <- getPutOffset-   b   <- getPutBuffer-   bs  <- liftIO (bufferSizeIO b)-   let !newOff = off+sz-   when (newOff > bs) $ bufferPutNotEnoughSpace sz-   lift (act b off)-   setPutOffset newOff-   --instance-   ( MonadIO m-   , MonadFail m-   ) => PutMonad (BufferPutT (Buffer 'Mutable pin gc heap) m)-   where-      putWord8  = putSomething 1 bufferWriteWord8IO-      putWord16 = putSomething 2 bufferWriteWord16IO-      putWord32 = putSomething 4 bufferWriteWord32IO-      putWord64 = putSomething 8 bufferWriteWord64IO--      putWord8s xs = putSomeThings (fromIntegral (length xs)) $ \b off -> do-         forM_ ([off,(off+1)..] `zip` xs) $ \(boff,v) -> do-            bufferWriteWord8IO b boff v--      putWord16s xs = putSomeThings (2*fromIntegral (length xs)) $ \b off -> do-         forM_ ([off,(off+2)..] `zip` xs) $ \(boff,v) -> do-            bufferWriteWord16IO b boff v--      putWord32s xs = putSomeThings (4*fromIntegral (length xs)) $ \b off -> do-         forM_ ([off,(off+4)..] `zip` xs) $ \(boff,v) -> do-            bufferWriteWord32IO b boff v--      putWord64s xs = putSomeThings (8*fromIntegral (length xs)) $ \b off -> do-         forM_ ([off,(off+8)..] `zip` xs) $ \(boff,v) -> do-            bufferWriteWord64IO b boff v--      preAllocateAtLeast l = do-         off <- getPutOffset-         b   <- getPutBuffer-         bs  <- liftIO (bufferSizeIO b)-         when (l+off > bs) $ bufferPutNotEnoughSpace l--      putBuffer x = do-         sz <- liftIO (bufferSizeIO x)-         putSomeThings sz (\b off -> copyBuffer x 0 b off sz)
− src/lib/Haskus/Format/Binary/Storable.hs
@@ -1,538 +0,0 @@-{-# LANGUAGE DataKinds #-}-{-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE TypeOperators #-}-{-# LANGUAGE TypeApplications #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE UndecidableInstances #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE DefaultSignatures #-}-{-# LANGUAGE AllowAmbiguousTypes #-}---- | Storable class-module Haskus.Format.Binary.Storable-   ( StaticStorable (..)-   , staticPeek-   , staticPoke-   , RequiredPadding-   , Padding-   , PaddingEx-   , staticSizeOf-   , staticAlignment-   , wordBytes-   -- * Storable-   , Storable (..)-   , peek-   , poke-   , sizeOf'-   , sizeOfT-   , sizeOfT'-   , alignment'-   , alignmentT-   , alignmentT'-   , peekByteOff-   , pokeByteOff-   , peekElemOff-   , pokeElemOff-   , alloca-   , allocaBytes-   , allocaBytesAligned-   , malloc-   , with-   , withMany-   , allocaArray-   , mallocArray-   , withArray-   , withArrayLen-   , peekArray-   , pokeArray-   )-where--import qualified Foreign.Storable as FS-import Foreign.C.Types (CSize,CChar,CULong,CLong,CUInt,CInt,CUShort,CShort)-import qualified Foreign.Marshal.Alloc as P-import System.IO.Unsafe--import Haskus.Format.Binary.Word-import Haskus.Format.Binary.Ptr-import Haskus.Utils.Types-import Haskus.Utils.Types.Generics-import Haskus.Utils.Flow---- | A storable data in constant space whose size is known at compile time-class StaticStorable a where-   -- | Size of the stored data (in bytes)-   type SizeOf a    :: Nat--   -- | Alignment requirement (in bytes)-   type Alignment a :: Nat--   -- | Peek (read) a value from a memory address-   staticPeekIO :: Ptr a -> IO a--   -- | Poke (write) a value at the given memory address-   staticPokeIO :: Ptr a -> a -> IO ()---- | Peek (read) a value from a memory address-staticPeek :: (StaticStorable a, MonadIO m) => Ptr a -> m a-staticPeek p = liftIO (staticPeekIO p)---- | Poke (write) a value at the given memory address-staticPoke :: (StaticStorable a, MonadIO m) => Ptr a -> a -> m ()-staticPoke p a = liftIO (staticPokeIO p a)----- | Compute the required padding between a and b to respect b's alignment-type family RequiredPadding a b where-   RequiredPadding a b = Padding (SizeOf a) b---- | Compute the required padding between the size sz and b to respect b's alignment-type family Padding (sz :: Nat) b where-   Padding sz b = PaddingEx (Mod sz (Alignment b)) (Alignment b)--type family PaddingEx (m :: Nat) (a :: Nat) where-   PaddingEx 0 a = 0-   PaddingEx m a = a - m----- | Get statically known size-staticSizeOf :: forall a.-   ( KnownNat (SizeOf a)-   ) => a -> Word-staticSizeOf _ = natValue' @(SizeOf a)---- | Get statically known alignment-staticAlignment :: forall a.-   ( KnownNat (Alignment a)-   ) => a -> Word-staticAlignment _ = natValue' @(Alignment a)----- | Get bytes in host-endianness order-wordBytes :: forall a.-   ( Storable a-   , KnownNat (SizeOf a)-   ) => a -> [Word8]-{-# INLINABLE wordBytes #-}-wordBytes x = unsafePerformIO $-   with x $ \p -> mapM (peekByteOff (castPtr p)) [0..natValue @(SizeOf a) - 1]------ | Storable data-types------ Currently we cannot automatically derive a Storable class with type-level--- naturals for "alignment" and "sizeOf". Instead we define a Storable class--- isomorphic to the Foreign.Storable's one but with default methods using--- DefaultSignatures (i.e., the Storable instance can be automatically derived--- from a Generic instance).-class Storable a where-  peekIO            :: Ptr a -> IO a-  default peekIO    :: (Generic a, GStorable (Rep a)) => Ptr a -> IO a-  peekIO p          = fmap to $ gcPeek 0 (castPtr p)--  pokeIO            :: Ptr a -> a -> IO ()-  default pokeIO    :: (Generic a, GStorable (Rep a)) => Ptr a -> a -> IO ()-  pokeIO p x        = gcPoke 0 (castPtr p) $ from x--  alignment         :: a -> Word-  default alignment :: (Generic a, GStorable (Rep a)) => a -> Word-  alignment         = gcAlignment . from--  sizeOf            :: a -> Word-  default sizeOf    :: (Generic a, GStorable (Rep a)) => a -> Word-  sizeOf            = gcSizeOf 0 . from---- | Peek a value from a pointer-peek :: (Storable a, MonadIO m) => Ptr a -> m a-peek p = liftIO (peekIO p)---- | Poke a value to a pointer-poke :: (Storable a, MonadIO m) => Ptr a -> a -> m ()-poke p v = liftIO (pokeIO p v)---- | Generalized 'sizeOf'-sizeOf' :: (Integral b, Storable a) => a -> b-{-# INLINABLE sizeOf' #-}-sizeOf' = fromIntegral . sizeOf---- | SizeOf (for type-application)-sizeOfT :: forall a. (Storable a) => Word-{-# INLINABLE sizeOfT #-}-sizeOfT = sizeOf (undefined :: a)---- | SizeOf' (for type-application)-sizeOfT' :: forall a b. (Storable a, Integral b) => b-{-# INLINABLE sizeOfT' #-}-sizeOfT' = sizeOf' (undefined :: a)---- | Generalized 'alignment'-alignment' :: (Integral b, Storable a) => a -> b-{-# INLINABLE alignment' #-}-alignment' = fromIntegral . alignment---- | Alignment (for type-application)-alignmentT :: forall a. (Storable a) => Word-{-# INLINABLE alignmentT #-}-alignmentT = alignment (undefined :: a)---- | Alignment' (for type-application)-alignmentT' :: forall a b. (Storable a, Integral b) => b-{-# INLINABLE alignmentT' #-}-alignmentT' = alignment' (undefined :: a)---- | Peek with byte offset-peekByteOff :: (MonadIO m, Storable a) => Ptr a -> Int -> m a-{-# INLINABLE peekByteOff #-}-peekByteOff ptr off = peek (ptr `indexPtr` off)---- | Poke with byte offset-pokeByteOff :: (MonadIO m, Storable a) => Ptr a -> Int -> a -> m ()-{-# INLINABLE pokeByteOff #-}-pokeByteOff ptr off = poke (ptr `indexPtr` off)---- | Peek with element size offset-peekElemOff :: forall a m. (MonadIO m, Storable a) => Ptr a -> Int -> m a-peekElemOff ptr off = peekByteOff ptr (off * sizeOfT' @a)---- | Poke with element size offset-pokeElemOff :: (MonadIO m, Storable a) => Ptr a -> Int -> a -> m ()-pokeElemOff ptr off val = pokeByteOff ptr (off * sizeOf' val) val---- | Allocate some bytes-allocaBytes :: MonadInIO m => Word -> (Ptr a -> m b) -> m b-allocaBytes sz = liftWith (P.allocaBytes (fromIntegral sz))---- | Allocate some aligned bytes-allocaBytesAligned :: MonadInIO m => Word -> Word -> (Ptr a -> m b) -> m b-allocaBytesAligned sz align = liftWith (P.allocaBytesAligned (fromIntegral sz) (fromIntegral align))---- | @'alloca' f@ executes the computation @f@, passing as argument--- a pointer to a temporarily allocated block of memory sufficient to--- hold values of type @a@.------ The memory is freed when @f@ terminates (either normally or via an--- exception), so the pointer passed to @f@ must /not/ be used after this.----alloca :: forall a b m. (MonadInIO m, Storable a) => (Ptr a -> m b) -> m b-{-# INLINABLE alloca #-}-alloca = allocaBytesAligned (sizeOfT' @a) (alignmentT' @a)---- | Allocate a block of memory that is sufficient to hold values of type--- @a@. The size of the area allocated is determined by the 'sizeOf'--- method from the instance of 'Storable' for the appropriate type.------ The memory may be deallocated using 'free' or 'finalizerFree' when--- no longer required.-malloc :: forall a m. (MonadIO m, Storable a) => m (Ptr a)-{-# INLINABLE malloc #-}-malloc = liftIO (mallocBytes (sizeOfT @a))---- | @'with' val f@ executes the computation @f@, passing as argument--- a pointer to a temporarily allocated block of memory into which--- @val@ has been marshalled (the combination of 'alloca' and 'poke').------ The memory is freed when @f@ terminates (either normally or via an--- exception), so the pointer passed to @f@ must /not/ be used after this.-with :: (MonadInIO m, Storable a) => a -> (Ptr a -> m b) -> m b-{-# INLINABLE with #-}-with val f =-   alloca $ \ptr -> do-      poke ptr val-      f ptr---- | Temporarily allocate space for the given number of elements--- (like 'alloca', but for multiple elements).-allocaArray :: forall a b m. (MonadInIO m, Storable a) => Word -> (Ptr a -> m b) -> m b-allocaArray size = liftWith (allocaBytesAligned (size * sizeOfT' @a) (alignmentT' @a))---- | Allocate space for the given number of elements--- (like 'malloc', but for multiple elements).-mallocArray :: forall a m. (MonadIO m, Storable a) => Word -> m (Ptr a)-mallocArray size = mallocBytes (size * sizeOfT @a)---- | Convert an array of given length into a Haskell list.  The implementation--- is tail-recursive and so uses constant stack space.-peekArray :: (MonadIO m, Storable a) => Word -> Ptr a -> m [a]-peekArray size ptr-   | size <= 0 = return []-   | otherwise = f (size-1) []-  where-    f 0 acc = (:acc) <$> peekElemOff ptr 0-    f n acc = f (n-1) =<< ((:acc) <$> peekElemOff ptr (fromIntegral n))---- | Write the list elements consecutive into memory-pokeArray :: (MonadIO m, Storable a) => Ptr a -> [a] -> m ()-pokeArray ptr vals0 = go vals0 0-  where go [] _         = return ()-        go (val:vals) n = do pokeElemOff ptr n val; go vals (n+1)---- | Temporarily store a list of storable values in memory--- (like 'with', but for multiple elements).-withArray :: (MonadInIO m, Storable a) => [a] -> (Ptr a -> m b) -> m b-withArray vals = withArrayLen vals . const---- | Like 'withArray', but the action gets the number of values--- as an additional parameter-withArrayLen :: (MonadInIO m, Storable a) => [a] -> (Word -> Ptr a -> m b) -> m b-withArrayLen vals f  =-  allocaArray len $ \ptr -> do-      pokeArray ptr vals-      f len ptr-  where-    len = fromIntegral (length vals)---- | Replicates a @withXXX@ combinator over a list of objects, yielding a list of--- marshalled objects-withMany :: (a -> (b -> res) -> res)  -- withXXX combinator for one object-         -> [a]                       -- storable objects-         -> ([b] -> res)              -- action on list of marshalled obj.s-         -> res-withMany _       []     f = f []-withMany withFoo (x:xs) f = withFoo x $ \x' ->-                              withMany withFoo xs (\xs' -> f (x':xs'))--class GStorable a where-  gcAlignment :: a x -> Word-  gcPeek      :: Word -> Ptr (a x)-> IO (a x)-  gcPoke      :: Word -> Ptr (a x) -> a x -> IO ()-  gcSizeOf    :: Word -> a x -> Word--  -- padding before the field to align from the given offset-  gcPadding   :: Word -> a x -> Word-  gcPadding off a = (gcAlignment a - off) `mod` gcAlignment a--instance GStorable U1 where-  gcAlignment _ = 0-  gcPeek _ _    = return U1-  gcPoke _ _ _  = return ()-  gcSizeOf _ _  = 0-  gcPadding _ _ = 0--instance (GStorable a, GStorable b) => GStorable (a :*: b) where-  gcAlignment _ = lcm (gcAlignment (undefined :: a x))-                      (gcAlignment (undefined :: b y))--  gcPeek off p = do-    a <- gcPeek off                    $ castPtr p-    b <- gcPeek (off + gcSizeOf off a) $ castPtr p-    return $ a :*: b--  gcPoke off p (a :*: b) = do-    gcPoke off                    (castPtr p) a-    gcPoke (off + gcSizeOf off a) (castPtr p) b--  gcSizeOf off _    = let-    a = undefined :: a x-    b = undefined :: b y-    off2 = off + gcSizeOf off a-    in gcSizeOf off a + gcSizeOf off2 b--instance (GStorable a) => GStorable (M1 i c a) where-  gcAlignment (M1 x)     = gcAlignment x-  gcPeek off p           = fmap M1 $ gcPeek off (castPtr p)-  gcPoke off p (M1 x)    = gcPoke off (castPtr p) x-  gcSizeOf off (M1 x)    = gcSizeOf off x-  gcPadding off (M1 x)   = gcPadding off x--instance (Storable a) => GStorable (K1 i a) where-  gcAlignment (K1 x)     = alignment x-  gcPeek off p           = fmap K1 $ peek (castPtr p `indexPtr'` (off + gcPadding off (undefined :: K1 i a x)))-  gcPoke off p (K1 x)    = poke (castPtr p `indexPtr'` (off + gcPadding off (undefined :: K1 i a x))) x-  gcSizeOf off (K1 x)    = gcPadding off (undefined :: K1 i a x) + sizeOf x----- | Generalize FS.peek-fsPeek :: (FS.Storable a, MonadIO m) => Ptr a -> m a-fsPeek = liftIO . FS.peek---- | Generalize FS.poke-fsPoke :: (FS.Storable a, MonadIO m) => Ptr a -> a -> m ()-fsPoke ptr a = liftIO (FS.poke ptr a)--instance StaticStorable Word8 where-   type SizeOf    Word8 = 1-   type Alignment Word8 = 1-   staticPeekIO         = fsPeek-   staticPokeIO         = fsPoke--instance StaticStorable Word16 where-   type SizeOf    Word16 = 2-   type Alignment Word16 = 2-   staticPeekIO          = fsPeek-   staticPokeIO          = fsPoke--instance StaticStorable Word32 where-   type SizeOf    Word32 = 4-   type Alignment Word32 = 4-   staticPeekIO          = fsPeek-   staticPokeIO          = fsPoke--instance StaticStorable Word64 where-   type SizeOf    Word64 = 8-   type Alignment Word64 = 8-   staticPeekIO          = fsPeek-   staticPokeIO          = fsPoke--instance StaticStorable Int8 where-   type SizeOf    Int8 = 1-   type Alignment Int8 = 1-   staticPeekIO        = fsPeek-   staticPokeIO        = fsPoke--instance StaticStorable Int16 where-   type SizeOf    Int16 = 2-   type Alignment Int16 = 2-   staticPeekIO         = fsPeek-   staticPokeIO         = fsPoke--instance StaticStorable Int32 where-   type SizeOf    Int32 = 4-   type Alignment Int32 = 4-   staticPeekIO         = fsPeek-   staticPokeIO         = fsPoke--instance StaticStorable Int64 where-   type SizeOf    Int64 = 8-   type Alignment Int64 = 8-   staticPeekIO         = fsPeek-   staticPokeIO         = fsPoke---instance Storable Word8 where-   sizeOf    _ = 1-   alignment _ = 1-   peekIO      = fsPeek-   pokeIO      = fsPoke--instance Storable Word16 where-   sizeOf    _ = 2-   alignment _ = 2-   peekIO      = fsPeek-   pokeIO      = fsPoke--instance Storable Word32 where-   sizeOf    _ = 4-   alignment _ = 4-   peekIO      = fsPeek-   pokeIO      = fsPoke--instance Storable Word64 where-   sizeOf    _ = 8-   alignment _ = 8-   peekIO      = fsPeek-   pokeIO      = fsPoke--instance Storable Int8 where-   sizeOf    _ = 1-   alignment _ = 1-   peekIO      = fsPeek-   pokeIO      = fsPoke--instance Storable Int16 where-   sizeOf    _ = 2-   alignment _ = 2-   peekIO      = fsPeek-   pokeIO      = fsPoke--instance Storable Int32 where-   sizeOf    _ = 4-   alignment _ = 4-   peekIO      = fsPeek-   pokeIO      = fsPoke--instance Storable Int64 where-   sizeOf    _ = 8-   alignment _ = 8-   peekIO      = fsPeek-   pokeIO      = fsPoke--instance Storable Float where-   sizeOf    _ = 4-   alignment _ = 4-   peekIO      = fsPeek-   pokeIO      = fsPoke--instance Storable Double where-   sizeOf    _ = 8-   alignment _ = 8-   peekIO      = fsPeek-   pokeIO      = fsPoke--instance Storable Char where-   sizeOf      = fromIntegral . FS.sizeOf-   alignment   = fromIntegral . FS.alignment-   peekIO      = fsPeek-   pokeIO      = fsPoke--instance Storable Word where-   sizeOf      = fromIntegral . FS.sizeOf-   alignment   = fromIntegral . FS.alignment-   peekIO      = fsPeek-   pokeIO      = fsPoke--instance Storable Int where-   sizeOf      = fromIntegral . FS.sizeOf-   alignment   = fromIntegral . FS.alignment-   peekIO      = fsPeek-   pokeIO      = fsPoke--instance Storable (Ptr a) where-   sizeOf      = fromIntegral . FS.sizeOf-   alignment   = fromIntegral . FS.alignment-   peekIO      = fsPeek-   pokeIO      = fsPoke--instance Storable CSize where-   sizeOf      = fromIntegral . FS.sizeOf-   alignment   = fromIntegral . FS.alignment-   peekIO      = fsPeek-   pokeIO      = fsPoke--instance Storable CChar where-   sizeOf      = fromIntegral . FS.sizeOf-   alignment   = fromIntegral . FS.alignment-   peekIO      = fsPeek-   pokeIO      = fsPoke--instance Storable CULong where-   sizeOf      = fromIntegral . FS.sizeOf-   alignment   = fromIntegral . FS.alignment-   peekIO      = fsPeek-   pokeIO      = fsPoke--instance Storable CLong where-   sizeOf      = fromIntegral . FS.sizeOf-   alignment   = fromIntegral . FS.alignment-   peekIO      = fsPeek-   pokeIO      = fsPoke--instance Storable CUInt where-   sizeOf      = fromIntegral . FS.sizeOf-   alignment   = fromIntegral . FS.alignment-   peekIO      = fsPeek-   pokeIO      = fsPoke--instance Storable CInt where-   sizeOf      = fromIntegral . FS.sizeOf-   alignment   = fromIntegral . FS.alignment-   peekIO      = fsPeek-   pokeIO      = fsPoke--instance Storable CUShort where-   sizeOf      = fromIntegral . FS.sizeOf-   alignment   = fromIntegral . FS.alignment-   peekIO      = fsPeek-   pokeIO      = fsPoke--instance Storable CShort where-   sizeOf      = fromIntegral . FS.sizeOf-   alignment   = fromIntegral . FS.alignment-   peekIO      = fsPeek-   pokeIO      = fsPoke--instance Storable WordPtr where-   sizeOf      = fromIntegral . FS.sizeOf-   alignment   = fromIntegral . FS.alignment-   peekIO      = fsPeek-   pokeIO      = fsPoke
− src/lib/Haskus/Format/Binary/Union.hs
@@ -1,185 +0,0 @@-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE DataKinds #-}-{-# LANGUAGE TypeOperators #-}-{-# LANGUAGE TypeApplications #-}-{-# LANGUAGE UndecidableInstances #-}-{-# LANGUAGE AllowAmbiguousTypes #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE FlexibleInstances #-}---- | Union (as in C)------ Unions are storable and can contain any storable data.--- --- Use 'fromUnion' to read an alternative:------ @--- {-# LANGUAGE DataKinds #-}------ getUnion :: IO (Union '[Word16, Word32, Word64])--- getUnion = ...------ test = do---    u <- getUnion------    -- to get one of the member---    let v = fromUnion u :: Word16---    let v = fromUnion u :: Word32---    let v = fromUnion u :: Word64------    -- This won't compile (Word8 is not a member of the union)---    let v = fromUnion u :: Word8--- @------ Use 'toUnion' to create a new union:------ @--- let---    u2 :: Union '[Word32, Vector 4 Word8]---    u2 = toUnion (0x12345678 :: Word32)--- @----module Haskus.Format.Binary.Union-   ( Union-   , fromUnion-   , toUnion-   , toUnionZero-   )-where--import Haskus.Utils.Memory (memCopy, memSet)-import Haskus.Utils.Types hiding (Union)-import Haskus.Utils.HList-import Haskus.Utils.Flow (when)-import Haskus.Format.Binary.Storable-import Haskus.Format.Binary.Ptr--import System.IO.Unsafe (unsafePerformIO)--import qualified Foreign.Storable as FS----- TODO: rewrite rules--- poke p (toUnion x) = poke (castPtr p) x------ (fromUnion <$> peek p) :: IO a  = peek (castPtr p) :: IO a------ | An union ------ We use a list of types as a parameter.------ The union is just a pointer to a buffer containing the value(s). The size of--- the buffer is implicitly known from the types in the list.-newtype Union (x :: [*]) = Union (ForeignPtr ()) deriving (Show)---- | Retrieve a union member from its type-fromUnion :: (Storable a, Member a l) => Union l -> a-fromUnion (Union fp) = unsafePerformIO $ withForeignPtr fp (peek . castPtr)---- | Create a new union from one of the union types-toUnion :: forall a l . (Storable (Union l), Storable a, Member a l) => a -> Union l-toUnion = toUnion' False---- | Like 'toUnion' but set the remaining bytes to 0-toUnionZero :: forall a l . (Storable (Union l), Storable a, Member a l) => a -> Union l-toUnionZero = toUnion' True----- | Create a new union from one of the union types-toUnion' :: forall a l . (Storable (Union l), Storable a, Member a l) => Bool -> a -> Union l-toUnion' zero v = unsafePerformIO $ do-   let sz = sizeOfT @(Union l)-   fp <- mallocForeignPtrBytes (fromIntegral sz)-   withForeignPtr fp $ \p -> do-      -- set bytes after the object to 0-      when zero $ do-         let psz = sizeOfT @a-         memSet (p `indexPtr'` psz) (fromIntegral (sz - psz)) 0-      poke (castPtr p) v-   return $ Union fp--type family MapSizeOf fs where-   MapSizeOf '[]       = '[]-   MapSizeOf (x ': xs) = SizeOf x ': MapSizeOf xs--type family MapAlignment fs where-   MapAlignment '[]       = '[]-   MapAlignment (x ': xs) = Alignment x ': MapAlignment xs---instance forall fs.-      ( KnownNat (ListMax (MapSizeOf fs))-      , KnownNat (ListMax (MapAlignment fs))-      )-      => StaticStorable (Union fs)-   where-      type SizeOf (Union fs)    = ListMax (MapSizeOf fs)-      type Alignment (Union fs) = ListMax (MapAlignment fs)--      staticPeekIO ptr = do-         let sz = natValue @(SizeOf (Union fs))-         fp <- mallocForeignPtrBytes sz-         withForeignPtr fp $ \p -> -            memCopy p (castPtr ptr) (fromIntegral sz)-         return (Union fp)--      staticPokeIO ptr (Union fp) = do-         withForeignPtr fp $ \p ->-            memCopy (castPtr ptr) p (natValue @(SizeOf (Union fs)))------------------------------------------------------------------------------------------ We use HFoldr' to get the maximum size and alignment of the types in the union----------------------------------------------------------------------------------------data FoldSizeOf    = FoldSizeOf-data FoldAlignment = FoldAlignment--instance (r ~ Word, Storable a) => Apply FoldSizeOf (a, Word) r where-   apply _ (_,r) = max r (sizeOfT @a)--instance (r ~ Word, Storable a) => Apply FoldAlignment (a, Word) r where-   apply _ (_,r) = max r (alignmentT @a)---- | Get the union size (i.e. the maximum of the types in the union)-unionSize :: forall l . HFoldr' FoldSizeOf Word l Word => Union l -> Word-unionSize _ = hFoldr' FoldSizeOf (0 :: Word) (undefined :: HList l)---- | Get the union alignment (i.e. the maximum of the types in the union)-unionAlignment :: forall l . HFoldr' FoldAlignment Word l Word => Union l -> Word-unionAlignment _ = hFoldr' FoldAlignment (0 :: Word) (undefined :: HList l)------------------------------------------------------------------------------------------- Finally we can write the Storable instance----------------------------------------------------------------------------------------instance-   ( HFoldr' FoldSizeOf Word l Word-   , HFoldr' FoldAlignment Word l Word-   ) => Storable (Union l) where-   sizeOf     = unionSize-   alignment  = unionAlignment-   peekIO ptr = do-      let sz = sizeOfT' @(Union l)-      fp <- mallocForeignPtrBytes sz-      withForeignPtr fp $ \p -> -         memCopy p (castPtr ptr) (fromIntegral sz)-      return (Union fp)--   pokeIO ptr (Union fp) = withForeignPtr fp $ \p ->-      memCopy (castPtr ptr) p (sizeOfT' @(Union l))----- compatibility instance with Foreign.Storable-instance-   ( HFoldr' FoldSizeOf Word l Word-   , HFoldr' FoldAlignment Word l Word-   ) => FS.Storable (Union l) where-   sizeOf     = fromIntegral . unionSize-   alignment  = fromIntegral . unionAlignment-   peek       = peekIO-   poke       = pokeIO
− src/lib/Haskus/Format/Binary/Unum.hs
@@ -1,737 +0,0 @@-{-# LANGUAGE DataKinds #-}-{-# LANGUAGE KindSignatures #-}-{-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE TypeOperators #-}-{-# LANGUAGE TypeApplications #-}-{-# LANGUAGE UndecidableInstances #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE ConstraintKinds #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE AllowAmbiguousTypes #-}-{-# LANGUAGE CPP #-}-#if MIN_VERSION_GLASGOW_HASKELL (8,6,0,0)-{-# LANGUAGE NoStarIsType #-}-#endif--module Haskus.Format.Binary.Unum-   ( Unum-   , UnumNum (..)-   , I-   , U (..)-   , Neg-   , Rcp-   , Infinite-   , Log2-   , UnumNumbers-   , UnumSize-   , BackingWord-   , UBit (..)-   , unumSize-   , unumZero-   , unumInfinite-   , unumEncode-   , unumBits-   , unumNegate-   , unumReciprocate-   , unumLabels-   , Sign (..)-   , unumSign-   -- * SORN (bit-sets)-   , SORN-   , SORNBackingWord-   , sornBits-   , sornSize-   , sornEmpty-   , sornFull-   , sornNonInfinite-   , sornNonZero-   , sornSingle-   , sornInsert-   , sornMember-   , sornRemove-   , sornUnion-   , sornIntersect-   , sornComplement-   , sornNegate-   , sornElems-   , sornFromElems-   , sornFromTo-   , SornAdd (..)-   -- * Contiguous SORN-   , CSORN (..)-   , csornSize-   , csornBits-   , csornToSorn-   , csornEmpty-   , csornIsEmpty-   , csornFromTo-   , csornFull-   , csornSingle-   )-where--import Haskus.Format.Binary.Word-import Haskus.Format.Binary.Bits-import Haskus.Format.Binary.BitField-import Haskus.Utils.Types hiding (Log2)-import Haskus.Utils.HList-import Haskus.Utils.Flow--import Data.Kind (Type)---- | An Unum------ 0 (and its reciprocal) is always included.--- Numbers have to be >= 1 and sorted.------ e.g., Unum '[] => /0 .. 0 .. /0---       Unum '[I 1] => /0 .. -1 .. 0 .. 1 .. /0---       Unum '[I 1, I 2] => /0 .. -2 .. -1 .. -/2 .. 0 .. /2 .. 1 .. 2 .. /0---       Unum '[I 1, PI]  => /0 .. -PI .. -1 .. -/PI .. 0 .. /PI .. 1 .. PI .. /0-data Unum (xs :: [Type])---class UnumNum a where-   unumLabel :: a -> String--data I (n :: Nat)-data Neg a-data Rcp a-data Uncertain a--instance KnownNat n => UnumNum (I n) where-   unumLabel _ = show (natValue' @n)--instance UnumNum x => UnumNum (Rcp x) where-   unumLabel _ = "/" ++ unumLabel (undefined :: x)--instance UnumNum x => UnumNum (Neg x) where-   unumLabel _ = "-" ++ unumLabel (undefined :: x)--instance UnumNum x => UnumNum (Uncertain x) where-   unumLabel _ = unumLabel (undefined :: x) ++ ".."--type Infinite = Rcp (I 0)--type family Simplify a where-   Simplify a = Simplify' 'True a--type family Simplify' loop a where-   Simplify' l (Rcp (Rcp x))  = Simplify x-   Simplify' l (Neg (Neg x))  = Simplify x-   Simplify' l (Neg (I 0))    = I 0-   Simplify' l (Rcp (I 1))    = I 1-   Simplify' l (Neg Infinite) = Infinite -- infinite is special-   Simplify' l (Rcp (Neg x))  = Simplify (Neg (Rcp x)) -- Neg are outer-   Simplify' 'True (Rcp x)    = Simplify' 'False (Rcp (Simplify x))-   Simplify' 'True (Neg x)    = Simplify' 'False (Neg (Simplify x))-   Simplify' 'False (Rcp x)   = Rcp (Simplify x)-   Simplify' 'False (Neg x)   = Neg (Simplify x)-   Simplify' l x              = x---- | Compute the precise numbers set-type family UnumNumbers x where-   -- add /0 (infinite), add reciprocals, add negations, nub-   UnumNumbers (Unum xs) = Nub (AddNeg (AddRcp (Snoc xs Infinite)))---- | Positive numbers in the unums-type family UnumPositives x where-   UnumPositives (Unum xs) = Nub (AddRcp (Snoc xs Infinite))---- | Indexable numbers-type family UnumIndexables x where-   UnumIndexables u =-      Nub (Concat (UnumPositives u) (Reverse (MapNeg (UnumPositives u))))---- | All unum members-type family UnumMembers x where-   UnumMembers u = MakeMembers (UnumIndexables u)--type family MakeMembers xs where-   MakeMembers '[]       = '[]-   MakeMembers (x ': xs) = x ': Uncertain x ': MakeMembers xs- --data GetLabel = GetLabel--instance  forall a r.-   ( UnumNum a-   , r ~ [String]-   ) => Apply GetLabel (a, [String]) r where-   apply _ (x,xs) = unumLabel x : xs---- | Unum labels-unumLabels :: forall u v.-   ( HFoldr' GetLabel [String] v [String]-   , v ~ UnumMembers u-   ) => [String]-unumLabels = hFoldr' GetLabel ([] :: [String]) (undefined :: HList v)---- | Compute the number of bits required-type family UnumSize x where-   UnumSize x = 1 + Log2 (Length (UnumNumbers x)) -- add 1 for ubit---- | Size of an unum in bits-unumSize :: forall u.-   ( KnownNat (UnumSize u)-   ) => Word-unumSize = natValue @(UnumSize u)---- | Zero-unumZero :: forall u.-   ( Num (BackingWord u)-   , Bits (BackingWord u)-   , Encodable (I 0) u-   ) => U u-unumZero = unumEncode @u @(I 0) ExactNumber---- | Infinite-unumInfinite :: forall u.-   ( Num (BackingWord u)-   , Bits (BackingWord u)-   , Encodable Infinite u-   ) => U u-unumInfinite = unumEncode @u @Infinite ExactNumber--type family Div2 n where-  Div2 0 = 0-  Div2 1 = 0-  Div2 n = Div2 (n - 2) + 1--type family Log2 n where-  Log2 0 = 0-  Log2 1 = 0-  Log2 n = Log2 (Div2 n) + 1---- | Backing word for the unum-type family BackingWord x where-   BackingWord x = WordAtLeast (UnumSize x)--type family MapRcp xs where-   MapRcp '[] = '[]-   MapRcp (x ': xs) = Simplify (Rcp x) ': MapRcp xs--type family MapNeg xs where-   MapNeg '[] = '[]-   MapNeg (x ': xs) = Simplify (Neg x) ': MapNeg xs--type family AddRcp xs where-   AddRcp xs = Concat (Reverse (MapRcp xs)) xs--type family AddNeg xs where-   AddNeg xs = Concat (Reverse (MapNeg xs)) xs--newtype U u = U (BackingWord u)--instance Eq (BackingWord u) => Eq (U u) where-   U x == U y = x == y--instance forall u v.-   ( HFoldr' GetLabel [String] v [String]-   , v ~ UnumMembers u-   , Integral (BackingWord u)-   ) => Show (U u) where-   show (U w) = unumLabels @u !! fromIntegral w--unumBits :: forall u.-   ( Bits (BackingWord u)-   , KnownNat (UnumSize u)-   ) => U u -> String-unumBits (U w) = drop (fromIntegral (bitSize w - unumSize @u)) (bitsToString w)--type Encodable x u =-   ( KnownNat (IndexOf (Simplify x) (UnumIndexables u)))----- | Uncertainty bit-data UBit-   = ExactNumber   -- ^ Exact number-   | OpenInterval  -- ^ OpenInterval above the exact number-   deriving (Show,Eq)---- | Encode a number-unumEncode :: forall u x i.-   ( i ~ IndexOf (Simplify x) (UnumIndexables u)-   , KnownNat i-   , Num (BackingWord u)-   , Bits (BackingWord u)-   ) => UBit -> U u-{-# INLINABLE unumEncode #-}-unumEncode b = case b of-      ExactNumber  -> U w-      OpenInterval -> U (setBit w 0)-   where-      w = natValue @i `shiftL` 1----- | Negate a number-unumNegate :: forall u.-   ( Bits (BackingWord u)-   , Num (BackingWord u)-   , KnownNat (UnumSize u)-   ) => U u -> U u-{-# INLINABLE unumNegate #-}-unumNegate (U w) = U (maskDyn s (complement w + 1))-   where-      s = unumSize @u----- | Reciprocate a number-unumReciprocate :: forall u.-   ( Bits (BackingWord u)-   , Num (BackingWord u)-   , KnownNat (UnumSize u)-   ) => U u -> U u-{-# INLINABLE unumReciprocate #-}-unumReciprocate (U w) = U (w `xor` m + 1)-   where-      s = unumSize @u-      m = makeMaskDyn (s-1)---data Sign-   = Positive-   | Negative-   | NoSign-   deriving (Show,Eq)---- | Get unum sign-unumSign :: forall u.-   ( Bits (BackingWord u)-   , KnownNat (UnumSize u)-   ) => U u -> Sign-unumSign (U w) =-      if clearBit w n == zeroBits -- infinity or zero-         then NoSign-         else if testBit w n -            then Negative -            else Positive-   where-      n = fromIntegral (unumSize @u - 1)--------------------------------------------------------------------------------------- SORN implementation as bit-sets--- ----------------------------------  --- We use one bit per unum in the set.------ E.g., 2-bit  unum means 4-bit          SORN---       8-bit  unum means 256-bit        SORN (32 B)---       16-bit unum means 65536-bit      SORN (8 kB)---       24-bit unum means 16777216-bit   SORN (2 MB)---       32-bit unum means 4294967296-bit SORN (512 MB)---------------------------------------------------------------------------------------type family SORNSize u where-   SORNSize u = Length (UnumMembers u)--type family SORNBackingWord u where-   SORNBackingWord u = WordAtLeast (SORNSize u)--newtype SORN u = SORN (SORNBackingWord u)--instance forall u v.-   ( KnownNat (SORNSize u)-   , Bits (SORNBackingWord u)-   , Num (BackingWord u)-   , Integral (BackingWord u)-   , HFoldr' GetLabel [String] v [String]-   , v ~ UnumMembers u-   ) => Show (SORN u) where-   show = show . sornElems-   ---- | Show SORN bits-sornBits :: forall u s.-   ( Bits (SORNBackingWord u)-   , KnownNat (UnumSize u)-   , s ~ SORNSize u-   , KnownNat s-   ) => SORN u -> String-sornBits (SORN w) = drop (bitSize w - natValue @s) (bitsToString w)------ | Size of a SORN in bits-sornSize :: forall u s.-   ( s ~ SORNSize u-   , KnownNat s-   ) => Word-sornSize = natValue @s---- | Empty SORN-sornEmpty :: (Bits (SORNBackingWord u)) => SORN u-sornEmpty = SORN zeroBits---- | Full SORN-sornFull :: forall u.-   ( Bits (SORNBackingWord u)-   , KnownNat (SORNSize u)-   ) => SORN u-sornFull = SORN (maskDyn s (complement zeroBits))-   where-      s = sornSize @u---- | Full SORN without infinite-sornNonInfinite :: forall u.-   ( Bits (SORNBackingWord u)-   , Integral (BackingWord u)-   , Bits (BackingWord u)-   , Encodable Infinite u-   ) => SORN u-sornNonInfinite = sornRemove (SORN (complement zeroBits)) inf-   where-      inf = unumEncode @u @Infinite ExactNumber---- | Full SORN without infinite-sornNonZero ::-   ( Bits (SORNBackingWord u)-   , Integral (BackingWord u)-   , Bits (BackingWord u)-   , Encodable (I 0) u-   ) => SORN u-sornNonZero = sornRemove (SORN (complement zeroBits)) unumZero---- | SORN singleton-sornSingle ::-   ( Integral (BackingWord u)-   , Bits (SORNBackingWord u)-   ) => U u -> SORN u-sornSingle = sornInsert sornEmpty---- | Insert in a SORN-sornInsert :: forall u.-   ( Bits (SORNBackingWord u)-   , Integral (BackingWord u)-   ) => SORN u -> U u -> SORN u-sornInsert (SORN w) (U v) = SORN (setBit w (fromIntegral v))---- | Remove in a SORN-sornRemove :: forall u.-   ( Bits (SORNBackingWord u)-   , Integral (BackingWord u)-   ) => SORN u -> U u -> SORN u-sornRemove (SORN w) (U v) = SORN (clearBit w (fromIntegral v))---- | Test membership in a SORN-sornMember :: forall u.-   ( Bits (SORNBackingWord u)-   , Integral (BackingWord u)-   ) => SORN u -> U u -> Bool-sornMember (SORN w) (U x) = testBit w (fromIntegral x)---- | Union of two SORNs-sornUnion :: forall u.-   ( Bits (SORNBackingWord u)-   ) => SORN u -> SORN u -> SORN u-sornUnion (SORN w) (SORN v) = SORN (w .|. v)---- | Intersection of two SORNs-sornIntersect :: forall u.-   ( Bits (SORNBackingWord u)-   ) => SORN u -> SORN u -> SORN u-sornIntersect (SORN w) (SORN v) = SORN (w .&. v)---- | Complement the SORN-sornComplement ::-   ( Bits (SORNBackingWord u)-   ) => SORN u -> SORN u-sornComplement (SORN x) = SORN (complement x)---- | Negate a SORN-sornNegate :: forall u.-   ( Bits (SORNBackingWord u)-   , Bits (BackingWord u)-   , Integral (BackingWord u)-   , KnownNat (SORNSize u)-   , KnownNat (UnumSize u)-   ) => SORN u -> SORN u-sornNegate = sornFromElems . fmap unumNegate . sornElems---- | Elements in the SORN-sornElems :: forall u s.-   ( s ~ SORNSize u-   , KnownNat s-   , Bits (SORNBackingWord u)-   , Num (BackingWord u)-   ) => SORN u -> [U u]-sornElems (SORN x) = foldl b [] (reverse ([s `shiftR` 1 .. s-1]-                                  ++ [0 .. (s-1) `shiftR` 1]))-   where-      s      = natValue @s-      b us i = if testBit x i-                  then U (fromIntegral i) : us-                  else us---- | Create a SORN from its elements-sornFromElems ::-   ( Integral (BackingWord u)-   , Bits (SORNBackingWord u)-   ) => [U u] -> SORN u-sornFromElems = foldl sornInsert sornEmpty---- | Create a contiguous SORN from two elements-sornFromTo :: forall u.-   ( Integral (BackingWord u)-   , Bits (SORNBackingWord u)-   , Bits (BackingWord u)-   , KnownNat (UnumSize u)-   ) => U u -> U u -> SORN u-sornFromTo (U a) (U b) = go sornEmpty a-   where-      go w x -         | x == b    = sornInsert w (U x)-         | otherwise = go (sornInsert w (U x)) (maskDyn s (x+1))-      s = unumSize @u---class SornAdd u where-   -- | Add two Unums-   sornAddU :: U u -> U u -> SORN u--   -- | Add two SORNs-   sornAdd ::-      ( KnownNat (SORNSize u)-      , Bits (SORNBackingWord u)-      , Num (BackingWord u)-      ) => SORN u -> SORN u -> SORN u-   sornAdd a b =-      foldl sornUnion sornEmpty [ sornAddU x y-                                | x <- sornElems a-                                , y <- sornElems b-                                ]--   -- | Add a SORN with itself-   sornAddDep ::-      ( KnownNat (SORNSize u)-      , Bits (SORNBackingWord u)-      , Num (BackingWord u)-      ) => SORN u -> SORN u-   sornAddDep a =-      foldl sornUnion sornEmpty [ sornAddU x x-                                | x <- sornElems a-                                ]--   -- | Subtract two Unums-   sornSubU :: -      ( Bits (BackingWord u)-      , Num (BackingWord u)-      , KnownNat (UnumSize u)-      ) => U u -> U u -> SORN u-   sornSubU a b = sornAddU a (unumNegate b)--   -- | Subtract two SORNS-   sornSub ::-      ( KnownNat (SORNSize u)-      , Bits (SORNBackingWord u)-      , Bits (BackingWord u)-      , Num (BackingWord u)-      , KnownNat (UnumSize u)-      ) => SORN u -> SORN u -> SORN u-   sornSub a b =-      foldl sornUnion sornEmpty [ sornSubU x y-                                | x <- sornElems a-                                , y <- sornElems b-                                ]--   -- | Subtract a SORN with itself-   sornSubDep ::-      ( KnownNat (SORNSize u)-      , Bits (SORNBackingWord u)-      , Bits (BackingWord u)-      , Num (BackingWord u)-      , KnownNat (UnumSize u)-      ) => SORN u -> SORN u-   sornSubDep a =-      foldl sornUnion sornEmpty [ sornSubU x x-                                | x <- sornElems a-                                ]--------------------------------------------------------------------------------------- Contiguous SORN implementation--- ----------------------------------  --- We encode contiguous SORN with two values:---    * start: the starting unum---    * count: the number of unums from start upwards------ If count == 0---    If start == 0---       then empty SORN---       else full SORN------ Pros:---    * size is much smaller (2 * unum size),  especially for look-up tables because---    connected sets remain connected under addition, subtraction, multiplication---    and division.---    * trivial logic for negate and reciprocate (i.e., operate on bounds only)-----------------------------------------------------------------------------------type family CSORNSize u where-   CSORNSize u = 2 * UnumSize u--type family CSORNBackingWord u where-   CSORNBackingWord u = WordAtLeast (CSORNSize u)--newtype CSORN u-   = CSORN (BitFields (CSORNBackingWord u)-      '[ BitField (UnumSize u) "start" (BackingWord u)-       , BitField (UnumSize u) "count" (BackingWord u)-       ])--csornStart :: forall u.-   ( Integral (BackingWord u)-   , Integral (CSORNBackingWord u)-   , KnownNat (UnumSize u)-   , Bits (CSORNBackingWord u)-   , Field (BackingWord u)-   ) => CSORN u -> U u-csornStart c = U (csornStart' c)--csornStart' :: forall u.-   ( Integral (BackingWord u)-   , Integral (CSORNBackingWord u)-   , KnownNat (UnumSize u)-   , Bits (CSORNBackingWord u)-   , Field (BackingWord u)-   ) => CSORN u -> BackingWord u-csornStart' (CSORN c) = extractField' @"start" c--csornCount ::-   ( Integral (BackingWord u)-   , Integral (CSORNBackingWord u)-   , KnownNat (UnumSize u)-   , Bits (CSORNBackingWord u)-   , Field (BackingWord u)-   ) => CSORN u -> BackingWord u-csornCount (CSORN c) = extractField' @"count" c--instance forall u v.-   ( KnownNat (SORNSize u)-   , KnownNat (UnumSize u)-   , Bits (BackingWord u)-   , Bits (CSORNBackingWord u)-   , Integral (CSORNBackingWord u)-   , Num (BackingWord u)-   , Integral (BackingWord u)-   , HFoldr' GetLabel [String] v [String]-   , Field (BackingWord u)-   , Bits (SORNBackingWord u)-   , Bits (SORNBackingWord u)-   , v ~ UnumMembers u-   ) => Show (CSORN u) where-   show = show . csornToSorn ---- | Convert a contiguous SORN into a SORN-csornToSorn :: forall u.-   ( KnownNat (UnumSize u)-   , Num (BackingWord u)-   , Integral (BackingWord u)-   , Integral (CSORNBackingWord u)-   , Bits (CSORNBackingWord u)-   , Bits (BackingWord u)-   , Bits (SORNBackingWord u)-   , Field (BackingWord u)-   , KnownNat (SORNSize u)-   , Bits (SORNBackingWord u)-   ) => CSORN u -> SORN u-csornToSorn c =-   if csornCount c == 0-      then if start == 0-         then sornEmpty-         else sornFull-      else sornFromTo (csornStart c) (U x')-   where-      start = csornStart' c-      x'    = maskDyn s (start + csornCount c - 1)-      s     = unumSize @u---- | Size of a contiguous SORN in bits-csornSize :: forall u s.-   ( s ~ CSORNSize u-   , KnownNat s-   ) => Word-csornSize = natValue @s---- | Show contiguous SORN bits-csornBits :: forall u s.-   ( Bits (CSORNBackingWord u)-   , KnownNat (UnumSize u)-   , s ~ CSORNSize u-   , KnownNat s-   ) => CSORN u -> String-csornBits (CSORN (BitFields w)) = drop (bitSize w - natValue @s) (bitsToString w)----- | Empty contigiuous SORN-csornEmpty :: forall u.-   ( Bits (CSORNBackingWord u)-   ) => CSORN u-csornEmpty = CSORN (BitFields zeroBits)---- | Test if a contigiuous SORN is empty-csornIsEmpty :: forall u.-   ( Bits (CSORNBackingWord u)-   ) => CSORN u -> Bool-{-# INLINABLE csornIsEmpty #-}-csornIsEmpty (CSORN (BitFields b)) = b == zeroBits---- | Contiguous SORN build-csornFromTo :: forall u.-   ( Num (BackingWord u)-   , Bits (BackingWord u)-   , KnownNat (UnumSize u)-   , KnownNat (SORNSize u)-   , Bits (BackingWord u)-   , Integral (CSORNBackingWord u)-   , Bits (CSORNBackingWord u)-   , Field (BackingWord u)-   , Integral (BackingWord u)-   ) => U u -> U u -> CSORN u-csornFromTo start stop =-      if fromIntegral count == unumSize @u-         then csornFull-         else CSORN b-   where-      U x   = start-      U y   = stop-      s     = unumSize @u-      count = maskDyn s (y-x+1)-      b     = BitFields 0-              |> updateField' @"start" x-              |> updateField' @"count" count----- | Full contiguous SORN-csornFull :: forall u. -   ( Bits (CSORNBackingWord u)-   , Integral (CSORNBackingWord u)-   , Integral (BackingWord u)-   , KnownNat (UnumSize u)-   , Field (BackingWord u)-   ) => CSORN u-csornFull = CSORN (BitFields zeroBits-  |> updateField' @"start" 1 -- dummy /= 0-  |> updateField' @"count" 0)----- | Contiguous SORN singleton-csornSingle :: forall u.-   ( Bits (CSORNBackingWord u)-   , Integral (CSORNBackingWord u)-   , Integral (BackingWord u)-   , KnownNat (UnumSize u)-   , Field (BackingWord u)-   ) => U u -> CSORN u-csornSingle (U u) = CSORN (BitFields zeroBits-  |> updateField' @"start" u-  |> updateField' @"count" 1)-
− src/lib/Haskus/Format/Binary/VariableLength.hs
@@ -1,94 +0,0 @@-{-# LANGUAGE FlexibleContexts #-}---- | Variable length encodings-module Haskus.Format.Binary.VariableLength-   ( getULEB128-   , putULEB128-   , getSLEB128-   , putSLEB128-   , getLEB128Buffer-   )-where--import Haskus.Format.Binary.Word-import Haskus.Format.Binary.Get-import Haskus.Format.Binary.Put-import Haskus.Format.Binary.Bits-import Haskus.Format.Binary.Bits.Put-import Haskus.Format.Binary.Bits.Order-import Haskus.Format.Binary.Buffer---- Unsigned Little Endian Base 128 (ULEB128)--- The word is splitted in chunks of 7 bits, starting from least significant--- bits. Each chunk is put in a Word8. The highest bit indicates if there is a--- following byte (0 false, 1 true)---- | Get an unsigned word in Little Endian Base 128-getULEB128 :: (Integral a, Bits a) => Get a-getULEB128 = do-   a <- getWord8-   let w = fromIntegral (a .&. 0x7f)-   if not (testBit a 7)-      then return w-      else do-         b <- getULEB128-         return $ (b `shiftL` 7) .|. w---- | Put an unsigned word in Little Endian Base 128-putULEB128 :: (Integral a, Bits a) => a -> Put-putULEB128 = rec True-   where-      rec first x = case (first,x) of-         (True,0)  -> putWord8 0-         (False,0) -> return ()-         _         -> do-            let -               r = x `shiftR` 7-               w = x .&. 0x7f-               w' = if r == 0 then w else setBit w 7-            putWord8 (fromIntegral w')-            rec False r---- | Get a signed int in Little Endian Base 128-getSLEB128 :: (Integral a, Bits a) => Get a-getSLEB128 = do-   let toInt8 :: Word8 -> Int8-       toInt8 = fromIntegral-   a <- getWord8-   if not (testBit a 7)-      then return . fromIntegral . toInt8 $ (a .&. 0x7f) .|. ((a .&. 0x40) `shiftL` 1)-      else do-         b <- getSLEB128-         return $ (b `shiftL` 7) .|. (fromIntegral (a .&. 0x7f))---- | Put a signed int in Little Endian Base 128-putSLEB128 :: (Integral a, Bits a) => a -> Put-putSLEB128 a = rec a-   where-      ext = if a >= 0 then 0 else complement 0-      rec x =  do-         let -            r = x `shiftR` 7-            w = x .&. 0x7f-         if r /= ext-            then do-               putWord8 (fromIntegral w .|. 0x80)-               rec r-            else if (testBit w 6 && a < 0) || (not (testBit w 6) && a >= 0)-               then putWord8 (fromIntegral w)   -- no need for sign byte-               else do-                  putWord8 (fromIntegral w .|. 0x80)-                  putWord8 (fromIntegral ext .&. 0x7f)   -- sign byte----- | Get a bytestring containing a decoded LEB128 string-getLEB128Buffer :: BitOrder -> Get Buffer-getLEB128Buffer bo = rec (newBitPutState bo)-   where-      rec state = do-         w      <- getWord8-         let state2 = putBits 7 w state-         case testBit w 7 of-            True  -> rec state2-            False -> return (getBitPutBuffer state2)-
− src/lib/Haskus/Format/Binary/Vector.hs
@@ -1,352 +0,0 @@-{-# LANGUAGE DataKinds #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE KindSignatures #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE TypeOperators #-}-{-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE TypeApplications #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE UndecidableInstances #-}-{-# LANGUAGE AllowAmbiguousTypes #-}-{-# LANGUAGE MultiWayIf #-}-{-# LANGUAGE BangPatterns #-}-{-# LANGUAGE CPP #-}-#if MIN_VERSION_GLASGOW_HASKELL (8,6,0,0)-{-# LANGUAGE NoStarIsType #-}-#endif----- | Vector with size in the type-module Haskus.Format.Binary.Vector-   ( Vector (..)-   , vectorBuffer-   , vectorReverse-   , take-   , drop-   , index-   , fromList-   , fromFilledList-   , fromFilledListZ-   , toList-   , replicate-   , concat-   , zipWith-   )-where--import Prelude hiding ( replicate, head, last-                      , tail, init, map, length, drop, take, concat-                      , zipWith )-import System.IO.Unsafe (unsafePerformIO)--import qualified Haskus.Utils.List as List-import Haskus.Utils.Types-import Haskus.Utils.HList-import Haskus.Utils.Maybe-import Haskus.Utils.Flow-import Haskus.Format.Binary.Storable-import Haskus.Format.Binary.Ptr-import Haskus.Format.Binary.Buffer-import Haskus.Format.Binary.Bits---- | Vector with type-checked size-data Vector (n :: Nat) a = Vector Buffer--instance (Storable a, Show a, KnownNat n) => Show (Vector n a) where-   show v = "fromList " ++ show (toList v)---- | Return the buffer backing the vector-vectorBuffer :: Vector n a -> Buffer-vectorBuffer (Vector b) = b---- | Reverse a vector-vectorReverse :: (KnownNat n, Storable a) => Vector n a -> Vector n a-vectorReverse = fromJust . fromList . reverse . toList---- | Offset of the i-th element in a stored vector-type family ElemOffset a i n where-   ElemOffset a i n = Assert (i+1 <=? n)-      (i * (SizeOf a))-      (('Text "Invalid vector index: " ':<>: 'ShowType i-       ':$$: 'Text "Vector size: "     ':<>: 'ShowType n))--instance forall a n.-   ( KnownNat (SizeOf a * n)-   ) => StaticStorable (Vector n a) where--   type SizeOf (Vector n a)    = SizeOf a * n-   type Alignment (Vector n a) = Alignment a--   staticPeekIO ptr =-      Vector <$> bufferPackPtr (natValue @(SizeOf a * n)) (castPtr ptr)--   staticPokeIO ptr (Vector b) = bufferPoke ptr b--instance forall a n.-   ( KnownNat n-   , Storable a-   ) => Storable (Vector n a) where-   sizeOf _    = natValue @n * sizeOfT @a-   alignment _ = alignmentT @a-   peekIO ptr  = -      Vector <$> bufferPackPtr (sizeOfT' @(Vector n a)) (castPtr ptr)--   pokeIO ptr (Vector b) = bufferPoke ptr b---- | Yield the first n elements-take :: forall n m a.-   ( KnownNat (SizeOf a * n)-   ) => Vector (m+n) a -> Vector n a-{-# INLINABLE take #-}-take (Vector b) = Vector (bufferTake (natValue @(SizeOf a * n)) b)---- | Drop the first n elements-drop :: forall n m a.-   ( KnownNat (SizeOf a * n)-   ) => Vector (m+n) a -> Vector m a-{-# INLINABLE drop #-}-drop (Vector b) = Vector (bufferDrop (natValue @(SizeOf a * n)) b)---- | /O(1)/ Index safely into the vector using a type level index.-index :: forall i a n.-   ( KnownNat (ElemOffset a i n)-   , Storable a-   ) => Vector n a -> a-{-# INLINABLE index #-}-index (Vector b) = bufferPeekStorableAt b (natValue @(ElemOffset a i n))---- | Convert a list into a vector if the number of elements matches-fromList :: forall a (n :: Nat) .-   ( KnownNat n-   , Storable a-   ) => [a] -> Maybe (Vector n a)-{-# INLINABLE fromList #-}-fromList v-   | n' /= n   = Nothing-   | n' == 0   = Just $ Vector $ emptyBuffer-   | otherwise = Just $ Vector $ bufferPackStorableList v-   where-      n' = natValue' @n-      n  = fromIntegral (List.length v)---- | Take at most n element from the list, then use z-fromFilledList :: forall a (n :: Nat) .-   ( KnownNat n-   , Storable a-   ) => a -> [a] -> Vector n a-{-# INLINABLE fromFilledList #-}-fromFilledList z v = Vector $ bufferPackStorableList v'-   where-      v' = List.take (natValue @n) (v ++ repeat z)---- | Take at most (n-1) element from the list, then use z-fromFilledListZ :: forall a (n :: Nat) .-   ( KnownNat n-   , Storable a-   ) => a -> [a] -> Vector n a-{-# INLINABLE fromFilledListZ #-}-fromFilledListZ z v = fromFilledList z v'-   where-      v' = List.take (natValue @n - 1) v---- | Convert a vector into a list-toList :: forall a (n :: Nat) .-   ( KnownNat n-   , Storable a-   ) => Vector n a -> [a]-{-# INLINABLE toList #-}-toList (Vector b)-   | n == 0    = []-   | otherwise = fmap (bufferPeekStorableAt b . (sza*)) [0..n-1]-   where-      n   = natValue @n-      sza = sizeOfT' @a---- | Create a vector by replicating a value-replicate :: forall a (n :: Nat) .-   ( KnownNat n-   , Storable a-   ) => a -> Vector n a-{-# INLINABLE replicate #-}-replicate v = fromFilledList v []---data StoreVector = StoreVector -- Store a vector at the right offset--instance forall n v a r.-   ( v ~ Vector n a-   , r ~ IO (Ptr a)-   , KnownNat n-   , KnownNat (SizeOf a)-   , StaticStorable a-   , Storable a-   ) => Apply StoreVector (v, IO (Ptr a)) r where-      apply _ (v, getP) = do-         p <- getP-         let-            vsz = natValue @n-            p'  = p `indexPtr'` (-1 * vsz * sizeOfT @a)-         poke (castPtr p') v -         return p'--type family WholeSize fs :: Nat where-   WholeSize '[]                 = 0-   WholeSize (Vector n s ': xs)  = n + WholeSize xs---- | Concat several vectors into a single one-concat :: forall l (n :: Nat) a .-   ( n ~ WholeSize l-   , KnownNat n-   , Storable a-   , StaticStorable a-   , HFoldr StoreVector (IO (Ptr a)) l (IO (Ptr a))-   )-   => HList l -> Vector n a-concat vs = unsafePerformIO $ do-   let sz = sizeOfT @a * natValue @n-   p <- mallocBytes (fromIntegral sz) :: IO (Ptr ())-   _ <- hFoldr StoreVector (return (castPtr p `indexPtr'` sz) :: IO (Ptr a)) vs :: IO (Ptr a)-   Vector <$> bufferUnsafePackPtr (fromIntegral sz) p----- | Zip two vectors-zipWith ::-   ( KnownNat n-   , Storable a-   , Storable b-   , Storable c-   ) => (a -> b -> c) -> Vector n a -> Vector n b -> Vector n c-zipWith f u v = fromJust . fromList <| List.zipWith f (toList u) (toList v)---- | map-map ::-   ( KnownNat n-   , Storable a-   , Storable b-   ) => (a -> b) -> Vector n a -> Vector n b-map f = fromJust . fromList . fmap f . toList--instance-   ( KnownNat n-   , Storable a-   , Eq a-   )-   => Eq (Vector n a)-   where-      u == v = toList u == toList v---instance-   ( KnownNat n-   , Bitwise a-   , Storable a-   ) => Bitwise (Vector n a)-   where-      u .&. v        = zipWith (.&.) u v-      u .|. v        = zipWith (.|.) u v-      u `xor` v      = zipWith xor u v---instance-   ( KnownNat (BitSize a)-   , FiniteBits a-   , KnownNat n-   , Storable a-   ) => FiniteBits (Vector n a)-   where-      type BitSize (Vector n a) = n * BitSize a-      zeroBits = fromJust (fromList (List.replicate (natValue @n) zeroBits))-      oneBits  = fromJust (fromList (List.replicate (natValue @n) oneBits))-      complement u = map complement u-      countLeadingZeros = go 0 . toList-         where-            go !n []     = n-            go !n (x:xs) = let c = countLeadingZeros x-                           in if c == natValue @(BitSize a)-                                 then go (n+c) xs-                                 else n+c--      countTrailingZeros = go 0 . reverse . toList-         where-            go !n []     = n-            go !n (x:xs) = let c = countTrailingZeros x-                           in if c == natValue @(BitSize a)-                                 then go (n+c) xs-                                 else n+c--instance-   ( Storable a-   , ShiftableBits a-   , Bitwise a-   , FiniteBits a-   , KnownNat (BitSize a)-   , KnownNat (n * BitSize a)-   , KnownNat n-   ) => ShiftableBits (Vector n a)-   where-      shiftL u c = uncheckedShiftL u (c `mod` natValue @(BitSize (Vector n a)))-      shiftR u c = uncheckedShiftR u (c `mod` natValue @(BitSize (Vector n a)))--      uncheckedShiftL u c =-         let n  = natValue @n-             sa = natValue @(BitSize a)-             go _ 0 _       = []-             go 0 k xs      = List.take k xs-             go s k xs-                | s >= sa   = go (s-sa) k (List.tail xs)-                | otherwise =-                   let (x:y:zs) = xs-                   in ((x `shiftL` s) .|. (y `shiftR` (sa-s))) : go s (k-1) (y:zs)-         in fromJust (fromList (go c n (toList u ++ List.repeat zeroBits)))--      uncheckedShiftR u c  =-         let n  = natValue @n-             sa = natValue @(BitSize a)-             go _ 0 _       = []-             go 0 k xs      = List.take k (List.tail xs)-             go s k xs-                | s >= sa   = zeroBits : go (s-sa) (k-1) xs-                | otherwise =-                   let (x:y:zs) = xs-                   in ((x `shiftL` (sa-s)) .|. (y `shiftR` s)) : go s (k-1) (y:zs)-         in fromJust (fromList (go c n (zeroBits : toList u)))---instance-   ( Storable a-   , IndexableBits a-   , FiniteBits a-   , KnownNat (BitSize a)-   , KnownNat n-   , Bitwise a-   ) => IndexableBits (Vector n a) where--      popCount = sum . fmap popCount . toList--      bit i    = let n     = natValue @n-                     sa    = natValue @(BitSize a)-                     (f,r) = i `divMod` sa-                     toRep = fromIntegral (n - f - 1)-                     xs    = List.replicate toRep zeroBits-                              ++ [bit r]-                              ++ List.replicate (fromIntegral f) zeroBits-                 in fromJust <| fromList <| if i >= n * sa-                     then List.replicate (fromIntegral n) zeroBits-                     else xs--      testBit u i = let n      = natValue @n-                        sa     = natValue @(BitSize a)-                        (f,r)  = i `divMod` sa-                        toDrop = fromIntegral (n - f - 1)-                    in if i >= n * sa-                        then False-                        else testBit (List.head (List.drop toDrop (toList u))) r---instance-   ( Storable a-   , Bits a-   , KnownNat n-   , KnownNat (n * BitSize a)-   ) => RotatableBits (Vector n a)
− src/lib/Haskus/Format/Binary/Word.hs
@@ -1,88 +0,0 @@-{-# LANGUAGE DataKinds #-}-{-# LANGUAGE TypeOperators #-}-{-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE KindSignatures #-}-{-# LANGUAGE UndecidableInstances #-}-{-# LANGUAGE MagicHash #-}---- | Unsigned and signed words-module Haskus.Format.Binary.Word-   ( WordAtLeast-   , IntAtLeast-   , WordN-   , IntN-   -- * Some C types-   , CSize(..)-   , CUShort-   , CShort-   , CUInt-   , CInt-   , CULong-   , CLong-   -- * Unlifted-   , module GHC.Word-   , module GHC.Int-   , Word#-   , Int#-   , plusWord#-   , minusWord#-   , (+#)-   , (-#)-   , (==#)-   , (>#)-   , (<#)-   , (>=#)-   , (<=#)-   , ltWord#-   , leWord#-   , gtWord#-   , geWord#-   , eqWord#-   , isTrue#-   )-where--import Data.Word-import Data.Int-import Foreign.C.Types-import GHC.Word-import GHC.Int-import GHC.Exts--import Haskus.Utils.Types---- | Return a Word with at least 'n' bits-type family WordAtLeast (n :: Nat) where-   WordAtLeast n =-       If (n <=? 8) Word8-      (If (n <=? 16) Word16-      (If (n <=? 32) Word32-      (Assert (n <=? 64) Word64-      ('Text "Cannot find Word with size " ':<>: 'ShowType n)-      )))---- | Return a Int with at least 'n' bits-type family IntAtLeast (n :: Nat) where-   IntAtLeast n =-       If (n <=? 8) Int8-      (If (n <=? 16) Int16-      (If (n <=? 32) Int32-      (Assert (n <=? 64) Int64-      ('Text "Cannot find Int with size " ':<>: 'ShowType n)-      )))---- | Return a Word with exactly 'n' bits-type family WordN (n :: Nat) where-   WordN 8  = Word8-   WordN 16 = Word16-   WordN 32 = Word32-   WordN 64 = Word64-   WordN n  = TypeError ('Text "Cannot find Word with size " ':<>: 'ShowType n)---- | Return a Int with exactly 'n' bits-type family IntN (n :: Nat) where-   IntN 8  = Int8-   IntN 16 = Int16-   IntN 32 = Int32-   IntN 64 = Int64-   IntN n  = TypeError ('Text "Cannot find Int with size " ':<>: 'ShowType n)
− src/lib/Haskus/Format/Number.hs
@@ -1,8 +0,0 @@--- | Numbers-module Haskus.Format.Number-   ( module X-   )-where--import Haskus.Format.Number.BitNat as X-import Haskus.Format.Number.NaturalRange as X
− src/lib/Haskus/Format/Number/BitNat.hs
@@ -1,342 +0,0 @@-{-# LANGUAGE DataKinds #-}-{-# LANGUAGE KindSignatures #-}-{-# LANGUAGE TypeApplications #-}-{-# LANGUAGE TypeOperators #-}-{-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE UndecidableInstances #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE ViewPatterns #-}-{-# LANGUAGE StandaloneDeriving #-}-{-# LANGUAGE PolyKinds #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE ConstraintKinds #-}-{-# LANGUAGE PatternSynonyms #-}-{-# LANGUAGE AllowAmbiguousTypes #-}---- | Natural numbers-module Haskus.Format.Number.BitNat-   ( NatVal (..)-   , Widen-   , widen-   , Narrow-   , narrow-   , BitNat-   , pattern BitNat-   , nat-   , unsafeMakeW-   , safeMakeW-   , zeroW-   , oneW-   , extractW-   , compareW-   , (.+.)-   , (.-.)-   , (.*.)-   , (./.)-   , (.<<.)-   , (.>>.)-   -- * Internal-   , BitNatWord-   , MakeW-   , toNaturalW-   )-where--import Haskus.Format.Binary.Word-import Haskus.Format.Binary.Bits-import Haskus.Utils.Types-import Numeric.Natural---- $setup--- >>> :set -XDataKinds--- >>> :set -XTypeApplications--- >>> :set -XFlexibleContexts--- >>> :set -XTypeFamilies--- >>> :set -XScopedTypeVariables---- | A natural on `b` bits-newtype BitNat (b :: Nat)-   = BitNat' (BitNatWord b)--pattern BitNat :: forall (n :: Nat). (Integral (BitNatWord n), MakeW n) => Natural -> BitNat n-{-# COMPLETE BitNat #-}-pattern BitNat x <- (toNaturalW -> x)-   where-      BitNat x = makeW @n x----- | Create a natural number with the minimal number of bits required to store--- it------ >>> nat @5--- BitNat @3 5------ >>> nat @0--- BitNat @1 0------ >>> nat @158748521123465897456465--- BitNat @78 158748521123465897456465----nat :: forall (v :: Nat) (n :: Nat).-   ( n ~ NatBitCount v-   , Integral (BitNatWord n)-   , MakeW n-   , KnownNat v-   ) => BitNat n-nat = BitNat @n (natValue @v)--mapW :: (BitNatWord a -> BitNatWord a) -> BitNat a -> BitNat a-mapW f (BitNat' x) = BitNat' (f x)--zipWithW :: (BitNatWord a -> BitNatWord a -> BitNatWord b) -> BitNat a -> BitNat a -> BitNat b-zipWithW f (BitNat' x) (BitNat' y) = BitNat' (f x y)---- | Show instance for naturals-instance (KnownNat b, Integral (BitNatWord b)) => Show (BitNat b) where-   showsPrec d x = showParen (d /= 0)-      $ showString "BitNat @"-      . showsPrec 0 (natValue' @b)-      . showString " "-      . showsPrec 0 (toNaturalW x)---- | BitNat backing type-type family BitNatWord b where-   BitNatWord 0 = TypeError ('Text "Naturals encoded on 0 bits are not allowed")-   BitNatWord b = BitNatWord' (b <=? 8) (b <=? 16) (b <=? 32) (b <=? 64)--type family BitNatWord' b8 b16 b32 b64 where-   BitNatWord' 'True _ _ _ = Word8-   BitNatWord' _ 'True _ _ = Word16-   BitNatWord' _ _ 'True _ = Word32-   BitNatWord' _ _ _ 'True = Word64-   BitNatWord' _ _ _ _     = Natural------------------------------------------------------ Creation------------------------------------------------------ | Zero natural-zeroW :: Num (BitNatWord a) => BitNat a-zeroW = BitNat' 0---- | One natural-oneW :: Num (BitNatWord a) => BitNat a-oneW = BitNat' 1---- | Convert a BitNat into a Natural-toNaturalW :: Integral (BitNatWord a) => BitNat a -> Natural-toNaturalW (BitNat' x) = fromIntegral x---- | Create a natural-unsafeMakeW :: forall a. (Maskable a (BitNatWord a)) => BitNatWord a -> BitNat a-unsafeMakeW x = BitNat' (mask @a x)--type MakeW a =-   ( Maskable a (BitNatWord a)-   , ShiftableBits (BitNatWord a)-   , Show (BitNatWord a)-   , Eq (BitNatWord a)-   , Num (BitNatWord a)-   )---- | Create a natural (check overflow)-safeMakeW :: forall a. MakeW a => Natural -> Maybe (BitNat a)-safeMakeW x = -   let-      x' = fromIntegral x :: BitNatWord a-   in case x' `uncheckedShiftR` natValue' @a of-      0 -> Just (unsafeMakeW x')-      _ -> Nothing---- | Create a natural (check overflow and throw on error)-makeW :: forall a. MakeW a => Natural -> BitNat a-makeW x = case safeMakeW x of-   Just y  -> y-   Nothing -> error $-               "`" ++ show x-               ++ "` is out of the range of values that can be encoded by a "-               ++ show (natValue' @a)-               ++ "-bit natural number: [0.."-               ++ show (2 ^ (natValue' @a) -1 :: Natural)-               ++ "]"---- | Extract the primitive value-extractW :: BitNat a -> BitNatWord a-extractW (BitNat' a) = a------------------------------------------------------ Widening / Narrowing------------------------------------------------------ | Widen a natural------ >>>  widen @7 (BitNat @5 25)--- BitNat @7 25----widen :: forall b a. Widen a b => BitNat a -> BitNat b-widen (BitNat' a) = BitNat' (fromIntegral a)--type Widen a b =-   ( Assert (a <=? b) (() :: Constraint)-      ('Text "Can't widen a natural of "-       ':<>: 'ShowType a-       ':<>: 'Text " bits into a natural of "-       ':<>: 'ShowType b-       ':<>: 'Text " bits"-      )-   , Integral (BitNatWord a)-   , Integral (BitNatWord b)-   )---- | Narrow a natural------ >>> narrow @3 (BitNat @5 25)--- BitNat @3 1----narrow :: forall b a. Narrow a b => BitNat a -> BitNat b-narrow (BitNat' a) = unsafeMakeW (fromIntegral a)--type Narrow a b =-   ( Assert (b <=? a) (() :: Constraint)-      ('Text "Can't narrow a natural of "-       ':<>: 'ShowType a-       ':<>: 'Text " bits into a natural of "-       ':<>: 'ShowType b-       ':<>: 'Text " bits"-      )-   , Integral (BitNatWord a)-   , Integral (BitNatWord b)-   , Maskable b (BitNatWord b)-   )-   ----------------------------------------------------- Comparison------------------------------------------------------ | Compare two naturals-compareW :: forall a b.-   ( Ord (BitNatWord (Max a b))-   , Widen a (Max a b)-   , Widen b (Max a b)-   ) => BitNat a -> BitNat b -> Ordering-compareW x y = compare x' y'-   where-      BitNat' x' = widen @(Max a b) x-      BitNat' y' = widen @(Max a b) y--instance Eq (BitNatWord a) => Eq (BitNat a) where-   (BitNat' x) == (BitNat' y) = x == y--instance Ord (BitNatWord a) => Ord (BitNat a) where-   compare (BitNat' x) (BitNat' y) = compare x y------------------------------------------------------ Addition / Subtraction------------------------------------------------------ | Add two Naturals------ >>> BitNat @5 25 .+. BitNat @2 3--- BitNat @6 28----(.+.) :: forall a b m.-   ( m ~ (Max a b + 1)-   , Widen a m-   , Widen b m-   , Num (BitNatWord m)-   ) => BitNat a -> BitNat b -> BitNat m-(.+.) x y = zipWithW (+) (widen @m x) (widen @m y)---- | Sub two Naturals------ >>> BitNat @5 25 .-. BitNat @2 3--- Just (BitNat @5 22)------ >>> BitNat @5 2 .-. BitNat @2 3--- Nothing----(.-.) :: forall a b m.-   ( m ~ Max a b-   , Widen a m-   , Widen b m-   , Num (BitNatWord m)-   ) => BitNat a -> BitNat b -> Maybe (BitNat m)-(.-.) (widen @m -> x) (widen @m -> y) = case compare x y of-   LT -> Nothing-   EQ -> Just zeroW-   GT -> Just (zipWithW (-) x y)---- | Multiply two Naturals------ >>> BitNat @5 25 .*. BitNat @2 3--- BitNat @7 75----(.*.) :: forall a b m.-   ( m ~ (a + b)-   , Widen a m-   , Widen b m-   , Num (BitNatWord m)-   ) => BitNat a -> BitNat b -> BitNat m-(.*.) x y = zipWithW (*) (widen @m x) (widen @m y)---- | Divide two Naturals, return (factor,rest)------ >>> BitNat @5 25 ./. BitNat @2 3--- Just (BitNat @5 8,BitNat @2 1)------ >>> BitNat @5 25 ./. BitNat @2 0--- Nothing------ > BitNat @2 3 ./. BitNat @5 25--- Just (BitNat @2 0,BitNat @5 3)----(./.) :: forall a b m.-   ( m ~ Max a b-   , Widen a m-   , Widen b m-   , Num (BitNatWord (Min a b))-   ) => BitNat a -> BitNat b -> Maybe (BitNat a,BitNat (Min a b))-(./.) x y-   | y == zeroW = Nothing-   | otherwise  = Just (BitNat' (fromIntegral q), BitNat' (fromIntegral r))-   where-      (q,r) = quotRem x' y'-      BitNat' x' = widen @m x-      BitNat' y' = widen @m y------------------------------------------------------ Shift------------------------------------------------------ | Shift-left naturals------ >>> let x = BitNat @5 25--- >>> x .<<. NatVal @2--- BitNat @7 100------ >>> show (x .<<. NatVal @2) == show (x .*. BitNat @3 4)--- False------ >>> x .<<. NatVal @2 == narrow (x .*. BitNat @3 4)--- True----(.<<.) :: forall (s :: Nat) a.-   ( ShiftableBits (BitNatWord (a + s))-   , KnownNat s-   , Widen a (a+s)-   ) => BitNat a -> NatVal s -> BitNat (a + s)-(.<<.) x _ = mapW (`uncheckedShiftL` natValue @s) (widen @(a+s) x)---- | Shift-right naturals------ >>> BitNat @5 25 .>>. NatVal @2--- BitNat @3 6----(.>>.) :: forall (s :: Nat) a.-   ( ShiftableBits (BitNatWord a)-   , KnownNat s-   , Narrow a (a-s)-   ) => BitNat a -> NatVal s -> BitNat (a - s)-(.>>.) x _ = narrow @(a-s) (mapW (`uncheckedShiftR` natValue @s) x)
− src/lib/Haskus/Format/Number/NaturalRange.hs
@@ -1,195 +0,0 @@-{-# LANGUAGE DataKinds #-}-{-# LANGUAGE KindSignatures #-}-{-# LANGUAGE TypeApplications #-}-{-# LANGUAGE TypeOperators #-}-{-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE UndecidableInstances #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE ViewPatterns #-}-{-# LANGUAGE StandaloneDeriving #-}-{-# LANGUAGE PolyKinds #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE ConstraintKinds #-}-{-# LANGUAGE PatternSynonyms #-}-{-# LANGUAGE AllowAmbiguousTypes #-}---- | A natural number in a specified range (fixed and checked at compile-time)-module Haskus.Format.Number.NaturalRange-   ( NatRange-   , pattern NatRange-   , natRange-   , safeMakeNatRange-   , makeNatRange-   , unsafeMakeNatRange-   , widenNatRange-   , (.++.)-   )-where--import Haskus.Format.Number.BitNat-import Haskus.Utils.Types-import Numeric.Natural---- $setup--- >>> :set -XDataKinds--- >>> :set -XTypeApplications--- >>> :set -XFlexibleContexts--- >>> :set -XTypeFamilies--- >>> :set -XScopedTypeVariables----- | A natural number in the specified range-newtype NatRange (f :: Nat) (t :: Nat) = NatRange' (BitNat (NatBitCount (t-f+1)))---- | Show instance for natural range-instance-   ( KnownNat (t-f)-   , KnownNat t-   , KnownNat f-   , Num (BitNatWord (NatBitCount (t-f+1)))-   , Integral (BitNatWord (NatBitCount (t-f+1)))-   ) => Show (NatRange f t) where-   showsPrec d x = showParen (d /= 0)-      $ showString "NatRange @"-      . showsPrec 0 (natValue' @f)-      . showString " @"-      . showsPrec 0 (natValue' @t)-      . showString " "-      . showsPrec 0 (toNaturalNatRange x)--type CheckInRange f t n =-   ( Assert (n <=? t) (() :: Constraint)-      ('ShowType n-       ':<>: 'Text " isn't in the range ["-       ':<>: 'ShowType f-       ':<>: 'Text ","-       ':<>: 'ShowType t-       ':<>: 'Text "]"-      )-   , Assert (f <=? n) (() :: Constraint)-      ('ShowType n-       ':<>: 'Text " isn't in the range ["-       ':<>: 'ShowType f-       ':<>: 'Text ","-       ':<>: 'ShowType t-       ':<>: 'Text "]"-      )-   )--type NatRangeBitCount f t = NatBitCount (t-f+1)--type MakeNatRange f t =-   ( Integral (BitNatWord (NatRangeBitCount f t))-   , MakeW (NatRangeBitCount f t)-   , KnownNat f-   , KnownNat t-   , Assert (f <=? t) (() :: Constraint)-      ('Text "["-       ':<>: 'ShowType f-       ':<>: 'Text ","-       ':<>: 'ShowType t-       ':<>: 'Text "] isn't a valid range"-      )-   )---- | Create a value in a Natural range-unsafeMakeNatRange :: forall f t.-   ( MakeNatRange f t-   ) => Natural -> NatRange f t-unsafeMakeNatRange v = NatRange' (BitNat @(NatRangeBitCount f t) (v - natValue @f))---- | Create a value in a Natural range (check validity)-safeMakeNatRange :: forall f t.-   ( MakeNatRange f t-   ) => Natural -> Maybe (NatRange f t)-safeMakeNatRange v-   | v < natValue @f || v > natValue @t = Nothing-   | otherwise                          = Just (unsafeMakeNatRange @f @t v)---- | Create a value in a Natural range (check validity and throw on error)-makeNatRange :: forall f t.-   ( MakeNatRange f t-   ) => Natural -> NatRange f t-makeNatRange v = case safeMakeNatRange @f @t v of-   Nothing ->error $ show v ++ " isn't in the range ["-               ++ show (natValue @f :: Natural)-               ++ ","-               ++ show (natValue @t :: Natural)-               ++ "]"-   Just x -> x----- | Create a value in a Natural range-natRange :: forall (n :: Nat) f t.-   ( MakeNatRange f t-   , CheckInRange f t n-   , KnownNat n-   ) => NatRange f t-natRange = unsafeMakeNatRange (natValue @n)---- | Convert a NatRange into a Natural-toNaturalNatRange :: forall f t.-   ( KnownNat f-   , Integral (BitNatWord (NatBitCount (t-f+1)))-   ) => NatRange f t -> Natural-toNaturalNatRange (NatRange' x) = natValue @f + toNaturalW x---- | Natural range pattern------ >>> NatRange @10 @12 11--- NatRange @10 @12 11----pattern NatRange :: forall (f :: Nat) (t :: Nat).-   ( MakeNatRange f t-   ) => Natural -> NatRange f t-{-# COMPLETE NatRange #-}-pattern NatRange x <- (toNaturalNatRange -> x)-   where-      NatRange x = makeNatRange @f @t x------------------------------------------------------- Widening------------------------------------------------------ | Widen a natural------ >>> let a = NatRange @18 @100 25--- >>> widenNatRange @16 @200 a--- NatRange @16 @200 25----widenNatRange :: forall f2 t2 f1 t1.-   ( WidenNatRange f1 t1 f2 t2-   ) => NatRange f1 t1 -> NatRange f2 t2-widenNatRange (NatRange a) = NatRange a--type WidenNatRange f1 t1 f2 t2 =-   ( Assert ((f2 <=? f1) `AndB` (t1 <=? t2)) (() :: Constraint)-      ('Text "Can't widen a natural range ["-       ':<>: 'ShowType f1-       ':<>: 'Text ","-       ':<>: 'ShowType t1-       ':<>: 'Text "] into range ["-       ':<>: 'ShowType f2-       ':<>: 'Text ","-       ':<>: 'ShowType t2-       ':<>: 'Text "]"-      )-   , MakeNatRange f1 t1-   , MakeNatRange f2 t2-   )---- | Add two natural ranges------ >>> NatRange @2 @4 3 .++. NatRange @7 @17 13--- NatRange @9 @21 16----(.++.) ::-   ( MakeNatRange f1 t1-   , MakeNatRange f2 t2-   , MakeNatRange (f1+f2) (t1+t2)-   ) => NatRange f1 t1 -> NatRange f2 t2 -> NatRange (f1+f2) (t1+t2)-(.++.) (NatRange x) (NatRange y) = NatRange (x+y)-
src/lib/Haskus/Memory/Allocator/Malloc.hs view
@@ -13,9 +13,7 @@ where  import GHC.Exts-import Haskus.Format.Binary.Ptr-   ( Ptr (..), nullPtr-   )+import Foreign.Ptr (nullPtr) import Haskus.Utils.Monad import Haskus.Memory.Buffer    ( Buffer(..), BufferME, BufferMEF
src/lib/Haskus/Memory/Buffer.hs view
@@ -13,11 +13,12 @@ {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE FunctionalDependencies #-} {-# LANGUAGE RankNTypes #-}+{-# LANGUAGE BlockArguments #-}+{-# LANGUAGE FlexibleContexts #-}  -- | A buffer in memory module Haskus.Memory.Buffer    ( Buffer (..)-   , TypedBuffer (..)    , AnyBuffer (..)    -- * Buffer taxonomy    , Pinning (..)@@ -73,28 +74,25 @@    , addFinalizer    , makeFinalizable    , touchBuffer+   , touch    -- * Conversions    , bufferToListIO    , BufferToList (..)-   -- * Reexport-   , module Control.Monad.Primitive    ) where -import Haskus.Format.Binary.Word-import Haskus.Format.Binary.Storable-import Haskus.Format.Binary.Ptr+import Haskus.Number.Word+import Haskus.Number.Int+import Haskus.Binary.Storable+import Haskus.Memory.Property+import Haskus.Memory.Utils (memcpy#) import Haskus.Utils.Monad -import qualified Data.Primitive.ByteArray as BA-import qualified Data.Primitive.Types     as BA-import Control.Monad.Primitive import Data.IORef-import Unsafe.Coerce+import System.IO.Unsafe  import GHC.Prim-import GHC.Weak-import GHC.Exts (toList, IsList(..))+import GHC.Exts (toList, IsList(..), Ptr (..)) import GHC.Types (IO(..))  -- $setup@@ -103,49 +101,22 @@ -- >>> :set -XFlexibleContexts -- >>> :set -XTypeFamilies -- >>> :set -XScopedTypeVariables--- >>> import Haskus.Format.Binary.Bits---- | Is the buffer pinned into memory?-data Pinning-   = Pinned    -- ^ The buffer has a fixed associated memory address-   | NotPinned -- ^ The buffer contents can be freely moved to another address-   deriving (Show,Eq)---- | Is the buffer automatically garbage collected?-data Finalization-   = Collected    -- ^ Automatically collected by the garbage-collector-   | Finalized    -- ^ Finalizers are run just before the garbage collector-                  -- collects the buffer entity. The memory used by the buffer-                  -- may be collected too (Internal heap), explicitly freed by a-                  -- finalizer or not freed at all.-   | NotFinalized -- ^ The buffer contents is not automatically freed and we-                  -- can't attach finalizers to the buffer.-   deriving (Show,Eq)---- | Allocation heap-data Heap-   = Internal -- ^ GHC heap-   | External -- ^ External heap---- | Is the buffer mutable or not?-data Mutability-   = Mutable   -- ^ Memory cells are mutable-   | Immutable -- ^ Memory cells are immutable-   deriving (Show,Eq)+-- >>> import Haskus.Binary.Bits +-- | A memory buffer data Buffer (mut :: Mutability) (pin :: Pinning) (fin :: Finalization) (heap :: Heap) where-   Buffer    :: {-# UNPACK #-} !BA.ByteArray                                                  -> BufferI-   BufferP   :: {-# UNPACK #-} !BA.ByteArray                                                  -> BufferP-   BufferM   :: {-# UNPACK #-} !(BA.MutableByteArray RealWorld)                               -> BufferM-   BufferMP  :: {-# UNPACK #-} !(BA.MutableByteArray RealWorld)                               -> BufferMP-   BufferME  :: Addr# -> {-# UNPACK #-} !Word                                                 -> BufferME-   BufferE   :: Addr# -> {-# UNPACK #-} !Word                                                 -> BufferE-   BufferF   :: {-# UNPACK #-} !BA.ByteArray                    -> {-# UNPACK #-} !Finalizers -> BufferF-   BufferPF  :: {-# UNPACK #-} !BA.ByteArray                    -> {-# UNPACK #-} !Finalizers -> BufferPF-   BufferMF  :: {-# UNPACK #-} !(BA.MutableByteArray RealWorld) -> {-# UNPACK #-} !Finalizers -> BufferMF-   BufferMPF :: {-# UNPACK #-} !(BA.MutableByteArray RealWorld) -> {-# UNPACK #-} !Finalizers -> BufferMPF-   BufferMEF :: Addr# -> {-# UNPACK #-} !Word                   -> {-# UNPACK #-} !Finalizers -> BufferMEF-   BufferEF  :: Addr# -> {-# UNPACK #-} !Word                   -> {-# UNPACK #-} !Finalizers -> BufferEF+   Buffer    :: !ByteArray#                                                  -> BufferI+   BufferP   :: !ByteArray#                                                  -> BufferP+   BufferM   :: !(MutableByteArray# RealWorld)                               -> BufferM+   BufferMP  :: !(MutableByteArray# RealWorld)                               -> BufferMP+   BufferME  :: Addr# -> {-# UNPACK #-} !Word                                -> BufferME+   BufferE   :: Addr# -> {-# UNPACK #-} !Word                                -> BufferE+   BufferF   :: !ByteArray#                    -> {-# UNPACK #-} !Finalizers -> BufferF+   BufferPF  :: !ByteArray#                    -> {-# UNPACK #-} !Finalizers -> BufferPF+   BufferMF  :: !(MutableByteArray# RealWorld) -> {-# UNPACK #-} !Finalizers -> BufferMF+   BufferMPF :: !(MutableByteArray# RealWorld) -> {-# UNPACK #-} !Finalizers -> BufferMPF+   BufferMEF :: Addr# -> {-# UNPACK #-} !Word  -> {-# UNPACK #-} !Finalizers -> BufferMEF+   BufferEF  :: Addr# -> {-# UNPACK #-} !Word  -> {-# UNPACK #-} !Finalizers -> BufferEF  type BufferI   = Buffer 'Immutable 'NotPinned 'Collected    'Internal type BufferP   = Buffer 'Immutable 'Pinned    'Collected    'Internal@@ -160,9 +131,6 @@ type BufferMEF = Buffer 'Mutable   'Pinned    'Finalized    'External type BufferEF  = Buffer 'Immutable 'Pinned    'Finalized    'External --- | A buffer with an additional phantom type indicating its binary format-newtype TypedBuffer (t :: k) mut pin fin heap = TypedBuffer (Buffer mut pin fin heap)- ----------------------------------------------------------------- -- Allocation -----------------------------------------------------------------@@ -173,18 +141,29 @@ -- newBuffer :: MonadIO m => Word -> m BufferM {-# INLINABLE newBuffer #-}-newBuffer sz = BufferM <$> liftIO (BA.newByteArray (fromIntegral sz))+newBuffer sz = liftIO $ IO \s ->+   case fromIntegral sz of+      I# sz# -> case newByteArray# sz# s of+         (# s', arr# #) -> (# s', BufferM arr# #)  -- | Allocate a buffer (mutable, pinned) newPinnedBuffer :: MonadIO m => Word -> m BufferMP {-# INLINABLE newPinnedBuffer #-}-newPinnedBuffer sz = BufferMP <$> liftIO (BA.newPinnedByteArray (fromIntegral sz))+newPinnedBuffer sz = liftIO $ IO \s ->+   case fromIntegral sz of+      I# sz# -> case newPinnedByteArray# sz# s of+         (# s', arr# #) -> (# s', BufferMP arr# #)  -- | Allocate an aligned buffer (mutable, pinned) newAlignedPinnedBuffer :: MonadIO m => Word -> Word -> m BufferMP {-# INLINABLE newAlignedPinnedBuffer #-}-newAlignedPinnedBuffer sz al = BufferMP <$> liftIO (BA.newAlignedPinnedByteArray (fromIntegral sz) (fromIntegral al))+newAlignedPinnedBuffer sz al = liftIO $ IO \s ->+   case fromIntegral sz of+      I# sz# -> case fromIntegral al of+         I# al# -> case newAlignedPinnedByteArray# sz# al# s of+            (# s', arr# #) -> (# s', BufferMP arr# #) + ----------------------------------------------------------------- -- Finalizers -----------------------------------------------------------------@@ -198,42 +177,28 @@     [] -> ([f] , True)     fs -> (f:fs, False) +-- | Get buffer finalizers+getFinalizers :: Buffer mut pin 'Finalized heap -> Finalizers+getFinalizers b = case b of+   BufferMEF _addr _sz fin -> fin+   BufferEF  _addr _sz fin -> fin+   BufferF   _ba fin       -> fin+   BufferPF  _ba fin       -> fin+   BufferMF  _ba fin       -> fin+   BufferMPF _ba fin       -> fin++ -- | Add a finalizer. -- -- The latest added finalizers are executed first. Finalizers are not guaranteed -- to run (e.g. if the program exits before the buffer is collected). -- addFinalizer :: MonadIO m => Buffer mut pin 'Finalized heap -> IO () -> m ()-addFinalizer b f = case b of-   BufferMEF _addr _sz fin@(Finalizers rfs) -> do-      wasEmpty <- insertFinalizer fin f-      -- add the weak reference to the finalizer IORef (not to Addr#)-      when wasEmpty $ void $ liftIO $ mkWeakIORef rfs (runFinalizers fin)--   BufferEF _addr _sz fin@(Finalizers rfs) -> do-      wasEmpty <- insertFinalizer fin f-      -- add the weak reference to the finalizer IORef (not to Addr#)-      when wasEmpty $ void $ liftIO $ mkWeakIORef rfs (runFinalizers fin)--   BufferF ba fin -> do-      wasEmpty <- insertFinalizer fin f-      -- add the weak reference to the ByteArray-      when wasEmpty $ void $ liftIO $ mkWeak ba () (Just (runFinalizers fin))--   BufferPF ba fin -> do-      wasEmpty <- insertFinalizer fin f-      -- add the weak reference to the ByteArray-      when wasEmpty $ void $ liftIO $ mkWeak ba () (Just (runFinalizers fin))--   BufferMF ba fin -> do-      wasEmpty <- insertFinalizer fin f-      -- add the weak reference to the MutableByteArray-      when wasEmpty $ void $ liftIO $ mkWeak ba () (Just (runFinalizers fin))--   BufferMPF ba fin -> do-      wasEmpty <- insertFinalizer fin f-      -- add the weak reference to the MutableByteArray-      when wasEmpty $ void $ liftIO $ mkWeak ba () (Just (runFinalizers fin))+addFinalizer b f = do+   let fin@(Finalizers rfs) = getFinalizers b+   wasEmpty <- insertFinalizer fin f+   -- add the weak reference to the finalizer IORef (not to Addr#/byteArray#/...)+   when wasEmpty $ void $ liftIO $ mkWeakIORef rfs (runFinalizers fin)  -- | Internal function used to execute finalizers runFinalizers :: Finalizers -> IO ()@@ -261,19 +226,25 @@ {-# SPECIALIZE INLINE touchBuffer :: MonadIO m => BufferMPF-> m () #-} {-# SPECIALIZE INLINE touchBuffer :: MonadIO m => BufferMEF-> m () #-} {-# SPECIALIZE INLINE touchBuffer :: MonadIO m => BufferEF -> m () #-}-touchBuffer (Buffer    ba                        ) = liftIO $ touch ba-touchBuffer (BufferP   ba                        ) = liftIO $ touch ba-touchBuffer (BufferM   ba                        ) = liftIO $ touch ba-touchBuffer (BufferMP  ba                        ) = liftIO $ touch ba-touchBuffer (BufferF   ba         _fin           ) = liftIO $ touch ba-touchBuffer (BufferPF  ba         _fin           ) = liftIO $ touch ba-touchBuffer (BufferMF  ba         _fin           ) = liftIO $ touch ba-touchBuffer (BufferMPF ba         _fin           ) = liftIO $ touch ba+touchBuffer (Buffer    _ba                       ) = return ()+touchBuffer (BufferP   _ba                       ) = return ()+touchBuffer (BufferM   _ba                       ) = return ()+touchBuffer (BufferMP  _ba                       ) = return ()+touchBuffer (BufferF   _ba       (Finalizers fin)) = liftIO $ touch fin+touchBuffer (BufferPF  _ba       (Finalizers fin)) = liftIO $ touch fin+touchBuffer (BufferMF  _ba       (Finalizers fin)) = liftIO $ touch fin+touchBuffer (BufferMPF _ba       (Finalizers fin)) = liftIO $ touch fin touchBuffer (BufferME  _addr _sz                 ) = return () touchBuffer (BufferE   _addr _sz                 ) = return () touchBuffer (BufferMEF _addr _sz (Finalizers fin)) = liftIO $ touch fin touchBuffer (BufferEF  _addr _sz (Finalizers fin)) = liftIO $ touch fin +-- | Touch a data+touch :: MonadIO m => a -> m ()+{-# NOINLINE touch #-}+touch x = liftIO $ IO \s -> case touch# x s of+   s' -> (# s', () #)+ -- | Make a buffer finalizable -- -- The new buffer liveness is used to trigger finalizers.@@ -314,9 +285,10 @@    where       {-# INLINABLE unsafeBufferFreeze #-}       unsafeBufferFreeze = \case-         BufferM mba  -> Buffer  <$> liftIO (BA.unsafeFreezeByteArray mba)-         BufferMP mba -> BufferP <$> liftIO (BA.unsafeFreezeByteArray mba)+         BufferM mba  -> liftIO $ IO (\s -> case unsafeFreezeByteArray# mba s of (# s', ba #) -> (# s', Buffer ba #))+         BufferMP mba -> liftIO $ IO (\s -> case unsafeFreezeByteArray# mba s of (# s', ba #) -> (# s', BufferP ba #)) + instance Freezable (Buffer 'Mutable   pin fin 'External)                    (Buffer 'Immutable pin fin 'External)    where@@ -338,8 +310,8 @@    where       {-# INLINABLE unsafeBufferThaw #-}       unsafeBufferThaw = \case-         Buffer mba  -> BufferM  <$> liftIO (BA.unsafeThawByteArray mba)-         BufferP mba -> BufferMP <$> liftIO (BA.unsafeThawByteArray mba)+         Buffer mba  -> pure $ BufferM  (unsafeCoerce# mba)+         BufferP mba -> pure $ BufferMP (unsafeCoerce# mba)  instance Thawable (Buffer 'Immutable pin 'NotFinalized heap)                   (Buffer 'Mutable   pin 'NotFinalized heap)@@ -362,10 +334,10 @@    BufferMEF{}       -> True    BufferEF {}       -> True    BufferMPF{}       -> True-   Buffer   ba       -> BA.isByteArrayPinned ba-   BufferM  mba      -> BA.isMutableByteArrayPinned mba-   BufferF  ba  _fin -> BA.isByteArrayPinned ba-   BufferMF mba _fin -> BA.isMutableByteArrayPinned mba+   Buffer   ba       -> isTrue# (isByteArrayPinned# ba)+   BufferM  mba      -> isTrue# (isMutableByteArrayPinned# mba)+   BufferF  ba  _fin -> isTrue# (isByteArrayPinned# ba)+   BufferMF mba _fin -> isTrue# (isMutableByteArrayPinned# mba)  -- | Transform type-level NotPinned buffers into type-level Pinned if the buffer -- is dynamically pinned (see `bufferIsDynamicallyPinned`).@@ -381,16 +353,16 @@    BufferMEF{}      -> Right b    BufferEF {}      -> Right b    BufferMPF{}      -> Right b-   Buffer   ba      -> if BA.isByteArrayPinned ba+   Buffer   ba      -> if isTrue# (isByteArrayPinned# ba)                         then Right (BufferP ba)                         else Left b-   BufferM  mba     -> if BA.isMutableByteArrayPinned mba+   BufferM  mba     -> if isTrue# (isMutableByteArrayPinned# mba)                         then Right (BufferMP mba)                         else Left b-   BufferF  ba  fin -> if BA.isByteArrayPinned ba+   BufferF  ba  fin -> if isTrue# (isByteArrayPinned# ba)                         then Right (BufferPF ba fin)                         else Left b-   BufferMF mba fin -> if BA.isMutableByteArrayPinned mba+   BufferMF mba fin -> if isTrue# (isMutableByteArrayPinned# mba)                         then Right (BufferMPF mba fin)                         else Left b @@ -411,23 +383,19 @@ {-# SPECIALIZE INLINE unsafeWithBufferAddr# :: MonadIO m => BufferMEF-> (Addr# -> m a) -> m a #-} {-# SPECIALIZE INLINE unsafeWithBufferAddr# :: MonadIO m => BufferEF -> (Addr# -> m a) -> m a #-} unsafeWithBufferAddr# b@(BufferP ba) f = do-   let !(BA.Addr addr) = BA.byteArrayContents ba-   r <- f addr+   r <- f (byteArrayContents# ba)    touchBuffer b    return r unsafeWithBufferAddr# b@(BufferMP ba) f = do-   let !(BA.Addr addr) = BA.mutableByteArrayContents ba-   r <- f addr+   r <- f (byteArrayContents# (unsafeCoerce# ba))    touchBuffer b    return r unsafeWithBufferAddr# b@(BufferPF ba _fin) f = do-   let !(BA.Addr addr) = BA.byteArrayContents ba-   r <- f addr+   r <- f (byteArrayContents# ba)    touchBuffer b    return r unsafeWithBufferAddr# b@(BufferMPF ba _fin) f = do-   let !(BA.Addr addr) = BA.mutableByteArrayContents ba-   r <- f addr+   r <- f (byteArrayContents# (unsafeCoerce# ba))    touchBuffer b    return r unsafeWithBufferAddr# (BufferME addr _sz)         f = f (addr)@@ -493,35 +461,43 @@ {-# SPECIALIZE INLINE bufferSizeIO :: MonadIO m => BufferMEF-> m Word #-} {-# SPECIALIZE INLINE bufferSizeIO :: MonadIO m => BufferEF -> m Word #-} bufferSizeIO = \case-   BufferM ba              -> fromIntegral <$> liftIO (BA.getSizeofMutableByteArray ba)-   BufferMP ba             -> fromIntegral <$> liftIO (BA.getSizeofMutableByteArray ba)-   BufferMF  ba _fin       -> fromIntegral <$> liftIO (BA.getSizeofMutableByteArray ba)-   BufferMPF ba _fin       -> fromIntegral <$> liftIO (BA.getSizeofMutableByteArray ba)+   BufferM ba              -> bufferSizeMBA ba+   BufferMP ba             -> bufferSizeMBA ba+   BufferMF  ba _fin       -> bufferSizeMBA ba+   BufferMPF ba _fin       -> bufferSizeMBA ba    BufferME  _addr sz      -> return sz    BufferMEF _addr sz _fin -> return sz    BufferE   _addr sz      -> return sz    BufferEF  _addr sz _fin -> return sz-   Buffer  ba              -> return $ fromIntegral $ BA.sizeofByteArray ba-   BufferP ba              -> return $ fromIntegral $ BA.sizeofByteArray ba-   BufferF   ba _fin       -> return $ fromIntegral $ BA.sizeofByteArray ba-   BufferPF  ba _fin       -> return $ fromIntegral $ BA.sizeofByteArray ba+   Buffer  ba              -> pure $ bufferSizeBA ba+   BufferP ba              -> pure $ bufferSizeBA ba+   BufferF   ba _fin       -> pure $ bufferSizeBA ba+   BufferPF  ba _fin       -> pure $ bufferSizeBA ba +bufferSizeMBA :: MonadIO m => MutableByteArray# RealWorld -> m Word+bufferSizeMBA mba = liftIO $ IO \s -> case getSizeofMutableByteArray# mba s of+   (# s', i #) -> case int2Word# i of+      n -> (# s', W# n #)++bufferSizeBA :: ByteArray# -> Word+bufferSizeBA ba = W# (int2Word# (sizeofByteArray# ba))+ class BufferSize a where    -- |  Get buffer size    bufferSize :: a -> Word  instance BufferSize BufferI where    {-# INLINABLE bufferSize #-}-   bufferSize (Buffer ba)  = fromIntegral $ BA.sizeofByteArray ba+   bufferSize (Buffer ba)  = bufferSizeBA ba instance BufferSize BufferP where    {-# INLINABLE bufferSize #-}-   bufferSize (BufferP ba) = fromIntegral $ BA.sizeofByteArray ba+   bufferSize (BufferP ba) = bufferSizeBA ba instance BufferSize BufferF where    {-# INLINABLE bufferSize #-}-   bufferSize (BufferF ba _fin)  = fromIntegral $ BA.sizeofByteArray ba+   bufferSize (BufferF ba _fin)  = bufferSizeBA ba instance BufferSize BufferPF where    {-# INLINABLE bufferSize #-}-   bufferSize (BufferPF ba _fin) = fromIntegral $ BA.sizeofByteArray ba+   bufferSize (BufferPF ba _fin) = bufferSizeBA ba instance BufferSize BufferME where    {-# INLINABLE bufferSize #-}    bufferSize (BufferME _addr sz) = sz@@ -537,32 +513,50 @@  -- | Get contents as a list of bytes bufferToListIO :: MonadIO m => Buffer mut pin fin heap -> m [Word8]-bufferToListIO = \case-   Buffer  ba             -> return (toList ba)-   BufferP ba             -> return (toList ba)-   BufferF   ba _fin      -> return (toList ba)-   BufferPF  ba _fin      -> return (toList ba)-   BufferM ba             -> return (toList (unsafeCoerce ba :: BA.ByteArray))-   BufferMP ba            -> return (toList (unsafeCoerce ba :: BA.ByteArray))-   BufferMF  ba _fin      -> return (toList (unsafeCoerce ba :: BA.ByteArray))-   BufferMPF ba _fin      -> return (toList (unsafeCoerce ba :: BA.ByteArray))-   BufferME addr sz       -> peekArray sz (Ptr addr)+bufferToListIO b = case b of+   Buffer    _ba          -> pure (toListBuffer b)+   BufferP   _ba          -> pure (toListBuffer b)+   BufferF   _ba _fin     -> pure (toListBuffer b)+   BufferPF  _ba _fin     -> pure (toListBuffer b)+   BufferM   _ba          -> toListBufferIO b+   BufferMP  _ba          -> toListBufferIO b+   BufferMF  _ba _fin     -> toListBufferIO b+   BufferMPF _ba _fin     -> toListBufferIO b+   BufferME  addr sz      -> peekArray sz (Ptr addr)    BufferMEF addr sz _fin -> peekArray sz (Ptr addr)-   BufferE  addr sz       -> peekArray sz (Ptr addr)+   BufferE   addr sz      -> peekArray sz (Ptr addr)    BufferEF  addr sz _fin -> peekArray sz (Ptr addr) +-- | Convert a buffer into a list of bytes by reading bytes one by one+toListBufferIO :: MonadIO m => Buffer mut pin fin heap -> m [Word8]+toListBufferIO b = do+   sz <- bufferSizeIO b+   let+      go i xs = do+         x <- bufferReadWord8IO b i+         if i == 0+            then return (x:xs)+            else go (i-1) (x:xs)+   go (sz-1) []++-- | Convert a buffer into a list of bytes by reading bytes one by one+toListBuffer :: BufferSize (Buffer 'Immutable pin fin heap) => Buffer 'Immutable pin fin heap -> [Word8]+toListBuffer b = if sz == 0 then [] else fmap (bufferReadWord8 b) [0..(sz-1)] +   where+      sz = bufferSize b+ class BufferToList a where    -- | Get contents as a list of bytes    bufferToList :: a -> [Word8]  instance BufferToList BufferI where-   bufferToList (Buffer ba) = toList ba+   bufferToList b = toListBuffer b instance BufferToList BufferP where-   bufferToList (BufferP ba) = toList ba+   bufferToList b = toListBuffer b instance BufferToList BufferF where-   bufferToList (BufferF ba _fin) = toList ba+   bufferToList b = toListBuffer b instance BufferToList BufferPF where-   bufferToList (BufferPF ba _fin) = toList ba+   bufferToList b = toListBuffer b  -- | Support for OverloadedLists --@@ -570,12 +564,22 @@ -- >>> let b = [25,26,27,28] :: BufferI -- instance IsList BufferI where-   type Item BufferI  = Word8-   toList (Buffer ba) = toList ba-   fromList xs        = Buffer (fromList xs)-   fromListN sz xs    = Buffer (fromListN sz xs)+   type Item BufferI = Word8+   toList b          = toListBuffer b+   fromList xs       = unsafePerformIO do+      let sz = fromIntegral (length xs)+      b <- newBuffer sz+      forM_ ([0..] `zip` xs) \(i,x) -> do+         bufferWriteWord8IO b i x+      unsafeBufferFreeze b +   fromListN sz xs   = unsafePerformIO do+      b <- newBuffer (fromIntegral sz)+      forM_ ([0..] `zip` xs) \(i,x) -> do+         bufferWriteWord8IO b i x+      unsafeBufferFreeze b + -- | Read a Word8, offset in bytes -- -- We don't check that the offset is valid@@ -599,18 +603,18 @@ {-# SPECIALIZE INLINE bufferReadWord8IO :: MonadIO m => BufferMEF-> Word -> m Word8 #-} {-# SPECIALIZE INLINE bufferReadWord8IO :: MonadIO m => BufferEF -> Word -> m Word8 #-} bufferReadWord8IO b (fromIntegral -> !(I# off)) = case b of-   BufferM (BA.MutableByteArray ba)          -> liftIO $ IO $ \s -> case readWord8Array# ba off s of (# s2 , r #) -> (# s2 , W8# r #)-   BufferMP (BA.MutableByteArray ba)         -> liftIO $ IO $ \s -> case readWord8Array# ba off s of (# s2 , r #) -> (# s2 , W8# r #)-   BufferMF  (BA.MutableByteArray ba) _fin   -> liftIO $ IO $ \s -> case readWord8Array# ba off s of (# s2 , r #) -> (# s2 , W8# r #)-   BufferMPF (BA.MutableByteArray ba) _fin   -> liftIO $ IO $ \s -> case readWord8Array# ba off s of (# s2 , r #) -> (# s2 , W8# r #)-   BufferME  addr _sz                        -> liftIO $ IO $ \s -> case readWord8OffAddr# addr off s of (# s2 , r #) -> (# s2 , W8# r #)-   BufferMEF addr _sz _fin                   -> liftIO $ IO $ \s -> case readWord8OffAddr# addr off s of (# s2 , r #) -> (# s2 , W8# r #)-   BufferE   addr _sz                        -> liftIO $ IO $ \s -> case readWord8OffAddr# addr off s of (# s2 , r #) -> (# s2 , W8# r #)-   BufferEF  addr _sz _fin                   -> liftIO $ IO $ \s -> case readWord8OffAddr# addr off s of (# s2 , r #) -> (# s2 , W8# r #)-   Buffer  (BA.ByteArray ba)                 -> return (W8# (indexWord8Array# ba off))-   BufferP (BA.ByteArray ba)                 -> return (W8# (indexWord8Array# ba off))-   BufferF   (BA.ByteArray ba) _fin          -> return (W8# (indexWord8Array# ba off))-   BufferPF  (BA.ByteArray ba) _fin          -> return (W8# (indexWord8Array# ba off))+   BufferM   ba            -> liftIO $ IO \s -> case readWord8Array# ba off s of (# s2 , r #)     -> (# s2 , W8# r #)+   BufferMP  ba            -> liftIO $ IO \s -> case readWord8Array# ba off s of (# s2 , r #)     -> (# s2 , W8# r #)+   BufferMF  ba  _fin      -> liftIO $ IO \s -> case readWord8Array# ba off s of (# s2 , r #)     -> (# s2 , W8# r #)+   BufferMPF ba  _fin      -> liftIO $ IO \s -> case readWord8Array# ba off s of (# s2 , r #)     -> (# s2 , W8# r #)+   BufferME  addr _sz      -> liftIO $ IO \s -> case readWord8OffAddr# addr off s of (# s2 , r #) -> (# s2 , W8# r #)+   BufferMEF addr _sz _fin -> liftIO $ IO \s -> case readWord8OffAddr# addr off s of (# s2 , r #) -> (# s2 , W8# r #)+   BufferE   addr _sz      -> liftIO $ IO \s -> case readWord8OffAddr# addr off s of (# s2 , r #) -> (# s2 , W8# r #)+   BufferEF  addr _sz _fin -> liftIO $ IO \s -> case readWord8OffAddr# addr off s of (# s2 , r #) -> (# s2 , W8# r #)+   Buffer    ba            -> return (W8# (indexWord8Array# ba off))+   BufferP   ba            -> return (W8# (indexWord8Array# ba off))+   BufferF   ba _fin       -> return (W8# (indexWord8Array# ba off))+   BufferPF  ba _fin       -> return (W8# (indexWord8Array# ba off))  -- | Read a Word8 in an immutable buffer, offset in bytes --@@ -629,12 +633,12 @@ {-# SPECIALIZE INLINE bufferReadWord8 :: BufferPF -> Word -> Word8 #-} {-# SPECIALIZE INLINE bufferReadWord8 :: BufferEF -> Word -> Word8 #-} bufferReadWord8 b (fromIntegral -> !(I# off)) = case b of-   Buffer  (BA.ByteArray ba)                 -> W8# (indexWord8Array# ba off)-   BufferP (BA.ByteArray ba)                 -> W8# (indexWord8Array# ba off)-   BufferF   (BA.ByteArray ba) _fin          -> W8# (indexWord8Array# ba off)-   BufferPF  (BA.ByteArray ba) _fin          -> W8# (indexWord8Array# ba off)-   BufferE  addr _sz                         -> W8# (indexWord8OffAddr# (addr `plusAddr#` off) 0#)-   BufferEF addr _sz _fin                    -> W8# (indexWord8OffAddr# (addr `plusAddr#` off) 0#)+   Buffer   ba               -> W8# (indexWord8Array# ba off)+   BufferP  ba               -> W8# (indexWord8Array# ba off)+   BufferF  ba _fin          -> W8# (indexWord8Array# ba off)+   BufferPF ba _fin          -> W8# (indexWord8Array# ba off)+   BufferE  addr _sz         -> W8# (indexWord8OffAddr# (addr `plusAddr#` off) 0#)+   BufferEF addr _sz _fin    -> W8# (indexWord8OffAddr# (addr `plusAddr#` off) 0#)  -- | Write a Word8, offset in bytes --@@ -654,15 +658,12 @@ {-# SPECIALIZE INLINE bufferWriteWord8IO :: MonadIO m => BufferMPF-> Word -> Word8 -> m ()#-} {-# SPECIALIZE INLINE bufferWriteWord8IO :: MonadIO m => BufferMEF-> Word -> Word8 -> m ()#-} bufferWriteWord8IO b (fromIntegral -> !(I# off)) (W8# v) = case b of-   BufferM (BA.MutableByteArray ba)          -> liftIO $ IO $ \s -> case writeWord8Array# ba off v s of s2 -> (# s2 , () #)-   BufferMP (BA.MutableByteArray ba)         -> liftIO $ IO $ \s -> case writeWord8Array# ba off v s of s2 -> (# s2 , () #)-   BufferMF  (BA.MutableByteArray ba) _fin   -> liftIO $ IO $ \s -> case writeWord8Array# ba off v s of s2 -> (# s2 , () #)-   BufferMPF (BA.MutableByteArray ba) _fin   -> liftIO $ IO $ \s -> case writeWord8Array# ba off v s of s2 -> (# s2 , () #)-   BufferME  addr _sz                        -> liftIO $ IO $ \s -> case writeWord8OffAddr# addr off v s of s2 -> (# s2 , () #)-   BufferMEF addr _sz _fin                   -> liftIO $ IO $ \s -> case writeWord8OffAddr# addr off v s of s2 -> (# s2 , () #)---+   BufferM   ba            -> liftIO $ IO \s -> case writeWord8Array# ba off v s of s2 -> (# s2 , () #)+   BufferMP  ba            -> liftIO $ IO \s -> case writeWord8Array# ba off v s of s2 -> (# s2 , () #)+   BufferMF  ba _fin       -> liftIO $ IO \s -> case writeWord8Array# ba off v s of s2 -> (# s2 , () #)+   BufferMPF ba _fin       -> liftIO $ IO \s -> case writeWord8Array# ba off v s of s2 -> (# s2 , () #)+   BufferME  addr _sz      -> liftIO $ IO \s -> case writeWord8OffAddr# addr off v s of s2 -> (# s2 , () #)+   BufferMEF addr _sz _fin -> liftIO $ IO \s -> case writeWord8OffAddr# addr off v s of s2 -> (# s2 , () #)   -- | Read a Word16, offset in bytes@@ -689,18 +690,18 @@ {-# SPECIALIZE INLINE bufferReadWord16IO :: MonadIO m => BufferMEF-> Word -> m Word16 #-} {-# SPECIALIZE INLINE bufferReadWord16IO :: MonadIO m => BufferEF -> Word -> m Word16 #-} bufferReadWord16IO b (fromIntegral -> !(I# off)) = case b of-   BufferM (BA.MutableByteArray ba)          -> liftIO $ IO $ \s -> case readWord8ArrayAsWord16# ba off s of (# s2 , r #) -> (# s2 , W16# r #)-   BufferMP (BA.MutableByteArray ba)         -> liftIO $ IO $ \s -> case readWord8ArrayAsWord16# ba off s of (# s2 , r #) -> (# s2 , W16# r #)-   BufferMF  (BA.MutableByteArray ba) _fin   -> liftIO $ IO $ \s -> case readWord8ArrayAsWord16# ba off s of (# s2 , r #) -> (# s2 , W16# r #)-   BufferMPF (BA.MutableByteArray ba) _fin   -> liftIO $ IO $ \s -> case readWord8ArrayAsWord16# ba off s of (# s2 , r #) -> (# s2 , W16# r #)-   BufferME  addr _sz                        -> liftIO $ IO $ \s -> case readWord16OffAddr# (addr `plusAddr#` off) 0# s of (# s2 , r #) -> (# s2 , W16# r #)-   BufferMEF addr _sz _fin                   -> liftIO $ IO $ \s -> case readWord16OffAddr# (addr `plusAddr#` off) 0# s of (# s2 , r #) -> (# s2 , W16# r #)-   BufferE   addr _sz                        -> liftIO $ IO $ \s -> case readWord16OffAddr# (addr `plusAddr#` off) 0# s of (# s2 , r #) -> (# s2 , W16# r #)-   BufferEF  addr _sz _fin                   -> liftIO $ IO $ \s -> case readWord16OffAddr# (addr `plusAddr#` off) 0# s of (# s2 , r #) -> (# s2 , W16# r #)-   Buffer  (BA.ByteArray ba)                 -> return (W16# (indexWord8ArrayAsWord16# ba off))-   BufferP (BA.ByteArray ba)                 -> return (W16# (indexWord8ArrayAsWord16# ba off))-   BufferF   (BA.ByteArray ba) _fin          -> return (W16# (indexWord8ArrayAsWord16# ba off))-   BufferPF  (BA.ByteArray ba) _fin          -> return (W16# (indexWord8ArrayAsWord16# ba off))+   BufferM   ba               -> liftIO $ IO \s -> case readWord8ArrayAsWord16# ba off s of (# s2 , r #) -> (# s2 , W16# r #)+   BufferMP  ba               -> liftIO $ IO \s -> case readWord8ArrayAsWord16# ba off s of (# s2 , r #) -> (# s2 , W16# r #)+   BufferMF  ba _fin          -> liftIO $ IO \s -> case readWord8ArrayAsWord16# ba off s of (# s2 , r #) -> (# s2 , W16# r #)+   BufferMPF ba _fin          -> liftIO $ IO \s -> case readWord8ArrayAsWord16# ba off s of (# s2 , r #) -> (# s2 , W16# r #)+   BufferME  addr _sz         -> liftIO $ IO \s -> case readWord16OffAddr# (addr `plusAddr#` off) 0# s of (# s2 , r #) -> (# s2 , W16# r #)+   BufferMEF addr _sz _fin    -> liftIO $ IO \s -> case readWord16OffAddr# (addr `plusAddr#` off) 0# s of (# s2 , r #) -> (# s2 , W16# r #)+   BufferE   addr _sz         -> liftIO $ IO \s -> case readWord16OffAddr# (addr `plusAddr#` off) 0# s of (# s2 , r #) -> (# s2 , W16# r #)+   BufferEF  addr _sz _fin    -> liftIO $ IO \s -> case readWord16OffAddr# (addr `plusAddr#` off) 0# s of (# s2 , r #) -> (# s2 , W16# r #)+   Buffer    ba               -> return (W16# (indexWord8ArrayAsWord16# ba off))+   BufferP   ba               -> return (W16# (indexWord8ArrayAsWord16# ba off))+   BufferF   ba _fin          -> return (W16# (indexWord8ArrayAsWord16# ba off))+   BufferPF  ba _fin          -> return (W16# (indexWord8ArrayAsWord16# ba off))  -- | Read a Word16 in an immutable buffer, offset in bytes --@@ -714,12 +715,12 @@ {-# SPECIALIZE INLINE bufferReadWord16 :: BufferPF -> Word -> Word16 #-} {-# SPECIALIZE INLINE bufferReadWord16 :: BufferEF -> Word -> Word16 #-} bufferReadWord16 b (fromIntegral -> !(I# off)) = case b of-   Buffer  (BA.ByteArray ba)                 -> W16# (indexWord8ArrayAsWord16# ba off)-   BufferP (BA.ByteArray ba)                 -> W16# (indexWord8ArrayAsWord16# ba off)-   BufferF   (BA.ByteArray ba) _fin          -> W16# (indexWord8ArrayAsWord16# ba off)-   BufferPF  (BA.ByteArray ba) _fin          -> W16# (indexWord8ArrayAsWord16# ba off)-   BufferE  addr _sz                         -> W16# (indexWord16OffAddr# (addr `plusAddr#` off) 0#)-   BufferEF addr _sz _fin                    -> W16# (indexWord16OffAddr# (addr `plusAddr#` off) 0#)+   Buffer   ba            -> W16# (indexWord8ArrayAsWord16# ba off)+   BufferP  ba            -> W16# (indexWord8ArrayAsWord16# ba off)+   BufferF  ba _fin       -> W16# (indexWord8ArrayAsWord16# ba off)+   BufferPF ba _fin       -> W16# (indexWord8ArrayAsWord16# ba off)+   BufferE  addr _sz      -> W16# (indexWord16OffAddr# (addr `plusAddr#` off) 0#)+   BufferEF addr _sz _fin -> W16# (indexWord16OffAddr# (addr `plusAddr#` off) 0#)  -- | Write a Word16, offset in bytes --@@ -745,12 +746,12 @@ {-# SPECIALIZE INLINE bufferWriteWord16IO :: MonadIO m => BufferMPF-> Word -> Word16 -> m ()#-} {-# SPECIALIZE INLINE bufferWriteWord16IO :: MonadIO m => BufferMEF-> Word -> Word16 -> m ()#-} bufferWriteWord16IO b (fromIntegral -> !(I# off)) (W16# v) = case b of-   BufferM (BA.MutableByteArray ba)          -> liftIO $ IO $ \s -> case writeWord8ArrayAsWord16# ba off v s of s2 -> (# s2 , () #)-   BufferMP (BA.MutableByteArray ba)         -> liftIO $ IO $ \s -> case writeWord8ArrayAsWord16# ba off v s of s2 -> (# s2 , () #)-   BufferMF  (BA.MutableByteArray ba) _fin   -> liftIO $ IO $ \s -> case writeWord8ArrayAsWord16# ba off v s of s2 -> (# s2 , () #)-   BufferMPF (BA.MutableByteArray ba) _fin   -> liftIO $ IO $ \s -> case writeWord8ArrayAsWord16# ba off v s of s2 -> (# s2 , () #)-   BufferME  addr _sz                        -> liftIO $ IO $ \s -> case writeWord16OffAddr# (addr `plusAddr#` off) 0# v s of s2 -> (# s2 , () #)-   BufferMEF addr _sz _fin                   -> liftIO $ IO $ \s -> case writeWord16OffAddr# (addr `plusAddr#` off) 0# v s of s2 -> (# s2 , () #)+   BufferM   ba            -> liftIO $ IO \s -> case writeWord8ArrayAsWord16# ba off v s of s2 -> (# s2 , () #)+   BufferMP  ba            -> liftIO $ IO \s -> case writeWord8ArrayAsWord16# ba off v s of s2 -> (# s2 , () #)+   BufferMF  ba _fin       -> liftIO $ IO \s -> case writeWord8ArrayAsWord16# ba off v s of s2 -> (# s2 , () #)+   BufferMPF ba _fin       -> liftIO $ IO \s -> case writeWord8ArrayAsWord16# ba off v s of s2 -> (# s2 , () #)+   BufferME  addr _sz      -> liftIO $ IO \s -> case writeWord16OffAddr# (addr `plusAddr#` off) 0# v s of s2 -> (# s2 , () #)+   BufferMEF addr _sz _fin -> liftIO $ IO \s -> case writeWord16OffAddr# (addr `plusAddr#` off) 0# v s of s2 -> (# s2 , () #)   @@ -778,18 +779,18 @@ {-# SPECIALIZE INLINE bufferReadWord32IO :: MonadIO m => BufferMEF-> Word -> m Word32 #-} {-# SPECIALIZE INLINE bufferReadWord32IO :: MonadIO m => BufferEF -> Word -> m Word32 #-} bufferReadWord32IO b (fromIntegral -> !(I# off)) = case b of-   BufferM    (BA.MutableByteArray ba)        -> liftIO $ IO $ \s -> case readWord8ArrayAsWord32# ba off s of (# s2 , r #) -> (# s2 , W32# r #)-   BufferMP   (BA.MutableByteArray ba)        -> liftIO $ IO $ \s -> case readWord8ArrayAsWord32# ba off s of (# s2 , r #) -> (# s2 , W32# r #)-   BufferMF   (BA.MutableByteArray ba) _fin   -> liftIO $ IO $ \s -> case readWord8ArrayAsWord32# ba off s of (# s2 , r #) -> (# s2 , W32# r #)-   BufferMPF  (BA.MutableByteArray ba) _fin   -> liftIO $ IO $ \s -> case readWord8ArrayAsWord32# ba off s of (# s2 , r #) -> (# s2 , W32# r #)-   BufferME   addr _sz                        -> liftIO $ IO $ \s -> case readWord32OffAddr# (addr `plusAddr#` off) 0# s of (# s2 , r #) -> (# s2 , W32# r #)-   BufferMEF  addr _sz _fin                   -> liftIO $ IO $ \s -> case readWord32OffAddr# (addr `plusAddr#` off) 0# s of (# s2 , r #) -> (# s2 , W32# r #)-   BufferE    addr _sz                        -> liftIO $ IO $ \s -> case readWord32OffAddr# (addr `plusAddr#` off) 0# s of (# s2 , r #) -> (# s2 , W32# r #)-   BufferEF   addr _sz _fin                   -> liftIO $ IO $ \s -> case readWord32OffAddr# (addr `plusAddr#` off) 0# s of (# s2 , r #) -> (# s2 , W32# r #)-   Buffer     (BA.ByteArray ba)               -> return (W32# (indexWord8ArrayAsWord32# ba off))-   BufferP    (BA.ByteArray ba)               -> return (W32# (indexWord8ArrayAsWord32# ba off))-   BufferF    (BA.ByteArray ba) _fin          -> return (W32# (indexWord8ArrayAsWord32# ba off))-   BufferPF   (BA.ByteArray ba) _fin          -> return (W32# (indexWord8ArrayAsWord32# ba off))+   BufferM    ba               -> liftIO $ IO \s -> case readWord8ArrayAsWord32# ba off s of (# s2 , r #) -> (# s2 , W32# r #)+   BufferMP   ba               -> liftIO $ IO \s -> case readWord8ArrayAsWord32# ba off s of (# s2 , r #) -> (# s2 , W32# r #)+   BufferMF   ba _fin          -> liftIO $ IO \s -> case readWord8ArrayAsWord32# ba off s of (# s2 , r #) -> (# s2 , W32# r #)+   BufferMPF  ba _fin          -> liftIO $ IO \s -> case readWord8ArrayAsWord32# ba off s of (# s2 , r #) -> (# s2 , W32# r #)+   BufferME   addr _sz         -> liftIO $ IO \s -> case readWord32OffAddr# (addr `plusAddr#` off) 0# s of (# s2 , r #) -> (# s2 , W32# r #)+   BufferMEF  addr _sz _fin    -> liftIO $ IO \s -> case readWord32OffAddr# (addr `plusAddr#` off) 0# s of (# s2 , r #) -> (# s2 , W32# r #)+   BufferE    addr _sz         -> liftIO $ IO \s -> case readWord32OffAddr# (addr `plusAddr#` off) 0# s of (# s2 , r #) -> (# s2 , W32# r #)+   BufferEF   addr _sz _fin    -> liftIO $ IO \s -> case readWord32OffAddr# (addr `plusAddr#` off) 0# s of (# s2 , r #) -> (# s2 , W32# r #)+   Buffer     ba               -> return (W32# (indexWord8ArrayAsWord32# ba off))+   BufferP    ba               -> return (W32# (indexWord8ArrayAsWord32# ba off))+   BufferF    ba _fin          -> return (W32# (indexWord8ArrayAsWord32# ba off))+   BufferPF   ba _fin          -> return (W32# (indexWord8ArrayAsWord32# ba off))  -- | Read a Word32 in an immutable buffer, offset in bytes --@@ -803,12 +804,12 @@ {-# SPECIALIZE INLINE bufferReadWord32 :: BufferPF -> Word -> Word32 #-} {-# SPECIALIZE INLINE bufferReadWord32 :: BufferEF -> Word -> Word32 #-} bufferReadWord32 b (fromIntegral -> !(I# off)) = case b of-   Buffer  (BA.ByteArray ba)                 -> W32# (indexWord8ArrayAsWord32# ba off)-   BufferP (BA.ByteArray ba)                 -> W32# (indexWord8ArrayAsWord32# ba off)-   BufferF   (BA.ByteArray ba) _fin          -> W32# (indexWord8ArrayAsWord32# ba off)-   BufferPF  (BA.ByteArray ba) _fin          -> W32# (indexWord8ArrayAsWord32# ba off)-   BufferE  addr _sz                         -> W32# (indexWord32OffAddr# (addr `plusAddr#` off) 0#)-   BufferEF addr _sz _fin                    -> W32# (indexWord32OffAddr# (addr `plusAddr#` off) 0#)+   Buffer   ba               -> W32# (indexWord8ArrayAsWord32# ba off)+   BufferP  ba               -> W32# (indexWord8ArrayAsWord32# ba off)+   BufferF  ba _fin          -> W32# (indexWord8ArrayAsWord32# ba off)+   BufferPF ba _fin          -> W32# (indexWord8ArrayAsWord32# ba off)+   BufferE  addr _sz         -> W32# (indexWord32OffAddr# (addr `plusAddr#` off) 0#)+   BufferEF addr _sz _fin    -> W32# (indexWord32OffAddr# (addr `plusAddr#` off) 0#)  -- | Write a Word32, offset in bytes --@@ -829,12 +830,12 @@ {-# SPECIALIZE INLINE bufferWriteWord32IO :: MonadIO m => BufferMPF-> Word -> Word32 -> m ()#-} {-# SPECIALIZE INLINE bufferWriteWord32IO :: MonadIO m => BufferMEF-> Word -> Word32 -> m ()#-} bufferWriteWord32IO b (fromIntegral -> !(I# off)) (W32# v) = case b of-   BufferM (BA.MutableByteArray ba)          -> liftIO $ IO $ \s -> case writeWord8ArrayAsWord32# ba off v s of s2 -> (# s2 , () #)-   BufferMP (BA.MutableByteArray ba)         -> liftIO $ IO $ \s -> case writeWord8ArrayAsWord32# ba off v s of s2 -> (# s2 , () #)-   BufferMF  (BA.MutableByteArray ba) _fin   -> liftIO $ IO $ \s -> case writeWord8ArrayAsWord32# ba off v s of s2 -> (# s2 , () #)-   BufferMPF (BA.MutableByteArray ba) _fin   -> liftIO $ IO $ \s -> case writeWord8ArrayAsWord32# ba off v s of s2 -> (# s2 , () #)-   BufferME  addr _sz                        -> liftIO $ IO $ \s -> case writeWord32OffAddr# (addr `plusAddr#` off) 0# v s of s2 -> (# s2 , () #)-   BufferMEF addr _sz _fin                   -> liftIO $ IO $ \s -> case writeWord32OffAddr# (addr `plusAddr#` off) 0# v s of s2 -> (# s2 , () #)+   BufferM   ba            -> liftIO $ IO \s -> case writeWord8ArrayAsWord32# ba off v s of s2 -> (# s2 , () #)+   BufferMP  ba            -> liftIO $ IO \s -> case writeWord8ArrayAsWord32# ba off v s of s2 -> (# s2 , () #)+   BufferMF  ba _fin       -> liftIO $ IO \s -> case writeWord8ArrayAsWord32# ba off v s of s2 -> (# s2 , () #)+   BufferMPF ba _fin       -> liftIO $ IO \s -> case writeWord8ArrayAsWord32# ba off v s of s2 -> (# s2 , () #)+   BufferME  addr _sz      -> liftIO $ IO \s -> case writeWord32OffAddr# (addr `plusAddr#` off) 0# v s of s2 -> (# s2 , () #)+   BufferMEF addr _sz _fin -> liftIO $ IO \s -> case writeWord32OffAddr# (addr `plusAddr#` off) 0# v s of s2 -> (# s2 , () #)   -- | Read a Word64, offset in bytes@@ -861,18 +862,18 @@ {-# SPECIALIZE INLINE bufferReadWord64IO :: MonadIO m => BufferMEF-> Word -> m Word64 #-} {-# SPECIALIZE INLINE bufferReadWord64IO :: MonadIO m => BufferEF -> Word -> m Word64 #-} bufferReadWord64IO b (fromIntegral -> !(I# off)) = case b of-   BufferM (BA.MutableByteArray ba)          -> liftIO $ IO $ \s -> case readWord8ArrayAsWord64# ba off s of (# s2 , r #) -> (# s2 , W64# r #)-   BufferMP (BA.MutableByteArray ba)         -> liftIO $ IO $ \s -> case readWord8ArrayAsWord64# ba off s of (# s2 , r #) -> (# s2 , W64# r #)-   BufferMF  (BA.MutableByteArray ba) _fin   -> liftIO $ IO $ \s -> case readWord8ArrayAsWord64# ba off s of (# s2 , r #) -> (# s2 , W64# r #)-   BufferMPF (BA.MutableByteArray ba) _fin   -> liftIO $ IO $ \s -> case readWord8ArrayAsWord64# ba off s of (# s2 , r #) -> (# s2 , W64# r #)-   BufferME  addr _sz                        -> liftIO $ IO $ \s -> case readWord64OffAddr# (addr `plusAddr#` off) 0# s of (# s2 , r #) -> (# s2 , W64# r #)-   BufferMEF addr _sz _fin                   -> liftIO $ IO $ \s -> case readWord64OffAddr# (addr `plusAddr#` off) 0# s of (# s2 , r #) -> (# s2 , W64# r #)-   BufferE  addr _sz                         -> liftIO $ IO $ \s -> case readWord64OffAddr# (addr `plusAddr#` off) 0# s of (# s2 , r #) -> (# s2 , W64# r #)-   BufferEF addr _sz _fin                    -> liftIO $ IO $ \s -> case readWord64OffAddr# (addr `plusAddr#` off) 0# s of (# s2 , r #) -> (# s2 , W64# r #)-   Buffer  (BA.ByteArray ba)                 -> return (W64# (indexWord8ArrayAsWord64# ba off))-   BufferP (BA.ByteArray ba)                 -> return (W64# (indexWord8ArrayAsWord64# ba off))-   BufferF   (BA.ByteArray ba) _fin          -> return (W64# (indexWord8ArrayAsWord64# ba off))-   BufferPF  (BA.ByteArray ba) _fin          -> return (W64# (indexWord8ArrayAsWord64# ba off))+   BufferM   ba              -> liftIO $ IO \s -> case readWord8ArrayAsWord64# ba off s of (# s2 , r #) -> (# s2 , W64# r #)+   BufferMP  ba              -> liftIO $ IO \s -> case readWord8ArrayAsWord64# ba off s of (# s2 , r #) -> (# s2 , W64# r #)+   BufferMF  ba _fin         -> liftIO $ IO \s -> case readWord8ArrayAsWord64# ba off s of (# s2 , r #) -> (# s2 , W64# r #)+   BufferMPF ba _fin         -> liftIO $ IO \s -> case readWord8ArrayAsWord64# ba off s of (# s2 , r #) -> (# s2 , W64# r #)+   BufferME  addr _sz        -> liftIO $ IO \s -> case readWord64OffAddr# (addr `plusAddr#` off) 0# s of (# s2 , r #) -> (# s2 , W64# r #)+   BufferMEF addr _sz _fin   -> liftIO $ IO \s -> case readWord64OffAddr# (addr `plusAddr#` off) 0# s of (# s2 , r #) -> (# s2 , W64# r #)+   BufferE  addr _sz         -> liftIO $ IO \s -> case readWord64OffAddr# (addr `plusAddr#` off) 0# s of (# s2 , r #) -> (# s2 , W64# r #)+   BufferEF addr _sz _fin    -> liftIO $ IO \s -> case readWord64OffAddr# (addr `plusAddr#` off) 0# s of (# s2 , r #) -> (# s2 , W64# r #)+   Buffer   ba               -> return (W64# (indexWord8ArrayAsWord64# ba off))+   BufferP  ba               -> return (W64# (indexWord8ArrayAsWord64# ba off))+   BufferF  ba _fin          -> return (W64# (indexWord8ArrayAsWord64# ba off))+   BufferPF ba _fin          -> return (W64# (indexWord8ArrayAsWord64# ba off))  -- | Read a Word64 in an immutable buffer, offset in bytes --@@ -886,12 +887,12 @@ {-# SPECIALIZE INLINE bufferReadWord64 :: BufferPF -> Word -> Word64 #-} {-# SPECIALIZE INLINE bufferReadWord64 :: BufferEF -> Word -> Word64 #-} bufferReadWord64 b (fromIntegral -> !(I# off)) = case b of-   Buffer    (BA.ByteArray ba)               -> W64# (indexWord8ArrayAsWord64# ba off)-   BufferP   (BA.ByteArray ba)               -> W64# (indexWord8ArrayAsWord64# ba off)-   BufferF   (BA.ByteArray ba) _fin          -> W64# (indexWord8ArrayAsWord64# ba off)-   BufferPF  (BA.ByteArray ba) _fin          -> W64# (indexWord8ArrayAsWord64# ba off)-   BufferE  addr _sz                         -> W64# (indexWord64OffAddr# (addr `plusAddr#` off) 0#)-   BufferEF addr _sz _fin                    -> W64# (indexWord64OffAddr# (addr `plusAddr#` off) 0#)+   Buffer   ba               -> W64# (indexWord8ArrayAsWord64# ba off)+   BufferP  ba               -> W64# (indexWord8ArrayAsWord64# ba off)+   BufferF  ba _fin          -> W64# (indexWord8ArrayAsWord64# ba off)+   BufferPF ba _fin          -> W64# (indexWord8ArrayAsWord64# ba off)+   BufferE  addr _sz         -> W64# (indexWord64OffAddr# (addr `plusAddr#` off) 0#)+   BufferEF addr _sz _fin    -> W64# (indexWord64OffAddr# (addr `plusAddr#` off) 0#)  -- | Write a Word64, offset in bytes --@@ -912,12 +913,12 @@ {-# SPECIALIZE INLINE bufferWriteWord64IO :: MonadIO m => BufferMPF-> Word -> Word64 -> m ()#-} {-# SPECIALIZE INLINE bufferWriteWord64IO :: MonadIO m => BufferMEF-> Word -> Word64 -> m ()#-} bufferWriteWord64IO b (fromIntegral -> !(I# off)) (W64# v) = case b of-   BufferM   (BA.MutableByteArray ba)        -> liftIO $ IO $ \s -> case writeWord8ArrayAsWord64# ba off v s of s2 -> (# s2 , () #)-   BufferMP  (BA.MutableByteArray ba)        -> liftIO $ IO $ \s -> case writeWord8ArrayAsWord64# ba off v s of s2 -> (# s2 , () #)-   BufferMF  (BA.MutableByteArray ba) _fin   -> liftIO $ IO $ \s -> case writeWord8ArrayAsWord64# ba off v s of s2 -> (# s2 , () #)-   BufferMPF (BA.MutableByteArray ba) _fin   -> liftIO $ IO $ \s -> case writeWord8ArrayAsWord64# ba off v s of s2 -> (# s2 , () #)-   BufferME  addr _sz                        -> liftIO $ IO $ \s -> case writeWord64OffAddr# (addr `plusAddr#` off) 0# v s of s2 -> (# s2 , () #)-   BufferMEF addr _sz _fin                   -> liftIO $ IO $ \s -> case writeWord64OffAddr# (addr `plusAddr#` off) 0# v s of s2 -> (# s2 , () #)+   BufferM   ba            -> liftIO $ IO \s -> case writeWord8ArrayAsWord64# ba off v s of s2 -> (# s2 , () #)+   BufferMP  ba            -> liftIO $ IO \s -> case writeWord8ArrayAsWord64# ba off v s of s2 -> (# s2 , () #)+   BufferMF  ba _fin       -> liftIO $ IO \s -> case writeWord8ArrayAsWord64# ba off v s of s2 -> (# s2 , () #)+   BufferMPF ba _fin       -> liftIO $ IO \s -> case writeWord8ArrayAsWord64# ba off v s of s2 -> (# s2 , () #)+   BufferME  addr _sz      -> liftIO $ IO \s -> case writeWord64OffAddr# (addr `plusAddr#` off) 0# v s of s2 -> (# s2 , () #)+   BufferMEF addr _sz _fin -> liftIO $ IO \s -> case writeWord64OffAddr# (addr `plusAddr#` off) 0# v s of s2 -> (# s2 , () #)   -- | Copy a buffer into another from/to the given offsets@@ -1022,7 +1023,7 @@          BufferME  addr _sz    -> toAddr addr          BufferMEF addr _sz _f -> toAddr addr -      toMba :: BA.MutableByteArray RealWorld -> m ()+      toMba :: MutableByteArray# RealWorld -> m ()       toMba mba = case sb of          Buffer    ba          -> baToMba ba mba          BufferP   ba          -> baToMba ba mba@@ -1052,45 +1053,43 @@          BufferMEF addr2 _sz _f -> addrToAddr addr2 addr          BufferEF  addr2 _sz _f -> addrToAddr addr2 addr -      mbaToMba :: BA.MutableByteArray RealWorld -> BA.MutableByteArray RealWorld -> m ()-      mbaToMba   (BA.MutableByteArray mba1) (BA.MutableByteArray mba2) =-         liftIO $ IO $ \s ->+      mbaToMba :: MutableByteArray# RealWorld -> MutableByteArray# RealWorld -> m ()+      mbaToMba mba1 mba2 =+         liftIO $ IO \s ->             case copyMutableByteArray# mba1 soff mba2 doff cnt s of                s2 -> (# s2, () #) -      baToMba :: BA.ByteArray -> BA.MutableByteArray RealWorld -> m ()-      baToMba (BA.ByteArray ba) (BA.MutableByteArray mba) =-         liftIO $ IO $ \s ->+      baToMba :: ByteArray# -> MutableByteArray# RealWorld -> m ()+      baToMba ba mba =+         liftIO $ IO \s ->             case copyByteArray# ba soff mba doff cnt s of                s2 -> (# s2, () #) -      addrToMba :: Addr# -> BA.MutableByteArray RealWorld -> m ()-      addrToMba addr (BA.MutableByteArray mba) =-         liftIO $ IO $ \s ->+      addrToMba :: Addr# -> MutableByteArray# RealWorld -> m ()+      addrToMba addr mba =+         liftIO $ IO \s ->             case copyAddrToByteArray# (addr `plusAddr#` soff) mba doff cnt s of                s2 -> (# s2, () #) -      baToAddr :: BA.ByteArray -> Addr# -> m ()-      baToAddr (BA.ByteArray ba) addr =-         liftIO $ IO $ \s ->+      baToAddr :: ByteArray# -> Addr# -> m ()+      baToAddr ba addr =+         liftIO $ IO \s ->             case copyByteArrayToAddr# ba soff (addr `plusAddr#` doff) cnt s of                s2 -> (# s2, () #)  -      mbaToAddr :: BA.MutableByteArray RealWorld -> Addr# -> m ()-      mbaToAddr (BA.MutableByteArray mba) addr =+      mbaToAddr :: MutableByteArray# RealWorld -> Addr# -> m ()+      mbaToAddr mba addr =          liftIO $ IO $ \s ->             case copyMutableByteArrayToAddr# mba soff (addr `plusAddr#` doff) cnt s of                s2 -> (# s2, () #)        addrToAddr :: Addr# -> Addr# -> m ()       addrToAddr addr1 addr2 =-         liftIO $ memcpy (addr1 `plusAddr#` soff)-                         (addr2 `plusAddr#` doff)-                         cnt+         liftIO $ memcpy# (addr1 `plusAddr#` soff)+                          (addr2 `plusAddr#` doff)+                          cnt         -foreign import ccall unsafe "memcpy" memcpy :: Addr# -> Addr# -> Int# -> IO ()- ----------------------------------------------------------------- -- AnyBuffer -----------------------------------------------------------------
src/lib/Haskus/Memory/Embed.hs view
@@ -25,12 +25,12 @@ where  import Haskus.Memory.Buffer-import Haskus.Format.Binary.Word-import Haskus.Format.Binary.Ptr+import Haskus.Number.Word import Haskus.Utils.List (intersperse) import Haskus.Utils.Maybe import Haskus.Utils.Monad +import Foreign.Ptr import Language.Haskell.TH import Language.Haskell.TH.Syntax import System.Directory (getFileSize)@@ -244,7 +244,7 @@     liftIO $ unsafeWithBufferPtr buf $ \ptr -> do       withBinaryFile tmp WriteMode $ \hdl -> do-         hPutBuf hdl (ptr `indexPtr` fromIntegral off) (fromIntegral sz)+         hPutBuf hdl (ptr `plusPtr` fromIntegral off) (fromIntegral sz)    embedFile' True tmp mut malign Nothing Nothing  -- | Embed a unpinned buffer in the executable. Return either a BufferE or a
+ src/lib/Haskus/Memory/Layout.hs view
@@ -0,0 +1,166 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE PolyKinds #-}+{-# LANGUAGE NoStarIsType #-}++-- | Memory layout+--+-- Describe a memory region+module Haskus.Memory.Layout+   ( LPath (..)+   , PathElem (..)+   , lPath+   , LPathType+   , LPathOffset+   , LRoot+   , (:->)+   , (:#>)+   -- * Layouts+   , CPrimitive (..)+   , CArray (..)+   , CUArray (..)+   , CStruct (..)+   , CUnion (..)+   )+where++import Haskus.Utils.Types++-- | Path in a layout+data LPath (path :: [PathElem])   = LPath++-- | Layout path element+data PathElem+   = LIndex Nat      -- ^ Addressing via a numeric index+   | LSymbol Symbol  -- ^ Addressing via a symbol++-- | Layout path root+type LRoot = LPath '[]++-- | Index in the layout path+--+-- Helper for ``ptr --> lPath @p``+-- until+lPath :: forall e. LPath '[e]+lPath = LPath++-- | Type obtained when following path p+type family LPathType p l :: Type+type instance LPathType (LPath '[]) l  = l++-- | Offset obtained when following path p+type family LPathOffset p l :: Nat+type instance LPathOffset (LPath '[]) l  = 0+++type family (:->) p (s :: Symbol) where+   (:->) (LPath xs) s = LPath (Snoc xs ('LSymbol s))++type family (:#>) p (n :: Nat) where+   (:#>) (LPath xs) n = LPath (Snoc xs ('LIndex n))++---------------------------+-- Layouts+---------------------------++type family CSizeOf a    :: Nat+type family CAlignment a :: Nat++-- | Primitives+--+-- >>> :kind! CSizeOf (CPrimitive 8 1)+-- CSizeOf (CPrimitive 8 1) :: Nat+-- = 8+--+-- >>> :kind! CAlignment (CPrimitive 8 2)+-- CAlignment (CPrimitive 8 2) :: Nat+-- = 2+--+data CPrimitive (size :: Nat) (align :: Nat)     = CPrimitive+type instance CSizeOf (CPrimitive size align)    = size+type instance CAlignment (CPrimitive size align) = align++-- | Array+--+-- >>> type S = CArray 10 (CPrimitive 8 8)+-- >>> :kind! CSizeOf S+-- CSizeOf S :: Nat+-- = 80+--+-- >>> :kind! CAlignment S+-- CAlignment S :: Nat+-- = 8+data CArray (n :: Nat) (a :: k)       = CArray+type instance CSizeOf (CArray n a)    = n * (CSizeOf a)+type instance CAlignment (CArray n a) = CAlignment a++-- | Unbounded array+--+-- >>> type S = CUArray (CPrimitive 8 8)+-- >>> :kind! CSizeOf S+-- CSizeOf S :: Nat+-- = (TypeError ...)+--+-- >>> :kind! CAlignment S+-- CAlignment S :: Nat+-- = 8+data CUArray (a :: k)                = CUArray+type instance CSizeOf (CUArray a)    = TypeError ('Text "Cannot apply SizeOf to an unbounded array")+type instance CAlignment (CUArray a) = CAlignment a++-- | Struct+--+-- >>> type S = CStruct ['Field "i8" (CPrimitive 1 1), 'Field "i32" (CPrimitive 4 4)]+-- >>> :kind! CSizeOf S+-- CSizeOf S :: Nat+-- = 8+--+-- >>> :kind! CAlignment S+-- CAlignment S :: Nat+-- = 4+data CStruct (fs :: [Field])           = CStruct+type instance CSizeOf (CStruct fs)     = CStructSize fs (CMaxAlignment fs 1) 0+type instance CAlignment (CStruct fs)  = CMaxAlignment fs 1++type family CStructSize (xs :: [Field]) al sz where+   CStructSize '[] al sz               =+      sz + PaddingEx (sz `Mod` al) al+   CStructSize ('Field s t : fs) al sz = CStructSize fs al+      (sz + CSizeOf t + PaddingEx (sz `Mod` CAlignment t) (CAlignment t))++-- | Union+--+-- >>> type S = CUnion ['Field "i8" (CPrimitive 1 1), 'Field "i32" (CPrimitive 4 4)]+-- >>> :kind! CSizeOf S+-- CSizeOf S :: Nat+-- = 4+--+-- >>> :kind! CAlignment S+-- CAlignment S :: Nat+-- = 4+data CUnion (fs :: [Field])           = CUnion+type instance CSizeOf (CUnion fs)     = CUnionSize fs (CMaxAlignment fs 1) 0+type instance CAlignment (CUnion fs)  = CMaxAlignment fs 1++type family CUnionSize (xs :: [Field]) al sz where+   CUnionSize '[] al sz               =+      sz + PaddingEx (sz `Mod` al) al+   CUnionSize ('Field s t : fs) al sz = CUnionSize fs al (Max (CSizeOf t) sz)++-- | Structure field+data Field = Field Symbol Type++type family PaddingEx (m :: Nat) (a :: Nat) where+   PaddingEx 0 a = 0+   PaddingEx m a = a - m++type family CMaxAlignment (xs :: [Field]) al where+   CMaxAlignment '[] al               = al+   CMaxAlignment ('Field s t : fs) al =+      CMaxAlignment fs (Max al (CAlignment t))+
+ src/lib/Haskus/Memory/Property.hs view
@@ -0,0 +1,37 @@+-- | Memory properties+module Haskus.Memory.Property+   ( Mutability (..)+   , Heap (..)+   , Pinning (..)+   , Finalization (..)+   )+where++-- | Is the memory mutable or not?+data Mutability+   = Mutable   -- ^ Memory cells are mutable+   | Immutable -- ^ Memory cells are immutable+   deriving (Show,Eq)++-- | Allocation heap+data Heap+   = Internal -- ^ GHC heap+   | External -- ^ External heap++-- | Is the buffer pinned into memory?+data Pinning+   = Pinned    -- ^ The buffer has a fixed associated memory address+   | NotPinned -- ^ The buffer contents can be freely moved to another address+   deriving (Show,Eq)++-- | Is the memory automatically garbage collected?+data Finalization+   = Collected    -- ^ Automatically collected by the garbage-collector+   | Finalized    -- ^ Finalizers are run just before the garbage collector+                  -- collects the referencing entity (buffer, pointer...). The+                  -- memory used by the entity may be collected too (Internal+                  -- heap), explicitly freed by a finalizer or not freed at all.+   | NotFinalized -- ^ The memory is not automatically freed and we+                  -- can't attach finalizers to the buffer.+   deriving (Show,Eq)+
+ src/lib/Haskus/Memory/Ptr.hs view
@@ -0,0 +1,187 @@+{-# LANGUAGE KindSignatures #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE RoleAnnotations #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE PolyKinds #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE LambdaCase #-}++-- | Pointers+--+-- A pointer is a number: an offset into a memory. This is the `Addr#` type.+--+-- We want the type-system to help us avoid errors when we use pointers, hence+-- we decorate them with phantom types describing the memory layout at the+-- pointed address. This is the `Ptr a` data type that wraps an `Addr#`.+--+-- We often want to associate finalizers to pointers, i.e., actions to be run+-- when the pointer is collected by the GC. These actions take the pointer as a+-- parameter. This is the `ForeignPtr a` data type.+--+-- A `ForeignPtr a` cannot be manipulated like a number because somehow we need+-- to keep the pointer value that will be passed to the finalizers. Moreover we+-- don't want finalizers to be executed too early, so we can't easily create a+-- new ForeignPtr from another (it would require a way to disable the existing+-- finalizers of a ForeignPtr, which would in turn open a whole can of worms).+-- Hence we use the `FinalizedPtr a` pointer type, which has an additional+-- offset field.+module Haskus.Memory.Ptr+   ( Pointer (..)+   , AnyPointer (..)+   , RawPtr+   , FinPtr+   , PtrI+   , PtrM+   , PtrIF+   , PtrMF+   , isNullPtr+   , nullPtrI+   , nullPtrM+   , indexPtr+   , distancePtr+   , withPtr+   , withFinalizedPtr+   , allocFinalizedPtr+   , allocPtr+   , freePtr++   -- * Function pointer+   , P.FunPtr+   , P.nullFunPtr+   , P.castPtrToFunPtr+   , P.castFunPtrToPtr+   -- * Pointer as a Word+   , P.WordPtr+   , P.wordPtrToPtr+   , P.ptrToWordPtr+   )+where++import qualified Foreign.Ptr               as P+import qualified Foreign.Marshal.Alloc     as P+import qualified Foreign.ForeignPtr        as FP+import qualified Foreign.ForeignPtr.Unsafe as FP++import Haskus.Memory.Property+import Haskus.Utils.Monad+import Haskus.Utils.Flow++-- | A pointer in memory+data Pointer (mut :: Mutability) (fin :: Finalization) where+   PtrI  :: {-# UNPACK #-} !RawPtr                        -> PtrI+   PtrM  :: {-# UNPACK #-} !RawPtr                        -> PtrM+   PtrIF :: {-# UNPACK #-} !FinPtr -> {-# UNPACK #-} !Int -> PtrIF+   PtrMF :: {-# UNPACK #-} !FinPtr -> {-# UNPACK #-} !Int -> PtrMF++type RawPtr = P.Ptr ()+type FinPtr = FP.ForeignPtr ()++type PtrI   = Pointer 'Immutable 'NotFinalized+type PtrM   = Pointer 'Mutable   'NotFinalized+type PtrIF  = Pointer 'Immutable 'Finalized+type PtrMF  = Pointer 'Mutable   'Finalized++-- | Wrapper containing any kind of buffer+newtype AnyPointer = AnyPointer (forall mut fin . Pointer mut fin)++instance Show (Pointer mut fin) where+   show = \case+      PtrI p    -> show p+      PtrM p    -> show p+      PtrIF p o -> show (fToR p `P.plusPtr` o)+      PtrMF p o -> show (fToR p `P.plusPtr` o)++-- | Unsafe Finalized to Raw pointer+fToR :: FinPtr -> RawPtr+fToR = FP.unsafeForeignPtrToPtr++-- | Test if a pointer is Null+{-# SPECIALIZE INLINE isNullPtr :: PtrI  -> Bool #-}+{-# SPECIALIZE INLINE isNullPtr :: PtrM  -> Bool #-}+{-# SPECIALIZE INLINE isNullPtr :: PtrIF -> Bool #-}+{-# SPECIALIZE INLINE isNullPtr :: PtrMF -> Bool #-}+isNullPtr :: Pointer mut fin -> Bool+isNullPtr = \case+   PtrI  p   -> p == P.nullPtr+   PtrM  p   -> p == P.nullPtr+   PtrIF p 0 -> fToR p == P.nullPtr+   PtrIF _ _ -> False+   PtrMF p 0 -> fToR p == P.nullPtr+   PtrMF _ _ -> False++-- | Null pointer+nullPtrI :: PtrI+nullPtrI = PtrI P.nullPtr++-- | Null pointer+nullPtrM :: PtrM+nullPtrM = PtrM P.nullPtr++-- | Index a pointer+{-# SPECIALIZE INLINE indexPtr :: PtrI  -> Int -> PtrI  #-}+{-# SPECIALIZE INLINE indexPtr :: PtrM  -> Int -> PtrM  #-}+{-# SPECIALIZE INLINE indexPtr :: PtrIF -> Int -> PtrIF #-}+{-# SPECIALIZE INLINE indexPtr :: PtrMF -> Int -> PtrMF #-}+indexPtr :: Pointer mut fin -> Int -> Pointer mut fin+indexPtr ptr i = case ptr of+   PtrI  p   -> PtrI (p `P.plusPtr` i)+   PtrM  p   -> PtrM (p `P.plusPtr` i)+   PtrIF p o -> PtrIF p (o+i)+   PtrMF p o -> PtrMF p (o+i)++-- | Distance between two pointers+{-# SPECIALIZE INLINE distancePtr :: PtrI  -> PtrI -> Int  #-}+{-# SPECIALIZE INLINE distancePtr :: PtrM  -> PtrM -> Int  #-}+{-# SPECIALIZE INLINE distancePtr :: PtrI  -> PtrM -> Int  #-}+{-# SPECIALIZE INLINE distancePtr :: PtrM  -> PtrI -> Int  #-}+distancePtr :: Pointer mut0 fin0 -> Pointer mut1 fin1 -> Int+distancePtr p1 p2 = P.minusPtr p1' p2' + o2 - o1+   where+      dec :: Pointer mut fin -> (RawPtr,Int)+      dec = \case+         PtrI p    -> (p,0)+         PtrM p    -> (p,0)+         PtrIF p o -> (fToR p,o)+         PtrMF p o -> (fToR p,o)+      (p1',o1) = dec p1+      (p2',o2) = dec p2++-- | Use a finalized pointer as a non finalized pointer+{-# INLINABLE withFinalizedPtr #-}+withFinalizedPtr :: (MonadInIO m) => Pointer mut 'Finalized -> (Pointer mut 'NotFinalized -> m b) -> m b+withFinalizedPtr ptr f = case ptr of+   PtrIF p o -> liftWith (FP.withForeignPtr p) <| \r ->+                  f (PtrI (r `P.plusPtr` o))+   PtrMF p o -> liftWith (FP.withForeignPtr p) <| \r ->+                  f (PtrM (r `P.plusPtr` o))++-- | Use a pointer (finalized or not) as a non finalized pointer+{-# INLINABLE withPtr #-}+withPtr :: (MonadInIO m) => Pointer mut fin -> (Pointer mut 'NotFinalized -> m b) -> m b+withPtr ptr f = case ptr of+   PtrI _    -> f ptr+   PtrM _    -> f ptr+   PtrIF p o -> liftWith (FP.withForeignPtr p) <| \r ->+                  f (PtrI (r `P.plusPtr` o))+   PtrMF p o -> liftWith (FP.withForeignPtr p) <| \r ->+                  f (PtrM (r `P.plusPtr` o))++-- | Alloc mutable finalized memory+allocFinalizedPtr :: MonadIO m => Word -> m PtrMF+allocFinalizedPtr = liftIO . fmap (`PtrMF` 0) . FP.mallocForeignPtrBytes . fromIntegral++-- | Alloc mutable non-finalized memory+allocPtr :: MonadIO m => Word -> m PtrM+allocPtr = liftIO . fmap PtrM . P.mallocBytes . fromIntegral+++-- | Free a non-finalized memory+{-# SPECIALIZE INLINE freePtr :: MonadIO m => PtrI -> m () #-}+{-# SPECIALIZE INLINE freePtr :: MonadIO m => PtrM -> m () #-}+freePtr :: MonadIO m => Pointer mut 'NotFinalized -> m ()+freePtr = \case+   PtrI p -> liftIO (P.free p)+   PtrM p -> liftIO (P.free p)
+ src/lib/Haskus/Memory/Typed.hs view
@@ -0,0 +1,26 @@+{-# LANGUAGE PolyKinds #-}+{-# LANGUAGE KindSignatures #-}++-- | Typed memory+--+-- Pointer-like datatypes with an additional phantom type indicating their+-- memory layout+module Haskus.Memory.Typed+   ( BufferT (..)+   , PointerT (..)+   , PtrT (..)+   )+where++import Haskus.Memory.Buffer+import Haskus.Memory.Ptr+import GHC.Exts++-- | Typed pointer +newtype PointerT (t :: k) mut fin = PointerT (Pointer mut fin)++-- | Typed buffer+newtype BufferT (t :: k) mut pin fin heap = BufferT (Buffer mut pin fin heap)++-- | Typed raw pointer+newtype PtrT (t :: k) = PtrT (Ptr ())
+ src/lib/Haskus/Memory/Utils.hs view
@@ -0,0 +1,80 @@+{-# LANGUAGE ForeignFunctionInterface #-}+{-# LANGUAGE UnliftedFFITypes #-}+{-# LANGUAGE MagicHash #-}+{-# LANGUAGE BangPatterns #-}++-- | Memory utilities+module Haskus.Memory.Utils+   ( memCopy+   , memSet+   , allocaArrays+   , peekArrays+   , pokeArrays+   , withArrays+   , withMaybeOrNull+   , memcpy#+   )+where++import Haskus.Number.Word+import Haskus.Binary.Storable+import Haskus.Utils.Flow++import Foreign.Ptr+import GHC.Exts++-- | Copy memory+memCopy :: MonadIO m => Ptr a -> Ptr b -> Word64 -> m ()+{-# INLINABLE memCopy #-}+memCopy (Ptr dest) (Ptr src) size = liftIO (memcpy# dest src s)+   where+      !(I# s) = fromIntegral size++-- | memcpy+foreign import ccall unsafe "memcpy" memcpy# :: Addr# -> Addr# -> Int# -> IO ()++++-- | Set memory+memSet :: MonadIO m => Ptr a -> Word64 -> Word8 -> m ()+{-# INLINABLE memSet #-}+memSet dest size fill = liftIO (void (memset dest fill size))++-- | memset+foreign import ccall unsafe memset  :: Ptr a -> Word8 -> Word64 -> IO (Ptr c)+++-- | Allocate several arrays+allocaArrays :: (MonadInIO m, Storable s, Integral a) => [a] -> ([Ptr s] -> m b) -> m b+allocaArrays sizes f = go [] sizes+   where+      go as []     = f (reverse as)+      go as (x:xs) = allocaArray (fromIntegral x) $ \a -> go (a:as) xs++-- | Peek several arrays+peekArrays :: (MonadIO m, Storable s, Integral a) => [a] -> [Ptr s] -> m [[s]]+peekArrays szs ptrs = mapM f (szs `zip` ptrs)+   where+      f (sz,p) = peekArray (fromIntegral sz) p++-- | Poke several arrays+pokeArrays :: (MonadIO m, Storable s) => [Ptr s] -> [[s]] -> m ()+pokeArrays ptrs vs = mapM_ f (ptrs `zip` vs)+   where+      f = uncurry pokeArray++-- | Allocate several arrays+withArrays :: (MonadInIO m, Storable s) => [[s]] -> ([Ptr s] -> m b) -> m b+withArrays vs f = go [] vs+   where+      go as []     = f (reverse as)+      go as (x:xs) = withArray x $ \a -> go (a:as) xs++-- | Execute f with a pointer to 'a' or NULL+withMaybeOrNull ::+   ( Storable a+   , MonadInIO m+   ) => Maybe a -> (Ptr a -> m b) -> m b+withMaybeOrNull s f = case s of+   Nothing -> f nullPtr+   Just x  -> with x f
src/lib/Haskus/Memory/View.hs view
@@ -69,7 +69,7 @@ import Control.Concurrent  import Haskus.Utils.Monad-import Haskus.Format.Binary.Word+import Haskus.Number.Word import Haskus.Memory.Buffer  -- | The source of a view
+ src/lib/Haskus/Number.hs view
@@ -0,0 +1,8 @@+-- | Numbers+module Haskus.Number+   ( module X+   )+where++import Haskus.Number.BitNat as X+import Haskus.Number.NaturalRange as X
+ src/lib/Haskus/Number/BitNat.hs view
@@ -0,0 +1,389 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE KindSignatures #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE ViewPatterns #-}+{-# LANGUAGE StandaloneDeriving #-}+{-# LANGUAGE PolyKinds #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE PatternSynonyms #-}+{-# LANGUAGE AllowAmbiguousTypes #-}++-- | Natural numbers+module Haskus.Number.BitNat+   ( NatVal (..)+   , Widen+   , widen+   , Narrow+   , narrow+   , IsBitNat+   , BitNat+   , pattern BitNat+   , unsafeMakeBitNat+   , safeMakeBitNat+   , bitNat+   , bitNatZero+   , bitNatOne+   , extractW+   , compareW+   , (.+.)+   , (.-.)+   , (.*.)+   , (./.)+   , BitNatShiftLeft+   , BitNatShiftRight+   , (.<<.)+   , (.>>.)+   , bitNatTestBit+   , bitNatXor+   , bitNatAnd+   , bitNatOr+   -- * Internal+   , BitNatWord+   , MakeBitNat+   , bitNatToNatural+   )+where++import Haskus.Number.Word+import Haskus.Binary.Bits+import Haskus.Utils.Types+import Numeric.Natural++-- $setup+-- >>> :set -XDataKinds+-- >>> :set -XTypeApplications+-- >>> :set -XFlexibleContexts+-- >>> :set -XTypeFamilies+-- >>> :set -XScopedTypeVariables++-- | A natural on `b` bits+newtype BitNat (b :: Nat)+   = BitNat' (BitNatWord b)++pattern BitNat :: forall (n :: Nat). (Integral (BitNatWord n), MakeBitNat n) => Natural -> BitNat n+{-# COMPLETE BitNat #-}+pattern BitNat x <- (bitNatToNatural -> x)+   where+      BitNat x = makeW @n x+++-- | Create a natural number with the minimal number of bits required to store+-- it+--+-- >>> bitNat @5+-- BitNat @3 5+--+-- >>> bitNat @0+-- BitNat @1 0+--+-- >>> bitNat @158748521123465897456465+-- BitNat @78 158748521123465897456465+--+bitNat :: forall (v :: Nat) (n :: Nat).+   ( n ~ NatBitCount v+   , Integral (BitNatWord n)+   , MakeBitNat n+   , KnownNat v+   ) => BitNat n+bitNat = BitNat @n (natValue @v)++mapW :: (BitNatWord a -> BitNatWord a) -> BitNat a -> BitNat a+mapW f (BitNat' x) = BitNat' (f x)++zipWithW :: (BitNatWord a -> BitNatWord a -> BitNatWord b) -> BitNat a -> BitNat a -> BitNat b+zipWithW f (BitNat' x) (BitNat' y) = BitNat' (f x y)++-- | Show instance for BitNat+instance (KnownNat b, Integral (BitNatWord b)) => Show (BitNat b) where+   showsPrec d x = showParen (d /= 0)+      $ showString "BitNat @"+      . showsPrec 0 (natValue' @b)+      . showString " "+      . showsPrec 0 (bitNatToNatural x)++-- | BitNat backing type+type family BitNatWord b where+   BitNatWord 0 = TypeError ('Text "Naturals encoded on 0 bits are not allowed")+   BitNatWord b = BitNatWord' (b <=? 8) (b <=? 16) (b <=? 32) (b <=? 64)++type family BitNatWord' b8 b16 b32 b64 where+   BitNatWord' 'True _ _ _ = Word8+   BitNatWord' _ 'True _ _ = Word16+   BitNatWord' _ _ 'True _ = Word32+   BitNatWord' _ _ _ 'True = Word64+   BitNatWord' _ _ _ _     = Natural++-------------------------------------------------+-- Creation+-------------------------------------------------++type IsBitNat b =+   ( Num (BitNatWord b)+   , Integral (BitNatWord b)+   , Bitwise (BitNatWord b)+   , IndexableBits (BitNatWord b)+   )++-- | Zero natural+bitNatZero :: Num (BitNatWord a) => BitNat a+bitNatZero = BitNat' 0++-- | One natural+bitNatOne :: Num (BitNatWord a) => BitNat a+bitNatOne = BitNat' 1++-- | Convert a BitNat into a Natural+bitNatToNatural :: Integral (BitNatWord a) => BitNat a -> Natural+bitNatToNatural (BitNat' x) = fromIntegral x++-- | Create a natural+unsafeMakeBitNat :: forall a. (Maskable a (BitNatWord a)) => BitNatWord a -> BitNat a+unsafeMakeBitNat x = BitNat' (mask @a x)++type MakeBitNat a =+   ( Maskable a (BitNatWord a)+   , ShiftableBits (BitNatWord a)+   , Show (BitNatWord a)+   , Eq (BitNatWord a)+   , Num (BitNatWord a)+   )++-- | Create a natural (check overflow)+safeMakeBitNat :: forall a. MakeBitNat a => Natural -> Maybe (BitNat a)+safeMakeBitNat x =+   let+      x' = fromIntegral x :: BitNatWord a+   in case x' `uncheckedShiftR` natValue' @a of+      0 -> Just (unsafeMakeBitNat x')+      _ -> Nothing++-- | Create a natural (check overflow and throw on error)+makeW :: forall a. MakeBitNat a => Natural -> BitNat a+makeW x = case safeMakeBitNat x of+   Just y  -> y+   Nothing -> error $+               "`" ++ show x+               ++ "` is out of the range of values that can be encoded by a "+               ++ show (natValue' @a)+               ++ "-bit natural number: [0.."+               ++ show (2 ^ (natValue' @a) -1 :: Natural)+               ++ "]"++-- | Extract the primitive value+extractW :: BitNat a -> BitNatWord a+extractW (BitNat' a) = a++-------------------------------------------------+-- Widening / Narrowing+-------------------------------------------------++-- | Widen a natural+--+-- >>>  widen @7 (BitNat @5 25)+-- BitNat @7 25+--+widen :: forall b a. Widen a b => BitNat a -> BitNat b+widen (BitNat' a) = BitNat' (fromIntegral a)++type Widen a b =+   ( Assert (a <=? b) (() :: Constraint)+      ('Text "Can't widen a natural of "+       ':<>: 'ShowType a+       ':<>: 'Text " bits into a natural of "+       ':<>: 'ShowType b+       ':<>: 'Text " bits"+      )+   , Integral (BitNatWord a)+   , Integral (BitNatWord b)+   )++-- | Narrow a natural+--+-- >>> narrow @3 (BitNat @5 25)+-- BitNat @3 1+--+narrow :: forall b a. Narrow a b => BitNat a -> BitNat b+narrow (BitNat' a) = unsafeMakeBitNat (fromIntegral a)++type Narrow a b =+   ( Assert (b <=? a) (() :: Constraint)+      ('Text "Can't narrow a natural of "+       ':<>: 'ShowType a+       ':<>: 'Text " bits into a natural of "+       ':<>: 'ShowType b+       ':<>: 'Text " bits"+      )+   , Integral (BitNatWord a)+   , Integral (BitNatWord b)+   , Maskable b (BitNatWord b)+   )+   +-------------------------------------------------+-- Comparison+-------------------------------------------------++-- | Compare two naturals+compareW :: forall a b.+   ( Ord (BitNatWord (Max a b))+   , Widen a (Max a b)+   , Widen b (Max a b)+   ) => BitNat a -> BitNat b -> Ordering+compareW x y = compare x' y'+   where+      BitNat' x' = widen @(Max a b) x+      BitNat' y' = widen @(Max a b) y++instance Eq (BitNatWord a) => Eq (BitNat a) where+   (BitNat' x) == (BitNat' y) = x == y++instance Ord (BitNatWord a) => Ord (BitNat a) where+   compare (BitNat' x) (BitNat' y) = compare x y++-------------------------------------------------+-- Addition / Subtraction+-------------------------------------------------++-- | Add two Naturals+--+-- >>> BitNat @5 25 .+. BitNat @2 3+-- BitNat @6 28+--+(.+.) :: forall a b m.+   ( m ~ (Max a b + 1)+   , Widen a m+   , Widen b m+   , Num (BitNatWord m)+   ) => BitNat a -> BitNat b -> BitNat m+(.+.) x y = zipWithW (+) (widen @m x) (widen @m y)++-- | Sub two Naturals+--+-- >>> BitNat @5 25 .-. BitNat @2 3+-- Just (BitNat @5 22)+--+-- >>> BitNat @5 2 .-. BitNat @2 3+-- Nothing+--+(.-.) :: forall a b m.+   ( m ~ Max a b+   , Widen a m+   , Widen b m+   , Num (BitNatWord m)+   ) => BitNat a -> BitNat b -> Maybe (BitNat m)+(.-.) (widen @m -> x) (widen @m -> y) = case compare x y of+   LT -> Nothing+   EQ -> Just bitNatZero+   GT -> Just (zipWithW (-) x y)++-- | Multiply two Naturals+--+-- >>> BitNat @5 25 .*. BitNat @2 3+-- BitNat @7 75+--+(.*.) :: forall a b m.+   ( m ~ (a + b)+   , Widen a m+   , Widen b m+   , Num (BitNatWord m)+   ) => BitNat a -> BitNat b -> BitNat m+(.*.) x y = zipWithW (*) (widen @m x) (widen @m y)++-- | Divide two Naturals, return (factor,rest)+--+-- >>> BitNat @5 25 ./. BitNat @2 3+-- Just (BitNat @5 8,BitNat @2 1)+--+-- >>> BitNat @5 25 ./. BitNat @2 0+-- Nothing+--+-- > BitNat @2 3 ./. BitNat @5 25+-- Just (BitNat @2 0,BitNat @5 3)+--+(./.) :: forall a b m.+   ( m ~ Max a b+   , Widen a m+   , Widen b m+   , Num (BitNatWord (Min a b))+   ) => BitNat a -> BitNat b -> Maybe (BitNat a,BitNat (Min a b))+(./.) x y+   | y == bitNatZero = Nothing+   | otherwise  = Just (BitNat' (fromIntegral q), BitNat' (fromIntegral r))+   where+      (q,r) = quotRem x' y'+      BitNat' x' = widen @m x+      BitNat' y' = widen @m y++-------------------------------------------------+-- Shift+-------------------------------------------------++type BitNatShiftRight a s =+   ( ShiftableBits (BitNatWord a)+   , KnownNat s+   , Narrow a (a-s)+   )++type BitNatShiftLeft a s =+   ( ShiftableBits (BitNatWord (a+s))+   , KnownNat s+   , Widen a (a+s)+   )++-- | Shift-left naturals+--+-- >>> let x = BitNat @5 25+-- >>> x .<<. NatVal @2+-- BitNat @7 100+--+-- >>> show (x .<<. NatVal @2) == show (x .*. BitNat @3 4)+-- False+--+-- >>> x .<<. NatVal @2 == narrow (x .*. BitNat @3 4)+-- True+--+(.<<.) :: forall (s :: Nat) a.+   ( BitNatShiftLeft a s+   ) => BitNat a -> NatVal s -> BitNat (a + s)+(.<<.) x _ = mapW (`uncheckedShiftL` natValue @s) (widen @(a+s) x)++-- | Shift-right naturals+--+-- >>> BitNat @5 25 .>>. NatVal @2+-- BitNat @3 6+--+(.>>.) :: forall (s :: Nat) a.+   ( BitNatShiftRight a s+   ) => BitNat a -> NatVal s -> BitNat (a - s)+(.>>.) x _ = narrow @(a-s) (mapW (`uncheckedShiftR` natValue @s) x)+++-- | Test a bit+bitNatTestBit ::+   ( IndexableBits (BitNatWord a)+   ) => BitNat a -> Word -> Bool+bitNatTestBit (BitNat' b) i = testBit b i++-- | Xor+bitNatXor :: forall a.+   ( IsBitNat a+   ) => BitNat a -> BitNat a -> BitNat a+bitNatXor (BitNat' a) (BitNat' b) = BitNat' (a `xor` b)++-- | And+bitNatAnd :: forall a.+   ( IsBitNat a+   ) => BitNat a -> BitNat a -> BitNat a+bitNatAnd (BitNat' a) (BitNat' b) = BitNat' (a .&. b)++-- | Or+bitNatOr :: forall a.+   ( IsBitNat a+   ) => BitNat a -> BitNat a -> BitNat a+bitNatOr (BitNat' a) (BitNat' b) = BitNat' (a .|. b)
+ src/lib/Haskus/Number/FixedPoint.hs view
@@ -0,0 +1,148 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE KindSignatures #-}+{-# LANGUAGE StandaloneDeriving #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE ExistentialQuantification #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE UndecidableInstances #-}++-- | Fixed-point numbers+module Haskus.Number.FixedPoint+   ( FixedPoint (..)+   , getFixedPointBase+   , fromFixedPointBase+   , toFixedPoint+   , fromFixedPoint+   )+where++import Haskus.Binary.BitField+import Haskus.Binary.Bits+import Haskus.Binary.Storable+import Haskus.Utils.Types+import Data.Coerce+import Data.Ratio++-- | Unsigned fixed-point number+-- * `w` is the backing type+-- * `i` is the number of bits for the integer part (before the radix point)+-- * `f` is the number of bits for the fractional part (after the radix point)+--+-- >>> :set -XDataKinds+-- >>> import Data.Word+-- >>> fromIntegral 0 :: FixedPoint Word32 16 16+-- 0 % 1+--+-- >>> fromIntegral 10 :: FixedPoint Word32 16 16+-- 10 % 1+newtype FixedPoint w (i :: Nat) (f :: Nat) = FixedPoint (BitFields w+   '[ BitField i "integer"    w+    , BitField f "fractional" w+    ])+   deriving (Storable)++-- | Get base value+getFixedPointBase :: FixedPoint w i f -> w+getFixedPointBase (FixedPoint (BitFields w)) = w++-- | Set base value+fromFixedPointBase :: forall w i f. w -> FixedPoint w i f+fromFixedPointBase w = FixedPoint @w @i @f (BitFields w)++instance+   ( BitSize w ~ (i + f)+   , Num w+   , FiniteBits w+   , Bits w+   , KnownNat i+   , KnownNat f+   , Field w+   , Integral w+   ) => Num (FixedPoint w i f) where+   (+)    = coerce ((+) :: w -> w -> w)+   (-)    = coerce ((-) :: w -> w -> w)+   negate = error "Can't negate unsigned fixed-point nubmer"+   abs    = id+   signum = error "Can't call signum on unsigned fixed-point number"+   (*)    = error "Fixed-point number multiplication not implemented yet"+   fromInteger x = toFixedPoint (toRational x)+++instance+   ( BitSize w ~ (i + f)+   , Integral w+   , FiniteBits w+   , Bits w+   , Field w+   , KnownNat i+   , KnownNat f+   ) => Real (FixedPoint w i f) where+   toRational fp = fromIntegral (getFixedPointBase fp) % (2^(natValue' @f))++deriving instance forall w n d.+   ( Integral w+   , Bits w+   , Field w+   , BitSize w ~ (n + d)+   , KnownNat n+   , KnownNat d+   ) => Eq (FixedPoint w n d)++instance forall w n d.+   ( Integral w+   , Bits w+   , Field w+   , BitSize w ~ (n + d)+   , KnownNat n+   , KnownNat d+   ) => Ord (FixedPoint w n d) where++   compare x y = compare (getFixedPointBase x) (getFixedPointBase y)+   x > y       = getFixedPointBase x >  getFixedPointBase y+   x >= y      = getFixedPointBase x >= getFixedPointBase y+   x < y       = getFixedPointBase x <  getFixedPointBase y+   x <= y      = getFixedPointBase x <= getFixedPointBase y++instance forall w n d.+   ( Integral w+   , Bits w+   , Field w+   , BitSize w ~ (n + d)+   , KnownNat n+   , KnownNat d+   , Show w+   ) => Show (FixedPoint w n d) where++   show w = show (toRational w)++-- | Convert to a fixed point value+toFixedPoint :: forall a w (n :: Nat) (d :: Nat).+   ( RealFrac a+   , BitSize w ~ (n + d)+   , KnownNat n+   , KnownNat d+   , Bits w+   , Field w+   , Num w+   , Integral w+   ) => a -> FixedPoint w n d+toFixedPoint a = FixedPoint $ BitFields (round (a * 2^natValue' @d))++-- | Convert from a fixed-point value+fromFixedPoint :: forall a w (n :: Nat) (d :: Nat).+   ( RealFrac a+   , BitSize w ~ (n + d)+   , KnownNat n+   , KnownNat d+   , Bits w+   , Field w+   , Num w+   , Integral w+   ) => FixedPoint w n d -> a+fromFixedPoint (FixedPoint bf) = w / 2^(natValue' @d)+   where+      w = fromIntegral (bitFieldsBits bf)
+ src/lib/Haskus/Number/Float.hs view
@@ -0,0 +1,58 @@+{-# LANGUAGE MagicHash #-}+{-# LANGUAGE UnboxedTuples #-}++-- | IEEE754 floating-point numbers+module Haskus.Number.Float+   ( Float32+   , Float64+   , float32ToWord32+   , float64ToWord64+   , word32ToFloat32+   , word64ToFloat64+   )+where++import Haskus.Number.Word+import GHC.Float+import GHC.ST+import GHC.Prim++type Float32 = Float+type Float64 = Double+++-- | Convert a Word32 into a Float32+word32ToFloat32 :: Word32 -> Float32+{-# INLINE word32ToFloat32 #-}+word32ToFloat32 (W32# x) = runST $ ST $ \s1 ->+   case newByteArray# 4# s1             of { (# s2, mbarr #) ->+   case writeWord32Array# mbarr 0# x s2 of { s3              ->+   case readFloatArray# mbarr 0# s3     of { (# s4, f #)     ->+      (# s4, F# f #) }}}++-- | Convert a Float32 into a Word32+float32ToWord32 :: Float32 -> Word32+{-# INLINE float32ToWord32 #-}+float32ToWord32 (F# x) = runST $ ST $ \s1 ->+   case newByteArray# 4# s1            of { (# s2, mbarr #) ->+   case writeFloatArray# mbarr 0# x s2 of { s3              ->+   case readWord32Array# mbarr 0# s3   of { (# s4, w #)     ->+      (# s4, W32# w #) }}}++-- | Convert a Word64 into a Float64+word64ToFloat64 :: Word64 -> Float64+{-# INLINE word64ToFloat64 #-}+word64ToFloat64 (W64# x) = runST $ ST $ \s1 ->+   case newByteArray# 8# s1             of { (# s2, mbarr #) ->+   case writeWord64Array# mbarr 0# x s2 of { s3              ->+   case readDoubleArray# mbarr 0# s3    of { (# s4, f #)     ->+      (# s4, D# f #) }}}++-- | Convert a Word64 into a Float64+float64ToWord64 :: Float64 -> Word64+{-# INLINE float64ToWord64 #-}+float64ToWord64 (D# x) = runST $ ST $ \s1 ->+   case newByteArray# 8# s1             of { (# s2, mbarr #) ->+   case writeDoubleArray# mbarr 0# x s2 of { s3              ->+   case readWord64Array# mbarr 0# s3    of { (# s4, w #)     ->+      (# s4, W64# w #) }}}
+ src/lib/Haskus/Number/Int.hs view
@@ -0,0 +1,48 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE KindSignatures #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE MagicHash #-}++-- | Signed primitive integers+module Haskus.Number.Int+   ( IntAtLeast+   , IntN+   -- * Unlifted+   , module GHC.Int+   , Int#+   , (+#)+   , (-#)+   , (==#)+   , (>#)+   , (<#)+   , (>=#)+   , (<=#)+   , isTrue#+   )+where++import Data.Int+import GHC.Int+import GHC.Exts++import Haskus.Utils.Types++-- | Return a Int with at least 'n' bits+type family IntAtLeast (n :: Nat) where+   IntAtLeast n =+       If (n <=? 8) Int8+      (If (n <=? 16) Int16+      (If (n <=? 32) Int32+      (Assert (n <=? 64) Int64+      ('Text "Cannot find Int with size " ':<>: 'ShowType n)+      )))++-- | Return a Int with exactly 'n' bits+type family IntN (n :: Nat) where+   IntN 8  = Int8+   IntN 16 = Int16+   IntN 32 = Int32+   IntN 64 = Int64+   IntN n  = TypeError ('Text "Cannot find Int with size " ':<>: 'ShowType n)
+ src/lib/Haskus/Number/NaturalRange.hs view
@@ -0,0 +1,195 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE KindSignatures #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE ViewPatterns #-}+{-# LANGUAGE StandaloneDeriving #-}+{-# LANGUAGE PolyKinds #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE PatternSynonyms #-}+{-# LANGUAGE AllowAmbiguousTypes #-}++-- | A natural number in a specified range (fixed and checked at compile-time)+module Haskus.Number.NaturalRange+   ( NatRange+   , pattern NatRange+   , natRange+   , safeMakeNatRange+   , makeNatRange+   , unsafeMakeNatRange+   , widenNatRange+   , (.++.)+   )+where++import Haskus.Number.BitNat+import Haskus.Utils.Types+import Numeric.Natural++-- $setup+-- >>> :set -XDataKinds+-- >>> :set -XTypeApplications+-- >>> :set -XFlexibleContexts+-- >>> :set -XTypeFamilies+-- >>> :set -XScopedTypeVariables+++-- | A natural number in the specified range+newtype NatRange (f :: Nat) (t :: Nat) = NatRange' (BitNat (NatBitCount (t-f+1)))++-- | Show instance for natural range+instance+   ( KnownNat (t-f)+   , KnownNat t+   , KnownNat f+   , Num (BitNatWord (NatBitCount (t-f+1)))+   , Integral (BitNatWord (NatBitCount (t-f+1)))+   ) => Show (NatRange f t) where+   showsPrec d x = showParen (d /= 0)+      $ showString "NatRange @"+      . showsPrec 0 (natValue' @f)+      . showString " @"+      . showsPrec 0 (natValue' @t)+      . showString " "+      . showsPrec 0 (toNaturalNatRange x)++type CheckInRange f t n =+   ( Assert (n <=? t) (() :: Constraint)+      ('ShowType n+       ':<>: 'Text " isn't in the range ["+       ':<>: 'ShowType f+       ':<>: 'Text ","+       ':<>: 'ShowType t+       ':<>: 'Text "]"+      )+   , Assert (f <=? n) (() :: Constraint)+      ('ShowType n+       ':<>: 'Text " isn't in the range ["+       ':<>: 'ShowType f+       ':<>: 'Text ","+       ':<>: 'ShowType t+       ':<>: 'Text "]"+      )+   )++type NatRangeBitCount f t = NatBitCount (t-f+1)++type MakeNatRange f t =+   ( Integral (BitNatWord (NatRangeBitCount f t))+   , MakeBitNat (NatRangeBitCount f t)+   , KnownNat f+   , KnownNat t+   , Assert (f <=? t) (() :: Constraint)+      ('Text "["+       ':<>: 'ShowType f+       ':<>: 'Text ","+       ':<>: 'ShowType t+       ':<>: 'Text "] isn't a valid range"+      )+   )++-- | Create a value in a Natural range+unsafeMakeNatRange :: forall f t.+   ( MakeNatRange f t+   ) => Natural -> NatRange f t+unsafeMakeNatRange v = NatRange' (BitNat @(NatRangeBitCount f t) (v - natValue @f))++-- | Create a value in a Natural range (check validity)+safeMakeNatRange :: forall f t.+   ( MakeNatRange f t+   ) => Natural -> Maybe (NatRange f t)+safeMakeNatRange v+   | v < natValue @f || v > natValue @t = Nothing+   | otherwise                          = Just (unsafeMakeNatRange @f @t v)++-- | Create a value in a Natural range (check validity and throw on error)+makeNatRange :: forall f t.+   ( MakeNatRange f t+   ) => Natural -> NatRange f t+makeNatRange v = case safeMakeNatRange @f @t v of+   Nothing ->error $ show v ++ " isn't in the range ["+               ++ show (natValue @f :: Natural)+               ++ ","+               ++ show (natValue @t :: Natural)+               ++ "]"+   Just x -> x+++-- | Create a value in a Natural range+natRange :: forall (n :: Nat) f t.+   ( MakeNatRange f t+   , CheckInRange f t n+   , KnownNat n+   ) => NatRange f t+natRange = unsafeMakeNatRange (natValue @n)++-- | Convert a NatRange into a Natural+toNaturalNatRange :: forall f t.+   ( KnownNat f+   , Integral (BitNatWord (NatBitCount (t-f+1)))+   ) => NatRange f t -> Natural+toNaturalNatRange (NatRange' x) = natValue @f + bitNatToNatural x++-- | Natural range pattern+--+-- >>> NatRange @10 @12 11+-- NatRange @10 @12 11+--+pattern NatRange :: forall (f :: Nat) (t :: Nat).+   ( MakeNatRange f t+   ) => Natural -> NatRange f t+{-# COMPLETE NatRange #-}+pattern NatRange x <- (toNaturalNatRange -> x)+   where+      NatRange x = makeNatRange @f @t x+++-------------------------------------------------+-- Widening+-------------------------------------------------++-- | Widen a natural+--+-- >>> let a = NatRange @18 @100 25+-- >>> widenNatRange @16 @200 a+-- NatRange @16 @200 25+--+widenNatRange :: forall f2 t2 f1 t1.+   ( WidenNatRange f1 t1 f2 t2+   ) => NatRange f1 t1 -> NatRange f2 t2+widenNatRange (NatRange a) = NatRange a++type WidenNatRange f1 t1 f2 t2 =+   ( Assert ((f2 <=? f1) `AndB` (t1 <=? t2)) (() :: Constraint)+      ('Text "Can't widen a natural range ["+       ':<>: 'ShowType f1+       ':<>: 'Text ","+       ':<>: 'ShowType t1+       ':<>: 'Text "] into range ["+       ':<>: 'ShowType f2+       ':<>: 'Text ","+       ':<>: 'ShowType t2+       ':<>: 'Text "]"+      )+   , MakeNatRange f1 t1+   , MakeNatRange f2 t2+   )++-- | Add two natural ranges+--+-- >>> NatRange @2 @4 3 .++. NatRange @7 @17 13+-- NatRange @9 @21 16+--+(.++.) ::+   ( MakeNatRange f1 t1+   , MakeNatRange f2 t2+   , MakeNatRange (f1+f2) (t1+t2)+   ) => NatRange f1 t1 -> NatRange f2 t2 -> NatRange (f1+f2) (t1+t2)+(.++.) (NatRange x) (NatRange y) = NatRange (x+y)+
+ src/lib/Haskus/Number/Posit.hs view
@@ -0,0 +1,423 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE KindSignatures #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE MultiWayIf #-}+{-# LANGUAGE AllowAmbiguousTypes #-}++-- | Posit (type III unum)+module Haskus.Number.Posit+   ( Posit (..)+   , PositKind (..)+   , PositK (..)+   , positKind+   , isZero+   , isInfinity+   , isPositive+   , isNegative+   , positAbs+   , PositEncoding (..)+   , PositFields (..)+   , positEncoding+   , positFields+   , positToRational+   , positFromRational+   , positApproxFactor+   , positDecimalError+   , positDecimalAccuracy+   , positBinaryError+   , positBinaryAccuracy+   , floatBinaryAccuracy+   )+where++import Haskus.Number.Int+import Haskus.Binary.Bits+import Haskus.Utils.Types+import Haskus.Utils.Tuple+import Haskus.Utils.Flow++import Data.Ratio+import qualified GHC.Real as Ratio++newtype Posit (nbits :: Nat) (es :: Nat) = Posit (IntN nbits)++-- | Show posit+instance+   ( Bits (IntN n)+   , FiniteBits (IntN n)+   , Ord (IntN n)+   , Num (IntN n)+   , KnownNat n+   , KnownNat es+   , Integral (IntN n)+   ) => Show (Posit n es)+   where+   show p = case positKind p of+      SomePosit Zero      -> "0"+      SomePosit Infinity  -> "Infinity"+      SomePosit (Value v) -> show (positToRational v)++data PositKind+   = ZeroK+   | InfinityK+   | NormalK+   deriving (Show,Eq)++-- | Kinded Posit+--+-- GADT that can be used to ensure at the type level that we deal with+-- non-infinite/non-zero Posit values+data PositK k nbits es where+   Zero     :: PositK 'ZeroK nbits es+   Infinity :: PositK 'InfinityK nbits es+   Value    :: Posit nbits es -> PositK 'NormalK nbits es++data SomePosit n es where+   SomePosit :: PositK k n es -> SomePosit n es++type PositValue n es = PositK 'NormalK n es++-- | Get the kind of the posit at the type level+positKind :: forall n es.+   ( Bits (IntN n)+   , KnownNat n+   , Eq (IntN n)+   ) => Posit n es -> SomePosit n es+positKind p+   | isZero p     = SomePosit Zero+   | isInfinity p = SomePosit Infinity+   | otherwise    = SomePosit (Value p)++-- | Check if a posit is zero+isZero :: forall n es.+   ( Bits (IntN n)+   , Eq (IntN n)+   , KnownNat n+   ) => Posit n es -> Bool+{-# INLINABLE isZero #-}+isZero (Posit i) = i == zeroBits++-- | Check if a posit is infinity+isInfinity :: forall n es.+   ( Bits (IntN n)+   , Eq (IntN n)+   , KnownNat n+   ) => Posit n es -> Bool+{-# INLINABLE isInfinity #-}+isInfinity (Posit i) = i == bit (natValue @n - 1)++-- | Check if a posit is positive+isPositive :: forall n es.+   ( Bits (IntN n)+   , Ord (IntN n)+   , KnownNat n+   ) => PositValue n es -> Bool+{-# INLINABLE isPositive #-}+isPositive (Value (Posit i)) = i > zeroBits++-- | Check if a posit is negative+isNegative :: forall n es.+   ( Bits (IntN n)+   , Ord (IntN n)+   , KnownNat n+   ) => PositValue n es -> Bool+{-# INLINABLE isNegative #-}+isNegative (Value (Posit i)) = i < zeroBits++-- | Posit absolute value+positAbs :: forall n es.+   ( Num (IntN n)+   , KnownNat n+   ) => PositValue n es -> PositValue n es+positAbs (Value (Posit i)) = Value (Posit (abs i))+++data PositFields = PositFields+   { positNegative         :: Bool+   , positRegimeBitCount   :: Word+   , positExponentBitCount :: Word+   , positFractionBitCount :: Word+   , positRegime           :: Int+   , positExponent         :: Word+   , positFraction         :: Word+   }+   deriving (Show)++data PositEncoding+   = PositInfinity+   | PositZero+   | PositEncoding PositFields+   deriving (Show)++positEncoding :: forall n es.+   ( Bits (IntN n)+   , Ord (IntN n)+   , Num (IntN n)+   , KnownNat n+   , KnownNat es+   , Integral (IntN n)+   ) => Posit n es -> PositEncoding+positEncoding p = case positKind p of+   SomePosit Zero        -> PositZero+   SomePosit Infinity    -> PositInfinity+   SomePosit v@(Value _) -> PositEncoding (positFields v)++-- | Decode posit fields+positFields :: forall n es.+   ( Bits (IntN n)+   , Ord (IntN n)+   , Num (IntN n)+   , KnownNat n+   , KnownNat es+   , Integral (IntN n)+   ) => PositValue n es -> PositFields+positFields p = PositFields+      { positNegative         = isNegative p+      , positRegimeBitCount   = rs+      , positExponentBitCount = es+      , positFractionBitCount = fs+      , positRegime           = regime+      , positExponent         = expo+      , positFraction         = frac+      }+   where+      -- get absolute value+      Value (Posit v) = positAbs p++      (negativeRegime,regimeLen) = +         if v `testBit` (natValue @n - 2)+            -- regime has shape 111...[0|end of word], subtract 1 for sign bit+            then (False, countLeadingZeros (complement v `clearBit` (natValue @n - 1)) - 1)+            -- regime has shape 00000...[1|end of word], subtract 1 for sign bit+            else (True, countLeadingZeros v - 1)++      regime = if negativeRegime+         then negate (fromIntegral regimeLen)+         else fromIntegral regimeLen - 1 -- we encode the 0 regime++      -- length of regime bits (with stop bit)+      rs = min (natValue @n - 1) (regimeLen + 1)++      -- real exponent size (regime bits can reduce the size of the exponent)+      es = min (natValue @n - rs - 1) (natValue @es)++      -- fraction size+      fs = natValue @n - es - rs - 1++      expo = fromIntegral (maskDyn es (v `shiftR` fs))+      frac = fromIntegral (maskDyn fs v)+++-- | Convert a Posit into a Rational+positToRational :: forall n es.+   ( KnownNat n+   , KnownNat es+   , Eq (IntN n)+   , Bits (IntN n)+   , Integral (IntN n)+   ) => Posit n es -> Rational+positToRational p+   | isZero p     = 0 Ratio.:% 1+   | isInfinity p = Ratio.infinity+   | otherwise    = (fromIntegral useed ^^ r) * (2 ^^ e) * (1 + (f % fd))+      where+         fields = positFields (Value p)+         r      = positRegime fields+         e      = positExponent fields+         f      = fromIntegral (positFraction fields)+         fd     = 1 `shiftL` positFractionBitCount fields+         useed  = 1 `shiftL` (1 `shiftL` natValue @es) :: Integer -- 2^(2^es)++-- | Convert a rational into the approximate Posit+positFromRational :: forall p n es.+   ( Posit n es ~ p+   , Num (IntN n)+   , Bits (IntN n)+   , KnownNat es+   , KnownNat n+   ) => Rational -> Posit n es+positFromRational x = if+      | x == 0              -> Posit 0+      | x == Ratio.infinity -> Posit (bit (natValue @n - 1))+      | otherwise           -> computeRegime+                              |> uncurry3 computeExponent+                              |> uncurry3 computeFraction+                              |> uncurry  computeRounding+                              |> computeSign+                              |> Posit+   where+      useed = fromIntegral (1 `shiftL` (1 `shiftL` es) :: Integer) -- 2^(2^es)++      nbits = natValue @n+      es    = natValue @es++      -- compute regime bits of the posit, return (y,p,i)+      --    y: remaining value to convert, in [1,useed) if there are enough available bits+      --    p: current posit bits+      --    i: number of set bits in p+      computeRegime+         | absx >= 1 = regime111 absx 1 2+         | otherwise = regime000 absx 1+         where+            absx = abs x++            -- push regime bits 111..1110+            regime111 y p i+               | y >= useed && i < nbits = regime111 (y / useed) ((p `uncheckedShiftL` 1) .|. 1) (i+1)+               | otherwise               = (y, p `uncheckedShiftL` 1, i+1)++            -- push regime bits 000..0001 (or 000...00010 if the full word+            -- (including the sign bit) is set)+            regime000 y i+               | y < 1 && i <= nbits = regime000 (y*useed) (i+1)+               | i >= nbits          = (y,2,nbits+1)+               | otherwise           = (y,1,i+1)++      -- compute exponent bits; return (y,p,i)+      --    y: remaining value to convert, in [1,2) if there are enough available bits+      --    p: current posit bits+      --    i: number of set bits in p+      computeExponent+            | es == 0   = (,,)+            | otherwise = go (1 `shiftL` (es - 1))+         where+            go e y p i+               | i > nbits || e == 0 = (y,p,i)+               | y >= pow2e          = go (e `uncheckedShiftR` 1) (y / pow2e) ((p `uncheckedShiftL` 1) .|. 1) (i+1)+               | otherwise           = go (e `uncheckedShiftR` 1) y            (p `uncheckedShiftL` 1)        (i+1)+               where+                  pow2e = fromIntegral (1 `shiftL` e :: Integer)++      -- compute fraction bits; return (y,p)+      --    y: remaining value to convert+      --    p: current posit bits+      computeFraction y' = go (y'-1) -- subtract hidden bit. Now y is in [0,1) if there are enough available bits+         where+            go y p i+               | i > nbits = (y,p)+               | y <= 0    = (y, p `shiftL` (nbits+1-i)) -- add remaining 0s fraction bits+               | y2 > 1    = go (y2-1) (p `shiftL` 1 + 1) (i+1)+               | otherwise = go y2     (p `shiftL` 1)     (i+1)+               where+                  y2 = 2*y++      -- at this stage, p contains an additional fraction bit.+      -- We remove it and we round accordingly.+      computeRounding y p =+         let p' = p `uncheckedShiftR` 1+         in if | not (p `testBit` 0) -> p'                                     -- closer to lower value+               | y == 1 || y == 0    -> p' + (if p' `testBit` 0 then 1 else 0) -- tie goes to nearest even+               | otherwise           -> p' + 1                                 -- closer to upper value+++      -- fixup the sign bit (and use 2's complement for the other bits)+      computeSign p+         | x < 0     = negate p+         | otherwise = p+++-- | Factor of approximation for a given Rational when encoded as a Posit.+-- The closer to 1, the better.+--+-- Usage:+--+--    positApproxFactor @(Posit 8 2) (52 % 137)+--+positApproxFactor :: forall p n es.+   ( Posit n es ~ p+   , Num (IntN n)+   , Bits (IntN n)+   , Integral (IntN n)+   , KnownNat es+   , KnownNat n+   ) => Rational -> Double+positApproxFactor r = fromRational ((positToRational (positFromRational r ::  p)) / r)++-- | Compute the decimal error if the given Rational is encoded as a Posit.+--+-- Usage:+--+--    positDecimalError @(Posit 8 2) (52 % 137)+--+positDecimalError :: forall p n es.+   ( Posit n es ~ p+   , Num (IntN n)+   , Bits (IntN n)+   , Integral (IntN n)+   , KnownNat es+   , KnownNat n+   ) => Rational -> Double+positDecimalError r = abs (logBase 10 (positApproxFactor @p r))++-- | Compute the number of decimals of accuracy if the given Rational is encoded+-- as a Posit.+--+-- Usage:+--+--    positDecimalAccuracy @(Posit 8 2) (52 % 137)+--+positDecimalAccuracy :: forall p n es.+   ( Posit n es ~ p+   , Num (IntN n)+   , Bits (IntN n)+   , Integral (IntN n)+   , KnownNat es+   , KnownNat n+   ) => Rational -> Double+positDecimalAccuracy r = -1 * logBase 10 (positDecimalError @p r)+++-- | Compute the binary error if the given Rational is encoded as a Posit.+--+-- Usage:+--+--    positBinaryError @(Posit 8 2) (52 % 137)+--+positBinaryError :: forall p n es.+   ( Posit n es ~ p+   , Num (IntN n)+   , Bits (IntN n)+   , Integral (IntN n)+   , KnownNat es+   , KnownNat n+   ) => Rational -> Double+positBinaryError r = abs (logBase 2 (positApproxFactor @p r))++-- | Compute the number of bits of accuracy if the given Rational is encoded+-- as a Posit.+--+-- Usage:+--+--    positBinaryAccuracy @(Posit 8 2) (52 % 137)+--+positBinaryAccuracy :: forall p n es.+   ( Posit n es ~ p+   , Num (IntN n)+   , Bits (IntN n)+   , Integral (IntN n)+   , KnownNat es+   , KnownNat n+   ) => Rational -> Double+positBinaryAccuracy r = -1 * logBase 2 (positBinaryError @p r)+++-- | Compute the number of bits of accuracy if the given Rational is encoded+-- as a Float/Double.+--+-- Usage:+--+--    floatBinaryAccuracy @Double (52 % 137)+--+floatBinaryAccuracy :: forall f.+   ( Fractional f+   , Real f+   ) => Rational -> Double+floatBinaryAccuracy r = -1 * logBase 2 floatError+   where+      floatApprox = fromRational (toRational (fromRational r :: f) / r)+      floatError  = abs (logBase 2 floatApprox)
+ src/lib/Haskus/Number/Signed.hs view
@@ -0,0 +1,166 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE KindSignatures #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE ConstraintKinds #-}++-- | Signed numbers+module Haskus.Number.Signed+   ( Signed (..)+   , SignedIsZero+   , signedIsZero+   , SignedFromBitNat+   , signedFromBitNat+   , SignedNegate+   , signedNegate+   , SignedPos+   , signedPos+   , SignedNeg+   , signedNeg+   )+where++import Haskus.Number.BitNat+import Haskus.Binary.Bits+import Haskus.Utils.Types++-- | A signed number (not in two-complement form)+--+-- * Bits: ddd..ddds where "s" is the sign bit+-- * Allows symetric positive and negative numbers+-- * Positive and negative zeros are zero+--+newtype Signed (b :: Nat)+   = Signed (BitNat (b+1))++-- | Show instance for Signed+instance+   ( KnownNat b+   , Integral (BitNatWord b)+   , IndexableBits (BitNatWord (b+1))+   , Num (BitNatWord (b+1))+   , Eq (BitNatWord (b+1))+   , Integral (BitNatWord (b+1))+   , ShiftableBits (BitNatWord (b+1))+   , Narrow (b+1) ((b+1)-1)+   ) => Show (Signed b)+   where+   showsPrec d x@(Signed b)+      | signedIsZero x = showString "0"+      | otherwise      =+            showParen (d /= 0)+            $ showString (if signedIsPositive x+                  then ""+                  else "-")+            . showsPrec 0 (bitNatToNatural (b .>>. NatVal @1))++type SignedPos b v =+   ( b ~ NatBitCount v+   , MakeBitNat b+   , KnownNat v+   , BitNatShiftLeft b 1+   )++-- | Positive signed literal+--+-- >>> signedPos @5+-- 5+-- >>> signedPos @0+-- 0+--+signedPos :: forall (v :: Nat) b.+   ( SignedPos b v+   ) => Signed b+signedPos = Signed @b (bitNat @v .<<. NatVal @1)+++type SignedNeg b v =+   ( SignedPos b v +   , SignedNegate b+   )++-- | Negative signed literal+--+-- >>> signedNeg @5+-- -5+-- >>> signedNeg @0+-- 0+--+signedNeg :: forall (v :: Nat) b.+   ( SignedNeg b v +   ) => Signed b+signedNeg = signedNegate (signedPos @v @b)+++type SignedIsZero b =+   ( BitNatShiftRight (b+1) 1+   )+++-- | Test for zero+--+-- >>> signedIsZero (signedNeg @5)+-- False+-- >>> signedIsZero (signedNeg @0)+-- True+--+signedIsZero :: forall b.+   ( SignedIsZero b+   ) => Signed b -> Bool+signedIsZero (Signed b) = (b .>>. NatVal @1 == bitNatZero)++type SignedIsPositive b =+   ( IndexableBits (BitNatWord (b+1))+   )++-- | Test if positive+--+-- >>> signedIsPositive (signedPos @5)+-- True+-- >>> signedIsPositive (signedPos @0)+-- True+-- >>> signedIsPositive (signedNeg @5)+-- False+--+signedIsPositive :: forall b.+   ( SignedIsPositive b+   ) => Signed b -> Bool+signedIsPositive (Signed b) = not (bitNatTestBit b 0)+++type SignedFromBitNat b =+   ( ShiftableBits (BitNatWord (b+1))+   , Widen b (b+1)+   )++-- | Create from a BitNat+--+-- >>> signedFromBitNat (bitNat @18)+-- 18+--+signedFromBitNat :: forall b.+   ( SignedFromBitNat b+   ) => BitNat b -> Signed b+signedFromBitNat b = Signed (b .<<. NatVal @1)+++type SignedNegate b =+   ( IsBitNat (b+1)+   )++-- | Negate a signed number+--+-- >>> signedNegate (signedPos @5)+-- -5+-- >>> signedNegate (signedNeg @5)+-- 5+--+signedNegate ::+   ( SignedNegate b+   ) => Signed b -> Signed b+signedNegate (Signed b)= Signed (b `bitNatXor` bitNatOne)
+ src/lib/Haskus/Number/SignedSafe.hs view
@@ -0,0 +1,162 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE KindSignatures #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE UndecidableInstances #-}++-- | Signed safe numbers+module Haskus.Number.SignedSafe+   ( Signed (..)+   , signedIsZero+   , signedIsNaN+   , signedFromBitNat+   , signedNegate+   , signedPos+   , signedNeg+   )+where++import Haskus.Number.BitNat+import Haskus.Binary.Bits+import Haskus.Utils.Types+import Prelude hiding (isNaN)++-- | A signed number (not in two-complement form)+--+-- * Bits: ddd..ddds where "s" is the sign bit+-- * Allows symetric positive and negative numbers+-- * Negative zero is NaN+--+newtype Signed (b :: Nat)+   = Signed (BitNat (b+1))++-- | Show instance for Signed+instance+   ( KnownNat b+   , Integral (BitNatWord b)+   , IndexableBits (BitNatWord (b+1))+   , Num (BitNatWord (b+1))+   , Eq (BitNatWord (b+1))+   , Integral (BitNatWord (b+1))+   , ShiftableBits (BitNatWord (b+1))+   , Narrow (b+1) ((b+1)-1)+   ) => Show (Signed b)+   where+   showsPrec d x@(Signed b)+      | signedIsNaN x = showString "NaN"+      | otherwise     =+            showParen (d /= 0)+            $ showString (if signedIsPositive x+                  then ""+                  else "-")+            . showsPrec 0 (bitNatToNatural (b .>>. NatVal @1))++-- | Positive signed literal+--+-- >>> signedPos @5+-- 5+-- >>> signedPos @0+-- 0+--+signedPos :: forall (v :: Nat) b.+   ( b ~ NatBitCount v+   , MakeBitNat b+   , Bitwise (BitNatWord b)+   , Integral (BitNatWord (b+1))+   , KnownNat v+   , ShiftableBits (BitNatWord (b+1))+   , Widen b (b+1)+   ) => Signed b+signedPos = Signed @b (bitNat @v .<<. NatVal @1)++-- | Negative signed literal+--+-- >>> signedNeg @5+-- -5+-- >>> signedNeg @0+-- 0+--+signedNeg :: forall (v :: Nat) b.+   ( b ~ NatBitCount v+   , MakeBitNat b+   , Bitwise (BitNatWord b)+   , KnownNat v+   , Widen b (b+1)+   , ShiftableBits (BitNatWord (b+1))+   , IsBitNat (b+1)+   ) => Signed b+signedNeg = if signedIsZero k then k else signedNegate k+   where+      k = signedPos @v @b+++-- | Test for zero+--+-- >>> signedIsZero (signedNeg @5)+-- False+-- >>> signedIsZero (signedNeg @0)+-- True+--+signedIsZero ::+   ( Num (BitNatWord (b+1))+   , Eq (BitNatWord (b+1))+   ) => Signed b -> Bool+signedIsZero (Signed b) = b == bitNatZero++-- | Test for NaN+--+-- >>> signedIsNaN (signedPos @5)+-- False+-- >>> signedIsNaN (signedPos @0)+-- False+--+signedIsNaN ::+   ( Num (BitNatWord (b+1))+   , Eq (BitNatWord (b+1))+   ) => Signed b -> Bool+signedIsNaN (Signed b) = b == bitNatOne++-- | Test if positive+--+-- >>> signedIsPositive (signedPos @5)+-- True+-- >>> signedIsPositive (signedPos @0)+-- True+-- >>> signedIsPositive (signedNeg @5)+-- False+--+signedIsPositive ::+   ( IndexableBits (BitNatWord (b+1))+   ) => Signed b -> Bool+signedIsPositive (Signed b) = not (bitNatTestBit b 0)+++-- | Create from a BitNat+--+-- >>> signedFromBitNat (bitNat @18)+-- 18+--+signedFromBitNat ::+   ( ShiftableBits (BitNatWord (b+1))+   , Widen b (b+1)+   ) => BitNat b -> Signed b+signedFromBitNat b = Signed (b .<<. NatVal @1)++-- | Negate a signed number+--+-- >>> signedNegate (signedPos @5)+-- -5+-- >>> signedNegate (signedNeg @5)+-- 5+--+signedNegate ::+   ( IsBitNat (b+1)+   ) => Signed b -> Signed b+signedNegate s+   | signedIsNaN s = s+   | otherwise     = case s of +      Signed b -> Signed (b `bitNatXor` bitNatOne)
+ src/lib/Haskus/Number/VariableLength.hs view
@@ -0,0 +1,123 @@+{-# LANGUAGE FlexibleContexts #-}++-- | Variable length encodings+--+-- * Unsigned Little Endian Base 128 (ULEB128)+--+-- The word is splitted in chunks of 7 bits, starting from least significant+-- bits. Each chunk is put in a Word8. The highest bit indicates if there is a+-- following byte (0 false, 1 true)+module Haskus.Number.VariableLength+   ( fromULEB128+   , toULEB128+   , getULEB128+   , putULEB128+   , getSLEB128+   , putSLEB128+   , getLEB128Buffer+   )+where++import Haskus.Number.Word+import Haskus.Number.Int+import Haskus.Binary.Get+import Haskus.Binary.Put+import Haskus.Binary.Bits+import Haskus.Binary.Bits.Put+import Haskus.Binary.Bits.Order+import Haskus.Binary.Buffer++-- | Convert a stream of ULEB 128 bytes into an Integral+--+-- >>> :set -XBinaryLiterals+-- >>> import Control.Monad.Trans.State+-- >>> getNext = do { ~(x:xs) <- get; put xs; pure x }+-- >>> let x = evalState (fromULEB128 getNext) [0b10000001, 0b01111111] :: Word64+-- >>> x == 0b11111110000001+-- True+fromULEB128 :: (Bits a, Monad m, Integral a) => m Word8 -> m a+fromULEB128 getW8 = go 0 0+   where+      go acc n = do+         a <- getW8+         let+            w    = fromIntegral (a .&. 0x7f)+            acc' = w `shiftL` n .|. acc+         if not (testBit a 7)+            then return acc'+            else go acc' (n+7)++-- | Convert an Integral into a stream of ULEB128 bytes+--+-- >>> :set -XBinaryLiterals+-- >>> :set -XFlexibleContexts+-- >>> let f = toULEB128 (putStr . (++ " ") . bitsToString)+-- >>> f (0b1001001010101010 :: Word64)+-- 10101010 10100101 00000010+toULEB128 :: (Bits a, Monad m, Integral a) => (Word8 -> m ()) -> a -> m ()+toULEB128 putW8 = goFirst+   where+      goFirst 0 = putW8 0+      goFirst n = go n++      go 0 = pure ()+      go x = do+         let+            r = x `shiftR` 7+            w = fromIntegral (x .&. 0x7f)+            w' = if r == 0 then w else setBit w 7+         putW8 w'+         go r++-- | Get an unsigned word in Little Endian Base 128+getULEB128 :: (Integral a, Bits a) => Get a+getULEB128 = fromULEB128 getWord8++-- | Put an unsigned word in Little Endian Base 128+putULEB128 :: (Integral a, Bits a) => a -> Put+putULEB128 = toULEB128 putWord8+++-- | Get a signed int in Little Endian Base 128+getSLEB128 :: (Integral a, Bits a) => Get a+getSLEB128 = do+   let toInt8 :: Word8 -> Int8+       toInt8 = fromIntegral+   a <- getWord8+   if not (testBit a 7)+      then return . fromIntegral . toInt8 $ (a .&. 0x7f) .|. ((a .&. 0x40) `shiftL` 1)+      else do+         b <- getSLEB128+         return $ (b `shiftL` 7) .|. (fromIntegral (a .&. 0x7f))++-- | Put a signed int in Little Endian Base 128+putSLEB128 :: (Integral a, Bits a) => a -> Put+putSLEB128 a = rec a+   where+      ext = if a >= 0 then 0 else complement 0+      rec x =  do+         let +            r = x `shiftR` 7+            w = x .&. 0x7f+         if r /= ext+            then do+               putWord8 (fromIntegral w .|. 0x80)+               rec r+            else if (testBit w 6 && a < 0) || (not (testBit w 6) && a >= 0)+               then putWord8 (fromIntegral w)   -- no need for sign byte+               else do+                  putWord8 (fromIntegral w .|. 0x80)+                  putWord8 (fromIntegral ext .&. 0x7f)   -- sign byte+++-- | Get a bytestring containing a decoded LEB128 string+getLEB128Buffer :: BitOrder -> Get Buffer+getLEB128Buffer bo = rec (newBitPutState bo)+   where+      rec state = do+         w      <- getWord8+         let state2 = putBits 7 w state+         case testBit w 7 of+            True  -> rec state2+            False -> return (getBitPutBuffer state2)+
+ src/lib/Haskus/Number/Word.hs view
@@ -0,0 +1,47 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE KindSignatures #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE MagicHash #-}++-- | Unsigned primitive words+module Haskus.Number.Word+   ( WordAtLeast+   , WordN+   -- * Unlifted+   , module GHC.Word+   , Word#+   , plusWord#+   , minusWord#+   , ltWord#+   , leWord#+   , gtWord#+   , geWord#+   , eqWord#+   )+where++import Data.Word+import GHC.Word+import GHC.Exts++import Haskus.Utils.Types++-- | Return a Word with at least 'n' bits+type family WordAtLeast (n :: Nat) where+   WordAtLeast n =+       If (n <=? 8) Word8+      (If (n <=? 16) Word16+      (If (n <=? 32) Word32+      (Assert (n <=? 64) Word64+      ('Text "Cannot find Word with size " ':<>: 'ShowType n)+      )))++-- | Return a Word with exactly 'n' bits+type family WordN (n :: Nat) where+   WordN 8  = Word8+   WordN 16 = Word16+   WordN 32 = Word32+   WordN 64 = Word64+   WordN n  = TypeError ('Text "Cannot find Word with size " ':<>: 'ShowType n)
− src/lib/Haskus/Utils/Memory.hs
@@ -1,72 +0,0 @@-{-# LANGUAGE ForeignFunctionInterface #-}---- | Memory utilities-module Haskus.Utils.Memory-   ( memCopy-   , memSet-   , allocaArrays-   , peekArrays-   , pokeArrays-   , withArrays-   , withMaybeOrNull-   )-where--import Haskus.Format.Binary.Word-import Haskus.Format.Binary.Ptr-import Haskus.Format.Binary.Storable-import Haskus.Utils.Flow---- | Copy memory-memCopy :: MonadIO m => Ptr a -> Ptr b -> Word64 -> m ()-{-# INLINABLE memCopy #-}-memCopy dest src size = liftIO (void (memcpy dest src size))---- | memcpy-foreign import ccall unsafe memcpy  :: Ptr a -> Ptr b -> Word64 -> IO (Ptr c)------ | Set memory-memSet :: MonadIO m => Ptr a -> Word64 -> Word8 -> m ()-{-# INLINABLE memSet #-}-memSet dest size fill = liftIO (void (memset dest fill size))---- | memset-foreign import ccall unsafe memset  :: Ptr a -> Word8 -> Word64 -> IO (Ptr c)----- | Allocate several arrays-allocaArrays :: (MonadInIO m, Storable s, Integral a) => [a] -> ([Ptr s] -> m b) -> m b-allocaArrays sizes f = go [] sizes-   where-      go as []     = f (reverse as)-      go as (x:xs) = allocaArray (fromIntegral x) $ \a -> go (a:as) xs---- | Peek several arrays-peekArrays :: (MonadIO m, Storable s, Integral a) => [a] -> [Ptr s] -> m [[s]]-peekArrays szs ptrs = mapM f (szs `zip` ptrs)-   where-      f (sz,p) = peekArray (fromIntegral sz) p---- | Poke several arrays-pokeArrays :: (MonadIO m, Storable s) => [Ptr s] -> [[s]] -> m ()-pokeArrays ptrs vs = mapM_ f (ptrs `zip` vs)-   where-      f = uncurry pokeArray---- | Allocate several arrays-withArrays :: (MonadInIO m, Storable s) => [[s]] -> ([Ptr s] -> m b) -> m b-withArrays vs f = go [] vs-   where-      go as []     = f (reverse as)-      go as (x:xs) = withArray x $ \a -> go (a:as) xs---- | Execute f with a pointer to 'a' or NULL-withMaybeOrNull ::-   ( Storable a-   , MonadInIO m-   ) => Maybe a -> (Ptr a -> m b) -> m b-withMaybeOrNull s f = case s of-   Nothing -> f nullPtr-   Just x  -> with x f
src/tests/Haskus/Tests/Common.hs view
@@ -13,7 +13,7 @@  import qualified Data.ByteString as BS -import Haskus.Format.Binary.Buffer+import Haskus.Binary.Buffer  -- | Ensure a function is bijective isBijective :: Eq a => (a -> a) -> a -> Bool
src/tests/Haskus/Tests/Format/Binary/Bits.hs view
@@ -14,17 +14,18 @@ import Haskus.Tests.Common import Haskus.Utils.Flow -import Haskus.Format.Binary.Bits.Put-import Haskus.Format.Binary.Bits.Get-import Haskus.Format.Binary.Bits.Order-import Haskus.Format.Binary.Bits.Reverse-import Haskus.Format.Binary.Bits+import Haskus.Binary.Bits.Put+import Haskus.Binary.Bits.Get+import Haskus.Binary.Bits.Order+import Haskus.Binary.Bits.Reverse+import Haskus.Binary.Bits -import Haskus.Format.Binary.Buffer-import Haskus.Format.Binary.Get-import Haskus.Format.Binary.Put-import Haskus.Format.Binary.VariableLength-import Haskus.Format.Binary.Word+import Haskus.Binary.Buffer+import Haskus.Binary.Get+import Haskus.Binary.Put+import Haskus.Number.VariableLength+import Haskus.Number.Word+import Haskus.Number.Int  testsBits :: TestTree testsBits = testGroup "Binary bits" $
src/tests/Haskus/Tests/Format/Binary/GetPut.hs view
@@ -8,8 +8,8 @@  import Haskus.Tests.Common -import Haskus.Format.Binary.Get-import Haskus.Format.Binary.Buffer+import Haskus.Binary.Get+import Haskus.Binary.Buffer  testsGetPut :: TestTree testsGetPut = testGroup "Get/Put" $
src/tests/Haskus/Tests/Format/Binary/Vector.hs view
@@ -14,9 +14,9 @@  import Haskus.Utils.Maybe import Haskus.Utils.HList-import Haskus.Format.Binary.Vector-import Haskus.Format.Binary.Word-import Haskus.Format.Binary.Bits+import Haskus.Binary.Vector+import Haskus.Number.Word+import Haskus.Binary.Bits  v1234 :: Vector 4 Word32 v1234 = fromJust $ fromList [1,2,3,4]