C 不明确错误“;。。。未声明(此函数首次使用)“;

C 不明确错误“;。。。未声明(此函数首次使用)“;,c,gcc,mingw,C,Gcc,Mingw,无论出于何种原因,MinGW的gcc似乎无法找到该变量的“#define”块。完全错误是 .../mapped.c:396:28: error: '_zzip_strcasecmp' undeclared (first use in this function) c.文件的内容: /* * NOTE: this is part of libzzipmmapped (i.e. it is not libzzip). *

无论出于何种原因,MinGW的gcc似乎无法找到该变量的“#define”块。完全错误是

.../mapped.c:396:28: error: '_zzip_strcasecmp' undeclared (first use in this function)
c.文件的内容:

/*
 * NOTE: this is part of libzzipmmapped (i.e. it is not libzzip).
 *                                            ==================
 *
 * These routines are fully independent from the traditional zzip
 * implementation. They assume a readonly mmapped sharedmem block
 * representing a complete zip file. The functions show how to 
 * parse the structure, find files and return a decoded bytestream.
 *
 * These routines are a bit simple and really here for documenting
 * the way to access a zip file. The complexity of zip access comes
 * from staggered reading of bytes and reposition of a filepointer in
 * a big archive with lots of files and long compressed datastreams.
 * Plus varaints of drop-in stdio replacements, obfuscation routines,
 * auto fileextensions, drop-in dirent replacements, and so on...
 *
 * Author: 
 *      Guido Draheim <guidod@gmx.de>
 *
 * Copyright (c) 2003,2004,2006 Guido Draheim
 *          All rights reserved,
 *          use under the restrictions of the 
 *          Lesser GNU General Public License
 *          or alternatively the restrictions 
 *          of the Mozilla Public License 1.1
 */

#define _ZZIP_DISK_FILE_STRUCT 1

#ifdef __linux__
#define _GNU_SOURCE _glibc_developers_are_idiots_to_call_strndup_gnu_specific_
#endif

#include <zzip/mmapped.h>
#include <zzip/format.h>
#include <zzip/fetch.h>
#include <zzip/__mmap.h>
#include <zzip/__fnmatch.h>

#include <stdlib.h>
#include <sys/stat.h>

#if   defined ZZIP_HAVE_UNISTD_H
#include <unistd.h>
#elif defined ZZIP_HAVE_IO_H
#include <io.h>
#endif

#if   defined ZZIP_HAVE_STRING_H
#include <string.h>
#elif defined ZZIP_HAVE_STRINGS_H
#include <strings.h>
#endif


#if __STDC_VERSION__+0 > 199900L
#define ___
#define ____
#else
#define ___ {
#define ____ }
#endif

/** => zzip_disk_mmap
 * This function does primary initialization of a disk-buffer struct.
 */
int
zzip_disk_init(ZZIP_DISK* disk, void* buffer, zzip_size_t buflen)
{
    disk->buffer = (zzip_byte_t*) buffer;
    disk->endbuf = (zzip_byte_t*) buffer + buflen;
    disk->reserved = 0;
    disk->flags = 0;
    disk->mapped = 0;
    /* do not touch disk->user */
    /* do not touch disk->code */
    return 0;
}

/** => zzip_disk_mmap
 * This function allocates a new disk-buffer with => malloc(3)
 */
zzip__new__ ZZIP_DISK*
zzip_disk_new(void)
{
    ZZIP_DISK* disk = malloc(sizeof(disk));
    if (! disk) return disk;
    zzip_disk_init (disk, 0, 0);
    return disk;
}

/** turn a filehandle into a mmapped zip disk archive handle
 *
 * This function uses the given file-descriptor to detect the length of the 
 * file and calls the system => mmap(2) to put it in main memory. If it is
 * successful then a newly allocated ZZIP_DISK* is returned with 
 * disk->buffer pointing to the mapview of the zipdisk content.
 */
