Subversion Repositories tendra.SVN

Rev

Rev 5 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 7u83 1
/*
6 7u83 2
 * Copyright (c) 2002-2005 The TenDRA Project <http://www.tendra.org/>.
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions are met:
7
 *
8
 * 1. Redistributions of source code must retain the above copyright notice,
9
 *    this list of conditions and the following disclaimer.
10
 * 2. Redistributions in binary form must reproduce the above copyright notice,
11
 *    this list of conditions and the following disclaimer in the documentation
12
 *    and/or other materials provided with the distribution.
13
 * 3. Neither the name of The TenDRA Project nor the names of its contributors
14
 *    may be used to endorse or promote products derived from this software
15
 *    without specific, prior written permission.
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
18
 * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
19
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
21
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22
 * EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
27
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
 *
29
 * $Id$
30
 */
31
/*
2 7u83 32
    		 Crown Copyright (c) 1997
6 7u83 33
 
2 7u83 34
    This TenDRA(r) Computer Program is subject to Copyright
35
    owned by the United Kingdom Secretary of State for Defence
36
    acting through the Defence Evaluation and Research Agency
37
    (DERA).  It is made available to Recipients with a
38
    royalty-free licence for its use, reproduction, transfer
39
    to other parties and amendment for any purpose not excluding
40
    product development provided that any such use et cetera
41
    shall be deemed to be acceptance of the following conditions:-
6 7u83 42
 
2 7u83 43
        (1) Its Recipients shall ensure that this Notice is
44
        reproduced upon any copies or amended versions of it;
6 7u83 45
 
2 7u83 46
        (2) Any amended version of it shall be clearly marked to
47
        show both the nature of and the organisation responsible
48
        for the relevant amendment or amendments;
6 7u83 49
 
2 7u83 50
        (3) Its onward transfer from a recipient to another
51
        party shall be deemed to be that party's acceptance of
52
        these conditions;
6 7u83 53
 
2 7u83 54
        (4) DERA gives no warranty or assurance as to its
55
        quality or suitability for any purpose and DERA accepts
56
        no liability whatsoever in relation to any use to which
57
        it may be put.
58
*/
59
 
60
 
61
#include "config.h"
62
#include "types.h"
63
#include "enc_types.h"
64
#include "bitstream.h"
65
#include "encode.h"
66
#include "high.h"
67
#include "names.h"
68
#include "table.h"
69
#include "tdf.h"
70
#include "utility.h"
71
 
72
 
73
/*
74
    ENCODE AN EXTENDED VALUE
75
 
76
    The extended value n is encoded in b bits on the bitstream p.
77
*/
78
 
6 7u83 79
void
80
enc_bits_extn(bitstream *p, int b, long n)
2 7u83 81
{
6 7u83 82
    long m = ((1 << b) - 1);
83
    if (n == 0)fatal_error("Can't encode 0 as an extended value");
84
    while (n > m) {
85
	enc_bits(p, b,(long)0);
86
	n -= m;
2 7u83 87
    }
6 7u83 88
    enc_bits(p, b, n);
89
    return;
2 7u83 90
}
91
 
92
 
93
/*
94
    AUXILIARY TDF INTEGER ENCODING ROUTINE
95
 
96
    The value n is encoded as a series of octal digits into the
97
    bitstream p.
98
*/
99
 
6 7u83 100
static void
101
enc_tdf_int_aux(bitstream *p, long n)
2 7u83 102
{
6 7u83 103
    unsigned long m = (unsigned long)n;
104
    if (m >= 8)enc_tdf_int_aux(p,(long)(m >> 3));
105
    enc_bits(p, 4,(long)(m & 7));
106
    return;
2 7u83 107
}
108
 
109
 
110
/*
111
    ENCODE A TDF INTEGER
112
 
113
    The value n is encoded as a TDF integer into the bitstream p.
114
*/
115
 
6 7u83 116
void
117
enc_tdf_int(bitstream *p, long n)
2 7u83 118
{
6 7u83 119
    unsigned long m = (unsigned long)n;
120
    if (m >= 8)enc_tdf_int_aux(p,(long)(m >> 3));
121
    enc_bits(p, 4,(long)((m & 7) | 8));
122
    return;
2 7u83 123
}
124
 
125
 
