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"
6 7u83 64
#include "enc_cap.h"
2 7u83 65
#include "bitstream.h"
66
#include "encode.h"
67
#include "names.h"
68
#include "node.h"
69
#include "table.h"
70
#include "tdf.h"
71
#include "utility.h"
72
 
73
 
74
/*
75
    CURRENT BITSTREAM
76
 
77
    This is the main bitstream.
78
*/
79
 
6 7u83 80
static bitstream *crt_bitstream;
2 7u83 81
 
82
 
83
/*
84
    NUMBERS OF EQUATIONS AND VARIABLE SORTS
85
 
86
    The number of equation types and variable sorts in the output capsule.
87
*/
88
 
6 7u83 89
static long eqn_total, var_total;
2 7u83 90
 
91
 
92
/*
93
    LINKAGE INFORMATION ENCODING VARIABLES
94
 
95
    The tld2 unit gives information on the use, declaration and
96
    definition of the externally named tags and tokens.
97
*/
98
 
6 7u83 99
static bitstream *tld_bs;
2 7u83 100
 
101
 
102
/*
103
    ALIGNMENT TAG ENCODING VARIABLES
104
 
105
    The alignment tag definitions are formed in the bitstream al_tag_defs_bs.
106
    There are al_tag_total alignment tags, of which al_tag_external have
107
    external names and al_tag_defs are defined.
108
*/
109
 
6 7u83 110
static long al_tag_total = 0;
111
static long al_tag_external = 0;
112
static long al_tag_defs = 0;
113
static bitstream *al_tag_defs_bs;
2 7u83 114
 
115
 
116
/*
117
    AUXILIARY ALIGNMENT TAG ENCODING ROUTINE
118
 
119
    The alignment tag encoding variables are modified according to the
120
    construct p.
121
*/
122
 
6 7u83 123
static void
124
enc_al_tag_aux(construct *p)
2 7u83 125
{
6 7u83 126
    al_tag_info *info = get_al_tag_info(p);
127
    al_tag_total++;
128
    if (p->ename) {
129
	al_tag_external++;
130
	enc_tdf_int(tld_bs,(long)(info->def ? 5 : 1));
2 7u83 131
    }
6 7u83 132
    if (info->def == null) return;
133
    al_tag_defs++;
134
    enc_aldef(al_tag_defs_bs, p);
135
    return;
2 7u83 136
}
137
 
138
 
139
/*
140
    AUXILIARY ROUTINE FOR ENCODING ALIGNMENT TAG NAMES
141
 
142
    The external name (if any) of the alignment tag construct p is encoded.
143
*/
144
 
6 7u83 145
static void
146
enc_al_tag_names(construct *p)
2 7u83 147
{
6 7u83 148
    if (p->ename == null) return;
149
    enc_external(crt_bitstream, p);
150
    return;
2 7u83 151
}
152
 
153
 
154
/*
155
    TAG ENCODING VARIABLES
156
 
157
    The tag declarations are formed in the bitstream tag_decs_bs and
158
    the definitions in tag_defs_bs.  There are tag_total tags, of
159
    which tag_external have external names, tag_decs have declarations
160
    and tag_defs have definitions.
161
*/
162
 
6 7u83 163
static long tag_total = 0;
164
static long tag_external = 0;
165
static long tag_decs = 0;
166
static long tag_defs = 0;
167
static bitstream *tag_decs_bs;
168
static bitstream *tag_defs_bs;
2 7u83 169
 
170
 
171
/*
172
    AUXILIARY TAG ENCODING ROUTINE
173
 
174
    The tag encoding variables are modified according to the construct p.
175
*/
176
 
6 7u83 177
static void
178
enc_tag_aux(construct *p)
2 7u83 179
{
6 7u83 180
    tag_info *info = get_tag_info(p);
181
    tag_total++;
182
    if (info->var == 3) return;
183
    if (p->ename) {
184
	tag_external++;
185
	enc_tdf_int(tld_bs,(long)(info->def ? 7 : 3));
2 7u83 186
    }
6 7u83 187
    tag_decs++;
188
    enc_tagdec(tag_decs_bs, p);
189
    if (info->def == null) return;
190
    tag_defs += enc_tagdef(tag_defs_bs, p);
191
    return;
2 7u83 192
}
193
 
194
 
195
/*
196
    AUXILIARY ROUTINE FOR ENCODING TAG NAMES
197
 
198
    The external name (if any) of the tag construct p is encoded.
199
*/
200
 
6 7u83 201
static void
202
enc_tag_names(construct *p)
2 7u83 203
{
6 7u83 204
    tag_info *info = get_tag_info(p);
205
    if (info->var == 3) return;
206
    if (p->ename == null) return;
207
    enc_external(crt_bitstream, p);
208
    return;
2 7u83 209
}
210
 
