예제 #1
0
파일: tabdump.cpp 프로젝트: stievie/Martis
/**********************************************************************
 *                          DumpIndFileObjects()
 *
 * Read and dump a .IND file
 **********************************************************************/
static int DumpIndFileObjects(const char *pszFname)
{
    TABINDFile  oINDFile;

    /*---------------------------------------------------------------------
     * Try to open source file
     *--------------------------------------------------------------------*/
    if (oINDFile.Open(pszFname, "rb") != 0)
    {
        printf("Failed to open %s\n", pszFname);
        return -1;
    }

    // oINDFile.SetIndexFieldType(1,TABFChar);
    oINDFile.Dump();

    /*---------------------------------------------------------------------
     * Read/Dump objects until EOF is reached
     *--------------------------------------------------------------------*/
    while ( 0 )
    {

    }

    /*---------------------------------------------------------------------
     * Cleanup and exit.
     *--------------------------------------------------------------------*/
    oINDFile.Close();

    return 0;
}
예제 #2
0
GIntBig *OGRMIAttrIndex::GetAllMatches( OGRField *psKey, GIntBig* panFIDList, int* nFIDCount, int* nLength )
{
    GByte *pabyKey = BuildKey( psKey );

    if (panFIDList == nullptr)
    {
        panFIDList = static_cast<GIntBig *>(CPLMalloc(sizeof(GIntBig) * 2));
        *nFIDCount = 0;
        *nLength = 2;
    }

    GIntBig nFID = poINDFile->FindFirst( iIndex, pabyKey );
    while( nFID > 0 )
    {
        if( *nFIDCount >= *nLength-1 )
        {
            *nLength = (*nLength) * 2 + 10;
            panFIDList = static_cast<GIntBig *>(CPLRealloc(panFIDList, sizeof(GIntBig)* (*nLength)));
        }
        panFIDList[(*nFIDCount)++] = nFID - 1;

        nFID = poINDFile->FindNext( iIndex, pabyKey );
    }

    panFIDList[*nFIDCount] = OGRNullFID;

    return panFIDList;
}
예제 #3
0
long *OGRMIAttrIndex::GetAllMatches( OGRField *psKey )

{
    GByte *pabyKey = BuildKey( psKey );
    long  *panFIDList = NULL, nFID;
    int   nFIDCount=0, nFIDMax=2;

    panFIDList = (long *) CPLMalloc(sizeof(long) * 2);

    nFID = poINDFile->FindFirst( iIndex, pabyKey );
    while( nFID > 0 )
    {
        if( nFIDCount >= nFIDMax-1 )
        {
            nFIDMax = nFIDMax * 2 + 10;
            panFIDList = (long *) CPLRealloc(panFIDList, sizeof(long)*nFIDMax);
        }
        panFIDList[nFIDCount++] = nFID - 1;
        
        nFID = poINDFile->FindNext( iIndex, pabyKey );
    }

    panFIDList[nFIDCount] = OGRNullFID;
    
    return panFIDList;
}
예제 #4
0
GByte *OGRMIAttrIndex::BuildKey( OGRField *psKey )

{
    GByte* ret = nullptr;
    switch( poFldDefn->GetType() )
    {
      case OFTInteger:
        ret = poINDFile->BuildKey( iIndex, psKey->Integer );
        break;

      case OFTInteger64:
      {
        if( !CPL_INT64_FITS_ON_INT32(psKey->Integer64) )
        {
            CPLError(CE_Warning, CPLE_NotSupported,
                     "64bit integer value passed to OGRMIAttrIndex::BuildKey()");
        }
        ret = poINDFile->BuildKey( iIndex, static_cast<int>(psKey->Integer64) );
        break;
      }

      case OFTReal:
        ret = poINDFile->BuildKey( iIndex, psKey->Real );
        break;

      case OFTString:
        ret = poINDFile->BuildKey( iIndex, psKey->String );
        break;

      default:
        CPLAssert( false );
        break;
    }
    return ret;
}
예제 #5
0
GByte *OGRMIAttrIndex::BuildKey( OGRField *psKey )

