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

📄 macos.c

📁 给出了 zip 压缩算法的完整实现过程。
💻 C
📖 第 1 页 / 共 2 页
字号:
char *in2ex(char *n)    /* internal file name *//* Convert the zip file name to an external file name, returning the malloc'ed   string or NULL if not enough memory. */{  char *x;              /* external file name */  AssertStr(n,n)  if ((x = malloc(strlen(n) + 1)) == NULL)    return NULL;  RfDfFilen2Real(x, n, MacZip.MacZipMode, MacZip.DataForkOnly,                 &MacZip.CurrentFork);  return x;}/*** Process on filenames. This function will be called to collect** the filenames.*/int procname(char *filename,         /* name to process */             int caseflag)           /* true to force case-sensitive match                                        (always false on a Mac) *//* Process a name .  Return   an error code in the ZE_ class. */{  int rc;                /* matched flag */AssertBool(caseflag,"caseflag")AssertStr(filename,filename)        /* add or remove name of file */rc = newname(filename, MacZip.isDirectory, caseflag);return rc;}ulg filetime(char *f,                /* name of file to get info on */ulg *a,                 /* return value: file attributes */long *n,                /* return value: file size */iztimes *t)             /* return value: access, modific. and creation times *//* If file *f does not exist, return 0.  Else, return the file's last   modified date and time as an MSDOS date and time.  The date and   time is returned in a long with the date most significant to allow   unsigned integer comparison of absolute times.  Also, if a is not   a NULL pointer, store the file attributes there, with the high two   bytes being the Unix attributes, and the low byte being a mapping   of that to DOS attributes.  If n is not NULL, store the file size   there.  If t is not NULL, the file's access, modification and creation   times are stored there as UNIX time_t values.   If f is "-", use standard input as the file. If f is a device, return   a file size of -1 */{  struct stat s;        /* results of stat() */  AssertStr(f,f)  if (strlen(f) == 0) return 0;  if (SSTAT(f, &s) != 0)             /* Accept about any file kind including directories              * (stored with trailing : with -r option)              */    return 0;  if (a != NULL) {    *a = ((ulg)s.st_mode << 16) | !(s.st_mode & S_IWRITE);    if (MacZip.isDirectory) {      *a |= MSDOS_DIR_ATTR;    }  }  if (n != NULL)    *n = (s.st_mode & UNX_IFMT) == UNX_IFREG ? s.st_size : -1L;  if (t != NULL) {    t->atime = s.st_atime;    t->mtime = s.st_mtime;    t->ctime = s.st_ctime;   /* on Mac, st_ctime contains creation time! */  }  return unix2dostime(&s.st_mtime);}void stamp(char *f, ulg d)/* char *f;                name of file to change *//* ulg d;                  dos-style time to change it to *//* Set last updated and accessed time of file f to the DOS time d. */{  time_t u[2];          /* argument for utime() */f = f;  /* Convert DOS time to time_t format in u */  u[0] = u[1] = dos2unixtime(d);/*  utime(f, u);  */}/***  return only the longest part of the path:**  second parameter: Volume:test folder:second folder:**  third parameter:  Volume:test folder:second folder:third folder:file**  result will be:   third folder:file**  first parameter:  contains string buffer that will be used to prepend**                    the "resource mark" part in front of the result when**                    a resource fork is processed in "M3" mode.***/char *StripPartialDir(char *CompletePath,                      const char *PartialPath, const char *FullPath){const char *tmpPtr1 = PartialPath;const char *tmpPtr2 = FullPath;int     result;Assert_it(CompletePath,"StripPartialDir","")AssertStrNoOverlap(FullPath,PartialPath,PartialPath)if (MacZip.DataForkOnly)        {        tmpPtr2 += strlen(tmpPtr1);        return (char *)tmpPtr2;        }switch (MacZip.MacZipMode)    {    case JohnnyLee_EF:        {        tmpPtr2 += strlen(tmpPtr1);        return (char *)tmpPtr2;        break;        }    case NewZipMode_EF:        {           /* determine Fork type */        result = strncmp(FullPath, ResourceMark, sizeof(ResourceMark)-2);        if (result != 0)            {                               /* data fork  */            MacZip.CurrentFork = DataFork;            tmpPtr2 += strlen(tmpPtr1);             return (char *)tmpPtr2;            }        else            {                                /* resource fork  */            MacZip.CurrentFork = ResourceFork;            sstrcpy(CompletePath, ResourceMark);            tmpPtr2 += strlen(tmpPtr1);            tmpPtr2 += sizeof(ResourceMark);            sstrcat(CompletePath, tmpPtr2);            return (char *)CompletePath;            }        break;        }    } return NULL;    /* function should never reach this point */}/*** Init all global variables** Must be called for each zip-run*/void ZipInitAllVars(void){getcwd(MacZip.CurrentPath, sizeof(MacZip.CurrentPath));/* MacZip.MacZipMode = JohnnyLee_EF;     */MacZip.MacZipMode = NewZipMode_EF;MacZip.DataForkOnly = false;MacZip.CurrentFork = NoFork;MacZip.StoreFoldersAlso = false;MacZip.FoundFiles = 0;MacZip.FoundDirectories = 0;MacZip.RawCountOfItems = 0;MacZip.BytesOfData = 0;MacZip.StoreFullPath = false;MacZip.StatingProgress = false;MacZip.IncludeInvisible = false;MacZip.isMacStatValid = false;MacZip.CurrTextEncodingBase = FontScript();MacZip.HaveGMToffset = false;createTime = TickCount();estTicksToFinish = -1;updateTicks = 0;/* init some functions */IsZipFile(NULL);destroy(NULL);deletedir(NULL);ShowCounter(true);extra_fields = 1;error_level = 0;count_of_Zippedfiles = 0;}/*** Get the findercomment and store it as file-comment in the Zip-file***/char *GetComment(char *filename){OSErr       err;static char buffer[NAME_MAX];char buffer2[NAME_MAX];char *tmpPtr;if (filename == NULL) return NULL;    /* now we can convert Unix-Path in HFS-Path */for (tmpPtr = filename; *tmpPtr; tmpPtr++)    if (*tmpPtr == '/')      *tmpPtr = ':';if (MacZip.StoreFullPath)    {  /* filename is already a fullpath */    sstrcpy(buffer,filename);    }else    {  /* make a fullpath */    sstrcpy(buffer,MacZip.SearchDir);    sstrcat(buffer,filename);    }/* make fullpath and get FSSpec *//* Unfortunately: I get only the converted filename here *//* so filenames with extended characters can not be found  */GetCompletePath(buffer2,buffer, &MacZip.fileSpec, &err);printerr("GetCompletePath:",(err != -43) && (err != -120) && (err != 0) ,          err,__LINE__,__FILE__,buffer);err = FSpDTGetComment(&MacZip.fileSpec, (unsigned char *) buffer);printerr("FSpDTGetComment:", (err != -5012) && (err != 0), err,         __LINE__, __FILE__, filename);P2CStr((unsigned char *) buffer);if (err == -5012) return NULL;  /* no finder-comments found */if (noisy) printf("\n%32s -> %s",filename, buffer);/*Beside the script change we need only to change 0x0d in 0x0aso the last two arguments are not needed and does nothing.*/MakeCompatibleString(buffer, 0x0d, 0x0a, ' ', ' ',                     MacZip.CurrTextEncodingBase);return buffer;}/*** Print a progress indicator for stating the files***/void PrintStatProgress(char *msg){if (!noisy) return;     /* do no output if noisy is false */MacZip.StatingProgress = true;if (strcmp(msg,"done") == 0)    {    MacZip.StatingProgress = false;    printf("\n ... done \n\n");    }else printf("\n %s",msg);}void InformProgress(const long progressMax, const long progressSoFar ){int curr_percent;char no_time[5] = "...";curr_percent = percent(progressMax, progressSoFar);if (curr_percent < 95)    {    estTicksToFinish = EstimateCompletionTime(progressMax,                                                  progressSoFar, curr_percent);    }else    {    rightStatusString(no_time);    leftStatusString(no_time);    }updateTicks = TickCount() + 60;return;}void ShowCounter(Boolean reset){static char statusline[100];static unsigned long filecount = 0;if (reset)        {        filecount = 0;        return;        }if (noisy)    {    sprintf(statusline, "%6d", filecount++);    rightStatusString(statusline);    }}static long EstimateCompletionTime(const long progressMax,                                const long progressSoFar,                                unsigned char curr_percent){    long  max = progressMax, value = progressSoFar;    static char buf[100];    unsigned long ticksTakenSoFar = TickCount() - createTime;    float currentRate = (float) ticksTakenSoFar / (float) value;    long  newEst = (long)( currentRate * (float)( max - value ));    sprintf(buf, "%d [%d%%]",progressSoFar, curr_percent);    rightStatusString(buf);    estTicksToFinish = newEst;    UpdateTimeToComplete();return estTicksToFinish;}static void UpdateTimeToComplete(void){    short       days, hours, minutes, seconds;    char    estStr[255];    Str15   xx, yy;    short   idx = 0;    if ( estTicksToFinish == -1 )        return;    days    =   estTicksToFinish / 5184000L;    hours   = ( estTicksToFinish - ( days * 5184000L )) / 216000L;    minutes = ( estTicksToFinish - ( days * 5184000L ) -              ( hours * 216000L )) / 3600L;    seconds = ( estTicksToFinish - ( days * 5184000L ) -              ( hours * 216000L ) - ( minutes * 3600L )) / 60L;        xx[0] = 0;        yy[0] = 0;        if ( days )        {            /* "more than 24 hours" */            idx = 1;            goto setEstTimeStr;        }        if ( hours >= 8 )        {            /* "more than x hours" */            NumToString( hours, xx );            idx = 2;            goto setEstTimeStr;        }        if ( estTicksToFinish > 252000L  )      /* > 1hr, 10 minutes */        {            /* "about x hours, y minutes" */            NumToString( hours, xx );            NumToString( minutes, yy );            idx = 3;            goto setEstTimeStr;        }        if ( estTicksToFinish > 198000L )   /* > 55 minutes */        {            /* "about an hour" */            idx = 4;            goto setEstTimeStr;        }        if ( estTicksToFinish > 144000L )   /* > 40 minutes */        {            /* "less than an hour" */            idx = 5;            goto setEstTimeStr;        }        if ( estTicksToFinish > 4200L )     /* > 1 minute, 10 sec */        {            /* "about x minutes, y seconds */            NumToString( minutes, xx );            NumToString( seconds, yy );            if ( minutes == 1 )                idx = 11;            else                idx = 6;            goto setEstTimeStr;        }        if ( estTicksToFinish > 3000L )     /* > 50 seconds */        {            /* "about a minute" */            idx = 7;            goto setEstTimeStr;        }        if ( estTicksToFinish > 1500L )     /* > 25 seconds */        {            /* "less than a minute" */            idx = 8;            goto setEstTimeStr;        }        if ( estTicksToFinish > 120L )      /* > 2 seconds */        {            NumToString( seconds, xx );            idx = 9;            goto setEstTimeStr;        }        idx = 10;    setEstTimeStr:        sprintf(estStr,Time_Est_strings[idx],P2CStr(xx),P2CStr(yy));        leftStatusString((char *)estStr);}/*** Just return the zip version***/char *GetZipVersionsInfo(void){static char ZipVersion[100];sprintf(ZipVersion, "Zip Module\n%d.%d%d%s of %s", Z_MAJORVER, Z_MINORVER,        Z_PATCHLEVEL, Z_BETALEVEL, REVDATE);return ZipVersion;}#ifndef USE_SIOUX/*** Just return the copyright message***/char *GetZipCopyright(void){static char CopyR[300];sstrcpy(CopyR, copyright[0]);sstrcat(CopyR, copyright[1]);sstrcat(CopyR, "\r\rPlease send bug reports to the authors at\r"\              "Zip-Bugs@lists.wku.edu");return CopyR;}/*** Just return the compilers date/time***/char *GetZipVersionLocal(void){static char ZipVersionLocal[50];sprintf(ZipVersionLocal, "[%s %s]", __DATE__, __TIME__);return ZipVersionLocal;}#endif  /*   #ifndef USE_SIOUX  */

⌨️ 快捷键说明

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