211
 
212
/*
213
    TOKEN ENCODING VARIABLES
214
 
215
    The token declarations are formed in the bitstream tok_decs_bs and
216
    the definitions in tok_defs_bs.  There are tok_total tokens, of
217
    which tok_external have external names, tok_decs have declarations
218
    and tok_defs have definitions.
219
*/
220
 
6 7u83 221
static long tok_total = 0;
222
static long tok_external = 0;
223
static long tok_decs = 0;
224
static long tok_defs = 0;
225
static bitstream *tok_decs_bs;
226
static bitstream *tok_defs_bs;
2 7u83 227
 
228
 
229
/*
230
    AUXILIARY TOKEN ENCODING ROUTINE
231
 
232
    The token encoding variables are modified according to the construct p.
233
*/
234
 
6 7u83 235
static void
236
enc_token_aux(construct *p)
2 7u83 237
{
6 7u83 238
    tok_info *info = get_tok_info(p);
239
    if (p->encoding == -1) return;
240
    tok_total++;
241
    if (info->dec == 0) return;
242
    if (p->ename) {
243
	tok_external++;
244
	if (info->def) {
245
	    enc_tdf_int(tld_bs,(long)5);
2 7u83 246
	} else {
6 7u83 247
	    enc_tdf_int(tld_bs,(long)3);
2 7u83 248
	}
249
    }
6 7u83 250
    if (info->def == null || !show_tokdefs) {
251
	if (info->args) {
252
	    tok_decs++;
253
	    enc_tokdec(tok_decs_bs, p);
2 7u83 254
	}
255
    } else {
6 7u83 256
	tok_defs++;
257
	enc_tokdef(tok_defs_bs, p);
2 7u83 258
    }
6 7u83 259
    return;
2 7u83 260
}
261
 
262
 
263
/*
264
    AUXILIARY ROUTINE FOR ENCODING TOKEN NAMES
265
 
266
    The external name (if any) of the token construct p is encoded.
267
*/
268
 
6 7u83 269
static void
270
enc_token_names(construct *p)
2 7u83 271
{
6 7u83 272
    tok_info *info = get_tok_info(p);
273
    if (p->encoding == -1) return;
274
    if (info->dec == 0) return;
275
    if (p->ename == null) return;
276
    enc_external(crt_bitstream, p);
277
    return;
2 7u83 278
}
279
 
280
 
281
/*
282
    LABEL ENCODING VARIABLES
283
 
284
    There are lab_total labels.
285
*/
286
 
6 7u83 287
static long lab_total = 0;
2 7u83 288
 
289
 
290
/*
291
    AUXILIARY LABEL ENCODING ROUTINE
292
 
293
    The label encoding variables are modified according to the construct p.
294
*/
295
 
6 7u83 296
/*ARGSUSED*/ static void
297
enc_label_aux(construct *p)
2 7u83 298
{
6 7u83 299
    UNUSED(p);
300
    lab_total++;
301
    return;
2 7u83 302
}
303
 
304
 
305
/*
306
    ENCODE A SET OF LINKS
307
 
308
    A set of ntok token link, nalign alignment tag links and ntag tag
309
    nlinks are encoded into the bitstream p.  Since the same numbers
310
    are used for variable sorts in all the encoded units these links
311
    are identities.
312
*/
313
 
6 7u83 314
static void
315
enc_links(bitstream *p, long ntok, long nalign, long ntag)
2 7u83 316
{
6 7u83 317
    long i;
318
    enc_tdf_int(p, var_total);
319
    if (tok_total)enc_tdf_int(p, ntok);
320
    if (al_tag_total)enc_tdf_int(p, nalign);
321
    if (tag_total)enc_tdf_int(p, ntag);
322
    enc_tdf_int(p, var_total);
2 7u83 323
 
324
    /* Token links */
6 7u83 325
    if (tok_total) {
326
	enc_tdf_int(p, ntok);
327
	for (i = 0; i < ntok; i++) {
328
	    enc_tdf_int(p, i);
329
	    enc_tdf_int(p, i);
2 7u83 330
	}
331
    }
332
 
333
    /* Alignment tag links */
6 7u83 334
    if (al_tag_total) {
335
	enc_tdf_int(p, nalign);
336
	for (i = 0; i < nalign; i++) {
337
	    enc_tdf_int(p, i);
338
	    enc_tdf_int(p, i);
2 7u83 339
	}
340
    }
341
 
342
    /* Tag links */
6 7u83 343
    if (tag_total) {
344
	enc_tdf_int(p, ntag);
345
	for (i = 0; i < ntag; i++) {
346
	    enc_tdf_int(p, i);
347
	    enc_tdf_int(p, i);
2 7u83 348
	}
349
    }
6 7u83 350
    return;
2 7u83 351
}
352
 