zzip__new__ ZZIP_DISK*
zzip_disk_mmap(int fd)
{
    struct stat st;
    if (fstat (fd, &st) || ! st.st_size) return 0;
    ___ ZZIP_DISK* disk = zzip_disk_new (); if (! disk) return 0;
    disk->buffer = _zzip_mmap (& disk->mapped, fd, 0, st.st_size);
    if (disk->buffer == MAP_FAILED) { free (disk); return 0; }
    disk->endbuf = disk->buffer + st.st_size;
    return disk; ____;
}

/** => zzip_disk_mmap
 * This function is the inverse of => zzip_disk_mmap and using the system
 * munmap(2) on the buffer area and => free(3) on the ZZIP_DISK structure.
 */
int
zzip_disk_munmap(ZZIP_DISK* disk)
{
    if (! disk) return 0;
    _zzip_munmap (disk->mapped, disk->buffer, disk->endbuf-disk->buffer);
    free (disk);
    return 0;
}

/** => zzip_disk_mmap
 *
 * This function opens the given archive by name and turn the filehandle 
 * to  => zzip_disk_mmap for bringing it to main memory. If it can not
 * be => mmap(2)'ed then we slurp the whole file into a newly => malloc(2)'ed
 * memory block. Only if that fails too then we return null. Since handling
 * of disk->buffer is ambigous it should not be snatched away please.
 */
ZZIP_DISK* zzip__new__
zzip_disk_open(char* filename)
{
#  ifndef O_BINARY
#  define O_BINARY 0
#  endif
    struct stat st;
    if (stat (filename, &st) || ! st.st_size) return 0;
    ___ int fd = open (filename, O_RDONLY|O_BINARY);
    if (fd <= 0) return 0;
    ___ ZZIP_DISK* disk = zzip_disk_mmap (fd);
    if (disk) return disk;
    ___ zzip_byte_t* buffer = malloc (st.st_size);
    if (! buffer) return 0;
    if ((st.st_size == read (fd, buffer, st.st_size)) &&
    (disk = zzip_disk_new ())) 
    {
    disk->buffer = buffer;
    disk->endbuf = buffer+st.st_size;
    disk->mapped = -1;
    }else free (buffer);
    return disk; ____;____;____;
}

/** => zzip_disk_mmap
 * 
 * This function will release all data needed to access a (mmapped)
 * zip archive, including any malloc()ed blocks, sharedmem mappings
 * and it dumps the handle struct as well.
 */
int
zzip_disk_close(ZZIP_DISK* disk)
{
    if (! disk) return 0;
    if (disk->mapped != -1) return zzip_disk_munmap (disk);
    free (disk->buffer);
    free (disk);
    return 0;
}

/* ====================================================================== */
/*                      helper functions                                  */

#ifdef ZZIP_HAVE_STRNDUP
#define _zzip_strndup strndup
#else
/* if your system does not have strndup: */
zzip__new__ static char* _zzip_strndup(char* p, size_t maxlen)
{
    if (! p) return 0;
    ___ zzip_byte_t* r = malloc (maxlen+1);
    if (! r) return r;
    strncpy (r, p, maxlen);
    r[maxlen] = '\0';
    return r; ____;
}
#endif

#if defined ZZIP_HAVE_STRCASECMP || defined strcasecmp
#define _zzip_strcasecmp strcasecmp
#else
/* if your system does not have strcasecmp: */
static int _zzip_strcasecmp(char* __zzip_restrict a, char* _zzip_restrict b)
{
    if (! a) return (b) ? 1 : 0;
    if (! b) return -1;
    while (1) 
    {
    int v = tolower(*a) - tolower(*b);
    if (v) return v;
    if (! *a) return 1;
    if (! *b) return -1;
    a++; b++;
    }
}
#endif

/** helper functions for (mmapped) zip access api
 *
 * This function augments the other zzip_disk_entry_* helpers: here we move 
 * a disk_entry pointer (as returned by _find* functions) into a pointer to
 * the data block right after the file_header. Only disk->buffer would be
 * needed to perform the seek but we check the mmapped range end as well.
 */
zzip_byte_t*
zzip_disk_entry_to_data(ZZIP_DISK* disk, struct zzip_disk_entry* entry)
{
    struct zzip_file_header* file = 
    zzip_disk_entry_to_file_header(disk, entry);
    if (file) return zzip_file_header_to_data (file);
    return 0;
}

