Add c-types in alien.endian for making endian-aware STRUCTs.
parent
eedc1e185f
commit
4220f9dc0c
|
@ -0,0 +1 @@
|
|||
Doug Coleman
|
|
@ -0,0 +1,90 @@
|
|||
! Copyright (C) 2011 Doug Coleman.
|
||||
! See http://factorcode.org/license.txt for BSD license.
|
||||
USING: help.markup help.syntax kernel math quotations ;
|
||||
IN: alien.endian
|
||||
|
||||
HELP: be16
|
||||
{ $var-description "Signed bit-endian 16-bit." } ;
|
||||
|
||||
HELP: be32
|
||||
{ $var-description "Signed bit-endian 32-bit." } ;
|
||||
|
||||
HELP: be64
|
||||
{ $var-description "Signed bit-endian 64-bit." } ;
|
||||
|
||||
HELP: be8
|
||||
{ $var-description "Signed bit-endian 8-bit." } ;
|
||||
|
||||
HELP: byte-reverse
|
||||
{ $values
|
||||
{ "n" integer } { "signed?" boolean }
|
||||
{ "quot" quotation }
|
||||
}
|
||||
{ $description "Reverses the " { $snippet "n" } " bytes in an integer with bitwise operations. The second parameter only works for 1, 2, 4, or 8 byte signed numbers." } ;
|
||||
|
||||
HELP: le16
|
||||
{ $var-description "Signed little-endian 16-bit." } ;
|
||||
|
||||
HELP: le32
|
||||
{ $var-description "Signed little-endian 32-bit." } ;
|
||||
|
||||
HELP: le64
|
||||
{ $var-description "Signed little-endian 64-bit." } ;
|
||||
|
||||
HELP: le8
|
||||
{ $var-description "Signed little-endian 8-bit." } ;
|
||||
|
||||
HELP: ube16
|
||||
{ $var-description "Unsigned big-endian 16-bit." } ;
|
||||
|
||||
HELP: ube32
|
||||
{ $var-description "Unsigned big-endian 32-bit." } ;
|
||||
|
||||
HELP: ube64
|
||||
{ $var-description "Unsigned big-endian 64-bit." } ;
|
||||
|
||||
HELP: ube8
|
||||
{ $var-description "Unsigned big-endian 8-bit." } ;
|
||||
|
||||
HELP: ule16
|
||||
{ $var-description "Unsigned little-endian 16-bit." } ;
|
||||
|
||||
HELP: ule32
|
||||
{ $var-description "Unsigned little-endian 32-bit." } ;
|
||||
|
||||
HELP: ule64
|
||||
{ $var-description "Unsigned little-endian 64-bit." } ;
|
||||
|
||||
HELP: ule8
|
||||
{ $var-description "Unsigned little-endian 8-bit." } ;
|
||||
|
||||
ARTICLE: "alien.endian" "Alien endian-aware types"
|
||||
"The " { $vocab-link "alien.endian" } " vocabulary defines c-types that are endian-aware for use in structs. These types will cause the bytes in a byte-array to be interpreted as little or big-endian transparently when reading or writing. There are both signed and unsigned types defined; signed is the default while unsigned are prefixed with a " { $snippet "u" } ". The intended use-case is for network protocols in network-byte-order (big-endian)." $nl
|
||||
"Byte-reversal of integers:"
|
||||
{ $subsections
|
||||
byte-reverse
|
||||
}
|
||||
"The big-endian c-types are:"
|
||||
{ $subsections
|
||||
be8
|
||||
be16
|
||||
be32
|
||||
be64
|
||||
ube8
|
||||
ube16
|
||||
ube32
|
||||
ube64
|
||||
}
|
||||
"The little-endian c-types are:"
|
||||
{ $subsections
|
||||
le8
|
||||
le16
|
||||
le32
|
||||
le64
|
||||
ule8
|
||||
ule16
|
||||
ule32
|
||||
ule64
|
||||
} ;
|
||||
|
||||
ABOUT: "alien.endian"
|
|
@ -0,0 +1,96 @@
|
|||
! Copyright (C) 2011 Doug Coleman.
|
||||
! See http://factorcode.org/license.txt for BSD license.
|
||||
USING: accessors alien.endian classes.struct io
|
||||
io.encodings.binary io.streams.byte-array kernel tools.test ;
|
||||
IN: alien.endian.tests
|
||||
|
||||
STRUCT: endian-struct
|
||||
{ a ule16 }
|
||||
{ b le16 }
|
||||
{ c ube16 }
|
||||
{ d be16 }
|
||||
{ e ule32 }
|
||||
{ f le32 }
|
||||
{ g ube32 }
|
||||
{ h be32 }
|
||||
{ i ule64 }
|
||||
{ j le64 }
|
||||
{ k ube64 }
|
||||
{ l be64 } ;
|
||||
|
||||
CONSTANT: endian-bytes-0f B{
|
||||
HEX: 0 HEX: ff
|
||||
HEX: 0 HEX: ff
|
||||
HEX: 0 HEX: ff
|
||||
HEX: 0 HEX: ff
|
||||
|
||||
HEX: 0 HEX: 0 HEX: 0 HEX: ff
|
||||
HEX: 0 HEX: 0 HEX: 0 HEX: ff
|
||||
HEX: 0 HEX: 0 HEX: 0 HEX: ff
|
||||
HEX: 0 HEX: 0 HEX: 0 HEX: ff
|
||||
|
||||
HEX: 0 HEX: 0 HEX: 0 HEX: 0 HEX: 0 HEX: 0 HEX: 0 HEX: ff
|
||||
HEX: 0 HEX: 0 HEX: 0 HEX: 0 HEX: 0 HEX: 0 HEX: 0 HEX: ff
|
||||
HEX: 0 HEX: 0 HEX: 0 HEX: 0 HEX: 0 HEX: 0 HEX: 0 HEX: ff
|
||||
HEX: 0 HEX: 0 HEX: 0 HEX: 0 HEX: 0 HEX: 0 HEX: 0 HEX: ff
|
||||
}
|
||||
|
||||
CONSTANT: endian-bytes-f0 B{
|
||||
HEX: ff HEX: 0
|
||||
HEX: ff HEX: 0
|
||||
HEX: ff HEX: 0
|
||||
HEX: ff HEX: 0
|
||||
|
||||
HEX: ff HEX: 0 HEX: 0 HEX: 0
|
||||
HEX: ff HEX: 0 HEX: 0 HEX: 0
|
||||
HEX: ff HEX: 0 HEX: 0 HEX: 0
|
||||
HEX: ff HEX: 0 HEX: 0 HEX: 0
|
||||
|
||||
HEX: ff HEX: 0 HEX: 0 HEX: 0 HEX: 0 HEX: 0 HEX: 0 HEX: 0
|
||||
HEX: ff HEX: 0 HEX: 0 HEX: 0 HEX: 0 HEX: 0 HEX: 0 HEX: 0
|
||||
HEX: ff HEX: 0 HEX: 0 HEX: 0 HEX: 0 HEX: 0 HEX: 0 HEX: 0
|
||||
HEX: ff HEX: 0 HEX: 0 HEX: 0 HEX: 0 HEX: 0 HEX: 0 HEX: 0
|
||||
}
|
||||
|
||||
: endian-test-struct-0f ( -- obj )
|
||||
endian-bytes-0f endian-struct memory>struct ;
|
||||
|
||||
: endian-test-struct-f0 ( -- obj )
|
||||
endian-bytes-f0 endian-struct memory>struct ;
|
||||
|
||||
[ HEX: ff00 ] [ endian-test-struct-0f a>> ] unit-test
|
||||
[ -256 ] [ endian-test-struct-0f b>> ] unit-test
|
||||
[ HEX: 00ff ] [ endian-test-struct-0f c>> ] unit-test
|
||||
[ HEX: 00ff ] [ endian-test-struct-0f d>> ] unit-test
|
||||
|
||||
[ HEX: ff000000 ] [ endian-test-struct-0f e>> ] unit-test
|
||||
[ -16777216 ] [ endian-test-struct-0f f>> ] unit-test
|
||||
[ HEX: 000000ff ] [ endian-test-struct-0f g>> ] unit-test
|
||||
[ HEX: 000000ff ] [ endian-test-struct-0f h>> ] unit-test
|
||||
|
||||
[ HEX: ff00000000000000 ] [ endian-test-struct-0f i>> ] unit-test
|
||||
[ -72057594037927936 ] [ endian-test-struct-0f j>> ] unit-test
|
||||
[ HEX: 00000000000000ff ] [ endian-test-struct-0f k>> ] unit-test
|
||||
[ HEX: 00000000000000ff ] [ endian-test-struct-0f l>> ] unit-test
|
||||
|
||||
|
||||
[ HEX: ff00 ] [ endian-test-struct-f0 c>> ] unit-test
|
||||
[ -256 ] [ endian-test-struct-f0 d>> ] unit-test
|
||||
[ HEX: 00ff ] [ endian-test-struct-f0 a>> ] unit-test
|
||||
[ HEX: 00ff ] [ endian-test-struct-f0 b>> ] unit-test
|
||||
|
||||
[ HEX: ff000000 ] [ endian-test-struct-f0 g>> ] unit-test
|
||||
[ -16777216 ] [ endian-test-struct-f0 h>> ] unit-test
|
||||
[ HEX: 000000ff ] [ endian-test-struct-f0 e>> ] unit-test
|
||||
[ HEX: 000000ff ] [ endian-test-struct-f0 f>> ] unit-test
|
||||
|
||||
[ HEX: ff00000000000000 ] [ endian-test-struct-f0 k>> ] unit-test
|
||||
[ -72057594037927936 ] [ endian-test-struct-f0 l>> ] unit-test
|
||||
[ HEX: 00000000000000ff ] [ endian-test-struct-f0 i>> ] unit-test
|
||||
[ HEX: 00000000000000ff ] [ endian-test-struct-f0 j>> ] unit-test
|
||||
|
||||
[ t ]
|
||||
[ endian-test-struct-0f binary [ write ] with-byte-writer endian-bytes-0f = ] unit-test
|
||||
|
||||
[ t ]
|
||||
[ endian-test-struct-f0 binary [ write ] with-byte-writer endian-bytes-f0 = ] unit-test
|
|
@ -0,0 +1,84 @@
|
|||
! Copyright (C) 2011 Doug Coleman.
|
||||
! See http://factorcode.org/license.txt for BSD license.
|
||||
USING: accessors alien.accessors alien.c-types combinators
|
||||
compiler.units endian fry generalizations kernel macros math
|
||||
namespaces sequences words alien.data ;
|
||||
QUALIFIED-WITH: alien.c-types ac
|
||||
IN: alien.endian
|
||||
|
||||
ERROR: invalid-signed-conversion n ;
|
||||
|
||||
: convert-signed-quot ( n -- quot )
|
||||
{
|
||||
{ 1 [ [ char <ref> char deref ] ] }
|
||||
{ 2 [ [ ac:short <ref> ac:short deref ] ] }
|
||||
{ 4 [ [ int <ref> int deref ] ] }
|
||||
{ 8 [ [ longlong <ref> longlong deref ] ] }
|
||||
[ invalid-signed-conversion ]
|
||||
} case ; inline
|
||||
|
||||
MACRO: byte-reverse ( n signed? -- quot )
|
||||
[
|
||||
drop
|
||||
[
|
||||
dup iota [
|
||||
[ 1 + - -8 * ] [ nip 8 * ] 2bi
|
||||
'[ _ shift HEX: ff bitand _ shift ]
|
||||
] with map
|
||||
] [ 1 - [ bitor ] n*quot ] bi
|
||||
] [
|
||||
[ convert-signed-quot ] [ drop [ ] ] if
|
||||
] 2bi
|
||||
'[ _ cleave @ @ ] ;
|
||||
|
||||
SYMBOLS: le8 be8 ule8 ube8
|
||||
ule16 ule32 ule64 ube16 ube32 ube64
|
||||
le16 le32 le64 be16 be32 be64 ;
|
||||
|
||||
ERROR: unknown-endian-c-type symbol ;
|
||||
|
||||
: endian-c-type>c-type-symbol ( symbol -- symbol' )
|
||||
{
|
||||
{ [ dup { ule16 ube16 } member? ] [ drop ushort ] }
|
||||
{ [ dup { le16 be16 } member? ] [ drop ac:short ] }
|
||||
{ [ dup { ule32 ube32 } member? ] [ drop uint ] }
|
||||
{ [ dup { le32 be32 } member? ] [ drop int ] }
|
||||
{ [ dup { ule64 ube64 } member? ] [ drop ulonglong ] }
|
||||
{ [ dup { le64 be64 } member? ] [ drop longlong ] }
|
||||
[ unknown-endian-c-type ]
|
||||
} cond ;
|
||||
|
||||
: change-c-type-accessors ( n ? c-type -- c-type' )
|
||||
endian-c-type>c-type-symbol "c-type" word-prop clone
|
||||
-rot
|
||||
[ '[ [ _ _ byte-reverse ] compose ] change-getter drop ]
|
||||
[ '[ [ [ _ _ byte-reverse ] 2dip ] prepose ] change-setter ] 3bi ;
|
||||
|
||||
: typedef-endian ( n ? c-type endian -- )
|
||||
native-endianness get = [
|
||||
2nip [ endian-c-type>c-type-symbol ] keep typedef
|
||||
] [
|
||||
[ change-c-type-accessors ] keep typedef
|
||||
] if ;
|
||||
|
||||
: typedef-le ( n ? c-type -- ) little-endian typedef-endian ;
|
||||
: typedef-be ( n ? c-type -- ) big-endian typedef-endian ;
|
||||
|
||||
[
|
||||
\ char \ le8 typedef
|
||||
\ char \ be8 typedef
|
||||
\ uchar \ ule8 typedef
|
||||
\ uchar \ ube8 typedef
|
||||
2 f \ ule16 typedef-le
|
||||
2 f \ ube16 typedef-be
|
||||
2 t \ le16 typedef-le
|
||||
2 t \ be16 typedef-be
|
||||
4 f \ ule32 typedef-le
|
||||
4 f \ ube32 typedef-be
|
||||
4 t \ le32 typedef-le
|
||||
4 t \ be32 typedef-be
|
||||
8 f \ ule64 typedef-le
|
||||
8 f \ ube64 typedef-be
|
||||
8 t \ le64 typedef-le
|
||||
8 t \ be64 typedef-be
|
||||
] with-compilation-unit
|
Loading…
Reference in New Issue