--- --------------------------------------------------------------
--- Main wrappers: getBinFileWithDict, putBinFileWithDict
---
--- This layer is built on top of the stuff above,
--- and should not know anything about BinHandles
--- --------------------------------------------------------------
-
-initBinMemSize = (1024*1024) :: Int
-
-#if WORD_SIZE_IN_BITS == 32
-binaryInterfaceMagic = 0x1face :: Word32
-#elif WORD_SIZE_IN_BITS == 64
-binaryInterfaceMagic = 0x1face64 :: Word32
-#endif
-
-getBinFileWithDict :: Binary a => FilePath -> IO a
-getBinFileWithDict file_path = do
- bh <- Binary.readBinMem file_path
-
- -- Read the magic number to check that this really is a GHC .hi file
- -- (This magic number does not change when we change
- -- GHC interface file format)
- magic <- get bh
- when (magic /= binaryInterfaceMagic) $
- throwDyn (ProgramError (
- "magic number mismatch: old/corrupt interface file?"))
-
- -- Read the dictionary
- -- The next word in the file is a pointer to where the dictionary is
- -- (probably at the end of the file)
- dict_p <- Binary.get bh -- Get the dictionary ptr
- data_p <- tellBin bh -- Remember where we are now
- seekBin bh dict_p
- dict <- getDictionary bh
- seekBin bh data_p -- Back to where we were before
-
- -- Initialise the user-data field of bh
- let bh' = setUserData bh (initReadState dict)
-
- -- At last, get the thing
- get bh'
-
-putBinFileWithDict :: Binary a => FilePath -> a -> IO ()
-putBinFileWithDict file_path the_thing = do
- bh <- openBinMem initBinMemSize
- put_ bh binaryInterfaceMagic
-
- -- Remember where the dictionary pointer will go
- dict_p_p <- tellBin bh
- put_ bh dict_p_p -- Placeholder for ptr to dictionary
-
- -- Make some intial state
- usr_state <- newWriteState
-
- -- Put the main thing,
- put_ (setUserData bh usr_state) the_thing
-
- -- Get the final-state
- j <- readIORef (ud_next usr_state)
- fm <- readIORef (ud_map usr_state)
- dict_p <- tellBin bh -- This is where the dictionary will start
-
- -- Write the dictionary pointer at the fornt of the file
- putAt bh dict_p_p dict_p -- Fill in the placeholder
- seekBin bh dict_p -- Seek back to the end of the file
-
- -- Write the dictionary itself
- putDictionary bh j (constructDictionary j fm)
-
- -- And send the result to the file
- writeBinMem bh file_path
-