{
    switch( poFldDefn->GetType() )
    {
      case OFTInteger:
        return poINDFile->BuildKey( iIndex, psKey->Integer );
        break;

      case OFTInteger64:
      {
        if( !CPL_INT64_FITS_ON_INT32(psKey->Integer64) )
        {
            CPLError(CE_Warning, CPLE_NotSupported,
                     "64bit integer value passed to OGRMIAttrIndex::BuildKey()");
        }
        return poINDFile->BuildKey( iIndex, (int)psKey->Integer64 );
        break;
      }

      case OFTReal:
        return poINDFile->BuildKey( iIndex, psKey->Real );
        break;

      case OFTString:
        return poINDFile->BuildKey( iIndex, psKey->String );
        break;

      default:
        CPLAssert( FALSE );

        return NULL;
    }
}
예제 #6
0
파일: tabdump.cpp 프로젝트: stievie/Martis
/**********************************************************************
 *                          SearchIndex()
 *
 * Search a TAB dataset's .IND file for pszVal in index nIndexNo
 **********************************************************************/
static int SearchIndex(const char *pszFname, int nIndexNo, const char *pszVal)
{
    TABFile     oTABFile;
    TABINDFile  *poINDFile;

    /*---------------------------------------------------------------------
     * Try to open source file
     *--------------------------------------------------------------------*/
    if (oTABFile.Open(pszFname, "rb") != 0)
    {
        printf("Failed to open %s as a TABFile.\n", pszFname);
        return -1;
    }

    /*---------------------------------------------------------------------
     * Fetch IND file handle
     *--------------------------------------------------------------------*/
    if ((poINDFile = oTABFile.GetINDFileRef()) == NULL)
    {
        printf("Dataset %s has no .IND file\n", pszFname);
        return -1;
    }

    /*---------------------------------------------------------------------
     * Search the index.
     * For now we search only 'char' index types!!!
     *--------------------------------------------------------------------*/
    GByte *pKey;
    int nRecordNo;

    pKey = poINDFile->BuildKey(nIndexNo, pszVal);
    nRecordNo = poINDFile->FindFirst(nIndexNo, pKey);

    if (nRecordNo < 1)
    {
        printf("Value '%s' not found in index #%d\n", pszVal, nIndexNo);
    }
    else
    {
        while(nRecordNo > 0)
        {
            printf("Record %d...\n", nRecordNo);

            nRecordNo = poINDFile->FindNext(nIndexNo, pKey);
        }
    }

    /*---------------------------------------------------------------------
     * Cleanup and exit.
     *--------------------------------------------------------------------*/
    oTABFile.Close();

    return 0;

}
예제 #7
0
GIntBig OGRMIAttrIndex::GetFirstMatch( OGRField *psKey )

{
    GByte *pabyKey = BuildKey( psKey );
    const GIntBig nFID = poINDFile->FindFirst( iIndex, pabyKey );
    if( nFID < 1 )
        return OGRNullFID;
    else
        return nFID - 1;
}
예제 #8
0
OGRErr OGRMIAttrIndex::AddEntry( OGRField *psKey, long nFID )

{
    GByte *pabyKey = BuildKey( psKey );

    if( psKey == NULL )
        return OGRERR_FAILURE;

    if( poINDFile->AddEntry( iIndex, pabyKey, nFID+1 ) != 0 )
        return OGRERR_FAILURE;
    else
        return OGRERR_NONE;
}
예제 #9
0
GByte *OGRMIAttrIndex::BuildKey( OGRField *psKey )

{
    switch( poFldDefn->GetType() )
    {
      case OFTInteger:
        return poINDFile->BuildKey( iIndex, psKey->Integer );
        break;

      case OFTReal:
        return poINDFile->BuildKey( iIndex, psKey->Real );
        break;

      case OFTString:
        return poINDFile->BuildKey( iIndex, psKey->String );
        break;

      default:
        CPLAssert( FALSE );

        return NULL;
    }
}
예제 #10
0
OGRErr OGRMIAttrIndex::AddEntry( OGRField *psKey, GIntBig nFID )

{
    if( psKey == nullptr )
        return OGRERR_FAILURE;

    if( nFID >= INT_MAX )
        return OGRERR_FAILURE;

    GByte *pabyKey = BuildKey( psKey );

    if( pabyKey == nullptr )
        return OGRERR_FAILURE;

    if( poINDFile->AddEntry( iIndex, pabyKey, static_cast<int>(nFID)+1 ) != 0 )
        return OGRERR_FAILURE;
    else
        return OGRERR_NONE;
}
예제 #11
0
OGRErr OGRMIAttrIndex::AddEntry( OGRField *psKey, GIntBig nFID )

