1{-# LANGUAGE CPP        #-}
2{-# LANGUAGE MagicHash  #-}
3{-# LANGUAGE Rank2Types #-}
4{-# LANGUAGE BangPatterns #-}
5
6-----------------------------------------------------------------------------
7-- |
8-- Module      : Data.Serialize.Get
9-- Copyright   : Lennart Kolmodin, Galois Inc. 2009
10-- License     : BSD3-style (see LICENSE)
11--
12-- Maintainer  : Trevor Elliott <trevor@galois.com>
13-- Stability   :
14-- Portability :
15--
16-- The Get monad. A monad for efficiently building structures from
17-- strict ByteStrings
18--
19-----------------------------------------------------------------------------
20
21#if defined(__GLASGOW_HASKELL__) && !defined(__HADDOCK__)
22#include "MachDeps.h"
23#endif
24
25module Data.Serialize.Get (
26
27    -- * The Get type
28      Get
29    , runGet
30    , runGetLazy
31    , runGetState
32    , runGetLazyState
33
34    -- ** Incremental interface
35    , Result(..)
36    , runGetPartial
37    , runGetChunk
38
39    -- * Parsing
40    , ensure
41    , isolate
42    , label
43    , skip
44    , uncheckedSkip
45    , lookAhead
46    , lookAheadM
47    , lookAheadE
48    , uncheckedLookAhead
49    , bytesRead
50
51    -- * Utility
52    , getBytes
53    , remaining
54    , isEmpty
55
56    -- * Parsing particular types
57    , getWord8
58    , getInt8
59
60    -- ** ByteStrings
61    , getByteString
62    , getLazyByteString
63    , getShortByteString
64
65    -- ** Big-endian reads
66    , getWord16be
67    , getWord32be
68    , getWord64be
69    , getInt16be
70    , getInt32be
71    , getInt64be
72
73    -- ** Little-endian reads
74    , getWord16le
75    , getWord32le
76    , getWord64le
77    , getInt16le
78    , getInt32le
79    , getInt64le
80
81    -- ** Host-endian, unaligned reads
82    , getWordhost
83    , getWord16host
84    , getWord32host
85    , getWord64host
86
87    -- ** Containers
88    , getTwoOf
89    , getListOf
90    , getIArrayOf
91    , getTreeOf
92    , getSeqOf
93    , getMapOf
94    , getIntMapOf
95    , getSetOf
96    , getIntSetOf
97    , getMaybeOf
98    , getEitherOf
99    , getNested
100  ) where
101
102import qualified Control.Applicative as A
103import qualified Control.Monad as M
104import Control.Monad (unless)
105import qualified Control.Monad.Fail as Fail
106import Data.Array.IArray (IArray,listArray)
107import Data.Ix (Ix)
108import Data.List (intercalate)
109import Data.Maybe (isNothing,fromMaybe)
110import Foreign
111import System.IO.Unsafe (unsafeDupablePerformIO)
112
113import qualified Data.ByteString          as B
114import qualified Data.ByteString.Internal as B
115import qualified Data.ByteString.Unsafe   as B
116import qualified Data.ByteString.Lazy     as L
117import qualified Data.ByteString.Short    as BS
118import qualified Data.IntMap              as IntMap
119import qualified Data.IntSet              as IntSet
120import qualified Data.Map                 as Map
121import qualified Data.Sequence            as Seq
122import qualified Data.Set                 as Set
123import qualified Data.Tree                as T
124
125#if defined(__GLASGOW_HASKELL__) && !defined(__HADDOCK__)
126import GHC.Base
127import GHC.Word
128#endif
129
130-- | The result of a parse.
131data Result r = Fail String B.ByteString
132              -- ^ The parse failed. The 'String' is the
133              --   message describing the error, if any.
134              | Partial (B.ByteString -> Result r)
135              -- ^ Supply this continuation with more input so that
136              --   the parser can resume. To indicate that no more
137              --   input is available, use an 'B.empty' string.
138              | Done r B.ByteString
139              -- ^ The parse succeeded.  The 'B.ByteString' is the
140              --   input that had not yet been consumed (if any) when
141              --   the parse succeeded.
142
143instance Show r => Show (Result r) where
144    show (Fail msg _) = "Fail " ++ show msg
145    show (Partial _)  = "Partial _"
146    show (Done r bs)  = "Done " ++ show r ++ " " ++ show bs
147
148instance Functor Result where
149    fmap _ (Fail msg rest) = Fail msg rest
150    fmap f (Partial k)     = Partial (fmap f . k)
151    fmap f (Done r bs)     = Done (f r) bs
152
153-- | The Get monad is an Exception and State monad.
154newtype Get a = Get
155  { unGet :: forall r. Input -> Buffer -> More
156                    -> Int -> Failure r
157                    -> Success a r -> Result r }
158
159type Input  = B.ByteString
160type Buffer = Maybe B.ByteString
161
162emptyBuffer :: Buffer
163emptyBuffer  = Just B.empty
164
165extendBuffer :: Buffer -> B.ByteString -> Buffer
166extendBuffer buf chunk =
167  do bs <- buf
168     return $! bs `B.append` chunk
169{-# INLINE extendBuffer #-}
170
171append :: Buffer -> Buffer -> Buffer
172append l r = B.append `fmap` l A.<*> r
173{-# INLINE append #-}
174
175bufferBytes :: Buffer -> B.ByteString
176bufferBytes  = fromMaybe B.empty
177{-# INLINE bufferBytes #-}
178
179type Failure   r = Input -> Buffer -> More -> [String] -> String -> Result r
180type Success a r = Input -> Buffer -> More -> Int      -> a      -> Result r
181
182-- | Have we read all available input?
183data More
184  = Complete
185  | Incomplete (Maybe Int)
186    deriving (Eq)
187
188moreLength :: More -> Int
189moreLength m = case m of
190  Complete      -> 0
191  Incomplete mb -> fromMaybe 0 mb
192
193instance Functor Get where
194    fmap p m =           Get $ \ s0 b0 m0 w0 kf ks ->
195      unGet m s0 b0 m0 w0 kf $ \ s1 b1 m1 w1 a  -> ks s1 b1 m1 w1 (p a)
196
197instance A.Applicative Get where
198    pure a = Get $ \ s0 b0 m0 w _ ks -> ks s0 b0 m0 w a
199    {-# INLINE pure #-}
200
201    f <*> x =            Get $ \ s0 b0 m0 w0 kf ks ->
202      unGet f s0 b0 m0 w0 kf $ \ s1 b1 m1 w1 g     ->
203      unGet x s1 b1 m1 w1 kf $ \ s2 b2 m2 w2 y  -> ks s2 b2 m2 w2 (g y)
204    {-# INLINE (<*>) #-}
205
206    m *> k =             Get $ \ s0 b0 m0 w0 kf ks ->
207      unGet m s0 b0 m0 w0 kf $ \ s1 b1 m1 w1 _     -> unGet k s1 b1 m1 w1 kf ks
208    {-# INLINE (*>) #-}
209
210instance A.Alternative Get where
211    empty = failDesc "empty"
212    {-# INLINE empty #-}
213
214    (<|>) = M.mplus
215    {-# INLINE (<|>) #-}
216
217-- Definition directly from Control.Monad.State.Strict
218instance Monad Get where
219    return = A.pure
220    {-# INLINE return #-}
221
222    m >>= g  =           Get $ \ s0 b0 m0 w0 kf ks ->
223      unGet m s0 b0 m0 w0 kf $ \ s1 b1 m1 w1 a     -> unGet (g a) s1 b1 m1 w1 kf ks
224    {-# INLINE (>>=) #-}
225
226    (>>) = (A.*>)
227    {-# INLINE (>>) #-}
228
229#if !(MIN_VERSION_base(4,13,0))
230    fail     = Fail.fail
231    {-# INLINE fail #-}
232#endif
233
234instance Fail.MonadFail Get where
235    fail     = failDesc
236    {-# INLINE fail #-}
237
238instance M.MonadPlus Get where
239    mzero     = failDesc "mzero"
240    {-# INLINE mzero #-}
241-- TODO: Test this!
242    mplus a b =
243      Get $ \s0 b0 m0 w0 kf ks ->
244        let ks' s1 b1        = ks s1 (b0 `append` b1)
245            kf' _  b1 m1     = kf (s0 `B.append` bufferBytes b1)
246                                  (b0 `append` b1) m1
247            try _  b1 m1 _ _ = unGet b (s0 `B.append` bufferBytes b1)
248                                       b1 m1 w0 kf' ks'
249         in unGet a s0 emptyBuffer m0 w0 try ks'
250    {-# INLINE mplus #-}
251
252
253------------------------------------------------------------------------
254
255formatTrace :: [String] -> String
256formatTrace [] = "Empty call stack"
257formatTrace ls = "From:\t" ++ intercalate "\n\t" ls ++ "\n"
258
259get :: Get B.ByteString
260get  = Get (\s0 b0 m0 w _ k -> k s0 b0 m0 w s0)
261{-# INLINE get #-}
262
263put :: B.ByteString -> Int -> Get ()
264put s !w = Get (\_ b0 m _ _ k -> k s b0 m w ())
265{-# INLINE put #-}
266
267label :: String -> Get a -> Get a
268label l m =
269  Get $ \ s0 b0 m0 w0 kf ks ->
270    let kf' s1 b1 m1 ls = kf s1 b1 m1 (l:ls)
271     in unGet m s0 b0 m0 w0 kf' ks
272
273finalK :: Success a a
274finalK s _ _ _ a = Done a s
275
276failK :: Failure a
277failK s b _ ls msg =
278  Fail (unlines [msg, formatTrace ls]) (s `B.append` bufferBytes b)
279
280-- | Run the Get monad applies a 'get'-based parser on the input ByteString
281runGet :: Get a -> B.ByteString -> Either String a
282runGet m str =
283  case unGet m str Nothing Complete 0 failK finalK of
284    Fail i _  -> Left i
285    Done a _  -> Right a
286    Partial{} -> Left "Failed reading: Internal error: unexpected Partial."
287{-# INLINE runGet #-}
288
289-- | Run the get monad on a single chunk, providing an optional length for the
290-- remaining, unseen input, with Nothing indicating that it's not clear how much
291-- input is left.  For example, with a lazy ByteString, the optional length
292-- represents the sum of the lengths of all remaining chunks.
293runGetChunk :: Get a -> Maybe Int -> B.ByteString -> Result a
294runGetChunk m mbLen str = unGet m str Nothing (Incomplete mbLen) 0 failK finalK
295{-# INLINE runGetChunk #-}
296
297-- | Run the Get monad applies a 'get'-based parser on the input ByteString
298runGetPartial :: Get a -> B.ByteString -> Result a
299runGetPartial m = runGetChunk m Nothing
300{-# INLINE runGetPartial #-}
301
302-- | Run the Get monad applies a 'get'-based parser on the input
303-- ByteString. Additional to the result of get it returns the number of
304-- consumed bytes and the rest of the input.
305runGetState :: Get a -> B.ByteString -> Int
306            -> Either String (a, B.ByteString)
307runGetState m str off = case runGetState' m str off of
308  (Right a,bs) -> Right (a,bs)
309  (Left i,_)   -> Left i
310{-# INLINE runGetState #-}
311
312-- | Run the Get monad applies a 'get'-based parser on the input
313-- ByteString. Additional to the result of get it returns the number of
314-- consumed bytes and the rest of the input, even in the event of a failure.
315runGetState' :: Get a -> B.ByteString -> Int
316             -> (Either String a, B.ByteString)
317runGetState' m str off =
318  case unGet m (B.drop off str) Nothing Complete 0 failK finalK of
319    Fail i bs -> (Left i,bs)
320    Done a bs -> (Right a, bs)
321    Partial{} -> (Left "Failed reading: Internal error: unexpected Partial.",B.empty)
322{-# INLINE runGetState' #-}
323
324
325
326-- Lazy Get --------------------------------------------------------------------
327
328runGetLazy' :: Get a -> L.ByteString -> (Either String a,L.ByteString)
329runGetLazy' m lstr =
330  case L.toChunks lstr of
331    [c]  -> wrapStrict (runGetState' m c       0)
332    []   -> wrapStrict (runGetState' m B.empty 0)
333    c:cs -> loop (runGetChunk m (Just (len - B.length c)) c) cs
334  where
335  len = fromIntegral (L.length lstr)
336
337  wrapStrict (e,s) = (e,L.fromChunks [s])
338
339  loop result chunks = case result of
340
341    Fail str rest -> (Left str, L.fromChunks (rest : chunks))
342    Partial k     -> case chunks of
343                       c:cs -> loop (k c)       cs
344                       []   -> loop (k B.empty) []
345
346    Done r rest   -> (Right r, L.fromChunks (rest : chunks))
347{-# INLINE runGetLazy' #-}
348
349-- | Run the Get monad over a Lazy ByteString.  Note that this will not run the
350-- Get parser lazily, but will operate on lazy ByteStrings.
351runGetLazy :: Get a -> L.ByteString -> Either String a
352runGetLazy m lstr = fst (runGetLazy' m lstr)
353{-# INLINE runGetLazy #-}
354
355-- | Run the Get monad over a Lazy ByteString.  Note that this does not run the
356-- Get parser lazily, but will operate on lazy ByteStrings.
357runGetLazyState :: Get a -> L.ByteString -> Either String (a,L.ByteString)
358runGetLazyState m lstr = case runGetLazy' m lstr of
359  (Right a,rest) -> Right (a,rest)
360  (Left err,_)   -> Left err
361{-# INLINE runGetLazyState #-}
362
363------------------------------------------------------------------------
364
365-- | If at least @n@ bytes of input are available, return the current
366--   input, otherwise fail.
367{-# INLINE ensure #-}
368ensure :: Int -> Get B.ByteString
369ensure n0 = n0 `seq` Get $ \ s0 b0 m0 w0 kf ks -> let
370    n' = n0 - B.length s0
371    in if n' <= 0
372        then ks s0 b0 m0 w0 s0
373        else getMore n' s0 [] b0 m0 w0 kf ks
374    where
375        -- The "accumulate and concat" pattern here is important not to incur
376        -- in quadratic behavior, see <https://github.com/GaloisInc/cereal/issues/48>
377
378        finalInput s0 ss = B.concat (reverse (s0 : ss))
379        finalBuffer b0 s0 ss = extendBuffer b0 (B.concat (reverse (init (s0 : ss))))
380        getMore !n s0 ss b0 m0 w0 kf ks = let
381            tooFewBytes = let
382                !s = finalInput s0 ss
383                !b = finalBuffer b0 s0 ss
384                in kf s b m0 ["demandInput"] "too few bytes"
385            in case m0 of
386                Complete -> tooFewBytes
387                Incomplete mb -> Partial $ \s ->
388                    if B.null s
389                        then tooFewBytes
390                        else let
391                            !mb' = case mb of
392                                Just l -> Just $! l - B.length s
393                                Nothing -> Nothing
394                            in checkIfEnough n s (s0 : ss) b0 (Incomplete mb') w0 kf ks
395
396        checkIfEnough !n s0 ss b0 m0 w0 kf ks = let
397            n' = n - B.length s0
398            in if n' <= 0
399                then let
400                    !s = finalInput s0 ss
401                    !b = finalBuffer b0 s0 ss
402                    in ks s b m0 w0 s
403                else getMore n' s0 ss b0 m0 w0 kf ks
404
405-- | Isolate an action to operating within a fixed block of bytes.  The action
406--   is required to consume all the bytes that it is isolated to.
407isolate :: Int -> Get a -> Get a
408isolate n m = do
409  M.when (n < 0) (fail "Attempted to isolate a negative number of bytes")
410  s <- ensure n
411  let (s',rest) = B.splitAt n s
412  cur <- bytesRead
413  put s' cur
414  a    <- m
415  used <- get
416  unless (B.null used) (fail "not all bytes parsed in isolate")
417  put rest (cur + n)
418  return a
419
420failDesc :: String -> Get a
421failDesc err = do
422    let msg = "Failed reading: " ++ err
423    Get (\s0 b0 m0 _ kf _ -> kf s0 b0 m0 [] msg)
424
425-- | Skip ahead @n@ bytes. Fails if fewer than @n@ bytes are available.
426skip :: Int -> Get ()
427skip n = do
428  s <- ensure n
429  cur <- bytesRead
430  put (B.drop n s) (cur + n)
431
432-- | Skip ahead up to @n@ bytes in the current chunk. No error if there aren't
433-- enough bytes, or if less than @n@ bytes are skipped.
434uncheckedSkip :: Int -> Get ()
435uncheckedSkip n = do
436    s <- get
437    cur <- bytesRead
438    put (B.drop n s) (cur + n)
439
440-- | Run @ga@, but return without consuming its input.
441-- Fails if @ga@ fails.
442lookAhead :: Get a -> Get a
443lookAhead ga = Get $ \ s0 b0 m0 w0 kf ks ->
444  -- the new continuation extends the old input with the new buffered bytes, and
445  -- appends the new buffer to the old one, if there was one.
446  let ks' _ b1 = ks (s0 `B.append` bufferBytes b1) (b0 `append` b1)
447      kf' _ b1 = kf s0 (b0 `append` b1)
448   in unGet ga s0 emptyBuffer m0 w0 kf' ks'
449
450-- | Like 'lookAhead', but consume the input if @gma@ returns 'Just _'.
451-- Fails if @gma@ fails.
452lookAheadM :: Get (Maybe a) -> Get (Maybe a)
453lookAheadM gma = do
454    s <- get
455    pre <- bytesRead
456    ma <- gma
457    M.when (isNothing ma) (put s pre)
458    return ma
459
460-- | Like 'lookAhead', but consume the input if @gea@ returns 'Right _'.
461-- Fails if @gea@ fails.
462lookAheadE :: Get (Either a b) -> Get (Either a b)
463lookAheadE gea = do
464    s <- get
465    pre <- bytesRead
466    ea <- gea
467    case ea of
468        Left _ -> put s pre
469        _      -> return ()
470    return ea
471
472-- | Get the next up to @n@ bytes as a ByteString until end of this chunk,
473-- without consuming them.
474uncheckedLookAhead :: Int -> Get B.ByteString
475uncheckedLookAhead n = do
476    s <- get
477    return (B.take n s)
478
479------------------------------------------------------------------------
480-- Utility
481
482-- | Get the number of remaining unparsed bytes.  Useful for checking whether
483-- all input has been consumed.
484--
485-- WARNING: when run with @runGetPartial@, remaining will only return the number
486-- of bytes that are remaining in the current input.
487remaining :: Get Int
488remaining = Get (\ s0 b0 m0 w0 _ ks -> ks s0 b0 m0 w0 (B.length s0 + moreLength m0))
489
490-- | Test whether all input has been consumed.
491--
492-- WARNING: when run with @runGetPartial@, isEmpty will only tell you if you're
493-- at the end of the current chunk.
494isEmpty :: Get Bool
495isEmpty = Get (\ s0 b0 m0 w0 _ ks -> ks s0 b0 m0 w0 (B.null s0 && moreLength m0 == 0))
496
497------------------------------------------------------------------------
498-- Utility with ByteStrings
499
500-- | An efficient 'get' method for strict ByteStrings. Fails if fewer
501-- than @n@ bytes are left in the input. This function creates a fresh
502-- copy of the underlying bytes.
503getByteString :: Int -> Get B.ByteString
504getByteString n = do
505  bs <- getBytes n
506  return $! B.copy bs
507
508getLazyByteString :: Int64 -> Get L.ByteString
509getLazyByteString n = f `fmap` getByteString (fromIntegral n)
510  where f bs = L.fromChunks [bs]
511
512getShortByteString :: Int -> Get BS.ShortByteString
513getShortByteString n = do
514  bs <- getBytes n
515  return $! BS.toShort bs
516
517
518------------------------------------------------------------------------
519-- Helpers
520
521-- | Pull @n@ bytes from the input, as a strict ByteString.
522getBytes :: Int -> Get B.ByteString
523getBytes n | n < 0 = fail "getBytes: negative length requested"
524getBytes n = do
525    s <- ensure n
526    let consume = B.unsafeTake n s
527        rest    = B.unsafeDrop n s
528        -- (consume,rest) = B.splitAt n s
529    cur <- bytesRead
530    put rest (cur + n)
531    return consume
532{-# INLINE getBytes #-}
533
534
535
536------------------------------------------------------------------------
537-- Primtives
538
539-- helper, get a raw Ptr onto a strict ByteString copied out of the
540-- underlying strict byteString.
541
542getPtr :: Storable a => Int -> Get a
543getPtr n = do
544    (fp,o,_) <- B.toForeignPtr `fmap` getBytes n
545    let k p = peek (castPtr (p `plusPtr` o))
546    return (unsafeDupablePerformIO (withForeignPtr fp k))
547{-# INLINE getPtr #-}
548
549-----------------------------------------------------------------------
550
551-- | Read a Int8 from the monad state
552getInt8 :: Get Int8
553getInt8 = do
554    s <- getBytes 1
555    return $! fromIntegral (B.unsafeHead s)
556
557-- | Read a Int16 in big endian format
558getInt16be :: Get Int16
559getInt16be = do
560    s <- getBytes 2
561    return $! (fromIntegral (s `B.unsafeIndex` 0) `shiftL` 8) .|.
562              (fromIntegral (s `B.unsafeIndex` 1) )
563
564-- | Read a Int16 in little endian format
565getInt16le :: Get Int16
566getInt16le = do
567    s <- getBytes 2
568    return $! (fromIntegral (s `B.unsafeIndex` 1) `shiftL` 8) .|.
569              (fromIntegral (s `B.unsafeIndex` 0) )
570
571-- | Read a Int32 in big endian format
572getInt32be :: Get Int32
573getInt32be = do
574    s <- getBytes 4
575    return $! (fromIntegral (s `B.unsafeIndex` 0) `shiftL` 24) .|.
576              (fromIntegral (s `B.unsafeIndex` 1) `shiftL` 16) .|.
577              (fromIntegral (s `B.unsafeIndex` 2) `shiftL`  8) .|.
578              (fromIntegral (s `B.unsafeIndex` 3) )
579
580-- | Read a Int32 in little endian format
581getInt32le :: Get Int32
582getInt32le = do
583    s <- getBytes 4
584    return $! (fromIntegral (s `B.unsafeIndex` 3) `shiftL` 24) .|.
585              (fromIntegral (s `B.unsafeIndex` 2) `shiftL` 16) .|.
586              (fromIntegral (s `B.unsafeIndex` 1) `shiftL`  8) .|.
587              (fromIntegral (s `B.unsafeIndex` 0) )
588
589-- | Read a Int64 in big endian format
590getInt64be :: Get Int64
591getInt64be = do
592    s <- getBytes 8
593    return $! (fromIntegral (s `B.unsafeIndex` 0) `shiftL` 56) .|.
594              (fromIntegral (s `B.unsafeIndex` 1) `shiftL` 48) .|.
595              (fromIntegral (s `B.unsafeIndex` 2) `shiftL` 40) .|.
596              (fromIntegral (s `B.unsafeIndex` 3) `shiftL` 32) .|.
597              (fromIntegral (s `B.unsafeIndex` 4) `shiftL` 24) .|.
598              (fromIntegral (s `B.unsafeIndex` 5) `shiftL` 16) .|.
599              (fromIntegral (s `B.unsafeIndex` 6) `shiftL`  8) .|.
600              (fromIntegral (s `B.unsafeIndex` 7) )
601
602-- | Read a Int64 in little endian format
603getInt64le :: Get Int64
604getInt64le = do
605    s <- getBytes 8
606    return $! (fromIntegral (s `B.unsafeIndex` 7) `shiftL` 56) .|.
607              (fromIntegral (s `B.unsafeIndex` 6) `shiftL` 48) .|.
608              (fromIntegral (s `B.unsafeIndex` 5) `shiftL` 40) .|.
609              (fromIntegral (s `B.unsafeIndex` 4) `shiftL` 32) .|.
610              (fromIntegral (s `B.unsafeIndex` 3) `shiftL` 24) .|.
611              (fromIntegral (s `B.unsafeIndex` 2) `shiftL` 16) .|.
612              (fromIntegral (s `B.unsafeIndex` 1) `shiftL`  8) .|.
613              (fromIntegral (s `B.unsafeIndex` 0) )
614
615{-# INLINE getInt8    #-}
616{-# INLINE getInt16be #-}
617{-# INLINE getInt16le #-}
618{-# INLINE getInt32be #-}
619{-# INLINE getInt32le #-}
620{-# INLINE getInt64be #-}
621{-# INLINE getInt64le #-}
622
623------------------------------------------------------------------------
624
625-- | Read a Word8 from the monad state
626getWord8 :: Get Word8
627getWord8 = do
628    s <- getBytes 1
629    return (B.unsafeHead s)
630
631-- | Read a Word16 in big endian format
632getWord16be :: Get Word16
633getWord16be = do
634    s <- getBytes 2
635    return $! (fromIntegral (s `B.unsafeIndex` 0) `shiftl_w16` 8) .|.
636              (fromIntegral (s `B.unsafeIndex` 1))
637
638-- | Read a Word16 in little endian format
639getWord16le :: Get Word16
640getWord16le = do
641    s <- getBytes 2
642    return $! (fromIntegral (s `B.unsafeIndex` 1) `shiftl_w16` 8) .|.
643              (fromIntegral (s `B.unsafeIndex` 0) )
644
645-- | Read a Word32 in big endian format
646getWord32be :: Get Word32
647getWord32be = do
648    s <- getBytes 4
649    return $! (fromIntegral (s `B.unsafeIndex` 0) `shiftl_w32` 24) .|.
650              (fromIntegral (s `B.unsafeIndex` 1) `shiftl_w32` 16) .|.
651              (fromIntegral (s `B.unsafeIndex` 2) `shiftl_w32`  8) .|.
652              (fromIntegral (s `B.unsafeIndex` 3) )
653
654-- | Read a Word32 in little endian format
655getWord32le :: Get Word32
656getWord32le = do
657    s <- getBytes 4
658    return $! (fromIntegral (s `B.unsafeIndex` 3) `shiftl_w32` 24) .|.
659              (fromIntegral (s `B.unsafeIndex` 2) `shiftl_w32` 16) .|.
660              (fromIntegral (s `B.unsafeIndex` 1) `shiftl_w32`  8) .|.
661              (fromIntegral (s `B.unsafeIndex` 0) )
662
663-- | Read a Word64 in big endian format
664getWord64be :: Get Word64
665getWord64be = do
666    s <- getBytes 8
667    return $! (fromIntegral (s `B.unsafeIndex` 0) `shiftl_w64` 56) .|.
668              (fromIntegral (s `B.unsafeIndex` 1) `shiftl_w64` 48) .|.
669              (fromIntegral (s `B.unsafeIndex` 2) `shiftl_w64` 40) .|.
670              (fromIntegral (s `B.unsafeIndex` 3) `shiftl_w64` 32) .|.
671              (fromIntegral (s `B.unsafeIndex` 4) `shiftl_w64` 24) .|.
672              (fromIntegral (s `B.unsafeIndex` 5) `shiftl_w64` 16) .|.
673              (fromIntegral (s `B.unsafeIndex` 6) `shiftl_w64`  8) .|.
674              (fromIntegral (s `B.unsafeIndex` 7) )
675
676-- | Read a Word64 in little endian format
677getWord64le :: Get Word64
678getWord64le = do
679    s <- getBytes 8
680    return $! (fromIntegral (s `B.unsafeIndex` 7) `shiftl_w64` 56) .|.
681              (fromIntegral (s `B.unsafeIndex` 6) `shiftl_w64` 48) .|.
682              (fromIntegral (s `B.unsafeIndex` 5) `shiftl_w64` 40) .|.
683              (fromIntegral (s `B.unsafeIndex` 4) `shiftl_w64` 32) .|.
684              (fromIntegral (s `B.unsafeIndex` 3) `shiftl_w64` 24) .|.
685              (fromIntegral (s `B.unsafeIndex` 2) `shiftl_w64` 16) .|.
686              (fromIntegral (s `B.unsafeIndex` 1) `shiftl_w64`  8) .|.
687              (fromIntegral (s `B.unsafeIndex` 0) )
688
689{-# INLINE getWord8    #-}
690{-# INLINE getWord16be #-}
691{-# INLINE getWord16le #-}
692{-# INLINE getWord32be #-}
693{-# INLINE getWord32le #-}
694{-# INLINE getWord64be #-}
695{-# INLINE getWord64le #-}
696
697------------------------------------------------------------------------
698-- Host-endian reads
699
700-- | /O(1)./ Read a single native machine word. The word is read in
701-- host order, host endian form, for the machine you're on. On a 64 bit
702-- machine the Word is an 8 byte value, on a 32 bit machine, 4 bytes.
703getWordhost :: Get Word
704getWordhost = getPtr (sizeOf (undefined :: Word))
705
706-- | /O(1)./ Read a 2 byte Word16 in native host order and host endianness.
707getWord16host :: Get Word16
708getWord16host = getPtr (sizeOf (undefined :: Word16))
709
710-- | /O(1)./ Read a Word32 in native host order and host endianness.
711getWord32host :: Get Word32
712getWord32host = getPtr  (sizeOf (undefined :: Word32))
713
714-- | /O(1)./ Read a Word64 in native host order and host endianness.
715getWord64host   :: Get Word64
716getWord64host = getPtr  (sizeOf (undefined :: Word64))
717
718------------------------------------------------------------------------
719-- Unchecked shifts
720
721shiftl_w16 :: Word16 -> Int -> Word16
722shiftl_w32 :: Word32 -> Int -> Word32
723shiftl_w64 :: Word64 -> Int -> Word64
724
725#if defined(__GLASGOW_HASKELL__) && !defined(__HADDOCK__)
726shiftl_w16 (W16# w) (I# i) = W16# (w `uncheckedShiftL#`   i)
727shiftl_w32 (W32# w) (I# i) = W32# (w `uncheckedShiftL#`   i)
728
729#if WORD_SIZE_IN_BITS < 64
730shiftl_w64 (W64# w) (I# i) = W64# (w `uncheckedShiftL64#` i)
731
732#if __GLASGOW_HASKELL__ <= 606
733-- Exported by GHC.Word in GHC 6.8 and higher
734foreign import ccall unsafe "stg_uncheckedShiftL64"
735    uncheckedShiftL64#     :: Word64# -> Int# -> Word64#
736#endif
737
738#else
739shiftl_w64 (W64# w) (I# i) = W64# (w `uncheckedShiftL#` i)
740#endif
741
742#else
743shiftl_w16 = shiftL
744shiftl_w32 = shiftL
745shiftl_w64 = shiftL
746#endif
747
748
749-- Containers ------------------------------------------------------------------
750
751getTwoOf :: Get a -> Get b -> Get (a,b)
752getTwoOf ma mb = M.liftM2 (,) ma mb
753
754-- | Get a list in the following format:
755--   Word64 (big endian format)
756--   element 1
757--   ...
758--   element n
759getListOf :: Get a -> Get [a]
760getListOf m = go [] =<< getWord64be
761  where
762  go as 0 = return $! reverse as
763  go as i = do x <- m
764               x `seq` go (x:as) (i - 1)
765
766-- | Get an IArray in the following format:
767--   index (lower bound)
768--   index (upper bound)
769--   Word64 (big endian format)
770--   element 1
771--   ...
772--   element n
773getIArrayOf :: (Ix i, IArray a e) => Get i -> Get e -> Get (a i e)
774getIArrayOf ix e = M.liftM2 listArray (getTwoOf ix ix) (getListOf e)
775
776-- | Get a sequence in the following format:
777--   Word64 (big endian format)
778--   element 1
779--   ...
780--   element n
781getSeqOf :: Get a -> Get (Seq.Seq a)
782getSeqOf m = go Seq.empty =<< getWord64be
783  where
784  go xs 0 = return $! xs
785  go xs n = xs `seq` n `seq` do
786              x <- m
787              go (xs Seq.|> x) (n - 1)
788
789-- | Read as a list of lists.
790getTreeOf :: Get a -> Get (T.Tree a)
791getTreeOf m = M.liftM2 T.Node m (getListOf (getTreeOf m))
792
793-- | Read as a list of pairs of key and element.
794getMapOf :: Ord k => Get k -> Get a -> Get (Map.Map k a)
795getMapOf k m = Map.fromList `fmap` getListOf (getTwoOf k m)
796
797-- | Read as a list of pairs of int and element.
798getIntMapOf :: Get Int -> Get a -> Get (IntMap.IntMap a)
799getIntMapOf i m = IntMap.fromList `fmap` getListOf (getTwoOf i m)
800
801-- | Read as a list of elements.
802getSetOf :: Ord a => Get a -> Get (Set.Set a)
803getSetOf m = Set.fromList `fmap` getListOf m
804
805-- | Read as a list of ints.
806getIntSetOf :: Get Int -> Get IntSet.IntSet
807getIntSetOf m = IntSet.fromList `fmap` getListOf m
808
809-- | Read in a Maybe in the following format:
810--   Word8 (0 for Nothing, anything else for Just)
811--   element (when Just)
812getMaybeOf :: Get a -> Get (Maybe a)
813getMaybeOf m = do
814  tag <- getWord8
815  case tag of
816    0 -> return Nothing
817    _ -> Just `fmap` m
818
819-- | Read an Either, in the following format:
820--   Word8 (0 for Left, anything else for Right)
821--   element a when 0, element b otherwise
822getEitherOf :: Get a -> Get b -> Get (Either a b)
823getEitherOf ma mb = do
824  tag <- getWord8
825  case tag of
826    0 -> Left  `fmap` ma
827    _ -> Right `fmap` mb
828
829-- | Read in a length and then read a nested structure
830--   of that length.
831getNested :: Get Int -> Get a -> Get a
832getNested getLen getVal = do
833    n <- getLen
834    isolate n getVal
835
836-- | Get the number of bytes read up to this point
837bytesRead :: Get Int
838bytesRead = Get (\i b m w _ k -> k i b m w w)
839