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

📄 fpopen.c

📁 进行Palm开发时
💻 C
字号:
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ *  * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. *  * The Original Code is par & libprc, released May 13, 1999. *  * The Initial Developer of the Original Code is David Williams, * http://www.djw.org.  Portions created by David Williams are * Copyright (C) 1999 David Williams. All Rights Reserved. * Contributor(s): * Tomi Kankaanpaa * Andrew Trevarrow *//* * fpopen.c * * created: djw@djw.org, January 2, 1999. */#include "prcp.h"static intread_records(prc_internal_t* iprc,             FILE* fp,             prc_uint32_t filesize,             prc_uint32_t* firstRecordOffset_r){    prc_uint16_t           i;    prc_internal_record_t* foo;    prc_internal_record_t* prev = NULL;    int n = 0;    unsigned isResource = PRC_IS_RESOURCE(&iprc->header);    iprc->records = NULL;    for (i = 0; i < iprc->header.nrecords; i++) {        union {            prc_record_header_t   record;            prc_resource_header_t resource;        } uBuf;        int rv;        if (isResource) {            rv = prcfreadresource(fp, &uBuf.resource);        } else {            rv = prcfreadrecord(fp, &uBuf.record);        }        if (rv == -1)            return rv;#if 0        PRC_DEBUGF(("%02d: %02d %5d\n",                    i, uBuf.record.id, uBuf.record.offset));#endif        foo = (prc_internal_record_t*)prcnewrecord();        if (foo == NULL)            return -1;        if (isResource) {            foo->u_contents.record.data = (prc_byte_t*)uBuf.resource.offset;            foo->u_contents.resource.id = uBuf.resource.id;            foo->u_contents.resource.type = uBuf.resource.type;        } else {            foo->u_contents.record.data = (prc_byte_t*)uBuf.record.offset;            foo->u_contents.record.id = uBuf.record.id;            foo->u_contents.record.flags = uBuf.record.flags;        }        foo->next = NULL;                if (prev != NULL) {            prev->next = foo;        } else {            iprc->records = foo;            if (!isResource)                *firstRecordOffset_r = uBuf.record.offset;        }                prev = foo;    }        /* seek to read data */    for (foo = iprc->records; foo != NULL; foo = foo->next) {        void*        data;        size_t       nread;        long         posn;        long         next_posn;        size_t       size;        posn = (long)foo->u_contents.record.data;        if (foo->next != NULL)            next_posn = (long)foo->next->u_contents.record.data;        else            next_posn = filesize;        size = next_posn - posn;        if (size >= (64 * 1024)) {            PRC_SET_ERRORNO(PRC_ERROR_RECORD_TOOBIG);            PRC_DEBUGF((">= 64k length record (%d)", n));            return -1;        } else if (size == 0) {            /* this is not really an error I guess */            PRC_SET_ERRORNO(PRC_ERROR_RECORD_ZEROLENGTH);            PRC_DEBUGF(("zero length record (%d)", n));            data = NULL;        } else {            data = (void*)malloc(size);                        if (data == NULL)                return -1;                        if (fseek(fp, posn, SEEK_SET) == -1) {                PRC_SET_ERRORNO(PRC_ERROR_SEEK_FAILED);                PRC_DEBUGF(("seek failed for record %d", n));                return -1;            }            nread = fread(data, 1, size, fp);                        if (size != nread) {                PRC_SET_ERRORNO(PRC_ERROR_READ_FAILED);                PRC_DEBUGF(("expected %ld, read %ld",                            (prc_uint32_t)size, (prc_uint32_t)nread));                return -1;            }        }                    foo->u_contents.record.data = data;        foo->u_contents.record.datalen = size;        n++;    }    return n;}static void*read_info(prc_internal_t* iprc, FILE* fp, const char* name,          prc_uint32_t offset, prc_uint32_t size){    size_t nread;    void* data = (void*)malloc(size);    if (!data) {        PRC_SET_ERRORNO(PRC_ERROR_ALLOC_FAILED);        PRC_DEBUGF(("memory allocation failed for %s", name));        return NULL;    }    if (fseek(fp, (size_t)offset, SEEK_SET) == -1) {        PRC_SET_ERRORNO(PRC_ERROR_SEEK_FAILED);        PRC_DEBUGF(("seek failed for %s", name));        free(data);        return NULL;    }    nread = fread(data, 1, (size_t)size, fp);                if (size != (prc_uint32_t)nread) {        PRC_SET_ERRORNO(PRC_ERROR_READ_FAILED);        PRC_DEBUGF(("fread failed for %s expected %ld, read %ld",                   name, size, (prc_uint32_t)nread));        free(data);        return NULL;    }    return data;}static intread_app_info(prc_internal_t* iprc, FILE* fp,              prc_uint32_t offset, prc_uint32_t size){    void* data;    data = read_info(iprc, fp, "appInfo", offset, size);    if (data == NULL)        return -1;    iprc->header.appinfoData = data;    iprc->header.appinfoSize = size;    return 0;}static intread_sort_info(prc_internal_t* iprc, FILE* fp,              prc_uint32_t offset, prc_uint32_t size){    void* data;    data = read_info(iprc, fp, "sortInfo", offset, size);    if (data == NULL)        return -1;    iprc->header.sortinfoData = data;    iprc->header.sortinfoSize = size;    return 0;}PRC_PUBLIC_API(prc_t*)prcfpopen(FILE* fp, unsigned mode){    prc_t      buf;    prc_internal_t* iprc = NULL;    prc_uint32_t appInfoOffset = 0;    prc_uint32_t sortInfoOffset = 0;    PRC_CLEAR_ERRORNO();    if ((mode & PRC_OPEN_CREATE) != 0) {        prcinitheader(&buf);    } else {        fseek(fp, 0, SEEK_SET);                if (prcfreadheader(fp, &buf, &appInfoOffset, &sortInfoOffset) != 0)            return NULL;    }        iprc = (prc_internal_t*)malloc(sizeof(prc_internal_t));    if (iprc == NULL)        return NULL;    memcpy(&iprc->header, &buf, sizeof(prc_t));    iprc->records = NULL;    iprc->fp = fp;    iprc->mode = mode;    iprc->posn = 0;    if ((mode & PRC_OPEN_CREATE) == 0) {        struct stat statbuf;        int    rv;        prc_uint32_t firstRecordOffset = 0;        if (fstat(fileno(fp), &statbuf) == -1) {            PRC_SET_ERRORNO(PRC_ERROR_STAT_FAILED);            PRC_DEBUGF(("could not stat!"));            return NULL;        }        rv = read_records(iprc, fp, statbuf.st_size, &firstRecordOffset);        if (!PRC_IS_RESOURCE(&iprc->header)) {            if (appInfoOffset != 0) {                prc_uint32_t appInfoSize;                if (sortInfoOffset != 0)                    appInfoSize = sortInfoOffset - appInfoOffset;                else if (firstRecordOffset != 0)                    appInfoSize = firstRecordOffset - appInfoOffset;                else                    appInfoSize = statbuf.st_size - appInfoOffset;                if (read_app_info(iprc, fp, appInfoOffset, appInfoSize) == -1)                    return NULL;            }            if (sortInfoOffset != 0) {                prc_uint32_t sortInfoSize;                if (firstRecordOffset != 0)                    sortInfoSize = firstRecordOffset - sortInfoOffset;                else                    sortInfoSize = statbuf.st_size - sortInfoOffset;                if (read_sort_info(iprc, fp,                                   sortInfoOffset, sortInfoSize) == -1)                    return NULL;            }        }        if (rv == -1)            return NULL;    }    return &iprc->header;}

⌨️ 快捷键说明

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