{
    if( psKey == NULL )
        return OGRERR_FAILURE;

    if( nFID >= INT_MAX )
        return OGRERR_FAILURE;

    GByte *pabyKey = BuildKey( psKey );

    if( pabyKey == NULL )
        return OGRERR_FAILURE;

    if( poINDFile->AddEntry( iIndex, pabyKey, (int)nFID+1 ) != 0 )
        return OGRERR_FAILURE;
    else
        return OGRERR_NONE;
}
예제 #12
0
OGRErr OGRMILayerAttrIndex::CreateIndex( int iField )

{
/* -------------------------------------------------------------------- */
/*      Do we have an open .ID file yet?  If not, create it now.        */
/* -------------------------------------------------------------------- */
    if( poINDFile == NULL )
    {
        poINDFile = new TABINDFile();
        if( poINDFile->Open( pszMIINDFilename, "w+" ) != 0 )
        {
            delete poINDFile;
            poINDFile = NULL;
            
            CPLError( CE_Failure, CPLE_OpenFailed, 
                      "Failed to create %s.",
                      pszMIINDFilename );
            return OGRERR_FAILURE;
        }
    }

/* -------------------------------------------------------------------- */
/*      Do we have this field indexed already?                          */
/* -------------------------------------------------------------------- */
    int i;
    OGRFieldDefn *poFldDefn=poLayer->GetLayerDefn()->GetFieldDefn(iField);

    for( i = 0; i < nIndexCount; i++ )
    {
        if( papoIndexList[i]->iField == iField )
        {
            CPLError( CE_Failure, CPLE_AppDefined, 
                      "It seems we already have an index for field %d/%s\n"
                      "of layer %s.", 
                      poFldDefn->GetNameRef(),
                      poLayer->GetLayerDefn()->GetName() );
            return OGRERR_FAILURE;
        }
    }

/* -------------------------------------------------------------------- */
/*      What is the corresponding field type in TAB?  Note that we      */
/*      don't allow indexing of any of the list types.                  */
/* -------------------------------------------------------------------- */
    TABFieldType eTABFT;
    int           nFieldWidth = 0;

    switch( poFldDefn->GetType() )
    {
      case OFTInteger:
        eTABFT = TABFInteger;
        break;

      case OFTReal:
        eTABFT = TABFFloat;
        break;

      case OFTString:
        eTABFT = TABFChar;
        if( poFldDefn->GetWidth() > 0 )
            nFieldWidth = poFldDefn->GetWidth();
        else
            nFieldWidth = 64;
        break;

      default:
        CPLError( CE_Failure, CPLE_AppDefined, 
                  "Indexing not support for the field type of field %s.",
                  poFldDefn->GetNameRef() );
        return OGRERR_FAILURE;
    }

/* -------------------------------------------------------------------- */
/*      Create the index.                                               */
/* -------------------------------------------------------------------- */
    int iINDIndex;

    iINDIndex = poINDFile->CreateIndex( eTABFT, nFieldWidth );

    // CreateIndex() reports it's own errors.
    if( iINDIndex < 0 )
        return OGRERR_FAILURE;

    AddAttrInd( iField, iINDIndex );

/* -------------------------------------------------------------------- */
/*      Save the new configuration.                                     */
/* -------------------------------------------------------------------- */
    return SaveConfigToXML();
}
예제 #13
0
OGRErr OGRMILayerAttrIndex::LoadConfigFromXML()

