⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 zipup.c

📁 给出了 zip 压缩算法的完整实现过程。
💻 C
📖 第 1 页 / 共 3 页
字号:
/*  Copyright (c) 1990-2006 Info-ZIP.  All rights reserved.  See the accompanying file LICENSE, version 2005-Feb-10 or later  (the contents of which are also included in zip.h) for terms of use.  If, for some reason, all these files are missing, the Info-ZIP license  also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html*//* *  zipup.c by Mark Adler and Jean-loup Gailly. */#define __ZIPUP_C#include "zip.h"#include <ctype.h>#ifndef UTIL            /* This module contains no code for Zip Utilities */#include "revision.h"#include "crypt.h"#ifdef USE_ZLIB#  include "zlib.h"#endif#ifdef OS2#  include "os2/os2zip.h"#endif#if defined(MMAP)#  include <sys/mman.h>#  ifndef PAGESIZE   /* used to be SYSV, what about pagesize on SVR3 ? */#    define PAGESIZE getpagesize()#  endif#  if defined(NO_VALLOC) && !defined(valloc)#    define valloc malloc#  endif#endif/* Use the raw functions for MSDOS and Unix to save on buffer space.   They're not used for VMS since it doesn't work (raw is weird on VMS). */#ifdef AMIGA#  include "amiga/zipup.h"#endif /* AMIGA */#ifdef AOSVS#  include "aosvs/zipup.h"#endif /* AOSVS */#ifdef ATARI#  include "atari/zipup.h"#endif#ifdef __BEOS__#  include "beos/zipup.h"#endif#ifdef __ATHEOS__#  include "atheos/zipup.h"#endif /* __ATHEOS__ */#ifdef __human68k__#  include "human68k/zipup.h"#endif /* __human68k__ */#ifdef MACOS#  include "macos/zipup.h"#endif#ifdef DOS#  include "msdos/zipup.h"#endif /* DOS */#ifdef OS2#  include "os2/zipup.h"#endif /* OS2 */#ifdef RISCOS#  include "acorn/zipup.h"#endif#ifdef TOPS20#  include "tops20/zipup.h"#endif#ifdef UNIX#  include "unix/zipup.h"#endif#ifdef CMS_MVS#  include "zipup.h"#endif /* CMS_MVS */#ifdef TANDEM#  include "zipup.h"#endif /* TANDEM */#ifdef VMS#  include "vms/zipup.h"#endif /* VMS */#ifdef QDOS#  include "qdos/zipup.h"#endif /* QDOS */#ifdef WIN32#  include "win32/zipup.h"#endif#ifdef THEOS#  include "theos/zipup.h"#endif/* Local functions */#ifndef RISCOS   local int suffixes OF((char *, char *));#else   local int filetypes OF((char *, char *));#endiflocal unsigned file_read OF((char *buf, unsigned size));#ifdef USE_ZLIB  local int zl_deflate_init OF((int pack_level));#else /* !USE_ZLIB */# ifdef ZP_NEED_MEMCOMPR    local unsigned mem_read OF((char *buf, unsigned size));# endif#endif /* ?USE_ZLIB */local ulg filecompress OF((struct zlist far *z_entry, FILE *zipfile,                           int *cmpr_method));/* Deflate "internal" global data (currently not in zip.h) */#if defined(MMAP) || defined(BIG_MEM)# ifdef USE_ZLIB    local uch *window = NULL;   /* Used to read all input file at once */    local ulg window_size;      /* size of said window */# else /* !USE_ZLIB */    extern uch *window;         /* Used to read all input file at once */#endif /* ?USE_ZLIB */#endif /* MMAP || BIG_MEM */#ifndef USE_ZLIB  extern ulg window_size;       /* size of said window */  unsigned (*read_buf) OF((char *buf, unsigned size)) = file_read;  /* Current input function. Set to mem_read for in-memory compression */#endif /* !USE_ZLIB *//* Local data */local ulg crc;          /* crc on uncompressed file data */local ftype ifile;      /* file to compress */#if defined(MMAP) || defined(BIG_MEM)  local ulg remain;  /* window bytes not yet processed.   *  special value "(ulg)-1L" reserved to signal normal reads.   */#endif /* MMAP || BIG_MEM */#ifdef USE_ZLIB  local int deflInit;           /* flag: zlib deflate is initialized */  local z_stream zstrm;         /* zlib's data interface structure */  local char *f_ibuf = NULL;  local char *f_obuf = NULL;#else /* !USE_ZLIB */  local FILE *zfile;            /* output zip file */  local char file_outbuf[1024]; /* output buffer for compression to file */# ifdef ZP_NEED_MEMCOMPR    local char *in_buf;    /* Current input buffer, in_buf is used only for in-memory compression. */    local unsigned in_offset;    /* Current offset in input buffer. in_offset is used only for in-memory     * compression. On 16 bit machines, the buffer is limited to 64K.     */    local unsigned in_size;    /* size of current input buffer */# endif /* ZP_NEED_MEMCOMPR */#endif /* ?USE_ZLIB */#ifdef DEBUG  ulg isize;           /* input file size. global only for debugging */#else /* !DEBUG */  local ulg isize;     /* input file size. */#endif /* ?DEBUG */int percent(n, m)ulg n;ulg m;               /* n is the original size, m is the new size *//* Return the percentage compression from n to m using only integer   operations */{  if (n > 0xffffffL)            /* If n >= 16M */  {                             /*  then divide n and m by 256 */    n += 0x80;  n >>= 8;    m += 0x80;  m >>= 8;  }  return n > m ? (int)(1 + (200 * (n - m)/n)) / 2 : 0;}#ifndef RISCOSlocal int suffixes(a, s)char *a;                /* name to check suffix of */char *s;                /* list of suffixes separated by : or ; *//* Return true if a ends in any of the suffixes in the list s. */{  int m;                /* true if suffix matches so far */  char *p;              /* pointer into special */  char *q;              /* pointer into name a */#ifdef QDOS  short dlen = devlen(a);  a = a + dlen;#endif  m = 1;#ifdef VMS  if( (q = strrchr(a,';')) != NULL )    /* Cut out VMS file version */    --q;  else    q = a + strlen(a) - 1;#else /* !VMS */  q = a + strlen(a) - 1;#endif /* ?VMS */  for (p = s + strlen(s) - 1; p >= s; p--)    if (*p == ':' || *p == ';')    {      if (m)        return 1;      else      {        m = 1;#ifdef VMS        if( (q = strrchr(a,';')) != NULL )      /* Cut out VMS file version */          --q;        else          q = a + strlen(a) - 1;#else /* !VMS */        q = a + strlen(a) - 1;#endif /* ?VMS */      }    }    else    {      m = m && q >= a && case_map(*p) == case_map(*q);      q--;    }  return m;}#else /* RISCOS */local int filetypes(a, s)char *a;                /* extra field of file to check filetype of */char *s;                /* list of filetypes separated by : or ; *//* Return true if a is any of the filetypes in the list s. */{ char *p;              /* pointer into special */ char typestr[4];     /* filetype hex string taken from a */ if ((((unsigned*)a)[2] & 0xFFF00000) != 0xFFF00000) { /* The file is not filestamped, always try to compress it */   return 0; } sprintf(typestr,"%.3X",(((unsigned*)a)[2] & 0x000FFF00) >> 8); for (p=s;p<=s+strlen(s)-3;p+=3) { /* p+=3 to skip 3 hex type */   while (*p==':' || *p==';')     p++;   if (typestr[0]==toupper(p[0]) && typestr[1]==toupper(p[1]) && typestr[2]==toupper(p[2]))     return 1; } return 0;}#endif /* ?RISCOS *//* Note: a zip "entry" includes a local header (which includes the file   name), an encryption header if encrypting, the compressed data   and possibly an extended local header. */int zipup(z, y)struct zlist far *z;    /* zip entry to compress */FILE *y;                /* output file *//* Compress the file z->name into the zip entry described by *z and write   it to the file *y. Encrypt if requested.  Return an error code in the   ZE_ class.  Also, update tempzn by the number of bytes written. */{  iztimes f_utim;       /* UNIX GMT timestamps, filled by filetime() */  ulg tim;              /* time returned by filetime() */  ulg a = 0L;           /* attributes returned by filetime() */  char *b;              /* malloc'ed file buffer */  extent k = 0;         /* result of zread */  int l = 0;            /* true if this file is a symbolic link */  int m;                /* method for this entry */  ulg o = 0, p;         /* offsets in zip file */  long q = -3L;         /* size returned by filetime */  int r;                /* temporary variable */  ulg s = 0L;           /* size of compressed data */  int isdir;            /* set for a directory name */  int set_type = 0;     /* set if file type (ascii/binary) unknown */  ulg last_o;           /* used to check if we wrapped beyond what fseek can handle */  z->nam = strlen(z->iname);  isdir = z->iname[z->nam-1] == (char)0x2f; /* ascii[(unsigned)('/')] */  if ((tim = filetime(z->name, &a, &q, &f_utim)) == 0 || q == -3L)    return ZE_OPEN;  /* q is set to -1 if the input file is a device, -2 for a volume label */  if (q == -2L) {     isdir = 1;     q = 0;  } else if (isdir != ((a & MSDOS_DIR_ATTR) != 0)) {     /* don't overwrite a directory with a file and vice-versa */     return ZE_MISS;  }  z->att = (ush)UNKNOWN; /* will be changed later */  z->atx = 0; /* may be changed by set_extra_field() */  /* Free the old extra fields which are probably obsolete */  if (z->ext) {    free((zvoid *)(z->extra));  }  if (z->cext && z->extra != z->cextra) {    free((zvoid *)(z->cextra));  }  z->extra = z->cextra = NULL;  z->ext = z->cext = 0;#if defined(MMAP) || defined(BIG_MEM)  remain = (ulg)-1L; /* changed only for MMAP or BIG_MEM */#endif /* MMAP || BIG_MEM */#if (!defined(USE_ZLIB) || defined(MMAP) || defined(BIG_MEM))  window_size = 0L;#endif /* !USE_ZLIB || MMAP || BIG_MEM */  /* Select method based on the suffix and the global method */#ifndef RISCOS  m = special != NULL && suffixes(z->name, special) ? STORE : method;#else /* RISCOS  must set m after setting extra field */  m = method;#endif /* ?RISCOS */  /* Open file to zip up unless it is stdin */  if (strcmp(z->name, "-") == 0)  {    ifile = (ftype)zstdin;#if defined(MSDOS) || defined(__human68k__)    if (isatty(zstdin) == 0)  /* keep default mode if stdin is a terminal */      setmode(zstdin, O_BINARY);#endif    z->tim = tim;  }  else  {#if !(defined(VMS) && defined(VMS_PK_EXTRA))    if (extra_fields) {      /* create extra field and change z->att and z->atx if desired */      set_extra_field(z, &f_utim);#ifdef QLZIP      if(qlflag)          a |= (S_IXUSR) << 16;   /* Cross compilers don't set this */#endif#ifdef RISCOS      m = special != NULL && filetypes(z->extra, special) ? STORE : method;#endif /* RISCOS */    }#endif /* !(VMS && VMS_PK_EXTRA) */    l = issymlnk(a);    if (l) {      ifile = fbad;      m = STORE;    }    else if (isdir) { /* directory */      ifile = fbad;      m = STORE;      q = 0;    }#ifdef THEOS    else if (((a >> 16) & S_IFMT) == S_IFLIB) {   /* library */      ifile = fbad;      m = STORE;      q = 0;    }#endif    else {#ifdef CMS_MVS      if (bflag) {        if ((ifile = zopen(z->name, fhowb)) == fbad)           return ZE_OPEN;      }      else#endif /* CMS_MVS */      if ((ifile = zopen(z->name, fhow)) == fbad)         return ZE_OPEN;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -