Commit | Line | Data |
---|---|---|
920dae64 AT |
1 | \ ========== Copyright Header Begin ========================================== |
2 | \ | |
3 | \ Hypervisor Software File: decompress.fth | |
4 | \ | |
5 | \ Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. | |
6 | \ | |
7 | \ - Do no alter or remove copyright notices | |
8 | \ | |
9 | \ - Redistribution and use of this software in source and binary forms, with | |
10 | \ or without modification, are permitted provided that the following | |
11 | \ conditions are met: | |
12 | \ | |
13 | \ - Redistribution of source code must retain the above copyright notice, | |
14 | \ this list of conditions and the following disclaimer. | |
15 | \ | |
16 | \ - Redistribution in binary form must reproduce the above copyright notice, | |
17 | \ this list of conditions and the following disclaimer in the | |
18 | \ documentation and/or other materials provided with the distribution. | |
19 | \ | |
20 | \ Neither the name of Sun Microsystems, Inc. or the names of contributors | |
21 | \ may be used to endorse or promote products derived from this software | |
22 | \ without specific prior written permission. | |
23 | \ | |
24 | \ This software is provided "AS IS," without a warranty of any kind. | |
25 | \ ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, | |
26 | \ INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A | |
27 | \ PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN | |
28 | \ MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR | |
29 | \ ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR | |
30 | \ DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN | |
31 | \ OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR | |
32 | \ FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE | |
33 | \ DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, | |
34 | \ ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF | |
35 | \ SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. | |
36 | \ | |
37 | \ You acknowledge that this software is not designed, licensed or | |
38 | \ intended for use in the design, construction, operation or maintenance of | |
39 | \ any nuclear facility. | |
40 | \ | |
41 | \ ========== Copyright Header End ============================================ | |
42 | id: @(#)decompress.fth 1.11 02/02/28 | |
43 | purpose: | |
44 | copyright: Copyright 1997-2001 Sun Microsystems, Inc. All Rights Reserved | |
45 | ||
46 | headers | |
47 | transient | |
48 | ||
49 | inline-struct? on | |
50 | d# 258 constant dc-first-code | |
51 | d# 257 constant dc-end-code | |
52 | d# 256 constant dc-clear-code | |
53 | inline-struct? off | |
54 | ||
55 | resident | |
56 | ||
57 | vocabulary decompressor also decompressor definitions | |
58 | headerless | |
59 | ||
60 | : decomp-cleanup ( err$ -- ) ." Decomp: " type cr r> drop ; | |
61 | ||
62 | : decomp-alloc ( len -- va ) | |
63 | 0 tuck [ also client-services ] claim [ previous ] | |
64 | ; | |
65 | ||
66 | : decomp-free ( va len -- ) | |
67 | swap [ also client-services ] release [ previous ] | |
68 | ; | |
69 | ||
70 | : maxcode! ( data buffer -- ) >maxcode l! ; | |
71 | ||
72 | : finchar@ ( buffer -- data ) >fin-char l@ ; | |
73 | : finchar! ( data buffer -- ) >fin-char l! ; | |
74 | ||
75 | : de-stack@ ( buffer -- data ) >de-stack l@ ; | |
76 | ||
77 | : tab-suffix@ ( offset buffer -- data ) >tab-suffix l@ + c@ ; | |
78 | : tab-suffix! ( data offset buffer -- ) >tab-suffix l@ + c! ; | |
79 | ||
80 | : tab-prefix@ ( offset buffer -- data ) >tab-prefix l@ swap 2* + w@ ; | |
81 | : tab-prefix! ( data offset buffer -- ) >tab-prefix l@ swap 2* + w! ; | |
82 | ||
83 | : free-ent@ ( offset -- data ) >free-ent l@ ; | |
84 | : free-ent! ( data offset -- ) >free-ent l! ; | |
85 | ||
86 | : n>maxbits ( n_bits -- maxcode ) 1 swap << 1- ; | |
87 | ||
88 | : >init-n-bits ( size buffer -- ) | |
89 | 2dup >n-bits l! ( size buffer ) | |
90 | swap n>maxbits swap maxcode! ( -- ) | |
91 | ; | |
92 | ||
93 | : clear-prefix ( buffer -- ) >tab-prefix l@ d# 512 0 fill ; | |
94 | ||
95 | : init-decompress ( src len dest buffer -- ) | |
96 | dup >r ( src len dest buffer ) | |
97 | /decomp-control 0 fill ( src len dest ) | |
98 | ||
99 | r@ >dest-addr l! ( src ) | |
100 | r@ >source-size l! ( src dest ) | |
101 | r@ >source-addr l! ( -- ) | |
102 | ||
103 | #init-bits r@ >init-n-bits | |
104 | dc-first-code r@ free-ent! | |
105 | ||
106 | r@ >tab-suffix-offset r@ >tab-suffix l! | |
107 | r@ >tab-prefix-offset r@ >tab-prefix l! | |
108 | r@ >destack-offset r@ >de-stack l! | |
109 | ||
110 | \ initialize the first 256 entries in the table. | |
111 | r@ clear-prefix | |
112 | r@ >tab-suffix l@ h# 100 0 do i over c! 1+ loop drop | |
113 | ||
114 | r> drop | |
115 | ; | |
116 | ||
117 | : getcode(n-bits) ( buffer -- code EOF? ) | |
118 | dup >n-bits l@ swap decomp-getcode ( code ) | |
119 | dup -1 = ( code -1? ) | |
120 | over dc-end-code = or ( code EOF? ) | |
121 | ; | |
122 | ||
123 | : (decompress) ( src len dest scratch -- ) | |
124 | ||
125 | dup >r | |
126 | init-decompress | |
127 | ||
128 | r@ decomp-getbyte h# 1f = | |
129 | r@ decomp-getbyte h# 9e = and 0= if | |
130 | r> drop " Bad MAGIC number" decomp-cleanup | |
131 | then | |
132 | ||
133 | r@ decomp-getbyte dc-#bits <> if | |
134 | r> drop " Bad #bits" decomp-cleanup | |
135 | then | |
136 | ||
137 | r@ getcode(n-bits) if ( code ) | |
138 | r> 2drop " short decompress" decomp-cleanup | |
139 | then ( code ) | |
140 | ||
141 | \ putbyte( finchar ) | |
142 | dup r@ decomp-putbyte ( oldcode ) | |
143 | dup r@ finchar! ( oldcode ) | |
144 | r@ de-stack@ ( oldcode stackp ) | |
145 | begin ( oldcode stackp ) | |
146 | r@ getcode(n-bits) 0= ( oldcode stackp code EOF? ) | |
147 | over dc-end-code <> and ( oldcode stackp code more? ) | |
148 | while ( oldcode stackp code ) | |
149 | ||
150 | dup dc-clear-code = if ( oldcode stackp code ) | |
151 | drop ( oldcode stackp ) | |
152 | ||
153 | \ for (i=255; i>=0; i--) tab_prefix[i] = 0; | |
154 | r@ clear-prefix ( oldcode stackp ) | |
155 | ||
156 | \ maxcode = MAXCODE(n_bits = INIT_BITS) | |
157 | #init-bits r@ >init-n-bits ( oldcode stackp ) | |
158 | ||
159 | \ free-ent = first-code - 1 | |
160 | dc-first-code 1- ( oldcode stackp first-code ) | |
161 | r@ free-ent! ( oldcode stackp ) | |
162 | ||
163 | \ if ( (code = getcode (n_bits)) == -1 ) break; | |
164 | r@ getcode(n-bits) if ( oldcode stackp code ) | |
165 | r> 2drop 2drop exit ( -- ) | |
166 | then ( oldcode stackp code ) | |
167 | then ( oldcpde stackp code ) | |
168 | ||
169 | \ incode = code | |
170 | dup r@ >incode l! ( oldcpde stackp code ) | |
171 | ||
172 | \ if (code >= free_ent) | |
173 | dup r@ free-ent@ >= if ( oldcode stackp code ) | |
174 | drop ( oldcode stackp ) | |
175 | ||
176 | \ *stackp++ = finchar | |
177 | r@ finchar@ over c! 1+ ( oldcode stackp finchar ) | |
178 | ||
179 | \ code = oldcode | |
180 | over ( oldcode stackp code ) | |
181 | then | |
182 | ||
183 | \ while (code>=256) | |
184 | begin ( oldcode stackp code ) | |
185 | dup d# 256 >= while ( oldcode stackp code ) | |
186 | tuck r@ tab-suffix@ ( oldcode code stackp data) | |
187 | ||
188 | \ *stackp++ = tab_suffix[code] | |
189 | over c! 1+ ( oldcode code stackp ) | |
190 | ||
191 | \ code = tab_prefix[code] | |
192 | swap r@ tab-prefix@ ( oldcode code stackp data ) | |
193 | repeat ( oldcode stackp code ) | |
194 | ||
195 | \ finchar = tab_suffix[code] | |
196 | tuck r@ tab-suffix@ ( oldcode code stackp data ) | |
197 | dup r@ finchar! ( oldcode code stackp data ) | |
198 | ||
199 | \ *stackp++ = finchar | |
200 | over c! 1+ ( oldcode code stackp ) | |
201 | ||
202 | begin ( oldcode code stackp ) | |
203 | \ putbyte ( *--stackp ) | |
204 | 1- dup c@ r@ decomp-putbyte | |
205 | dup r@ de-stack@ = until ( oldcode code stackp ) | |
206 | ||
207 | \ code = free-ent | |
208 | nip r@ free-ent@ ( oldcode stackp code ) | |
209 | ||
210 | rot ( stackp code oldcode ) | |
211 | ||
212 | \ if (code < maxmaxcode) | |
213 | over maxmaxbits < if ( stackp code oldcode ) | |
214 | ||
215 | \ tab_prefix[code] = oldcode | |
216 | over r@ tab-prefix! ( stackp code ) | |
217 | ||
218 | \ tab_suffix[code] = finchar | |
219 | r@ finchar@ ( stackp code finchar ) | |
220 | over r@ tab-suffix! ( stackp code ) | |
221 | ||
222 | \ free_ent = code+1 | |
223 | 1+ r@ free-ent! ( stackp ) | |
224 | else ( stackp code oldcode ) | |
225 | 2drop ( stackp ) | |
226 | then ( stackp ) | |
227 | ||
228 | \ oldcode = incode | |
229 | r@ >incode l@ swap ( oldcode stackp ) | |
230 | ||
231 | \ if ( free_ent > maxcode ) | |
232 | r@ free-ent@ ( oldcode stackp free-ent ) | |
233 | r@ >maxcode l@ > if ( oldcode stackp ) | |
234 | ||
235 | \ n_bits++ | |
236 | r@ >n-bits ( oldcode stackp addr ) | |
237 | 1 over l+! l@ ( oldcode stackp nbits ) | |
238 | ||
239 | \ maxcode = ( n_bits == BITS ) ? maxmaxbits : MAXCODE(n_bits) | |
240 | dup n>maxbits ( oldcode stackp nbits maxcode ) | |
241 | swap dc-#bits = if ( oldcode stackp maxcode ) | |
242 | drop maxmaxbits ( oldcode stackp maxcode ) | |
243 | then ( oldcode stackp maxcode ) | |
244 | r@ maxcode! ( oldcode stackp ) | |
245 | ||
246 | then ( oldcode stackp ) | |
247 | repeat ( oldcode stackp ) | |
248 | ||
249 | r> 2drop 2drop ( -- ) | |
250 | ; | |
251 | ||
252 | : bump-addr,len ( addr len n -- addr' len' ) tuck - -rot + swap ; | |
253 | ||
254 | : (do-decompress) ( addr len dlen -- addr' len' ) | |
255 | dup /di-header + decomp-alloc ( addr len dlen dest ) | |
256 | /di-header + swap ( adr len dest dlen ) | |
257 | over ( adr len dest dlen dest ) | |
258 | /decomp-data decomp-alloc ( adr len dest dlen dest scratch ) | |
259 | -rot ( adr len dest scratch dlen dest ) | |
260 | swap 2>r dup >r ( adr len dest scratch ) | |
261 | (decompress) ( -- ) | |
262 | r> /decomp-data decomp-free ( -- ) | |
263 | 2r> ( addr' len' ) | |
264 | ; | |
265 | ||
266 | \ | |
267 | \ Support for other decompression would be added here. | |
268 | \ | |
269 | headers | |
270 | ||
271 | : do-decompress ( addr len -- ok? ) | |
272 | over d# 12 + l@ >r ( addr len ) ( r: dlen ) | |
273 | over d# 8 + l@ >r ( addr len ) ( r: dlen type ) | |
274 | d# 16 bump-addr,len ( addr' len' dlen ) | |
275 | 2r> case ( addr' len' dlen ) | |
276 | h# 434f4d50 of (do-decompress) true endof ( true ) \ COMP | |
277 | \ h# 475a4950 of ... true endof ( true ) \ GZIP | |
278 | ( default ) 2drop 0 swap ( false ) | |
279 | endcase ( flag? ) | |
280 | ; | |
281 | ||
282 | : finish-decompress ( addr' len' -- ) | |
283 | [ 0 /di-header - ] literal bump-addr,len decomp-free | |
284 | ; | |
285 | ||
286 | previous definitions | |
287 | headerless |