The author of HIME (http://www.devotechs.com/) (Huge Integer Math and Encryption) library, Eddy Van Esch, has graciously helped me with the programs and granted permission to post these programs on the forums as a kind of tutorial. I will also post the programs on the CB forums.
The hi_PutReg function cannot be translated to EBasic because it uses dynamic (OLE) strings.
So? Then use OLE strings then.
They may not be a buillt in type but you can definately use OLE system strings in Emergence.
Thanks, Paul. I didn't know that.
How do I set up and use OLE strings?
This should get you started:
'OLE strings (BSTR) are just unicode strings that have the length of the string in the
'four bytes preceeding the beginning of the string.
declare import, SysAllocString(wstring in),pointer
declare import, SysFreeString(pointer bstr)
declare import, SysStringLen(pointer bstr),int
pointer mystr:mystr = SysAllocString(L"Hello There")
print SysStringLen(mystr)
'An OLE string is just a unicode string.
print w2s(*<WSTRING>mystr)
'free the string unless you pass it to another function that does it for you.
SysFreeString(mystr)
Do:until inkey$<> ""
Thanks, Paul.
Sounds like a good candidate for a Class definition.
Paul,
Closer examination of PB shows that their strings as ascii and not wide strings(unicode).
Another question. How is it possible to store embedded nulls inside a string?
Memory variables?
Quote from: REDEBOLT on February 10, 2008, 11:35:59 PM
Closer examination of PB shows that their strings as ascii and not wide strings(unicode).
Then they can't be OLE strings as all OLE strings are unicode.
I've shown quite a few times on the forums how to embed nulls in a string, using the substitution of a key character. Search for them ;)
Paul.
I have searched for "embed," "substitute key character," "substitute," "0x00," "nul," "null," "insert"
plus trying to visually search through the subject headings, with no luck.
Can you give me a hint?
Hint: http://www.ionicwind.com/forums/index.php/topic,1415.msg19298.html#msg19298
Larry
Thanks, Larry.
I don't know why my searches were not working.
:)
If we have a string, and know its length, then we can use "hi_PutRegAdd." This source code is included in the attached zip file along with the source for the "HIME.INC" file and the requisite dlls. Note that this format allows us to have embedded nulls within the string.
' hi_PutRegAdd.EBA
'
' This program tests the hi_PutRegAdd function by
' loading an ascii value into a hime register.
'
$MAIN
AUTODEFINE "OFF"
'$USE "HIME_IOTest.lib"
$USE "HIME.lib"
$INCLUDE "HIME.INC"
DECLARE IMPORT, GetTickCount(),UINT
DEF time1 AS UINT
DEF time2 AS UINT
DEF lAddress AS POINTER
DEF lLen AS INT
DEF izData[2000] as ISTRING ' Make sure that string variable is large enough to hold the result.
INT h1:h1=1 ' Register 1.
OPENCONSOLE
time1 = GetTickCount()
PRINT
izData = "sweat and tears - this is a long string"
lAddress = izData
lLen = LEN(izData)
hi_PutRegAdd(lAddress, lLen, h1) ' The return value is not needed.
SETPRECISION (3)
time2 = GetTickCount()
PRINT (time2-time1)/1000.000, " secs."
PRINT:PRINT "Done..."
PRINT:PRINT "Press any key to end program."
PRINT
DO:UNTIL INKEY$<>""
CLOSECONSOLE
END
If we have a null-terminated string, then we can use "hi_PutRegAsciiz." This source code is included in the attached zip file along with the source for the "HIME.INC" file and the requisite dlls.
' hi_PutRegAsciiz.EBA
'
' This program tests the hi_PutRegAsciiz function by
' loading an ascii value into a hime register.
'
$MAIN
AUTODEFINE "OFF"
'$USE "HIME_IOTest.lib"
$USE "HIME.lib"
$INCLUDE "HIME.INC"
DECLARE IMPORT, GetTickCount(),UINT
DEF time1 AS UINT
DEF time2 AS UINT
DEF lAddress AS POINTER
DEF lLen AS INT
DEF izData[2000] as ISTRING ' Make sure that string variable is large enough to hold the result.
INT h1:h1=1 ' Register 1.
OPENCONSOLE
time1 = GetTickCount()
PRINT
izData = "sweat and tears - this is a long string"
hi_PutRegAsciiz( izData, h1 ) ' The return value is not needed.
SETPRECISION (3)
time2 = GetTickCount()
PRINT (time2-time1)/1000.000, " secs."
PRINT:PRINT "Done..."
PRINT:PRINT "Press any key to end program."
PRINT
DO:UNTIL INKEY$<>""
CLOSECONSOLE
END
The "hi_PutRegDword" function puts 32 bits unsigned integer data in one of the HIME internal registers.
The data can contain an integer ranging from 0 to 4294967295.
After storing data in a huge integer register with hi_PutRegDword, this data can immediately be used to perform huge integer calculations because it has the 'huge integer' format.
The source is included in the zip file below. Note that the hime.dll will no longer be in the zip file containing the source in order to conserve space on the website. The hime.dll can be obtained from a post prior to this one, or directly from the DevOTechS (http://www.devotechs.com/HIMEMain.html#Available_versions) website.
Note that the hime.inc file has been updated from prior posts.
' hi_PutRegDword.EBA
'
' This program tests the hi_PutRegDword function by
' loading an unsigned integer into a hime register.
' The data can contain an integer ranging from 0 to 4294967295.
' After storing data in a huge integer register with hi_PutRegDword,
' this data can immediately be used to perform huge integer calculations
' because it has the 'huge integer' format.
'
$MAIN
AUTODEFINE "OFF"
'$USE "HIME_IOTest.lib"
$USE "HIME.lib"
$INCLUDE "HIME.INC"
DECLARE IMPORT, GetTickCount(),UINT
DEF time1 AS UINT
DEF time2 AS UINT
DEF izData[2000] as ISTRING ' Make sure that string variable is large enough to hold the result.
INT h1:h1=1 ' Register 1.
INT h2:h2=2 ' Register 2.
INT h3:h3=3 ' Register 3.
INT h4:h4=4 ' Register 4.
INT h5:h5=5 ' Register 5.
INT h6:h6=6 ' Register 6.
INT h7:h7=7 ' Register 7.
INT h8:h8=8 ' Register 8.
INT h9:h9=9 ' Register 9.
INT h10:h10=10 ' Register 10.
INT h11:h11=11 ' Register 11.
INT h12:h12=12 ' Register 12.
INT h13:h13=13 ' Register 13.
INT h14:h14=14 ' Register 14.
INT h15:h15=15 ' Register 15.
INT h16:h16=16 ' Register 16.
INT h17:h17=17 ' Register 17.
INT h18:h18=18 ' Register 18.
INT h19:h19=19 ' Register 19.
INT h20:h20=20 ' Register 20.
OPENCONSOLE
time1 = GetTickCount()
PRINT
INT i
UINT d
STRING zh1
PRINT "hi_PutRegDword | hi_Huge2Dec | hi_GetRegDword | hi_GetRegLong"
PRINT "--------------------------------------------------------------"
zh1 = " ############# | & | ########### | #############"
d = 0
hi_PutRegDword(d, h2)
hi_Huge2Dec (h2,h10)
hi_GetRegAsciiz2(h10, izData)
PRINT USING(zh1 ,d, izData, hi_GetRegDword(h2), hi_GetRegLong(h2))
d = 1
hi_PutRegDword(d, h2)
hi_Huge2Dec (h2,h10)
hi_GetRegAsciiz2(h10, izData)
PRINT USING(zh1 ,d, izData, hi_GetRegDword(h2), hi_GetRegLong(h2))
d = 2147483647
hi_PutRegDword(d, h2)
hi_Huge2Dec (h2,h10)
hi_GetRegAsciiz2(h10, izData)
PRINT USING(zh1 ,d, izData, hi_GetRegDword(h2), hi_GetRegLong(h2))
d = 4294967295
hi_PutRegDword(d, h2)
hi_Huge2Dec (h2,h10)
hi_GetRegAsciiz2(h10, izData)
PRINT USING(zh1 ,d, izData, hi_GetRegDword(h2), hi_GetRegLong(h2))
SETPRECISION (3)
time2 = GetTickCount()
PRINT (time2-time1)/1000.000, " secs."
PRINT:PRINT "Done..."
PRINT:PRINT "Press any key to end program."
PRINT
DO:UNTIL INKEY$<>""
CLOSECONSOLE
END
You will probably see that this program takes a long time to run. It takes more than 20 seconds on my machine. Please bear with me. I will cover this issue in a subsequent post. I will introduce functions which will make the programs run in less than one second.
The "hi_PutRegFromFile" function retrieves data from a file and stores that data in the specified HIME register. The file would be created with the "hi_GetRegToFile" function.
' hi_PutRegFromFile.EBA
'
'This function retrieves data from a file and stores that data in the specified HIME register.
'The data may be binary.
'File operations may result in error conditions. It is strongly advised to test this functions
' return value for error codes!
'It is good practice to always specify the full path name instead of relying on the 'current directory'.
'
$MAIN
AUTODEFINE "OFF"
'$USE "HIME_IOTest.lib"
$USE "HIME.lib"
$INCLUDE "HIME.INC"
$INCLUDE "FILEERRORS.INC"
DECLARE IMPORT, GetTickCount(),UINT
DEF time1 AS UINT
DEF time2 AS UINT
DEF pizData AS pointer
DEF izData[2000] as ISTRING ' Make sure that string variable is large enough to hold the result.
pizData=izData
INT h1:h1=1 ' Register 1.
INT h2:h2=2 ' Register 2.
INT h3:h3=3 ' Register 3.
INT h4:h4=4 ' Register 4.
INT h5:h5=5 ' Register 5.
INT h6:h6=6 ' Register 6.
INT h7:h7=7 ' Register 7.
INT h8:h8=8 ' Register 8.
INT h9:h9=9 ' Register 9.
INT h10:h10=10 ' Register 10.
INT h11:h11=11 ' Register 11.
INT h12:h12=12 ' Register 12.
INT h13:h13=13 ' Register 13.
INT h14:h14=14 ' Register 14.
INT h15:h15=15 ' Register 15.
INT h16:h16=16 ' Register 16.
INT h17:h17=17 ' Register 17.
INT h18:h18=18 ' Register 18.
INT h19:h19=19 ' Register 19.
INT h20:h20=20 ' Register 20.
OPENCONSOLE
time1 = GetTickCount()
' $INCLUDE "REGISTER.INC"
PRINT
INT i
hi_PutRegAsciiz( GETSTARTPATH + "JohnsKey.dat", h1 )
i = hi_PutRegFromFile( h1, h2 ) 'Store data in register 2
IF i<>0 THEN
PRINT "hi_PutRegFromFile returned an error:" + STR$( i )
PRINT FILEERRORS( i )
ENDIF
SETPRECISION (3)
time2 = GetTickCount()
PRINT
PRINT (time2-time1)/1000.000, " secs."
PRINT:PRINT "Done..."
PRINT:PRINT "Press any key to end program."
PRINT
DO:UNTIL INKEY$<>""
CLOSECONSOLE
END
PURPOSE
Put 32 bits signed integer data in one of the HIME internal registers.
If lData contains an integer ranging from 0 to 2147483647, then this data can immediately be used to perform huge integer calculations because it has the 'huge integer' format.
Using negative integers with hi_PutRegLong may result in unexpected results if you are not familiar with the 2's complement format of signed integer data.
If you want to use the full 32 bits data range (0 to 4294967295), use hi_PutRegDword instead.
' hi_PutRegLong.EBA
'
' This program tests the hi_PutRegDword function by
' loading an unsigned integer into a hime register.
' The data can contain an integer ranging from 0 to 4294967295.
' After storing data in a huge integer register with hi_PutRegDword,
' this data can immediately be used to perform huge integer calculations
' because it has the 'huge integer' format.
'
$MAIN
AUTODEFINE "OFF"
'$USE "HIME_IOTest.lib"
$USE "HIME.lib"
$INCLUDE "HIME.INC"
DECLARE IMPORT, GetTickCount(),UINT
DEF time1 AS UINT
DEF time2 AS UINT
DEF izData[2000] as ISTRING ' Make sure that string variable is large enough to hold the result.
INT h1:h1=1 ' Register 1.
INT h2:h2=2 ' Register 2.
INT h3:h3=3 ' Register 3.
INT h4:h4=4 ' Register 4.
INT h5:h5=5 ' Register 5.
INT h6:h6=6 ' Register 6.
INT h7:h7=7 ' Register 7.
INT h8:h8=8 ' Register 8.
INT h9:h9=9 ' Register 9.
INT h10:h10=10 ' Register 10.
INT h11:h11=11 ' Register 11.
INT h12:h12=12 ' Register 12.
INT h13:h13=13 ' Register 13.
INT h14:h14=14 ' Register 14.
INT h15:h15=15 ' Register 15.
INT h16:h16=16 ' Register 16.
INT h17:h17=17 ' Register 17.
INT h18:h18=18 ' Register 18.
INT h19:h19=19 ' Register 19.
INT h20:h20=20 ' Register 20.
OPENCONSOLE
time1 = GetTickCount()
' $INCLUDE "REGISTER.INC"
PRINT
INT l
STRING zh1
PRINT "hi_PutRegDword | hi_Huge2Dec | hi_GetRegDword | hi_GetRegLong"
PRINT "--------------------------------------------------------------"
zh1 = " ############# | & | ########### | #############"
l = 0
hi_PutRegLong(l, h2)
hi_Huge2Dec (h2,h10)
hi_GetRegAsciiz2(h10, izData)
PRINT USING(zh1 ,l, izData, hi_GetRegDword(h2), hi_GetRegLong(h2))
l = 1
hi_PutRegLong(l, h2)
hi_Huge2Dec (h2,h10)
hi_GetRegAsciiz2(h10, izData)
PRINT USING(zh1 ,l, izData, hi_GetRegDword(h2), hi_GetRegLong(h2))
l = 2147483647
hi_PutRegLong(l, h2)
hi_Huge2Dec (h2,h10)
hi_GetRegAsciiz2(h10, izData)
PRINT USING(zh1 ,l, izData, hi_GetRegDword(h2), hi_GetRegLong(h2))
l = -1
hi_PutRegLong(l, h2)
hi_Huge2Dec (h2,h10)
hi_GetRegAsciiz2(h10, izData)
PRINT USING(zh1 ,l, izData, hi_GetRegDword(h2), hi_GetRegLong(h2))
l = -2147483648
hi_PutRegLong(l, h2)
hi_Huge2Dec (h2,h10)
hi_GetRegAsciiz2(h10, izData)
PRINT USING(zh1 ,l, izData, hi_GetRegDword(h2), hi_GetRegLong(h2))
SETPRECISION (3)
time2 = GetTickCount()
PRINT (time2-time1)/1000.000, " secs."
PRINT:PRINT "Done..."
PRINT:PRINT "Press any key to end program."
PRINT
DO:UNTIL INKEY$<>""
CLOSECONSOLE
END
PURPOSE
Concatenate a byte to the contents of a register.
The byte value is passed as a LONG (4-byte signed integer) variable, but the value can not exceed 255.
' hi_RegConcatByte.EBA
'
' Concatenate a byte to the contents of a register.
' The byte value is passed as a INT (4-byte signed integer) variable, but the value can not exceed 255.
'
$MAIN
AUTODEFINE "OFF"
'$USE "HIME_IOTest.lib"
$USE "HIME.lib"
$INCLUDE "HIME.INC"
DECLARE IMPORT, GetTickCount(),UINT
DEF time1 AS UINT
DEF time2 AS UINT
DEF lAddress AS POINTER
DEF lLen AS INT
DEF izData[2000] as ISTRING ' Make sure that string variable is large enough to hold the result.
INT h1:h1=1 ' Register 1.
OPENCONSOLE
time1 = GetTickCount()
' $INCLUDE "REGISTER.INC"
PRINT
DEF g as pointer
DEF h AS STRING
DEF i AS INT
DEF j AS INT
h = "Some string" 'Store some data in string
hi_RegClear(h1)
FOR i = 1 TO LEN(h)
j = ASC(MID$(h, i, h1)) 'Get every byte of the string one by one
hi_RegConcatByte( h1, j ) 'Concatenate every byte to register 1
NEXT i
g=hi_GetRegAsciiz1(h1)
PRINT #<string>g
SETPRECISION (3)
time2 = GetTickCount()
PRINT
PRINT (time2-time1)/1000.000, " secs."
PRINT:PRINT "Done..."
PRINT:PRINT "Press any key to end program."
PRINT
DO:UNTIL INKEY$<>""
CLOSECONSOLE
END