How to import unicode data from WinHttpReq

95 Views Asked by At

WinHttpRequest is used to import bank statement from Nordiget.com containing characters from Windows-1257 code page. For an unknown reason, FoxPro does replace accented characters with? signs. To fix this, COMPROP(WinHttpReq ,"UTF8",1) is added:

  WinHttpReq = CREATEOBJECT("WinHttp.WinHttpRequest.5.1")
  WinHttpReq.Open("GET", "https://ob.nordigen.com/api/v2/accounts/11111-22222-333333-4444-/transactions/", .f.)
  WinHttpReq.setrequestheader('accept', 'application/json')
  WinHttpReq.setrequestheader('Authorization', "Bearer afde554a5sd45a45as4")
  WinHttpReq.Send()
  * If this is removed, accented characters appear as single question characters:
  COMPROP(WinHttpReq ,"UTF8",1)

Response WinHttpReq.ResponseText contains accented characters represented by 4 bytes. The first 3 are the same but the fourth is different. Those characters are converted by code using

Function NordigetConvert(cStr)
cstr = strt( cStr, CHR(0xc3)+CHR(0x83)+ CHR(0xc2)+CHR(0x9c) , 'Ü' ) 
cstr = strt( cStr, CHR(0xc3)+CHR(0x83)+ CHR(0xc2)+CHR(0xBC) , 'ü' ) 
cstr = strt( cStr, CHR(0xc3)+CHR(0x83)+ CHR(0xc2)+CHR(0x84) , 'Ä' ) 
cstr = strt( cStr, CHR(0xc3)+CHR(0x83)+ CHR(0xc2)+CHR(0xB6) , 'ö' ) 
return cStr

This converts only ÜüÄö. There are much more characters to convert.

Tried

STRCONV(strconv(CHR(0xc3)+CHR(0x83)+ CHR(0xc2)+CHR(0x9c) ,10) ,11, 1257, 1)

this should return letter Ü but returns two question marks. Tried also code below from https://github.com/VFPX/Win32API/blob/master/libraries/kernel32/WideCharToMultiByte.md but it still returns two question marks. How to convert it?

SET ECHO OFF
SET TALK OFF
CLEAR


#DEFINE CF_UNICODETEXT  13
DO decl
 
LOCAL hData, lcUnicode

MESSAGEBOX( uconv (CHR(0xc3)+CHR(0x83)+ CHR(0xc2)+CHR(0x9c), 1257)  )

* end of main
 
FUNCTION uconv (lcSrc, lnCodePage)
    LOCAL lcDst, lnUsedDefault, lnResult
    lcDst = Repli(Chr(0), Len(lcSrc) * 2)
    lnUsedDefault = 0
 
    lnResult = WideCharToMultiByte (lnCodePage, 0,;
        lcSrc, Len(lcSrc),;
        @lcDst, Len(lcDst), "?", 0)
 
    IF lnResult = 0
    *   87 - ERROR_INVALID_PARAMETER
    *  122 - ERROR_INSUFFICIENT_BUFFER
    * 1004 - ERROR_INVALID_FLAGS
        ? "Error code:", GetLastError()
        lcDst = ""
    ELSE
        lcDst = SUBSTR(lcDst, 1, lnResult)
    ENDIF
RETURN SUBSTR(lcDst, 1, AT(Chr(0),lcDst)-1)
 
FUNCTION  memwchar2str (lnMemBlock)
* copies Unicode characters (two-byte) from a memory address to a VFP string
RETURN  mem2str(lnMemBlock, Chr(0)+Chr(0))
 
FUNCTION  mem2str(lnMemBlock, end_sequence)
#DEFINE BUFFER_SIZE   16
#DEFINE EMPTY_BUFFER  Repli(Chr(0), BUFFER_SIZE)
 
    DECLARE RtlMoveMemory IN kernel32 As Heap2Str;
        STRING @, INTEGER, INTEGER
 
    LOCAL lnPtr, lcResult, lcBuffer, lnPos
    lnPtr = lnMemBlock
    lcResult = ""
 
    DO WHILE .T.
        lcBuffer = EMPTY_BUFFER
        = Heap2Str (@lcBuffer, lnPtr, BUFFER_SIZE)
        lnPos = AT(end_sequence, lcBuffer)
        IF lnPos > 0
            lcResult = lcResult + SUBSTR(lcBuffer, 1, lnPos-1)
            RETURN  lcResult
        ELSE
            lcResult = lcResult + lcBuffer
            lnPtr = lnPtr + BUFFER_SIZE
        ENDIF
    ENDDO
 
PROCEDURE decl
    DECLARE INTEGER GetLastError IN kernel32
    DECLARE INTEGER OpenClipboard IN user32 INTEGER hwnd
    DECLARE INTEGER CloseClipboard IN user32
    DECLARE INTEGER GetClipboardData IN user32 INTEGER uFormat
    DECLARE INTEGER IsClipboardFormatAvailable IN user32 INTEGER wFormat
 
    DECLARE INTEGER WideCharToMultiByte IN kernel32;
        INTEGER CodePage, INTEGER dwFlags, STRING lpWideCharStr,;
        INTEGER cchWideChar, STRING @lpMultiByteStr, INTEGER cbMultiByte,;
        STRING lpDefaultChar, INTEGER lpUsedDefaultChar
0

There are 0 best solutions below