Data.Store.Core

store-core-0.4: Fast and lightweight binary serialization

Safe Haskell | None
Language | Haskell2010

Data.Store.Core

Contents

- Core Types
- Encode ByteString
- Decode ByteString
- Storable
- ForeignPtr
- ByteArray

Synopsis

- newtype Poke a = Poke {
  - runPoke :: PokeState -> Offset -> IO (Offset, a)
  }
- data PokeException = PokeException {
  - pokeExByteIndex :: Offset
  - pokeExMessage :: Text
  }
- pokeException :: Text -> Poke a
- newtype Peek a = Peek {
  - runPeek :: PeekState -> Ptr Word8 -> IO (PeekResult a)
  }
- data PeekResult a = PeekResult !(Ptr Word8) !a
- data PeekException = PeekException {
  - peekExBytesFromEnd :: Offset
  - peekExMessage :: Text
  }
- peekException :: Text -> Peek a
- tooManyBytes :: Int -> Int -> String -> IO void
- data PokeState
- pokeStatePtr :: PokeState -> Ptr Word8
- data PeekState
- peekStateEndPtr :: PeekState -> Ptr Word8
- type Offset = Int
- unsafeEncodeWith :: Poke () -> Int -> ByteString
- decodeWith :: Peek a -> ByteString -> Either PeekException a
- decodeExWith :: Peek a -> ByteString -> a
- decodeExPortionWith :: Peek a -> ByteString -> (Offset, a)
- decodeIOWith :: Peek a -> ByteString -> IO a
- decodeIOPortionWith :: Peek a -> ByteString -> IO (Offset, a)
- decodeIOWithFromPtr :: Peek a -> Ptr Word8 -> Int -> IO a
- decodeIOPortionWithFromPtr :: Peek a -> Ptr Word8 -> Int -> IO (Offset, a)
- pokeStorable :: Storable a => a -> Poke ()
- peekStorable :: forall a. (Storable a, Typeable a) => Peek a
- peekStorableTy :: forall a. Storable a => String -> Peek a
- pokeFromForeignPtr :: ForeignPtr a -> Int -> Int -> Poke ()
- peekToPlainForeignPtr :: String -> Int -> Peek (ForeignPtr a)
- pokeFromPtr :: Ptr a -> Int -> Int -> Poke ()
- pokeFromByteArray :: ByteArray# -> Int -> Int -> Poke ()
- peekToByteArray :: String -> Int -> Peek ByteArray

# Core Types

newtype Poke a #

`Poke` actions are useful for building sequential serializers.

They are actions which write values to bytes into memory specified by a `Ptr` base. The `Applicative` and `Monad` instances make it easy to write serializations, by keeping track of the `Offset` of the current byte. They allow you to chain `Poke` action such that subsequent `Poke`s write into subsequent portions of the output.

Constructors

Poke |
Fields runPoke :: PokeState -> Offset -> IO (Offset, a) Run the `Poke` action, with the `Ptr` to the buffer where data is poked, and the current `Offset`. The result is the new offset, along with a return value. May throw a `PokeException`, though this should be avoided when possible. They usually indicate a programming error.

Instances

Monad Poke # |
Methods (>>=) :: Poke a -> (a -> Poke b) -> Poke b # (>>) :: Poke a -> Poke b -> Poke b # return :: a -> Poke a # fail :: String -> Poke a #
Functor Poke # |
Methods fmap :: (a -> b) -> Poke a -> Poke b # (<$) :: a -> Poke b -> Poke a #
MonadFail Poke # |
Methods fail :: String -> Poke a #
Applicative Poke # |
Methods pure :: a -> Poke a # (<*>) :: Poke (a -> b) -> Poke a -> Poke b # (*>) :: Poke a -> Poke b -> Poke b # (<*) :: Poke a -> Poke b -> Poke a #
MonadIO Poke # |
Methods liftIO :: IO a -> Poke a #

