给出了 zip 压缩算法的完整实现过程。

源代码在线查看: riscos.c

软件大小: 940 K
上传用户: sun67512945
关键词: zip 压缩算法 过程
下载地址: 免注册下载 普通下载 VIP

相关代码

				/*				  Copyright (c) 1990-2005 Info-ZIP.  All rights reserved.								  See the accompanying file LICENSE, version 2004-May-22 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				*/				/* riscos.c */								#include 				#include 				#include 				#include "zip.h"				#include "riscos.h"								#define MAXEXT 256								/* External globals */				extern int scanimage;								/* Local globals (!?!?) */				char *exts2swap = NULL; /* Extensions to swap (actually, directory names) */								int stat(char *filename,struct stat *res)				{				 int attr;              /* object attributes */				 unsigned int load;     /* load address */				 unsigned int exec;     /* exec address */				 int type;              /* type: 0 not found, 1 file, 2 dir, 3 image */								 if (!res)				   return -1;								 if (SWI_OS_File_5(filename,&type,&load,&exec,(int *)&res->st_size,&attr)!=NULL)				   return -1;								 if (type==0)				   return -1;								 res->st_dev=0;				 res->st_ino=0;				 res->st_nlink=0;				 res->st_uid=1;				 res->st_gid=1;				 res->st_rdev=0;				 res->st_blksize=1024;								 res->st_mode = ((attr & 0001) 				                ((attr & 0020) >> 2) | ((attr & 0040) >> 4);								 switch (type) {				   case 1:                        /* File */				    res->st_mode |= S_IFREG;				    break;				   case 2:                        /* Directory */				    res->st_mode |= S_IFDIR | 0700;				    break;				   case 3:                        /* Image file */				    if (scanimage)				      res->st_mode |= S_IFDIR | 0700;				    else				      res->st_mode |= S_IFREG;				    break;				 }								 if ((((unsigned int) load) >> 20) == 0xfff) {     /* date stamped file */				   unsigned int t1, t2, tc;								   t1 = (unsigned int) (exec);				   t2 = (unsigned int) (load & 0xff);								   tc = 0x6e996a00U;				   if (t1 < tc)				     t2--;				   t1 -= tc;				   t2 -= 0x33;          /* 00:00:00 Jan. 1 1970 = 0x336e996a00 */								   t1 = (t1 / 100) + (t2 * 42949673U);  /* 0x100000000 / 100 = 42949672.96 */				   t1 -= (t2 / 25);             /* compensate for .04 error */								   res->st_atime = res->st_mtime = res->st_ctime = t1;				 }				 else				   res->st_atime = res->st_mtime = res->st_ctime = 0;								 return 0;				}								#ifndef SFX								DIR *opendir(char *dirname)				{				 DIR *thisdir;				 int type;				 int attr;				 os_error *er;								 thisdir=(DIR *)malloc(sizeof(DIR));				 if (thisdir==NULL)				   return NULL;								 thisdir->dirname=(char *)malloc(strlen(dirname)+1);				 if (thisdir->dirname==NULL) {				   free(thisdir);				   return NULL;				 }								 strcpy(thisdir->dirname,dirname);				 if (thisdir->dirname[strlen(thisdir->dirname)-1]=='.')				   thisdir->dirname[strlen(thisdir->dirname)-1]=0;								 if (er=SWI_OS_File_5(thisdir->dirname,&type,NULL,NULL,NULL,&attr),er!=NULL ||				     type				 {				   free(thisdir->dirname);				   free(thisdir);				   return NULL;				 }								 thisdir->buf=malloc(DIR_BUFSIZE);				 if (thisdir->buf==NULL) {				   free(thisdir->dirname);				   free(thisdir);				   return NULL;				 }								 thisdir->size=DIR_BUFSIZE;				 thisdir->offset=0;				 thisdir->read=0;								 return thisdir;				}								struct dirent *readdir(DIR *d)				{				 static struct dirent dent;								 if (d->read==0) {    /* no more objects read in the buffer */				   if (d->offset==-1) {    /* no more objects to read */				     return NULL;				   }								   d->read=255;				   if (SWI_OS_GBPB_9(d->dirname,d->buf,&d->read,&d->offset,DIR_BUFSIZE,NULL)!=NULL)				     return NULL;								   if (d->read==0) {				     d->offset=-1;				     return NULL;				   }				   d->read--;				   d->act=(char *)d->buf;				 }				 else {     /* some object is ready in buffer */				   d->read--;				   d->act=(char *)(d->act+strlen(d->act)+1);				 }								 strcpy(dent.d_name,d->act);				 dent.d_namlen=strlen(dent.d_name);								 return &dent;				}								void closedir(DIR *d)				{				 if (d->buf!=NULL)				   free(d->buf);				 if (d->dirname!=NULL)				   free(d->dirname);				 free(d);				}								int unlink(f)				char *f;                /* file to delete */				/* Delete the file *f, returning non-zero on failure. */				{				 os_error *er;				 char canon[256];				 int size=255;								 er=SWI_OS_FSControl_37(f,canon,&size);				 if (er==NULL) {				   er=SWI_OS_FSControl_27(canon,0x100);				 }				 else {				   er=SWI_OS_FSControl_27(f,0x100);				 }				 return (int)er;				}								int deletedir(char *d)				{				 int objtype;				 char *s;				 int len;				 os_error *er;								 len = strlen(d);				 if ((s = malloc(len + 1)) == NULL)				   return -1;								 strcpy(s,d);				 if (s[len-1]=='.')				   s[len-1]=0;								 if (er=SWI_OS_File_5(s,&objtype,NULL,NULL,NULL,NULL),er!=NULL) {				   free(s);				   return -1;				 }				 if (objtype				   /* this is a file or it doesn't exist */				   free(s);				   return -1;				 }								 if (er=SWI_OS_File_6(s),er!=NULL) {				   /* maybe this is a problem with the DDEUtils module, try to canonicalise the path */				   char canon[256];				   int size=255;								   if (er=SWI_OS_FSControl_37(s,canon,&size),er!=NULL) {				     free(s);				     return -1;				   }				   if (er=SWI_OS_File_6(canon),er!=NULL) {				     free(s);				     return -1;				   }				 }				 free(s);				 return 0;				}								#endif /* !SFX */								int chmod(char *file, int mode)				{				/*************** NOT YET IMPLEMENTED!!!!!! ******************/				/* I don't know if this will be needed or not... */				 file=file;				 mode=mode;				 return 0;				}								void setfiletype(char *fname,int ftype)				{				 char str[256];				 sprintf(str,"SetType %s &%3.3X",fname,ftype);				 SWI_OS_CLI(str);				}								void getRISCOSexts(char *envstr)				{				 char *envptr;                               /* value returned by getenv */								 envptr = getenv(envstr);				 if (envptr == NULL || *envptr == 0) return;								 exts2swap=malloc(1+strlen(envptr));				 if (exts2swap == NULL)				   return;								 strcpy(exts2swap, envptr);				}								int checkext(char *suff)				{				 register char *extptr=exts2swap;				 register char *suffptr;				 register int e,s;								 if (extptr != NULL) while(*extptr) {				   suffptr=suff;				   e=*extptr; s=*suffptr;				   while (e && e!=':' && s && s!='.' && s!='/' && e==s) {				     e=*++extptr; s=*++suffptr;				   }				   if (e==':') e=0;				   if (s=='.' || s=='/') s=0;				   if (!e && !s) {				     return 1;				   }				   while(*extptr!=':' && *extptr!='\0')    /* skip to next extension */				     extptr++;				   if (*extptr!='\0')				     extptr++;				 }				 return 0;				}								int swapext(char *name, char *exptr)				{				 char *ext;				 char *p1=exptr;				 char *p2;				 int extchar=*exptr;				 unsigned int i=0;								 while(*++p1 && *p1!='.' && *p1!='/')				   ;				 ext=malloc(i=p1-exptr);				 if (!ext)				   return 1;				 memcpy(ext, exptr+1, i);				 p2=exptr-1;				 p1=exptr+i-1;				 while(p2 >= name)				   *p1--=*p2--;				 strcpy(name,ext);				 *p1=(extchar=='/'?'.':'/');				 free(ext);				 return 0;				}								void remove_prefix(void)				{				 SWI_DDEUtils_Prefix(NULL);				}								void set_prefix(void)				{				 char *pref;				 int size=0;								 if (SWI_OS_FSControl_37("@",pref,&size)!=NULL)				   return;								 size=1-size;								 if (pref=malloc(size),pref!=NULL) {				   if (SWI_OS_FSControl_37("@",pref,&size)!=NULL) {				     free(pref);				     return;				   }								   if (SWI_DDEUtils_Prefix(pref)==NULL) {				     atexit(remove_prefix);				   }								   free(pref);				 }				}								#ifdef localtime				#  undef localtime				#endif								#ifdef gmtime				#  undef gmtime				#endif								/* Acorn's implementation of localtime() and gmtime()				 * doesn't consider the timezone offset, so we have to				 * add it before calling the library functions				 */								struct tm *riscos_localtime(const time_t *timer)				{				 time_t localt=*timer;								 localt+=SWI_Read_Timezone()/100;								 return localtime(&localt);				}								struct tm *riscos_gmtime(const time_t *timer)				{				 time_t localt=*timer;								 localt+=SWI_Read_Timezone()/100;								 return gmtime(&localt);				}												int riscos_fseek(FILE *fd, long offset, int whence)				{				  int ret;				  switch (whence)				  {				    case SEEK_END:				      ret = (fseek) (fd, 0, SEEK_END);				      if (ret)				        return ret;				      /* fall through */				    case SEEK_CUR:				      offset += ftell (fd);				      /* fall through */				    default: /* SEEK_SET */				      return (fseek) (fd, offset < 0 ? 0 : offset, SEEK_SET);				  }				}							

相关资源