2-- Module : Streamly.Internal.Serialize.ToBytes
3-- Copyright : (c) 2022 Composewell Technologies
4-- License : BSD-3-Clause
5-- Maintainer : streamly@composewell.com
6-- Stability : pre-release
9-- Encode Haskell data types to byte streams.
11module Streamly.Internal.Serialize.ToBytes
44import Data.Bits (shiftR)
45import Data.Word (Word8, Word16, Word32, Word64)
46import GHC.Float (castDoubleToWord64, castFloatToWord32)
47import Streamly.Internal.Data.Stream.StreamD (Stream)
48import Streamly.Internal.Data.Stream.StreamD (Step(..))
50import qualified Streamly.Internal.Data.Stream.StreamD as Stream
51import qualified Streamly.Internal.Data.Stream.StreamD as D
53import Data.Int (Int8, Int16, Int32, Int64)
55-- XXX Use StreamD directly?
57-- | A value of type '()' is encoded as @0@ in binary encoding.
66unit :: Applicative m => Stream m Word8
67unit = Stream.fromPure 0
69{-# INLINE boolToWord8 #-}
70boolToWord8 :: Bool -> Word8
74-- | A value of type 'Bool' is encoded as follows in binary encoding.
84bool :: Applicative m => Bool -> Stream m Word8
85bool = Stream.fromPure . boolToWord8
87{-# INLINE orderingToWord8 #-}
88orderingToWord8 :: Ordering -> Word8
93-- | A value of type 'Ordering' is encoded as follows in binary encoding.
103{-# INLINE ordering #-}
104ordering :: Applicative m => Ordering -> Stream m Word8
105ordering = Stream.fromPure . orderingToWord8
107-- | Stream a 'Word8'.
112word8 :: Applicative m => Word8 -> Stream m Word8
113word8 = Stream.fromPure
115data W16State = W16B1 | W16B2 | W16Done
117{-# INLINE word16beD #-}
118word16beD :: Applicative m => Word16 -> D.Stream m Word8
119word16beD w = D.Stream step W16B1
123 step _ W16B1 = pure $ Yield (fromIntegral (shiftR w 8) :: Word8) W16B2
124 step _ W16B2 = pure $ Yield (fromIntegral w :: Word8) W16Done
125 step _ W16Done = pure Stop
127-- | Stream a 'Word16' as two bytes, the first byte is the MSB of the Word16
128-- and second byte is the LSB (big endian representation).
132{-# INLINE word16be #-}
133word16be :: Monad m => Word16 -> Stream m Word8
136-- | Little endian (LSB first) Word16
137{-# INLINE word16leD #-}
138word16leD :: Applicative m => Word16 -> D.Stream m Word8
139word16leD w = D.Stream step W16B1
143 step _ W16B1 = pure $ Yield (fromIntegral w :: Word8) W16B2
144 step _ W16B2 = pure $ Yield (fromIntegral (shiftR w 8) :: Word8) W16Done
145 step _ W16Done = pure Stop
147-- | Stream a 'Word16' as two bytes, the first byte is the LSB of the Word16
148-- and second byte is the MSB (little endian representation).
152{-# INLINE word16le #-}
153word16le :: Monad m => Word16 -> Stream m Word8
156data W32State = W32B1 | W32B2 | W32B3 | W32B4 | W32Done
158-- | Big endian (MSB first) Word32
159{-# INLINE word32beD #-}
160word32beD :: Applicative m => Word32 -> D.Stream m Word8
161word32beD w = D.Stream step W32B1
165 yield n s = pure $ Yield (fromIntegral (shiftR w n) :: Word8) s
167 step _ W32B1 = yield 24 W32B2
168 step _ W32B2 = yield 16 W32B3
169 step _ W32B3 = yield 8 W32B4
170 step _ W32B4 = pure $ Yield (fromIntegral w :: Word8) W32Done
171 step _ W32Done = pure Stop
173-- | Stream a 'Word32' as four bytes, the first byte is the MSB of the Word32
174-- and last byte is the LSB (big endian representation).
178{-# INLINE word32be #-}
179word32be :: Monad m => Word32 -> Stream m Word8
182-- | Little endian (LSB first) Word32
183{-# INLINE word32leD #-}
184word32leD :: Applicative m => Word32 -> D.Stream m Word8
185word32leD w = D.Stream step W32B1
189 yield n s = pure $ Yield (fromIntegral (shiftR w n) :: Word8) s
191 step _ W32B1 = pure $ Yield (fromIntegral w :: Word8) W32B2
192 step _ W32B2 = yield 8 W32B3
193 step _ W32B3 = yield 16 W32B4
194 step _ W32B4 = yield 24 W32Done
195 step _ W32Done = pure Stop
197-- | Stream a 'Word32' as four bytes, the first byte is the MSB of the Word32
198-- and last byte is the LSB (big endian representation).
202{-# INLINE word32le #-}
203word32le :: Monad m => Word32 -> Stream m Word8
207 W64B1 | W64B2 | W64B3 | W64B4 | W64B5 | W64B6 | W64B7 | W64B8 | W64Done
209-- | Big endian (MSB first) Word64
210{-# INLINE word64beD #-}
211word64beD :: Applicative m => Word64 -> D.Stream m Word8
212word64beD w = D.Stream step W64B1
216 yield n s = pure $ Yield (fromIntegral (shiftR w n) :: Word8) s
218 step _ W64B1 = yield 56 W64B2
219 step _ W64B2 = yield 48 W64B3
220 step _ W64B3 = yield 40 W64B4
221 step _ W64B4 = yield 32 W64B5
222 step _ W64B5 = yield 24 W64B6
223 step _ W64B6 = yield 16 W64B7
224 step _ W64B7 = yield 8 W64B8
225 step _ W64B8 = pure $ Yield (fromIntegral w :: Word8) W64Done
226 step _ W64Done = pure Stop
228-- | Stream a 'Word64' as eight bytes, the first byte is the MSB of the Word64
229-- and last byte is the LSB (big endian representation).
233{-# INLINE word64be #-}
234word64be :: Monad m => Word64 -> Stream m Word8
237-- | Little endian (LSB first) Word64
238{-# INLINE word64leD #-}
239word64leD :: Applicative m => Word64 -> D.Stream m Word8
240word64leD w = D.Stream step W64B1
244 yield n s = pure $ Yield (fromIntegral (shiftR w n) :: Word8) s
246 step _ W64B1 = pure $ Yield (fromIntegral w :: Word8) W64B2
247 step _ W64B2 = yield 8 W64B3
248 step _ W64B3 = yield 16 W64B4
249 step _ W64B4 = yield 24 W64B5
250 step _ W64B5 = yield 32 W64B6
251 step _ W64B6 = yield 40 W64B7
252 step _ W64B7 = yield 48 W64B8
253 step _ W64B8 = yield 56 W64Done
254 step _ W64Done = pure Stop
256-- | Stream a 'Word64' as eight bytes, the first byte is the MSB of the Word64
257-- and last byte is the LSB (big endian representation).
261{-# INLINE word64le #-}
262word64le :: Monad m => Word64 -> Stream m Word8
266int8 :: Applicative m => Int8 -> Stream m Word8
267int8 i = word8 (fromIntegral i :: Word8)
269-- | Stream a 'Int16' as two bytes, the first byte is the MSB of the Int16
270-- and second byte is the LSB (big endian representation).
274{-# INLINE int16be #-}
275int16be :: Monad m => Int16 -> Stream m Word8
276int16be i = word16be (fromIntegral i :: Word16)
278-- | Stream a 'Int16' as two bytes, the first byte is the LSB of the Int16
279-- and second byte is the MSB (little endian representation).
283{-# INLINE int16le #-}
284int16le :: Monad m => Int16 -> Stream m Word8
285int16le i = word16le (fromIntegral i :: Word16)
287-- | Stream a 'Int32' as four bytes, the first byte is the MSB of the Int32
288-- and last byte is the LSB (big endian representation).
292{-# INLINE int32be #-}
293int32be :: Monad m => Int32 -> Stream m Word8
294int32be i = word32be (fromIntegral i :: Word32)
296{-# INLINE int32le #-}
297int32le :: Monad m => Int32 -> Stream m Word8
298int32le i = word32le (fromIntegral i :: Word32)
300-- | Stream a 'Int64' as eight bytes, the first byte is the MSB of the Int64
301-- and last byte is the LSB (big endian representation).
305{-# INLINE int64be #-}
306int64be :: Monad m => Int64 -> Stream m Word8
307int64be i = word64be (fromIntegral i :: Word64)
309-- | Stream a 'Int64' as eight bytes, the first byte is the LSB of the Int64
310-- and last byte is the MSB (little endian representation).
314{-# INLINE int64le #-}
315int64le :: Monad m => Int64 -> Stream m Word8
316int64le i = word64le (fromIntegral i :: Word64)
318-- | Big endian (MSB first) Float
319{-# INLINE float32be #-}
320float32be :: Monad m => Float -> Stream m Word8
321float32be = word32beD . castFloatToWord32
323-- | Little endian (LSB first) Float
324{-# INLINE float32le #-}
325float32le :: Monad m => Float -> Stream m Word8
326float32le = word32leD . castFloatToWord32
328-- | Big endian (MSB first) Double
329{-# INLINE double64be #-}
330double64be :: Monad m => Double -> Stream m Word8
331double64be = word64beD . castDoubleToWord64
333-- | Little endian (LSB first) Double
334{-# INLINE double64le #-}
335double64le :: Monad m => Double -> Stream m Word8
336double64le = word64leD . castDoubleToWord64
338-------------------------------------------------------------------------------
340-------------------------------------------------------------------------------
342-- | Stream a 'Word64' as eight bytes in the host byte order.
346{-# INLINE word64host #-}
347word64host :: Monad m => Word64 -> Stream m Word8
349#ifdef WORDS_BIGENDIAN
355-------------------------------------------------------------------------------
357-------------------------------------------------------------------------------
360 -- | Convert a Haskell type to a byte stream.
361 toBytes :: a -> Stream m Word8
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list