data PokeException #

Exception thrown while running `poke`. Note that other types of exceptions could also be thrown. Invocations of `fail` in the `Poke` monad causes this exception to be thrown.

`PokeException`s are not expected to occur in ordinary circumstances, and usually indicate a programming error.

Constructors

PokeException |
Fields pokeExByteIndex :: Offset pokeExMessage :: Text

Instances

Eq PokeException # |
Methods (==) :: PokeException -> PokeException -> Bool # (/=) :: PokeException -> PokeException -> Bool #
Show PokeException # |
Methods showsPrec :: Int -> PokeException -> ShowS # show :: PokeException -> String # showList :: [PokeException] -> ShowS #
Exception PokeException # |
Methods toException :: PokeException -> SomeException # fromException :: SomeException -> Maybe PokeException # displayException :: PokeException -> String #

pokeException :: Text -> Poke a #

Throws a `PokeException`. These should be avoided when possible, they usually indicate a programming error.

newtype Peek a #

`Peek` actions are useful for building sequential deserializers.

They are actions which read from memory and construct values from it. The `Applicative` and `Monad` instances make it easy to chain these together to get more complicated deserializers. This machinery keeps track of the current `Ptr` and end-of-buffer `Ptr`.

Constructors

Peek |
Fields runPeek :: PeekState -> Ptr Word8 -> IO (PeekResult a) Run the `Peek` action, with a `Ptr` to the end of the buffer where data is poked, and a `Ptr` to the current position. The result is the `Ptr`, along with a return value. May throw a `PeekException` if the memory contains invalid values.

Instances

Monad Peek # |
Methods (>>=) :: Peek a -> (a -> Peek b) -> Peek b # (>>) :: Peek a -> Peek b -> Peek b # return :: a -> Peek a # fail :: String -> Peek a #
Functor Peek # |
Methods fmap :: (a -> b) -> Peek a -> Peek b # (<$) :: a -> Peek b -> Peek a #
MonadFail Peek # |
Methods fail :: String -> Peek a #
Applicative Peek # |
Methods pure :: a -> Peek a # (<*>) :: Peek (a -> b) -> Peek a -> Peek b # (*>) :: Peek a -> Peek b -> Peek b # (<*) :: Peek a -> Peek b -> Peek a #
MonadIO Peek # |
Methods liftIO :: IO a -> Peek a #
PrimMonad Peek # |
Associated Types type PrimState (Peek :: * -> *) :: * # Methods primitive :: (State# (PrimState Peek) -> (#VoidRep, PtrRepLifted, State# (PrimState Peek), a#)) -> Peek a #
type PrimState Peek # |
type PrimState Peek = RealWorld

data PeekResult a #

A result of a `Peek` action containing the current `Ptr` and a return value.

Constructors

PeekResult !(Ptr Word8) !a |

Instances

Functor PeekResult # |
Methods fmap :: (a -> b) -> PeekResult a -> PeekResult b # (<$) :: a -> PeekResult b -> PeekResult a #

data PeekException #

Exception thrown while running `peek`. Note that other types of exceptions can also be thrown. Invocations of `fail` in the `Poke` monad causes this exception to be thrown.

`PeekException` is thrown when the data being decoded is invalid.

Constructors

PeekException |
Fields peekExBytesFromEnd :: Offset peekExMessage :: Text

Instances

Eq PeekException # |
Methods (==) :: PeekException -> PeekException -> Bool # (/=) :: PeekException -> PeekException -> Bool #
Show PeekException # |
Methods showsPrec :: Int -> PeekException -> ShowS # show :: PeekException -> String # showList :: [PeekException] -> ShowS #
Exception PeekException # |
Methods toException :: PeekException -> SomeException # fromException :: SomeException -> Maybe PeekException # displayException :: PeekException -> String #

peekException :: Text -> Peek a #

Throws a `PeekException`.

tooManyBytes :: Int -> Int -> String -> IO void #

