Unusual file format
[1/4] from: mduncan::homezipr::com at: 14-Nov-2000 13:39
I need to create a file in Windows with the following format (not one I
designed):
Field number - 2 bytes in MS Lo-Hi order
Field length - 1 byte
String data - as many characters as specified in field length
Using a hex editor the file would look like this:
01 00 05 41 42 43 44 45 02 00 10 41 42 43 44 45 ...ABCDEF...ABCDE
46 47 48 49 4A 4B 4C 4D 4E 4F 50 FF FF FGHIJKLMNOP..
with field number 1, 5 characters "ABCDE"
field number 2, 16 characters "ABCDEFGHIJKLMNOP"
FF FF marks the end of the file.
Any help would be appreciated. I'm new to Rebol and am having trouble with
this one.
TIA
Mike
[2/4] from: larry:ecotope at: 14-Nov-2000 14:38
Hi Mike
The tricky part is creating the 2-byte integers. Here is a useful function
to convert REBOL integers to 2-byte or 4-byte byte-reversed (Intel format)
binary values:
=====TO-BYTE FUNCTION======
to-byte: func [int [integer!] /long][
head reverse do join "#{" [(copy skip (to-string to-hex int) either
long [0][4]) "}"]
]
Example:
>> bin: to-byte 694
== #{B602}
Note: there is no checking for sign, so TO-BYTE will only work properly for
unsigned 2-byte up to 32767 and unsigned 4-byte up to 2147483647. It is
fairly easy to add code to allow REBOL negative integers to be
re-interpreted as the high-half unsigned's.
The field length is just one byte and can be generated as:
binary-byte: to-binary to-string to-char <integer between 0 and 255>
So, in outline, for each line to be written:
1) Convert the string content to binary
b-string: to-binary <data-string>
2) insert b-string binary-byte ; binary-byte as above
3) insert b-string to-byte <field number as integer between 0 and 32767>
4) write/binary/append <filename> b-string ; append the line to the file.
5) After all lines are written
write/binary/append <filename> #{FFFF}
HTH
-Larry
[3/4] from: tim:johnsons-web at: 14-Nov-2000 14:17
Hello Mike:
I'll show you how to get started, and I'll bet that you will
get even better tips from others in the list. But first, I
observe a discrepancy in your example, the hex dump seems
to off by 1.
;First, run the following code so that you have a test setup:
variable: #{01 00 05 41 42 43 44 45 02 00 10 41 42 43 44 45
46 47 48 49 4A 4B 4C 4D 4E 4F 50 FF FF}
write/binary %bin.tst variable
;Now you have the binary data written to a file, next step
; is to test the binary read, and give you an idea of how to
;map out the binary data into the data-types that you request;
; run the following script now:
; read data into buffer
print variable: read/binary %bin.tst
; parse out field-number
print field-num: copy/part variable 2
; and convert it to an integer, correcting for byte order
print field-num: to-integer head reverse field-num
; skip the read data
variable: skip variable 2
; demonstrate where variable points to
print variable
; get the field length
field-len: copy/part variable 1
; and convert it to an integer so that copy/part has an integer argument
print field-len: to-integer field-len
; skip the read data
variable: skip variable 1
; get text
text-field: copy/part variable field-len
; convert to string
print to-string text-field
; hopefully, this will get you started in the conceptualization....
; next step is to make this elegant! :)
I hope this helps (I wrote an entire dbms in "C" using this method).
Trust me, it's much easier in rebol
-Tim
Mike Duncan wrote:
[4/4] from: mduncan:homezipr at: 14-Nov-2000 15:17
Thanks so much, Larry, that did the trick! I'll have some more questions
soon, I imagine.
And thanks to whomever made REBOL available on BeOS!
Mike