rebol [ File: %addr.r Date: 10/03/2005 Version: 1.0.0 Title: "Addr" Purpose: "Convert C data to Rebol - get the memory address and cast* to a given struct or array" Author: "Romano Paolo Tenca" Note: { Define 2 functions: & to get the address of a Rebol string! binary! or struct! cast* to get the content of an address and cast it to a Rebol struct The Type argument of the cast* function can be a Rebol struct spec, es.: [i [integer!] i2 [short] i3 [short] i4 [char]] or a block with a sequence of [number type ...], es. [1 long 2 short 2 char] or a number followed by a block. This can be useful for arrays, es.: [30 [1 long 2 short 1 char 1 char]] an array of 30 C struct of the type {long; short; short; char; char} [25 [i [integer!] i2 [short] i3 [short]]] an array of 25 C struct of the type {long; short; short} Pay attention to alignement of C type!! } Date: 10/03/2005 Library: [ level: 'intermediate platform: 'all type: [function] domain: [external-library] tested-under: none support: none license: none see-also: none ] ] context [ mode: get-modes system:// 'endian system/words/addr-to-int: func [ "Convert a binary in an integer - little of big endian aware" b [binary!] /endian "Force an endian mode" lmode [word!] "'little or 'big" ] [ to integer! either 'little = any [lmode mode] [head reverse copy b][b] ] system/words/&: func [ "Return the memory address of a binary, string or struct as a binary value" b [binary! string! struct!] ][ third make struct! [s [string!]] reduce [either struct? b [third b][b]] ] system/words/cast*: func [ "Return the content of a binary memory address as a struct!" pointer [binary!] type [block!] "Spec for data: es. [2 short 1 long] or [i [integer!]]" /local spec n ][ spec: copy/deep [inner [struct! []]] n: 1 if all [integer? type/1 block? type/2] [n: type/1 type: type/2] loop n [ either integer? type/1 [ foreach [size type] type [ insert/dup tail spec/2/2 reduce ['. reduce [type]] size ] ][insert spec/2/2 type] ] spec: make struct! spec none change third spec pointer spec/inner ] ] do [ ;examples and tests probe value: #{0100 0200 0300 0400} print ["address of binary! is" & value "=" addr-to-int & value] print ["content is" mold second cast* & value [8 char]] print ["content is" mold second cast* & value [4 short]] print ["content is" mold second cast* & value [i [short] i2 [short] i3 [short] i4 [short]]] print ["content is" mold second cast* & value [2 long]] probe value: make struct! [i [integer!] i2 [integer!]] [6 33] print ["address of struct! is" & value "=" addr-to-int & value] print ["content is" mold third value] print ["content is" mold second cast* & value [8 char]] print ["content is" mold second cast* & value [4 short]] print ["content is" mold second cast* & value [2 long]] print ["content is" mold second cast* & value [2 char 1 long 1 short]] probe value: make struct! [s [string!] i [integer!]] ["C string" 33] print ["address of struct! is" & value "=" addr-to-int & value] print ["content is" mold third value] print ["content is" mold second cast* & value [8 char]] print ["content is" mold second cast* & value [4 short]] print ["content is" mold second cast* & value [2 long]] print ["content is" mold second cast* & value [1 char* 1 long]] probe value: make struct! [s [string!] i [struct! [i [integer!]]]] ["C string" 1134] print ["address of struct! is" & value "=" addr-to-int & value] print ["content is" mold third value] print ["content is" mold second cast* & value [1 long 2 short]] print ["content is" mold second cast* & value [i [integer!] i2 [short] i3 [short]]] print ["content is" mold second cast* & value [2 long]] print ["content of inner struct is" mold second cast* & value [s [string!] i [struct! [i [integer!]]]]] probe value: #{0100 0200 0300 0400 0100 0200 0300 0400} print ["address of binary! is" & value "=" addr-to-int & value] print ["content is" mold second cast* & value [8 short]] print ["content is" mold second cast* & value [4 [1 short 1 char]]] probe value: make struct! [s [string!] i [integer!] s [string!] i [integer!] s [string!] i [integer!]] ["C string 1" 10 "C string 2" 20 "C string 3" 30] print ["address of struct! is" & value "=" addr-to-int & value] print ["content is" mold second cast* & value [3 [1 string! 1 long]]] print ["content is" mold second cast* & value [3 [i [string!] n [long]]]] halt ]