/** => zzip_disk_entry_to_data
 * This function does half the job of => zzip_disk_entry_to_data where it
 * can augment with => zzip_file_header_to_data helper from format/fetch.h
 */
struct zzip_file_header*
zzip_disk_entry_to_file_header(ZZIP_DISK* disk, struct zzip_disk_entry* entry)
{
    zzip_byte_t* file_header = /* (struct zzip_file_header*) */
    (disk->buffer + zzip_disk_entry_fileoffset (entry));
    if (disk->buffer > file_header || file_header >= disk->endbuf) 
    return 0;
    return (struct zzip_file_header*) file_header;
}

/** => zzip_disk_entry_to_data
 * This function is a big helper despite its little name: in a zip file the
 * encoded filenames are usually NOT zero-terminated but for common usage
 * with libc we need it that way. Secondly, the filename SHOULD be present
 * in the zip central directory but if not then we fallback to the filename
 * given in the file_header of each compressed data portion.
 */
zzip__new__ char*
zzip_disk_entry_strdup_name(ZZIP_DISK* disk, struct zzip_disk_entry* entry)
{
    if (! disk || ! entry) return 0;

    ___ char* name; zzip_size_t len;
    struct zzip_file_header* file;
    if ((len = zzip_disk_entry_namlen (entry)))
    name = zzip_disk_entry_to_filename (entry);
    else if ((file = zzip_disk_entry_to_file_header (disk, entry)) &&
         (len = zzip_file_header_namlen (file)))
    name = zzip_file_header_to_filename (file);
    else
    return 0;

    if ((zzip_byte_t*) name < disk->buffer || 
    (zzip_byte_t*) name+len > disk->endbuf)
    return 0;

    return  _zzip_strndup (name, len); ____;
}

/** => zzip_disk_entry_to_data
 * This function is similar creating a reference to a zero terminated
 * string but it can only exist in the zip central directory entry.
 */
zzip__new__ char*
zzip_disk_entry_strdup_comment(ZZIP_DISK* disk, struct zzip_disk_entry* entry)
{
    if (! disk || ! entry) return 0;

    ___ char* text; zzip_size_t len;
    if ((len = zzip_disk_entry_comment (entry)))
    text = zzip_disk_entry_to_comment (entry);
    else
    return 0;

    if ((zzip_byte_t*) text < disk->buffer || 
    (zzip_byte_t*) text+len > disk->endbuf)
    return 0;

    return  _zzip_strndup (text, len); ____;
}

/* ====================================================================== */

/** => zzip_disk_findfile
 *
 * This function is the first call of all the zip access functions here.
 * It contains the code to find the first entry of the zip central directory. 
 * Here we require the mmapped block to represent a real zip file where the
 * disk_trailer is _last_ in the file area, so that its position would be at 
 * a fixed offset from the end of the file area if not for the comment field 
 * allowed to be of variable length (which needs us to do a little search
 * for the disk_tailer). However, in this simple implementation we disregard 
 * any disk_trailer info telling about multidisk archives, so we just return
 * a pointer to the zip central directory.
 * 
 * For an actual means, we are going to search backwards from the end 
 * of the mmaped block looking for the PK-magic signature of a 
 * disk_trailer. If we see one then we check the rootseek value to
 * find the first disk_entry of the root central directory. If we find
 * the correct PK-magic signature of a disk_entry over there then we 
 * assume we are done and we are going to return a pointer to that label.
 *
 * The return value is a pointer to the first zzip_disk_entry being checked
 * to be within the bounds of the file area specified by the arguments. If
 * no disk_trailer was found then null is returned, and likewise we only 
 * accept a disk_trailer with a seekvalue that points to a disk_entry and 
 * both parts have valid PK-magic parts. Beyond some sanity check we try to
 * catch a common brokeness with zip archives that still allows us to find
 * the start of the zip central directory.
 */
