2-- Module : Streamly.Internal.Serialize.ToBytes
3-- Copyright : (c) 2022 Composewell Technologies
4-- License : BSD-3-Clause
5-- Maintainer : streamly@composewell.com
8-- Encode Haskell data types to byte streams.
10module Streamly.Internal.Serialize.ToBytes
45import Data.Bits (shiftR)
47import Data.Int (Int8, Int16, Int32, Int64)
48import Data.Word (Word8, Word16, Word32, Word64)
49import GHC.Float (castDoubleToWord64, castFloatToWord32)
50import Streamly.Internal.Data.Stream (Stream)
51import Streamly.Internal.Data.Stream (Step(..))
52import Streamly.Internal.Unicode.Stream (readCharUtf8)
54import qualified Streamly.Internal.Data.Stream as Stream
55import qualified Streamly.Internal.Data.Stream as D
57-- XXX Use StreamD directly?
59-- | A value of type '()' is encoded as @0@ in binary encoding.
68unit :: Applicative m => Stream m Word8
69unit = Stream.fromPure 0
71{-# INLINE boolToWord8 #-}
72boolToWord8 :: Bool -> Word8
76-- | A value of type 'Bool' is encoded as follows in binary encoding.
86bool :: Applicative m => Bool -> Stream m Word8
87bool = Stream.fromPure . boolToWord8
89{-# INLINE orderingToWord8 #-}
90orderingToWord8 :: Ordering -> Word8
95-- | A value of type 'Ordering' is encoded as follows in binary encoding.
105{-# INLINE ordering #-}
106ordering :: Applicative m => Ordering -> Stream m Word8
107ordering = Stream.fromPure . orderingToWord8
109-- | Stream a 'Word8'.
114word8 :: Applicative m => Word8 -> Stream m Word8
115word8 = Stream.fromPure
117data W16State = W16B1 | W16B2 | W16Done
119{-# INLINE word16beD #-}
120word16beD :: Applicative m => Word16 -> D.Stream m Word8
121word16beD w = D.Stream step W16B1
125 step _ W16B1 = pure $ Yield (fromIntegral (shiftR w 8) :: Word8) W16B2
126 step _ W16B2 = pure $ Yield (fromIntegral w :: Word8) W16Done
127 step _ W16Done = pure Stop
129-- | Stream a 'Word16' as two bytes, the first byte is the MSB of the Word16
130-- and second byte is the LSB (big endian representation).
134{-# INLINE word16be #-}
135word16be :: Monad m => Word16 -> Stream m Word8
138-- | Little endian (LSB first) Word16
139{-# INLINE word16leD #-}
140word16leD :: Applicative m => Word16 -> D.Stream m Word8
141word16leD w = D.Stream step W16B1
145 step _ W16B1 = pure $ Yield (fromIntegral w :: Word8) W16B2
146 step _ W16B2 = pure $ Yield (fromIntegral (shiftR w 8) :: Word8) W16Done
147 step _ W16Done = pure Stop
149-- | Stream a 'Word16' as two bytes, the first byte is the LSB of the Word16
150-- and second byte is the MSB (little endian representation).
154{-# INLINE word16le #-}
155word16le :: Monad m => Word16 -> Stream m Word8
158data W32State = W32B1 | W32B2 | W32B3 | W32B4 | W32Done
160-- | Big endian (MSB first) Word32
161{-# INLINE word32beD #-}
162word32beD :: Applicative m => Word32 -> D.Stream m Word8
163word32beD w = D.Stream step W32B1
167 yield n s = pure $ Yield (fromIntegral (shiftR w n) :: Word8) s
169 step _ W32B1 = yield 24 W32B2
170 step _ W32B2 = yield 16 W32B3
171 step _ W32B3 = yield 8 W32B4
172 step _ W32B4 = pure $ Yield (fromIntegral w :: Word8) W32Done
173 step _ W32Done = pure Stop
175-- | Stream a 'Word32' as four bytes, the first byte is the MSB of the Word32
176-- and last byte is the LSB (big endian representation).
180{-# INLINE word32be #-}
181word32be :: Monad m => Word32 -> Stream m Word8
184-- | Little endian (LSB first) Word32
185{-# INLINE word32leD #-}
186word32leD :: Applicative m => Word32 -> D.Stream m Word8
187word32leD w = D.Stream step W32B1
191 yield n s = pure $ Yield (fromIntegral (shiftR w n) :: Word8) s
193 step _ W32B1 = pure $ Yield (fromIntegral w :: Word8) W32B2
194 step _ W32B2 = yield 8 W32B3
195 step _ W32B3 = yield 16 W32B4
196 step _ W32B4 = yield 24 W32Done
197 step _ W32Done = pure Stop
199-- | Stream a 'Word32' as four bytes, the first byte is the MSB of the Word32
200-- and last byte is the LSB (big endian representation).
204{-# INLINE word32le #-}
205word32le :: Monad m => Word32 -> Stream m Word8
209 W64B1 | W64B2 | W64B3 | W64B4 | W64B5 | W64B6 | W64B7 | W64B8 | W64Done
211-- | Big endian (MSB first) Word64
212{-# INLINE word64beD #-}
213word64beD :: Applicative m => Word64 -> D.Stream m Word8
214word64beD w = D.Stream step W64B1
218 yield n s = pure $ Yield (fromIntegral (shiftR w n) :: Word8) s
220 step _ W64B1 = yield 56 W64B2
221 step _ W64B2 = yield 48 W64B3
222 step _ W64B3 = yield 40 W64B4
223 step _ W64B4 = yield 32 W64B5
224 step _ W64B5 = yield 24 W64B6
225 step _ W64B6 = yield 16 W64B7
226 step _ W64B7 = yield 8 W64B8
227 step _ W64B8 = pure $ Yield (fromIntegral w :: Word8) W64Done
228 step _ W64Done = pure Stop
230-- | Stream a 'Word64' as eight bytes, the first byte is the MSB of the Word64
231-- and last byte is the LSB (big endian representation).
235{-# INLINE word64be #-}
236word64be :: Monad m => Word64 -> Stream m Word8
239-- | Little endian (LSB first) Word64
240{-# INLINE word64leD #-}
241word64leD :: Applicative m => Word64 -> D.Stream m Word8
242word64leD w = D.Stream step W64B1
246 yield n s = pure $ Yield (fromIntegral (shiftR w n) :: Word8) s
248 step _ W64B1 = pure $ Yield (fromIntegral w :: Word8) W64B2
249 step _ W64B2 = yield 8 W64B3
250 step _ W64B3 = yield 16 W64B4
251 step _ W64B4 = yield 24 W64B5
252 step _ W64B5 = yield 32 W64B6
253 step _ W64B6 = yield 40 W64B7
254 step _ W64B7 = yield 48 W64B8
255 step _ W64B8 = yield 56 W64Done
256 step _ W64Done = pure Stop
258-- | Stream a 'Word64' as eight bytes, the first byte is the MSB of the Word64
259-- and last byte is the LSB (big endian representation).
263{-# INLINE word64le #-}
264word64le :: Monad m => Word64 -> Stream m Word8
268int8 :: Applicative m => Int8 -> Stream m Word8
269int8 i = word8 (fromIntegral i :: Word8)
271-- | Stream a 'Int16' as two bytes, the first byte is the MSB of the Int16
272-- and second byte is the LSB (big endian representation).
276{-# INLINE int16be #-}
277int16be :: Monad m => Int16 -> Stream m Word8
278int16be i = word16be (fromIntegral i :: Word16)
280-- | Stream a 'Int16' as two bytes, the first byte is the LSB of the Int16
281-- and second byte is the MSB (little endian representation).
285{-# INLINE int16le #-}
286int16le :: Monad m => Int16 -> Stream m Word8
287int16le i = word16le (fromIntegral i :: Word16)
289-- | Stream a 'Int32' as four bytes, the first byte is the MSB of the Int32
290-- and last byte is the LSB (big endian representation).
294{-# INLINE int32be #-}
295int32be :: Monad m => Int32 -> Stream m Word8
296int32be i = word32be (fromIntegral i :: Word32)
298{-# INLINE int32le #-}
299int32le :: Monad m => Int32 -> Stream m Word8
300int32le i = word32le (fromIntegral i :: Word32)
302-- | Stream a 'Int64' as eight bytes, the first byte is the MSB of the Int64
303-- and last byte is the LSB (big endian representation).
307{-# INLINE int64be #-}
308int64be :: Monad m => Int64 -> Stream m Word8
309int64be i = word64be (fromIntegral i :: Word64)
311-- | Stream a 'Int64' as eight bytes, the first byte is the LSB of the Int64
312-- and last byte is the MSB (little endian representation).
316{-# INLINE int64le #-}
317int64le :: Monad m => Int64 -> Stream m Word8
318int64le i = word64le (fromIntegral i :: Word64)
320-- | Big endian (MSB first) Float
321{-# INLINE float32be #-}
322float32be :: Monad m => Float -> Stream m Word8
323float32be = word32beD . castFloatToWord32
325-- | Little endian (LSB first) Float
326{-# INLINE float32le #-}
327float32le :: Monad m => Float -> Stream m Word8
328float32le = word32leD . castFloatToWord32
330-- | Big endian (MSB first) Double
331{-# INLINE double64be #-}
332double64be :: Monad m => Double -> Stream m Word8
333double64be = word64beD . castDoubleToWord64
335-- | Little endian (LSB first) Double
336{-# INLINE double64le #-}
337double64le :: Monad m => Double -> Stream m Word8
338double64le = word64leD . castDoubleToWord64
340-- | Encode a Unicode character to stream of bytes in 0-255 range.
342{-# INLINE charLatin1 #-}
343charLatin1 :: Applicative m => Char -> Stream m Word8
344charLatin1 = Stream.fromPure . fromIntegral . ord
346{-# INLINE charUtf8 #-}
347charUtf8 :: Monad m => Char -> Stream m Word8
348charUtf8 = Stream.unfold readCharUtf8
350-------------------------------------------------------------------------------
352-------------------------------------------------------------------------------
354-- | Stream a 'Word64' as eight bytes in the host byte order.
358{-# INLINE word64host #-}
359word64host :: Monad m => Word64 -> Stream m Word8
361#ifdef WORDS_BIGENDIAN
367-------------------------------------------------------------------------------
369-------------------------------------------------------------------------------
372 -- | Convert a Haskell type to a byte stream.
373 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