+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE ForeignFunctionInterface #-}
+module Mate.Strings (
+ getUniqueStringAddr
+ ) where
+
+import Data.Word
+import qualified Data.Map as M
+import qualified Data.ByteString.Lazy as B
+import qualified Data.ByteString.Internal as BI
+import Text.Printf
+
+import Foreign.Ptr
+import Foreign.ForeignPtr
+import Foreign.Marshal.Array
+
+import Mate.Types
+
+
+getUniqueStringAddr :: B.ByteString -> IO Word32
+getUniqueStringAddr str = do
+ smap <- get_stringsmap >>= ptr2stringsmap
+ case M.lookup str smap of
+ Nothing -> do
+ addr <- allocateJavaString str
+ let smap' = M.insert str addr smap
+ stringsmap2ptr smap' >>= set_stringsmap
+ return addr
+ Just addr -> return addr
+
+-- TOOD(bernhard): quite hackish
+allocateJavaString :: B.ByteString -> IO Word32
+allocateJavaString str = do
+ let strlen = fromIntegral $ B.length str
+ let str_unpacked = (map fromIntegral $ B.unpack str) :: [Word8]
+ arr <- newArray str_unpacked
+ newstr <- BI.create strlen (\x -> BI.memcpy x arr (fromIntegral strlen))
+ let (newstrptr, _, _) = BI.toForeignPtr newstr
+ let w32_ptr = fromIntegral $ ptrToIntPtr $ unsafeForeignPtrToPtr newstrptr
+ printf "new str ptr: 0x%08x\n" w32_ptr
+ return w32_ptr