struct zzip_disk_entry*
zzip_disk_findfirst(ZZIP_DISK* disk)
{
    if (disk->buffer > disk->endbuf-sizeof(struct zzip_disk_trailer))
    return 0;
    ___ zzip_byte_t* p = disk->endbuf-sizeof(struct zzip_disk_trailer);
    for (; p >= disk->buffer ; p--)
    {
    zzip_byte_t* root; /* (struct zzip_disk_entry*) */
    if (zzip_disk_trailer_check_magic(p)) {
        root =  disk->buffer + zzip_disk_trailer_get_rootseek (
        (struct zzip_disk_trailer*)p);
        if (root > p) 
        {   /* the first disk_entry is after the disk_trailer? can't be! */
        zzip_size_t rootsize = zzip_disk_trailer_get_rootsize (
            (struct zzip_disk_trailer*)p);
        if (disk->buffer+rootsize > p) continue;
        /* a common brokeness that can be fixed: we just assume the
         * central directory was written directly before the trailer:*/
        root = p - rootsize;
        }
    } else if (zzip_disk64_trailer_check_magic(p)) {
        if (sizeof(void*) < 8) return 0; /* EOVERFLOW */
        root =  disk->buffer + zzip_disk64_trailer_get_rootseek (
        (struct zzip_disk64_trailer*)p);
        if (root > p) continue; 
    } else continue;

    if (root < disk->buffer) continue;
    if (zzip_disk_entry_check_magic(root)) 
        return (struct zzip_disk_entry*) root;
    }____;
    return 0;
}

/** => zzip_disk_findfile
 *
 * This function takes an existing disk_entry in the central root directory
 * (e.g. from zzip_disk_findfirst) and returns the next entry within in
 * the given bounds of the mmapped file area.
 */
struct zzip_disk_entry*
zzip_disk_findnext(ZZIP_DISK* disk, struct zzip_disk_entry* entry)
{
    if ((zzip_byte_t*)entry < disk->buffer || 
    (zzip_byte_t*)entry > disk->endbuf-sizeof(entry) ||
    ! zzip_disk_entry_check_magic (entry) ||
    zzip_disk_entry_sizeto_end (entry) > 64*1024)
    return 0;
    entry = zzip_disk_entry_to_next_entry (entry);
    if ((zzip_byte_t*)entry > disk->endbuf-sizeof(entry) ||
    ! zzip_disk_entry_check_magic (entry) ||
    zzip_disk_entry_sizeto_end (entry) > 64*1024 ||
    zzip_disk_entry_skipto_end (entry) + sizeof(entry) > disk->endbuf)
    return 0;
    else
    return entry;
}

/** search for files in the (mmapped) zip central directory
 *
 * This function is given a filename as an additional argument, to find the 
 * disk_entry matching a given filename. The compare-function is usually 
 * strcmp or strcasecmp or perhaps strcoll, if null then strcmp is used. 
 * - use null as argument for "after"-entry when searching the first 
 * matching entry, otherwise the last returned value if you look for other
 * entries with a special "compare" function (if null then a doubled search
 * is rather useless with this variant of _findfile).
 */
struct zzip_disk_entry*
zzip_disk_findfile(ZZIP_DISK* disk, char* filename, 
            struct zzip_disk_entry* after, zzip_strcmp_fn_t compare)
{
    struct zzip_disk_entry* entry = (! after ? zzip_disk_findfirst (disk) 
                     : zzip_disk_findnext (disk, after));
    if (! compare) 
    compare = (zzip_strcmp_fn_t)( (disk->flags&1) ? 
                      (_zzip_strcasecmp) : (strcmp));
    for (; entry ; entry = zzip_disk_findnext (disk, entry))
    {
    /* filenames within zip files are often not null-terminated! */
    char* realname = zzip_disk_entry_strdup_name (disk, entry);
    if (realname && ! compare(filename, realname))
    {
        free (realname);
        return entry;
    }
    free (realname);
    }
    return 0;
}

