| 
									
										
										
										
											2011-09-21 17:04:17 -04:00
										 |  |  | ! Copyright (C) 2011 Doug Coleman. | 
					
						
							|  |  |  | ! See http://factorcode.org/license.txt for BSD license. | 
					
						
							| 
									
										
										
										
											2014-11-16 23:31:32 -05:00
										 |  |  | USING: accessors alien.accessors alien.c-types alien.data arrays | 
					
						
							| 
									
										
										
										
											2011-09-22 12:26:06 -04:00
										 |  |  | classes.struct.private combinators compiler.units endian fry | 
					
						
							| 
									
										
										
										
											2014-11-16 23:31:32 -05:00
										 |  |  | generalizations kernel macros math math.bitwise namespaces | 
					
						
							|  |  |  | sequences slots words ;
 | 
					
						
							| 
									
										
										
										
											2014-06-02 20:07:32 -04:00
										 |  |  | QUALIFIED-WITH: alien.c-types c | 
					
						
							| 
									
										
										
										
											2011-09-21 17:04:17 -04:00
										 |  |  | IN: alien.endian | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ERROR: invalid-signed-conversion n ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : convert-signed-quot ( n -- quot )
 | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         { 1 [ [ char <ref> char deref ] ] } | 
					
						
							| 
									
										
										
										
											2014-06-02 20:07:32 -04:00
										 |  |  |         { 2 [ [ c:short <ref> c:short deref ] ] } | 
					
						
							| 
									
										
										
										
											2011-09-21 17:04:17 -04:00
										 |  |  |         { 4 [ [ int <ref> int deref ] ] } | 
					
						
							|  |  |  |         { 8 [ [ longlong <ref> longlong deref ] ] } | 
					
						
							| 
									
										
										
										
											2015-08-13 19:13:05 -04:00
										 |  |  |         [ invalid-signed-conversion ] | 
					
						
							| 
									
										
										
										
											2011-09-21 17:04:17 -04:00
										 |  |  |     } case ; inline
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | MACRO: byte-reverse ( n signed? -- quot )
 | 
					
						
							|  |  |  |     [ | 
					
						
							|  |  |  |         drop
 | 
					
						
							|  |  |  |         [ | 
					
						
							|  |  |  |             dup iota [ | 
					
						
							|  |  |  |                 [ 1 + - -8 * ] [ nip 8 * ] 2bi
 | 
					
						
							| 
									
										
										
										
											2011-11-23 21:49:33 -05:00
										 |  |  |                 '[ _ shift 0xff bitand _ shift ] | 
					
						
							| 
									
										
										
										
											2011-09-21 17:04:17 -04:00
										 |  |  |             ] 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 ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-22 12:26:06 -04:00
										 |  |  | : endian-c-type? ( symbol -- ? )
 | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         le8 be8 ule8 ube8 ule16 ule32 ule64 | 
					
						
							|  |  |  |         ube16 ube32 ube64 le16 le32 le64 be16 be32 be64 | 
					
						
							|  |  |  |     } member? ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-21 17:04:17 -04:00
										 |  |  | ERROR: unknown-endian-c-type symbol ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : endian-c-type>c-type-symbol ( symbol -- symbol' )
 | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         { [ dup { ule16 ube16 } member? ] [ drop ushort ] } | 
					
						
							| 
									
										
										
										
											2014-06-02 20:07:32 -04:00
										 |  |  |         { [ dup { le16 be16 } member? ] [ drop c:short ] } | 
					
						
							| 
									
										
										
										
											2011-09-21 17:04:17 -04:00
										 |  |  |         { [ 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
 | 
					
						
							| 
									
										
										
										
											2011-11-15 16:22:12 -05:00
										 |  |  |     -rot over 8 = [ | 
					
						
							|  |  |  |         [ | 
					
						
							|  |  |  |             nip
 | 
					
						
							|  |  |  |             [ | 
					
						
							|  |  |  |                 [ | 
					
						
							|  |  |  |                     [ alien-unsigned-4 4 f byte-reverse 32 shift ] | 
					
						
							|  |  |  |                     [ 4 + alien-unsigned-4 4 f byte-reverse ] 2bi bitor
 | 
					
						
							|  |  |  |                 ] | 
					
						
							| 
									
										
										
										
											2015-06-29 19:43:15 -04:00
										 |  |  |             ] dip [ [ 64 >signed ] compose ] when
 | 
					
						
							| 
									
										
										
										
											2011-11-15 16:22:12 -05:00
										 |  |  |             >>getter drop
 | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  |         [ '[ [ [ _ _ byte-reverse ] 2dip ] prepose ] change-setter ] 3bi
 | 
					
						
							|  |  |  |     ] [ | 
					
						
							|  |  |  |         [ '[ [ _ _ byte-reverse ] compose ] change-getter drop ] | 
					
						
							|  |  |  |         [ '[ [ [ _ _ byte-reverse ] 2dip ] prepose ] change-setter ] 3bi
 | 
					
						
							|  |  |  |     ] if ;
 | 
					
						
							| 
									
										
										
										
											2011-09-21 17:04:17 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : 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 | 
					
						
							| 
									
										
										
										
											2011-09-22 12:26:06 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | ! pair: { le be } | 
					
						
							|  |  |  | : pair>c-type ( pair -- c-type )
 | 
					
						
							|  |  |  |     [ native-endianness get big-endian = ] dip first2 ? ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ! endian is desired endian type. if we match endianness, return the c type | 
					
						
							|  |  |  | ! otherwise return the opposite of our endianness | 
					
						
							|  |  |  | : endian-slot ( endian c-type pair -- endian-slot )
 | 
					
						
							|  |  |  |     [ native-endianness get = ] 2dip rot [ drop ] [ nip pair>c-type ] if ;
 | 
					
						
							| 
									
										
										
										
											2014-06-02 20:07:32 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-22 12:26:06 -04:00
										 |  |  | ERROR: unsupported-endian-type endian slot ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : slot>endian-slot ( endian slot -- endian-slot )
 | 
					
						
							|  |  |  |     dup array? [ | 
					
						
							|  |  |  |         first2 [ slot>endian-slot ] dip 2array
 | 
					
						
							|  |  |  |     ] [ | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             { [ dup char = ] [ 2drop char ] } | 
					
						
							|  |  |  |             { [ dup uchar = ] [ 2drop uchar ] } | 
					
						
							| 
									
										
										
										
											2014-06-02 20:07:32 -04:00
										 |  |  |             { [ dup c:short = ] [ { le16 be16 } endian-slot ] } | 
					
						
							| 
									
										
										
										
											2011-09-22 12:26:06 -04:00
										 |  |  |             { [ dup ushort = ] [ { ule16 ube16 } endian-slot ] } | 
					
						
							|  |  |  |             { [ dup int = ] [ { le32 be32 } endian-slot ] } | 
					
						
							|  |  |  |             { [ dup uint = ] [ { ule32 ube32 } endian-slot ] } | 
					
						
							|  |  |  |             { [ dup longlong = ] [ { le64 be64 } endian-slot ] } | 
					
						
							|  |  |  |             { [ dup ulonglong = ] [ { ule64 ube64 } endian-slot ] } | 
					
						
							|  |  |  |             { [ dup endian-c-type? ] [ nip ] } | 
					
						
							|  |  |  |             [ unsupported-endian-type ] | 
					
						
							|  |  |  |         } cond
 | 
					
						
							|  |  |  |     ] if ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : set-endian-slots ( endian slots -- slot-specs )
 | 
					
						
							|  |  |  |     [ [ slot>endian-slot ] change-type ] with map ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : define-endian-struct-class ( class slots endian -- )
 | 
					
						
							|  |  |  |     swap make-slots set-endian-slots | 
					
						
							|  |  |  |     [ compute-struct-offsets ] [ struct-alignment ] | 
					
						
							|  |  |  |     (define-struct-class) ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : define-endian-packed-struct-class ( class slots endian -- )
 | 
					
						
							|  |  |  |     swap make-packed-slots set-endian-slots | 
					
						
							|  |  |  |     [ compute-struct-offsets ] [ drop 1 ] | 
					
						
							|  |  |  |     (define-struct-class) ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | SYNTAX: LE-STRUCT: | 
					
						
							|  |  |  |     parse-struct-definition | 
					
						
							|  |  |  |     little-endian define-endian-struct-class ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | SYNTAX: BE-STRUCT: | 
					
						
							|  |  |  |     parse-struct-definition | 
					
						
							|  |  |  |     big-endian define-endian-struct-class ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | SYNTAX: LE-PACKED-STRUCT: | 
					
						
							|  |  |  |     parse-struct-definition | 
					
						
							|  |  |  |     little-endian define-endian-packed-struct-class ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | SYNTAX: BE-PACKED-STRUCT: | 
					
						
							|  |  |  |     parse-struct-definition | 
					
						
							|  |  |  |     big-endian define-endian-packed-struct-class ;
 |