{-# LANGUAGE CPP #-}{- | Module : System.Win32.Encoding Copyright : 2012 shelarcy License : BSD-style Maintainer : shelarcy@gmail.com Stability : Provisional Portability : Non-portable (Win32 API) Enocode/Decode mutibyte character using Win32 API. -}moduleSystem.Win32.Encoding(getCurrentCodePage,encodeMultiByte,encodeMultiByteIO,decodeMultiByte,decodeMultiByteIO,wideCharToMultiByte,multiByteToWideChar)whereimportForeign.C.Types(CInt(..))importForeign.C.String(peekCAStringLen,withCWStringLen)importForeign.Marshal.Array(allocaArray)importForeign.Marshal.Unsafe(unsafeLocalState)importSystem.Win32.ConsoleimportSystem.Win32.NLSimportSystem.Win32.Types #include "windows_cconv.h" -- note CodePage = UInt which might not work on Win64. But the Win32 package -- also has this issue. getCurrentCodePage::IODWORDgetCurrentCodePage=doconCP<-getConsoleCPifconCP>0thenreturnconCPelsegetACP-- | The "System.IO" output functions (e.g., `putStr`) don't -- automatically convert to multibyte string on Windows, so this -- function is provided to make the conversion from a Unicode string -- in the given code page to a proper multibyte string. To get the -- code page for the console, use `getCurrentCodePage`. -- encodeMultiByte::CodePage->String->StringencodeMultiBytecp=unsafeLocalState.encodeMultiByteIOcpencodeMultiByteIO::CodePage->String->IOStringencodeMultiByteIO_""=return""-- WideCharToMultiByte doesn't handle empty strings encodeMultiByteIOcpwstr=withCWStringLenwstr$\(cwstr,len)->dombchars'<-failIfZero"WideCharToMultiByte"$wideCharToMultiBytecp0cwstr(fromIntegrallen)nullPtr0nullPtrnullPtr-- mbchar' is the length of buffer required allocaArray(fromIntegralmbchars')$\mbstr->dombchars<-failIfZero"WideCharToMultiByte"$wideCharToMultiBytecp0cwstr(fromIntegrallen)mbstrmbchars'nullPtrnullPtrpeekCAStringLen(mbstr,fromIntegralmbchars)-- converts [Char] to UTF-16 foreignimportWINDOWS_CCONV"WideCharToMultiByte"wideCharToMultiByte::CodePage->DWORD-- dwFlags, ->LPCWSTR-- lpWideCharStr ->CInt-- cchWideChar ->LPSTR-- lpMultiByteStr ->CInt-- cbMultiByte ->LPCSTR-- lpMultiByteStr ->LPBOOL-- lpbFlags ->IOCInt-- | The "System.IO" input functions (e.g. `getLine`) don't -- automatically convert to Unicode, so this function is provided to -- make the conversion from a multibyte string in the given code page -- to a proper Unicode string. To get the code page for the console, -- use `getCurrentCodePage`. decodeMultiByte::CodePage->String->StringdecodeMultiBytecp=unsafeLocalState.decodeMultiByteIOcp-- | Because of `stringToUnicode` is unclear name, we use `decodeMultiByteIO` -- for alias of `stringToUnicode`. decodeMultiByteIO::CodePage->String->IOStringdecodeMultiByteIO=stringToUnicode{-# INLINEdecodeMultiByteIO#-}