353
 
354
/*
355
    EQUATION TYPES
356
*/
357
 
358
#define EQN_VERS	0
359
#define EQN_TLD		1
360
#define EQN_TOKDEC	2
361
#define EQN_TOKDEF	3
362
#define EQN_ALDEF	4
363
#define EQN_TAGDEC	5
364
#define EQN_TAGDEF	6
365
 
366
 
367
/*
368
    ENCODE AN EQUATION
369
 
370
    The ne equations of type t (see above) given in the bitstream q are
371
    encoded into the bitstream p.
372
*/
373
 
6 7u83 374
static void
375
enc_equation(bitstream *p, long ne, bitstream *q, int t)
2 7u83 376
{
6 7u83 377
    long n;
378
    bitstream *u;
2 7u83 379
 
6 7u83 380
    if (ne == 0) {
2 7u83 381
	/* There are no sets of equations */
6 7u83 382
	enc_tdf_int(p,(long)0);
383
	return;
2 7u83 384
    }
385
 
386
    /* There is one set of equations */
6 7u83 387
    enc_tdf_int(p,(long)1);
388
    u = new_bitstream();
2 7u83 389
 
390
    /* Encode the links */
6 7u83 391
    switch (t) {
392
	case EQN_VERS: {
393
	    enc_links(p,(long)0,(long)0,(long)0);
394
	    enc_tdf_int(u, ne);
395
	    break;
2 7u83 396
	}
6 7u83 397
	case EQN_TLD: {
398
	    enc_tdf_int(p,(long)0);
399
	    enc_tdf_int(p,(long)0);
400
	    break;
2 7u83 401
	}
6 7u83 402
	case EQN_TOKDEC: {
403
	    enc_links(p, tok_total,(long)0,(long)0);
404
	    enc_tdf_int(u, ne);
405
	    break;
2 7u83 406
	}
407
	default : {
6 7u83 408
	    enc_links(p, tok_total, al_tag_total, tag_total);
409
	    enc_tdf_int(u, lab_total);
410
	    enc_tdf_int(u, ne);
411
	    break;
2 7u83 412
	}
413
    }
414
 
415
    /* Append the body to the links */
6 7u83 416
    join_bitstreams(u, q);
417
    align_bitstream(u);
2 7u83 418
 
419
    /* Precede links and body by their length in bytes */
6 7u83 420
    n = bitstream_length(u);
421
    enc_tdf_int(p,(long)(n / BYTESIZE));
422
    align_bitstream(p);
423
    join_bitstreams(p, u);
424
    return;
2 7u83 425
}
426
 
427
 
428
/*
429
    VERSION NUMBERS
430
 
431
    These variables give the major and minor version numbers.
432
*/
433
 
6 7u83 434
static char *magic_number = VERSION_capsule;
435
long version_major = VERSION_major;
436
long version_minor = VERSION_minor;
2 7u83 437
 
438
 
439
/*
440
    ENCODE A CAPSULE
441
 
442
    A complete capsule is encoded.
443
*/
444
 
