Safe Haskell | None |
---|---|
Language | Haskell2010 |
Data.Packed
Description
Packed data is data serialised into a binary format that is usable as-is, meaning there is no need to parse it to be able to use it. Another perk of such format is that it can be stored in files easily.
`packed-data` allows using packed data type-safely, without explicit pointer arithmetic.
Check out examples here: https://github.com/Arthi-chaud/packed-data/tree/main/examples
Example of a tree traversal:
{-# LANGUAGE DataKinds #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE KindSignatures #-} {-# LANGUAGE LambdaCase #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE LambdaCase #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE TemplateHaskellQuotes #-} {-# LANGUAGE TupleSections #-} {-# LANGUAGE QualifiedDo #-} {-# LANGUAGE ViewPatterns #-} {-# LANGUAGE PatternSynonyms #-} {-# LANGUAGE UnboxedTuples #-} import Data.Packed import Data.Packed.Reader import qualified Data.Packed.Reader as R data Tree a = Leaf a | Node (Tree a) (Tree a) $(mkPacked
''Tree []) myTree :: Tree Int myTree = Node (Leaf 1) (Leaf 2) packedTree ::Packed
'[Tree Int] packedTree =pack
myTree -- The two following functions do th same thing sumPacked1 ::PackedReader
'[Tree Int] r Int sumPacked1 = caseTree -- Generated ( R.do !n <-reader
R.return
n ) ( R.do !left <- sumPacked1 !right <- sumPacked1 let !res = left + right R.return
res ) -- The patternsPackedLead
andPackedNode
are generated sumPacked2 ::PackedReader
'[Tree Int] r Int sumPacked2 =mkPackedReader
$ case PackedLeaf l ->reader
with
l PackedNode n ->threadedWith
n $ R.do !left <- sumPacked2 !right <- sumPacked2 let !res = left + right R.return
res runSum :: Int runSum = fst $runReader
sumPacked1 packedTree
Synopsis
- class Packable a where
- write :: forall (r :: [Type]) (t :: [Type]). a -> NeedsWriter a r t
- pack :: Packable a => a -> Packed '[a]
- class Unpackable a where
- reader :: forall (r :: [Type]). PackedReader '[a] r a
- readerWithoutShift :: forall a (r :: [Type]). Unpackable a => PackedReader ('[] :: [Type]) (a ': r) a
- unpack :: forall a (r :: [Type]). Unpackable a => Packed (a ': r) -> (a, Packed r)
- unpack' :: forall a (r :: [Type]). Unpackable a => Packed (a ': r) -> a
- data Needs (p :: [Type]) (t :: [Type])
- runBuilder :: forall (p1 :: [Type]) (r :: [Type]). NeedsBuilder p1 r ('[] :: [Type]) r -> Packed r
- writeWithFieldSize :: forall a (r :: [Type]) (t :: [Type]). Packable a => a -> NeedsWriter' '[FieldSize, a] r t
- unsafeCastNeeds :: forall (a :: [Type]) (b :: [Type]) (c :: [Type]) (d :: [Type]). Needs a b %1 -> Needs c d
- data Packed (l :: [Type])
- skipWithFieldSize :: forall a (r :: [Type]). PackedReader '[FieldSize, a] r ()
- isolate :: forall a (r :: [Type]). PackedReader '[FieldSize, a] r (PackedFragment '[a])
- fromPacked :: forall (a :: [Type]). Packed a -> ByteString
- unsafeToPacked :: forall (a :: [Type]). ByteString -> Packed a
- unsafeCastPacked :: forall (a :: [Type]) (b :: [Type]). Packed a -> Packed b
- data PackedReader (p :: [Type]) (r :: [Type]) v
- mkPackedReader :: forall (p :: [Type]) (r :: [Type]) v. (PackedFragment (p :++: r) -> Identity (v, PackedFragment r)) -> PackedReader p r v
- runReader :: forall (p :: [Type]) (r :: [Type]) v. PackedReader p r v -> Packed (p :++: r) -> (v, Packed r)
- readerWithFieldSize :: forall a (r :: [Type]). Unpackable a => PackedReader '[FieldSize, a] r a
- mkPacked :: Name -> [PackingFlag] -> Q [Dec]
- data PackingFlag
- newtype FieldSize = FieldSize Int32
- getFieldSizeFromPacked :: Packed '[a] -> FieldSize
- class Skippable a where
- skip :: forall (r :: [Type]). PackedReader '[a] r ()
Classes
class Packable a where Source #
Typeclass for values that can be packed, i.e. written inside a Needs
Instances
Packable FieldSize Source # | |
Defined in Data.Packed.FieldSize | |
Storable a => Packable a Source # | |
Defined in Data.Packed.Packable |
class Unpackable a where Source #
An Unpackable
is a value that can be read (i.e. deserialised) from a Packed
value
Methods
reader :: forall (r :: [Type]). PackedReader '[a] r a Source #
The PackedReader
to unpack a value of that type
Instances
Unpackable FieldSize Source # | |
Defined in Data.Packed.FieldSize | |
Storable a => Unpackable a Source # | |
Defined in Data.Packed.Unpackable Methods reader :: forall (r :: [Type]). PackedReader '[a] r a Source # |
readerWithoutShift :: forall a (r :: [Type]). Unpackable a => PackedReader ('[] :: [Type]) (a ': r) a Source #
In a PackedReader
, reads a value without moving the cursor
unpack' :: forall a (r :: [Type]). Unpackable a => Packed (a ': r) -> a Source #
Same as unpack
, but throws away the unconsumed bytes
Needs
data Needs (p :: [Type]) (t :: [Type]) Source #
A buffer where packed values can be written
The order to write these values is defined by the l
type list
If p
is an empty list, then a value of type t
can be extracted from that buffer.
(See the signature of runReader
)
runBuilder :: forall (p1 :: [Type]) (r :: [Type]). NeedsBuilder p1 r ('[] :: [Type]) r -> Packed r Source #
Runs a NeedsBuilder
computation. Produces a Packed
writeWithFieldSize :: forall a (r :: [Type]) (t :: [Type]). Packable a => a -> NeedsWriter' '[FieldSize, a] r t Source #
unsafeCastNeeds :: forall (a :: [Type]) (b :: [Type]) (c :: [Type]) (d :: [Type]). Needs a b %1 -> Needs c d Source #
Casts a Needs
Packed
data Packed (l :: [Type]) Source #
A buffer that contains one or more packed (i.e. serialised) values.
The order of the values in the buffer is defined by the l
type list
skipWithFieldSize :: forall a (r :: [Type]). PackedReader '[FieldSize, a] r () Source #
Allows skipping over a field without having to unpack it
isolate :: forall a (r :: [Type]). PackedReader '[FieldSize, a] r (PackedFragment '[a]) Source #
Splits the Packed
value, and isolate the first encoded value.
fromPacked :: forall (a :: [Type]). Packed a -> ByteString Source #
Extracts the raw buffer from a Packed
value
unsafeToPacked :: forall (a :: [Type]). ByteString -> Packed a Source #
UNSAFE: Casts a generic ByteString
into a Needs
PackedReader
data PackedReader (p :: [Type]) (r :: [Type]) v Source #
Basically a function that reads/desrialises a value from a Packed
p
the types of the packed values to read
r
the packed type after the encoded values to read
v
the type of the value to unpack
Note: It is an indexed monad.
Instances
Functor (PackedReader p r) Source # | |
Defined in Data.Packed.Reader Methods fmap :: (a -> b) -> PackedReader p r a -> PackedReader p r b # (<$) :: a -> PackedReader p r b -> PackedReader p r a # |
mkPackedReader :: forall (p :: [Type]) (r :: [Type]) v. (PackedFragment (p :++: r) -> Identity (v, PackedFragment r)) -> PackedReader p r v Source #
Builds a PackedReader
runReader :: forall (p :: [Type]) (r :: [Type]) v. PackedReader p r v -> Packed (p :++: r) -> (v, Packed r) Source #
Run the reading function using a Packed
.
readerWithFieldSize :: forall a (r :: [Type]). Unpackable a => PackedReader '[FieldSize, a] r a Source #
Produces a reader for a value preceded by its FieldSize
Code generation
Arguments
:: Name | The name of the type to generate the functions for |
-> [PackingFlag] | Generation customisation flags |
-> Q [Dec] |
Generate the following for the given type
- A 'case' function (see
genCase
) - An instance of
Packable
(seegenPackableInstance
) - An instance of
Unpackable
(seegenUnpackableInstance
) - An instance of
Skippable
(seegenSkippableInstance
)
Example:
$(mkPacked
''Tree [InsertFieldSize
])
data PackingFlag Source #
Options for the generation process.
Beware: these options alter the signature and behaviour of the generated functions.
Constructors
InsertFieldSize | When specified, each field in a packed data constructor will be preceded by a Example As a consequence, for the following type, the caseTree :: ( |
SkipLastFieldSize | This flag should be used in complement to If set, no Example If this flag is set (along with caseTree :: ( |
Instances
Eq PackingFlag Source # | |
Defined in Data.Packed.TH.Flag |
Utils
Type representation for the size of a packed data. The size is in bytes.
Note: Take a look at the PackingFlag
s to understand how to use it
Instances
getFieldSizeFromPacked :: Packed '[a] -> FieldSize Source #
Returns the size of the packed value.
Warning: For this to be accurate, there should only be one value packed in the binary strea.