**DONOTDELETE**
(Lurker)
2001-08-20 11:41 AM
What about ReadString()

Kix only supports reading lines (until next Cr/Lf). There are a lot of files whith an other structure that can't be read properly in this way. I suggest a function that reads an string (given amount) of bytes, starting from a pointer (given point) from the Opened file handle.

Example that reads 12 bytes, starting at the 8th byte from the beginning of the opened file.

Open(2, "c:\whatever.exe")
$Line=ReadString(2,7,12)
Close(2)

For screen representation a function like Bin2Hex($Line)would be nice in case the content is binairy.

A ReadString()is also usefull for databases with fixed-size records or finding binairy values in all kind of non ascii files.

LonkeroAdministrator
(KiX Master Guru)
2001-08-20 11:52 AM
Re: What about ReadString()

that's not bad idea at all. actually the readstring might have a argument that specifies which is the char where the line (or string) ends.
like I've used split to get the html lines out from <br> (like with bbcodeparser), but if you could right away say that lines are separated with some specific char...
like split allready integrated.
this can be done with udf, but what about lines that go to the length of 50,000 chars.

what about bin2hex, I would like to see open extended to support binary files or new function openb. this way files are humanreadable only with kix and binary editors.

**DONOTDELETE**
(Lurker)
2003-01-13 09:28 PM
Re: What about ReadString()

After more than 1 year I came up against the problem of reading some dumps that contain binairy data among text, including 00h and 0D0D0Ah that needed to be scipped (TCP/DUMP). Finaly I found a way to bypass this, by scipping all non ascii, but I still would like to see this function to read an amount of bytes in a way that the function can be specified to read N bytes from offset X to offset y.
Like

Open(2,"C:\somefile.bin)
$Offset=1
$Bytse2Read=10
$Data=ReadString(2,$Offset,$Bytes2Read)
Close(2)
;$Data contains all 10 bytes, even if they are 00h or CrLf.


kholm
(Korg Regular)
2003-01-13 10:41 PM
Re: What about ReadString()

This looks like the good old BlockRead from Turbo Pascal

To Read the entire file you could have a buildin function like:

BlockRead(Handle, Numbytes)

Just a suggestion of how to implement this witout using pointers [Wink]

The function should return the bytes read from the file, @Error should return the actual number of bytes read (file could be less than NumBytes)
I know this is reversing the meaning of @Error, in this situation: 0 would be an Error or nothing read!

Pseudocode example:
code:
$Handle = 1
$NumBytes = 100
$RC = Open($Handle,'BinFile')
If $RC = 0
$Read = BlockRead($Handle,$NumBytes)
$NumRead = @Error
While $NumRead > 0
For $i = 1 To $NumRead
$Char = SubStr($Read,$i,1)
; Do something with the char !!
Next
$Read = BlockRead($Handle,$NumBytes) ; NumBytes could be optional, only needed for first BlockRead
$NumRead = @Error
Loop
EndIf
$RC = Close($Handle)

Ofcourse this could have a BlockWrite() compagnion. We would then be able to manipulate small binary files.

-Erik

[ 13. January 2003, 22:43: Message edited by: kholm ]


Richard H.Administrator
(KiX Supporter)
2003-01-14 11:12 AM
Re: What about ReadString()

KiXtart does not support binary types natively. This means that you cannot read/write or otherwise manipulate binary data in any reliable way.

The only native KiXtart data type which is useful in this context is an array of integers, so you would use
code:
$aiData=ReadArray($fnFileNumber,$iOffset,$iBytesToRead)

$aiData will contain $iBytesToRead elements, each of which is the integer value of the datum starting at $iOffset. If $iBytesToRead is longer than the amount of data available, $aiData will contain as much data as could be read - use UBound() to see how much data was read.

Some significant changes would need to be made to KiXtart's file handling to fully support binary files. Currently files are entirely read into memory on the first ReadLine(), and ReadLine() simply returns the next line from an internal buffer each time it is called. At present there is no support for random file i/o.


Rocco Capra
(Hey THIS is FUN)
2003-01-14 02:14 PM
Re: What about ReadString()

LOL at Rich!! [Big Grin] [Big Grin] [Big Grin]

kholm
(Korg Regular)
2003-01-14 09:10 PM
Re: What about ReadString()

Howarth,

I thought this was the suggestions forum!

What we would like for future releases of KiXtart, and not what can’t be done in the current release.

Also it is not correct, that binary data can only be manipulated from an array.
SubStr() can get binary data from a strings, and a string can contain binary data including CR, LF, TAB etc.

Try the following code:
code:
$Str = ''
For $i = 0 To 31
$Str = $Str + Chr($i)
Next

For $i = 1 To Len($Str)
? Asc(SubStr($Str,$i,1))
Next

I like your idea though, of returning the result of a BinaryRead into an array

-Kærholm


Richard H.Administrator
(KiX Supporter)
2003-01-15 11:03 AM
Re: What about ReadString()

You will also note that I said you cannot manipulate binary data in any reliable way. It will work perfectly well some of the time, and will fail completely some of the time. Have you tried getting a Chr(0) into a string? Your example code you have provided fails on this, you will note that there is no "0" in the displayed output. If you do manage to read in data with Chr(0) in it the first time that you try to use SubStr() or catenate the string or use any other string oriented function you will have problems.

I should point out that characters like LF,CR and TAB are not binary. They are ASCII control-characters and are perfectly valid in string contexts.

The reason that Chr(0) (ASCII NUL) is such a problem is that it was chosen way back goodness knows when as a string delimiter (SZ data type in MS-speak). Therefore it cannot itself be part of a string although the other 255 characters probably can be. Chr(0) was probably chosen because it is a useful value programatically, and in a string context it is a no-operation character as far as display/printing devices are concerned - it used to be used as padding to give slow devices time to perform functions.

On the subject of what KiXtart cannot currently do, we are also missing functions to convert data types to/from a format which is suitable for file i/o.

For binary compatibility, we would need to be able to convert numeric data to the big/little endian byte format of the machines chip set and back again. This could be done at the read/write stage:
code:
$iInteger=ReadInteger($fhFileHandle)

Or as a type conversion (assuming 32 bit integer):
code:
$iInteger=ByteToInt($iByte0,$iByte1,$iByte2,$iByte3)

It's possible to code UDFs to convert these types, but it is probably better done by an architecture independant function call. And decimals would be tricky [Eek!]

You should look at my posts more as a shopping list of the things we need to get binary data functionality working rather than a list of obstructions or objections.