Throws a `PeekException` about an attempt to read too many bytes.

data PokeState #

Holds a `pokeStatePtr`, which is passed in to each `Poke` action. If the package is built with the 'force-alignment' flag, this also has a hidden `Ptr` field, which is used as scratch space during unaligned writes.

pokeStatePtr :: PokeState -> Ptr Word8 #

data PeekState #

Holds a `peekStatePtr`, which is passed in to each `Peek` action. If the package is built with the 'force-alignment' flag, this also has a hidden `Ptr` field, which is used as scratch space during unaligned reads.

peekStateEndPtr :: PeekState -> Ptr Word8 #

type Offset = Int #

How far into the given Ptr to look

# Encode ByteString

unsafeEncodeWith :: Poke () -> Int -> ByteString #

Given a `Poke` and its length, uses it to fill a `ByteString`

This function is unsafe because the provided length must exactly match the number of bytes used by the `Poke`. It will throw `PokeException` errors when the buffer is under or overshot. However, in the case of overshooting the buffer, memory corruption and segfaults may occur.

# Decode ByteString

decodeWith :: Peek a -> ByteString -> Either PeekException a #

Decodes a value from a `ByteString`, potentially throwing exceptions, and taking a `Peek` to run. It is an exception to not consume all input.

decodeExWith :: Peek a -> ByteString -> a #

Decodes a value from a `ByteString`, potentially throwing exceptions, and taking a `Peek` to run. It is an exception to not consume all input.

decodeExPortionWith :: Peek a -> ByteString -> (Offset, a) #

Similar to `decodeExWith`, but it allows there to be more of the buffer remaining. The `Offset` of the buffer contents immediately after the decoded value is returned.

decodeIOWith :: Peek a -> ByteString -> IO a #

Decodes a value from a `ByteString`, potentially throwing exceptions, and taking a `Peek` to run. It is an exception to not consume all input.

decodeIOPortionWith :: Peek a -> ByteString -> IO (Offset, a) #

Similar to `decodeExPortionWith`, but runs in the `IO` monad.

decodeIOWithFromPtr :: Peek a -> Ptr Word8 -> Int -> IO a #

Like `decodeIOWith`, but using `Ptr` and length instead of a `ByteString`.

decodeIOPortionWithFromPtr :: Peek a -> Ptr Word8 -> Int -> IO (Offset, a) #

Like `decodeIOPortionWith`, but using `Ptr` and length instead of a `ByteString`.

# Storable

pokeStorable :: Storable a => a -> Poke () #

A `poke` implementation based on an instance of `Storable`.

peekStorable :: forall a. (Storable a, Typeable a) => Peek a #

A `peek` implementation based on an instance of `Storable` and `Typeable`.

peekStorableTy :: forall a. Storable a => String -> Peek a #

A `peek` implementation based on an instance of `Storable`. Use this if the type is not `Typeable`.

# ForeignPtr

pokeFromForeignPtr :: ForeignPtr a -> Int -> Int -> Poke () #

Copy a section of memory, based on a `ForeignPtr`, to the output. Note that this operation is unsafe, the offset and length parameters are not checked.

peekToPlainForeignPtr :: String -> Int -> Peek (ForeignPtr a) #

Allocate a plain ForeignPtr (no finalizers), of the specified length and fill it with bytes from the input.

pokeFromPtr :: Ptr a -> Int -> Int -> Poke () #

Copy a section of memory, based on a `Ptr`, to the output. Note that this operation is unsafe, because the offset and length parameters are not checked.

# ByteArray

pokeFromByteArray :: ByteArray# -> Int -> Int -> Poke () #

Copy a section of memory, based on a `ByteArray#`, to the output. Note that this operation is unsafe, because the offset and length parameters are not checked.

peekToByteArray :: String -> Int -> Peek ByteArray #

Allocate a ByteArray of the specified length and fill it with bytes from the input.