Initial import of the CDE 2.1.30 sources from the Open Group.
This commit is contained in:
6
cde/programs/dtksh/ksh93/src/lib/libvdelta/Makefile
Normal file
6
cde/programs/dtksh/ksh93/src/lib/libvdelta/Makefile
Normal file
@@ -0,0 +1,6 @@
|
||||
/* $XConsortium: Makefile /main/2 1996/05/10 17:21:11 drk $ */
|
||||
:PACKAGE: ast
|
||||
|
||||
vdelta 1.0 :LIBRARY: vdelta.3 vdelhdr.h vdelta.h vddelta.c vdio.c vdupdate.c
|
||||
|
||||
$(INCLUDEDIR) :INSTALLDIR: vdelta.h
|
||||
153
cde/programs/dtksh/ksh93/src/lib/libvdelta/Mamfile
Normal file
153
cde/programs/dtksh/ksh93/src/lib/libvdelta/Mamfile
Normal file
@@ -0,0 +1,153 @@
|
||||
note : : make abstract machine file generated from Makefile : : note
|
||||
info mam static 00000 07/17/94 make (AT&T Bell Laboratories) 3.2 research 07/17/95
|
||||
setv INSTALLROOT ../../..
|
||||
setv PACKAGE_ast ${INSTALLROOT}
|
||||
setv PACKAGE_ast_INCLUDE ${PACKAGE_ast}/include
|
||||
setv PACKAGE_ast_LIB ${PACKAGE_ast}/lib
|
||||
setv AR ar
|
||||
setv ARFLAGS cr
|
||||
setv AS as
|
||||
setv ASFLAGS
|
||||
setv CC cc
|
||||
setv CCFLAGS "-O"
|
||||
setv COTEMP $$
|
||||
setv CPIO cpio
|
||||
setv CPIOFLAGS
|
||||
setv CPP "${CC} -E"
|
||||
setv F77 f77
|
||||
setv HOSTCC ${CC}
|
||||
setv IGNORE
|
||||
setv LD ld
|
||||
setv LDFLAGS
|
||||
setv LEX lex
|
||||
setv LEXFLAGS
|
||||
setv LPR lpr
|
||||
setv LPRFLAGS
|
||||
setv M4FLAGS
|
||||
setv MAKE nmake
|
||||
setv MAKEFLAGS
|
||||
setv PR pr
|
||||
setv PRFLAGS
|
||||
setv SHELL /bin/sh
|
||||
setv SILENT
|
||||
setv TAR tar
|
||||
setv YACC yacc
|
||||
setv YACCFLAGS -d
|
||||
make install
|
||||
make all
|
||||
make vdelta
|
||||
make libvdelta.a archive
|
||||
make vddelta.o
|
||||
make vddelta.c
|
||||
make vdelhdr.h implicit
|
||||
done vdelhdr.h
|
||||
done vddelta.c
|
||||
prev vddelta.c
|
||||
exec - ${CC} ${CCFLAGS} -I. -I${INSTALLROOT}/include/ast -D_PACKAGE_ast -c vddelta.c
|
||||
done vddelta.o generated
|
||||
make vdio.o
|
||||
make vdio.c
|
||||
prev vdelhdr.h implicit
|
||||
done vdio.c
|
||||
prev vdio.c
|
||||
exec - ${CC} ${CCFLAGS} -I. -I${INSTALLROOT}/include/ast -D_PACKAGE_ast -c vdio.c
|
||||
done vdio.o generated
|
||||
make vdupdate.o
|
||||
make vdupdate.c
|
||||
prev vdelhdr.h implicit
|
||||
done vdupdate.c
|
||||
prev vdupdate.c
|
||||
exec - ${CC} ${CCFLAGS} -I. -I${INSTALLROOT}/include/ast -D_PACKAGE_ast -c vdupdate.c
|
||||
done vdupdate.o generated
|
||||
exec - ${AR} cr libvdelta.a vddelta.o vdio.o vdupdate.o
|
||||
exec - (ranlib libvdelta.a) >/dev/null 2>&1 || true
|
||||
done libvdelta.a generated
|
||||
done vdelta virtual
|
||||
prev libvdelta.a archive
|
||||
done all virtual
|
||||
make ${INSTALLROOT}/lib
|
||||
exec - set -
|
||||
exec - if test ! -d ${INSTALLROOT}/lib
|
||||
exec - then set -x && mkdir -p ${INSTALLROOT}/lib 2>/dev/null && set - ||
|
||||
exec - {
|
||||
exec - test -d ./-p && rm -rf ./-p
|
||||
exec - p=
|
||||
exec - for d in `echo ${INSTALLROOT}/lib | sed -e 's%\\(.\\)/%\\1 %g'`
|
||||
exec - do case $p in
|
||||
exec - "") p=$d ;;
|
||||
exec - *) p=$p/$d ;;
|
||||
exec - esac
|
||||
exec - case $d in
|
||||
exec - .|..) ;;
|
||||
exec - *) if test ! -d $p
|
||||
exec - then rm -f $p
|
||||
exec - set -x && mkdir $p && set -
|
||||
exec - fi
|
||||
exec - ;;
|
||||
exec - esac
|
||||
exec - done
|
||||
exec - } && set -x
|
||||
exec - fi
|
||||
done ${INSTALLROOT}/lib generated
|
||||
make ${INSTALLROOT}/lib/libvdelta.a archive
|
||||
prev libvdelta.a archive
|
||||
exec - { mv ${INSTALLROOT}/lib/libvdelta.a ${INSTALLROOT}/lib/libvdelta.a.old 2>/dev/null; cp libvdelta.a ${INSTALLROOT}/lib/libvdelta.a 2>/dev/null ;} || true
|
||||
exec - (ranlib ${INSTALLROOT}/lib/libvdelta.a) >/dev/null 2>&1 || true
|
||||
done ${INSTALLROOT}/lib/libvdelta.a generated
|
||||
make ${INSTALLROOT}/man/man3
|
||||
exec - set -
|
||||
exec - if test ! -d ${INSTALLROOT}/man/man3
|
||||
exec - then set -x && mkdir -p ${INSTALLROOT}/man/man3 2>/dev/null && set - ||
|
||||
exec - {
|
||||
exec - test -d ./-p && rm -rf ./-p
|
||||
exec - p=
|
||||
exec - for d in `echo ${INSTALLROOT}/man/man3 | sed -e 's%\\(.\\)/%\\1 %g'`
|
||||
exec - do case $p in
|
||||
exec - "") p=$d ;;
|
||||
exec - *) p=$p/$d ;;
|
||||
exec - esac
|
||||
exec - case $d in
|
||||
exec - .|..) ;;
|
||||
exec - *) if test ! -d $p
|
||||
exec - then rm -f $p
|
||||
exec - set -x && mkdir $p && set -
|
||||
exec - fi
|
||||
exec - ;;
|
||||
exec - esac
|
||||
exec - done
|
||||
exec - } && set -x
|
||||
exec - fi
|
||||
done ${INSTALLROOT}/man/man3 generated
|
||||
make ${INSTALLROOT}/man/man3/vdelta.3
|
||||
make vdelta.3
|
||||
done vdelta.3
|
||||
exec - { mv ${INSTALLROOT}/man/man3/vdelta.3 ${INSTALLROOT}/man/man3/vdelta.3.old 2>/dev/null; cp vdelta.3 ${INSTALLROOT}/man/man3/vdelta.3 2>/dev/null ;} || true
|
||||
done ${INSTALLROOT}/man/man3/vdelta.3 generated
|
||||
make ${INSTALLROOT}/include/ast
|
||||
exec - set -
|
||||
exec - if test ! -d ${INSTALLROOT}/include/ast
|
||||
exec - then set -x && mkdir -p ${INSTALLROOT}/include/ast 2>/dev/null && set - ||
|
||||
exec - {
|
||||
exec - test -d ./-p && rm -rf ./-p
|
||||
exec - p=
|
||||
exec - for d in `echo ${INSTALLROOT}/include/ast | sed -e 's%\\(.\\)/%\\1 %g'`
|
||||
exec - do case $p in
|
||||
exec - "") p=$d ;;
|
||||
exec - *) p=$p/$d ;;
|
||||
exec - esac
|
||||
exec - case $d in
|
||||
exec - .|..) ;;
|
||||
exec - *) if test ! -d $p
|
||||
exec - then rm -f $p
|
||||
exec - set -x && mkdir $p && set -
|
||||
exec - fi
|
||||
exec - ;;
|
||||
exec - esac
|
||||
exec - done
|
||||
exec - } && set -x
|
||||
exec - fi
|
||||
done ${INSTALLROOT}/include/ast generated
|
||||
make ${INSTALLROOT}/include/ast/vdelta.h
|
||||
exec - { mv ${INSTALLROOT}/include/ast/vdelta.h ${INSTALLROOT}/include/ast/vdelta.h.old 2>/dev/null; cp vdelta.h ${INSTALLROOT}/include/ast/vdelta.h 2>/dev/null ;} || true
|
||||
done ${INSTALLROOT}/include/ast/vdelta.h generated
|
||||
done install virtual
|
||||
496
cde/programs/dtksh/ksh93/src/lib/libvdelta/vddelta.c
Normal file
496
cde/programs/dtksh/ksh93/src/lib/libvdelta/vddelta.c
Normal file
@@ -0,0 +1,496 @@
|
||||
/* $XConsortium: vddelta.c /main/2 1996/05/08 20:06:58 drk $ */
|
||||
/***************************************************************
|
||||
* *
|
||||
* AT&T - PROPRIETARY *
|
||||
* *
|
||||
* THIS IS PROPRIETARY SOURCE CODE LICENSED BY *
|
||||
* AT&T CORP. *
|
||||
* *
|
||||
* Copyright (c) 1995 AT&T Corp. *
|
||||
* All Rights Reserved *
|
||||
* *
|
||||
* This software is licensed by AT&T Corp. *
|
||||
* under the terms and conditions of the license in *
|
||||
* http://www.research.att.com/orgs/ssr/book/reuse *
|
||||
* *
|
||||
* This software was created by the *
|
||||
* Software Engineering Research Department *
|
||||
* AT&T Bell Laboratories *
|
||||
* *
|
||||
* For further information contact *
|
||||
* gsf@research.att.com *
|
||||
* *
|
||||
***************************************************************/
|
||||
#include "vdelhdr.h"
|
||||
|
||||
/* Compute a transformation that takes source data to target data
|
||||
**
|
||||
** Written by (Kiem-)Phong Vo, kpv@research.att.com, 5/20/94
|
||||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
long S_copy, S_add; /* amount of input covered by COPY and ADD */
|
||||
long N_copy, N_add; /* # of COPY and ADD instructions */
|
||||
long M_copy, M_add; /* max size of a COPY or ADD instruction */
|
||||
long N_merge; /* # of merged instructions */
|
||||
#endif
|
||||
|
||||
#define MERGABLE(a,c,k) ((a) > 0 && A_ISTINY(a) && \
|
||||
(c) > 0 && C_ISTINY(c) && \
|
||||
(k) >= K_SELF )
|
||||
|
||||
typedef struct _match_s Match_t;
|
||||
typedef struct _table_s Table_t;
|
||||
struct _match_s
|
||||
{ Match_t* next; /* linked list ptr */
|
||||
};
|
||||
struct _table_s
|
||||
{ Vdio_t io; /* io structure */
|
||||
uchar* src; /* source string */
|
||||
int n_src;
|
||||
uchar* tar; /* target string */
|
||||
int n_tar;
|
||||
K_DDECL(quick,recent,rhere); /* address caches */
|
||||
Match_t* base; /* base of elements */
|
||||
int size; /* size of hash table */
|
||||
Match_t** table; /* hash table */
|
||||
};
|
||||
|
||||
/* encode and output delta instructions */
|
||||
#if __STD_C
|
||||
static vdputinst(Table_t* tab, uchar* begs, uchar* here, Match_t* match, int n_copy)
|
||||
#else
|
||||
static vdputinst(tab, begs, here, match, n_copy)
|
||||
Table_t* tab;
|
||||
uchar* begs; /* ADD data if any */
|
||||
uchar* here; /* current location */
|
||||
Match_t* match; /* best match if any */
|
||||
int n_copy; /* length of match */
|
||||
#endif
|
||||
{
|
||||
reg int n_add, i_add, i_copy, k_type;
|
||||
reg int n, c_addr, copy, best, d;
|
||||
|
||||
n_add = begs ? here-begs : 0; /* add size */
|
||||
c_addr = (here-tab->tar)+tab->n_src; /* current address */
|
||||
k_type = 0;
|
||||
|
||||
if(match) /* process the COPY instruction */
|
||||
{ /**/DBTOTAL(N_copy,1); DBTOTAL(S_copy,n_copy); DBMAX(M_copy,n_copy);
|
||||
|
||||
best = copy = match - tab->base;
|
||||
k_type = K_SELF;
|
||||
if((d = c_addr - copy) < best)
|
||||
{ best = d;
|
||||
k_type = K_HERE;
|
||||
}
|
||||
for(n = 0; n < K_RTYPE; ++n)
|
||||
{ if((d = copy - tab->recent[n]) < 0 || d >= best)
|
||||
continue;
|
||||
best = d;
|
||||
k_type = K_RECENT+n;
|
||||
}
|
||||
if(best >= I_MORE && tab->quick[n = copy%K_QSIZE] == copy)
|
||||
{ for(d = K_QTYPE-1; d > 0; --d)
|
||||
if(n >= (d<<VD_BITS) )
|
||||
break;
|
||||
best = n - (d<<VD_BITS); /**/ASSERT(best < (1<<VD_BITS));
|
||||
k_type = K_QUICK+d;
|
||||
}
|
||||
|
||||
/**/ASSERT(best >= 0);
|
||||
/**/ASSERT((k_type+K_MERGE) < (1<<I_BITS) );
|
||||
|
||||
/* update address caches */
|
||||
K_UPDATE(tab->quick,tab->recent,tab->rhere,copy);
|
||||
|
||||
/* see if mergable to last ADD instruction */
|
||||
if(MERGABLE(n_add,n_copy,k_type) )
|
||||
{ /**/DBTOTAL(N_merge,1);
|
||||
i_add = K_TPUT(k_type)|A_TPUT(n_add)|C_TPUT(n_copy);
|
||||
}
|
||||
else
|
||||
{ i_copy = K_PUT(k_type);
|
||||
if(C_ISLOCAL(n_copy) )
|
||||
i_copy |= C_LPUT(n_copy);
|
||||
}
|
||||
}
|
||||
|
||||
if(n_add > 0)
|
||||
{ /**/DBTOTAL(N_add,1); DBTOTAL(S_add,n_add); DBMAX(M_add,n_add);
|
||||
|
||||
if(!MERGABLE(n_add,n_copy,k_type) )
|
||||
i_add = A_ISLOCAL(n_add) ? A_LPUT(n_add) : 0;
|
||||
|
||||
if(VDPUTC((Vdio_t*)tab,i_add) < 0 )
|
||||
return -1;
|
||||
if(!A_ISLOCAL(n_add) &&
|
||||
(*_Vdputu)((Vdio_t*)tab, (ulong)A_PUT(n_add)) < 0 )
|
||||
return -1;
|
||||
if((*_Vdwrite)((Vdio_t*)tab, begs, n_add) < 0 )
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(n_copy > 0)
|
||||
{ if(!MERGABLE(n_add,n_copy,k_type) && VDPUTC((Vdio_t*)tab,i_copy) < 0 )
|
||||
return -1;
|
||||
|
||||
if(!C_ISLOCAL(n_copy) &&
|
||||
(*_Vdputu)((Vdio_t*)tab, (ulong)C_PUT(n_copy)) < 0 )
|
||||
return -1;
|
||||
|
||||
if(k_type >= K_QUICK && k_type < (K_QUICK+K_QTYPE) )
|
||||
{ if(VDPUTC((Vdio_t*)tab,(uchar)best) < 0 )
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{ if((*_Vdputu)((Vdio_t*)tab, (ulong)best) < 0 )
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ if((*_Vdflsbuf)((Vdio_t*)tab) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Fold a string */
|
||||
#if __STD_C
|
||||
static vdfold(Table_t* tab, int output)
|
||||
#else
|
||||
static vdfold(tab, output)
|
||||
Table_t* tab;
|
||||
int output;
|
||||
#endif
|
||||
{
|
||||
reg ulong key, n;
|
||||
reg uchar *s, *sm, *ends, *ss, *heade;
|
||||
reg Match_t *m, *list, *curm, *bestm;
|
||||
reg uchar *add, *endfold;
|
||||
reg int head, len, n_src = tab->n_src;
|
||||
reg int size = tab->size;
|
||||
reg uchar *src = tab->src, *tar = tab->tar;
|
||||
reg Match_t *base = tab->base, **table = tab->table;
|
||||
|
||||
if(!output)
|
||||
{ if(tab->n_src < M_MIN)
|
||||
return 0;
|
||||
endfold = (s = src) + tab->n_src;
|
||||
curm = base;
|
||||
}
|
||||
else
|
||||
{ endfold = (s = tar) + tab->n_tar;
|
||||
curm = base+n_src;
|
||||
if(tab->n_tar < M_MIN)
|
||||
return vdputinst(tab,s,endfold,NIL(Match_t*),0);
|
||||
}
|
||||
|
||||
add = NIL(uchar*);
|
||||
bestm = NIL(Match_t*);
|
||||
len = M_MIN-1;
|
||||
HINIT(key,s,n);
|
||||
for(;;)
|
||||
{ for(;;) /* search for the longest match */
|
||||
{ if(!(m = table[key&size]) )
|
||||
goto endsearch;
|
||||
list = m = m->next; /* head of list */
|
||||
|
||||
if(bestm) /* skip over past elements */
|
||||
{ for(;;)
|
||||
{ if(m >= bestm+len)
|
||||
break;
|
||||
if((m = m->next) == list)
|
||||
goto endsearch;
|
||||
}
|
||||
}
|
||||
|
||||
head = len - (M_MIN-1); /* header before the match */
|
||||
heade = s+head;
|
||||
for(;;)
|
||||
{ if((n = m-base) < n_src)
|
||||
{ if(n < head)
|
||||
goto next;
|
||||
sm = src + n;
|
||||
}
|
||||
else
|
||||
{ if((n -= n_src) < head)
|
||||
goto next;
|
||||
sm = tar + n;
|
||||
}
|
||||
|
||||
/* make sure that the M_MIN bytes match */
|
||||
if(!EQUAL(heade,sm))
|
||||
goto next;
|
||||
|
||||
/* make sure this is a real match */
|
||||
for(sm -= head, ss = s; ss < heade; )
|
||||
if(*sm++ != *ss++)
|
||||
goto next;
|
||||
ss += M_MIN;
|
||||
sm += M_MIN;
|
||||
ends = endfold;
|
||||
if((m-base) < n_src && (n = (src+n_src)-sm) < (ends-s) )
|
||||
ends = s+n;
|
||||
for(; ss < ends; ++ss, ++sm)
|
||||
if(*sm != *ss)
|
||||
goto extend;
|
||||
goto extend;
|
||||
|
||||
next: if((m = m->next) == list )
|
||||
goto endsearch;
|
||||
}
|
||||
|
||||
extend: bestm = m-head;
|
||||
n = len;
|
||||
len = ss-s;
|
||||
if(ss >= endfold) /* already match everything */
|
||||
goto endsearch;
|
||||
|
||||
/* check for a longer match */
|
||||
ss -= M_MIN-1;
|
||||
if(len == n+1)
|
||||
HNEXT(key,ss,n);
|
||||
else HINIT(key,ss,n);
|
||||
}
|
||||
|
||||
endsearch:
|
||||
if(bestm)
|
||||
{ if(output && vdputinst(tab,add,s,bestm,len) < 0)
|
||||
return -1;
|
||||
|
||||
/* add a sufficient number of suffices */
|
||||
ends = (s += len);
|
||||
ss = ends - (M_MIN-1);
|
||||
if(!output)
|
||||
curm = base + (ss-src);
|
||||
else curm = base + n_src + (ss-tar);
|
||||
|
||||
len = M_MIN-1;
|
||||
add = NIL(uchar*);
|
||||
bestm = NIL(Match_t*);
|
||||
}
|
||||
else
|
||||
{ if(!add)
|
||||
add = s;
|
||||
ss = s;
|
||||
ends = (s += 1); /* add one prefix */
|
||||
}
|
||||
|
||||
if(ends > (endfold - (M_MIN-1)) )
|
||||
ends = endfold - (M_MIN-1);
|
||||
|
||||
if(ss < ends) for(;;) /* add prefices/suffices */
|
||||
{ n = key&size;
|
||||
if(!(m = table[n]) )
|
||||
curm->next = curm;
|
||||
else
|
||||
{ curm->next = m->next;
|
||||
m->next = curm;
|
||||
}
|
||||
table[n] = curm++;
|
||||
|
||||
if((ss += 1) >= ends)
|
||||
break;
|
||||
HNEXT(key,ss,n);
|
||||
}
|
||||
|
||||
if(s > endfold-M_MIN) /* too short to match */
|
||||
{ if(!add)
|
||||
add = s;
|
||||
break;
|
||||
}
|
||||
|
||||
HNEXT(key,s,n);
|
||||
}
|
||||
|
||||
if(output) /* flush output */
|
||||
return vdputinst(tab,add,endfold,NIL(Match_t*),0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#if __STD_C
|
||||
long vddelta(Vddisc_t* source, Vddisc_t* target, Vddisc_t* delta, long window)
|
||||
#else
|
||||
long vddelta(source, target, delta, window)
|
||||
Vddisc_t* source; /* source data */
|
||||
Vddisc_t* target; /* target data */
|
||||
Vddisc_t* delta; /* transform output data */
|
||||
long window; /* amount to process each time */
|
||||
#endif
|
||||
{
|
||||
reg int size, k, n;
|
||||
reg long p, n_src, n_tar;
|
||||
Table_t tab;
|
||||
|
||||
if(!target || (n_tar = target->size) < 0)
|
||||
return -1;
|
||||
if(n_tar > 0 && !target->data && !target->readf)
|
||||
return -1;
|
||||
|
||||
if((n_src = source ? source->size : 0) < 0)
|
||||
n_src = 0;
|
||||
if(n_src > 0 && !source->data && !source->readf)
|
||||
return -1;
|
||||
|
||||
if(!delta || (!delta->data && !delta->writef) )
|
||||
return -1;
|
||||
|
||||
tab.n_src = tab.n_tar = tab.size = 0;
|
||||
tab.tar = tab.src = NIL(uchar*);
|
||||
tab.base = NIL(Match_t*);
|
||||
tab.table = NIL(Match_t**);
|
||||
INIT(&tab.io,delta);
|
||||
|
||||
if(window <= 0)
|
||||
window = DFLTWINDOW;
|
||||
else if(window > MAXWINDOW)
|
||||
window = MAXWINDOW;
|
||||
if(window > n_tar)
|
||||
window = n_tar;
|
||||
if(n_src > 0 && window > n_src)
|
||||
window = n_src;
|
||||
|
||||
/* try to allocate working space */
|
||||
while(window > 0)
|
||||
{ /* space for the target string */
|
||||
size = (n_tar == 0 || target->data) ? 0 : (int)window;
|
||||
if((long)size > n_tar)
|
||||
size = (int)n_tar;
|
||||
if(size > 0 && !(tab.tar = (uchar*)malloc(size*sizeof(uchar))) )
|
||||
goto reduce_window;
|
||||
|
||||
/* space for sliding header or source string */
|
||||
if(n_src <= 0) /* compression only */
|
||||
size = target->data ? 0 : HEADER(window);
|
||||
else /* differencing */
|
||||
{ size = source->data ? 0 : window;
|
||||
if((long)size > n_src)
|
||||
size = (int)n_src;
|
||||
}
|
||||
if(size > 0 && !(tab.src = (uchar*)malloc(size*sizeof(uchar))) )
|
||||
goto reduce_window;
|
||||
|
||||
/* space for the hash table elements */
|
||||
size = (int)(window < n_tar ? window : n_tar);
|
||||
if(n_src <= 0)
|
||||
size += (int)(window < n_tar ? HEADER(window) : 0);
|
||||
else size += (int)(window < n_src ? window : n_src);
|
||||
if(!(tab.base = (Match_t*)malloc(size*sizeof(Match_t))) )
|
||||
goto reduce_window;
|
||||
|
||||
/* space for the hash table */
|
||||
n = size/2;
|
||||
do (size = n); while((n &= n-1) != 0);
|
||||
if(size < 64)
|
||||
size = 64;
|
||||
while(!(tab.table = (Match_t**)malloc(size*sizeof(Match_t*))) )
|
||||
if((size >>= 1) <= 0)
|
||||
goto reduce_window;
|
||||
|
||||
/* if get here, successful */
|
||||
tab.size = size-1;
|
||||
break;
|
||||
|
||||
reduce_window:
|
||||
if(tab.tar)
|
||||
{ free((Void_t*)tab.tar);
|
||||
tab.tar = NIL(uchar*);
|
||||
}
|
||||
if(tab.src)
|
||||
{ free((Void_t*)tab.src);
|
||||
tab.src = NIL(uchar*);
|
||||
}
|
||||
if(tab.base)
|
||||
{ free((Void_t*)tab.base);
|
||||
tab.base = NIL(Match_t*);
|
||||
}
|
||||
if((window >>= 1) <= 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* amount processed */
|
||||
n = 0;
|
||||
|
||||
/* output magic bytes and sizes */
|
||||
for(k = 0; VD_MAGIC[k]; k++)
|
||||
;
|
||||
if((*_Vdwrite)(&tab.io,(uchar*)VD_MAGIC,k) != k ||
|
||||
(*_Vdputu)(&tab.io,(ulong)n_tar) <= 0 ||
|
||||
(*_Vdputu)(&tab.io,(ulong)n_src) <= 0 ||
|
||||
(*_Vdputu)(&tab.io,(ulong)window) <= 0 )
|
||||
goto done;
|
||||
|
||||
/* do one window at a time */
|
||||
while(n < n_tar)
|
||||
{ /* prepare the source string */
|
||||
if(n_src <= 0) /* data compression */
|
||||
{ if(n <= 0)
|
||||
tab.n_src = 0;
|
||||
else
|
||||
{ size = (int)HEADER(window);
|
||||
if(target->data)
|
||||
tab.src = tab.tar + tab.n_tar - size;
|
||||
else memcpy((Void_t*)tab.src,
|
||||
(Void_t*)(tab.tar + tab.n_tar - size),
|
||||
size );
|
||||
tab.n_src = size;
|
||||
}
|
||||
}
|
||||
else /* data differencing */
|
||||
{ if(n < n_src)
|
||||
{ if(n+window > n_src)
|
||||
p = n_src-window;
|
||||
else p = n;
|
||||
if(source->data)
|
||||
tab.src = (uchar*)source->data + p;
|
||||
else
|
||||
{ size = (*source->readf)
|
||||
(tab.src, (int)window, p, source);
|
||||
if((long)size != window)
|
||||
goto done;
|
||||
}
|
||||
} /* else use last window */
|
||||
|
||||
tab.n_src = window;
|
||||
}
|
||||
|
||||
/* prepare the target string */
|
||||
size = (int)((n_tar-n) < window ? (n_tar-n) : window);
|
||||
tab.n_tar = size;
|
||||
if(target->data)
|
||||
tab.tar = (uchar*)target->data + n;
|
||||
else
|
||||
{ size = (*target->readf)(tab.tar, size, (long)n, target);
|
||||
if((long)size != tab.n_tar)
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* reinitialize table before processing */
|
||||
for(k = tab.size; k >= 0; --k)
|
||||
tab.table[k] = NIL(Match_t*);
|
||||
K_INIT(tab.quick,tab.recent,tab.rhere);
|
||||
|
||||
if(tab.n_src > 0 && vdfold(&tab,0) < 0)
|
||||
goto done;
|
||||
if(vdfold(&tab,1) < 0)
|
||||
goto done;
|
||||
|
||||
n += size;
|
||||
}
|
||||
|
||||
done:
|
||||
if(!target->data && tab.tar)
|
||||
free((Void_t*)tab.tar);
|
||||
if(tab.src && ((n_src <= 0 && !target->data) || (n_src > 0 && !source->data) ) )
|
||||
free((Void_t*)tab.src);
|
||||
if(tab.base)
|
||||
free((Void_t*)tab.base);
|
||||
if(tab.table)
|
||||
free((Void_t*)tab.table);
|
||||
|
||||
return tab.io.here + (tab.io.next - tab.io.data);
|
||||
}
|
||||
249
cde/programs/dtksh/ksh93/src/lib/libvdelta/vdelhdr.h
Normal file
249
cde/programs/dtksh/ksh93/src/lib/libvdelta/vdelhdr.h
Normal file
@@ -0,0 +1,249 @@
|
||||
/* $XConsortium: vdelhdr.h /main/2 1996/05/08 20:07:13 drk $ */
|
||||
/***************************************************************
|
||||
* *
|
||||
* AT&T - PROPRIETARY *
|
||||
* *
|
||||
* THIS IS PROPRIETARY SOURCE CODE LICENSED BY *
|
||||
* AT&T CORP. *
|
||||
* *
|
||||
* Copyright (c) 1995 AT&T Corp. *
|
||||
* All Rights Reserved *
|
||||
* *
|
||||
* This software is licensed by AT&T Corp. *
|
||||
* under the terms and conditions of the license in *
|
||||
* http://www.research.att.com/orgs/ssr/book/reuse *
|
||||
* *
|
||||
* This software was created by the *
|
||||
* Software Engineering Research Department *
|
||||
* AT&T Bell Laboratories *
|
||||
* *
|
||||
* For further information contact *
|
||||
* gsf@research.att.com *
|
||||
* *
|
||||
***************************************************************/
|
||||
#ifndef _VDELHDR_H
|
||||
#define _VDELHDR_H 1
|
||||
|
||||
#include "vdelta.h"
|
||||
|
||||
#if _PACKAGE_ast
|
||||
#include <ast_std.h>
|
||||
#else
|
||||
#if __STD_C
|
||||
#include <stddef.h>
|
||||
#else
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
_BEGIN_EXTERNS_
|
||||
extern int abort();
|
||||
_END_EXTERNS_
|
||||
#define ASSERT(p) ((p) ? 0 : abort())
|
||||
#define DBTOTAL(t,v) ((t) += (v))
|
||||
#define DBMAX(m,v) ((m) = (m) > (v) ? (m) : (v) )
|
||||
#else
|
||||
#define ASSERT(p)
|
||||
#define DBTOTAL(t,v)
|
||||
#define DBMAX(m,v)
|
||||
#endif
|
||||
|
||||
/* short-hand notations */
|
||||
#define reg register
|
||||
#define uchar unsigned char
|
||||
#define uint unsigned int
|
||||
#define ulong unsigned long
|
||||
|
||||
/* default window size - Chosen to suit malloc() even on 16-bit machines. */
|
||||
#define MAXINT ((int)(((uint)~0) >> 1))
|
||||
#define MAXWINDOW ((int)(((uint)~0) >> 2))
|
||||
#define DFLTWINDOW (MAXWINDOW <= (1<<14) ? (1<<14) : (1<<16) )
|
||||
#define HEADER(w) ((w)/4)
|
||||
|
||||
#define M_MIN 4 /* min number of bytes to match */
|
||||
|
||||
/* The hash function is s[0]*alpha^3 + s[1]*alpha^2 + s[2]*alpha + s[3] */
|
||||
#define ALPHA 33
|
||||
#if 0
|
||||
#define A1(x,t) (ALPHA*(x))
|
||||
#define A2(x,t) (ALPHA*ALPHA*(x))
|
||||
#define A3(x,t) (ALPHA*ALPHA*ALPHA*(x))
|
||||
#else /* fast multiplication using shifts&adds */
|
||||
#define A1(x,t) ((t = (x)), (t + (t<<5)) )
|
||||
#define A2(x,t) ((t = (x)), (t + (t<<6) + (t<<10)) )
|
||||
#define A3(x,t) ((t = (x)), (t + (t<<5) + ((t+(t<<4))<<6) + ((t+(t<<4))<<11)) )
|
||||
#endif
|
||||
#define HINIT(h,s,t) ((h = A3(s[0],t)), (h += A2(s[1],t)), (h += A1(s[2],t)+s[3]) )
|
||||
#define HNEXT(h,s,t) ((h -= A3(s[-1],t)), (h = A1(h,t) + s[3]) )
|
||||
|
||||
#define EQUAL(s,t) ((s)[0] == (t)[0] && (s)[1] == (t)[1] && \
|
||||
(s)[2] == (t)[2] && (s)[3] == (t)[3] )
|
||||
|
||||
/* Every instruction will start with a control byte.
|
||||
** For portability, only 8 bits of the byte are used.
|
||||
** The bits are used as follows:
|
||||
** iiii ssss
|
||||
** ssss: size of data involved.
|
||||
** iiii: this defines 16 instruction types:
|
||||
** 0: an ADD instruction.
|
||||
** 1,2,3: COPY with K_QUICK addressing scheme.
|
||||
** 4,5: COPY with K_SELF,K_HERE addressing schemes.
|
||||
** 6,7,8,9: COPY with K_RECENT addressing scheme.
|
||||
** For the above types, ssss if not zero codes the size;
|
||||
** otherwise, the size is coded in subsequent bytes.
|
||||
** 10,11: merged ADD/COPY with K_SELF,K_HERE addressing
|
||||
** 12,13,14,15: merged ADD/COPY with K_RECENT addressing.
|
||||
** For merged ADD/COPY instructions, ssss is divided into "cc aa"
|
||||
** where cc codes the size of COPY and aa codes the size of ADD.
|
||||
*/
|
||||
|
||||
#define VD_BITS 8 /* # bits usable in a byte */
|
||||
|
||||
#define S_BITS 4 /* bits for the size field */
|
||||
#define I_BITS 4 /* bits for the instruction type */
|
||||
|
||||
/* The below macros compute the coding for a COPY address.
|
||||
** There are two caches, a "quick" cache of (K_QTYPE*256) addresses
|
||||
** and a revolving cache of K_RTYPE "recent" addresses.
|
||||
** First, we look in the quick cache to see if the address is there.
|
||||
** If so, we use the cache index as the code.
|
||||
** Otherwise, we compute from 0, the current location and
|
||||
** the "recent" cache an address that is closest to the being coded address,
|
||||
** then code the difference. The type is set accordingly.
|
||||
**
|
||||
** An invariance is 2*K_MERGE + K_QTYPE + 1 == 16
|
||||
*/
|
||||
#define K_RTYPE 4 /* # of K_RECENT types */
|
||||
#define K_QTYPE 3 /* # of K_QUICK types */
|
||||
#define K_MERGE (K_RTYPE+2) /* # of types allowing add+copy */
|
||||
#define K_QSIZE (K_QTYPE<<VD_BITS) /* size of K_QUICK cache */
|
||||
|
||||
#define K_QUICK 1 /* start of K_QUICK types */
|
||||
#define K_SELF (K_QUICK+K_QTYPE)
|
||||
#define K_HERE (K_SELF+1)
|
||||
#define K_RECENT (K_HERE+1) /* start of K_RECENT types */
|
||||
|
||||
#define K_DDECL(quick,recent,rhere) /* cache decls in vdelta */ \
|
||||
int quick[K_QSIZE]; int recent[K_RTYPE]; int rhere/*;*/
|
||||
#define K_UDECL(quick,recent,rhere) /* cache decls in vdupdate */ \
|
||||
long quick[K_QSIZE]; long recent[K_RTYPE]; int rhere/*;*/
|
||||
#define K_INIT(quick,recent,rhere) \
|
||||
{ quick[rhere=0] = (1<<7); \
|
||||
while((rhere += 1) < K_QSIZE) quick[rhere] = rhere + (1<<7); \
|
||||
recent[rhere=0] = (1<<8); \
|
||||
while((rhere += 1) < K_RTYPE) recent[rhere] = (rhere+1)*(1<<8); \
|
||||
}
|
||||
#define K_UPDATE(quick,recent,rhere,copy) \
|
||||
{ quick[copy%K_QSIZE] = copy; \
|
||||
if((rhere += 1) >= K_RTYPE) rhere = 0; recent[rhere] = copy; \
|
||||
}
|
||||
|
||||
#define VD_ISCOPY(k) ((k) > 0 && (k) < (K_RECENT+K_RTYPE) )
|
||||
#define K_ISMERGE(k) ((k) >= (K_RECENT+K_RTYPE))
|
||||
|
||||
#define A_SIZE ((1<<S_BITS)-1) /* max local ADD size */
|
||||
#define A_ISLOCAL(s) ((s) <= A_SIZE ) /* can be coded locally */
|
||||
#define A_LPUT(s) (s) /* coded local value */
|
||||
#define A_PUT(s) ((s) - (A_SIZE+1) ) /* coded normal value */
|
||||
|
||||
#define A_ISHERE(i) ((i) & A_SIZE) /* locally coded size */
|
||||
#define A_LGET(i) ((i) & A_SIZE)
|
||||
#define A_GET(s) ((s) + (A_SIZE+1) )
|
||||
|
||||
#define C_SIZE ((1<<S_BITS)+M_MIN-2) /* max local COPY size */
|
||||
#define C_ISLOCAL(s) ((s) <= C_SIZE ) /* can be coded locally */
|
||||
#define C_LPUT(s) ((s) - (M_MIN-1) ) /* coded local value */
|
||||
#define C_PUT(s) ((s) - (C_SIZE+1) ) /* coded normal value */
|
||||
|
||||
#define C_ISHERE(i) ((i) & ((1<<S_BITS)-1)) /* size was coded local */
|
||||
#define C_LGET(i) (((i) & ((1<<S_BITS)-1)) + (M_MIN-1) )
|
||||
#define C_GET(s) ((s) + (C_SIZE+1) )
|
||||
|
||||
#define K_PUT(k) ((k) << S_BITS)
|
||||
#define K_GET(i) ((i) >> S_BITS)
|
||||
|
||||
/* coding merged ADD/COPY instructions */
|
||||
#define A_TINY 2 /* bits for tiny ADD */
|
||||
#define A_TINYSIZE (1<<A_TINY) /* max tiny ADD size */
|
||||
#define A_ISTINY(s) ((s) <= A_TINYSIZE )
|
||||
#define A_TPUT(s) ((s) - 1)
|
||||
#define A_TGET(i) (((i) & (A_TINYSIZE-1)) + 1)
|
||||
|
||||
#define C_TINY 2 /* bits for tiny COPY */
|
||||
#define C_TINYSIZE ((1<<C_TINY) + M_MIN-1) /* max tiny COPY size */
|
||||
#define C_ISTINY(s) ((s) <= C_TINYSIZE)
|
||||
#define C_TPUT(s) (((s) - M_MIN) << A_TINY)
|
||||
#define C_TGET(i) ((((i) >> A_TINY) & ((1<<C_TINY)-1)) + M_MIN )
|
||||
|
||||
#define K_TPUT(k) (((k)+K_MERGE) << S_BITS)
|
||||
|
||||
#define MEMCPY(to,from,n) \
|
||||
switch(n) \
|
||||
{ default: memcpy((Void_t*)to,(Void_t*)from,(size_t)n); \
|
||||
to += n; from += n; break; \
|
||||
case 7 : *to++ = *from++; \
|
||||
case 6 : *to++ = *from++; \
|
||||
case 5 : *to++ = *from++; \
|
||||
case 4 : *to++ = *from++; \
|
||||
case 3 : *to++ = *from++; \
|
||||
case 2 : *to++ = *from++; \
|
||||
case 1 : *to++ = *from++; \
|
||||
case 0 : break; \
|
||||
}
|
||||
|
||||
/* Below here is code for a buffered I/O subsystem to speed up I/O */
|
||||
#define I_SHIFT 7
|
||||
#define I_MORE (1<<I_SHIFT) /* continuation bit */
|
||||
#define I_CODE(n) ((uchar)((n)&(I_MORE-1)) ) /* get lower bits */
|
||||
|
||||
/* structure to do buffered IO */
|
||||
typedef struct _vdio_s
|
||||
{ uchar* next;
|
||||
uchar* endb;
|
||||
uchar* data;
|
||||
int size;
|
||||
long here;
|
||||
Vddisc_t* delta;
|
||||
uchar buf[512];
|
||||
} Vdio_t;
|
||||
|
||||
#define ENDB(io) ((io)->endb)
|
||||
#define NEXT(io) ((io)->next)
|
||||
#define HERE(io) ((io)->here)
|
||||
#define DATA(io) ((io)->data)
|
||||
#define SIZE(io) ((io)->size)
|
||||
#define DELTA(io) ((io)->delta)
|
||||
#define READF(io) ((io)->delta->readf)
|
||||
#define WRITEF(io) ((io)->delta->writef)
|
||||
#define REMAIN(io) (ENDB(io) - NEXT(io))
|
||||
#define INIT(io,delta) ((io)->endb = (io)->next = (io)->data = NIL(uchar*), \
|
||||
(io)->size = 0, (io)->here = 0, (io)->delta = (delta) )
|
||||
#define VDPUTC(io,c) ((REMAIN(io) > 0 || (*_Vdflsbuf)(io) > 0) ? \
|
||||
(int)(*(io)->next++ = (uchar)(c)) : -1 )
|
||||
#define VDGETC(io) ((REMAIN(io) > 0 || (*_Vdfilbuf)(io) > 0) ? \
|
||||
(int)(*(io)->next++) : -1 )
|
||||
|
||||
typedef struct _vdbufio_s
|
||||
{ int(* vdfilbuf)_ARG_((Vdio_t*));
|
||||
int(* vdflsbuf)_ARG_((Vdio_t*));
|
||||
ulong(* vdgetu)_ARG_((Vdio_t*, ulong));
|
||||
int(* vdputu)_ARG_((Vdio_t*, ulong));
|
||||
int(* vdread)_ARG_((Vdio_t*, uchar*, int));
|
||||
int(* vdwrite)_ARG_((Vdio_t*, uchar*, int));
|
||||
} Vdbufio_t;
|
||||
#define _Vdfilbuf _Vdbufio.vdfilbuf
|
||||
#define _Vdflsbuf _Vdbufio.vdflsbuf
|
||||
#define _Vdgetu _Vdbufio.vdgetu
|
||||
#define _Vdputu _Vdbufio.vdputu
|
||||
#define _Vdread _Vdbufio.vdread
|
||||
#define _Vdwrite _Vdbufio.vdwrite
|
||||
|
||||
_BEGIN_EXTERNS_
|
||||
extern Vdbufio_t _Vdbufio;
|
||||
extern Void_t* memcpy _ARG_((Void_t*, const Void_t*, size_t));
|
||||
extern Void_t* malloc _ARG_((size_t));
|
||||
extern void free _ARG_((Void_t*));
|
||||
_END_EXTERNS_
|
||||
|
||||
#endif /*_VDELHDR_H*/
|
||||
83
cde/programs/dtksh/ksh93/src/lib/libvdelta/vdelta.3
Normal file
83
cde/programs/dtksh/ksh93/src/lib/libvdelta/vdelta.3
Normal file
@@ -0,0 +1,83 @@
|
||||
.\" $XConsortium: vdelta.3 /main/2 1996/10/29 15:17:44 drk $
|
||||
.de MW
|
||||
\f5\\$1\fP
|
||||
..
|
||||
.TH VDELTA 3 "16 July 1994"
|
||||
.SH NAME
|
||||
vdelta \- data differencing and compression
|
||||
.SH SYNOPSIS
|
||||
.MW "#include <vdelta.h>"
|
||||
.nf
|
||||
.MW "long vddelta(Vddisc_t* source, Vddisc_t* target, Vddisc_t* delta, int window);"
|
||||
.MW "long vdupdate(Vddisc_t* source, Vddisc_t* target, Vddisc_t* delta);"
|
||||
.fi
|
||||
.SH DESCRIPTION
|
||||
These functions embody an algorithm for determining a compressed form of the
|
||||
difference between two byte streams,
|
||||
and for applying that difference to a byte stream.
|
||||
.PP
|
||||
.I Vddelta
|
||||
computes a transformation (encoded as the byte stream \f5delta\fP)
|
||||
that maps the source byte stream \f5source\fP
|
||||
to the target byte stream \f5target\fP.
|
||||
If the source stream is empty (\f5source\fP is \f5NULL\fP or
|
||||
\f5source->size\fP is non-positive),
|
||||
\fIvddelta\fP acts like a compression routine.
|
||||
\f5window\fP specifies the largest amount of data that
|
||||
will be processed at one time.
|
||||
Typically, larger values decrease the size of the transformation and increase
|
||||
the time needed to calculate it.
|
||||
A non-positive value for \f5window\fP indicates that \fIvddelta\fP
|
||||
should pick some value at its convenience.
|
||||
\fIVddelta\fP returns the length of the transformation byte stream.
|
||||
.PP
|
||||
.I Vdupdate
|
||||
applies a transformation \f5delta\fP generated by
|
||||
\fIvddelta\fP to the source byte stream \f5source\fP
|
||||
and emits the target byte stream \f5target\fP.
|
||||
\fIVdupdate\fP returns the length of the target byte stream.
|
||||
.PP
|
||||
The handling of data for a data stream is defined
|
||||
by a discipline structure of type \f5Vddisc_t\fP.
|
||||
This type contains the following members:
|
||||
.in +.5i
|
||||
.nf
|
||||
.MW "long size;"
|
||||
.MW "Void_t* data;"
|
||||
.MW "int (*readf)(Void_t* buf, int n, long offset, Vddisc_t* disc);"
|
||||
.MW "int (*writef)Void_t* buf, int n, long offset, Vddisc_t* disc);"
|
||||
.fi
|
||||
.in -.5i
|
||||
.TP
|
||||
\f5size\fP defines the length of the respective data stream.
|
||||
.TP
|
||||
\f5data\fP, if not \f5NULL\fP, is an array that either contains
|
||||
the entire data for a read stream or is large enough to store
|
||||
the entire generated data. For example, in the \fIvddelta\fP call,
|
||||
\f5target->size\fP defines the length of the target stream.
|
||||
In this case, if \f5target->data\fP is not \f5NULL\fP,
|
||||
it is assumed to contain all of the target data
|
||||
(therefore, \f5target->readf\fP is not required.)
|
||||
.TP
|
||||
.MW readf
|
||||
points to a function that reads at most \f5n\fP bytes
|
||||
into \f5buf\fP from position \f5offset\fP
|
||||
in the byte stream specified by the as described above, and
|
||||
returns the number of bytes actually read, or \-1 on error.
|
||||
The argument \f5disc\fP is the containing discipline structure.
|
||||
.TP
|
||||
.MW writef
|
||||
is identical to \f5readf\fP except that it writes rather than reads bytes.
|
||||
.TP
|
||||
.PP
|
||||
\f5Void_t\fP is \f5#define\fPd as \f5void\fP if possible, otherwise \f5char\fP.
|
||||
.SH DIAGNOSTICS
|
||||
Both
|
||||
.I vddelta
|
||||
and
|
||||
.I vdupdate
|
||||
return \-1 on error.
|
||||
.SH AUTHORS
|
||||
David G. Korn, dgk@research.att.com, AT&T Bell Laboratories
|
||||
.br
|
||||
Kiem-Phong Vo, kpv@research.att.com, AT&T Bell Laboratories
|
||||
92
cde/programs/dtksh/ksh93/src/lib/libvdelta/vdelta.h
Normal file
92
cde/programs/dtksh/ksh93/src/lib/libvdelta/vdelta.h
Normal file
@@ -0,0 +1,92 @@
|
||||
/* $XConsortium: vdelta.h /main/2 1996/05/08 20:07:29 drk $ */
|
||||
/***************************************************************
|
||||
* *
|
||||
* AT&T - PROPRIETARY *
|
||||
* *
|
||||
* THIS IS PROPRIETARY SOURCE CODE LICENSED BY *
|
||||
* AT&T CORP. *
|
||||
* *
|
||||
* Copyright (c) 1995 AT&T Corp. *
|
||||
* All Rights Reserved *
|
||||
* *
|
||||
* This software is licensed by AT&T Corp. *
|
||||
* under the terms and conditions of the license in *
|
||||
* http://www.research.att.com/orgs/ssr/book/reuse *
|
||||
* *
|
||||
* This software was created by the *
|
||||
* Software Engineering Research Department *
|
||||
* AT&T Bell Laboratories *
|
||||
* *
|
||||
* For further information contact *
|
||||
* gsf@research.att.com *
|
||||
* *
|
||||
***************************************************************/
|
||||
#ifndef _VDELTA_H
|
||||
#define _VDELTA_H 1
|
||||
|
||||
#ifndef __KPV__
|
||||
#define __KPV__ 1
|
||||
|
||||
#ifndef __STD_C
|
||||
#ifdef __STDC__
|
||||
#define __STD_C 1
|
||||
#else
|
||||
#if __cplusplus
|
||||
#define __STD_C 1
|
||||
#else
|
||||
#define __STD_C 0
|
||||
#endif /*__cplusplus*/
|
||||
#endif /*__STDC__*/
|
||||
#endif /*__STD_C*/
|
||||
|
||||
#ifndef _BEGIN_EXTERNS_
|
||||
#if __cplusplus
|
||||
#define _BEGIN_EXTERNS_ extern "C" {
|
||||
#define _END_EXTERNS_ }
|
||||
#else
|
||||
#define _BEGIN_EXTERNS_
|
||||
#define _END_EXTERNS_
|
||||
#endif
|
||||
#endif /*_BEGIN_EXTERNS_*/
|
||||
|
||||
#ifndef _ARG_
|
||||
#if __STD_C
|
||||
#define _ARG_(x) x
|
||||
#else
|
||||
#define _ARG_(x) ()
|
||||
#endif
|
||||
#endif /*_ARG_*/
|
||||
|
||||
#ifndef Void_t
|
||||
#if __STD_C
|
||||
#define Void_t void
|
||||
#else
|
||||
#define Void_t char
|
||||
#endif
|
||||
#endif /*Void_t*/
|
||||
|
||||
#ifndef NIL
|
||||
#define NIL(type) ((type)0)
|
||||
#endif /*NIL*/
|
||||
|
||||
#endif /*__KPV__*/
|
||||
|
||||
/* user-supplied functions to do io */
|
||||
typedef struct _vddisc_s Vddisc_t;
|
||||
typedef int(* Vdio_f)_ARG_((Void_t*, int, long, Vddisc_t*));
|
||||
struct _vddisc_s
|
||||
{ long size; /* total data size */
|
||||
Void_t* data; /* data array */
|
||||
Vdio_f readf; /* to read data */
|
||||
Vdio_f writef; /* to write data */
|
||||
};
|
||||
|
||||
/* magic header for delta output */
|
||||
#define VD_MAGIC "vd01"
|
||||
|
||||
_BEGIN_EXTERNS_
|
||||
extern long vddelta _ARG_((Vddisc_t*,Vddisc_t*,Vddisc_t*,long));
|
||||
extern long vdupdate _ARG_((Vddisc_t*,Vddisc_t*,Vddisc_t*));
|
||||
_END_EXTERNS_
|
||||
|
||||
#endif /*_VDELTA_H*/
|
||||
207
cde/programs/dtksh/ksh93/src/lib/libvdelta/vdio.c
Normal file
207
cde/programs/dtksh/ksh93/src/lib/libvdelta/vdio.c
Normal file
@@ -0,0 +1,207 @@
|
||||
/* $XConsortium: vdio.c /main/2 1996/05/08 20:07:43 drk $ */
|
||||
/***************************************************************
|
||||
* *
|
||||
* AT&T - PROPRIETARY *
|
||||
* *
|
||||
* THIS IS PROPRIETARY SOURCE CODE LICENSED BY *
|
||||
* AT&T CORP. *
|
||||
* *
|
||||
* Copyright (c) 1995 AT&T Corp. *
|
||||
* All Rights Reserved *
|
||||
* *
|
||||
* This software is licensed by AT&T Corp. *
|
||||
* under the terms and conditions of the license in *
|
||||
* http://www.research.att.com/orgs/ssr/book/reuse *
|
||||
* *
|
||||
* This software was created by the *
|
||||
* Software Engineering Research Department *
|
||||
* AT&T Bell Laboratories *
|
||||
* *
|
||||
* For further information contact *
|
||||
* gsf@research.att.com *
|
||||
* *
|
||||
***************************************************************/
|
||||
#include "vdelhdr.h"
|
||||
|
||||
/* IO subsystem for the delta routines
|
||||
**
|
||||
** Written by Kiem-Phong Vo (12/15/94)
|
||||
*/
|
||||
|
||||
#if __STD_C
|
||||
static _vdinit(reg Vdio_t* io)
|
||||
#else
|
||||
static _vdinit(io)
|
||||
reg Vdio_t* io;
|
||||
#endif
|
||||
{
|
||||
if((io->data = (uchar*)io->delta->data) )
|
||||
io->size = io->delta->size;
|
||||
else
|
||||
{ io->data = io->buf;
|
||||
io->size = sizeof(io->buf);
|
||||
}
|
||||
io->next = io->data;
|
||||
io->endb = io->data + io->size;
|
||||
}
|
||||
|
||||
|
||||
#if __STD_C
|
||||
static _vdfilbuf(reg Vdio_t* io)
|
||||
#else
|
||||
static _vdfilbuf(io)
|
||||
reg Vdio_t* io;
|
||||
#endif
|
||||
{ reg int n;
|
||||
|
||||
if(!io->data)
|
||||
_vdinit(io);
|
||||
|
||||
if(io->data != io->buf) /* all data was given in core */
|
||||
return REMAIN(io);
|
||||
|
||||
if((n = (*READF(io))(DATA(io),SIZE(io),HERE(io),DELTA(io))) > 0)
|
||||
{ ENDB(io) = (NEXT(io) = DATA(io)) + n;
|
||||
HERE(io) += n;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
#if __STD_C
|
||||
static _vdflsbuf(reg Vdio_t* io)
|
||||
#else
|
||||
static _vdflsbuf(io)
|
||||
reg Vdio_t* io;
|
||||
#endif
|
||||
{ reg int n;
|
||||
|
||||
if(!io->data )
|
||||
_vdinit(io);
|
||||
|
||||
if(io->data != io->buf) /* all space was given */
|
||||
return REMAIN(io);
|
||||
|
||||
if((n = NEXT(io) - DATA(io)) > 0 &&
|
||||
(*WRITEF(io))(DATA(io),n,HERE(io),DELTA(io)) != n)
|
||||
return -1;
|
||||
|
||||
HERE(io) += n;
|
||||
NEXT(io) = DATA(io);
|
||||
return SIZE(io);
|
||||
}
|
||||
|
||||
#if __STD_C
|
||||
static ulong _vdgetu(reg Vdio_t* io, reg ulong v)
|
||||
#else
|
||||
static ulong _vdgetu(io,v)
|
||||
reg Vdio_t* io;
|
||||
reg ulong v;
|
||||
#endif
|
||||
{ reg int c;
|
||||
|
||||
for(v &= I_MORE-1;;)
|
||||
{ if((c = VDGETC(io)) < 0)
|
||||
return (ulong)(-1L);
|
||||
if(!(c&I_MORE) )
|
||||
return ((v<<I_SHIFT) | c);
|
||||
v = (v<<I_SHIFT) | (c & (I_MORE-1));
|
||||
}
|
||||
}
|
||||
|
||||
#if __STD_C
|
||||
static _vdputu(reg Vdio_t* io, ulong v)
|
||||
#else
|
||||
static _vdputu(io, v)
|
||||
reg Vdio_t* io;
|
||||
reg ulong v;
|
||||
#endif
|
||||
{
|
||||
reg uchar *s, *next;
|
||||
reg int len;
|
||||
uchar c[sizeof(ulong)+1];
|
||||
|
||||
s = next = &c[sizeof(c)-1];
|
||||
*s = I_CODE(v);
|
||||
while((v >>= I_SHIFT) )
|
||||
*--s = I_CODE(v)|I_MORE;
|
||||
len = (next-s) + 1;
|
||||
|
||||
if(REMAIN(io) < len && _vdflsbuf(io) < len)
|
||||
return -1;
|
||||
|
||||
next = io->next;
|
||||
switch(len)
|
||||
{
|
||||
default: memcpy((Void_t*)next,(Void_t*)s,len); next += len; break;
|
||||
case 3: *next++ = *s++;
|
||||
case 2: *next++ = *s++;
|
||||
case 1: *next++ = *s;
|
||||
}
|
||||
io->next = next;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
#if __STD_C
|
||||
static _vdread(Vdio_t* io, reg uchar* s, reg int n)
|
||||
#else
|
||||
static _vdread(io, s, n)
|
||||
Vdio_t* io;
|
||||
reg uchar* s;
|
||||
reg int n;
|
||||
#endif
|
||||
{
|
||||
reg uchar* next;
|
||||
reg int r, m;
|
||||
|
||||
for(m = n; m > 0; )
|
||||
{ if((r = REMAIN(io)) <= 0 && (r = _vdfilbuf(io)) <= 0)
|
||||
break;
|
||||
if(r > m)
|
||||
r = m;
|
||||
|
||||
next = io->next;
|
||||
MEMCPY(s,next,r);
|
||||
io->next = next;
|
||||
|
||||
m -= r;
|
||||
}
|
||||
return n-m;
|
||||
}
|
||||
|
||||
#if __STD_C
|
||||
static _vdwrite(Vdio_t* io, reg uchar* s, reg int n)
|
||||
#else
|
||||
static _vdwrite(io, s, n)
|
||||
Vdio_t* io;
|
||||
reg uchar* s;
|
||||
reg int n;
|
||||
#endif
|
||||
{
|
||||
reg uchar* next;
|
||||
reg int w, m;
|
||||
|
||||
for(m = n; m > 0; )
|
||||
{ if((w = REMAIN(io)) <= 0 && (w = _vdflsbuf(io)) <= 0)
|
||||
break;
|
||||
if(w > m)
|
||||
w = m;
|
||||
|
||||
next = io->next;
|
||||
MEMCPY(next,s,w);
|
||||
io->next = next;
|
||||
|
||||
m -= w;
|
||||
}
|
||||
return n-m;
|
||||
}
|
||||
|
||||
|
||||
Vdbufio_t _Vdbufio =
|
||||
{ _vdfilbuf,
|
||||
_vdflsbuf,
|
||||
_vdgetu,
|
||||
_vdputu,
|
||||
_vdread,
|
||||
_vdwrite
|
||||
};
|
||||
411
cde/programs/dtksh/ksh93/src/lib/libvdelta/vdupdate.c
Normal file
411
cde/programs/dtksh/ksh93/src/lib/libvdelta/vdupdate.c
Normal file
@@ -0,0 +1,411 @@
|
||||
/* $XConsortium: vdupdate.c /main/2 1996/05/08 20:07:59 drk $ */
|
||||
/***************************************************************
|
||||
* *
|
||||
* AT&T - PROPRIETARY *
|
||||
* *
|
||||
* THIS IS PROPRIETARY SOURCE CODE LICENSED BY *
|
||||
* AT&T CORP. *
|
||||
* *
|
||||
* Copyright (c) 1995 AT&T Corp. *
|
||||
* All Rights Reserved *
|
||||
* *
|
||||
* This software is licensed by AT&T Corp. *
|
||||
* under the terms and conditions of the license in *
|
||||
* http://www.research.att.com/orgs/ssr/book/reuse *
|
||||
* *
|
||||
* This software was created by the *
|
||||
* Software Engineering Research Department *
|
||||
* AT&T Bell Laboratories *
|
||||
* *
|
||||
* For further information contact *
|
||||
* gsf@research.att.com *
|
||||
* *
|
||||
***************************************************************/
|
||||
#include "vdelhdr.h"
|
||||
|
||||
|
||||
/* Apply the transformation source->target to reconstruct target
|
||||
** This code is designed to work even if the local machine has
|
||||
** word size smaller than that of the machine where the delta
|
||||
** was computed. A requirement is that "long" on the local
|
||||
** machine must be large enough to hold source and target sizes.
|
||||
** It is also assumed that if an array is given, the size of
|
||||
** that array in bytes must be storable in an "int". This is
|
||||
** used in various cast from "long" to "int".
|
||||
**
|
||||
** Written by (Kiem-)Phong Vo, kpv@research.att.com, 5/20/94
|
||||
*/
|
||||
typedef struct _table_s
|
||||
{ Vdio_t io; /* io structure */
|
||||
Vddisc_t* source; /* source data discipline */
|
||||
Vddisc_t* target; /* target data discipline */
|
||||
uchar* src; /* source string */
|
||||
long n_src;
|
||||
uchar* tar; /* target string */
|
||||
long n_tar;
|
||||
long s_org; /* start of window in source */
|
||||
long t_org; /* start of window in target */
|
||||
uchar data[128]; /* buffer for data transferring */
|
||||
char s_alloc; /* 1 if source was allocated */
|
||||
char t_alloc; /* 1 if target was allocated */
|
||||
char compress; /* 1 if compressing only */
|
||||
K_UDECL(quick,recent,rhere); /* address caches */
|
||||
} Table_t;
|
||||
|
||||
#if __STD_C
|
||||
static vdunfold(Table_t* tab)
|
||||
#else
|
||||
static vdunfold(tab)
|
||||
Table_t* tab;
|
||||
#endif
|
||||
{
|
||||
reg long size, copy;
|
||||
reg int inst, k_type, n, r;
|
||||
reg uchar *tar, *src, *to, *fr;
|
||||
reg long t, c_addr, n_tar, n_src;
|
||||
reg Vddisc_t *target, *source;
|
||||
|
||||
n_tar = tab->n_tar;
|
||||
tar = tab->tar;
|
||||
n_src = tab->n_src;
|
||||
src = tab->src;
|
||||
target = tab->target;
|
||||
source = tab->source;
|
||||
|
||||
for(t = 0, c_addr = n_src; t < n_tar; )
|
||||
{ if((inst = VDGETC((Vdio_t*)tab)) < 0)
|
||||
return -1;
|
||||
k_type = K_GET(inst);
|
||||
|
||||
if(!VD_ISCOPY(k_type))
|
||||
{ if(K_ISMERGE(k_type)) /* merge/add instruction */
|
||||
size = A_TGET(inst);
|
||||
else if(A_ISHERE(inst)) /* locally coded ADD size */
|
||||
size = A_LGET(inst);
|
||||
else /* non-local ADD size */
|
||||
{ if((size = VDGETC((Vdio_t*)tab)) < 0)
|
||||
return -1;
|
||||
if(size >= I_MORE &&
|
||||
(size = (long)(*_Vdgetu)((Vdio_t*)tab,size)) < 0)
|
||||
return -1;
|
||||
size = A_GET(size);
|
||||
}
|
||||
if((t+size) > n_tar) /* out of sync */
|
||||
return -1;
|
||||
c_addr += size;
|
||||
|
||||
/* copy data from the delta stream to target */
|
||||
for(;;)
|
||||
{ if(!tar)
|
||||
{ if((long)(n = sizeof(tab->data)) > size)
|
||||
n = (int)size;
|
||||
if((*_Vdread)((Vdio_t*)tab,tab->data,n) != n )
|
||||
return -1;
|
||||
r = (*target->writef)((Void_t*)tab->data, n,
|
||||
tab->t_org+t, target);
|
||||
if(r != n)
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{ n = (int)size;
|
||||
if((*_Vdread)((Vdio_t*)tab,tar+t,n) != n)
|
||||
return -1;
|
||||
}
|
||||
t += n;
|
||||
if((size -= n) <= 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if(K_ISMERGE(k_type))
|
||||
{ size = C_TGET(inst);
|
||||
k_type -= K_MERGE;
|
||||
goto do_copy;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ if(C_ISHERE(inst)) /* locally coded COPY size */
|
||||
size = C_LGET(inst);
|
||||
else
|
||||
{ if((size = VDGETC((Vdio_t*)tab)) < 0)
|
||||
return -1;
|
||||
if(size >= I_MORE &&
|
||||
(size = (long)(*_Vdgetu)((Vdio_t*)tab,size)) < 0)
|
||||
return -1;
|
||||
size = C_GET(size);
|
||||
}
|
||||
do_copy:
|
||||
if((t+size) > n_tar) /* out of sync */
|
||||
return -1;
|
||||
|
||||
if((copy = VDGETC((Vdio_t*)tab)) < 0)
|
||||
return -1;
|
||||
if(k_type >= K_QUICK && k_type < (K_QUICK+K_QTYPE) )
|
||||
copy = tab->quick[copy + ((k_type-K_QUICK)<<VD_BITS)];
|
||||
else
|
||||
{ if(copy >= I_MORE &&
|
||||
(copy = (long)(*_Vdgetu)((Vdio_t*)tab,copy)) < 0)
|
||||
return -1;
|
||||
if(k_type >= K_RECENT && k_type < (K_RECENT+K_RTYPE) )
|
||||
copy += tab->recent[k_type - K_RECENT];
|
||||
else if(k_type == K_HERE)
|
||||
copy = c_addr - copy;
|
||||
/* else k_type == K_SELF */
|
||||
}
|
||||
K_UPDATE(tab->quick,tab->recent,tab->rhere,copy);
|
||||
c_addr += size;
|
||||
|
||||
if(copy < n_src) /* copy from source data */
|
||||
{ if((copy+size) > n_src) /* out of sync */
|
||||
return -1;
|
||||
if(src)
|
||||
{ n = (int)size;
|
||||
fr = src+copy;
|
||||
if(tar)
|
||||
{ to = tar+t;
|
||||
MEMCPY(to,fr,n);
|
||||
}
|
||||
else
|
||||
{ r = (*target->writef)((Void_t*)fr, n,
|
||||
tab->t_org+t, target);
|
||||
if(r != n)
|
||||
return -1;
|
||||
}
|
||||
t += n;
|
||||
}
|
||||
else
|
||||
{ reg Vddisc_t* disc;
|
||||
|
||||
if(tab->compress)
|
||||
{ copy += tab->t_org - tab->n_src;
|
||||
disc = target;
|
||||
}
|
||||
else
|
||||
{ copy += tab->s_org;
|
||||
disc = source;
|
||||
}
|
||||
for(;;)
|
||||
{ if(tar)
|
||||
{ n = (int)size;
|
||||
r = (*disc->readf)
|
||||
((Void_t*)(tar+t), n,
|
||||
copy, disc );
|
||||
}
|
||||
else
|
||||
{ n = sizeof(tab->data);
|
||||
if((long)n > size)
|
||||
n = (int)size;
|
||||
r = (*disc->readf)
|
||||
((Void_t*)tab->data, n,
|
||||
copy, disc );
|
||||
if(r != n)
|
||||
return -1;
|
||||
r = (*target->writef)
|
||||
((Void_t*)tab->data, n,
|
||||
tab->t_org+t, target);
|
||||
}
|
||||
if(r != n)
|
||||
return -1;
|
||||
t += n;
|
||||
if((size -= n) <= 0)
|
||||
break;
|
||||
copy += n;
|
||||
}
|
||||
}
|
||||
}
|
||||
else /* copy from target data */
|
||||
{ copy -= n_src;
|
||||
if(copy >= t || (copy+size) > n_tar) /* out-of-sync */
|
||||
return -1;
|
||||
for(;;) /* allow for copying overlapped data */
|
||||
{ reg long s, a;
|
||||
if((s = t-copy) > size)
|
||||
s = size;
|
||||
if(tar)
|
||||
{ to = tar+t; fr = tar+copy; n = (int)s;
|
||||
MEMCPY(to,fr,n);
|
||||
t += n;
|
||||
goto next;
|
||||
}
|
||||
|
||||
/* hard read/write */
|
||||
a = copy;
|
||||
for(;;)
|
||||
{ if((long)(n = sizeof(tab->data)) > s)
|
||||
n = (int)s;
|
||||
r = (*target->readf)
|
||||
((Void_t*)tab->data, n,
|
||||
a + tab->t_org, target );
|
||||
if(r != n)
|
||||
return -1;
|
||||
r = (*target->writef)
|
||||
((Void_t*)tab->data, n,
|
||||
t + tab->t_org, target );
|
||||
if(r != n)
|
||||
return -1;
|
||||
t += n;
|
||||
if((s -= n) <= 0)
|
||||
break;
|
||||
a += n;
|
||||
}
|
||||
|
||||
next: if((size -= s) == 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if __STD_C
|
||||
long vdupdate(Vddisc_t* source, Vddisc_t* target, Vddisc_t* delta)
|
||||
#else
|
||||
long vdupdate(source,target,delta)
|
||||
Vddisc_t* source; /* source data */
|
||||
Vddisc_t* target; /* target data */
|
||||
Vddisc_t* delta; /* delta data */
|
||||
#endif
|
||||
{
|
||||
reg int n, r;
|
||||
reg uchar *tar, *src;
|
||||
reg long t, p, window, n_src, n_tar;
|
||||
reg uchar *data;
|
||||
uchar magic[8];
|
||||
Table_t tab;
|
||||
|
||||
if(!target || (!target->data && !target->writef) )
|
||||
return -1;
|
||||
if(!delta || (!delta->data && !delta->readf) )
|
||||
return -1;
|
||||
|
||||
/* initialize I/O buffer */
|
||||
INIT(&tab.io,delta);
|
||||
tab.source = source;
|
||||
tab.target = target;
|
||||
|
||||
/* check magic header */
|
||||
data = (uchar*)(VD_MAGIC);
|
||||
for(n = 0; data[n]; ++n)
|
||||
;
|
||||
if((*_Vdread)(&tab.io,magic,n) != n)
|
||||
return -1;
|
||||
for(n -= 1; n >= 0; --n)
|
||||
if(data[n] != magic[n])
|
||||
return -1;
|
||||
|
||||
/* get true target size */
|
||||
if((t = (long)(*_Vdgetu)(&tab.io,0)) < 0 ||
|
||||
(target->data && target->size < t) )
|
||||
return -1;
|
||||
n_tar = t;
|
||||
|
||||
/* get true source size */
|
||||
if((t = (long)(*_Vdgetu)(&tab.io,0)) < 0)
|
||||
return -1;
|
||||
else if(t > 0)
|
||||
{ if(!source || (!source->data && !source->readf) )
|
||||
return -1;
|
||||
if(source->data && source->size < t)
|
||||
return -1;
|
||||
}
|
||||
n_src = t;
|
||||
|
||||
/* get window size */
|
||||
if((window = (long)(*_Vdgetu)(&tab.io,0)) < 0)
|
||||
return -1;
|
||||
|
||||
tab.compress = n_src == 0 ? 1 : 0;
|
||||
|
||||
/* if we have space, it'll be faster to unfold */
|
||||
tab.tar = tab.src = NIL(uchar*);
|
||||
tab.t_alloc = tab.s_alloc = 0;
|
||||
|
||||
if(n_tar > 0 && !target->data && window < (long)MAXINT)
|
||||
n = (int)window;
|
||||
else n = 0;
|
||||
if(n > 0 && (tab.tar = (uchar*)malloc(n*sizeof(uchar))) )
|
||||
tab.t_alloc = 1;
|
||||
|
||||
if(n_src > 0 && !source->data && window < (long)MAXINT)
|
||||
n = (int)window;
|
||||
else if(n_src == 0 && window < n_tar && !target->data &&
|
||||
HEADER(window) < (long)MAXINT)
|
||||
n = (int)HEADER(window);
|
||||
else n = 0;
|
||||
if(n > 0 && (tab.src = (uchar*)malloc(n*sizeof(uchar))) )
|
||||
tab.s_alloc = 1;
|
||||
|
||||
tar = (uchar*)target->data;
|
||||
src = (uchar*)(source ? source->data : NIL(Void_t*));
|
||||
for(t = 0; t < n_tar; )
|
||||
{ tab.t_org = t; /* current location in target stream */
|
||||
|
||||
if(n_src == 0) /* data compression */
|
||||
{ tab.s_org = 0;
|
||||
|
||||
if(t == 0)
|
||||
tab.n_src = 0;
|
||||
else
|
||||
{ tab.n_src = HEADER(window);
|
||||
p = t - tab.n_src;
|
||||
if(tar)
|
||||
tab.src = tar + p;
|
||||
else if(tab.src)
|
||||
{ n = (int)tab.n_src;
|
||||
if(tab.tar)
|
||||
{ data = tab.tar + tab.n_tar - n;
|
||||
memcpy((Void_t*)tab.src,(Void_t*)data,n);
|
||||
}
|
||||
else
|
||||
{ r = (*target->readf)(tab.src,n,p,target);
|
||||
if(r != n)
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else /* data differencing */
|
||||
{ tab.n_src = window;
|
||||
if(t < n_src)
|
||||
{ if((t+window) > n_src)
|
||||
p = n_src-window;
|
||||
else p = t;
|
||||
|
||||
tab.s_org = p;
|
||||
|
||||
if(src)
|
||||
tab.src = src + p;
|
||||
else if(tab.src)
|
||||
{ n = (int)tab.n_src;
|
||||
r = (*source->readf)(tab.src,n,p,source);
|
||||
if(r != n)
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(tar)
|
||||
tab.tar = (uchar*)tar+t;
|
||||
tab.n_tar = window < (n_tar-t) ? window : (n_tar-t);
|
||||
|
||||
K_INIT(tab.quick,tab.recent,tab.rhere);
|
||||
if(vdunfold(&tab) < 0)
|
||||
goto done;
|
||||
if(!target->data && tab.tar)
|
||||
{ p = (*target->writef)((Void_t*)tab.tar,(int)tab.n_tar,t,target);
|
||||
if(p != tab.n_tar)
|
||||
goto done;
|
||||
}
|
||||
|
||||
t += tab.n_tar;
|
||||
}
|
||||
|
||||
done:
|
||||
if(tab.t_alloc)
|
||||
free((Void_t*)tab.tar);
|
||||
if(tab.s_alloc)
|
||||
free((Void_t*)tab.src);
|
||||
|
||||
return t;
|
||||
}
|
||||
Reference in New Issue
Block a user