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

📄 avc_binwr.c

📁 GIS系统支持库Geospatial Data Abstraction Library代码.GDAL is a translator library for raster geospatial dat
💻 C
📖 第 1 页 / 共 5 页
字号:
 * or -1 if something failed. **********************************************************************//* Prototype for _AVCBinReadNextArcDir() from avc_bin.c */int _AVCBinReadNextArcDir(AVCRawBinFile *psFile, AVCTableDef *psArcDir);int _AVCBinWriteCreateArcDirEntry(const char *pszArcDirFile,                                  AVCTableDef *psTableDef,                                   AVCDBCSInfo *psDBCSInfo){    int          iEntry, numDirEntries=0, nTableIndex = 0;    VSIStatBuf   sStatBuf;    AVCRawBinFile *hRawBinFile;    GBool        bFound;    AVCTableDef  sEntry;    /*-----------------------------------------------------------------     * Open and Scan the ARC.DIR to establish the table index (ARC####)     *----------------------------------------------------------------*/#ifdef _WIN32    /*-----------------------------------------------------------------     * Note, DM, 20010507 - We used to use VSIFStat() to establish the     * size of arc.dir, but when working on a WinNT4 networked drive, the     * stat() information was not always right, and we sometimes ended      * up overwriting arc.dir entries.  The solution: open and scan arc.dir     * until EOF to establish its size.       * That trick also seems to fix another network buffer problem: when      * writing a coverage in a new empty dir (with no info dir yet), we     * would get an error in fwrite() while writing the 3rd arc.dir      * entry of the coverage.  That second problem could also have been      * fixed by forcing a VSIFSeek() before the first fwrite()... we've      * added it below.     *----------------------------------------------------------------*/    FILE *fp;    if ((fp = VSIFOpen(pszArcDirFile, "r")) != NULL)    {        char buf[380];        while (!VSIFEof(fp))        {            if (VSIFRead(buf, 380, 1, fp) == 1)                numDirEntries++;        }        VSIFClose(fp);        hRawBinFile = AVCRawBinOpen(pszArcDirFile, "r+",                                    AVC_COVER_BYTE_ORDER(AVCCoverV7),                                    psDBCSInfo);    }    else #endif    /* On Unix we can still use fstat() */    if ( VSIStat(pszArcDirFile, &sStatBuf) != -1 )    {        numDirEntries = sStatBuf.st_size/380;        hRawBinFile = AVCRawBinOpen(pszArcDirFile, "r+",                                    AVC_COVER_BYTE_ORDER(AVCCoverV7),                                    psDBCSInfo);    }    else    {        numDirEntries = 0;        hRawBinFile = AVCRawBinOpen(pszArcDirFile, "w",                                     AVC_COVER_BYTE_ORDER(AVCCoverV7),                                     psDBCSInfo);    }    if (hRawBinFile == NULL)    {        /* Failed to open file... just return -1 since an error message         * has already been issued by AVCRawBinOpen()         */        return -1;    }    /* Init nTableIndex at -1 so that first table created should have      * index 0      */    nTableIndex = -1;    iEntry = 0;    bFound = FALSE;    while(!bFound && iEntry<numDirEntries &&          _AVCBinReadNextArcDir(hRawBinFile, &sEntry) == 0)    {        nTableIndex = atoi(sEntry.szInfoFile+3);        if (EQUALN(psTableDef->szTableName, sEntry.szTableName,                    strlen(psTableDef->szTableName)))        {               bFound = TRUE;            break;        }        iEntry++;    }    /*-----------------------------------------------------------------     * Reposition the file pointer and write the entry.     *     * We use VSIFSeek() directly since the AVCRawBin*() functions do     * not support random access yet... it is OK to do so here since the     * ARC.DIR does not have a header and we will close it right away.     *----------------------------------------------------------------*/    if (bFound)        VSIFSeek(hRawBinFile->fp, iEntry*380, SEEK_SET);    else    {        /* Not found... Use the next logical table index */        nTableIndex++;        /* We're already at EOF so we shouldn't need to fseek here, but         * ANSI-C requires that a file positioning function be called          * between read and writes... this had never been a problem before         * on any system except with NT4 network drives.         */        VSIFSeek(hRawBinFile->fp, numDirEntries*380, SEEK_SET);    }    sprintf(psTableDef->szInfoFile, "ARC%4.4d", nTableIndex);    _AVCBinWriteArcDir(hRawBinFile, psTableDef);    AVCRawBinClose(hRawBinFile);    return nTableIndex;}/********************************************************************** *                          AVCBinWriteCreateTable() * * Open an INFO table for writing: * *  - Add an entry for the new table in the info/arc.dir *  - Write the attributes definitions to the info/arc####.nit *  - Create the data file, ready to write data records to it *  - If necessary, set the arc####.dat to point to the location of *    the data file. * * pszInfoPath is the info directory path, terminated by a '/' or a '\\' * It is assumed that this 'info' directory already exists and is writable. * * psTableDef should contain a valid table definition for this coverage. * This function will create and maintain its own copy of the structure. * * The name of the file to create and its location will be based on the  * table name and the external ("XX") flag values in the psTableDef  * structure, so you have to make sure that these values are valid. * * If a table with the same name is already present in the arc.dir, then  * the same arc.dir entry will be used and overwritten.  This happens * when a coverage directory is deleted by hand.  The behavior implemented * here correspond to Arc/Info's behavior. * * For internal tables, the data file goes directly in the info directory, so * there is not much to worry about. * * For external tables, the table name is composed of 3 parts: * *         <COVERNAME>.<EXT><SUBCLASSNAME> * *  - <COVERNAME>: *    The first part of the table name (before the '.') is the *    name of the coverage to which the table belongs, and the data file *    will be created in this coverage's directory... so it is assumed that *    the directory "../<covername>" already exists and is writable. *  - <EXT>: *    The coverage name is followed by a 3 chars extension that will be  *    used to build the name of the external table to create. *  - <SUBCLASSNAME>: *    For some table types, the extension is followed by a subclass name. *     *  When <SUBCLASSNAME> is present, then the data file name will be: *            "../<covername>/<subclassname>.<ext>" * *    e.g. The table named "TEST.PATCOUNTY" would be stored in the file *         "../test/county.pat" (this path is realtive to the info directory) * *  When the <SUBCLASSNAME> is not present, then the name of the data file *  will be the "../<covername>/<ext>.adf" * *    e.g. The table named "TEST.PAT" would be stored in the file  *         "../test/pat.adf" * * Of course, it would be too easy if there were no exceptions to these * rules!  Single precision ".TIC" and ".BND" follow the above rules and * will be named "tic.adf" and "bnd.adf" but in double precision coverages, * they will be named "dbltic.adf" and "dblbnd.adf". * * Returns a valid AVCBinFile handle, or NULL if the table could * not be created. * * AVCBinClose() will eventually have to be called to release the  * resources used by the AVCBinFile structure. **********************************************************************/AVCBinFile *AVCBinWriteCreateTable(const char *pszInfoPath,                                    const char *pszCoverName,                                   AVCTableDef *psSrcTableDef,                                   AVCCoverType eCoverType,                                   int nPrecision, AVCDBCSInfo *psDBCSInfo){    AVCBinFile   *psFile;    AVCRawBinFile *hRawBinFile;    AVCTableDef  *psTableDef = NULL;    char         *pszFname = NULL, szInfoFile[8]="";    int          i, nTableIndex = 0;    if (eCoverType == AVCCoverPC)        return _AVCBinWriteCreateDBFTable(pszInfoPath, pszCoverName,                                          psSrcTableDef, eCoverType,                                           nPrecision, psDBCSInfo);    /*-----------------------------------------------------------------     * Make sure precision value is valid (AVC_DEFAULT_PREC is NOT valid)     *----------------------------------------------------------------*/    if (nPrecision!=AVC_SINGLE_PREC && nPrecision!=AVC_DOUBLE_PREC)    {        CPLError(CE_Failure, CPLE_IllegalArg,                 "AVCBinWriteCreateTable(): Invalid precision parameter "                 "(value must be AVC_SINGLE_PREC or AVC_DOUBLE_PREC)");        return NULL;    }    /* Alloc a buffer big enough for the longest possible filename...     */    pszFname = (char*)CPLMalloc((strlen(pszInfoPath)+81)*sizeof(char));    /*-----------------------------------------------------------------     * Alloc and init the AVCBinFile struct.     *----------------------------------------------------------------*/    psFile = (AVCBinFile*)CPLCalloc(1, sizeof(AVCBinFile));    psFile->eFileType = AVCFileTABLE;    /* Precision is not important for tables */    psFile->nPrecision = nPrecision;    psFile->eCoverType = eCoverType;    psFile->hdr.psTableDef = psTableDef = _AVCDupTableDef(psSrcTableDef);    /*-----------------------------------------------------------------     * Add a record for this table in the "arc.dir"     * Note: there could be a problem if 2 processes try to add an entry     * at the exact same time... does Arc/Info do any locking on that file???     *----------------------------------------------------------------*/    sprintf(pszFname, "%sarc.dir", pszInfoPath);    nTableIndex = _AVCBinWriteCreateArcDirEntry(pszFname, psTableDef,                                                 psDBCSInfo);    if (nTableIndex < 0)    {        /* Failed to add arc.dir entry... just return NULL since an error         * message has already been issued by _AVCBinWriteCreateArcDirEntry()         */        _AVCDestroyTableDef(psTableDef);        CPLFree(psFile);        CPLFree(pszFname);        return NULL;    }    sprintf(szInfoFile, "arc%4.4d", nTableIndex);    /*-----------------------------------------------------------------     * Create the "arc####.nit" with the attribute definitions.     *----------------------------------------------------------------*/    sprintf(pszFname, "%s%s.nit", pszInfoPath, szInfoFile);    hRawBinFile = AVCRawBinOpen(pszFname, "w",                                AVC_COVER_BYTE_ORDER(AVCCoverV7),                                psDBCSInfo);    if (hRawBinFile == NULL)    {        /* Failed to open file... just return NULL since an error message         * has already been issued by AVCRawBinOpen()         */        _AVCDestroyTableDef(psTableDef);        CPLFree(psFile);        CPLFree(pszFname);        return NULL;    }    for(i=0; i<psTableDef->numFields; i++)    {        _AVCBinWriteArcNit(hRawBinFile, &(psTableDef->pasFieldDef[i]));    }    AVCRawBinClose(hRawBinFile);    hRawBinFile = NULL;    /*-----------------------------------------------------------------     * The location of the data file depends on the external flag.     *----------------------------------------------------------------*/    if (EQUAL(psTableDef->szExternal, "  "))    {        /*-------------------------------------------------------------         * Internal table: data goes directly in "arc####.dat"         *------------------------------------------------------------*/        psTableDef->szDataFile[0] = '\0';        sprintf(pszFname, "%s%s.dat", pszInfoPath, szInfoFile);        psFile->pszFilename = CPLStrdup(pszFname);    }    else    {        /*-------------------------------------------------------------         * External table: data stored in the coverage directory, and         * the path to the data file is written to "arc####.dat"         *... start by extracting the info to build the data file name...         *------------------------------------------------------------*/        char szCoverName[40]="", szExt[4]="", szSubclass[40]="", *pszPtr;        int nLen;        FILE *fpOut;        nLen = strlen(psTableDef->szTableName);        CPLAssert(nLen <= 32);        if (nLen > 32) return NULL;        pszPtr = psTableDef->szTableName;        for(i=0; *pszPtr!='\0' && *pszPtr!='.' && *pszPtr!=' ';  i++, pszPtr++)        {            szCoverName[i] = tolower(*pszPtr);        }        szCoverName[i] = '\0';        if (*pszPtr == '.')            pszPtr++;        for(i=0; i<3 && *pszPtr!='\0' && *pszPtr!=' ';  i++, pszPtr++)        {            szExt[i] = tolower(*pszPtr);        }        szExt[i] = '\0';        for(i=0; *pszPtr!='\0' && *pszPtr!=' ';  i++, pszPtr++)        {            szSubclass[i] = tolower(*pszPtr);        }        szSubclass[i] = '\0';        /*-------------------------------------------------------------         * ... and build the data file name based on what we extracted         *------------------------------------------------------------*/        if (strlen(szSubclass) == 0)        {            if (nPrecision == AVC_DOUBLE_PREC &&                (EQUAL(szExt, "TIC") || EQUAL(szExt, "BND")) )            {                /* "../<covername>/dbl<ext>.adf" */                sprintf(psTableDef->szDataFile,                         "../%s/dbl%s.adf", szCoverName, szExt);            }            else            {                /* "../<covername>/<ext>.adf" */                sprintf(psTableDef->szDataFile,                         "../%s/%s.adf", szCoverName, szExt);            }        }        else        {            /* "../<covername>/<subclass>.<ext>" */            sprintf(psTableDef->szDataFile,                     "../%s/%s.%s", szCoverName, szSubclass, szExt);        }        /*-------------------------

⌨️ 快捷键说明

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