packages feed

Win32-security-0.1: src/System/Win32/Security/MarshalText.hs

-- | Helper functions to marshal the text back and forth to null-terminated CWchar.
-- Borrowed from a Win32-junction-point package
module System.Win32.Security.MarshalText
  ( useAsPtr0
  , fromPtr0
  ) where

import Data.Char (chr)
import Foreign
import Foreign.C
import Foreign.Marshal.Array (lengthArray0)
import qualified Data.Text as T
import qualified Data.Text.Foreign as T

-- | useAsPtr returns a length and byte buffer, but all the win32 functions
-- rely on null termination.
useAsPtr0 :: T.Text -> (Ptr CWchar -> IO a) -> IO a
useAsPtr0 t f = T.useAsPtr (T.snoc t (chr 0x0)) $ \ str _ -> f  (castPtr str)

-- This traverses the string twice. Is there a faster way?
fromPtr0 :: Ptr CWchar -> IO T.Text
fromPtr0 ptr = do
    -- length in 16-bit words.
    len <- lengthArray0 0x0000 ptr'
    -- no loss of precision here. I16 is a newtype wrapper around Int.
    T.fromPtr ptr' $ fromIntegral len
  where
    ptr' :: Ptr Word16
    ptr' = castPtr ptr