{-# LANGUAGE CPP #-}
module System.Win32.Encoding
( getCurrentCodePage
, encodeMultiByte
, encodeMultiByteIO
, decodeMultiByte
, decodeMultiByteIO
, wideCharToMultiByte
, multiByteToWideChar
) where
import Foreign.C.Types (CInt(..))
import Foreign.C.String (peekCAStringLen, withCWStringLen)
import Foreign.Marshal.Array (allocaArray)
import Foreign.Marshal.Unsafe (unsafeLocalState)
import System.Win32.Console
import System.Win32.NLS
import System.Win32.Types
#include "windows_cconv.h"
getCurrentCodePage :: IO DWORD
getCurrentCodePage = do
conCP <- getConsoleCP
if conCP > 0
then return conCP
else getACP
encodeMultiByte :: CodePage -> String -> String
encodeMultiByte cp = unsafeLocalState . encodeMultiByteIO cp
encodeMultiByteIO :: CodePage -> String -> IO String
encodeMultiByteIO _ "" = return ""
encodeMultiByteIO cp wstr =
withCWStringLen wstr $ \(cwstr,len) -> do
mbchars' <- failIfZero "WideCharToMultiByte" $ wideCharToMultiByte
cp
0
cwstr
(fromIntegral len)
nullPtr 0
nullPtr nullPtr
allocaArray (fromIntegral mbchars') $ \mbstr -> do
mbchars <- failIfZero "WideCharToMultiByte" $ wideCharToMultiByte
cp
0
cwstr
(fromIntegral len)
mbstr mbchars'
nullPtr nullPtr
peekCAStringLen (mbstr,fromIntegral mbchars)
foreign import WINDOWS_CCONV "WideCharToMultiByte"
wideCharToMultiByte
:: CodePage
-> DWORD
-> LPCWSTR
-> CInt
-> LPSTR
-> CInt
-> LPCSTR
-> LPBOOL
-> IO CInt
decodeMultiByte :: CodePage -> String -> String
decodeMultiByte cp = unsafeLocalState . decodeMultiByteIO cp
decodeMultiByteIO :: CodePage -> String -> IO String
decodeMultiByteIO = stringToUnicode
{-# INLINE decodeMultiByteIO #-}