126
/*
127
    ENCODE AN ALIGNED STRING
128
 
129
    The string s is encoded as an aligned string into the bitstream p.
130
    n is either the length of s, or -1, indicating that strlen should
131
    be used to find the length.
132
*/
133
 
6 7u83 134
void
135
enc_aligned_string(bitstream *p, char *s, long n)
2 7u83 136
{
6 7u83 137
    long i;
138
    if (n == -1)n = (long)strlen(s);
139
    enc_tdf_int(p,(long)8);
140
    enc_tdf_int(p, n);
141
    align_bitstream(p);
142
    for (i = 0; i < n; i++) {
143
	long c = (long)s[i];
144
	enc_bits(p, 8, c);
2 7u83 145
    }
6 7u83 146
    return;
2 7u83 147
}
148
 
149
 
150
/*
151
    ENCODE AN EXTERNAL NAME
152
 
153
    The external name of the construct p is encoded into the bitstream b.
154
*/
155
 
6 7u83 156
void
157
enc_external(bitstream *b, construct *p)
2 7u83 158
{
6 7u83 159
    node *e = p->ename;
160
    enc_tdf_int(b, p->encoding);
161
    if (e->cons->encoding) {
162
	node *q = e->son;
163
	if (q->cons->sortnum == SORT_tdfstring) {
164
	    node *r = q->bro;
165
	    if (r == null) {
166
		enc_external_bits(b, ENC_string_extern);
167
		align_bitstream(b);
168
		enc_aligned_string(b, q->cons->name, q->cons->encoding);
2 7u83 169
	    } else {
6 7u83 170
		enc_external_bits(b, ENC_chain_extern);
171
		align_bitstream(b);
172
		enc_aligned_string(b, q->cons->name, q->cons->encoding);
173
		enc_node(b, r);
2 7u83 174
	    }
175
	} else {
6 7u83 176
	    enc_external_bits(b, ENC_unique_extern);
177
	    align_bitstream(b);
178
	    enc_tdf_int(b, q->cons->encoding);
179
	    for (q = e->son->son; q; q = q->bro) {
180
		enc_aligned_string(b, q->cons->name, q->cons->encoding);
2 7u83 181
	    }
182
	}
183
    } else {
6 7u83 184
	enc_external_bits(b, ENC_string_extern);
185
	align_bitstream(b);
186
	enc_aligned_string(b, p->name,(long) -1);
2 7u83 187
    }
6 7u83 188
    return;
2 7u83 189
}
190
 
191
 
192
/*
193
    FIND THE VALUE OF A STRING OF OCTAL DIGITS
194
 
195
    The value of the node p, which represents a number, is returned.
196
*/
197
 
6 7u83 198
static long
199
octval(node *p)
2 7u83 200
{
6 7u83 201
    long n = (long)octal_to_ulong(p->bro->cons->name);
202
    if (p->cons->encoding)n = -n;
203
    return(n);
2 7u83 204
}
205
 
206
 
207
/*
208
    ENCODE A NODE
209
 
210
    The node p is encoded into the bitstream b.
211
*/
212
 
