/*
* Copyright (c) 2002, The Tendra Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice unmodified, this list of conditions, and the following
* disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
* Crown Copyright (c) 1997
*
* This TenDRA(r) Computer Program is subject to Copyright
* owned by the United Kingdom Secretary of State for Defence
* acting through the Defence Evaluation and Research Agency
* (DERA). It is made available to Recipients with a
* royalty-free licence for its use, reproduction, transfer
* to other parties and amendment for any purpose not excluding
* product development provided that any such use et cetera
* shall be deemed to be acceptance of the following conditions:-
*
* (1) Its Recipients shall ensure that this Notice is
* reproduced upon any copies or amended versions of it;
*
* (2) Any amended version of it shall be clearly marked to
* show both the nature of and the organisation responsible
* for the relevant amendment or amendments;
*
* (3) Its onward transfer from a recipient to another
* party shall be deemed to be that party's acceptance of
* these conditions;
*
* (4) DERA gives no warranty or assurance as to its
* quality or suitability for any purpose and DERA accepts
* no liability whatsoever in relation to any use to which
* it may be put.
*
* $TenDRA: tendra/src/tools/pl/streams.c,v 1.7 2005/09/18 20:28:57 stefanf Exp $
*/
#include "config.h"
#include "defs.h"
#include "fmm.h"
#include "msgcat.h"
#include "streams.h"
#include "enc_nos.h"
#include "errors.h"
TDF * current_TDF;
static Chunk * free_chunks = (Chunk*)0;
Chunk *
create_chunk(void)
{
Chunk * ans;
if (free_chunks != (Chunk*)0) {
ans = free_chunks;
free_chunks = free_chunks->next;
} else {
ans = xalloc(sizeof(*ans));
}
ans->next = (Chunk*)0;
ans->usage = 0;
ans->offst = 0; ans->aligned = 0;
ans->data[0] = 0;
return ans;
}
static void
free_chunk(Chunk * x)
{
x->next = free_chunks;
free_chunks = x;
}
void
out_basic_int(unsigned long num, unsigned int bts)
/* outputs num onto current stream in bts bits */
{
Chunk * t_ch = current_TDF->last;
unsigned disp = t_ch->offst;
unsigned space = 8 - disp;
for (;bts>=space;bts-=space,space=8,disp=0){
(t_ch->data)[t_ch->usage]|=UC((num>>(bts-space))&255);
t_ch->usage+=1;t_ch->offst=0;
if (t_ch->usage == DATA_SIZE) {
Chunk * nch = create_chunk();
t_ch->next = nch;
current_TDF->last = nch;
t_ch = nch;
}
else (t_ch->data)[t_ch->usage] = 0;
}
if (bts){
unsigned garbage=8-bts;
(t_ch->data)[t_ch->usage]|=UC(((num<>disp);
t_ch->offst+=UC(bts);
}
}
void
append_TDF(TDF * tdf, Bool free_it) /* appends the stream tdf onto current stream; if free_it, chunks in tdf will be reused */
{
Chunk * t_ch = current_TDF->last;
Chunk * a_ch = tdf->first;
if (t_ch->usage < DATA_SIZE -1 - a_ch->usage) {
/* room to put it in current chunk */
int i;
int offst = a_ch->offst;
Chunk * nextch = a_ch->next;
for (i=0; iusage; i++) {
out_basic_int(UL(a_ch->data[i]),UI(8));
}
if (a_ch ->offst != 0) {
out_basic_int(UL(a_ch->data[i])>>(8-offst), UI(offst));
}
if (free_it) free_chunk(a_ch);
a_ch = nextch;
}
if (a_ch != (Chunk*)0) {
if (free_it) { /* use existing chunks */
t_ch->next = a_ch;
current_TDF->last = tdf->last;
} else { /* copy chunks */
while (a_ch != (Chunk*)0) {
Chunk *nch = create_chunk();
t_ch->next = nch;
t_ch = current_TDF->last = nch;
*nch = *a_ch;
a_ch = a_ch->next;
}
}
}
SET_RSORT(tdf->sort);
if (free_it) {
tdf->first = tdf->last = (Chunk*)0; /* Don't use it again! */
}
return;
}
unsigned long
bits_in_TDF(TDF * tdf)
{
Chunk * t_ch = tdf->first;
unsigned long ans = 0;
while (t_ch != (Chunk*)0) {
Assert(!t_ch->aligned);
ans+= (UL(t_ch->usage)<<3) + UL(t_ch->offst);
t_ch = t_ch->next;
}
return ans;
}
void
out_extendable_int(unsigned long num, unsigned int bts)
{
if (num < (UL(1)<0; sh-=3) {
unsigned long i = (n>>sh)&7;
if (sig || i!=0) {
out_basic_int(i, UI(4));
sig = 1;
}
}
out_basic_int((n &7)+8, 4);
SET_RSORT(s_tdfint);
}
void
out_tdfbool(Bool b)
{
out_basic_int(UL(b), UI(1));
SET_RSORT(s_tdfbool);
}
void
out_tdfstring_bytes(char *s, unsigned int k, unsigned int n)
{
unsigned int i;
out_tdfint32(UL(k));
out_tdfint32(UL(n));
for (i=0; ilast;
if (ch->aligned !=0) {
if (ch->offst !=0) out_basic_int(UL(0), UI(8-ch->offst));
Assert(ch->offst == 0);
} else {
Chunk * nch = create_chunk();
nch->aligned = 1;
ch->next = nch;
current_TDF->last = nch;
}
}
void
out_tdfident_bytes(char *s)
{
unsigned long i;
unsigned long n = (unsigned long) strlen(s);
byte_align();
out_tdfint32(UL(8));
out_tdfint32(n);
byte_align();
for (i=0; i>3;
out_tdfint32(lenb);
byte_align();
append_TDF(tdf, free_it);
if ((lenb<<3) != len) {
out_basic_int(UL(0), UI((lenb<<3)-len));
}
SET_RSORT(s_bytestream);
}