Subversion Repositories tendra.SVN

Rev

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

Rev Author Line No. Line
6 7u83 1
/*
2
 * Copyright (c) 2002-2006 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
/*
32
    		 Crown Copyright (c) 1997
33
 
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:-
42
 
43
        (1) Its Recipients shall ensure that this Notice is
44
        reproduced upon any copies or amended versions of it;
45
 
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;
49
 
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;
53
 
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 "util.h"
63
#include "defs.h"
64
#include "streams.h"
65
#include "enc_nos.h"
66
#include "errors.h"
67
 
68
 
69
TDF *current_TDF;
70
 
71
static Chunk *free_chunks = (Chunk *)0;
72
 
73
 
74
Chunk *
75
create_chunk(void)
76
{
77
	Chunk *ans;
78
	if (free_chunks != (Chunk *)0) {
79
		ans = free_chunks;
80
		free_chunks = free_chunks->next;
81
	} else {
82
		ans = MALLOC(Chunk);
83
	}
84
	ans->next = (Chunk *)0;
85
	ans->usage = 0;
86
	ans->offst = 0;
87
	ans->aligned = 0;
88
	ans->data[0] = 0;
89
	return ans;
90
}
91
 
92
 
93
static void
94
free_chunk(Chunk *x)
95
{
96
	x->next = free_chunks;
97
	free_chunks = x;
98
}
99
 
100
 
101
void
102
out_basic_int(unsigned long num, unsigned int bts)
103
    /* outputs num onto current stream in bts bits */
104
{
105
	Chunk *t_ch = current_TDF->last;
106
	unsigned disp = t_ch->offst;
107
	unsigned space = 8 - disp;
108
	for (;bts >= space; bts -= space, space = 8, disp = 0) {
109
		(t_ch->data)[t_ch->usage] |= UC((num >> (bts-space)) & 255);
110
		t_ch->usage += 1;
111
		t_ch->offst = 0;
112
		if (t_ch->usage == DATA_SIZE) {
113
			Chunk *nch = create_chunk();
114
			t_ch->next = nch;
115
			current_TDF->last = nch;
116
			t_ch = nch;
117
		} else {
118
			(t_ch->data)[t_ch->usage] = 0;
119
		}
120
	}
121
	if (bts) {
122
		unsigned garbage=8-bts;
123
		(t_ch->data)[t_ch->usage] |=
124
		    UC(((num << garbage) & 255) >> disp);
125
		t_ch->offst+=UC(bts);
126
	}
127
}
128
 
129
 
130
void
131
append_TDF(TDF *tdf, Bool free_it)
132
    /* appends the stream tdf onto current stream;
133
       if free_it, chunks in tdf will be reused */
134
{
135
	Chunk *t_ch = current_TDF->last;
136
	Chunk *a_ch = tdf->first;
137
 
138
	if (t_ch->usage < DATA_SIZE - 1 - a_ch->usage) {
139
		/* room to put it in current chunk */
140
		int i;
141
		int offst = a_ch->offst;
142
		Chunk *nextch = a_ch->next;
143
		for (i = 0; i < a_ch->usage; i++) {
144
			out_basic_int(UL(a_ch->data[i]), UI(8));
145
		}
146
		if (a_ch->offst != 0) {
147
			out_basic_int(UL(a_ch->data[i]) >> (8-offst),
148
				      UI(offst));
149
		}
150
		if (free_it) {
151
			free_chunk(a_ch);
152
		}
153
		a_ch = nextch;
154
	}
155
	if (a_ch != (Chunk *)0) {
156
		if (free_it) {	/* use existing chunks */
157
			t_ch->next = a_ch;
158
			current_TDF->last = tdf->last;
159
		} else {  /* copy chunks */
160
			while (a_ch != (Chunk *)0) {
161
				Chunk *nch = create_chunk();
162
				t_ch->next = nch;
163
				t_ch = current_TDF->last = nch;
164
				*nch = *a_ch;
165
				a_ch = a_ch->next;
166
			}
167
		}
168
	}
169
	SET_RSORT(tdf->sort);
170
	if (free_it) {
171
		tdf->first = tdf->last = (Chunk *)0; /* Don't use it again! */
172
	}
173
	return;
174
}
175
 
176
 
177
unsigned long
178
bits_in_TDF(TDF * tdf)
179
{
180
	Chunk *t_ch = tdf->first;
181
	unsigned long ans = 0;
182
	while (t_ch != (Chunk *)0) {
183
		Assert(!t_ch->aligned);
184
		ans+= (UL(t_ch->usage) << 3) + UL(t_ch->offst);
185
		t_ch = t_ch->next;
186
	}
187
	return ans;
188
}
189
 
190
 
191
void
192
out_extendable_int(unsigned long num, unsigned int bts)
193
{
194
	if (num < (UL(1) << bts)) {
195
		out_basic_int(num,bts);
196
	} else {
197
		out_basic_int(UL(0), bts);
198
		out_extendable_int(num- (UL(1) << bts) + 1, bts);
199
	}
200
}
201
 
202
 
203
void
204
out_tdfint32(unsigned long n)
205
    /* output 32 bit int as tdfint */
206
{
207
	int sh;
208
	Bool sig = 0;
209
	for (sh = 30; sh > 0; sh -= 3) {
210
		unsigned long i = (n >> sh) & 7;
211
		if (sig || i != 0) {
212
			out_basic_int(i, UI(4));
213
			sig = 1;
214
		}
215
	}
216
	out_basic_int((n & 7) + 8, 4);
217
	SET_RSORT(s_tdfint);
218
}
219
 
220
 
221
void
222
out_tdfbool(Bool b)
223
{
224
	out_basic_int(UL(b), UI(1));
225
	SET_RSORT(s_tdfbool);
226
}
227
 
228
 
229
void
230
out_tdfstring_bytes(char *s, unsigned int k, unsigned int n)
231
{
232
	unsigned int i;
233
	out_tdfint32(UL(k));
234
	out_tdfint32(UL(n));
235
	for (i = 0; i < n; i++) {
236
		out_basic_int(UL(s[i]), k);
237
	}
238
	SET_RSORT(s_tdfstring);
239
}
240
 
241
 
242
void
243
byte_align(void)
244
{
245
	Chunk *ch = current_TDF->last;
246
	if (ch->aligned != 0) {
247
		if (ch->offst != 0) {
248
			out_basic_int(UL(0), UI(8-ch->offst));
249
		}
250
		Assert(ch->offst == 0);
251
	} else {
252
		Chunk *nch = create_chunk();
253
		nch->aligned = 1;
254
		ch->next = nch;
255
		current_TDF->last = nch;
256
	}
257
}
258
 
259
 
260
void
261
out_tdfident_bytes(char *s)
262
{
263
	unsigned long i;
264
	unsigned long n = (unsigned long)strlen(s);
265
	byte_align();
266
	out_tdfint32(UL(8));
267
	out_tdfint32(n);
268
	byte_align();
269
	for (i = 0; i < n; i++) {
270
		out_basic_int(UL(s[i]), UI(8));
271
	}
272
	SET_RSORT(s_tdfident);
273
}
274
 
275
 
276
void
277
append_bytestream(TDF *tdf, Bool free_it)
278
{
279
	unsigned long len = bits_in_TDF(tdf);
280
	unsigned long lenb = (len + 7) >> 3;
281
	out_tdfint32(lenb);
282
	byte_align();
283
	append_TDF(tdf, free_it);
284
	if ((lenb << 3) != len) {
285
		out_basic_int(UL(0), UI((lenb << 3) - len));
286
	}
287
	SET_RSORT(s_bytestream);
288
}