6 7u83 213
void
214
enc_node(bitstream *b, node *p)
2 7u83 215
{
6 7u83 216
    while (p) {
217
	construct *q = p->cons;
218
	switch (q->sortnum) {
2 7u83 219
 
6 7u83 220
	    case SORT_tdfbool: {
2 7u83 221
		/* Encode a bit */
6 7u83 222
		enc_bits(b, 1, q->encoding);
223
		break;
2 7u83 224
	    }
225
 
6 7u83 226
	    case SORT_bytestream: {
2 7u83 227
		/* Encode a bytestream */
6 7u83 228
		bitstream *c = new_bitstream();
229
		enc_node(c, p->son);
230
		enc_tdf_int(b, bitstream_length(c));
231
		join_bitstreams(b, c);
232
		break;
2 7u83 233
	    }
234
 
6 7u83 235
	    case SORT_completion: {
2 7u83 236
		/* Encode a completion */
6 7u83 237
		if (p->son)enc_node(b, p->son);
238
		break;
2 7u83 239
	    }
240
 
6 7u83 241
	    case SORT_small_tdfint: {
2 7u83 242
		/* Encode a small integer */
6 7u83 243
		enc_tdf_int(b, q->encoding);
244
		break;
2 7u83 245
	    }
246
 
6 7u83 247
	    case SORT_tdfint: {
2 7u83 248
		/* Encode a number */
6 7u83 249
		char *num = q->name;
250
		while (*num) {
251
		    long d = (long)(*num - '0');
252
		    num++;
253
		    if (*num == 0)d |= 8;
254
		    enc_bits(b, 4, d);
2 7u83 255
		}
6 7u83 256
		break;
2 7u83 257
	    }
258
 
6 7u83 259
	    case SORT_option: {
2 7u83 260
		/* Encode an optional argument */
6 7u83 261
		if (p->son) {
262
		    enc_bits(b, 1,(long)1);
263
		    enc_node(b, p->son);
2 7u83 264
		} else {
6 7u83 265
		    enc_bits(b, 1,(long)0);
2 7u83 266
		}
6 7u83 267
		break;
2 7u83 268
	    }
269
 
6 7u83 270
	    case SORT_repeat: {
2 7u83 271
		/* Encode a repeated argument */
6 7u83 272
		enc_list_start(b);
273
		enc_tdf_int(b, q->encoding);
274
		if (p->son)enc_node(b, p->son);
275
		break;
2 7u83 276
	    }
277
 
6 7u83 278
	    case SORT_tdfstring: {
2 7u83 279
		/* Encode a string */
6 7u83 280
		long i, n = q->encoding;
281
		if (n == -1) {
282
		    node *r = p->son;
283
		    long m = octval(r);
284
		    if (m < 0)m = -m;
285
		    r = r->bro->bro;
286
		    n = r->cons->encoding;
287
		    r = r->son;
288
		    enc_tdf_int(b, m);
289
		    enc_tdf_int(b, n);
290
		    for (i = 0; i < n; i++) {
291
			enc_bits(b,(int)m, octval(r));
292
			r = r->bro->bro;
2 7u83 293
		    }
294
		} else {
6 7u83 295
		    enc_tdf_int(b,(long)8);
296
		    enc_tdf_int(b, n);
297
		    for (i = 0; i < n; i++) {
298
			long c = (long)q->name[i];
299
			enc_bits(b, 8, c);
2 7u83 300
		    }
301
		}
6 7u83 302
		break;
2 7u83 303
	    }
304
 
6 7u83 305
	    case SORT_unknown: {
2 7u83 306
		/* Encode an unknown bitstream */
6 7u83 307
		fatal_error("Can't encode unknown bitstream");
308
		break;
2 7u83 309
	    }
310
 
6 7u83 311
	    case SORT_al_tag: {
2 7u83 312
		/* Encode an alignment tag */
6 7u83 313
		long e = q->encoding;
314
		enc_al_tag_bits(b,(int)e);
315
		if (e == ENC_make_al_tag) {
316
		    enc_tdf_int(b, p->son->cons->encoding);
2 7u83 317
		} else {
6 7u83 318
		    if (p->son)enc_node(b, p->son);
2 7u83 319
		}
6 7u83 320
		break;
2 7u83 321
	    }
322
 
6 7u83 323
	    case SORT_label: {
2 7u83 324
		/* Encode a label */
6 7u83 325
		long e = q->encoding;
326
		enc_label_bits(b,(int)e);
327
		if (e == ENC_make_label) {
328
		    enc_tdf_int(b, p->son->cons->encoding);
2 7u83 329
		} else {
6 7u83 330
		    if (p->son)enc_node(b, p->son);
2 7u83 331
		}
6 7u83 332
		break;
2 7u83 333
	    }
334
 
6 7u83 335
	    case SORT_tag: {
2 7u83 336
		/* Encode a tag */
6 7u83 337
		long e = q->encoding;
338
		enc_tag_bits(b,(int)e);
339
		if (e == ENC_make_tag) {
340
		    enc_tdf_int(b, p->son->cons->encoding);
2 7u83 341
		} else {
6 7u83 342
		    if (p->son)enc_node(b, p->son);
2 7u83 343
		}
6 7u83 344
		break;
2 7u83 345
	    }
346
 
6 7u83 347
	    case SORT_token: {
2 7u83 348
		/* Encode a token */
6 7u83 349
		tok_info *info = get_tok_info(q);
350
		if (is_high(info->res)) {
351
		    enc_token_bits(b, ENC_token_apply_token);
352
		    enc_token_bits(b, ENC_make_tok);
353
		    enc_tdf_int(b, q->encoding);
354
		    enc_tdf_int(b,(long)0);
2 7u83 355
		} else {
6 7u83 356
		    enc_token_bits(b, ENC_make_tok);
357
		    enc_tdf_int(b, q->encoding);
2 7u83 358
		}
6 7u83 359
		if (p->son) {
360
		    if (p->son->cons != &token_cons) {
361
			bitstream *c = new_bitstream();
362
			enc_node(c, p->son);
363
			enc_tdf_int(b, bitstream_length(c));
364
			join_bitstreams(b, c);
2 7u83 365
		    }
366
		} else {
6 7u83 367
		    enc_tdf_int(b,(long)0);
2 7u83 368
		}
6 7u83 369
		break;
2 7u83 370
	    }
371
 
372
	    default : {
373
		/* Encode a simple sort */
6 7u83 374
		int bits = sort_encoding[q->sortnum];
375
		int extn = sort_extension[q->sortnum];
376
		if (extn) {
377
		    enc_bits_extn(b, bits, q->encoding);
2 7u83 378
		} else {
6 7u83 379
		    enc_bits(b, bits, q->encoding);
2 7u83 380
		}
6 7u83 381
		if (p->son)enc_node(b, p->son);
382
		break;
2 7u83 383
	    }
384
	}
6 7u83 385
	p = p->bro;
2 7u83 386
    }
6 7u83 387
    return;
2 7u83 388
}
389
 
