Oxygen Basic
Programming => Example Code => Topic started by: Arnold on May 13, 2019, 11:43:33 PM
-
Hi Charles,
I am experimenting a bit with CreateFile and Readfile and try to compare with Oxygen's getfile function. I am able to load text with ReadFile into a buffer of type char* or zstring*, but it does not work with string or bstring. Is this possible in some way? There are some older postings dealing with ReadFile and strings, but they do not run with the latest version of Oxygen. Unfortunately Peter has deleted his messages, so it is a bit difficult to see the context.
Does getfile apply getmemory or freememory internally?
Roland
TestReadFile.o2bas:
$ filename "TestReadFile.exe"
'uses rtl32
'uses rtl64
uses corewin
uses console
function lof (string Fname) as int
'length of file
WIN32_FIND_DATA W32FD
sys hFile
int FSize
if len(Fname) = 0 then return 0
hFile=FindFirstFile(Fname, &W32FD)
if hFile != INVALID_HANDLE_VALUE then
FSize = W32FD.nFileSizeLow
FindClose(hFile)
return FSize
end if
return 0
end function
function LoadFile (string Fname, sys Buff) as int
' Assumes a valid existing file and Buff large enough to hold the content of the file
sys Read
sys hFile
int Fsize
Fsize = LOF(Fname)
hFile = CreateFile(Fname,GENERIC_READ,FILE_SHARE_READ,null,OPEN_EXISTING,0,0)
if hFile != INVALID_HANDLE_VALUE then
ReadFile (hFile,Buff,Fsize,&Read,null)
CloseHandle(hFile)
end if
function = Read
end function
cls
int FileSize
string fn = "TestReadFile.o2bas"
sys buf = getmemory (lof(fn) +1)
'zstring *buffer : @buffer = buf
char *buffer : @buffer = buf
FileSize = LoadFile(fn, @buffer)
print fn
printl "LoadFile loaded " FileSize " bytes into buffer"
string s=getfile(fn)
printl "Getfile loaded " len(s) " bytes into string"
printl "Press Enter to display contents of buffer"
waitkey
Cls
print buffer 's
freememory buf
printl "Enter..."
waitkey
-
Hi Roland,
getfile uses SysAllocStringByteLen directly to create the bstring buffer.
getmemory also uses SysAllocStringByteLen
This is the function in RTL32. It would look much less intimidating in Basic :)
function getfiles(string w) as sys external 'at [ebx+336]
'========================================================
'
dim as sys b,h,p,pf,ph,le,leh
'
'
'CHECK VALID NAME
'
cmp dword ptr [w],0
jz ngetfile
'
'OPEN FILE
'
push 0 'HANDLE hTemplateFile OPT
push 128 'FILE_ATTRIBUTE_NORMAL
push 3 'CREATE (NEW 1) (ALWAYS 2) (OPEN 4) (OPEN EXISTING 3)
push 0 'LP SECURITY ATTRIBUTES OPT
push 1 'SHARE MODE read(1) write(2)
push 0x80000000 'GENERIC_READ (0x80000000) GENERIC_WRITE (0x40000000)
push [w] 'name
call Createfile
mov [h],eax
'
'SET FILE POINTER
'
push 0 'DWORD dwMoveMethod 0,FILE_BEGIN(0) FILE_CURRENT(1) FILE_END (2)
lea eax,[ph] 'PLONG lpDistanceToMoveHigh
push eax
push 0 'LONG lDistanceToMove
push [h] 'DWORD HANDLE
call SetFilePointer '
mov [pf],eax 'File Pointer position low
'
'GET FILE SIZE
'
lea eax,[leh] 'PLONG lpFileSizeHigh
push eax '
push [h] 'DWORD HANDLE
call GetFileSize '
mov [le],eax '
'
'CREATE STRING BUFFER
'
push [le] 'FILE LENGTH
push 0 'OPTIONAL COPY POINTER
call SysAllocStringByteLen 'CREATE BSTR
mov [p],eax
mov [function],eax
'
'READ FILE
'
push 0 'LPOVERLAPPED lpOverlapped
lea eax,[b] 'lpNumberOfBytesRead
push eax '
push [le] 'DWORD nNumberOfBytesToRead
push [p] 'LPVOID lpBuffer
push [h] 'DWORD HANDLE
call ReadFile
'
push [h]
call CloseHandle
'
ngetfile:
'
'CLOSE HANDLE
'
end function
-
Hi Charles,
you opened the door to a new world for me and once again I see the complexity of OxygenBasic. I will need some time to understand the connections. Until now I have not paid much attention to bstrings.
Is Oxygen's bstr type different from the declaration which I found in MSDN info: typedef WCHAR* BSTR (can contain embedded null characters, 4 bytes length prefix)? Oxygen Helpfile: bstr - specify a bstring type with 8-bit characters.
Is there a relationship between bstr, bstring and bstring2 ? Can they contain embedded null characters and is there a count of chars prefix too?
Roland
-
Hi Roland,
In o2, all dynamic strings are based on getmemory which calls SysAllocStringByteLen. So they all have the 4 byte (int) length prefix, which means they are not dependent on null terminators and therefore can include null characters.
-
Thank you Charles. This is a real eye-opener for me.