6 7u83 445
void
446
enc_capsule(void)
2 7u83 447
{
6 7u83 448
    long n;
449
    bitstream *vers_bs;
450
    char *m = magic_number;
451
    bitstream *p = new_bitstream();
2 7u83 452
 
453
    /* Map to lowest applicable version number */
6 7u83 454
    if (version_major == 4) {
455
	if (version_minor == 1)version_minor = 0;
2 7u83 456
    }
457
 
458
    /* Initialize the equation bitstreams */
6 7u83 459
    tld_bs = new_bitstream();
460
    tok_decs_bs = new_bitstream();
461
    tok_defs_bs = new_bitstream();
462
    al_tag_defs_bs = new_bitstream();
463
    tag_decs_bs = new_bitstream();
464
    tag_defs_bs = new_bitstream();
2 7u83 465
 
466
    /* Analyse all the tags, tokens etc */
6 7u83 467
    enc_tdf_int(tld_bs,(long)1);
468
    apply_to_all(enc_label_aux, SORT_label);
469
    apply_to_all(enc_token_aux, SORT_token);
470
    apply_to_all(enc_al_tag_aux, SORT_al_tag);
471
    apply_to_all(enc_tag_aux, SORT_tag);
2 7u83 472
 
473
    /* Check on output options */
6 7u83 474
    if (!show_tokdecs)tok_decs = 0;
475
    if (!show_tokdefs)tok_defs = 0;
476
    if (!show_aldefs)al_tag_defs = 0;
477
    if (!show_tagdecs)tag_decs = 0;
478
    if (!show_tagdefs)tag_defs = 0;
2 7u83 479
 
480
    /* Output equation types */
6 7u83 481
    eqn_total = 2;
482
    if (tok_decs)eqn_total++;
483
    if (tok_defs)eqn_total++;
484
    if (al_tag_defs)eqn_total++;
485
    if (tag_decs)eqn_total++;
486
    if (tag_defs)eqn_total++;
487
    while (n = (long)*(m++), n != 0) {
488
	enc_bits(p, 8, n);
2 7u83 489
    }
6 7u83 490
    enc_tdf_int(p, version_major);
491
    enc_tdf_int(p, version_minor);
492
    align_bitstream(p);
493
    enc_tdf_int(p, eqn_total);
494
    enc_aligned_string(p, LINK_tld_props,(long) -1);
495
    enc_aligned_string(p, LINK_version_props,(long) -1);
496
    if (tok_decs) {
497
	enc_aligned_string(p, LINK_tokdec_props,(long) -1);
2 7u83 498
    }
6 7u83 499
    if (tok_defs) {
500
	enc_aligned_string(p, LINK_tokdef_props,(long) -1);
2 7u83 501
    }
6 7u83 502
    if (al_tag_defs) {
503
	enc_aligned_string(p, LINK_al_tagdef_props,(long) -1);
2 7u83 504
    }
6 7u83 505
    if (tag_decs) {
506
	enc_aligned_string(p, LINK_tagdec_props,(long) -1);
2 7u83 507
    }
6 7u83 508
    if (tag_defs) {
509
	enc_aligned_string(p, LINK_tagdef_props,(long) -1);
2 7u83 510
    }
511
 
512
    /* Adjust totals for removed variables */
6 7u83 513
    tok_total += sort_removed[SORT_token];
514
    tag_total += sort_removed[SORT_tag];
515
    al_tag_total += sort_removed[SORT_al_tag];
516
    lab_total += sort_removed[SORT_label];
2 7u83 517
 
518
    /* Output variable sorts */
6 7u83 519
    var_total = 0;
520
    if (tok_total)var_total++;
521
    if (al_tag_total)var_total++;
522
    if (tag_total)var_total++;
523
    enc_tdf_int(p, var_total);
524
    if (tok_total) {
525
	enc_aligned_string(p, LINK_token,(long) -1);
526
	enc_tdf_int(p, tok_total);
2 7u83 527
    }
6 7u83 528
    if (al_tag_total) {
529
	enc_aligned_string(p, LINK_al_tag,(long) -1);
530
	enc_tdf_int(p, al_tag_total);
2 7u83 531
    }
6 7u83 532
    if (tag_total) {
533
	enc_aligned_string(p, LINK_tag,(long) -1);
534
	enc_tdf_int(p, tag_total);
2 7u83 535
    }
536
 
537
    /* Output external names */
6 7u83 538
    enc_tdf_int(p, var_total);
539
    crt_bitstream = p;
540
    if (tok_total) {
541
	enc_tdf_int(p, tok_external);
542
	apply_to_all(enc_token_names, SORT_token);
2 7u83 543
    }
6 7u83 544
    if (al_tag_total) {
545
	enc_tdf_int(p, al_tag_external);
546
	apply_to_all(enc_al_tag_names, SORT_al_tag);
2 7u83 547
    }
6 7u83 548
    if (tag_total) {
549
	enc_tdf_int(p, tag_external);
550
	apply_to_all(enc_tag_names, SORT_tag);
2 7u83 551
    }
552
 
553
    /* Output equations */
6 7u83 554
    enc_tdf_int(p, eqn_total);
555
    enc_equation(p,(long)1, tld_bs, EQN_TLD);
556
    vers_bs = new_bitstream();
557
    enc_version_bits(vers_bs, ENC_make_version);
558
    enc_tdf_int(vers_bs, version_major);
559
    enc_tdf_int(vers_bs, version_minor);
560
    enc_equation(p,(long)1, vers_bs, EQN_VERS);
561
    if (tok_decs)enc_equation(p, tok_decs, tok_decs_bs, EQN_TOKDEC);
562
    if (tok_defs)enc_equation(p, tok_defs, tok_defs_bs, EQN_TOKDEF);
563
    if (al_tag_defs) {
564
	enc_equation(p, al_tag_defs, al_tag_defs_bs, EQN_ALDEF);
2 7u83 565
    }
6 7u83 566
    if (tag_decs)enc_equation(p, tag_decs, tag_decs_bs, EQN_TAGDEC);
567
    if (tag_defs)enc_equation(p, tag_defs, tag_defs_bs, EQN_TAGDEF);
2 7u83 568
 
569
    /* Send bitstream to output file */
6 7u83 570
    print_bitstream(p);
571
    return;
2 7u83 572
}