390
 
391
/*
392
    ENCODE A SORT
393
*/
394
 
6 7u83 395
static void
396
enc_sort(bitstream *b, sortname s)
2 7u83 397
{
6 7u83 398
    if (is_high(s)) {
399
	int i;
400
	high_sort *h = high_sorts + high_no(s);
401
	enc_sort(b, SORT_token);
402
	enc_sort(b, h->res);
403
	enc_list_start(b);
404
	enc_tdf_int(b,(long)h->no_args);
405
	for (i = 0; i < h->no_args; i++) {
406
	    enc_sort(b, h->args[i]);
2 7u83 407
	}
408
    } else {
6 7u83 409
	enc_sortname_bits(b, s);
2 7u83 410
    }
6 7u83 411
    return;
2 7u83 412
}
413
 
414
 
415
/*
416
    ALIGNMENT TAG DEFINITION AUXILIARY ENCODING ROUTINE
417
 
418
    The definition of the alignment tag p is encoded into the bitstream p.
419
*/
420
 
6 7u83 421
void
422
enc_aldef(bitstream *b, construct *p)
2 7u83 423
{
6 7u83 424
    al_tag_info *info = get_al_tag_info(p);
425
    enc_al_tagdef_bits(b, ENC_make_al_tagdef);
426
    enc_tdf_int(b, p->encoding);
427
    enc_node(b, info->def);
428
    return;
2 7u83 429
}
430
 
431
 
432
/*
433
    TAG DECLARATION AUXILIARY ENCODING ROUTINE
434
 
435
    The declaration of the tag p is encoded into the bitstream p.
436
*/
437
 
6 7u83 438
void
439
enc_tagdec(bitstream *b, construct *p)
2 7u83 440
{
6 7u83 441
    int m = 0;
442
    tag_info *info = get_tag_info(p);
443
    switch (info->var) {
444
	case 0: m = ENC_make_id_tagdec; break;
445
	case 1: m = ENC_make_var_tagdec; break;
446
	case 2: m = ENC_common_tagdec; break;
2 7u83 447
    }
6 7u83 448
    enc_tagdec_bits(b, m);
449
    enc_tdf_int(b, p->encoding);
450
    enc_node(b, info->dec);
451
    return;
2 7u83 452
}
453
 
454
 
455
/*
456
    TAG DEFINITION AUXILIARY ENCODING ROUTINE
457
 
458
    The definition of the tag p is encoded into the bitstream p.  Because
459
    of common_tagdef, there may actually be more than one definition.
460
    The number of definitions is returned.
461
*/
462
 
6 7u83 463
int
464
enc_tagdef(bitstream *b, construct *p)
2 7u83 465
{
6 7u83 466
    int n = 0;
467
    int m = 0;
468
    tag_info *info = get_tag_info(p);
469
    node *d = info->def;
470
    switch (info->var) {
471
	case 0: m = ENC_make_id_tagdef; break;
472
	case 1: m = ENC_make_var_tagdef; break;
473
	case 2: m = ENC_common_tagdef; break;
2 7u83 474
    }
6 7u83 475
    while (d) {
2 7u83 476
	/* Can have multiple definitions */
6 7u83 477
	enc_tagdef_bits(b, m);
478
	enc_tdf_int(b, p->encoding);
479
	enc_node(b, d->son);
480
	d = d->bro;
481
	n++;
2 7u83 482
    }
6 7u83 483
    return(n);
2 7u83 484
}
485
 
