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