/** => zzip_disk_findfile
 *
 * This function uses a compare-function with an additional argument
 * and it is called just like fnmatch(3) from POSIX.2 AD:1993), i.e.
 * the argument filespec first and the ziplocal filename second with
 * the integer-flags put in as third to the indirect call. If the
 * platform has fnmatch available then null-compare will use that one
 * and otherwise we fall back to mere strcmp, so if you need fnmatch
 * searching then please provide an implementation somewhere else.
 * - use null as argument for "after"-entry when searching the first 
 * matching entry, or the last disk_entry return-value to find the
 * next entry matching the given filespec.
 */
struct zzip_disk_entry*
zzip_disk_findmatch(ZZIP_DISK* disk, char* filespec, 
            struct zzip_disk_entry* after,
            zzip_fnmatch_fn_t compare, int flags)
{
    struct zzip_disk_entry* entry = (! after ? zzip_disk_findfirst (disk) 
                     : zzip_disk_findnext (disk, after));
    if (! compare) { 
    compare = (zzip_fnmatch_fn_t) _zzip_fnmatch; 
    if (disk->flags&1) disk->flags |= _zzip_fnmatch_CASEFOLD;
    }
    for (; entry ; entry = zzip_disk_findnext (disk, entry))
    {
    /* filenames within zip files are often not null-terminated! */
    char* realname = zzip_disk_entry_strdup_name(disk, entry);
    if (realname && ! compare(filespec, realname, flags))
    {
        free (realname);
        return entry;
    }
    free (realname);
    }
    return 0;
}

/* ====================================================================== */

/** => zzip_disk_fopen
 *
 * the ZZIP_DISK_FILE* is rather simple in just encapsulating the
 * arguments given to this function plus a zlib deflate buffer.
 * Note that the ZZIP_DISK pointer does already contain the full
 * mmapped file area of a zip disk, so open()ing a file part within
 * that area happens to be a lookup of its bounds and encoding. That
 * information is memorized on the ZZIP_DISK_FILE so that subsequent
 * _read() operations will be able to get the next data portion or
 * return an eof condition for that file part wrapped in the zip archive.
 */
zzip__new__ ZZIP_DISK_FILE*
zzip_disk_entry_fopen (ZZIP_DISK* disk, ZZIP_DISK_ENTRY* entry)
{
    /* keep this in sync with zzip_mem_entry_fopen */
    struct zzip_file_header* header = 
    zzip_disk_entry_to_file_header (disk, entry);
    if (! header) return 0;
    ___ ZZIP_DISK_FILE* file = malloc(sizeof(ZZIP_DISK_FILE));
    if (! file) return file;
    file->buffer = disk->buffer;
    file->endbuf = disk->endbuf;
    file->avail = zzip_file_header_usize (header);

    if (! file->avail || zzip_file_header_data_stored (header))
    { file->stored = zzip_file_header_to_data (header); return file; }

    file->stored = 0;
    file->zlib.opaque = 0;
    file->zlib.zalloc = Z_NULL;
    file->zlib.zfree = Z_NULL;
    file->zlib.avail_in = zzip_file_header_csize (header);
    file->zlib.next_in = zzip_file_header_to_data (header);

    if (! zzip_file_header_data_deflated(header) ||
        inflateInit2(&file->zlib, -MAX_WBITS) != Z_OK)
        { free (file); return 0; }

    return file;
    ____;
}

/** openening a file part wrapped within a (mmapped) zip archive
 *
 * This function opens a file found by name, so it does a search into
 * the zip central directory with => zzip_disk_findfile and whatever
 * is found first is given to => zzip_disk_entry_fopen
 */
zzip__new__ ZZIP_DISK_FILE*
zzip_disk_fopen (ZZIP_DISK* disk, char* filename)
{
    ZZIP_DISK_ENTRY* entry = zzip_disk_findfile (disk, filename, 0, 0);
    if (! entry) return 0; else return zzip_disk_entry_fopen (disk, entry);
}


/** => zzip_disk_fopen
 *
 * This function reads more bytes into the output buffer specified as
 * arguments. The return value is null on eof or error, the stdio-like
 * interface can not distinguish between these so you need to check
 * with => zzip_disk_feof for the difference.
 */
