View Single Post
Old 16 July 2015, 14:27   #59
BigFan
Registered User
 
BigFan's Avatar
 
Join Date: Feb 2014
Location: Germany
Posts: 261
Ascii to hex

In a previous example i told you about the problem using Readln in conjuction
with EoF(). The second function to read from a file is Readch(). This function
has less to no problems with file length. We simply tell Readch() the exact numbers
of characters to read. Readch() returns a string of same length or less if file
boundaries crossed. Stepping only one character gives opportunity to check its
value (0 means end of file), makes it easier to check for Eof() than using Readln().
Readch() does not stop on any special character (e.g. $0a , aka line feed).

Exercise:
Write a little hex file reader. I suggest to make use of the following functions:
C2x()
Copies()
Min()
Open()
Readch()
Statef()
Substr()
Translate()
Xrange()

Try first before continue.

Example:
Code:
/*
* $VER: HexReader 1.1 (15.07.15)
* written by BigFan
*/
If Exists('libs:rexxsupport.library') Then
  Addlib('rexxsupport.library',0,-30,0)
Else Exit
If Exists('libs:rexxreqtools.library') Then
  Addlib('rexxreqtools.library',0,-30,0)
Else Exit 

    files=rtfilerequest()
    Parse Value Statef(files) With type size .

If size='SIZE' Then Exit  /* no file size, no fun */

 /* preparing hex code table */

as2 = Xrange('00'x,'1f'x)
as3 = Copies(".",32)


  /* variable init */
chars = ""
size = Min(size, 65535)   /* string is restricted to 64kB */

Open(infile,files)

  /* read and concatenate */
Do i=1 To size
 chars = chars||Readch(infile)
End

  /* apply hex and ascii table  */

Do i = 1 To size By 16
  hex = C2x(Substr(chars,i,16))
  asc = Substr(chars,i,16)
 tasc = Translate(asc,as3,as2)
 comb = hex||" "||tasc
 Writeln(stdout,comb)
End
Close(infile)
Exit
First we ask for a file. If nothing is returned then quit.
Two strings are created, 1st with forbidden characters, 2nd with the replacer

We face a new problem here: String length must not exceed 65536 bytes !!
The code above does check for it but doesn't deal well with it.

After opening the file we concatenate all chars read into one string.

This new string is processed in chunks of 16 byte, because hex values have 2 digits
we need 32 + 1 + 16 = 49 chars to show it.

We read a substring of 16 bytes and convert it to hex values.
Same substring again for ascii.
Now, Translate() cleans the ascii part from unwanted chars. All values lower than
32 are substituted by a period.

Hex string + blank + ascii string are concatenated and written to stdout.

This code could be enhanced.
Code is sluggish, speed up.
Find a way to process files bigger then 64kB (multiple strings).
Add file information.
Better input handling.
Circumvent the 64kB restriction (using allocated memory).
Scrolling. (uh, no, that is difficult, you have to create a list view and do
your own drawing routines(add graphics.library, poke addresses))
Send data to a file reader or editor.
Build a MUI around it with MUIRexx.
Add editing features(not serious, ARexx is not good at this, better use another
language, ARexx is for interprocess communication).

Last edited by BigFan; 17 July 2015 at 14:09. Reason: formerly written code wasn't fail save
BigFan is offline  
 
Page generated in 0.04362 seconds with 11 queries