]> gitweb.factorcode.org Git - factor.git/blob - basis/pack/pack.factor
a330337c5e992b391eeb30e7233d5806714d0b1b
[factor.git] / basis / pack / pack.factor
1 ! Copyright (C) 2009 Doug Coleman.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: alien alien.c-types arrays assocs byte-arrays io
4 io.binary io.streams.string kernel math math.parser namespaces
5 make parser quotations sequences strings vectors
6 words macros math.functions math.bitwise fry generalizations
7 combinators.smart io.streams.byte-array io.encodings.binary
8 math.vectors combinators multiline endian ;
9 IN: pack
10
11 GENERIC: >n-byte-array ( obj n -- byte-array )
12
13 M: integer >n-byte-array ( m n -- byte-array ) >endian ;
14
15 ! for doing native, platform-dependent sized values
16 M: string >n-byte-array ( n string -- byte-array ) heap-size >n-byte-array ;
17
18 : s8>byte-array ( n -- byte-array ) 1 >n-byte-array ;
19 : u8>byte-array ( n -- byte-array ) 1 >n-byte-array ;
20 : s16>byte-array ( n -- byte-array ) 2 >n-byte-array ;
21 : u16>byte-array ( n -- byte-array ) 2 >n-byte-array ;
22 : s24>byte-array ( n -- byte-array ) 3 >n-byte-array ;
23 : u24>byte-array ( n -- byte-array ) 3 >n-byte-array ;
24 : s32>byte-array ( n -- byte-array ) 4 >n-byte-array ;
25 : u32>byte-array ( n -- byte-array ) 4 >n-byte-array ;
26 : s64>byte-array ( n -- byte-array ) 8 >n-byte-array ;
27 : u64>byte-array ( n -- byte-array ) 8 >n-byte-array ;
28 : s128>byte-array ( n -- byte-array ) 16 >n-byte-array ;
29 : u128>byte-array ( n -- byte-array ) 16 >n-byte-array ;
30 : write-float ( n -- byte-array ) float>bits 4 >n-byte-array ;
31 : write-double ( n -- byte-array ) double>bits 8 >n-byte-array ;
32 : write-c-string ( byte-array -- byte-array ) { 0 } B{ } append-as ;
33
34 <PRIVATE
35
36 CONSTANT: pack-table
37     H{
38         { CHAR: c s8>byte-array }
39         { CHAR: C u8>byte-array }
40         { CHAR: s s16>byte-array }
41         { CHAR: S u16>byte-array }
42         { CHAR: t s24>byte-array }
43         { CHAR: T u24>byte-array }
44         { CHAR: i s32>byte-array }
45         { CHAR: I u32>byte-array }
46         { CHAR: q s64>byte-array }
47         { CHAR: Q u64>byte-array }
48         { CHAR: f write-float }
49         { CHAR: F write-float }
50         { CHAR: d write-double }
51         { CHAR: D write-double }
52     }
53
54 CONSTANT: unpack-table
55     H{
56         { CHAR: c [ 8 signed-endian> ] }
57         { CHAR: C [ unsigned-endian> ] }
58         { CHAR: s [ 16 signed-endian> ] }
59         { CHAR: S [ unsigned-endian> ] }
60         { CHAR: t [ 24 signed-endian> ] }
61         { CHAR: T [ unsigned-endian> ] }
62         { CHAR: i [ 32 signed-endian> ] }
63         { CHAR: I [ unsigned-endian> ] }
64         { CHAR: q [ 64 signed-endian> ] }
65         { CHAR: Q [ unsigned-endian> ] }
66         { CHAR: f [ unsigned-endian> bits>float ] }
67         { CHAR: F [ unsigned-endian> bits>float ] }
68         { CHAR: d [ unsigned-endian> bits>double ] }
69         { CHAR: D [ unsigned-endian> bits>double ] }
70     }
71
72 CONSTANT: packed-length-table
73     H{
74         { CHAR: c 1 }
75         { CHAR: C 1 }
76         { CHAR: s 2 }
77         { CHAR: S 2 }
78         { CHAR: t 3 }
79         { CHAR: T 3 }
80         { CHAR: i 4 }
81         { CHAR: I 4 }
82         { CHAR: q 8 }
83         { CHAR: Q 8 }
84         { CHAR: f 4 }
85         { CHAR: F 4 }
86         { CHAR: d 8 }
87         { CHAR: D 8 }
88     }
89
90 PRIVATE>
91
92 MACRO: pack ( str -- quot )
93     [ pack-table at '[ _ execute ] ] { } map-as
94     '[ [ [ _ spread ] input<sequence ] B{ } append-outputs-as ] ;
95
96 : ch>packed-length ( ch -- n )
97     packed-length-table at ; inline
98
99 : packed-length ( str -- n )
100     [ ch>packed-length ] map-sum ;
101  
102 : pack-native ( seq str -- seq )
103     '[ _ _ pack ] with-native-endian ; inline
104
105 : pack-be ( seq str -- seq )
106     '[ _ _ pack ] with-big-endian ; inline
107
108 : pack-le ( seq str -- seq )
109     '[ _ _ pack ] with-little-endian ; inline
110
111 <PRIVATE
112
113 : start/end ( seq -- seq1 seq2 )
114     [ 0 [ + ] accumulate nip dup ] keep v+ ; inline
115
116 PRIVATE>
117
118 MACRO: unpack ( str -- quot )
119     [ [ ch>packed-length ] { } map-as start/end ]
120     [ [ unpack-table at '[ @ ] ] { } map-as ] bi
121     [ '[ [ _ _ ] dip <slice> @ ] ] 3map
122     '[ [ _ cleave ] output>array ] ;
123
124 : unpack-native ( seq str -- seq )
125     '[ _ _ unpack ] with-native-endian ; inline
126
127 : unpack-be ( seq str -- seq )
128     '[ _ _ unpack ] with-big-endian ; inline
129
130 : unpack-le ( seq str -- seq )
131     '[ _ _ unpack ] with-little-endian ; inline
132
133 ERROR: packed-read-fail str bytes ;
134
135 <PRIVATE
136
137 : read-packed-bytes ( str -- bytes )
138     dup packed-length [ read dup length ] keep =
139     [ nip ] [ packed-read-fail ] if ; inline
140
141 PRIVATE>
142
143 : read-packed ( str quot -- seq )
144     [ read-packed-bytes ] swap bi ; inline
145
146 : read-packed-le ( str -- seq )
147     [ unpack-le ] read-packed ; inline
148
149 : read-packed-be ( str -- seq )
150     [ unpack-be ] read-packed ; inline
151
152 : read-packed-native ( str -- seq )
153     [ unpack-native ] read-packed ; inline