/***********************************************************************
* *
* This software is part of the ast package *
* Copyright (c) 2003-2011 AT&T Intellectual Property *
* and is licensed under the *
* Eclipse Public License, Version 1.0 *
* by AT&T Intellectual Property *
* *
* A copy of the License is available at *
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
* *
* Information and Software Systems Research *
* AT&T Research *
* Florham Park NJ *
* *
* Phong Vo <kpv@research.att.com> *
* *
***********************************************************************/
#include "vchdr.h"
/* Sfio discipline to run Vcodex methods for compression.
**
** Written by Kiem-Phong Vo, kpv@research.att.com.
*/
/* these bits are in sfdc->flags and must be outside VC_FLAGS */
typedef struct _sfdc_s
} Sfdc_t;
#ifndef SKIPVCDX /* deal with the ancient VCDX header that uses method numbers */
#ifndef elementsof
#define elementsof(x) (sizeof(x)/sizeof(x[0]))
#endif
} Map_t;
} Meth_t;
{ { "delta", 0 },
{ "huffman", 1 },
{ "huffgroup", 2 },
{ "arith", 3 },
{ "bwt", 4 },
{ "rle", 5 },
{ "mtf", 6 },
{ "transpose", 7 },
{ "table", 8 },
{ "huffpart", 9 },
{ "map", 50 },
{ "ama", 100 },
{ "ss7", 101 },
};
#if __STD_C
#else
#endif
{
/* parse old header into list of transforms */
for(k = 0; k < elementsof(Map); ++k)
break;
return dtsz; /* must be new header format */
return dtsz;
}
return dtsz; /* must be new header format */
}
return dtsz; /* must be new header */
/* construct new header in reverse order */
for(n -= 1; n >= 0; --n)
{ /* get and write out the method id string */
return -1; /* error, no id string for method? */
return dtsz; /* must be new header format */
return dtsz;
if(sz == 0)
{ if(*dt == 0) /* coding rle.0 or mtf.0 */
}
}
else /* let us pray for the right coding! */
}
}
}
#endif /* SKIPVCDX */
/* dealing with RFC3284 Vcdiff header */
#if __STD_C
#else
int indi; /* indicator byte */
#endif
{
return -1;
/* write out the method identification string */
return -1;
return -1;
if(indi&VCD_CODETABLE)
return -1;
return -1;
return -1;
}
else
return -1;
}
}
#if __STD_C
#else
#endif
{
/* header should be done at most once */
return 0;
/* header not wanted */
return 0;
/* get the string that codes the methods */
/* output standard header bytes */
/* output indicator byte - see also compatibility with RFC3284 */
/* output data encoding the methods used */
}
return 0;
}
#if __STD_C
#else
#endif
{
return 0;
return -1;
return 0;
}
#if __STD_C
#else
Sfio_t* f;
#endif
{
sz = 0;
}
}
{ if(!disc) /* plain read if no discipline set yet */
if(n <= 0)
break;
}
return sz;
}
static int
#if _STD_C
#else
char** pc;
char** pb;
char** pe;
int n;
#endif
{
int x;
int o;
if (x < n)
x = n;
x *= 2;
return -1;
return 0;
}
#if __STD_C
#else
#endif
{
char *mt;
unsigned char *dt;
int x;
return -1;
x = 256;
return -1;
{
return -1;
*id++ = VC_METHSEP;
}
return -1;
if(mt[k] == 0)
break;
}
if(k >= sz)
return -1;
/* get the initialization data, if any */
return -1;
if(sz)
return -1;
*id++ = '=';
for(k = 0; k < sz; k++)
{ x = dt[k];
}
}
}
*id = 0;
return 1;
}
#if __STD_C
#else
Sfio_t* f;
int init; /* initial call */
int identify;
#endif
{
if(identify)
{ /* verify header magic -- ignore if no magic */
return 0;
if(cdbuf[0]!=VC_HEADER0 || cdbuf[1]!=VC_HEADER1 || cdbuf[2]!=VC_HEADER2 || cdbuf[3]!=VC_HEADER3 && cdbuf[3]!=0)
return 0;
}
{
/* buffer was too small for header data */
/* read header data as necessary */
}
continue;
continue;
}
if(head == 0) /* RFC3284 Vcdiff format */
else if(cdsz == 0)
continue;
}
else /* Vcodex encoding */
continue;
else if(cdsz == 0)
continue;
#ifndef SKIPVCDX /* deal with old headers that use method numbers instead of names */
#endif
}
/* successfully read the header data */
break;
}
if(cdsz <= 0 )
else if(identify)
else
else return 0;
}
}
#if __STD_C
#else
#endif
{
{ /* control data */
ctrl = 0;
/* compute a matching window to enhance compression */
if(wm)
}
}
{ if(cdsz < 0)
}
else
}
}
return -1;
}
continue;
else /* need fresh data */
}
break;
}
}
}
return size; /* return amount processed */
}
/* read data from the filter */
#if __STD_C
#else
Sfio_t* f; /* stream reading from */
size_t n; /* number of bytes requested */
#endif
{
int ctrl;
{ /* copy already decoded data */
}
else /* need to decode a new batch of data */
{
break;
}
/* get the control byte */
/* let upper level write and flush first */
break;
}
}
continue; /* skip a sequence of VC_EOF's */
break;
else continue;
}
}
/* size of coded data */
}
/* make sure all the data is available */
}
/* decode data */
m = d;
}
else
}
}
/* set plaintext data buffer */
}
}
return sz;
}
#if __STD_C
#else
Sfio_t* f; /* stream writing to */
size_t n; /* number of bytes requested */
#endif
{
{ /* final flush */
break;
}
else sz += w;
break;
}
{ w = 0; /* so for(;;) won't add to sz, dt */
continue; /* back to flushing */
}
else break;
}
{ /* flush a full buffer */
break;
}
break;
}
}
/* process data directly if buffer is empty and data is large */
break;
}
break;
}
}
else /* accumulating data into buffer */
}
}
return sz;
}
/* for the duration of this discipline, the stream is unseekable */
#if __STD_C
#else
Sfio_t* f;
int offset;
#endif
{
return (Sfoff_t)(-1);
}
/* on close, remove the discipline */
#if __STD_C
#else
Sfio_t* f;
int type;
#endif
{
switch(type)
{
case VCSF_DISC: /* get the discipline */
if(data)
return VCSF_DISC;
case SF_SYNC:
case SF_DPOP:
case SF_CLOSING:
case SF_ATEXIT:
{
sfset(f, SF_IOCHECK, 0);
#else /* Stdio: must call vcsfdcwrite() directly to encode */
#endif
}
/* back to plain text mode */
}
}
}
}
break;
}
return 0;
}
/* syntax for window size is "[0-9]+[mMkK]" */
#if __STD_C
#else
#endif
{
if(!spec)
spec = "";
spec += 1;
wsize *= 1024;
if(vcwmt)
spec += 1;
}
return wsize;
}
#if __STD_C
#else
int type; /* VC_ENCODE or VC_DECODE or 0 */
#endif
{
char *trans;
}
trans = "delta";
}
/* local error processing function */
{ if(!type)
errorsfio("Out of memory for transformation structure");
}
#endif
}
{ /* creat handle for transformation */
errorsfio("Ill-defined transformation for encoding.");
/* create windowing handle if needed */
errorsfio("Non-existing or unreadable source file.");
errorsfio("Windowing not possible");
}
/* buffer to accumulate data before encoding */
errorsfio("Out of memory for data buffer");
/* buffer for the encoder to output results */
errorsfio("Out of memory for output buffer");
}
else /* VC_DECODE */
{ /* make output buffer */
{ if(!type)
errorsfio("Out of memory for output buffer");
}
/* reconstruct handle to decode data */
{ if(!trans)
errorsfio("No transform specified for decoding.");
errorsfio("Ill-defined transformation for decoding.");
}
else
{ if(!type)
{ if(!type)
}
errorsfio("Badly encoded data, decoding not possible.");
}
if(!type)
{
}
}
/* construct window handle to get data for delta-decoding */
errorsfio("Non-existing or unreadable source file.");
errorsfio("Windowing not possible");
}
}
errorsfio("Stream not initializable");
#if _SFIO_H == 1
#else
#endif
if(sfdc)
}
}
#if _SFIO_H != 1
struct _rsrv_s
Sfio_t* f; /* file stream for I/O */
};
#if __STD_C
#else
Sfio_t* f; /* stream to to create reserve buffer */
ssize_t n; /* <0: remove, 0: find, >0: buffer size */
#endif
{
Rsrv_t *p, *r;
if(r->f == f)
break;
if(!r) /* create a new reserve structure if requested */
{ if(n <= 0)
r->f = f;
}
else
{ if(p) /* remove from list */
if(n < 0) /* remove all together */
free(r);
}
}
if(n > r->size) /* allocate buffer as necessary */
{ if(r->data)
{ free(r);
}
else r->size = n;
}
return r;
}
#if __STD_C
#else
Sfio_t* f;
ssize_t n;
int type;
#endif
{
Rsrv_t *r;
n = n < 0 ? -n : n;
}
#if __STD_C
#else
Sfio_t* f;
#endif
{
Rsrv_t *r;
}
#if __STD_C
#else
Sfio_t* f;
int nl;
int type;
#endif
{
Rsrv_t *r;
if(!(r = vcsfrsrv(f, 1024)) )
return NIL(char*);
return NIL(char*);
if(type > 0)
}
return (char*)r->data;
}
#if __STD_C
#else
int sfclose(f)
Sfio_t* f;
#endif
{ vcsfrsrv(f, -1);
fclose(f);
return 0;
}
#if __STD_C
#else
Sfio_t* f;
#endif
{
if(fseek(f, (long)0, 1) < 0 )
return -1;
fseek(f, (long)0, 2);
return siz;
}
#if __STD_C
#else
size_t n;
#endif
{
}
#if __STD_C
#else
size_t n;
#endif
{
}
#if __STD_C
#else
#endif
{
}
#if __STD_C
#else
#endif
{
return -1;
return -1;
return 0;
}
#endif /*!SFIO_H*/