neko-lib-0.0.1.0: src/lib/Binary/Neko/Hashtbl.hs
{-|
Module : Binary.Neko.Hashtbl
Description : Minimal hashtable support
Copyright : (c) Petr Penzin, 2015
License : BSD2
Maintainer : penzin.dev@gmail.com
Stability : experimental
Portability : cross-platform
A minimal support for Binary.Neko hashtable type needed for working with tables of fields
-}
module Binary.Neko.Hashtbl where
import qualified Data.Map.Strict as M
import Data.ByteString.Char8 as BC
import Data.ByteString as B
import Data.Word
-- | A minimal hashtable type. Binary.Neko supports hashing of all types,
-- but we will focus on strings, since those are necessary for assembly and disassembly
type Hashtbl = M.Map Word32 String
-- | Binary.Neko 'hash_field' function
hash :: String -> Word32
hash s = hash' bs
where bs = B.reverse $ BC.pack s
hash' b | B.null b = 0
hash' b | otherwise = (hash' $ B.tail b) * 223 + (fromIntegral $ B.head b)
-- | Create an empty Hashtbl, wrapper for corresponding Map function
empty :: Hashtbl
empty = M.empty
-- | Check whether there is a member for a given key, wrapper for corresponding Map function
member :: Word32 -> Hashtbl -> Bool
member = M.member
-- | Check whether there is a member for a given value
memberString :: String -> Hashtbl -> Bool
memberString s h = M.member (hash s) h
-- | Insert a string to Hashtbl
insertString :: String -> Hashtbl -> Hashtbl
insertString s h = M.insert (hash s) s h
-- | Lookup a value by its key, wrapper for corresponding Map function
lookup :: Word32 -> Hashtbl -> Maybe String
lookup = M.lookup
-- | Convert entire Hashtbl ot a list of key-value pairs, wrapper for corresponding Map function
toList :: Hashtbl -> [(Word32, String)]
toList = M.toList
-- | Convert a list of strings into a Hashtbl, generating hash values for them
fromStringList :: [String] -> Hashtbl
fromStringList ss = M.fromList $ Prelude.map (\s -> (hash s, s)) ss
-- | Get a list of elements (values) in the Hashtbl, wrapper for corresponding Map function
elems :: Hashtbl -> [String]
elems = M.elems