/* * 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); }