home *** CD-ROM | disk | FTP | other *** search
- /*
- CXSUB functions.
- Copyright (c) 1990-1994 Eugene Nelson, Four Lakes Computing.
-
- This file contains useful subroutines that may be used with Cx.
- See files CXSUB.DOC and CXSUB.H for interface information.
- */
-
- #include <stddef.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <io.h>
- #include <fcntl.h>
- #include <sys\types.h>
- #include <sys\stat.h>
-
- #include "cxsub.h"
-
- /*-----------------------------------------------------------------------*/
- char *cx_error_message(
- CXINT err)
- {
- switch (err)
- {
- case CX_ERR_INVALID: return ("data could not be decompressed");
- case CX_ERR_METHOD: return ("invalid compression method");
- case CX_ERR_BUFFSIZE: return ("invalid buffer size");
- case CX_ERR_TEMPSIZE: return ("invalid temp buffer size");
- case CXSUB_ERR_OPENS: return ("could not open source");
- case CXSUB_ERR_OPEND: return ("could not open destination");
- case CXSUB_ERR_NOMEM: return ("insufficient memory");
- case CXSUB_ERR_READ: return ("could not read from source");
- case CXSUB_ERR_WRITE: return ("could not write to destination");
- case CXSUB_ERR_CLOSE: return ("could not close destination");
- case CXSUB_ERR_INVALID: return ("source file is invalid or corrupt");
- }
-
- return ("unknown");
- }
-
-
- /*
- The following define and routine
-
- CX_FILESUB_RET
- cx_filesub_error
-
- Are used to release allocated memory.
- */
-
-
- #define CX_FILESUB_RET(n) return(cx_filesub_error(n, ibuff, obuff, tbuff))
- /*----------------------------------------------------------------------*/
- static CXINT cx_filesub_error(
- CXINT err,
- CXBUFF ibuff,
- CXBUFF obuff,
- CXBUFF tbuff)
- {
- if (ibuff != NULL) free(ibuff);
- if (obuff != NULL) free(obuff);
- if (tbuff != NULL) free(tbuff);
-
- return (err);
- }
-
- /*----------------------------------------------------------------------*/
- CXINT cx_compress_ofile(
- int ofile,
- int ifile,
- CXINT method,
- CXINT bsize,
- CXINT tsize,
- int (*callback)(void *),
- void *p)
- {
- CXBUFF ibuff = NULL;
- CXBUFF obuff = NULL;
- CXBUFF tbuff = NULL;
-
- CXINT j, k, crc;
- CXBUFF t;
-
- ibuff = (CXBUFF) malloc(bsize);
- obuff = (CXBUFF) malloc(bsize+CX_SLOP);
- tbuff = (CXBUFF) malloc(tsize);
-
- if ((ibuff == NULL) || (obuff == NULL) || (tbuff == NULL))
- CX_FILESUB_RET (CXSUB_ERR_NOMEM);
-
- while (1)
- {
- if (callback != NULL)
- if (callback(p) != 0)
- return (0);
-
- j = read(ifile, ibuff, bsize);
- if (j == 0xffff)
- CX_FILESUB_RET (CXSUB_ERR_READ);
-
- if (write(ofile, &j, CXINTSIZE) != CXINTSIZE)
- CX_FILESUB_RET (CXSUB_ERR_WRITE);
-
- if (j == 0)
- break;
-
- k = CX_COMPRESS(method, obuff, bsize, ibuff, j, tbuff, tsize);
-
- if (k > j)
- CX_FILESUB_RET (k);
-
- if (write(ofile, &k, CXINTSIZE) != CXINTSIZE)
- CX_FILESUB_RET (CXSUB_ERR_WRITE);
-
-
- if (k == j) /* if block could not be compressed */
- t = ibuff;
- else
- t = obuff;
-
- crc = CX_CRC(t, k);
-
- if (write(ofile, &crc, CXINTSIZE) != CXINTSIZE)
- CX_FILESUB_RET (CXSUB_ERR_WRITE);
-
- if (write(ofile, t, k) != k)
- CX_FILESUB_RET (CXSUB_ERR_WRITE);
- }
-
- CX_FILESUB_RET (0);
- }
-
- /*----------------------------------------------------------------------*/
- CXINT cx_compress_file(
- char *dst,
- char *src,
- CXINT method,
- CXINT bsize,
- CXINT tsize,
- int (*callback)(void *),
- void *p)
- {
- int ifile = -1;
- int ofile = -1;
- CXINT j, k;
-
- if ((ifile = open(src, O_RDWR|O_BINARY, 0)) == -1)
- return (CXSUB_ERR_OPENS);
-
- unlink(dst);
- if ((ofile = open(dst, O_WRONLY|O_CREAT|O_BINARY, S_IREAD|S_IWRITE)) == -1)
- {
- close(ifile);
- return (CXSUB_ERR_OPEND);
- }
-
- k = cx_compress_ofile(ofile, ifile, method, bsize, tsize, callback, p);
-
- close(ifile);
-
- j = (close(ofile) == 0? 0: CXSUB_ERR_CLOSE);
-
- return (k==0? j: k);
- }
-
- /*----------------------------------------------------------------------*/
- CXINT cx_decompress_ofile(
- int ofile,
- int ifile,
- int (*callback)(void *),
- void *p)
- {
- CXBUFF ibuff = NULL;
- CXBUFF obuff = NULL;
- CXBUFF tbuff = NULL;
-
- CXINT bsize;
- CXINT j, k, crc;
- CXBUFF t;
-
- if ((tbuff = (CXBUFF) malloc(CX_D_MINTEMP)) == NULL)
- CX_FILESUB_RET (CXSUB_ERR_NOMEM);
-
- bsize = 0;
-
- while (1)
- {
- if (callback != NULL)
- if (callback(p) != 0)
- return (0);
-
- if (read(ifile, &j, CXINTSIZE) != CXINTSIZE)
- CX_FILESUB_RET (CXSUB_ERR_READ);
-
- if (j == 0) /* This indicates the end of file */
- break;
-
- if (bsize < j)
- {
- bsize = j;
- ibuff = (CXBUFF) realloc(obuff, bsize+CX_SLOP);
- obuff = (CXBUFF) realloc(obuff, bsize);
-
- if ((ibuff == NULL) || (obuff == NULL))
- CX_FILESUB_RET (CXSUB_ERR_NOMEM);
- }
-
- if (read(ifile, &k, CXINTSIZE) != CXINTSIZE)
- CX_FILESUB_RET (CXSUB_ERR_READ);
-
- if ((k > j) || (k > bsize) || (j > bsize))
- CX_FILESUB_RET (CXSUB_ERR_INVALID);
-
- if (read(ifile, &crc, CXINTSIZE) != CXINTSIZE)
- CX_FILESUB_RET (CXSUB_ERR_READ);
-
- if (read(ifile, ibuff, k) != k)
- CX_FILESUB_RET (CXSUB_ERR_READ);
-
- if (CX_CRC(ibuff, k) != crc)
- CX_FILESUB_RET (CXSUB_ERR_INVALID);
-
-
- if (j == k) /* if block is not compressed */
- t = ibuff;
- else
- {
- k = CX_DECOMPRESS(obuff, bsize, ibuff, k, tbuff, CX_D_MINTEMP);
- if (k > CX_MAX_BUFFER)
- CX_FILESUB_RET (k);
-
- if (j != k)
- CX_FILESUB_RET (CXSUB_ERR_INVALID);
-
- t = obuff;
- }
-
- if (ofile != -1)
- if (write(ofile, t, j) != j)
- CX_FILESUB_RET (CXSUB_ERR_WRITE);
- }
-
- CX_FILESUB_RET (0);
- }
-
-
- /*----------------------------------------------------------------------*/
- CXINT cx_decompress_file(
- char *dst,
- char *src,
- int (*callback)(void *),
- void *p)
- {
- int ifile = -1;
- int ofile = -1;
- CXINT k, j;
-
- if ((ifile = open(src, O_RDWR|O_BINARY, 0)) == -1)
- return (CXSUB_ERR_OPENS);
-
- if (dst != NULL)
- {
- unlink(dst);
- if ((ofile = open(dst, O_WRONLY|O_CREAT|O_BINARY, S_IREAD|S_IWRITE)) == -1)
- {
- close(ifile);
- return (CXSUB_ERR_OPEND);
- }
- }
-
- k = cx_decompress_ofile(ofile, ifile, callback, p);
-
- close(ifile);
-
- if (dst != NULL)
- j = (close(ofile) == 0? 0: CXSUB_ERR_CLOSE);
- else
- j = 0;
-
- return (k==0? j: k);
- }
-