How to import unicode data from WinHttpReq - com

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

Related

Get number from Excel column

I'm am using the code example below to represent an integer as an alphabetic string
Private Function GetExcelColumnName(columnNumber As Integer) As String
Dim dividend As Integer = columnNumber
Dim columnName As String = String.Empty
Dim modulo As Integer
While dividend > 0
modulo = (dividend - 1) Mod 26
columnName = Convert.ToChar(65 + modulo).ToString() & columnName
dividend = CInt((dividend - modulo) / 26)
End While
Return columnName
End Function
I found the above example here:
Converting Numbers to Excel Letter Column vb.net
How do I get the reverse, for example:
123 = DS -- Reverse -- DS = 123
35623789 = BYXUWS -- Reverse -- BYXUWS = 35623789
Is it possible to get the number from the alphabetic string without importing Excel?
I found an answer from another post. This function below will work to get the reverse
Public Function GetCol(c As String) As Long
Dim i As Long, t As Long
c = UCase(c)
For i = Len(c) To 1 Step -1
t = t + ((Asc(Mid(c, i, 1)) - 64) * (26 ^ (Len(c) - i)))
Next i
GetCol = t
End Function

vb.net arithmetic operation resulted in an overflow in decryption

I am working on new decryption functions for password recovery tools. I tried code in c++ and worked:
void poco_pwd(u_char *pwd, int type) {
int len,
tmp;
u_char *out;
short azz;
if(type) azz = 0x2537; // encrypt message
else azz = 0x2a9a; // other passwords
len = strlen(pwd) >> 1;
out = pwd;
while(len--) {
sscanf(pwd, "%02X", &tmp);
pwd += 2;
*out++ = tmp ^ (azz >> 8);
azz = ((tmp + azz) * 0x8141) + 0x3171;
}
*out = 0;
}
I tried to convert this code to vb.net and c# but it throws arithmetic overflow operation. This functions new value is put to "azz" variable. "azz" is a short variable but this these values are very high. Strange is that it works in c++.
I converted this code to vb.net:
Dim encpass As String = "1EF66D8BD3C32476CEC8CF"
Dim encpassByte As Byte() = Encoding.UTF8.GetBytes(HexToString(encpass))
Dim azz As Integer = &H2A9A
Dim len As Integer = encpassByte.Length >> 1
Dim storage(len) As Char
For i = 0 To len
storage(i) = (ChrW(encpassByte(i) Xor (azz >> 8)))
azz = ((encpassByte(i) + azz) * &H8141) + &H3171 //Error: arithmetic operation resulted in an overflow.
Next
Console.WriteLine(storage.ToString)
Console.ReadKey()
Hex to string function:
Function HexToString(ByVal hex As String) As String
Dim text As New System.Text.StringBuilder(hex.Length \ 2)
For i As Integer = 0 To hex.Length - 2 Step 2
text.Append(Chr(Convert.ToByte(hex.Substring(i, 2), 16)))
Next
Return text.ToString
End Function
This code throws this error: arithmetic operation resulted in an overflow.

Performance loss in VB.net equivalent of light weight conversion from hex to byte

I have read through the answers here https://stackoverflow.com/a/14332574/44080
I've also tried to produce equivalent VB.net code:
Option Strict ON
Public Function ParseHex(hexString As String) As Byte()
If (hexString.Length And 1) <> 0 Then
Throw New ArgumentException("Input must have even number of characters")
End If
Dim length As Integer = hexString.Length \ 2
Dim ret(length - 1) As Byte
Dim i As Integer = 0
Dim j As Integer = 0
Do While i < length
Dim high As Integer = ParseNybble(hexString.Chars(j))
j += 1
Dim low As Integer = ParseNybble(hexString.Chars(j))
j += 1
ret(i) = CByte((high << 4) Or low)
i += 1
Loop
Return ret
End Function
Private Function ParseNybble(c As Char) As Integer
If c >= "0"C AndAlso c <= "9"C Then
Return c - "0"C
End If
c = ChrW(c And Not &H20)
If c >= "A"C AndAlso c <= "F"C Then
Return c - ("A"C - 10)
End If
Throw New ArgumentException("Invalid nybble: " & c)
End Function
Can we remove the compile errors in ParseNybble without introducing data conversions?
Return c - "0"c Operator '-' is not defined for types 'Char' and 'Char'
c = ChrW(c And Not &H20) Operator 'And' is not defined for types 'Char' and 'Integer'
As it stands, no.
However, you could change ParseNybble to take an integer and pass AscW(hexString.Chars(j)) to it, so that the data conversion takes place outside of ParseNybble.
This solution is much much faster than all the alternative i have tried. And it avoids any ParseNybble lookup.
Function hex2byte(s As String) As Byte()
Dim l = s.Length \ 2
Dim hi, lo As Integer
Dim b(l - 1) As Byte
For i = 0 To l - 1
hi = AscW(s(i + i))
lo = AscW(s(i + i + 1))
hi = (hi And 15) + ((hi And 64) >> 6) * 9
lo = (lo And 15) + ((lo And 64) >> 6) * 9
b(i) = CByte((hi << 4) Or lo)
Next
Return b
End Function