{
    FILE *fp;
    int  nXMLSize;
    char *pszRawXML;

    CPLAssert( poINDFile == NULL );

/* -------------------------------------------------------------------- */
/*      Read the XML file.                                              */
/* -------------------------------------------------------------------- */
    fp = VSIFOpen( pszMetadataFilename, "rb" );
    if( fp == NULL )
        return OGRERR_NONE;

    VSIFSeek( fp, 0, SEEK_END );
    nXMLSize = VSIFTell( fp );
    VSIFSeek( fp, 0, SEEK_SET );

    pszRawXML = (char *) CPLMalloc(nXMLSize+1);
    pszRawXML[nXMLSize] = '\0';
    VSIFRead( pszRawXML, nXMLSize, 1, fp );

    VSIFClose( fp );

/* -------------------------------------------------------------------- */
/*      Parse the XML.                                                  */
/* -------------------------------------------------------------------- */
    CPLXMLNode *psRoot = CPLParseXMLString( pszRawXML );
    CPLFree( pszRawXML );

    if( psRoot == NULL )
        return OGRERR_FAILURE;

/* -------------------------------------------------------------------- */
/*      Open the index file.                                            */
/* -------------------------------------------------------------------- */
    poINDFile = new TABINDFile();
    if( poINDFile->Open( pszMetadataFilename, "r+" ) != 0 )
    {
        CPLDestroyXMLNode( psRoot );
        CPLError( CE_Failure, CPLE_OpenFailed,
                  "Failed to open index file %s.", 
                  pszMIINDFilename );
        return OGRERR_FAILURE;
    }

/* -------------------------------------------------------------------- */
/*      Process each attrindex.                                         */
/* -------------------------------------------------------------------- */
    CPLXMLNode *psAttrIndex;

    for( psAttrIndex = psRoot->psChild; 
         psAttrIndex != NULL; 
         psAttrIndex = psAttrIndex->psNext )
    {
        int iField, iIndexIndex;

        if( psAttrIndex->eType != CXT_Element 
            || !EQUAL(psAttrIndex->pszValue,"OGRMIAttrIndex") )
            continue;

        iField = atoi(CPLGetXMLValue(psAttrIndex,"FieldIndex","-1"));
        iIndexIndex = atoi(CPLGetXMLValue(psAttrIndex,"IndexIndex","-1"));

        if( iField == -1 || iIndexIndex == -1 )
        {
            CPLError( CE_Warning, CPLE_AppDefined, 
                      "Skipping corrupt OGRMIAttrIndex entry." );
            continue;
        }

        AddAttrInd( iField, iIndexIndex );
    }

    CPLDestroyXMLNode( psRoot );

    CPLDebug( "OGR", "Restored %d field indexes for layer %s from %s on %s.",
              nIndexCount, poLayer->GetLayerDefn()->GetName(), 
              pszMetadataFilename, pszMIINDFilename );

    return OGRERR_NONE;
}
예제 #14
0
OGRErr OGRMILayerAttrIndex::LoadConfigFromXML(const char* pszRawXML)

{
/* -------------------------------------------------------------------- */
/*      Parse the XML.                                                  */
/* -------------------------------------------------------------------- */
    CPLXMLNode *psRoot = CPLParseXMLString( pszRawXML );

    if( psRoot == nullptr )
        return OGRERR_FAILURE;

/* -------------------------------------------------------------------- */
/*      Open the index file.                                            */
/* -------------------------------------------------------------------- */
    poINDFile = new TABINDFile();

    if (pszMIINDFilename == nullptr)
        pszMIINDFilename = CPLStrdup(CPLGetXMLValue(psRoot,"MIIDFilename",""));

    if( pszMIINDFilename == nullptr )
        return OGRERR_FAILURE;

    /* NOTE: Replaced r+ with r according to explanation in Ticket #1620.
     * This change has to be observed if it doesn't cause any
     * problems in future. (mloskot)
     */
    if( poINDFile->Open( pszMIINDFilename, "r" ) != 0 )
    {
        CPLDestroyXMLNode( psRoot );
        CPLError( CE_Failure, CPLE_OpenFailed,
                  "Failed to open index file %s.",
                  pszMIINDFilename );
        return OGRERR_FAILURE;
    }
/* -------------------------------------------------------------------- */
/*      Process each attrindex.                                         */
/* -------------------------------------------------------------------- */
    for( CPLXMLNode *psAttrIndex = psRoot->psChild;
         psAttrIndex != nullptr;
         psAttrIndex = psAttrIndex->psNext )
    {
        if( psAttrIndex->eType != CXT_Element
            || !EQUAL(psAttrIndex->pszValue,"OGRMIAttrIndex") )
            continue;

        int iField = atoi(CPLGetXMLValue(psAttrIndex,"FieldIndex","-1"));
        int iIndexIndex = atoi(CPLGetXMLValue(psAttrIndex,"IndexIndex","-1"));

        if( iField == -1 || iIndexIndex == -1 )
        {
            CPLError( CE_Warning, CPLE_AppDefined,
                      "Skipping corrupt OGRMIAttrIndex entry." );
            continue;
        }

        AddAttrInd( iField, iIndexIndex );
    }

    CPLDestroyXMLNode( psRoot );

    CPLDebug( "OGR", "Restored %d field indexes for layer %s from %s on %s.",
              nIndexCount, poLayer->GetLayerDefn()->GetName(),
              pszMetadataFilename ? pszMetadataFilename : "--unknown--",
              pszMIINDFilename );

    return OGRERR_NONE;
}
예제 #15
0
/**********************************************************************
 *                          CreateIndex()
 *
 * Create index for specified field in an existing TAB dataset.
 **********************************************************************/