zzip_size_t
zzip_disk_fread (void* ptr, zzip_size_t sized, zzip_size_t nmemb,
         ZZIP_DISK_FILE* file)
{
    zzip_size_t size = sized*nmemb;
    if (size > file->avail) size = file->avail;
    if (file->stored)
    {
    memcpy (ptr, file->stored, size);
    file->stored += size;
    file->avail -= size;
    return size;
    }

    file->zlib.avail_out = sized*nmemb;
    file->zlib.next_out = ptr;
    ___ zzip_size_t total_old = file->zlib.total_out;
    ___ int err = inflate (& file->zlib, Z_NO_FLUSH);
    if (err == Z_STREAM_END)
    file->avail = 0;
    else if (err == Z_OK)
    file->avail -= file->zlib.total_out - total_old;
    else
    return 0;
    return file->zlib.total_out - total_old;
    ____;____;
}

/** => zzip_disk_fopen
 * This function releases any zlib decoder info needed for decompression
 * and dumps the ZZIP_DISK_FILE* then.
 */
int
zzip_disk_fclose (ZZIP_DISK_FILE* file)
{
    if (! file->stored)
    inflateEnd (& file->zlib);
    free (file);
    return 0;
}

/** => zzip_disk_fopen
 *
 * This function allows to distinguish an error from an eof condition. 
 * Actually, if we found an error but we did already reach eof then we
 * just keep on saying that it was an eof, so the app can just continue.
 */ 
