annotate gcc/ada/tree_io.adb @ 145:1830386684a0

gcc-9.2.0
author anatofuz
date Thu, 13 Feb 2020 11:34:05 +0900
parents 84e7813d76e9
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 ------------------------------------------------------------------------------
kono
parents:
diff changeset
2 -- --
kono
parents:
diff changeset
3 -- GNAT COMPILER COMPONENTS --
kono
parents:
diff changeset
4 -- --
kono
parents:
diff changeset
5 -- T R E E _ I O --
kono
parents:
diff changeset
6 -- --
kono
parents:
diff changeset
7 -- B o d y --
kono
parents:
diff changeset
8 -- --
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
9 -- Copyright (C) 1992-2019, Free Software Foundation, Inc. --
111
kono
parents:
diff changeset
10 -- --
kono
parents:
diff changeset
11 -- GNAT is free software; you can redistribute it and/or modify it under --
kono
parents:
diff changeset
12 -- terms of the GNU General Public License as published by the Free Soft- --
kono
parents:
diff changeset
13 -- ware Foundation; either version 3, or (at your option) any later ver- --
kono
parents:
diff changeset
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
kono
parents:
diff changeset
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
kono
parents:
diff changeset
16 -- or FITNESS FOR A PARTICULAR PURPOSE. --
kono
parents:
diff changeset
17 -- --
kono
parents:
diff changeset
18 -- As a special exception under Section 7 of GPL version 3, you are granted --
kono
parents:
diff changeset
19 -- additional permissions described in the GCC Runtime Library Exception, --
kono
parents:
diff changeset
20 -- version 3.1, as published by the Free Software Foundation. --
kono
parents:
diff changeset
21 -- --
kono
parents:
diff changeset
22 -- You should have received a copy of the GNU General Public License and --
kono
parents:
diff changeset
23 -- a copy of the GCC Runtime Library Exception along with this program; --
kono
parents:
diff changeset
24 -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
kono
parents:
diff changeset
25 -- <http://www.gnu.org/licenses/>. --
kono
parents:
diff changeset
26 -- --
kono
parents:
diff changeset
27 -- GNAT was originally developed by the GNAT team at New York University. --
kono
parents:
diff changeset
28 -- Extensive contributions were provided by Ada Core Technologies Inc. --
kono
parents:
diff changeset
29 -- --
kono
parents:
diff changeset
30 ------------------------------------------------------------------------------
kono
parents:
diff changeset
31
kono
parents:
diff changeset
32 with Debug; use Debug;
kono
parents:
diff changeset
33 with Output; use Output;
kono
parents:
diff changeset
34 with Unchecked_Conversion;
kono
parents:
diff changeset
35
kono
parents:
diff changeset
36 package body Tree_IO is
kono
parents:
diff changeset
37 Debug_Flag_Tree : Boolean := False;
kono
parents:
diff changeset
38 -- Debug flag for debug output from tree read/write
kono
parents:
diff changeset
39
kono
parents:
diff changeset
40 -------------------------------------------
kono
parents:
diff changeset
41 -- Compression Scheme Used for Tree File --
kono
parents:
diff changeset
42 -------------------------------------------
kono
parents:
diff changeset
43
kono
parents:
diff changeset
44 -- We don't just write the data directly, but instead do a mild form
kono
parents:
diff changeset
45 -- of compression, since we expect lots of compressible zeroes and
kono
parents:
diff changeset
46 -- blanks. The compression scheme is as follows:
kono
parents:
diff changeset
47
kono
parents:
diff changeset
48 -- 00nnnnnn followed by nnnnnn bytes (non compressed data)
kono
parents:
diff changeset
49 -- 01nnnnnn indicates nnnnnn binary zero bytes
kono
parents:
diff changeset
50 -- 10nnnnnn indicates nnnnnn ASCII space bytes
kono
parents:
diff changeset
51 -- 11nnnnnn bbbbbbbb indicates nnnnnnnn occurrences of byte bbbbbbbb
kono
parents:
diff changeset
52
kono
parents:
diff changeset
53 -- Since we expect many zeroes in trees, and many spaces in sources,
kono
parents:
diff changeset
54 -- this compression should be reasonably efficient. We can put in
kono
parents:
diff changeset
55 -- something better later on.
kono
parents:
diff changeset
56
kono
parents:
diff changeset
57 -- Note that this compression applies to the Write_Tree_Data and
kono
parents:
diff changeset
58 -- Read_Tree_Data calls, not to the calls to read and write single
kono
parents:
diff changeset
59 -- scalar values, which are written in memory format without any
kono
parents:
diff changeset
60 -- compression.
kono
parents:
diff changeset
61
kono
parents:
diff changeset
62 C_Noncomp : constant := 2#00_000000#;
kono
parents:
diff changeset
63 C_Zeros : constant := 2#01_000000#;
kono
parents:
diff changeset
64 C_Spaces : constant := 2#10_000000#;
kono
parents:
diff changeset
65 C_Repeat : constant := 2#11_000000#;
kono
parents:
diff changeset
66 -- Codes for compression sequences
kono
parents:
diff changeset
67
kono
parents:
diff changeset
68 Max_Count : constant := 63;
kono
parents:
diff changeset
69 -- Maximum data length for one compression sequence
kono
parents:
diff changeset
70
kono
parents:
diff changeset
71 -- The above compression scheme applies only to data written with the
kono
parents:
diff changeset
72 -- Tree_Write routine and read with Tree_Read. Data written using the
kono
parents:
diff changeset
73 -- Tree_Write_Char or Tree_Write_Int routines and read using the
kono
parents:
diff changeset
74 -- corresponding input routines is not compressed.
kono
parents:
diff changeset
75
kono
parents:
diff changeset
76 type Int_Bytes is array (1 .. 4) of Byte;
kono
parents:
diff changeset
77 for Int_Bytes'Size use 32;
kono
parents:
diff changeset
78
kono
parents:
diff changeset
79 function To_Int_Bytes is new Unchecked_Conversion (Int, Int_Bytes);
kono
parents:
diff changeset
80 function To_Int is new Unchecked_Conversion (Int_Bytes, Int);
kono
parents:
diff changeset
81
kono
parents:
diff changeset
82 ----------------------
kono
parents:
diff changeset
83 -- Global Variables --
kono
parents:
diff changeset
84 ----------------------
kono
parents:
diff changeset
85
kono
parents:
diff changeset
86 Tree_FD : File_Descriptor;
kono
parents:
diff changeset
87 -- File descriptor for tree
kono
parents:
diff changeset
88
kono
parents:
diff changeset
89 Buflen : constant Int := 8_192;
kono
parents:
diff changeset
90 -- Length of buffer for read and write file data
kono
parents:
diff changeset
91
kono
parents:
diff changeset
92 Buf : array (Pos range 1 .. Buflen) of Byte;
kono
parents:
diff changeset
93 -- Read/write file data buffer
kono
parents:
diff changeset
94
kono
parents:
diff changeset
95 Bufn : Nat;
kono
parents:
diff changeset
96 -- Number of bytes read/written from/to buffer
kono
parents:
diff changeset
97
kono
parents:
diff changeset
98 Buft : Nat;
kono
parents:
diff changeset
99 -- Total number of bytes in input buffer containing valid data. Used only
kono
parents:
diff changeset
100 -- for input operations. There is data left to be processed in the buffer
kono
parents:
diff changeset
101 -- if Buft > Bufn. A value of zero for Buft means that the buffer is empty.
kono
parents:
diff changeset
102
kono
parents:
diff changeset
103 -----------------------
kono
parents:
diff changeset
104 -- Local Subprograms --
kono
parents:
diff changeset
105 -----------------------
kono
parents:
diff changeset
106
kono
parents:
diff changeset
107 procedure Read_Buffer;
kono
parents:
diff changeset
108 -- Reads data into buffer, setting Bufn appropriately
kono
parents:
diff changeset
109
kono
parents:
diff changeset
110 function Read_Byte return Byte;
kono
parents:
diff changeset
111 pragma Inline (Read_Byte);
kono
parents:
diff changeset
112 -- Returns next byte from input file, raises Tree_Format_Error if none left
kono
parents:
diff changeset
113
kono
parents:
diff changeset
114 procedure Write_Buffer;
kono
parents:
diff changeset
115 -- Writes out current buffer contents
kono
parents:
diff changeset
116
kono
parents:
diff changeset
117 procedure Write_Byte (B : Byte);
kono
parents:
diff changeset
118 pragma Inline (Write_Byte);
kono
parents:
diff changeset
119 -- Write one byte to output buffer, checking for buffer-full condition
kono
parents:
diff changeset
120
kono
parents:
diff changeset
121 -----------------
kono
parents:
diff changeset
122 -- Read_Buffer --
kono
parents:
diff changeset
123 -----------------
kono
parents:
diff changeset
124
kono
parents:
diff changeset
125 procedure Read_Buffer is
kono
parents:
diff changeset
126 begin
kono
parents:
diff changeset
127 Buft := Int (Read (Tree_FD, Buf (1)'Address, Integer (Buflen)));
kono
parents:
diff changeset
128
kono
parents:
diff changeset
129 if Buft = 0 then
kono
parents:
diff changeset
130 raise Tree_Format_Error;
kono
parents:
diff changeset
131 else
kono
parents:
diff changeset
132 Bufn := 0;
kono
parents:
diff changeset
133 end if;
kono
parents:
diff changeset
134 end Read_Buffer;
kono
parents:
diff changeset
135
kono
parents:
diff changeset
136 ---------------
kono
parents:
diff changeset
137 -- Read_Byte --
kono
parents:
diff changeset
138 ---------------
kono
parents:
diff changeset
139
kono
parents:
diff changeset
140 function Read_Byte return Byte is
kono
parents:
diff changeset
141 begin
kono
parents:
diff changeset
142 if Bufn = Buft then
kono
parents:
diff changeset
143 Read_Buffer;
kono
parents:
diff changeset
144 end if;
kono
parents:
diff changeset
145
kono
parents:
diff changeset
146 Bufn := Bufn + 1;
kono
parents:
diff changeset
147 return Buf (Bufn);
kono
parents:
diff changeset
148 end Read_Byte;
kono
parents:
diff changeset
149
kono
parents:
diff changeset
150 --------------------
kono
parents:
diff changeset
151 -- Tree_Read_Bool --
kono
parents:
diff changeset
152 --------------------
kono
parents:
diff changeset
153
kono
parents:
diff changeset
154 procedure Tree_Read_Bool (B : out Boolean) is
kono
parents:
diff changeset
155 begin
kono
parents:
diff changeset
156 B := Boolean'Val (Read_Byte);
kono
parents:
diff changeset
157
kono
parents:
diff changeset
158 if Debug_Flag_Tree then
kono
parents:
diff changeset
159 if B then
kono
parents:
diff changeset
160 Write_Str ("True");
kono
parents:
diff changeset
161 else
kono
parents:
diff changeset
162 Write_Str ("False");
kono
parents:
diff changeset
163 end if;
kono
parents:
diff changeset
164
kono
parents:
diff changeset
165 Write_Eol;
kono
parents:
diff changeset
166 end if;
kono
parents:
diff changeset
167 end Tree_Read_Bool;
kono
parents:
diff changeset
168
kono
parents:
diff changeset
169 --------------------
kono
parents:
diff changeset
170 -- Tree_Read_Char --
kono
parents:
diff changeset
171 --------------------
kono
parents:
diff changeset
172
kono
parents:
diff changeset
173 procedure Tree_Read_Char (C : out Character) is
kono
parents:
diff changeset
174 begin
kono
parents:
diff changeset
175 C := Character'Val (Read_Byte);
kono
parents:
diff changeset
176
kono
parents:
diff changeset
177 if Debug_Flag_Tree then
kono
parents:
diff changeset
178 Write_Str ("==> transmitting Character = ");
kono
parents:
diff changeset
179 Write_Char (C);
kono
parents:
diff changeset
180 Write_Eol;
kono
parents:
diff changeset
181 end if;
kono
parents:
diff changeset
182 end Tree_Read_Char;
kono
parents:
diff changeset
183
kono
parents:
diff changeset
184 --------------------
kono
parents:
diff changeset
185 -- Tree_Read_Data --
kono
parents:
diff changeset
186 --------------------
kono
parents:
diff changeset
187
kono
parents:
diff changeset
188 procedure Tree_Read_Data (Addr : Address; Length : Int) is
kono
parents:
diff changeset
189
kono
parents:
diff changeset
190 type S is array (Pos) of Byte;
kono
parents:
diff changeset
191 -- This is a big array, for which we have to suppress the warning
kono
parents:
diff changeset
192
kono
parents:
diff changeset
193 type SP is access all S;
kono
parents:
diff changeset
194
kono
parents:
diff changeset
195 function To_SP is new Unchecked_Conversion (Address, SP);
kono
parents:
diff changeset
196
kono
parents:
diff changeset
197 Data : constant SP := To_SP (Addr);
kono
parents:
diff changeset
198 -- Data buffer to be read as an indexable array of bytes
kono
parents:
diff changeset
199
kono
parents:
diff changeset
200 OP : Pos := 1;
kono
parents:
diff changeset
201 -- Pointer to next byte of data buffer to be read into
kono
parents:
diff changeset
202
kono
parents:
diff changeset
203 B : Byte;
kono
parents:
diff changeset
204 C : Byte;
kono
parents:
diff changeset
205 L : Int;
kono
parents:
diff changeset
206
kono
parents:
diff changeset
207 begin
kono
parents:
diff changeset
208 if Debug_Flag_Tree then
kono
parents:
diff changeset
209 Write_Str ("==> transmitting ");
kono
parents:
diff changeset
210 Write_Int (Length);
kono
parents:
diff changeset
211 Write_Str (" data bytes");
kono
parents:
diff changeset
212 Write_Eol;
kono
parents:
diff changeset
213 end if;
kono
parents:
diff changeset
214
kono
parents:
diff changeset
215 -- Verify data length
kono
parents:
diff changeset
216
kono
parents:
diff changeset
217 Tree_Read_Int (L);
kono
parents:
diff changeset
218
kono
parents:
diff changeset
219 if L /= Length then
kono
parents:
diff changeset
220 Write_Str ("==> transmitting, expected ");
kono
parents:
diff changeset
221 Write_Int (Length);
kono
parents:
diff changeset
222 Write_Str (" bytes, found length = ");
kono
parents:
diff changeset
223 Write_Int (L);
kono
parents:
diff changeset
224 Write_Eol;
kono
parents:
diff changeset
225 raise Tree_Format_Error;
kono
parents:
diff changeset
226 end if;
kono
parents:
diff changeset
227
kono
parents:
diff changeset
228 -- Loop to read data
kono
parents:
diff changeset
229
kono
parents:
diff changeset
230 while OP <= Length loop
kono
parents:
diff changeset
231
kono
parents:
diff changeset
232 -- Get compression control character
kono
parents:
diff changeset
233
kono
parents:
diff changeset
234 B := Read_Byte;
kono
parents:
diff changeset
235 C := B and 2#00_111111#;
kono
parents:
diff changeset
236 B := B and 2#11_000000#;
kono
parents:
diff changeset
237
kono
parents:
diff changeset
238 -- Non-repeat case
kono
parents:
diff changeset
239
kono
parents:
diff changeset
240 if B = C_Noncomp then
kono
parents:
diff changeset
241 if Debug_Flag_Tree then
kono
parents:
diff changeset
242 Write_Str ("==> uncompressed: ");
kono
parents:
diff changeset
243 Write_Int (Int (C));
kono
parents:
diff changeset
244 Write_Str (", starting at ");
kono
parents:
diff changeset
245 Write_Int (OP);
kono
parents:
diff changeset
246 Write_Eol;
kono
parents:
diff changeset
247 end if;
kono
parents:
diff changeset
248
kono
parents:
diff changeset
249 for J in 1 .. C loop
kono
parents:
diff changeset
250 Data (OP) := Read_Byte;
kono
parents:
diff changeset
251 OP := OP + 1;
kono
parents:
diff changeset
252 end loop;
kono
parents:
diff changeset
253
kono
parents:
diff changeset
254 -- Repeated zeroes
kono
parents:
diff changeset
255
kono
parents:
diff changeset
256 elsif B = C_Zeros then
kono
parents:
diff changeset
257 if Debug_Flag_Tree then
kono
parents:
diff changeset
258 Write_Str ("==> zeroes: ");
kono
parents:
diff changeset
259 Write_Int (Int (C));
kono
parents:
diff changeset
260 Write_Str (", starting at ");
kono
parents:
diff changeset
261 Write_Int (OP);
kono
parents:
diff changeset
262 Write_Eol;
kono
parents:
diff changeset
263 end if;
kono
parents:
diff changeset
264
kono
parents:
diff changeset
265 for J in 1 .. C loop
kono
parents:
diff changeset
266 Data (OP) := 0;
kono
parents:
diff changeset
267 OP := OP + 1;
kono
parents:
diff changeset
268 end loop;
kono
parents:
diff changeset
269
kono
parents:
diff changeset
270 -- Repeated spaces
kono
parents:
diff changeset
271
kono
parents:
diff changeset
272 elsif B = C_Spaces then
kono
parents:
diff changeset
273 if Debug_Flag_Tree then
kono
parents:
diff changeset
274 Write_Str ("==> spaces: ");
kono
parents:
diff changeset
275 Write_Int (Int (C));
kono
parents:
diff changeset
276 Write_Str (", starting at ");
kono
parents:
diff changeset
277 Write_Int (OP);
kono
parents:
diff changeset
278 Write_Eol;
kono
parents:
diff changeset
279 end if;
kono
parents:
diff changeset
280
kono
parents:
diff changeset
281 for J in 1 .. C loop
kono
parents:
diff changeset
282 Data (OP) := Character'Pos (' ');
kono
parents:
diff changeset
283 OP := OP + 1;
kono
parents:
diff changeset
284 end loop;
kono
parents:
diff changeset
285
kono
parents:
diff changeset
286 -- Specified repeated character
kono
parents:
diff changeset
287
kono
parents:
diff changeset
288 else -- B = C_Repeat
kono
parents:
diff changeset
289 B := Read_Byte;
kono
parents:
diff changeset
290
kono
parents:
diff changeset
291 if Debug_Flag_Tree then
kono
parents:
diff changeset
292 Write_Str ("==> other char: ");
kono
parents:
diff changeset
293 Write_Int (Int (C));
kono
parents:
diff changeset
294 Write_Str (" (");
kono
parents:
diff changeset
295 Write_Int (Int (B));
kono
parents:
diff changeset
296 Write_Char (')');
kono
parents:
diff changeset
297 Write_Str (", starting at ");
kono
parents:
diff changeset
298 Write_Int (OP);
kono
parents:
diff changeset
299 Write_Eol;
kono
parents:
diff changeset
300 end if;
kono
parents:
diff changeset
301
kono
parents:
diff changeset
302 for J in 1 .. C loop
kono
parents:
diff changeset
303 Data (OP) := B;
kono
parents:
diff changeset
304 OP := OP + 1;
kono
parents:
diff changeset
305 end loop;
kono
parents:
diff changeset
306 end if;
kono
parents:
diff changeset
307 end loop;
kono
parents:
diff changeset
308
kono
parents:
diff changeset
309 -- At end of loop, data item must be exactly filled
kono
parents:
diff changeset
310
kono
parents:
diff changeset
311 if OP /= Length + 1 then
kono
parents:
diff changeset
312 raise Tree_Format_Error;
kono
parents:
diff changeset
313 end if;
kono
parents:
diff changeset
314
kono
parents:
diff changeset
315 end Tree_Read_Data;
kono
parents:
diff changeset
316
kono
parents:
diff changeset
317 --------------------------
kono
parents:
diff changeset
318 -- Tree_Read_Initialize --
kono
parents:
diff changeset
319 --------------------------
kono
parents:
diff changeset
320
kono
parents:
diff changeset
321 procedure Tree_Read_Initialize (Desc : File_Descriptor) is
kono
parents:
diff changeset
322 begin
kono
parents:
diff changeset
323 Buft := 0;
kono
parents:
diff changeset
324 Bufn := 0;
kono
parents:
diff changeset
325 Tree_FD := Desc;
kono
parents:
diff changeset
326 Debug_Flag_Tree := Debug_Flag_5;
kono
parents:
diff changeset
327 end Tree_Read_Initialize;
kono
parents:
diff changeset
328
kono
parents:
diff changeset
329 -------------------
kono
parents:
diff changeset
330 -- Tree_Read_Int --
kono
parents:
diff changeset
331 -------------------
kono
parents:
diff changeset
332
kono
parents:
diff changeset
333 procedure Tree_Read_Int (N : out Int) is
kono
parents:
diff changeset
334 N_Bytes : Int_Bytes;
kono
parents:
diff changeset
335
kono
parents:
diff changeset
336 begin
kono
parents:
diff changeset
337 for J in 1 .. 4 loop
kono
parents:
diff changeset
338 N_Bytes (J) := Read_Byte;
kono
parents:
diff changeset
339 end loop;
kono
parents:
diff changeset
340
kono
parents:
diff changeset
341 N := To_Int (N_Bytes);
kono
parents:
diff changeset
342
kono
parents:
diff changeset
343 if Debug_Flag_Tree then
kono
parents:
diff changeset
344 Write_Str ("==> transmitting Int = ");
kono
parents:
diff changeset
345 Write_Int (N);
kono
parents:
diff changeset
346 Write_Eol;
kono
parents:
diff changeset
347 end if;
kono
parents:
diff changeset
348 end Tree_Read_Int;
kono
parents:
diff changeset
349
kono
parents:
diff changeset
350 -------------------
kono
parents:
diff changeset
351 -- Tree_Read_Str --
kono
parents:
diff changeset
352 -------------------
kono
parents:
diff changeset
353
kono
parents:
diff changeset
354 procedure Tree_Read_Str (S : out String_Ptr) is
kono
parents:
diff changeset
355 N : Nat;
kono
parents:
diff changeset
356
kono
parents:
diff changeset
357 begin
kono
parents:
diff changeset
358 Tree_Read_Int (N);
kono
parents:
diff changeset
359 S := new String (1 .. Natural (N));
kono
parents:
diff changeset
360 Tree_Read_Data (S.all (1)'Address, N);
kono
parents:
diff changeset
361 end Tree_Read_Str;
kono
parents:
diff changeset
362
kono
parents:
diff changeset
363 -------------------------
kono
parents:
diff changeset
364 -- Tree_Read_Terminate --
kono
parents:
diff changeset
365 -------------------------
kono
parents:
diff changeset
366
kono
parents:
diff changeset
367 procedure Tree_Read_Terminate is
kono
parents:
diff changeset
368 begin
kono
parents:
diff changeset
369 -- Must be at end of input buffer, so we should get Tree_Format_Error
kono
parents:
diff changeset
370 -- if we try to read one more byte, if not, we have a format error.
kono
parents:
diff changeset
371
kono
parents:
diff changeset
372 declare
kono
parents:
diff changeset
373 B : Byte;
kono
parents:
diff changeset
374 pragma Warnings (Off, B);
kono
parents:
diff changeset
375
kono
parents:
diff changeset
376 begin
kono
parents:
diff changeset
377 B := Read_Byte;
kono
parents:
diff changeset
378
kono
parents:
diff changeset
379 exception
kono
parents:
diff changeset
380 when Tree_Format_Error => return;
kono
parents:
diff changeset
381 end;
kono
parents:
diff changeset
382
kono
parents:
diff changeset
383 raise Tree_Format_Error;
kono
parents:
diff changeset
384 end Tree_Read_Terminate;
kono
parents:
diff changeset
385
kono
parents:
diff changeset
386 ---------------------
kono
parents:
diff changeset
387 -- Tree_Write_Bool --
kono
parents:
diff changeset
388 ---------------------
kono
parents:
diff changeset
389
kono
parents:
diff changeset
390 procedure Tree_Write_Bool (B : Boolean) is
kono
parents:
diff changeset
391 begin
kono
parents:
diff changeset
392 if Debug_Flag_Tree then
kono
parents:
diff changeset
393 Write_Str ("==> transmitting Boolean = ");
kono
parents:
diff changeset
394
kono
parents:
diff changeset
395 if B then
kono
parents:
diff changeset
396 Write_Str ("True");
kono
parents:
diff changeset
397 else
kono
parents:
diff changeset
398 Write_Str ("False");
kono
parents:
diff changeset
399 end if;
kono
parents:
diff changeset
400
kono
parents:
diff changeset
401 Write_Eol;
kono
parents:
diff changeset
402 end if;
kono
parents:
diff changeset
403
kono
parents:
diff changeset
404 Write_Byte (Boolean'Pos (B));
kono
parents:
diff changeset
405 end Tree_Write_Bool;
kono
parents:
diff changeset
406
kono
parents:
diff changeset
407 ---------------------
kono
parents:
diff changeset
408 -- Tree_Write_Char --
kono
parents:
diff changeset
409 ---------------------
kono
parents:
diff changeset
410
kono
parents:
diff changeset
411 procedure Tree_Write_Char (C : Character) is
kono
parents:
diff changeset
412 begin
kono
parents:
diff changeset
413 if Debug_Flag_Tree then
kono
parents:
diff changeset
414 Write_Str ("==> transmitting Character = ");
kono
parents:
diff changeset
415 Write_Char (C);
kono
parents:
diff changeset
416 Write_Eol;
kono
parents:
diff changeset
417 end if;
kono
parents:
diff changeset
418
kono
parents:
diff changeset
419 Write_Byte (Character'Pos (C));
kono
parents:
diff changeset
420 end Tree_Write_Char;
kono
parents:
diff changeset
421
kono
parents:
diff changeset
422 ---------------------
kono
parents:
diff changeset
423 -- Tree_Write_Data --
kono
parents:
diff changeset
424 ---------------------
kono
parents:
diff changeset
425
kono
parents:
diff changeset
426 procedure Tree_Write_Data (Addr : Address; Length : Int) is
kono
parents:
diff changeset
427
kono
parents:
diff changeset
428 type S is array (Pos) of Byte;
kono
parents:
diff changeset
429 -- This is a big array, for which we have to suppress the warning
kono
parents:
diff changeset
430
kono
parents:
diff changeset
431 type SP is access all S;
kono
parents:
diff changeset
432
kono
parents:
diff changeset
433 function To_SP is new Unchecked_Conversion (Address, SP);
kono
parents:
diff changeset
434
kono
parents:
diff changeset
435 Data : constant SP := To_SP (Addr);
kono
parents:
diff changeset
436 -- Pointer to data to be written, converted to array type
kono
parents:
diff changeset
437
kono
parents:
diff changeset
438 IP : Pos := 1;
kono
parents:
diff changeset
439 -- Input buffer pointer, next byte to be processed
kono
parents:
diff changeset
440
kono
parents:
diff changeset
441 NC : Nat range 0 .. Max_Count := 0;
kono
parents:
diff changeset
442 -- Number of bytes of non-compressible sequence
kono
parents:
diff changeset
443
kono
parents:
diff changeset
444 C : Byte;
kono
parents:
diff changeset
445
kono
parents:
diff changeset
446 procedure Write_Non_Compressed_Sequence;
kono
parents:
diff changeset
447 -- Output currently collected sequence of non-compressible data
kono
parents:
diff changeset
448
kono
parents:
diff changeset
449 -----------------------------------
kono
parents:
diff changeset
450 -- Write_Non_Compressed_Sequence --
kono
parents:
diff changeset
451 -----------------------------------
kono
parents:
diff changeset
452
kono
parents:
diff changeset
453 procedure Write_Non_Compressed_Sequence is
kono
parents:
diff changeset
454 begin
kono
parents:
diff changeset
455 if NC > 0 then
kono
parents:
diff changeset
456 Write_Byte (C_Noncomp + Byte (NC));
kono
parents:
diff changeset
457
kono
parents:
diff changeset
458 if Debug_Flag_Tree then
kono
parents:
diff changeset
459 Write_Str ("==> uncompressed: ");
kono
parents:
diff changeset
460 Write_Int (NC);
kono
parents:
diff changeset
461 Write_Str (", starting at ");
kono
parents:
diff changeset
462 Write_Int (IP - NC);
kono
parents:
diff changeset
463 Write_Eol;
kono
parents:
diff changeset
464 end if;
kono
parents:
diff changeset
465
kono
parents:
diff changeset
466 for J in reverse 1 .. NC loop
kono
parents:
diff changeset
467 Write_Byte (Data (IP - J));
kono
parents:
diff changeset
468 end loop;
kono
parents:
diff changeset
469
kono
parents:
diff changeset
470 NC := 0;
kono
parents:
diff changeset
471 end if;
kono
parents:
diff changeset
472 end Write_Non_Compressed_Sequence;
kono
parents:
diff changeset
473
kono
parents:
diff changeset
474 -- Start of processing for Tree_Write_Data
kono
parents:
diff changeset
475
kono
parents:
diff changeset
476 begin
kono
parents:
diff changeset
477 if Debug_Flag_Tree then
kono
parents:
diff changeset
478 Write_Str ("==> transmitting ");
kono
parents:
diff changeset
479 Write_Int (Length);
kono
parents:
diff changeset
480 Write_Str (" data bytes");
kono
parents:
diff changeset
481 Write_Eol;
kono
parents:
diff changeset
482 end if;
kono
parents:
diff changeset
483
kono
parents:
diff changeset
484 -- We write the count at the start, so that we can check it on
kono
parents:
diff changeset
485 -- the corresponding read to make sure that reads and writes match
kono
parents:
diff changeset
486
kono
parents:
diff changeset
487 Tree_Write_Int (Length);
kono
parents:
diff changeset
488
kono
parents:
diff changeset
489 -- Conversion loop
kono
parents:
diff changeset
490 -- IP is index of next input character
kono
parents:
diff changeset
491 -- NC is number of non-compressible bytes saved up
kono
parents:
diff changeset
492
kono
parents:
diff changeset
493 loop
kono
parents:
diff changeset
494 -- If input is completely processed, then we are all done
kono
parents:
diff changeset
495
kono
parents:
diff changeset
496 if IP > Length then
kono
parents:
diff changeset
497 Write_Non_Compressed_Sequence;
kono
parents:
diff changeset
498 return;
kono
parents:
diff changeset
499 end if;
kono
parents:
diff changeset
500
kono
parents:
diff changeset
501 -- Test for compressible sequence, must be at least three identical
kono
parents:
diff changeset
502 -- bytes in a row to be worthwhile compressing.
kono
parents:
diff changeset
503
kono
parents:
diff changeset
504 if IP + 2 <= Length
kono
parents:
diff changeset
505 and then Data (IP) = Data (IP + 1)
kono
parents:
diff changeset
506 and then Data (IP) = Data (IP + 2)
kono
parents:
diff changeset
507 then
kono
parents:
diff changeset
508 Write_Non_Compressed_Sequence;
kono
parents:
diff changeset
509
kono
parents:
diff changeset
510 -- Count length of new compression sequence
kono
parents:
diff changeset
511
kono
parents:
diff changeset
512 C := 3;
kono
parents:
diff changeset
513 IP := IP + 3;
kono
parents:
diff changeset
514
kono
parents:
diff changeset
515 while IP < Length
kono
parents:
diff changeset
516 and then Data (IP) = Data (IP - 1)
kono
parents:
diff changeset
517 and then C < Max_Count
kono
parents:
diff changeset
518 loop
kono
parents:
diff changeset
519 C := C + 1;
kono
parents:
diff changeset
520 IP := IP + 1;
kono
parents:
diff changeset
521 end loop;
kono
parents:
diff changeset
522
kono
parents:
diff changeset
523 -- Output compression sequence
kono
parents:
diff changeset
524
kono
parents:
diff changeset
525 if Data (IP - 1) = 0 then
kono
parents:
diff changeset
526 if Debug_Flag_Tree then
kono
parents:
diff changeset
527 Write_Str ("==> zeroes: ");
kono
parents:
diff changeset
528 Write_Int (Int (C));
kono
parents:
diff changeset
529 Write_Str (", starting at ");
kono
parents:
diff changeset
530 Write_Int (IP - Int (C));
kono
parents:
diff changeset
531 Write_Eol;
kono
parents:
diff changeset
532 end if;
kono
parents:
diff changeset
533
kono
parents:
diff changeset
534 Write_Byte (C_Zeros + C);
kono
parents:
diff changeset
535
kono
parents:
diff changeset
536 elsif Data (IP - 1) = Character'Pos (' ') then
kono
parents:
diff changeset
537 if Debug_Flag_Tree then
kono
parents:
diff changeset
538 Write_Str ("==> spaces: ");
kono
parents:
diff changeset
539 Write_Int (Int (C));
kono
parents:
diff changeset
540 Write_Str (", starting at ");
kono
parents:
diff changeset
541 Write_Int (IP - Int (C));
kono
parents:
diff changeset
542 Write_Eol;
kono
parents:
diff changeset
543 end if;
kono
parents:
diff changeset
544
kono
parents:
diff changeset
545 Write_Byte (C_Spaces + C);
kono
parents:
diff changeset
546
kono
parents:
diff changeset
547 else
kono
parents:
diff changeset
548 if Debug_Flag_Tree then
kono
parents:
diff changeset
549 Write_Str ("==> other char: ");
kono
parents:
diff changeset
550 Write_Int (Int (C));
kono
parents:
diff changeset
551 Write_Str (" (");
kono
parents:
diff changeset
552 Write_Int (Int (Data (IP - 1)));
kono
parents:
diff changeset
553 Write_Char (')');
kono
parents:
diff changeset
554 Write_Str (", starting at ");
kono
parents:
diff changeset
555 Write_Int (IP - Int (C));
kono
parents:
diff changeset
556 Write_Eol;
kono
parents:
diff changeset
557 end if;
kono
parents:
diff changeset
558
kono
parents:
diff changeset
559 Write_Byte (C_Repeat + C);
kono
parents:
diff changeset
560 Write_Byte (Data (IP - 1));
kono
parents:
diff changeset
561 end if;
kono
parents:
diff changeset
562
kono
parents:
diff changeset
563 -- No compression possible here
kono
parents:
diff changeset
564
kono
parents:
diff changeset
565 else
kono
parents:
diff changeset
566 -- Output non-compressed sequence if at maximum length
kono
parents:
diff changeset
567
kono
parents:
diff changeset
568 if NC = Max_Count then
kono
parents:
diff changeset
569 Write_Non_Compressed_Sequence;
kono
parents:
diff changeset
570 end if;
kono
parents:
diff changeset
571
kono
parents:
diff changeset
572 NC := NC + 1;
kono
parents:
diff changeset
573 IP := IP + 1;
kono
parents:
diff changeset
574 end if;
kono
parents:
diff changeset
575 end loop;
kono
parents:
diff changeset
576
kono
parents:
diff changeset
577 end Tree_Write_Data;
kono
parents:
diff changeset
578
kono
parents:
diff changeset
579 ---------------------------
kono
parents:
diff changeset
580 -- Tree_Write_Initialize --
kono
parents:
diff changeset
581 ---------------------------
kono
parents:
diff changeset
582
kono
parents:
diff changeset
583 procedure Tree_Write_Initialize (Desc : File_Descriptor) is
kono
parents:
diff changeset
584 begin
kono
parents:
diff changeset
585 Bufn := 0;
kono
parents:
diff changeset
586 Tree_FD := Desc;
kono
parents:
diff changeset
587 Set_Standard_Error;
kono
parents:
diff changeset
588 Debug_Flag_Tree := Debug_Flag_5;
kono
parents:
diff changeset
589 end Tree_Write_Initialize;
kono
parents:
diff changeset
590
kono
parents:
diff changeset
591 --------------------
kono
parents:
diff changeset
592 -- Tree_Write_Int --
kono
parents:
diff changeset
593 --------------------
kono
parents:
diff changeset
594
kono
parents:
diff changeset
595 procedure Tree_Write_Int (N : Int) is
kono
parents:
diff changeset
596 N_Bytes : constant Int_Bytes := To_Int_Bytes (N);
kono
parents:
diff changeset
597
kono
parents:
diff changeset
598 begin
kono
parents:
diff changeset
599 if Debug_Flag_Tree then
kono
parents:
diff changeset
600 Write_Str ("==> transmitting Int = ");
kono
parents:
diff changeset
601 Write_Int (N);
kono
parents:
diff changeset
602 Write_Eol;
kono
parents:
diff changeset
603 end if;
kono
parents:
diff changeset
604
kono
parents:
diff changeset
605 for J in 1 .. 4 loop
kono
parents:
diff changeset
606 Write_Byte (N_Bytes (J));
kono
parents:
diff changeset
607 end loop;
kono
parents:
diff changeset
608 end Tree_Write_Int;
kono
parents:
diff changeset
609
kono
parents:
diff changeset
610 --------------------
kono
parents:
diff changeset
611 -- Tree_Write_Str --
kono
parents:
diff changeset
612 --------------------
kono
parents:
diff changeset
613
kono
parents:
diff changeset
614 procedure Tree_Write_Str (S : String_Ptr) is
kono
parents:
diff changeset
615 begin
kono
parents:
diff changeset
616 Tree_Write_Int (S'Length);
kono
parents:
diff changeset
617 Tree_Write_Data (S (1)'Address, S'Length);
kono
parents:
diff changeset
618 end Tree_Write_Str;
kono
parents:
diff changeset
619
kono
parents:
diff changeset
620 --------------------------
kono
parents:
diff changeset
621 -- Tree_Write_Terminate --
kono
parents:
diff changeset
622 --------------------------
kono
parents:
diff changeset
623
kono
parents:
diff changeset
624 procedure Tree_Write_Terminate is
kono
parents:
diff changeset
625 begin
kono
parents:
diff changeset
626 if Bufn > 0 then
kono
parents:
diff changeset
627 Write_Buffer;
kono
parents:
diff changeset
628 end if;
kono
parents:
diff changeset
629 end Tree_Write_Terminate;
kono
parents:
diff changeset
630
kono
parents:
diff changeset
631 ------------------
kono
parents:
diff changeset
632 -- Write_Buffer --
kono
parents:
diff changeset
633 ------------------
kono
parents:
diff changeset
634
kono
parents:
diff changeset
635 procedure Write_Buffer is
kono
parents:
diff changeset
636 begin
kono
parents:
diff changeset
637 if Integer (Bufn) = Write (Tree_FD, Buf'Address, Integer (Bufn)) then
kono
parents:
diff changeset
638 Bufn := 0;
kono
parents:
diff changeset
639
kono
parents:
diff changeset
640 else
kono
parents:
diff changeset
641 Set_Standard_Error;
kono
parents:
diff changeset
642 Write_Str ("fatal error: disk full");
kono
parents:
diff changeset
643 OS_Exit (2);
kono
parents:
diff changeset
644 end if;
kono
parents:
diff changeset
645 end Write_Buffer;
kono
parents:
diff changeset
646
kono
parents:
diff changeset
647 ----------------
kono
parents:
diff changeset
648 -- Write_Byte --
kono
parents:
diff changeset
649 ----------------
kono
parents:
diff changeset
650
kono
parents:
diff changeset
651 procedure Write_Byte (B : Byte) is
kono
parents:
diff changeset
652 begin
kono
parents:
diff changeset
653 Bufn := Bufn + 1;
kono
parents:
diff changeset
654 Buf (Bufn) := B;
kono
parents:
diff changeset
655
kono
parents:
diff changeset
656 if Bufn = Buflen then
kono
parents:
diff changeset
657 Write_Buffer;
kono
parents:
diff changeset
658 end if;
kono
parents:
diff changeset
659 end Write_Byte;
kono
parents:
diff changeset
660
kono
parents:
diff changeset
661 end Tree_IO;