@@ -12,12 +12,17 @@
12-- Portability : GHC
12-- Portability : GHC
14module Streamly.Internal.Data.Unbox
14module Streamly.Internal.Data.Unbox
16− , PinnedState(..)
16+ -- ** MutableByteArray
17− , MutableByteArray(..)
17+ MutableByteArray(..)
19 , getMutableByteArray#
18 , getMutableByteArray#
20 , sizeOfMutableByteArray
19 , sizeOfMutableByteArray
21 , isPinned
26 , isPinned
@@ -25,30 +30,29 @@ module Streamly.Internal.Data.Unbox
25 , newBytes
30 , newBytes
26 , pinnedNewBytes
31 , pinnedNewBytes
27 , pinnedNewAlignedBytes
32 , pinnedNewAlignedBytes
31− -- * Type Parser and Builder
34+ -- ** Unbox type class
32− , BoundedPtr (..)
35+ , Unbox(..)
37+ -- ** Peek and poke utilities
34 , Peeker (..)
40 , Peeker (..)
36 , readUnsafe
42 , readUnsafe
37 , skipByte
43 , skipByte
38 , runPeeker
44 , runPeeker
40 , pokeBoundedPtrUnsafe
46 , pokeBoundedPtrUnsafe
41 , pokeBoundedPtr
47 , pokeBoundedPtr
43− -- * Generic Unbox instances
49+ -- ** Generic Deriving
45− , genericPeekByteIndex
46− , genericPokeByteIndex
48− -- Classess used for generic deriving.
49 , PeekRep(..)
50 , PeekRep(..)
50 , PokeRep(..)
51 , PokeRep(..)
51 , SizeOfRep(..)
52 , SizeOfRep(..)
54+ , genericPeekByteIndex
55+ , genericPokeByteIndex
54#include "MachDeps.h"
58#include "MachDeps.h"
@@ -92,6 +96,10 @@ data PinnedState
92 | Unpinned
96 | Unpinned
94-- XXX can use UnliftedNewtypes
98-- XXX can use UnliftedNewtypes
100+-- | A lifted mutable byte array type wrapping @MutableByteArray# RealWorld@.
101+-- This is a low level array used to back high level unboxed arrays and
95data MutableByteArray = MutableByteArray (MutableByteArray# RealWorld)
103data MutableByteArray = MutableByteArray (MutableByteArray# RealWorld)
97{-# INLINE getMutableByteArray# #-}
105{-# INLINE getMutableByteArray# #-}
@@ -327,23 +335,37 @@ unpin arr@(MutableByteArray marr#) =
327-- size fields at each nesting level, aggregating the size upwards.
335-- size fields at each nesting level, aggregating the size upwards.
329-- | The 'Unbox' type class provides operations for serialization (unboxing)
337-- | The 'Unbox' type class provides operations for serialization (unboxing)
330−-- and deserialization (boxing) of a fixed-length, non-recursive Haskell data
338+-- and deserialization (boxing) of fixed-length, non-recursive Haskell data
331−-- type to and from its unboxed byte representation in a mutable byte array.
339+-- types to and from their byte stream representation.
332-- Unbox uses fixed size encoding, therefore, size is independent of the value,
341-- Unbox uses fixed size encoding, therefore, size is independent of the value,
333−-- it can be determined solely by the type. This makes types with 'Unbox'
342+-- it must be determined solely by the type. This restriction makes types with
334−-- instances suitable for storing in arrays. Note that sum types may have
343+-- 'Unbox' instances suitable for storing in arrays. Note that sum types may
335−-- multiple constructors of different sizes, the size of the sum type is
344+-- have multiple constructors of different sizes, the size of a sum type is
336-- computed as the maximum required by any constructor.
345-- computed as the maximum required by any constructor.
338−-- The 'peekByteIndex' read operation converts a Haskell type from its unboxed
347+-- The 'peekByteIndex' operation reads as many bytes from the mutable byte
339−-- representation stored in a mutable byte array, while the 'pokeByteIndex'
348+-- array as the @size@ of the data type and builds a Haskell data type from
340−-- write operation serializes a Haskell data type to its byte representation in
349+-- these bytes. 'pokeByteIndex' operation converts a Haskell data type to its
350+-- binary representation which consists of @size@ bytes and then stores
341−-- the mutable byte array. These operations do not check the bounds of the
351+-- these bytes into the mutable byte array. These operations do not check the
342−-- array, the user of the type class is expected to check the bounds before
352+-- bounds of the array, the user of the type class is expected to check the
343−-- peeking or poking.
353+-- bounds before peeking or poking.
355+-- IMPORTANT: The serialized data's byte ordering remains the same as the host
356+-- machine's byte order. Therefore, it can not be deserialized from host
357+-- machines with a different byte ordering.
345−-- Instances can be derived via Generics or Template Haskell. Note that the
359+-- Instances can be derived via Generics, Template Haskell, or written
346−-- data type must be non-recursive.
360+-- manually. Note that the data type must be non-recursive. WARNING! Generic
361+-- and Template Haskell deriving, both hang for recursive data types. Deriving
362+-- via Generics is more convenient but Template Haskell should be preferred
363+-- over Generics for the following reasons:
365+-- 1. Instances derived via Template Haskell provide better and more reliable
367+-- 2. Generic deriving allows only 256 fields or constructor tags whereas
368+-- template Haskell has no limit.
348-- Here is an example, for deriving an instance of this type class using
370-- Here is an example, for deriving an instance of this type class using
349-- generics:
371-- generics:
@@ -356,28 +378,20 @@ unpin arr@(MutableByteArray marr#) =
356-- } deriving Generic
378-- } deriving Generic
381+-- >>> import Streamly.Data.Serialize (Unbox(..))
382+-- >>> instance Unbox Object
359-- To derive the instance via Template Haskell:
384-- To derive the instance via Template Haskell:
362-- import Streamly.Data.Serialize (deriveUnbox)
387-- import Streamly.Data.Serialize (deriveUnbox)
363−-- $(deriveUnbox ''Object)
388+-- \$(deriveUnbox ''Object)
366-- See 'Streamly.Data.Serialize.deriveUnbox' and
391-- See 'Streamly.Data.Serialize.deriveUnbox' and
367-- 'Streamly.Data.Serialize.deriveUnboxWith' for more information on deriving
392-- 'Streamly.Data.Serialize.deriveUnboxWith' for more information on deriving
368-- using Template Haskell.
393-- using Template Haskell.
370−-- Deriving via Template Haskell should be preferred for the following reasons:
371−-- 1. Instances derived via Template Haskell have more performant routines.
372−-- 2. Template Haskell deriving can handle (maxBound :: Word64) number of
373−-- constructors whereas the Generic deriving can only handle 256.
375−-- WARNING! Generic and Template Haskell deriving, both hang for recursive data
378−-- >>> import Streamly.Data.Array (Unbox(..))
379−-- >>> instance Unbox Object
381-- If you want to write the instance manually:
395-- If you want to write the instance manually:
@@ -395,15 +409,15 @@ unpin arr@(MutableByteArray marr#) =
397class Unbox a where
411class Unbox a where
398− -- | Get the size. Size cannot be zero.
412+ -- | Get the size. Size cannot be zero, should be at least 1 byte.
399 sizeOf :: Proxy a -> Int
413 sizeOf :: Proxy a -> Int
401 {-# INLINE sizeOf #-}
415 {-# INLINE sizeOf #-}
402 default sizeOf :: (SizeOfRep (Rep a)) => Proxy a -> Int
416 default sizeOf :: (SizeOfRep (Rep a)) => Proxy a -> Int
403 sizeOf = genericSizeOf
417 sizeOf = genericSizeOf
405− -- | Read an element of type "a" from a MutableByteArray given the byte
419+ -- | @peekByteIndex byte-index array@ reads an element of type @a@ from the
406− -- index.
420+ -- the given the byte index in the array.
408 -- IMPORTANT: The implementation of this interface may not check the bounds
422 -- IMPORTANT: The implementation of this interface may not check the bounds
409 -- of the array, the caller must not assume that.
423 -- of the array, the caller must not assume that.
@@ -414,8 +428,8 @@ class Unbox a where
414 Int -> MutableByteArray -> IO a
428 Int -> MutableByteArray -> IO a
415 peekByteIndex i arr = genericPeekByteIndex arr i
429 peekByteIndex i arr = genericPeekByteIndex arr i
417− -- | Write an element of type "a" to a MutableByteArray given the byte
431+ -- | @pokeByteIndex byte-index array@ writes an element of type @a@ to the
418− -- index.
432+ -- the given the byte index in the array.
420 -- IMPORTANT: The implementation of this interface may not check the bounds
434 -- IMPORTANT: The implementation of this interface may not check the bounds
421 -- of the array, the caller must not assume that.
435 -- of the array, the caller must not assume that.