static int CreateIndex(const char *pszSrcFname, const char *pszField)
{
    IMapInfoFile *poSrcFile = NULL;
    int         nFeatureId, iField;
    TABFeature *poFeature;
    TABINDFile *poINDFile;

    /*---------------------------------------------------------------------
     * Try to open source file
     *--------------------------------------------------------------------*/
    if ((poSrcFile = IMapInfoFile::SmartOpen(pszSrcFname)) == NULL)
    {
        printf("Failed to open %s\n", pszSrcFname);
        return -1;
    }

    if (poSrcFile->GetFileClass() != TABFC_TABFile)
    {
        printf("Indexes cannot be added to this type of TAB datasets\n");
        poSrcFile->Close();
        delete poSrcFile;
        return -1;
    }

    /*---------------------------------------------------------------------
     * Make sure field exists and is not already indexed
     *--------------------------------------------------------------------*/
    OGRFeatureDefn *poDefn = poSrcFile->GetLayerDefn();
    if ( poDefn == NULL ||
         (iField = poDefn->GetFieldIndex(pszField)) == -1 ||
         poSrcFile->IsFieldIndexed(iField))
    {
        printf("Cannot create index: field '%s' not found or is already indexed.\n", 
               pszField);
        poSrcFile->Close();
        delete poSrcFile;
        return -1;
    }

    /*---------------------------------------------------------------------
     * Things seem OK... open IND file for update
     * (Note that TABINDFile automagically adjusts file extension)
     *--------------------------------------------------------------------*/
    poINDFile = new TABINDFile; 
    if ( poINDFile->Open(pszSrcFname, "r+", TRUE) != 0 &&
         poINDFile->Open(pszSrcFname, "w", TRUE) != 0)
    {
        printf("Unable to create IND file for %s.\n", pszSrcFname);
        delete poINDFile;
        poSrcFile->Close();
        delete poSrcFile;
        return -1;
    }

    int nNewIndexNo = -1;
    OGRFieldDefn *poFieldDefn = poDefn->GetFieldDefn(iField);
    TABFieldType eFieldType = poSrcFile->GetNativeFieldType(iField);
    if (poFieldDefn == NULL ||
        (nNewIndexNo = poINDFile->CreateIndex(eFieldType,
                                              poFieldDefn->GetWidth()) ) < 1)
    {
        // Failed... an error has already been reported.
        delete poINDFile;
        poSrcFile->Close();
        delete poSrcFile;
        return -1;
    }

    printf("Index number %d will be created for field %s...\n\n"
           "This program does not update the TAB header file (yet!) so you \n"
           "should edit %s and add 'Index %d' at the end of the definition \n"
           "of field %s.\n\n",
           nNewIndexNo, pszField, pszSrcFname, nNewIndexNo, pszField);

    /*---------------------------------------------------------------------
     * Add index entries until we reach EOF
     *--------------------------------------------------------------------*/
    nFeatureId = -1;
    while ( (nFeatureId = poSrcFile->GetNextFeatureId(nFeatureId)) != -1 )
    {
        poFeature = poSrcFile->GetFeatureRef(nFeatureId);
        if (poFeature)
        {
            GByte *pKey = NULL;
            switch(eFieldType)
            {
              case TABFChar:
                pKey = poINDFile->BuildKey(nNewIndexNo, 
                                        poFeature->GetFieldAsString(iField));
                break;
              case TABFInteger:
              case TABFSmallInt:
                pKey = poINDFile->BuildKey(nNewIndexNo, 
                                        poFeature->GetFieldAsInteger(iField));
                break;
              case TABFDecimal:
              case TABFFloat:
              case TABFLogical:
                pKey = poINDFile->BuildKey(nNewIndexNo, 
                                        poFeature->GetFieldAsDouble(iField));
                break;
              default:
              case TABFDate:
                CPLAssert(FALSE); // Unsupported for now.
            }

            if (poINDFile->AddEntry(nNewIndexNo, pKey, nFeatureId) != 0)
                return -1;
        }
        else
            break;      // GetFeatureRef() failed: Abort the loop
    }

    /*---------------------------------------------------------------------
     * Cleanup and exit.
     *--------------------------------------------------------------------*/
    poINDFile->Close();
    delete poINDFile;

    poSrcFile->Close();
    delete poSrcFile;

    MITABFreeCoordSysTable();

    return 0;
}