Need VB code commented to convert it to Java

I am a Java developer. I have the task of converting a VB class to Java.
Can some VB developer comment the following VB code so that I can write its Java equivalent?
Public Class RmaValidationCode
' Values for test type
Public Const SOFTWARE_TEST_TYPE = 0
Public Const FIRMWARE_TEST_TYPE = 1
' Values for test length
Public Const SHORT_TEST_LENGTH = 0
Public Const LONG_TEST_LENGTH = 1
' Values for test result
Public Const PASS_TEST_RESULT = 0
Public Const FAIL_TEST_RESULT = 1
Public Const ABORT_TEST_RESULT = 2
Public Const CAUTION_TEST_RESULT = 3
' GetRMAValidationCode function bit mapped return values
Public Const RMA_VC_RET_PASS = 0
Public Const RMA_VC_RET_NULL_PTR_PARAMETER = 1
Public Const RMA_VC_RET_INVALID_STR_LENGTH = 2
Public Const RMA_VC_RET_INVALID_SN_STRING = 4
Public Const RMA_VC_RET_INVALID_TEST_TYPE = 8
Public Const RMA_VC_RET_INVALID_TEST_LENGTH = 16
Public Const RMA_VC_RET_INVALID_TEST_RESULT = 32
Private Const RMA_LENGTH = 8
Private rmaValidationCode As String
' This function will return the warranty validation code based on serial number, test type,
' test result, test software and test length.
' Test type - Generic=0, DST=1
' Test result - Pass=0, FAIL=1
' Test Software - DOS=0, Windows=1
' Test Length - Short=0 Long=1
Public Function GetRMAValidationCode(ByVal serialNumber As String, ByVal testType As Byte, _
ByVal testResult As Byte, ByVal testSoftware As Byte, ByVal testLength As Byte)
Dim returnValue As UInt32
Dim tempRMACode As String
Dim tempRMAEnumerator As CharEnumerator
Dim temp8Bit As Byte
returnValue = RMA_VC_RET_PASS
temp8Bit = 0
' Make sure we were passed valid strings
If String.IsNullOrEmpty(serialNumber) OrElse _
String.IsNullOrEmpty(rmaValidationCode) Then
returnValue = returnValue Or RMA_VC_RET_NULL_PTR_PARAMETER
End If
' Make sure our strings are big enough
If serialNumber.Length < RMA_LENGTH OrElse _
rmaValidationCode.Length < RMA_LENGTH Then
returnValue = returnValue Or RMA_VC_RET_INVALID_STR_LENGTH
End If
' Assure that valid test types were passed in
If testType <> SOFTWARE_TEST_TYPE AndAlso _
testType <> FIRMWARE_TEST_TYPE Then
returnValue = returnValue Or RMA_VC_RET_INVALID_TEST_TYPE
End If
' Assure that valid test lengths were passed in
If testLength <> SHORT_TEST_LENGTH AndAlso _
testLength <> LONG_TEST_LENGTH Then
returnValue = returnValue Or RMA_VC_RET_INVALID_TEST_LENGTH
End If
' Assure that valid test results were passed in
If testResult <> PASS_TEST_RESULT AndAlso _
testResult <> FAIL_TEST_RESULT AndAlso _
testResult <> ABORT_TEST_RESULT AndAlso _
testResult <> CAUTION_TEST_RESULT Then
returnValue = returnValue Or RMA_VC_RET_INVALID_TEST_RESULT
End If
If returnValue = RMA_VC_RET_PASS Then
' Trim leading and trailing whitespace
serialNumber.Trim()
' Check to see if the serialNumber string is long enough
' after whitespace is removed
If serialNumber.Length < RMA_LENGTH Then
Return RMA_VC_RET_INVALID_SN_STRING
End If
tempRMACode = serialNumber.ToLower()
tempRMAEnumerator = tempRMACode.GetEnumerator()
While (tempRMAEnumerator.MoveNext())
If Not Char.IsLetterOrDigit(tempRMAEnumerator.Current) Then
Return RMA_VC_RET_INVALID_SN_STRING
End If
End While
' Initialize the rmaValidationCode
rmaValidationCode = ""
' Compute and save the first 6 bytes of RMA Validation Code
temp8Bit = 0
temp8Bit = Convert.ToByte(tempRMACode.ToCharArray().GetValue(0)) + Convert.ToByte((tempRMACode.ToCharArray()).GetValue(7))
rmaValidationCode += String.Format("{0:X2}", temp8Bit)
temp8Bit = 0
temp8Bit = Convert.ToByte((tempRMACode.ToCharArray()).GetValue(1)) + Convert.ToByte((tempRMACode.ToCharArray()).GetValue(6))
rmaValidationCode += String.Format("{0:X2}", temp8Bit)
temp8Bit = 0
temp8Bit = Convert.ToByte((tempRMACode.ToCharArray()).GetValue(2)) + Convert.ToByte((tempRMACode.ToCharArray()).GetValue(5))
rmaValidationCode += String.Format("{0:X2}", temp8Bit)
' Byte 6 is the Test & Result byte.
temp8Bit = 0
temp8Bit = (testSoftware << 3) Or (testResult << 2) Or (testType << 1) Or testLength
rmaValidationCode += String.Format("{0:X1}", temp8Bit)
' Compute the parity byte
temp8Bit = 0
Dim mychar As Char
mychar = rmaValidationCode.ToCharArray().GetValue(3)
If ((Convert.ToInt32(rmaValidationCode.ToCharArray().GetValue(3), 16) Mod 2) = 1) Then
temp8Bit = temp8Bit Or (1 << 3)
Else
temp8Bit = temp8Bit Or (0 << 3)
End If
Dim value As Integer
mychar = rmaValidationCode.ToCharArray().GetValue(2)
value = System.Convert.ToInt32(mychar, 16)
If ((Convert.ToInt32(rmaValidationCode.ToCharArray().GetValue(2), 16) Mod 2) = 1) Then
temp8Bit = temp8Bit Or (1 << 2)
Else
temp8Bit = temp8Bit Or (0 << 2)
End If
mychar = rmaValidationCode.ToCharArray().GetValue(1)
If ((Convert.ToInt32(rmaValidationCode.ToCharArray().GetValue(1), 16) Mod 2) = 1) Then
temp8Bit = temp8Bit Or (1 << 1)
Else
temp8Bit = temp8Bit Or (0 << 1)
End If
mychar = rmaValidationCode.ToCharArray().GetValue(0)
If ((Convert.ToInt32(rmaValidationCode.ToCharArray().GetValue(0), 16) Mod 2) = 1) Then
temp8Bit = temp8Bit Or 1
Else
temp8Bit = temp8Bit Or 0
End If
rmaValidationCode += String.Format("{0:X1}", temp8Bit)
End If
Return rmaValidationCode
End Function
Public Sub New()
' serialNumber = " "
rmaValidationCode = " "
' testType = 0
'testLength = 0
'testResult = 0
End Sub
End Class
Actually that is pretty readable and straightforward code. You may want to take a look at VB keywords as well as the AndAlso/OrElse operators (those two sometimes confuse C-style language developers). The rest that's used are just plain old .NET class library methods. Nothing too fancy and you'll find plenty of documentation about those on MSDN.
Unfortunately you're not going to find anyone here that will comment the above code for free.
Visual Basic syntax is relatively simple - it was designed as an entry level language. If you engage your mind and read over the general key words such as AndAlso OrElse WhileNot etc, you shouldn't have a massive issue commenting it yourself.
If you were further interested in the way the code works - the way I usually learn to understand X piece of code is to go step - by - step through it until I finally get the gist of it.
Try searching MSDN for any keywords you don't fully understand.