486
 
487
/*
488
    WORK OUT THE NUMBER OF FORMAL ARGUMENTS GIVEN A STRING
489
*/
490
 
6 7u83 491
static long
492
no_formals(char *args)
2 7u83 493
{
6 7u83 494
    long n = 0;
495
    while (*args) {
496
	args = find_sortname(args,(sortname *)null);
497
	args++;
498
	n = n + 1;
2 7u83 499
    }
6 7u83 500
    return(n);
2 7u83 501
}
502
 
503
 
504
/*
505
    TOKEN DECLARATION AUXILIARY ENCODING ROUTINE
506
 
507
    The declaration of the token p is encoded into the bitstream p.
508
*/
509
 
6 7u83 510
void
511
enc_tokdec(bitstream *b, construct *p)
2 7u83 512
{
6 7u83 513
    tok_info *info = get_tok_info(p);
514
    enc_tokdec_bits(b, ENC_make_tokdec);
515
    enc_tdf_int(b, p->encoding);
2 7u83 516
 
517
    /* Deal with signature */
6 7u83 518
    if (info->sig == null) {
519
	enc_bits(b, 1,(long)0);
2 7u83 520
    } else {
6 7u83 521
	enc_node(b, info->sig);
2 7u83 522
    }
523
 
524
    /* Encode token sort */
6 7u83 525
    enc_sort(b, SORT_token);
2 7u83 526
 
527
    /* Encode the token result sort */
6 7u83 528
    enc_sort(b, info->res);
2 7u83 529
 
530
    /* Encode the token argument sorts */
6 7u83 531
    enc_list_start(b);
532
    if (info->args) {
533
	char *q = info->args;
534
	enc_tdf_int(b, no_formals(q));
535
	while (*q) {
536
	    sortname s;
537
	    q = find_sortname(q, &s);
538
	    q++;
539
	    enc_sort(b, s);
2 7u83 540
	}
541
    } else {
6 7u83 542
	enc_tdf_int(b,(long)0);
2 7u83 543
    }
6 7u83 544
    return;
2 7u83 545
}
546
 
547
 
548
/*
549
    TOKEN DEFINITION AUXILIARY ENCODING ROUTINE
550
 
551
    The definition of the token p is encoded into the bitstream p.
552
*/
553
 
6 7u83 554
void
555
enc_tokdef(bitstream *b, construct *p)
2 7u83 556
{
6 7u83 557
    bitstream *c = new_bitstream();
558
    tok_info *info = get_tok_info(p);
559
    enc_tokdef_bits(b, ENC_make_tokdef);
560
    enc_tdf_int(b, p->encoding);
2 7u83 561
 
562
    /* Deal with signature */
6 7u83 563
    if (info->sig == null) {
564
	enc_bits(b, 1,(long)0);
2 7u83 565
    } else {
6 7u83 566
	enc_node(b, info->sig);
2 7u83 567
    }
568
 
569
    /* Encode token definition type */
6 7u83 570
    enc_token_defn_bits(c, ENC_token_definition);
2 7u83 571
 
572
    /* Encode the token result sort */
6 7u83 573
    enc_sort(c, info->res);
2 7u83 574
 
575
    /* Encode the token arguments */
6 7u83 576
    enc_list_start(c);
577
    if (info->args) {
578
	construct **q = info->pars;
579
	enc_tdf_int(c, no_formals(info->args));
580
	while (*q) {
581
	    tok_info *qinfo = get_tok_info(*q);
582
	    enc_sort(c, qinfo->res);
583
	    enc_tdf_int(c,(*q) ->encoding);
584
	    q++;
2 7u83 585
	}
586
    } else {
6 7u83 587
	enc_tdf_int(c,(long)0);
2 7u83 588
    }
589
 
590
    /* Encode the token definition */
6 7u83 591
    enc_node(c, info->def);
592
    enc_tdf_int(b, bitstream_length(c));
593
    join_bitstreams(b, c);
594
    return;
2 7u83 595
}