int
zzip_disk_feof (ZZIP_DISK_FILE* file)
{
    return ! file || ! file->avail;
}
/*
*注意:这是libzzipmap的一部分(即它不是libzzip)。
*                                            ==================
*
*这些例程完全独立于传统的zzip
*实施。它们假定一个只读的mmappedsharedmem块
*表示完整的zip文件。这些函数显示了如何
*解析结构,查找文件并返回解码的ByTestStream。
*
*这些例程有点简单,在这里真正用于记录
*访问zip文件的方法。zip访问的复杂性随之而来
*从交错读取字节和在中重新定位文件指针
*包含大量文件和长压缩数据流的大型存档。
*加上替换stdio、模糊处理程序、,
*自动文件扩展、插入式目录替换等。。。
*
*作者:
*吉多德拉海姆
*
*版权所有(c)200320042006 Guido Draheim
*保留所有权利,
*在以下限制下使用:
*小GNU通用公共许可证
*或者是限制
*Mozilla公共许可证1.1的
*/
#定义磁盘文件结构1
#ifdef_uuuLinux__
#定义GNU源代码glibc开发者都是白痴称为特定GNU_
#恩迪夫
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#如果定义为ZZIP,则具有UNISTD
#包括
#如果你有
#包括
#恩迪夫
#如果定义了ZZIP,则具有字符串
#包括
#elif定义的ZZIP有字符串
#包括
#恩迪夫
#如果STDC版本>199900L
#定义___
#定义____
#否则
#定义{
#定义{{{}
#恩迪夫
/**=>zzip\u磁盘\u mmap
*此函数主要初始化磁盘缓冲区结构。
*/
int
zzip_disk_init(zzip_disk*disk,void*buffer,zzip_size_t buflen)
{
磁盘->缓冲区=(zzip_字节_t*)缓冲区;
disk->endbuf=(zzip_byte_t*)缓冲区+buflen;
磁盘->保留=0;
磁盘->标志=0;
磁盘->映射=0;
/*请勿触摸磁盘->用户*/
/*请勿触摸磁盘->代码*/
返回0;
}
/**=>zzip\u磁盘\u mmap
*此函数使用=>malloc(3)分配新的磁盘缓冲区
*/
新磁盘*
zzip_磁盘_新(无效)
{
ZZIP_DISK*DISK=malloc(sizeof(DISK));
如果(!disk)返回磁盘;
zzip_disk_init(disk,0,0);
返回盘;
}
/**将文件句柄转换为映射的zip磁盘存档句柄
*
*此函数使用给定的文件描述符来检测文件的长度
*文件并调用system=>mmap(2)将其放入主内存。如果是
*成功,则返回一个新分配的ZZIP_磁盘*,带有
*磁盘->缓冲区指向zipdisk内容的地图视图。
*/
新磁盘*
磁盘映射(内部fd)
{
结构统计;
如果(fstat(fd,&st)| |!st.st|u size)返回0;
___ZZIP_DISK*DISK=ZZIP_DISK_new();如果(!DISK)返回0;
磁盘->缓冲区=\uzzip\ummap(&disk->映射,fd,0,st.st\u大小);
如果(磁盘->缓冲区==MAP_失败){空闲(磁盘);返回0;}
disk->endbuf=disk->buffer+st.st\u size;
返回磁盘;
}
/**=>zzip\u磁盘\u mmap
*此函数与=>zzip\u disk\u mmap和使用系统相反
*缓冲区上的munmap(2)和ZZIP_磁盘结构上的=>free(3)。
*/
int
zzip_disk_munmap(zzip_disk*disk)
{
如果(!disk)返回0;
_zzip_munmap(磁盘->映射,磁盘->缓冲区,磁盘->尾端磁盘->缓冲区);
空闲(磁盘);
返回0;
}
/**=>zzip\u磁盘\u mmap
*
*此函数用于按名称打开给定的存档,并旋转文件句柄
*to=>zzip\u disk\u mmap,用于将其带到主内存。如果不能
*be=>mmap(2)'ed然后我们将整个文件拼凑成一个新的=>malloc(2)'ed
*内存块。只有当这也失败时,我们才返回null。自处理
*磁盘->缓冲区模棱两可,请不要抢走。
*/
ZZIP_磁盘*ZZIP_新__
zzip_磁盘_打开(字符*文件名)
{
#ifndef O_二进制文件
#定义O_二进制0
#恩迪夫
结构统计;
if(stat(filename,&st)| |!st.st_size)返回0;
___int fd=打开(文件名,O|RDONLY | O|u二进制文件);
if(fd buffer=buffer;
disk->endbuf=缓冲区+st.st\u大小;
磁盘->映射=-1;
}其他自由(缓冲);
返回磁盘;
}
/**=>zzip\u磁盘\u mmap
* 
*此功能将释放访问(MMAP)所需的所有数据
*zip存档,包括任何malloc()ed块、sharedmem映射
*它还转储句柄结构。
*/
int
zzip_磁盘_关闭(zzip_磁盘*磁盘)
{
如果(!disk)返回0;
if(disk->mapped!=-1)返回zzip\u disk\u munmap(disk);
空闲(磁盘->缓冲区);
空闲(磁盘);
返回0;
}
/* ====================================================================== */
/*辅助函数*/
#如果你有
#定义_zzip_strndup strndup
#否则
/*如果您的系统没有strndup:*/
zzip\uuuu新\uuuuu静态字符*\uZZIP\u strndup(字符*p,大小\u t最大值)
{
如果(!p)返回0;
___zzip_字节_t*r=malloc(maxlen+1);
如果(!r)返回r;
strncpy(r,p,maxlen);
r[maxlen]='\0';
返回r;u_;;
}
#恩迪夫
#如果定义了ZZIP,则有定义的STRCACMP
#定义_zzip_stracecmp stracecmp
#否则
/*如果您的系统没有STRCAECMP:*/
静态int zzip rcasecmp(字符*zzip ;限制a,字符*zzip ;限制b)
{
如果(!a)返回(b)?1:0;
如果(!b)返回-1;
而(1)
{
int v=通行费(*a)-通行费(*b);
如果(v)返回v;
如果(!*a)返回1;
如果(!*b)返回-1;
a++;b++;
}
}
#恩迪夫
/**(mmapped)zip访问api的助手函数
*
*此函数增强了其他zzip_磁盘_条目*帮助程序:我们开始
*磁盘项指针(由_find*函数返回)指向
*文件头后面的数据块。将只显示磁盘->缓冲区
*需要执行
#define _zzip_strcasecmp strcasecmp
_zzip_strcasecmp( /* whatever */ )
compare = (zzip_strcmp_fn_t)( (disk->flags&1) ? 
                  (_zzip_strcasecmp) : (strcmp));
compare = (zzip_strcmp_fn_t)( (disk->flags&1) ? 
                _zzip_strcasecmp : strcmp);