How to show the Windows File copying progress dialog throug PB?

I used the functions CopyFilea and ShFileOperation. CopyFileA it copied the file(large cumbersome data). but it didn't show the Copy Progress and Also tried in SHFileOperation api this shows the error.
PB Version is 10.2.0 build 7516
Error Msg: Error Calling external function %s
any body Please give me a solution?
There is a discussion of SHFileOperation on sybase.public.powerbuilder.general . This code block shows how to set up the structure correctly, for a delete operation in this case - does it help?
type os_shfileopstruct from structure
unsignedlong hwnd
unsignedlong wfunc
blob pfrom
blob pto
unsignedinteger fflags
unsignedlong banyoperationsaborted
unsignedlong hnamemappings
string lpszprogresstitle
end type
//inside a function call:
// Arguments: as_SourceFile - the file(s) to delete.
// aui_flags - file operation flags (0 - default)
// aw_requestor - the requesting window
os_shfileopstruct lstr_FileOp
Integer li_rc
lstr_FileOp.hWnd = Handle(aw_requestor)
lstr_FileOp.wFunc = FO_DELETE
lstr_FileOp.pFrom = Blob( as_SourceFile + Space(2) )
BlobEdit( lstr_FileOp.pFrom, Len( as_sourcefile ) + 1, Char(0) )
BlobEdit( lstr_FileOp.pFrom, Len( as_sourcefile ) + 2, Char(0) )
lstr_FileOp.fFlags = aui_flags
lstr_FileOp.hNameMappings = 0
lstr_FileOp.lpszProgressTitle = Space(10)
li_rc = SHFileOperationA( lstr_FileOp )
IF li_rc <> 0 THEN
IF NOT IsNull( lstr_FileOp ) THEN
IF lstr_FileOp.bAnyOperationsAborted = 1 THEN
RETURN 0
END IF
END IF
ELSE
-1
END IF
RETURN 1
from sybase.public.powerbuilder.general
What is your operating system? SHFileOperation has has been replaced in Windows Vista by IFileOperation.