예제 #1
0
GMLFeature *GMLReader::NextFeature()

{
    if (!m_bReadStarted)
    {
        if (oParser == NULL)
            SetupParser();

        if (fpGML == NULL)
            fpGML = VSIFOpenL(m_pszFilename, "rt");

        m_bReadStarted = TRUE;
    }

    if (fpGML == NULL || m_bStopParsing)
        return NULL;

    if (nFeatureTabIndex < nFeatureTabLength)
    {
        return ppoFeatureTab[nFeatureTabIndex++];
    }

    if (VSIFEofL(fpGML))
        return NULL;

    char aBuf[BUFSIZ];

    CPLFree(ppoFeatureTab);
    ppoFeatureTab = NULL;
    nFeatureTabLength = 0;
    nFeatureTabIndex = 0;

    int nDone;
    do
    {
        m_poGMLHandler->ResetDataHandlerCounter();

        unsigned int nLen =
                (unsigned int)VSIFReadL( aBuf, 1, sizeof(aBuf), fpGML );
        nDone = VSIFEofL(fpGML);
        if (XML_Parse(oParser, aBuf, nLen, nDone) == XML_STATUS_ERROR)
        {
            CPLError(CE_Failure, CPLE_AppDefined,
                     "XML parsing of GML file failed : %s "
                     "at line %d, column %d",
                     XML_ErrorString(XML_GetErrorCode(oParser)),
                     (int)XML_GetCurrentLineNumber(oParser),
                     (int)XML_GetCurrentColumnNumber(oParser));
            m_bStopParsing = TRUE;
        }
        if (!m_bStopParsing)
            m_bStopParsing = m_poGMLHandler->HasStoppedParsing();

    } while (!nDone && !m_bStopParsing && nFeatureTabLength == 0);

    return (nFeatureTabLength) ? ppoFeatureTab[nFeatureTabIndex++] : NULL;
}
예제 #2
0
파일: ogrjmllayer.cpp 프로젝트: OSGeo/gdal
OGRFeature *OGRJMLLayer::GetNextFeature()
{
    if (!bHasReadSchema)
        LoadSchema();

    if (bStopParsing)
        return nullptr;

    if (nFeatureTabIndex < nFeatureTabLength)
    {
        return ppoFeatureTab[nFeatureTabIndex++];
    }

    if (VSIFEofL(fp))
        return nullptr;

    char aBuf[BUFSIZ];

    nFeatureTabLength = 0;
    nFeatureTabIndex = 0;

    nWithoutEventCounter = 0;

    int nDone = 0;
    do
    {
        nDataHandlerCounter = 0;
        unsigned int nLen =
                (unsigned int)VSIFReadL( aBuf, 1, sizeof(aBuf), fp );
        nDone = VSIFEofL(fp);
        if (XML_Parse(oParser, aBuf, nLen, nDone) == XML_STATUS_ERROR)
        {
            CPLError(CE_Failure, CPLE_AppDefined,
                     "XML parsing of JML file failed : %s "
                     "at line %d, column %d",
                     XML_ErrorString(XML_GetErrorCode(oParser)),
                     (int)XML_GetCurrentLineNumber(oParser),
                     (int)XML_GetCurrentColumnNumber(oParser));
            bStopParsing = true;
        }
        nWithoutEventCounter ++;
    } while (!nDone && !bStopParsing && nFeatureTabLength == 0 &&
             nWithoutEventCounter < 10);

    if (nWithoutEventCounter == 10)
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Too much data inside one element. File probably corrupted");
        bStopParsing = true;
    }

    return (nFeatureTabLength) ? ppoFeatureTab[nFeatureTabIndex++] : nullptr;
}
예제 #3
0
파일: ceostest.c 프로젝트: Joe-xXx/gdal
int main( int nArgc, char ** papszArgv )

{
    const char  *pszFilename;
    FILE	*fp;
    CEOSRecord *psRecord;
    int nPosition = 0;

    if( nArgc > 1 )
        pszFilename = papszArgv[1];
    else
        pszFilename = "imag_01.dat";

    fp = VSIFOpenL( pszFilename, "rb" );
    if( fp == NULL )
    {
        fprintf( stderr, "Can't open %s at all.\n", pszFilename );
        exit( 1 );
    }

    while( !VSIFEofL(fp) 
           && (psRecord = CEOSReadRecord( fp )) != NULL )
    {
        printf( "%9d:%4d:%8x:%d\n", 
                nPosition, psRecord->nRecordNum, 
                psRecord->nRecordType, psRecord->nLength );
        CEOSDestroyRecord( psRecord );

        nPosition = (int) VSIFTellL( fp );
    }
    VSIFCloseL( fp );

    exit( 0 );
}
예제 #4
0
void KML::parse()
{
    std::size_t nDone = 0;
    std::size_t nLen = 0;
    char aBuf[BUFSIZ] = { 0 };

    if( NULL == pKMLFile_ )
    {
        sError_ = "No file given";
        return;
    }

    if(poTrunk_ != NULL) {
        delete poTrunk_;
        poTrunk_ = NULL;
    }

    if(poCurrent_ != NULL)
    {
        delete poCurrent_;
        poCurrent_ = NULL;
    }

    XML_Parser oParser = OGRCreateExpatXMLParser();
    XML_SetUserData(oParser, this);
    XML_SetElementHandler(oParser, startElement, endElement);
    XML_SetCharacterDataHandler(oParser, dataHandler);
    oCurrentParser = oParser;
    nWithoutEventCounter = 0;

    do
    {
        nDataHandlerCounter = 0;
        nLen = (int)VSIFReadL( aBuf, 1, sizeof(aBuf), pKMLFile_ );
        nDone = VSIFEofL(pKMLFile_);
        if (XML_Parse(oParser, aBuf, nLen, nDone) == XML_STATUS_ERROR)
        {
            CPLError(CE_Failure, CPLE_AppDefined,
                        "XML parsing of KML file failed : %s at line %d, column %d",
                        XML_ErrorString(XML_GetErrorCode(oParser)),
                        (int)XML_GetCurrentLineNumber(oParser),
                        (int)XML_GetCurrentColumnNumber(oParser));
            XML_ParserFree(oParser);
            VSIRewindL(pKMLFile_);
            return;
        }
        nWithoutEventCounter ++;
    } while (!nDone && nLen > 0 && nWithoutEventCounter < 10);

    XML_ParserFree(oParser);
    VSIRewindL(pKMLFile_);
    poCurrent_ = NULL;

    if (nWithoutEventCounter == 10)
    {
        CPLError(CE_Failure, CPLE_AppDefined,
                 "Too much data inside one element. File probably corrupted");
    }
}
예제 #5
0
int VSISubFileHandle::Eof()

{
    if (nSubregionSize != 0)
        return VSIFTellL( fp ) >= nSubregionOffset + nSubregionSize;
    else
        return VSIFEofL( fp );
}
예제 #6
0
void MoveOverwrite(VSILFILE *fpDest,VSILFILE *fpSource) {
    VSIRewindL(fpSource);
    VSIRewindL(fpDest);
    VSIFTruncateL(fpDest,0);
    char anBuf[0x10000];
    while (!VSIFEofL(fpSource)) {
        size_t nSize=VSIFReadL(anBuf,1,0x10000,fpSource);
        size_t nLeft=nSize;
        while (nLeft>0) nLeft-=VSIFWriteL(anBuf+nSize-nLeft,1,nLeft,fpDest);
    }
    VSIFCloseL(fpSource);
    VSIFFlushL(fpDest);
}
예제 #7
0
void OGRGTMDataSource::AppendTemporaryFiles()
{
    if( fpOutput == NULL )
        return;

    if (numTrackpoints != 0 || numTracks != 0)
    {
        void* pBuffer = CPLMalloc(2048);
        size_t bytes;

        // Append Trackpoints to the output file
        fpTmpTrackpoints = VSIFOpenL( pszTmpTrackpoints, "r" );
        if (fpTmpTrackpoints != NULL)
        { 
            while ( !VSIFEofL(fpTmpTrackpoints) )
            {
                bytes = VSIFReadL(pBuffer, 1, 2048, fpTmpTrackpoints);
                VSIFWriteL(pBuffer, bytes, 1, fpOutput);
            }
            VSIFCloseL( fpTmpTrackpoints );
            fpTmpTrackpoints = NULL;
        }

        // Append Tracks to the output file
        fpTmpTracks = VSIFOpenL( pszTmpTracks, "r" );
        if (fpTmpTracks != NULL)
        {
            while ( !VSIFEofL(fpTmpTracks) )
            {
                bytes = VSIFReadL(pBuffer, 1, 2048, fpTmpTracks);
                VSIFWriteL(pBuffer, bytes, 1, fpOutput);
            }
            VSIFCloseL( fpTmpTracks );
            fpTmpTracks = NULL;
        }
        CPLFree(pBuffer);
    }
}
예제 #8
0
파일: ceos.c 프로젝트: 0004c/node-gdal
void SerializeCeosRecordsFromFile(Link_t *record_list, VSILFILE *fp)
{
    CeosRecord_t *crec;
    Link_t *Link;

    while(!VSIFEofL(fp))
    {
	crec = HMalloc(sizeof(CeosRecord_t));
	VSIFReadL(crec,sizeof(CeosRecord_t),1,fp);
	crec->Buffer = HMalloc(crec->Length * sizeof(char) );
	VSIFReadL(crec->Buffer,sizeof(char),crec->Length,fp);
	Link = ceos2CreateLink(crec);
	AddLink(record_list,Link);
    }
}
예제 #9
0
void OGRVFPLayer::LoadSchema()
{
    oSchemaParser = OGRCreateExpatXMLParser();
    XML_SetElementHandler(oSchemaParser, ::startElementLoadSchemaCbk, ::endElementLoadSchemaCbk);
    XML_SetCharacterDataHandler(oSchemaParser, ::dataHandlerLoadSchemaCbk);
    XML_SetUserData(oSchemaParser, this);

    VSIFSeekL( fpVFP, 0, SEEK_SET );

    bStopParsing = FALSE;
    nWithoutEventCounter = 0;
    interestingDepthLevel = depthLevel = 0;
    inInterestingElement = FALSE;
    
    char aBuf[BUFSIZ];
    int nDone;
    do
    {
        nDataHandlerCounter = 0;
        unsigned int nLen = (unsigned int)VSIFReadL( aBuf, 1, sizeof(aBuf), fpVFP );
        nDone = VSIFEofL(fpVFP);
        if (XML_Parse(oSchemaParser, aBuf, nLen, nDone) == XML_STATUS_ERROR)
        {
            CPLError(CE_Failure, CPLE_AppDefined,
                     "XML parsing of GPX file failed : %s at line %d, column %d",
                     XML_ErrorString(XML_GetErrorCode(oSchemaParser)),
                     (int)XML_GetCurrentLineNumber(oSchemaParser),
                     (int)XML_GetCurrentColumnNumber(oSchemaParser));
            bStopParsing = TRUE;
            break;
        }
        nWithoutEventCounter ++;
    } while (!nDone && !bStopParsing && nWithoutEventCounter < 10);

    if (nWithoutEventCounter == 10)
    {
        CPLError(CE_Failure, CPLE_AppDefined,
                 "Too much data inside one element. File probably corrupted");
        bStopParsing = TRUE;
    }

    XML_ParserFree(oSchemaParser);
    oSchemaParser = NULL;

    VSIFSeekL( fpVFP, 0, SEEK_SET );
}
예제 #10
0
int FileDataSource::DataSourceFeof()
{
    return VSIFEofL( fp );
}
예제 #11
0
/** This function parses the whole file to build the schema */
void OGRSVGLayer::LoadSchema()
{
    CPLAssert(poFeatureDefn == NULL);

    for(int i=0;i<poDS->GetLayerCount();i++)
    {
        OGRSVGLayer* poLayer = (OGRSVGLayer*)poDS->GetLayer(i);
        poLayer->poFeatureDefn = new OGRFeatureDefn( poLayer->osLayerName );
        poLayer->poFeatureDefn->Reference();
        poLayer->poFeatureDefn->SetGeomType(poLayer->GetGeomType());
        poLayer->poFeatureDefn->GetGeomFieldDefn(0)->SetSpatialRef(poLayer->poSRS);
    }

    oSchemaParser = OGRCreateExpatXMLParser();
    XML_SetElementHandler(oSchemaParser, ::startElementLoadSchemaCbk,
                                         ::endElementLoadSchemaCbk);
    XML_SetCharacterDataHandler(oSchemaParser, ::dataHandlerLoadSchemaCbk);
    XML_SetUserData(oSchemaParser, this);

    if (fpSVG == NULL)
        return;

    VSIFSeekL( fpSVG, 0, SEEK_SET );

    inInterestingElement = FALSE;
    depthLevel = 0;
    nWithoutEventCounter = 0;
    bStopParsing = FALSE;

    char aBuf[BUFSIZ];
    int nDone;
    do
    {
        nDataHandlerCounter = 0;
        unsigned int nLen =
            (unsigned int)VSIFReadL( aBuf, 1, sizeof(aBuf), fpSVG );
        nDone = VSIFEofL(fpSVG);
        if (XML_Parse(oSchemaParser, aBuf, nLen, nDone) == XML_STATUS_ERROR)
        {
            CPLError(CE_Failure, CPLE_AppDefined,
                     "XML parsing of SVG file failed : %s at line %d, column %d",
                     XML_ErrorString(XML_GetErrorCode(oSchemaParser)),
                     (int)XML_GetCurrentLineNumber(oSchemaParser),
                     (int)XML_GetCurrentColumnNumber(oSchemaParser));
            bStopParsing = TRUE;
            break;
        }
        nWithoutEventCounter ++;
    } while (!nDone && !bStopParsing && nWithoutEventCounter < 1000);

    if (nWithoutEventCounter == 1000)
    {
        CPLError(CE_Failure, CPLE_AppDefined,
                 "Too much data inside one element. File probably corrupted");
        bStopParsing = TRUE;
    }

    XML_ParserFree(oSchemaParser);
    oSchemaParser = NULL;

    VSIFSeekL( fpSVG, 0, SEEK_SET );
}
예제 #12
0
int TigerCompleteChain::GetShapeRecordId( int nChainId, int nTLID )

{
    CPLAssert( nChainId >= 0 && nChainId < GetFeatureCount() );

    if( fpShape == NULL || panShapeRecordId == NULL )
        return -1;
    
/* -------------------------------------------------------------------- */
/*      Do we already have the answer?                                  */
/* -------------------------------------------------------------------- */
    if( panShapeRecordId[nChainId] != 0 )
        return panShapeRecordId[nChainId];
    
/* -------------------------------------------------------------------- */
/*      If we don't already have this value, then search from the       */
/*      previous known record.                                          */
/* -------------------------------------------------------------------- */
    int iTestChain, nWorkingRecId;
        
    for( iTestChain = nChainId-1;
         iTestChain >= 0 && panShapeRecordId[iTestChain] <= 0;
         iTestChain-- ) {}

    if( iTestChain < 0 )
    {
        iTestChain = -1;
        nWorkingRecId = 1;
    }
    else
    {
        nWorkingRecId = panShapeRecordId[iTestChain]+1;
    }

/* -------------------------------------------------------------------- */
/*      If we have non existent records following (-1's) we can         */
/*      narrow our search a bit.                                        */
/* -------------------------------------------------------------------- */
    while( panShapeRecordId[iTestChain+1] == -1 )
    {
        iTestChain++;
    }

/* -------------------------------------------------------------------- */
/*      Read records up to the maximum distance that is possibly        */
/*      required, looking for our target TLID.                          */
/* -------------------------------------------------------------------- */
    int         nMaxChainToRead = nChainId - iTestChain;
    int         nChainsRead = 0;
    char        achShapeRec[OGR_TIGER_RECBUF_LEN];
    int         nShapeRecLen = psRT2Info->nRecordLength + nRecordLength - psRT1Info->nRecordLength;

    while( nChainsRead < nMaxChainToRead )
    {
        if( VSIFSeekL( fpShape, (nWorkingRecId-1) * nShapeRecLen,
                      SEEK_SET ) != 0 )
        {
            CPLError( CE_Failure, CPLE_FileIO,
                      "Failed to seek to %d of %s2",
                      (nWorkingRecId-1) * nShapeRecLen, pszModule );
            return -2;
        }

        if( VSIFReadL( achShapeRec, psRT2Info->nRecordLength, 1, fpShape ) != 1 )
        {
            if( !VSIFEofL( fpShape ) )
            {
                CPLError( CE_Failure, CPLE_FileIO,
                          "Failed to read record %d of %s2",
                          nWorkingRecId-1, pszModule );
                return -2;
            }
            else
                return -1;
        }

        if( atoi(GetField(achShapeRec,6,15)) == nTLID )
        {
            panShapeRecordId[nChainId] = nWorkingRecId;

            return nWorkingRecId;
        }

        if( atoi(GetField(achShapeRec,16,18)) == 1 )
        {
            nChainsRead++;
        }

        nWorkingRecId++;
    }

    panShapeRecordId[nChainId] = -1;

    return -1;
}
예제 #13
0
CEOSRecord * CEOSReadRecord( CEOSImage *psImage )

{
    GByte	abyHeader[12];
    CEOSRecord  *psRecord;

/* -------------------------------------------------------------------- */
/*      Read the standard CEOS header.                                  */
/* -------------------------------------------------------------------- */
    if( VSIFEofL( psImage->fpImage ) )
        return NULL;

    if( VSIFReadL( abyHeader, 1, 12, psImage->fpImage ) != 12 )
    {
        CPLError( CE_Failure, CPLE_FileIO,
                  "Ran out of data reading CEOS record." );
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Extract this information.                                       */
/* -------------------------------------------------------------------- */
    psRecord = (CEOSRecord *) CPLMalloc(sizeof(CEOSRecord));
    if( psImage->bLittleEndian )
    {
        CPL_SWAP32PTR( abyHeader + 0 );
        CPL_SWAP32PTR( abyHeader + 8 );
    }

    psRecord->nRecordNum = abyHeader[0] * 256 * 256 * 256
                         + abyHeader[1] * 256 * 256
                         + abyHeader[2] * 256
                         + abyHeader[3];

    psRecord->nRecordType = abyHeader[4] * 256 * 256 * 256
                          + abyHeader[5] * 256 * 256
                          + abyHeader[6] * 256
                          + abyHeader[7];

    psRecord->nLength = abyHeader[8]  * 256 * 256 * 256
                      + abyHeader[9]  * 256 * 256
                      + abyHeader[10] * 256
                      + abyHeader[11];

/* -------------------------------------------------------------------- */
/*      Does it look reasonable?  We assume there can't be too many     */
/*      records and that the length must be between 12 and 200000.      */
/* -------------------------------------------------------------------- */
    if( psRecord->nRecordNum < 0 || psRecord->nRecordNum > 200000
        || psRecord->nLength < 12 || psRecord->nLength > 200000 )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "CEOS record leader appears to be corrupt.\n"
                  "Record Number = %d, Record Length = %d\n",
                  psRecord->nRecordNum, psRecord->nLength );
        CPLFree( psRecord );
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Read the remainder of the record into a buffer.  Ensure that    */
/*      the first 12 bytes gets moved into this buffer as well.         */
/* -------------------------------------------------------------------- */
    psRecord->pachData = (char *) VSIMalloc(psRecord->nLength );
    if( psRecord->pachData == NULL )
    {
        CPLError( CE_Failure, CPLE_OutOfMemory,
                  "Out of memory allocated %d bytes for CEOS record data.\n"
                  "Are you sure you aren't leaking CEOSRecords?\n",
                  psRecord->nLength );
        CPLFree( psRecord );
        return NULL;
    }

    memcpy( psRecord->pachData, abyHeader, 12 );

    if( (int)VSIFReadL( psRecord->pachData + 12, 1, psRecord->nLength-12, 
                       psImage->fpImage )
        != psRecord->nLength - 12 )
    {
        CPLError( CE_Failure, CPLE_FileIO,
                  "Short read on CEOS record data.\n" );
        CPLFree( psRecord );
        return NULL;
    }

    return psRecord;
}
예제 #14
0
파일: rdataset.cpp 프로젝트: ksshannon/gdal
GDALDataset *RDataset::Open( GDALOpenInfo * poOpenInfo )
{
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
    if( poOpenInfo->pabyHeader == nullptr )
        return nullptr;
#else
    // During fuzzing, do not use Identify to reject crazy content.
    if( !Identify(poOpenInfo) )
        return nullptr;
#endif

    // Confirm the requested access is supported.
    if( poOpenInfo->eAccess == GA_Update )
    {
        CPLError(CE_Failure, CPLE_NotSupported,
                 "The R driver does not support update access to existing"
                 " datasets.");
        return nullptr;
    }

    // Do we need to route the file through the decompression machinery?
    const bool bCompressed =
        memcmp(poOpenInfo->pabyHeader, "\037\213\b", 3) == 0;
    const CPLString osAdjustedFilename =
        std::string(bCompressed ? "/vsigzip/" : "") + poOpenInfo->pszFilename;

    // Establish this as a dataset and open the file using VSI*L.
    RDataset *poDS = new RDataset();

    poDS->fp = VSIFOpenL(osAdjustedFilename, "r");
    if( poDS->fp == nullptr )
    {
        delete poDS;
        return nullptr;
    }

    poDS->bASCII = STARTS_WITH_CI(
        reinterpret_cast<char *>(poOpenInfo->pabyHeader), "RDA2\nA\n");

    // Confirm this is a version 2 file.
    VSIFSeekL(poDS->fp, 7, SEEK_SET);
    if( poDS->ReadInteger() != R_LISTSXP )
    {
        delete poDS;
        CPLError(CE_Failure, CPLE_OpenFailed,
                 "It appears %s is not a version 2 R object file after all!",
                 poOpenInfo->pszFilename);
        return nullptr;
    }

    // Skip the version values.
    poDS->ReadInteger();
    poDS->ReadInteger();

    // Confirm we have a numeric vector object in a pairlist.
    CPLString osObjName;
    int nObjCode = 0;

    if( !poDS->ReadPair(osObjName, nObjCode) )
    {
        delete poDS;
        return nullptr;
    }

    if( nObjCode % 256 != R_REALSXP )
    {
        delete poDS;
        CPLError(CE_Failure, CPLE_OpenFailed,
                 "Failed to find expected numeric vector object.");
        return nullptr;
    }

    poDS->SetMetadataItem("R_OBJECT_NAME", osObjName);

    // Read the count.
    const int nValueCount = poDS->ReadInteger();
    if( nValueCount < 0 )
    {
        CPLError(
            CE_Failure, CPLE_AppDefined, "nValueCount < 0: %d", nValueCount);
        delete poDS;
        return nullptr;
    }

    poDS->nStartOfData = VSIFTellL(poDS->fp);

    // TODO(schwehr): Factor in the size of doubles.
    VSIStatBufL stat;
    const int dStatSuccess =
        VSIStatExL(osAdjustedFilename, &stat, VSI_STAT_SIZE_FLAG);
    if( dStatSuccess != 0 ||
        static_cast<vsi_l_offset>(nValueCount) >
        stat.st_size - poDS->nStartOfData )
    {
        CPLError(
            CE_Failure, CPLE_AppDefined,
            "Corrupt file.  "
            "Object claims to be larger than available bytes. "
            "%d > " CPL_FRMT_GUIB,
            nValueCount,
            stat.st_size - poDS->nStartOfData);
        delete poDS;
        return nullptr;
    }

    // Read/Skip ahead to attributes.
    if( poDS->bASCII )
    {
        poDS->padfMatrixValues =
            static_cast<double *>(VSIMalloc2(nValueCount, sizeof(double)));
        if (poDS->padfMatrixValues == nullptr)
        {
            CPLError(CE_Failure, CPLE_AppDefined,
                     "Cannot allocate %d doubles", nValueCount);
            delete poDS;
            return nullptr;
        }
        for( int iValue = 0; iValue < nValueCount; iValue++ )
            poDS->padfMatrixValues[iValue] = poDS->ReadFloat();
    }
    else
    {
        VSIFSeekL(poDS->fp, 8 * nValueCount, SEEK_CUR);
    }

    // Read pairs till we run out, trying to find a few items that
    // have special meaning to us.
    poDS->nRasterXSize = 0;
    poDS->nRasterYSize = 0;
    int nBandCount = 0;

    while( poDS->ReadPair(osObjName, nObjCode) && nObjCode != 254 )
    {
        if( osObjName == "dim" && nObjCode % 256 == R_INTSXP )
        {
            const int nCount = poDS->ReadInteger();
            if( nCount == 2 )
            {
                poDS->nRasterXSize = poDS->ReadInteger();
                poDS->nRasterYSize = poDS->ReadInteger();
                nBandCount = 1;
            }
            else if( nCount == 3 )
            {
                poDS->nRasterXSize = poDS->ReadInteger();
                poDS->nRasterYSize = poDS->ReadInteger();
                nBandCount = poDS->ReadInteger();
            }
            else
            {
                CPLError(CE_Failure, CPLE_AppDefined,
                         "R 'dim' dimension wrong.");
                delete poDS;
                return nullptr;
            }
        }
        else if( nObjCode % 256 == R_REALSXP )
        {
            int nCount = poDS->ReadInteger();
            while( nCount > 0 && !VSIFEofL(poDS->fp) )
            {
                nCount --;
                poDS->ReadFloat();
            }
        }
        else if( nObjCode % 256 == R_INTSXP )
        {
            int nCount = poDS->ReadInteger();
            while( nCount > 0 && !VSIFEofL(poDS->fp) )
            {
                nCount --;
                poDS->ReadInteger();
            }
        }
        else if( nObjCode % 256 == R_STRSXP )
        {
            int nCount = poDS->ReadInteger();
            while( nCount > 0 && !VSIFEofL(poDS->fp) )
            {
                nCount --;
                poDS->ReadString();
            }
        }
        else if( nObjCode % 256 == R_CHARSXP )
        {
            poDS->ReadString();
        }
    }

    if( poDS->nRasterXSize == 0 )
    {
        delete poDS;
        CPLError(CE_Failure, CPLE_AppDefined,
                 "Failed to find dim dimension information for R dataset.");
        return nullptr;
    }

    if (!GDALCheckDatasetDimensions(poDS->nRasterXSize, poDS->nRasterYSize) ||
        !GDALCheckBandCount(nBandCount, TRUE))
    {
        delete poDS;
        return nullptr;
    }

    GIntBig result = 0;
    bool ok = SafeMult(nBandCount, poDS->nRasterXSize, &result);
    ok &= SafeMult(result, poDS->nRasterYSize, &result);

    if( !ok || nValueCount <  result )
    {
        CPLError(CE_Failure, CPLE_AppDefined, "Not enough pixel data.");
        delete poDS;
        return nullptr;
    }

    // Create the raster band object(s).
    for( int iBand = 0; iBand < nBandCount; iBand++ )
    {
        GDALRasterBand *poBand = nullptr;

        if( poDS->bASCII )
            poBand = new RRasterBand(
                poDS, iBand + 1,
                poDS->padfMatrixValues +
                    iBand * poDS->nRasterXSize * poDS->nRasterYSize);
        else
            poBand = new RawRasterBand(
                poDS, iBand + 1, poDS->fp,
                poDS->nStartOfData +
                    poDS->nRasterXSize * poDS->nRasterYSize * 8 * iBand,
                8, poDS->nRasterXSize * 8,
                GDT_Float64, !CPL_IS_LSB,
                TRUE, FALSE);

        poDS->SetBand(iBand + 1, poBand);
    }

    // Initialize any PAM information.
    poDS->SetDescription(poOpenInfo->pszFilename);
    poDS->TryLoadXML();

    // Check for overviews.
    poDS->oOvManager.Initialize(poDS, poOpenInfo->pszFilename);

    return poDS;
}
예제 #15
0
int TigerCompleteChain::AddShapePoints( int nTLID, int nRecordId,
                                        OGRLineString * poLine, CPL_UNUSED int nSeqNum )
{
    int         nShapeRecId;

    nShapeRecId = GetShapeRecordId( nRecordId, nTLID );

    // -2 means an error occured.
    if( nShapeRecId == -2 )
        return FALSE;

    // -1 means there are no extra shape vertices, but things worked fine.
    if( nShapeRecId == -1 )
        return TRUE;

/* -------------------------------------------------------------------- */
/*      Read all the sequential records with the same TLID.             */
/* -------------------------------------------------------------------- */
    char        achShapeRec[OGR_TIGER_RECBUF_LEN];
    int         nShapeRecLen = psRT2Info->nRecordLength + nRecordLength - psRT1Info->nRecordLength;

    for( ; TRUE; nShapeRecId++ )
    {
        int  nBytesRead = 0;

        if( VSIFSeekL( fpShape, (nShapeRecId-1) * nShapeRecLen,
                      SEEK_SET ) != 0 )
        {
            CPLError( CE_Failure, CPLE_FileIO,
                      "Failed to seek to %d of %s2",
                      (nShapeRecId-1) * nShapeRecLen, pszModule );
            return FALSE;
        }

        nBytesRead = VSIFReadL( achShapeRec, 1, psRT2Info->nRecordLength, 
                                fpShape );

        /* 
        ** Handle case where the last record in the file is full.  We will
        ** try to read another record but not find it.  We require that we
        ** have found at least one shape record for this case though. 
        */
        if( nBytesRead <= 0 && VSIFEofL( fpShape ) 
            && poLine->getNumPoints() > 0 )
            break;

        if( nBytesRead != psRT2Info->nRecordLength )
        {
            CPLError( CE_Failure, CPLE_FileIO,
                      "Failed to read %d bytes of record %d of %s2 at offset %d",
                      psRT2Info->nRecordLength, nShapeRecId, pszModule,
                      (nShapeRecId-1) * nShapeRecLen );
            return FALSE;
        }

        if( atoi(GetField(achShapeRec,6,15)) != nTLID )
            break;

/* -------------------------------------------------------------------- */
/*      Translate the locations into OGRLineString vertices.            */
/* -------------------------------------------------------------------- */
        int     iVertex;

        for( iVertex = 0; iVertex < 10; iVertex++ )
        {
            int         iStart = 19 + 19*iVertex;
            int         nX = atoi(GetField(achShapeRec,iStart,iStart+9));
            int         nY = atoi(GetField(achShapeRec,iStart+10,iStart+18));

            if( nX == 0 && nY == 0 )
                break;

            poLine->addPoint( nX / 1000000.0, nY / 1000000.0 );
        }

/* -------------------------------------------------------------------- */
/*      Don't get another record if this one was incomplete.            */
/* -------------------------------------------------------------------- */
        if( iVertex < 10 )
            break;
    }

    return TRUE;
}
예제 #16
0
int VSISubFileHandle::Eof()

{
    return VSIFEofL( fp );
}
예제 #17
0
OGRFeature *OGRSVGLayer::GetNextFeature()
{
    GetLayerDefn();

    if (fpSVG == NULL)
        return NULL;

    if (bStopParsing)
        return NULL;

#ifdef HAVE_EXPAT
    if (nFeatureTabIndex < nFeatureTabLength)
    {
        return ppoFeatureTab[nFeatureTabIndex++];
    }

    if (VSIFEofL(fpSVG))
        return NULL;

    char aBuf[BUFSIZ];

    CPLFree(ppoFeatureTab);
    ppoFeatureTab = NULL;
    nFeatureTabLength = 0;
    nFeatureTabIndex = 0;
    nWithoutEventCounter = 0;
    iCurrentField = -1;

    int nDone;
    do
    {
        nDataHandlerCounter = 0;
        unsigned int nLen = (unsigned int)
                    VSIFReadL( aBuf, 1, sizeof(aBuf), fpSVG );
        nDone = VSIFEofL(fpSVG);
        if (XML_Parse(oParser, aBuf, nLen, nDone) == XML_STATUS_ERROR)
        {
            CPLError(CE_Failure, CPLE_AppDefined,
                     "XML parsing of SVG file failed : %s at line %d, column %d",
                     XML_ErrorString(XML_GetErrorCode(oParser)),
                     (int)XML_GetCurrentLineNumber(oParser),
                     (int)XML_GetCurrentColumnNumber(oParser));
            bStopParsing = TRUE;
            break;
        }
        nWithoutEventCounter ++;
    } while (!nDone && nFeatureTabLength == 0 && !bStopParsing &&
             nWithoutEventCounter < 1000);

    if (nWithoutEventCounter == 1000)
    {
        CPLError(CE_Failure, CPLE_AppDefined,
                 "Too much data inside one element. File probably corrupted");
        bStopParsing = TRUE;
    }

    return (nFeatureTabLength) ? ppoFeatureTab[nFeatureTabIndex++] : NULL;
#else
    return NULL;
#endif
}
예제 #18
0
파일: ogrjmllayer.cpp 프로젝트: OSGeo/gdal
/** This function parses the beginning of the file to detect the fields */
void OGRJMLLayer::LoadSchema()
{
    if (bHasReadSchema)
        return;

    bHasReadSchema = true;

    oParser = OGRCreateExpatXMLParser();
    XML_SetElementHandler(oParser, ::startElementLoadSchemaCbk,
                          ::endElementLoadSchemaCbk);
    XML_SetCharacterDataHandler(oParser, ::dataHandlerCbk);
    XML_SetUserData(oParser, this);

    VSIFSeekL( fp, 0, SEEK_SET );

    char aBuf[BUFSIZ];
    int nDone = 0;
    do
    {
        nDataHandlerCounter = 0;
        const unsigned int nLen = static_cast<unsigned int>(
            VSIFReadL( aBuf, 1, sizeof(aBuf), fp ) );
        nDone = VSIFEofL(fp);
        if (XML_Parse(oParser, aBuf, nLen, nDone) == XML_STATUS_ERROR)
        {
            CPLError( CE_Failure, CPLE_AppDefined,
                      "XML parsing of JML file failed : %s at line %d, "
                      "column %d",
                      XML_ErrorString(XML_GetErrorCode(oParser)),
                      static_cast<int>(XML_GetCurrentLineNumber(oParser)),
                      static_cast<int>(XML_GetCurrentColumnNumber(oParser)) );
            bStopParsing = true;
        }
        nWithoutEventCounter ++;
    } while ( !nDone && !bStopParsing && !bSchemaFinished &&
              nWithoutEventCounter < 10 );

    XML_ParserFree(oParser);
    oParser = nullptr;

    if (nWithoutEventCounter == 10)
    {
        CPLError(CE_Failure, CPLE_AppDefined,
                 "Too much data inside one element. File probably corrupted");
        bStopParsing = true;
    }

    if( osCollectionElement.empty() || osFeatureElement.empty() ||
        osGeometryElement.empty() )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Missing CollectionElement, FeatureElement or "
                  "GeometryElement" );
        bStopParsing = true;
    }

    if( !osSRSName.empty() )
    {
        if( osSRSName.find("http://www.opengis.net/gml/srs/epsg.xml#") == 0 )
        {
            OGRSpatialReference* poSRS = new OGRSpatialReference();
            poSRS->importFromEPSG(atoi(osSRSName.substr(
                strlen("http://www.opengis.net/gml/srs/epsg.xml#")).c_str()));
            poSRS->SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER);
            poFeatureDefn->GetGeomFieldDefn(0)->SetSpatialRef(poSRS);
            poSRS->Release();
        }
    }

    nJCSGMLInputTemplateDepth = 0;
    nCollectionElementDepth = 0;
    nFeatureCollectionDepth = 0;
    nFeatureElementDepth = 0;
    nGeometryElementDepth = 0;
    nColumnDepth = 0;
    nNameDepth = 0;
    nTypeDepth = 0;
    nAttributeElementDepth = 0;

    ResetReading();
}
예제 #19
0
int OGRSVGDataSource::Open( const char * pszFilename, int bUpdateIn)

{
    if (bUpdateIn)
    {
        CPLError(CE_Failure, CPLE_NotSupported,
                    "OGR/SVG driver does not support opening a file in update mode");
        return FALSE;
    }
#ifdef HAVE_EXPAT
    pszName = CPLStrdup( pszFilename );

/* -------------------------------------------------------------------- */
/*      Try to open the file.                                           */
/* -------------------------------------------------------------------- */
    CPLString osFilename(pszFilename);
    if (EQUAL(CPLGetExtension(pszFilename), "svgz") &&
        strstr(pszFilename, "/vsigzip/") == NULL)
    {
        osFilename = CPLString("/vsigzip/") + pszFilename;
        pszFilename = osFilename.c_str();
    }

    VSILFILE* fp = VSIFOpenL(pszFilename, "r");
    if (fp == NULL)
        return FALSE;
    
    eValidity = SVG_VALIDITY_UNKNOWN;

    XML_Parser oParser = OGRCreateExpatXMLParser();
    oCurrentParser = oParser;
    XML_SetUserData(oParser, this);
    XML_SetElementHandler(oParser, ::startElementValidateCbk, NULL);
    XML_SetCharacterDataHandler(oParser, ::dataHandlerValidateCbk);
    
    char aBuf[BUFSIZ];
    int nDone;
    unsigned int nLen;
    int nCount = 0;
    
    /* Begin to parse the file and look for the <svg> element */
    /* It *MUST* be the first element of an XML file */
    /* So once we have read the first element, we know if we can */
    /* handle the file or not with that driver */
    do
    {
        nDataHandlerCounter = 0;
        nLen = (unsigned int) VSIFReadL( aBuf, 1, sizeof(aBuf), fp );
        nDone = VSIFEofL(fp);
        if (XML_Parse(oParser, aBuf, nLen, nDone) == XML_STATUS_ERROR)
        {
            if (nLen <= BUFSIZ-1)
                aBuf[nLen] = 0;
            else
                aBuf[BUFSIZ-1] = 0;
            if (strstr(aBuf, "<?xml") && strstr(aBuf, "<svg"))
            {
                CPLError(CE_Failure, CPLE_AppDefined,
                        "XML parsing of SVG file failed : %s at line %d, column %d",
                        XML_ErrorString(XML_GetErrorCode(oParser)),
                        (int)XML_GetCurrentLineNumber(oParser),
                        (int)XML_GetCurrentColumnNumber(oParser));
            }
            eValidity = SVG_VALIDITY_INVALID;
            break;
        }
        if (eValidity == SVG_VALIDITY_INVALID)
        {
            break;
        }
        else if (eValidity == SVG_VALIDITY_VALID)
        {
            break;
        }
        else
        {
            /* After reading 50 * BUFSIZE bytes, and not finding whether the file */
            /* is SVG or not, we give up and fail silently */
            nCount ++;
            if (nCount == 50)
                break;
        }
    } while (!nDone && nLen > 0 );

    XML_ParserFree(oParser);

    VSIFCloseL(fp);

    if (eValidity == SVG_VALIDITY_VALID)
    {
        if (bIsCloudmade)
        {
            nLayers = 3;
            papoLayers =(OGRSVGLayer **) CPLRealloc(papoLayers,
                                            nLayers * sizeof(OGRSVGLayer*));
            papoLayers[0] = new OGRSVGLayer( pszFilename, "points", SVG_POINTS, this );
            papoLayers[1] = new OGRSVGLayer( pszFilename, "lines", SVG_LINES, this );
            papoLayers[2] = new OGRSVGLayer( pszFilename, "polygons", SVG_POLYGONS, this );
        }
        else
        {
            CPLDebug("SVG",
                     "%s seems to be a SVG file, but not a Cloudmade vector one.",
                     pszFilename);
        }
    }

    return (nLayers > 0);
#else
    char aBuf[256];
    VSILFILE* fp = VSIFOpenL(pszFilename, "r");
    if (fp)
    {
        unsigned int nLen = (unsigned int)VSIFReadL( aBuf, 1, 255, fp );
        aBuf[nLen] = 0;
        if (strstr(aBuf, "<?xml") && strstr(aBuf, "<svg") &&
            strstr(aBuf, "http://cloudmade.com/"))
        {
            CPLError(CE_Failure, CPLE_NotSupported,
                    "OGR/SVG driver has not been built with read support. "
                    "Expat library required");
        }
        VSIFCloseL(fp);
    }
    return FALSE;
#endif
}
예제 #20
0
CEOSRecord * CEOSReadRecord( CEOSImage *psImage )

{
    GByte	abyHeader[12];
    CEOSRecord  *psRecord;
    GUInt32 nRecordNumUInt32, nLengthUInt32;

/* -------------------------------------------------------------------- */
/*      Read the standard CEOS header.                                  */
/* -------------------------------------------------------------------- */
    if( VSIFEofL( psImage->fpImage ) )
        return NULL;

    if( VSIFReadL( abyHeader, 1, 12, psImage->fpImage ) != 12 )
    {
        CPLError( CE_Failure, CPLE_FileIO,
                  "Ran out of data reading CEOS record." );
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Extract this information.                                       */
/* -------------------------------------------------------------------- */
    psRecord = (CEOSRecord *) CPLMalloc(sizeof(CEOSRecord));
    if( psImage->bLittleEndian )
    {
        CPL_SWAP32PTR( abyHeader + 0 );
        CPL_SWAP32PTR( abyHeader + 8 );
    }

    nRecordNumUInt32 = (abyHeader[0] << 24)
                         + (abyHeader[1] << 16)
                         + (abyHeader[2] << 8)
                         + abyHeader[3];

    psRecord->nRecordType = (abyHeader[4] << 24)
                         + (abyHeader[5] << 16)
                         + (abyHeader[6] << 8)
                         + abyHeader[7];

    nLengthUInt32 = (abyHeader[8] << 24)
                         + (abyHeader[9] << 16)
                         + (abyHeader[10] << 8)
                         + abyHeader[11];

/* -------------------------------------------------------------------- */
/*      Does it look reasonable?  We assume there can't be too many     */
/*      records and that the length must be between 12 and 200000.      */
/* -------------------------------------------------------------------- */
    if( nRecordNumUInt32 > 200000
        || nLengthUInt32 < 12 || nLengthUInt32 > 200000 )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "CEOS record leader appears to be corrupt.\n"
                  "Record Number = %u, Record Length = %u\n",
                  nRecordNumUInt32, nLengthUInt32 );
        CPLFree( psRecord );
        return NULL;
    }

    psRecord->nRecordNum = (int)nRecordNumUInt32;
    psRecord->nLength = (int)nLengthUInt32;

/* -------------------------------------------------------------------- */
/*      Read the remainder of the record into a buffer.  Ensure that    */
/*      the first 12 bytes gets moved into this buffer as well.         */
/* -------------------------------------------------------------------- */
    psRecord->pachData = (char *) VSI_MALLOC_VERBOSE(psRecord->nLength );
    if( psRecord->pachData == NULL )
    {
        CPLFree( psRecord );
        return NULL;
    }

    memcpy( psRecord->pachData, abyHeader, 12 );

    if( (int)VSIFReadL( psRecord->pachData + 12, 1, psRecord->nLength-12,
                       psImage->fpImage )
        != psRecord->nLength - 12 )
    {
        CPLError( CE_Failure, CPLE_FileIO,
                  "Short read on CEOS record data.\n" );
        CPLFree( psRecord );
        return NULL;
    }

    return psRecord;
}
예제 #21
0
CPLErr GSAGDataset::ShiftFileContents( VSILFILE *fp, vsi_l_offset nShiftStart,
				       int nShiftSize, const char *pszEOL )
{
    /* nothing to do for zero-shift */
    if( nShiftSize == 0 )
	return CE_None;

    /* make sure start location is sane */
    if( nShiftStart < 0
	|| (nShiftSize < 0
	    && nShiftStart < static_cast<vsi_l_offset>(-nShiftSize)) )
	nShiftStart = (nShiftSize > 0) ? 0 : -nShiftSize;

    /* get offset at end of file */
    if( VSIFSeekL( fp, 0, SEEK_END ) != 0 )
    {
	CPLError( CE_Failure, CPLE_FileIO,
		  "Unable to seek to end of grid file.\n" );
	return CE_Failure;
    }

    vsi_l_offset nOldEnd = VSIFTellL( fp );

    /* If shifting past end, just zero-pad as necessary */
    if( nShiftStart >= nOldEnd )
    {
	if( nShiftSize < 0 )
	{
	    if( nShiftStart + nShiftSize >= nOldEnd )
		return CE_None;

	    if( VSIFSeekL( fp, nShiftStart + nShiftSize, SEEK_SET ) != 0 )
	    {
		CPLError( CE_Failure, CPLE_FileIO,
			  "Unable to seek near end of file.\n" );
		return CE_Failure;
	    }

	    /* ftruncate()? */
	    for( vsi_l_offset nPos = nShiftStart + nShiftSize;
		 nPos > nOldEnd; nPos++ )
	    {
		if( VSIFWriteL( (void *)" ", 1, 1, fp ) != 1 )
		{
		    CPLError( CE_Failure, CPLE_FileIO,
			      "Unable to write padding to grid file "
			      "(Out of space?).\n" );
		    return CE_Failure;
		}
	    }

	    return CE_None;
	}
	else
	{
	    for( vsi_l_offset nPos = nOldEnd;
		 nPos < nShiftStart + nShiftSize; nPos++ )
	    {
		if( VSIFWriteL( (void *)" ", 1, 1, fp ) != 1 )
		{
		    CPLError( CE_Failure, CPLE_FileIO,
			      "Unable to write padding to grid file "
			      "(Out of space?).\n" );
		    return CE_Failure;
		}
	    }
	    return CE_None;
	}
    }

    /* prepare buffer for real shifting */
    size_t nBufferSize = (1024 >= abs(nShiftSize)*2) ? 1024 : abs(nShiftSize)*2;
    char *pabyBuffer = (char *)VSIMalloc( nBufferSize );
    if( pabyBuffer == NULL)
    {
	CPLError( CE_Failure, CPLE_OutOfMemory,
		  "Unable to allocate space for shift buffer.\n" );
	return CE_Failure;
    }

    if( VSIFSeekL( fp, nShiftStart, SEEK_SET ) != 0 )
    {
	VSIFree( pabyBuffer );
	CPLError( CE_Failure, CPLE_FileIO,
		  "Unable to seek to start of shift in grid file.\n" );
	return CE_Failure;
    }

    size_t nRead;
    size_t nOverlap = (nShiftSize > 0) ? nShiftSize : 0;
    /* If there is overlap, fill buffer with the overlap to start */
    if( nOverlap > 0)
    {
	nRead = VSIFReadL( (void *)pabyBuffer, 1, nOverlap, fp );
	if( nRead < nOverlap && !VSIFEofL( fp ) )
	{
	    VSIFree( pabyBuffer );
	    CPLError( CE_Failure, CPLE_FileIO,
		      "Error reading grid file.\n" );
	    return CE_Failure;
	}

	/* overwrite the new space with ' ' */
    	if( VSIFSeekL( fp, nShiftStart, SEEK_SET ) != 0 )
	{
	    VSIFree( pabyBuffer );
	    CPLError( CE_Failure, CPLE_FileIO,
		      "Unable to seek to start of shift in grid file.\n" );
	    return CE_Failure;
	}

	for( int iFill=0; iFill<nShiftSize; iFill++ )
	{
	    if( VSIFWriteL( (void *)" ", 1, 1, fp ) != 1 )
	    {
		VSIFree( pabyBuffer );
		CPLError( CE_Failure, CPLE_FileIO,
			  "Unable to write padding to grid file "
			  "(Out of space?).\n" );
		return CE_Failure;
	    }
	}

	/* if we have already read the entire file, finish it off */
	if( VSIFTellL( fp ) >= nOldEnd )
	{
	    if( VSIFWriteL( (void *)pabyBuffer, 1, nRead, fp ) != nRead )
	    {
		VSIFree( pabyBuffer );
		CPLError( CE_Failure, CPLE_FileIO,
			  "Unable to write to grid file (Out of space?).\n" );
		return CE_Failure;
	    }

	    VSIFree( pabyBuffer );
	    return CE_None;
	}
    }

    /* iterate over the remainder of the file and shift as requested */
    bool bEOF = false;
    while( !bEOF )
    {
	nRead = VSIFReadL( (void *)(pabyBuffer+nOverlap), 1,
			   nBufferSize - nOverlap, fp );

        if( VSIFEofL( fp ) )
            bEOF = true;
        else 
            bEOF = false;

	if( nRead == 0 && !bEOF )
	{
	    VSIFree( pabyBuffer );
	    CPLError( CE_Failure, CPLE_FileIO,
		      "Unable to read from grid file (possible corruption).\n");
	    return CE_Failure;
	}

	/* FIXME:  Should use SEEK_CUR, review integer promotions... */
	if( VSIFSeekL( fp, VSIFTellL(fp)-nRead+nShiftSize-nOverlap,
		       SEEK_SET ) != 0 )
	{
	    VSIFree( pabyBuffer );
	    CPLError( CE_Failure, CPLE_FileIO,
		      "Unable to seek in grid file (possible corruption).\n" );
	    return CE_Failure;
	}

	size_t nWritten = VSIFWriteL( (void *)pabyBuffer, 1, nRead, fp );
	if( nWritten != nRead )
	{
	    VSIFree( pabyBuffer );
	    CPLError( CE_Failure, CPLE_FileIO,
		      "Unable to write to grid file (out of space?).\n" );
	    return CE_Failure;
	}

	/* shift overlapped contents to the front of the buffer if necessary */
	if( nOverlap > 0)
	    memmove(pabyBuffer, pabyBuffer+nRead, nOverlap);
    }

    /* write the remainder of the buffer or overwrite leftovers and finish */
    if( nShiftSize > 0 )
    {
	size_t nTailSize = nOverlap;
	while( nTailSize > 0 && isspace( (unsigned char)pabyBuffer[nTailSize-1] ) )
	    nTailSize--;

	if( VSIFWriteL( (void *)pabyBuffer, 1, nTailSize, fp ) != nTailSize )
	{
	    VSIFree( pabyBuffer );
	    CPLError( CE_Failure, CPLE_FileIO,
		      "Unable to write to grid file (out of space?).\n" );
	    return CE_Failure;
	}

	if( VSIFWriteL( (void *)pszEOL, 1, strlen(pszEOL), fp )
            != strlen(pszEOL) )
	{
	    VSIFree( pabyBuffer );
	    CPLError( CE_Failure, CPLE_FileIO,
		      "Unable to write to grid file (out of space?).\n" );
	    return CE_Failure;
	}
    }
    else
    {
	/* FIXME: ftruncate()? */
	/* FIXME:  Should use SEEK_CUR, review integer promotions... */
	if( VSIFSeekL( fp, VSIFTellL(fp)-strlen(pszEOL), SEEK_SET ) != 0 )
	{
	    VSIFree( pabyBuffer );
	    CPLError( CE_Failure, CPLE_FileIO,
		      "Unable to seek in grid file.\n" );
	    return CE_Failure;
	}

	for( int iPadding=0; iPadding<-nShiftSize; iPadding++ )
	{
	    if( VSIFWriteL( (void *)" ", 1, 1, fp ) != 1 )
	    {
		VSIFree( pabyBuffer );
		CPLError( CE_Failure, CPLE_FileIO,
			  "Error writing to grid file.\n" );
		return CE_Failure;
	    }
	}

	if( VSIFWriteL( (void *)pszEOL, 1, strlen(pszEOL), fp )
            != strlen(pszEOL) )
	{
	    VSIFree( pabyBuffer );
	    CPLError( CE_Failure, CPLE_FileIO,
		      "Unable to write to grid file (out of space?).\n" );
	    return CE_Failure;
	}
    }

    VSIFree( pabyBuffer );
    return CE_None;
}
예제 #22
0
void KML::checkValidity()
{
    std::size_t nDone = 0;
    std::size_t nLen = 0;
    char aBuf[BUFSIZ] = { 0 };

    if(poTrunk_ != NULL)
    {
        delete poTrunk_;
        poTrunk_ = NULL;
    }

    if(poCurrent_ != NULL)
    {
        delete poCurrent_;
        poCurrent_ = NULL;
    }

    if(pKMLFile_ == NULL)
    {
        this->sError_ = "No file given";
        return;
    }

    XML_Parser oParser = OGRCreateExpatXMLParser();
    XML_SetUserData(oParser, this);
    XML_SetElementHandler(oParser, startElementValidate, NULL);
    XML_SetCharacterDataHandler(oParser, dataHandlerValidate);
    int nCount = 0;

    oCurrentParser = oParser;

    /* Parses the file until we find the first element */
    do
    {
        nDataHandlerCounter = 0;
        nLen = (int)VSIFReadL( aBuf, 1, sizeof(aBuf), pKMLFile_ );
        nDone = VSIFEofL(pKMLFile_);
        if (XML_Parse(oParser, aBuf, nLen, nDone) == XML_STATUS_ERROR)
        {
            if (nLen <= BUFSIZ-1)
                aBuf[nLen] = 0;
            else
                aBuf[BUFSIZ-1] = 0;
            if (strstr(aBuf, "<?xml") && strstr(aBuf, "<kml"))
            {
                CPLError(CE_Failure, CPLE_AppDefined,
                        "XML parsing of KML file failed : %s at line %d, column %d",
                        XML_ErrorString(XML_GetErrorCode(oParser)),
                        (int)XML_GetCurrentLineNumber(oParser),
                        (int)XML_GetCurrentColumnNumber(oParser));
            }

            validity = KML_VALIDITY_INVALID;
            XML_ParserFree(oParser);
            VSIRewindL(pKMLFile_);
            return;
        }

        nCount ++;
        /* After reading 50 * BUFSIZE bytes, and not finding whether the file */
        /* is KML or not, we give up and fail silently */
    } while (!nDone && nLen > 0 && validity == KML_VALIDITY_UNKNOWN && nCount < 50);

    XML_ParserFree(oParser);
    VSIRewindL(pKMLFile_);
    poCurrent_ = NULL;
}
예제 #23
0
CPLErr RIKRasterBand::IReadBlock( int nBlockXOff, int nBlockYOff,
                                  void * pImage )

{
    RIKDataset *poRDS = (RIKDataset *) poDS;
    GByte *blockData;
    GUInt32 blocks;
    GUInt32 nBlockIndex;
    GUInt32 nBlockOffset;
    GUInt32 nBlockSize;

    blocks = poRDS->nHorBlocks * poRDS->nVertBlocks;
    nBlockIndex = nBlockXOff + nBlockYOff * poRDS->nHorBlocks;
    nBlockOffset = poRDS->pOffsets[nBlockIndex];

    nBlockSize = poRDS->nFileSize;
    for( GUInt32 bi = nBlockIndex + 1; bi < blocks; bi++ )
    {
        if( poRDS->pOffsets[bi] )
        {
            nBlockSize = poRDS->pOffsets[bi];
            break;
        }
    }
    nBlockSize -= nBlockOffset;

    GUInt32 pixels;

    pixels = poRDS->nBlockXSize * poRDS->nBlockYSize;

    if( !nBlockOffset || !nBlockSize
#ifdef RIK_SINGLE_BLOCK
        || nBlockIndex != RIK_SINGLE_BLOCK
#endif
        )
    {
        for( GUInt32 i = 0; i < pixels; i++ )
        ((GByte *) pImage)[i] = 0;
        return CE_None;
    }

    VSIFSeekL( poRDS->fp, nBlockOffset, SEEK_SET );

/* -------------------------------------------------------------------- */
/*      Read uncompressed block.                                        */
/* -------------------------------------------------------------------- */

    if( poRDS->options == 0x00 || poRDS->options == 0x40 )
    {
        VSIFReadL( pImage, 1, nBlockSize, poRDS->fp );
        return CE_None;
    }

    // Read block to memory
    blockData = (GByte *) CPLMalloc(nBlockSize);
    VSIFReadL( blockData, 1, nBlockSize, poRDS->fp );

    GUInt32 filePos = 0;
    GUInt32 imagePos = 0;

/* -------------------------------------------------------------------- */
/*      Read RLE block.                                                 */
/* -------------------------------------------------------------------- */

    if( poRDS->options == 0x01 ||
        poRDS->options == 0x41 ) do
    {
        GByte count = blockData[filePos++];
        GByte color = blockData[filePos++];

        for (GByte i = 0; i <= count; i++)
        {
            ((GByte *) pImage)[imagePos++] = color;
        }
    } while( filePos < nBlockSize && imagePos < pixels );

/* -------------------------------------------------------------------- */
/*      Read LZW block.                                                 */
/* -------------------------------------------------------------------- */

    else if( poRDS->options == 0x0b )
    {
        const bool LZW_HAS_CLEAR_CODE = !!(blockData[4] & 0x80);
        const int LZW_MAX_BITS = blockData[4] & 0x1f; // Max 13
        const int LZW_BITS_PER_PIXEL = 8;
        const int LZW_OFFSET = 5;

        const int LZW_CLEAR = 1 << LZW_BITS_PER_PIXEL;
        const int LZW_CODES = 1 << LZW_MAX_BITS;
        const int LZW_NO_SUCH_CODE = LZW_CODES + 1;

        int lastAdded = LZW_HAS_CLEAR_CODE ? LZW_CLEAR : LZW_CLEAR - 1;
        int codeBits = LZW_BITS_PER_PIXEL + 1;

        int code;
        int lastCode;
        GByte lastOutput;
        int bitsTaken = 0;

        int prefix[8192];      // only need LZW_CODES for size.
        GByte character[8192]; // only need LZW_CODES for size.

        int i;

        for( i = 0; i < LZW_CLEAR; i++ )
            character[i] = (GByte)i;
        for( i = 0; i < LZW_CODES; i++ )
            prefix[i] = LZW_NO_SUCH_CODE;

        filePos = LZW_OFFSET;
        GUInt32 fileAlign = LZW_OFFSET;
        int imageLine = poRDS->nBlockYSize - 1;

        GUInt32 lineBreak = poRDS->nBlockXSize;

        // 32 bit alignment
        lineBreak += 3;
        lineBreak &= 0xfffffffc;

        code = GetNextLZWCode( codeBits, blockData, filePos,
                               fileAlign, bitsTaken );

        OutputPixel( (GByte)code, pImage, poRDS->nBlockXSize,
                     lineBreak, imageLine, imagePos );
        lastOutput = (GByte)code;

        while( imageLine >= 0 &&
               (imageLine || imagePos < poRDS->nBlockXSize) &&
               filePos < nBlockSize ) try
        {
            lastCode = code;
            code = GetNextLZWCode( codeBits, blockData,
                                   filePos, fileAlign, bitsTaken );
            if( VSIFEofL( poRDS->fp ) )
            {
                CPLFree( blockData );
                CPLError( CE_Failure, CPLE_AppDefined,
                          "RIK decompression failed. "
                          "Read past end of file.\n" );
                return CE_Failure;
            }

            if( LZW_HAS_CLEAR_CODE && code == LZW_CLEAR )
            {
#if RIK_CLEAR_DEBUG
                CPLDebug( "RIK",
                          "Clearing block %d\n"
                          " x=%d y=%d\n"
                          " pos=%d size=%d\n",
                          nBlockIndex,
                          imagePos, imageLine,
                          filePos, nBlockSize );
#endif

                // Clear prefix table
                for( i = LZW_CLEAR; i < LZW_CODES; i++ )
                    prefix[i] = LZW_NO_SUCH_CODE;
                lastAdded = LZW_CLEAR;
                codeBits = LZW_BITS_PER_PIXEL + 1;

                filePos = fileAlign;
                bitsTaken = 0;

                code = GetNextLZWCode( codeBits, blockData,
                                       filePos, fileAlign, bitsTaken );

                if( code > lastAdded )
                {
                    throw "Clear Error";
                }

                OutputPixel( (GByte)code, pImage, poRDS->nBlockXSize,
                             lineBreak, imageLine, imagePos );
                lastOutput = (GByte)code;
            }
            else
            {
                // Set-up decoding

                GByte stack[8192]; // only need LZW_CODES for size.

                int stackPtr = 0;
                int decodeCode = code;

                if( code == lastAdded + 1 )
                {
                    // Handle special case
                    *stack = lastOutput;
                    stackPtr = 1;
                    decodeCode = lastCode;
       	        }
                else if( code > lastAdded + 1 )
                {
                    throw "Too high code";
                }

                // Decode

                i = 0;
                while( ++i < LZW_CODES &&
       	               decodeCode >= LZW_CLEAR &&
       	               decodeCode < LZW_NO_SUCH_CODE )
                {
                    stack[stackPtr++] = character[decodeCode];
                    decodeCode = prefix[decodeCode];
                }
                stack[stackPtr++] = (GByte)decodeCode;

                if( i == LZW_CODES || decodeCode >= LZW_NO_SUCH_CODE )
                {
                    throw "Decode error";
                }

                // Output stack

                lastOutput = stack[stackPtr - 1];

                while( stackPtr != 0 && imagePos < pixels )
                {
                    OutputPixel( stack[--stackPtr], pImage, poRDS->nBlockXSize,
                                 lineBreak, imageLine, imagePos );
                }

                // Add code to string table

                if( lastCode != LZW_NO_SUCH_CODE &&
                    lastAdded != LZW_CODES - 1 )
                {
                    prefix[++lastAdded] = lastCode;
                    character[lastAdded] = lastOutput;
                }

                // Check if we need to use more bits

                if( lastAdded == (1 << codeBits) - 1 &&
                    codeBits != LZW_MAX_BITS )
                {
                     codeBits++;

                     filePos = fileAlign;
                     bitsTaken = 0;
                }
            }
        }
        catch (const char *errStr)
        {
#if RIK_ALLOW_BLOCK_ERRORS
                CPLDebug( "RIK",
                          "LZW Decompress Failed: %s\n"
                          " blocks: %d\n"
                          " blockindex: %d\n"
                          " blockoffset: %X\n"
                          " blocksize: %d\n",
                          errStr, blocks, nBlockIndex,
                          nBlockOffset, nBlockSize );
                break;
#else
                CPLFree( blockData );
                CPLError( CE_Failure, CPLE_AppDefined,
                          "RIK decompression failed. "
                          "Corrupt image block." );
                return CE_Failure;
#endif
        }
    }

/* -------------------------------------------------------------------- */
/*      Read ZLIB block.                                                */
/* -------------------------------------------------------------------- */

    else if( poRDS->options == 0x0d )
    {
        uLong destLen = pixels;
        Byte *upsideDown = (Byte *) CPLMalloc( pixels );

        uncompress( upsideDown, &destLen, blockData, nBlockSize );

        for (GUInt32 i = 0; i < poRDS->nBlockYSize; i++)
        {
            memcpy( ((Byte *)pImage) + poRDS->nBlockXSize * i,
                    upsideDown + poRDS->nBlockXSize *
                                 (poRDS->nBlockYSize - i - 1),
                    poRDS->nBlockXSize );
        }

        CPLFree( upsideDown );
    }

    CPLFree( blockData );

    return CE_None;
}
예제 #24
0
GDALDataset *RDataset::Open( GDALOpenInfo * poOpenInfo )
{
    if( !Identify( poOpenInfo ) )
        return NULL;

/* -------------------------------------------------------------------- */
/*      Confirm the requested access is supported.                      */
/* -------------------------------------------------------------------- */
    if( poOpenInfo->eAccess == GA_Update )
    {
        CPLError( CE_Failure, CPLE_NotSupported, 
                  "The R driver does not support update access to existing"
                  " datasets.\n" );
        return NULL;
    }
    
/* -------------------------------------------------------------------- */
/*      Do we need to route the file through the decompression          */
/*      machinery?                                                      */
/* -------------------------------------------------------------------- */
    CPLString osAdjustedFilename;

    if( memcmp(poOpenInfo->pabyHeader,"\037\213\b",3) == 0 )
        osAdjustedFilename = "/vsigzip/";

    osAdjustedFilename += poOpenInfo->pszFilename;

/* -------------------------------------------------------------------- */
/*      Establish this as a dataset and open the file using VSI*L.      */
/* -------------------------------------------------------------------- */
    RDataset *poDS = new RDataset();

    poDS->fp = VSIFOpenL( osAdjustedFilename, "r" );
    if( poDS->fp == NULL )
    {
        delete poDS;
        return NULL;
    }

    poDS->bASCII = EQUALN((const char *)poOpenInfo->pabyHeader,"RDA2\nA\n",7);

/* -------------------------------------------------------------------- */
/*      Confirm this is a version 2 file.                               */
/* -------------------------------------------------------------------- */
    VSIFSeekL( poDS->fp, 7, SEEK_SET );
    if( poDS->ReadInteger() != R_LISTSXP )
    {
        delete poDS;
        CPLError( CE_Failure, CPLE_OpenFailed, 
                  "It appears %s is not a version 2 R object file after all!",
                  poOpenInfo->pszFilename );
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Skip the version values.                                        */
/* -------------------------------------------------------------------- */
    poDS->ReadInteger();
    poDS->ReadInteger();

/* -------------------------------------------------------------------- */
/*      Confirm we have a numeric vector object in a pairlist.          */
/* -------------------------------------------------------------------- */
    CPLString osObjName;
    int nObjCode;

    if( !poDS->ReadPair( osObjName, nObjCode ) )
    {
        delete poDS;
        return NULL;
    }

    if( nObjCode % 256 != R_REALSXP )
    {
        delete poDS;
        CPLError( CE_Failure, CPLE_OpenFailed,
                  "Failed to find expected numeric vector object." );
        return NULL;
    }

    poDS->SetMetadataItem( "R_OBJECT_NAME", osObjName );

/* -------------------------------------------------------------------- */
/*      Read the count.                                                 */
/* -------------------------------------------------------------------- */
    int nValueCount = poDS->ReadInteger();

    poDS->nStartOfData = VSIFTellL( poDS->fp );

/* -------------------------------------------------------------------- */
/*      Read/Skip ahead to attributes.                                  */
/* -------------------------------------------------------------------- */
    if( poDS->bASCII )
    {
        poDS->padfMatrixValues = (double*) VSIMalloc2( nValueCount, sizeof(double) );
        if (poDS->padfMatrixValues == NULL)
        {
            CPLError(CE_Failure, CPLE_AppDefined,
                     "Cannot allocate %d doubles", nValueCount);
            delete poDS;
            return NULL;
        }
        for( int iValue = 0; iValue < nValueCount; iValue++ )
            poDS->padfMatrixValues[iValue] = poDS->ReadFloat();
    }
    else
    {
        VSIFSeekL( poDS->fp, 8 * nValueCount, SEEK_CUR );
    }

/* -------------------------------------------------------------------- */
/*      Read pairs till we run out, trying to find a few items that     */
/*      have special meaning to us.                                     */
/* -------------------------------------------------------------------- */
    poDS->nRasterXSize = poDS->nRasterYSize = 0;
    int nBandCount = 0;

    while( poDS->ReadPair( osObjName, nObjCode ) && nObjCode != 254 )
    {
        if( osObjName == "dim" && nObjCode % 256 == R_INTSXP )
        {
            int nCount = poDS->ReadInteger();
            if( nCount == 2 )
            {
                poDS->nRasterXSize = poDS->ReadInteger();
                poDS->nRasterYSize = poDS->ReadInteger();
                nBandCount = 1;
            }
            else if( nCount == 3 )
            {
                poDS->nRasterXSize = poDS->ReadInteger();
                poDS->nRasterYSize = poDS->ReadInteger();
                nBandCount = poDS->ReadInteger();
            }
            else
            {
                CPLError( CE_Failure, CPLE_AppDefined,
                          "R 'dim' dimension wrong." );
                delete poDS;
                return NULL;
            }
        }
        else if( nObjCode % 256 == R_REALSXP )
        {
            int nCount = poDS->ReadInteger();
            while( nCount-- > 0 && !VSIFEofL(poDS->fp) )
                poDS->ReadFloat();
        }
        else if( nObjCode % 256 == R_INTSXP )
        {
            int nCount = poDS->ReadInteger();
            while( nCount-- > 0 && !VSIFEofL(poDS->fp) )
                poDS->ReadInteger();
        }
        else if( nObjCode % 256 == R_STRSXP )			
        {
            int nCount = poDS->ReadInteger();
            while( nCount-- > 0 && !VSIFEofL(poDS->fp) )
                poDS->ReadString();
        }
        else if( nObjCode % 256 == R_CHARSXP )			
        {
            poDS->ReadString();
        }
    }

    if( poDS->nRasterXSize == 0 )
    {
        delete poDS;
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Failed to find dim dimension information for R dataset." );
        return NULL;
    }

    if (!GDALCheckDatasetDimensions(poDS->nRasterXSize, poDS->nRasterYSize) ||
        !GDALCheckBandCount(nBandCount, TRUE))
    {
        delete poDS;
        return NULL;
    }

    if( nValueCount 
        < ((GIntBig) nBandCount) * poDS->nRasterXSize * poDS->nRasterYSize )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Not enough pixel data." );
        delete poDS;
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Create the raster band object(s).                               */
/* -------------------------------------------------------------------- */
    for( int iBand = 0; iBand < nBandCount; iBand++ )
    {
        GDALRasterBand *poBand;

        if( poDS->bASCII )
            poBand = new RRasterBand( poDS, iBand+1, 
                                      poDS->padfMatrixValues + iBand * poDS->nRasterXSize * poDS->nRasterYSize );
        else
            poBand = new RawRasterBand( poDS, iBand+1, poDS->fp,
                                        poDS->nStartOfData 
                                        + poDS->nRasterXSize*poDS->nRasterYSize*8*iBand, 
                                        8, poDS->nRasterXSize * 8,
                                        GDT_Float64, !CPL_IS_LSB,
                                        TRUE, FALSE );
                                      
        poDS->SetBand( iBand+1, poBand );
    }

/* -------------------------------------------------------------------- */
/*      Initialize any PAM information.                                 */
/* -------------------------------------------------------------------- */
    poDS->SetDescription( poOpenInfo->pszFilename );
    poDS->TryLoadXML();

/* -------------------------------------------------------------------- */
/*      Check for overviews.                                            */
/* -------------------------------------------------------------------- */
    poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename );

    return( poDS );
}
예제 #25
0
GDALDataset *RIKDataset::Open( GDALOpenInfo * poOpenInfo )

{
    if( Identify(poOpenInfo) == FALSE )
        return NULL;

    bool rik3header = false;

    if( EQUALN((const char *) poOpenInfo->pabyHeader, "RIK3", 4) )
    {
        rik3header = true;
        VSIFSeekL( poOpenInfo->fpL, 4, SEEK_SET );
    }
    else
        VSIFSeekL( poOpenInfo->fpL, 0, SEEK_SET );

/* -------------------------------------------------------------------- */
/*      Read the map name.                                              */
/* -------------------------------------------------------------------- */

    char name[1024];

    GUInt16 nameLength = GetRikString( poOpenInfo->fpL, name, sizeof(name) );

    if( nameLength > sizeof(name) - 1 )
    {
        return NULL;
    }

    if( !rik3header )
    {
        if( nameLength == 0 || nameLength != strlen(name) )
            return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Read the header.                                                */
/* -------------------------------------------------------------------- */

    RIKHeader header;
    double metersPerPixel;

    const char *headerType = "RIK3";

    if( rik3header )
    {
/* -------------------------------------------------------------------- */
/*      RIK3 header.                                                    */
/* -------------------------------------------------------------------- */

        // Read projection name

        char projection[1024];

        GUInt16 projLength = GetRikString( poOpenInfo->fpL,
                                           projection, sizeof(projection) );

        if( projLength > sizeof(projection) - 1 )
        {
            // Unreasonable string length, assume wrong format
            return NULL;
        }

        // Read unknown string

        projLength = GetRikString( poOpenInfo->fpL, projection, sizeof(projection) );

        // Read map north edge

        char tmpStr[16];

        GUInt16 tmpLength = GetRikString( poOpenInfo->fpL,
                                          tmpStr, sizeof(tmpStr) );

        if( tmpLength > sizeof(tmpStr) - 1 )
        {
            // Unreasonable string length, assume wrong format
            return NULL;
        }

        header.fNorth = CPLAtof( tmpStr );

        // Read map west edge

        tmpLength = GetRikString( poOpenInfo->fpL,
                                  tmpStr, sizeof(tmpStr) );

        if( tmpLength > sizeof(tmpStr) - 1 )
        {
            // Unreasonable string length, assume wrong format
            return NULL;
        }

        header.fWest = CPLAtof( tmpStr );

        // Read binary values

        VSIFReadL( &header.iScale, 1, sizeof(header.iScale), poOpenInfo->fpL );
        VSIFReadL( &header.iMPPNum, 1, sizeof(header.iMPPNum), poOpenInfo->fpL );
        VSIFReadL( &header.iBlockWidth, 1, sizeof(header.iBlockWidth), poOpenInfo->fpL );
        VSIFReadL( &header.iBlockHeight, 1, sizeof(header.iBlockHeight), poOpenInfo->fpL );
        VSIFReadL( &header.iHorBlocks, 1, sizeof(header.iHorBlocks), poOpenInfo->fpL );
        VSIFReadL( &header.iVertBlocks, 1, sizeof(header.iVertBlocks), poOpenInfo->fpL );
#ifdef CPL_MSB
        CPL_SWAP32PTR( &header.iScale );
        CPL_SWAP32PTR( &header.iMPPNum );
        CPL_SWAP32PTR( &header.iBlockWidth );
        CPL_SWAP32PTR( &header.iBlockHeight );
        CPL_SWAP32PTR( &header.iHorBlocks );
        CPL_SWAP32PTR( &header.iVertBlocks );
#endif

        VSIFReadL( &header.iBitsPerPixel, 1, sizeof(header.iBitsPerPixel), poOpenInfo->fpL );
        VSIFReadL( &header.iOptions, 1, sizeof(header.iOptions), poOpenInfo->fpL );
        header.iUnknown = header.iOptions;
        VSIFReadL( &header.iOptions, 1, sizeof(header.iOptions), poOpenInfo->fpL );

        header.fSouth = header.fNorth -
            header.iVertBlocks * header.iBlockHeight * header.iMPPNum;
        header.fEast = header.fWest +
            header.iHorBlocks * header.iBlockWidth * header.iMPPNum;

        metersPerPixel = header.iMPPNum;
    }
    else
    {
/* -------------------------------------------------------------------- */
/*      Old RIK header.                                                 */
/* -------------------------------------------------------------------- */

        VSIFReadL( &header.iUnknown, 1, sizeof(header.iUnknown), poOpenInfo->fpL );
        VSIFReadL( &header.fSouth, 1, sizeof(header.fSouth), poOpenInfo->fpL );
        VSIFReadL( &header.fWest, 1, sizeof(header.fWest), poOpenInfo->fpL );
        VSIFReadL( &header.fNorth, 1, sizeof(header.fNorth), poOpenInfo->fpL );
        VSIFReadL( &header.fEast, 1, sizeof(header.fEast), poOpenInfo->fpL );
        VSIFReadL( &header.iScale, 1, sizeof(header.iScale), poOpenInfo->fpL );
        VSIFReadL( &header.iMPPNum, 1, sizeof(header.iMPPNum), poOpenInfo->fpL );
#ifdef CPL_MSB
        CPL_SWAP64PTR( &header.fSouth );
        CPL_SWAP64PTR( &header.fWest );
        CPL_SWAP64PTR( &header.fNorth );
        CPL_SWAP64PTR( &header.fEast );
        CPL_SWAP32PTR( &header.iScale );
        CPL_SWAP32PTR( &header.iMPPNum );
#endif

        if (!CPLIsFinite(header.fSouth) |
            !CPLIsFinite(header.fWest) |
            !CPLIsFinite(header.fNorth) |
            !CPLIsFinite(header.fEast))
            return NULL;

        bool offsetBounds;

        offsetBounds = header.fSouth < 4000000;

        header.iMPPDen = 1;

        if( offsetBounds )
        {
            header.fSouth += 4002995;
            header.fNorth += 5004000;
            header.fWest += 201000;
            header.fEast += 302005;

            VSIFReadL( &header.iMPPDen, 1, sizeof(header.iMPPDen), poOpenInfo->fpL );
#ifdef CPL_MSB
            CPL_SWAP32PTR( &header.iMPPDen );
#endif

            headerType = "RIK1";
        }
        else
        {
            headerType = "RIK2";
        }

        metersPerPixel = header.iMPPNum / double(header.iMPPDen);

        VSIFReadL( &header.iBlockWidth, 1, sizeof(header.iBlockWidth), poOpenInfo->fpL );
        VSIFReadL( &header.iBlockHeight, 1, sizeof(header.iBlockHeight), poOpenInfo->fpL );
        VSIFReadL( &header.iHorBlocks, 1, sizeof(header.iHorBlocks), poOpenInfo->fpL );
#ifdef CPL_MSB
        CPL_SWAP32PTR( &header.iBlockWidth );
        CPL_SWAP32PTR( &header.iBlockHeight );
        CPL_SWAP32PTR( &header.iHorBlocks );
#endif

        if(( header.iBlockWidth > 2000 ) || ( header.iBlockWidth < 10 ) ||
           ( header.iBlockHeight > 2000 ) || ( header.iBlockHeight < 10 ))
           return NULL;

        if( !offsetBounds )
        {
            VSIFReadL( &header.iVertBlocks, 1, sizeof(header.iVertBlocks), poOpenInfo->fpL );
#ifdef CPL_MSB
            CPL_SWAP32PTR( &header.iVertBlocks );
#endif
        }

        if( offsetBounds || !header.iVertBlocks )
        {
            header.iVertBlocks = (GUInt32)
                ceil( (header.fNorth - header.fSouth) /
                      (header.iBlockHeight * metersPerPixel) );
        }

#if RIK_HEADER_DEBUG
        CPLDebug( "RIK",
                  "Original vertical blocks %d\n",
                  header.iVertBlocks );
#endif

        VSIFReadL( &header.iBitsPerPixel, 1, sizeof(header.iBitsPerPixel), poOpenInfo->fpL );

        if( header.iBitsPerPixel != 8 )
        {
            CPLError( CE_Failure, CPLE_OpenFailed,
                      "File %s has unsupported number of bits per pixel.\n",
                      poOpenInfo->pszFilename );
            return NULL;
        }

        VSIFReadL( &header.iOptions, 1, sizeof(header.iOptions), poOpenInfo->fpL );

        if( !header.iHorBlocks || !header.iVertBlocks )
           return NULL;

        if( header.iOptions != 0x00 && // Uncompressed
            header.iOptions != 0x40 && // Uncompressed
            header.iOptions != 0x01 && // RLE
            header.iOptions != 0x41 && // RLE
            header.iOptions != 0x0B && // LZW
            header.iOptions != 0x0D )  // ZLIB
        {
            CPLError( CE_Failure, CPLE_OpenFailed,
                      "File %s. Unknown map options.\n",
                      poOpenInfo->pszFilename );
            return NULL;
        }
    }

/* -------------------------------------------------------------------- */
/*      Read the palette.                                               */
/* -------------------------------------------------------------------- */

    GByte palette[768];

    GUInt16 i;
    for( i = 0; i < 256; i++ )
    {
        VSIFReadL( &palette[i * 3 + 2], 1, 1, poOpenInfo->fpL );
        VSIFReadL( &palette[i * 3 + 1], 1, 1, poOpenInfo->fpL );
        VSIFReadL( &palette[i * 3 + 0], 1, 1, poOpenInfo->fpL );
    }

/* -------------------------------------------------------------------- */
/*      Find block offsets.                                             */
/* -------------------------------------------------------------------- */

    GUInt32 blocks;
    GUInt32 *offsets;

    blocks = header.iHorBlocks * header.iVertBlocks;
    offsets = (GUInt32 *)CPLMalloc( blocks * sizeof(GUInt32) );

    if( !offsets )
    {
        CPLError( CE_Failure, CPLE_OpenFailed,
                  "File %s. Unable to allocate offset table.\n",
                  poOpenInfo->pszFilename );
        return NULL;
    }

    if( header.iOptions == 0x00 )
    {
        offsets[0] = VSIFTellL( poOpenInfo->fpL );

        for( GUInt32 i = 1; i < blocks; i++ )
        {
            offsets[i] = offsets[i - 1] +
                header.iBlockWidth * header.iBlockHeight;
        }
    }
    else
    {
        for( GUInt32 i = 0; i < blocks; i++ )
        {
            VSIFReadL( &offsets[i], 1, sizeof(offsets[i]), poOpenInfo->fpL );
#ifdef CPL_MSB
            CPL_SWAP32PTR( &offsets[i] );
#endif
            if( rik3header )
            {
                GUInt32 blockSize;
                VSIFReadL( &blockSize, 1, sizeof(blockSize), poOpenInfo->fpL );
#ifdef CPL_MSB
                CPL_SWAP32PTR( &blockSize );
#endif
            }
        }
    }

/* -------------------------------------------------------------------- */
/*      Final checks.                                                   */
/* -------------------------------------------------------------------- */

    // File size

    if( VSIFEofL( poOpenInfo->fpL ) )
    {
        CPLError( CE_Failure, CPLE_OpenFailed,
                  "File %s. Read past end of file.\n",
                  poOpenInfo->pszFilename );
        return NULL;
    }

    VSIFSeekL( poOpenInfo->fpL, 0, SEEK_END );
    GUInt32 fileSize = VSIFTellL( poOpenInfo->fpL );

#if RIK_HEADER_DEBUG
    CPLDebug( "RIK",
              "File size %d\n",
              fileSize );
#endif

    // Make sure the offset table is valid

    GUInt32 lastoffset = 0;

    for( GUInt32 y = 0; y < header.iVertBlocks; y++)
    {
        for( GUInt32 x = 0; x < header.iHorBlocks; x++)
        {
            if( !offsets[x + y * header.iHorBlocks] )
            {
                continue;
            }

            if( offsets[x + y * header.iHorBlocks] >= fileSize )
            {
                if( !y )
                {
                    CPLError( CE_Failure, CPLE_OpenFailed,
                              "File %s too short.\n",
                              poOpenInfo->pszFilename );
                    return NULL;
                }
                header.iVertBlocks = y;
                break;
            }

            if( offsets[x + y * header.iHorBlocks] < lastoffset )
            {
                if( !y )
                {
                    CPLError( CE_Failure, CPLE_OpenFailed,
                              "File %s. Corrupt offset table.\n",
                              poOpenInfo->pszFilename );
                    return NULL;
                }
                header.iVertBlocks = y;
                break;
            }

            lastoffset = offsets[x + y * header.iHorBlocks];
        }
    }

#if RIK_HEADER_DEBUG
    CPLDebug( "RIK",
              "first offset %d\n"
              "last offset %d\n",
              offsets[0],
              lastoffset );
#endif

    const char *compression = "RLE";

    if( header.iOptions == 0x00 ||
        header.iOptions == 0x40 )
        compression = "Uncompressed";
    if( header.iOptions == 0x0b )
        compression = "LZW";
    if( header.iOptions == 0x0d )
        compression = "ZLIB";

    CPLDebug( "RIK",
              "RIK file parameters:\n"
              " name: %s\n"
              " header: %s\n"
              " unknown: 0x%X\n"
              " south: %f\n"
              " west: %f\n"
              " north: %f\n"
              " east: %f\n"
              " original scale: %d\n"
              " meters per pixel: %f\n"
              " block width: %d\n"
              " block height: %d\n"
              " horizontal blocks: %d\n"
              " vertical blocks: %d\n"
              " bits per pixel: %d\n"
              " options: 0x%X\n"
              " compression: %s\n",
              name, headerType, header.iUnknown,
              header.fSouth, header.fWest, header.fNorth, header.fEast,
              header.iScale, metersPerPixel,
              header.iBlockWidth, header.iBlockHeight,
              header.iHorBlocks, header.iVertBlocks,
              header.iBitsPerPixel, header.iOptions, compression);

/* -------------------------------------------------------------------- */
/*      Create a corresponding GDALDataset.                             */
/* -------------------------------------------------------------------- */

    RIKDataset 	*poDS;

    poDS = new RIKDataset();

    poDS->fp = poOpenInfo->fpL;
    poOpenInfo->fpL = NULL;

    poDS->fTransform[0] = header.fWest - metersPerPixel / 2.0;
    poDS->fTransform[1] = metersPerPixel;
    poDS->fTransform[2] = 0.0;
    poDS->fTransform[3] = header.fNorth + metersPerPixel / 2.0;
    poDS->fTransform[4] = 0.0;
    poDS->fTransform[5] = -metersPerPixel;

    poDS->nBlockXSize = header.iBlockWidth;
    poDS->nBlockYSize = header.iBlockHeight;
    poDS->nHorBlocks = header.iHorBlocks;
    poDS->nVertBlocks = header.iVertBlocks;
    poDS->pOffsets = offsets;
    poDS->options = header.iOptions;
    poDS->nFileSize = fileSize;

    poDS->nRasterXSize = header.iBlockWidth * header.iHorBlocks;
    poDS->nRasterYSize = header.iBlockHeight * header.iVertBlocks;

    poDS->nBands = 1;

    GDALColorEntry oEntry;
    poDS->poColorTable = new GDALColorTable();
    for( i = 0; i < 256; i++ )
    {
        oEntry.c1 = palette[i * 3 + 2]; // Red
        oEntry.c2 = palette[i * 3 + 1]; // Green
        oEntry.c3 = palette[i * 3];     // Blue
        oEntry.c4 = 255;

        poDS->poColorTable->SetColorEntry( i, &oEntry );
    }

/* -------------------------------------------------------------------- */
/*      Create band information objects.                                */
/* -------------------------------------------------------------------- */

    poDS->SetBand( 1, new RIKRasterBand( poDS, 1 ));

/* -------------------------------------------------------------------- */
/*      Initialize any PAM information.                                 */
/* -------------------------------------------------------------------- */

    poDS->SetDescription( poOpenInfo->pszFilename );
    poDS->TryLoadXML();

/* -------------------------------------------------------------------- */
/*      Check for external overviews.                                   */
/* -------------------------------------------------------------------- */
    poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename, poOpenInfo->GetSiblingFiles() );

/* -------------------------------------------------------------------- */
/*      Confirm the requested access is supported.                      */
/* -------------------------------------------------------------------- */
    if( poOpenInfo->eAccess == GA_Update )
    {
        delete poDS;
        CPLError( CE_Failure, CPLE_NotSupported, 
                  "The RIK driver does not support update access to existing"
                  " datasets.\n" );
        return NULL;
    }
    
    return( poDS );
}
예제 #26
0
int OGRGPXDataSource::Open( const char * pszFilename, int bUpdateIn)

{
    if (bUpdateIn)
    {
        CPLError(CE_Failure, CPLE_NotSupported,
                    "OGR/GPX driver does not support opening a file in update mode");
        return FALSE;
    }
#ifdef HAVE_EXPAT
    pszName = CPLStrdup( pszFilename );

/* -------------------------------------------------------------------- */
/*      Try to open the file.                                           */
/* -------------------------------------------------------------------- */
    VSILFILE* fp = VSIFOpenL(pszFilename, "r");
    if (fp == NULL)
        return FALSE;
    
    validity = GPX_VALIDITY_UNKNOWN;
    CPLFree(pszVersion);
    pszVersion = NULL;
    bUseExtensions = FALSE;
    nElementsRead = 0;
    
    XML_Parser oParser = OGRCreateExpatXMLParser();
    oCurrentParser = oParser;
    XML_SetUserData(oParser, this);
    XML_SetElementHandler(oParser, ::startElementValidateCbk, NULL);
    XML_SetCharacterDataHandler(oParser, ::dataHandlerValidateCbk);
    
    char aBuf[BUFSIZ];
    int nDone;
    unsigned int nLen;
    int nCount = 0;
    
    /* Begin to parse the file and look for the <gpx> element */
    /* It *MUST* be the first element of an XML file */
    /* So once we have read the first element, we know if we can */
    /* handle the file or not with that driver */
    do
    {
        nDataHandlerCounter = 0;
        nLen = (unsigned int) VSIFReadL( aBuf, 1, sizeof(aBuf), fp );
        nDone = VSIFEofL(fp);
        if (XML_Parse(oParser, aBuf, nLen, nDone) == XML_STATUS_ERROR)
        {
            if (nLen <= BUFSIZ-1)
                aBuf[nLen] = 0;
            else
                aBuf[BUFSIZ-1] = 0;
            if (strstr(aBuf, "<?xml") && strstr(aBuf, "<gpx"))
            {
                CPLError(CE_Failure, CPLE_AppDefined,
                        "XML parsing of GPX file failed : %s at line %d, column %d",
                        XML_ErrorString(XML_GetErrorCode(oParser)),
                        (int)XML_GetCurrentLineNumber(oParser),
                        (int)XML_GetCurrentColumnNumber(oParser));
            }
            validity = GPX_VALIDITY_INVALID;
            break;
        }
        if (validity == GPX_VALIDITY_INVALID)
        {
            break;
        }
        else if (validity == GPX_VALIDITY_VALID)
        {
            /* If we have recognized the <gpx> element, now we try */
            /* to recognize if they are <extensions> tags */
            /* But we stop to look for after an arbitrary number of tags */
            if (bUseExtensions)
                break;
            else if (nElementsRead > 200)
                break;
        }
        else
        {
            /* After reading 50 * BUFSIZE bytes, and not finding whether the file */
            /* is GPX or not, we give up and fail silently */
            nCount ++;
            if (nCount == 50)
                break;
        }
    } while (!nDone && nLen > 0 );
    
    XML_ParserFree(oParser);
    
    VSIFCloseL(fp);
    
    if (validity == GPX_VALIDITY_VALID)
    {
        CPLDebug("GPX", "%s seems to be a GPX file.", pszFilename);
        if (bUseExtensions)
            CPLDebug("GPX", "It uses <extensions>");

        if (pszVersion == NULL)
        {
            /* Default to 1.1 */
            CPLError(CE_Warning, CPLE_AppDefined, "GPX schema version is unknown. "
                     "The driver may not be able to handle the file correctly and will behave as if it is GPX 1.1.");
            pszVersion = CPLStrdup("1.1");
        }
        else if (strcmp(pszVersion, "1.0") == 0 || strcmp(pszVersion, "1.1") == 0)
        {
            /* Fine */
        }
        else
        {
            CPLError(CE_Warning, CPLE_AppDefined,
                     "GPX schema version '%s' is not handled by the driver. "
                     "The driver may not be able to handle the file correctly and will behave as if it is GPX 1.1.", pszVersion);
        }

        nLayers = 5;
        papoLayers = (OGRGPXLayer **) CPLRealloc(papoLayers, nLayers * sizeof(OGRGPXLayer*));
        papoLayers[0] = new OGRGPXLayer( pszName, "waypoints", GPX_WPT, this, FALSE );
        papoLayers[1] = new OGRGPXLayer( pszName, "routes", GPX_ROUTE, this, FALSE );
        papoLayers[2] = new OGRGPXLayer( pszName, "tracks", GPX_TRACK, this, FALSE );
        papoLayers[3] = new OGRGPXLayer( pszName, "route_points", GPX_ROUTE_POINT, this, FALSE );
        papoLayers[4] = new OGRGPXLayer( pszName, "track_points", GPX_TRACK_POINT, this, FALSE );
    }

    return (validity == GPX_VALIDITY_VALID);
#else
    char aBuf[256];
    VSILFILE* fp = VSIFOpenL(pszFilename, "r");
    if (fp)
    {
        unsigned int nLen = (unsigned int)VSIFReadL( aBuf, 1, 255, fp );
        aBuf[nLen] = 0;
        if (strstr(aBuf, "<?xml") && strstr(aBuf, "<gpx"))
        {
            CPLError(CE_Failure, CPLE_NotSupported,
                    "OGR/GPX driver has not been built with read support. Expat library required");
        }
        VSIFCloseL(fp);
    }
    return FALSE;
#endif
}
예제 #27
0
GDALDataset *AAIGDataset::CommonOpen( GDALOpenInfo *poOpenInfo,
                                      GridFormat eFormat )
{
    if( poOpenInfo->fpL == nullptr )
        return nullptr;

    // Create a corresponding GDALDataset.
    AAIGDataset *poDS = nullptr;

    if (eFormat == FORMAT_AAIG)
        poDS = new AAIGDataset();
    else
        poDS = new GRASSASCIIDataset();

    const char *pszDataTypeOption =
        eFormat == FORMAT_AAIG ?
        "AAIGRID_DATATYPE" : "GRASSASCIIGRID_DATATYPE";

    const char *pszDataType = CPLGetConfigOption(pszDataTypeOption, nullptr);
    if( pszDataType == nullptr )
        pszDataType =
            CSLFetchNameValue(poOpenInfo->papszOpenOptions, "DATATYPE");
    if (pszDataType != nullptr)
    {
        poDS->eDataType = GDALGetDataTypeByName(pszDataType);
        if (!(poDS->eDataType == GDT_Int32 || poDS->eDataType == GDT_Float32 ||
              poDS->eDataType == GDT_Float64))
        {
            CPLError(CE_Warning, CPLE_NotSupported,
                     "Unsupported value for %s : %s",
                     pszDataTypeOption, pszDataType);
            poDS->eDataType = GDT_Int32;
            pszDataType = nullptr;
        }
    }

    // Parse the header.
    if (!poDS->ParseHeader((const char *)poOpenInfo->pabyHeader, pszDataType))
    {
        delete poDS;
        return nullptr;
    }

    poDS->fp = poOpenInfo->fpL;
    poOpenInfo->fpL = nullptr;

    // Find the start of real data.
    int nStartOfData = 0;

    for( int i = 2; true; i++ )
    {
        if( poOpenInfo->pabyHeader[i] == '\0' )
        {
            CPLError(CE_Failure, CPLE_AppDefined,
                     "Couldn't find data values in ASCII Grid file.");
            delete poDS;
            return nullptr;
        }

        if( poOpenInfo->pabyHeader[i - 1] == '\n' ||
            poOpenInfo->pabyHeader[i - 2] == '\n' ||
            poOpenInfo->pabyHeader[i - 1] == '\r' ||
            poOpenInfo->pabyHeader[i - 2] == '\r' )
        {
            if( !isalpha(poOpenInfo->pabyHeader[i]) &&
                poOpenInfo->pabyHeader[i] != '\n' &&
                poOpenInfo->pabyHeader[i] != '\r')
            {
                nStartOfData = i;

                // Beginning of real data found.
                break;
            }
        }
    }

    // Recognize the type of data.
    CPLAssert(nullptr != poDS->fp);

    if( pszDataType == nullptr &&
        poDS->eDataType != GDT_Float32 && poDS->eDataType != GDT_Float64)
    {
        // Allocate 100K chunk + 1 extra byte for NULL character.
        constexpr size_t nChunkSize = 1024 * 100;
        GByte *pabyChunk = static_cast<GByte *>(
            VSI_CALLOC_VERBOSE(nChunkSize + 1, sizeof(GByte)));
        if (pabyChunk == nullptr)
        {
            delete poDS;
            return nullptr;
        }
        pabyChunk[nChunkSize] = '\0';

        if( VSIFSeekL(poDS->fp, nStartOfData, SEEK_SET) < 0 )
        {
            delete poDS;
            VSIFree(pabyChunk);
            return nullptr;
        }

        // Scan for dot in subsequent chunks of data.
        while( !VSIFEofL(poDS->fp) )
        {
            CPL_IGNORE_RET_VAL(VSIFReadL(pabyChunk, nChunkSize, 1, poDS->fp));

            for( int i = 0; i < static_cast<int>(nChunkSize); i++)
            {
                GByte ch = pabyChunk[i];
                if (ch == '.' || ch == ',' || ch == 'e' || ch == 'E')
                {
                    poDS->eDataType = GDT_Float32;
                    break;
                }
            }
        }

        // Deallocate chunk.
        VSIFree(pabyChunk);
    }

    // Create band information objects.
    AAIGRasterBand *band = new AAIGRasterBand(poDS, nStartOfData);
    poDS->SetBand(1, band);
    if (band->panLineOffset == nullptr)
    {
        delete poDS;
        return nullptr;
    }

    // Try to read projection file.
    char *const pszDirname = CPLStrdup(CPLGetPath(poOpenInfo->pszFilename));
    char *const pszBasename =
        CPLStrdup(CPLGetBasename(poOpenInfo->pszFilename));

    poDS->osPrjFilename = CPLFormFilename(pszDirname, pszBasename, "prj");
    int nRet = 0;
    {
        VSIStatBufL sStatBuf;
        nRet = VSIStatL(poDS->osPrjFilename, &sStatBuf);
    }
    if( nRet != 0 && VSIIsCaseSensitiveFS(poDS->osPrjFilename) )
    {
        poDS->osPrjFilename = CPLFormFilename(pszDirname, pszBasename, "PRJ");

        VSIStatBufL sStatBuf;
        nRet = VSIStatL(poDS->osPrjFilename, &sStatBuf);
    }

    if( nRet == 0 )
    {
        poDS->papszPrj = CSLLoad(poDS->osPrjFilename);

        CPLDebug("AAIGrid", "Loaded SRS from %s", poDS->osPrjFilename.c_str());

        OGRSpatialReference oSRS;
        if( oSRS.importFromESRI(poDS->papszPrj) == OGRERR_NONE )
        {
            // If geographic values are in seconds, we must transform.
            // Is there a code for minutes too?
            if( oSRS.IsGeographic() &&
                EQUAL(OSR_GDS(poDS->papszPrj, "Units", ""), "DS") )
            {
                poDS->adfGeoTransform[0] /= 3600.0;
                poDS->adfGeoTransform[1] /= 3600.0;
                poDS->adfGeoTransform[2] /= 3600.0;
                poDS->adfGeoTransform[3] /= 3600.0;
                poDS->adfGeoTransform[4] /= 3600.0;
                poDS->adfGeoTransform[5] /= 3600.0;
            }

            CPLFree(poDS->pszProjection);
            oSRS.exportToWkt(&(poDS->pszProjection));
        }
    }

    CPLFree(pszDirname);
    CPLFree(pszBasename);

    // Initialize any PAM information.
    poDS->SetDescription(poOpenInfo->pszFilename);
    poDS->TryLoadXML();

    // Check for external overviews.
    poDS->oOvManager.Initialize(
        poDS, poOpenInfo->pszFilename, poOpenInfo->GetSiblingFiles());

    return poDS;
}
예제 #28
0
int OGRGeoRSSDataSource::Open( const char * pszFilename, int bUpdateIn)

{
    if (bUpdateIn)
    {
        CPLError(CE_Failure, CPLE_NotSupported,
                    "OGR/GeoRSS driver does not support opening a file in update mode");
        return FALSE;
    }
#ifdef HAVE_EXPAT
    pszName = CPLStrdup( pszFilename );

/* -------------------------------------------------------------------- */
/*      Try to open the file.                                           */
/* -------------------------------------------------------------------- */
    VSILFILE* fp = VSIFOpenL(pszFilename, "r");
    if (fp == NULL)
        return FALSE;
    
    validity = GEORSS_VALIDITY_UNKNOWN;
    
    XML_Parser oParser = OGRCreateExpatXMLParser();
    XML_SetUserData(oParser, this);
    XML_SetElementHandler(oParser, ::startElementValidateCbk, NULL);
    XML_SetCharacterDataHandler(oParser, ::dataHandlerValidateCbk);
    oCurrentParser = oParser;
    
    char aBuf[BUFSIZ];
    int nDone;
    unsigned int nLen;
    int nCount = 0;
    
    /* Begin to parse the file and look for the <rss> or <feed> element */
    /* It *MUST* be the first element of an XML file */
    /* So once we have read the first element, we know if we can */
    /* handle the file or not with that driver */
    do
    {
        nDataHandlerCounter = 0;
        nLen = (unsigned int) VSIFReadL( aBuf, 1, sizeof(aBuf), fp );
        nDone = VSIFEofL(fp);
        if (XML_Parse(oParser, aBuf, nLen, nDone) == XML_STATUS_ERROR)
        {
            if (nLen <= BUFSIZ-1)
                aBuf[nLen] = 0;
            else
                aBuf[BUFSIZ-1] = 0;
            if (strstr(aBuf, "<?xml") && (strstr(aBuf, "<rss") || strstr(aBuf, "<feed") || strstr(aBuf, "<atom:feed")))
            {
                CPLError(CE_Failure, CPLE_AppDefined,
                        "XML parsing of GeoRSS file failed : %s at line %d, column %d",
                        XML_ErrorString(XML_GetErrorCode(oParser)),
                        (int)XML_GetCurrentLineNumber(oParser),
                        (int)XML_GetCurrentColumnNumber(oParser));
            }
            validity = GEORSS_VALIDITY_INVALID;
            break;
        }
        if (validity == GEORSS_VALIDITY_INVALID)
        {
            break;
        }
        else if (validity == GEORSS_VALIDITY_VALID)
        {
            break;
        }
        else
        {
            /* After reading 50 * BUFSIZ bytes, and not finding whether the file */
            /* is GeoRSS or not, we give up and fail silently */
            nCount ++;
            if (nCount == 50)
                break;
        }
    } while (!nDone && nLen > 0 );
    
    XML_ParserFree(oParser);
    
    VSIFCloseL(fp);
    
    if (validity == GEORSS_VALIDITY_VALID)
    {
        CPLDebug("GeoRSS", "%s seems to be a GeoRSS file.", pszFilename);

        nLayers = 1;
        papoLayers = (OGRGeoRSSLayer **) CPLRealloc(papoLayers, nLayers * sizeof(OGRGeoRSSLayer*));
        papoLayers[0] = new OGRGeoRSSLayer( pszName, "georss", this, NULL, FALSE );
    }

    return (validity == GEORSS_VALIDITY_VALID);
#else
    char aBuf[256];
    VSILFILE* fp = VSIFOpenL(pszFilename, "r");
    if (fp)
    {
        unsigned int nLen = (unsigned int)VSIFReadL( aBuf, 1, 255, fp );
        aBuf[nLen] = 0;
        if (strstr(aBuf, "<?xml") && (strstr(aBuf, "<rss") || strstr(aBuf, "<atom:feed") || strstr(aBuf, "<feed")))
        {
            CPLError(CE_Failure, CPLE_NotSupported,
                    "OGR/GeoRSS driver has not been built with read support. Expat library required");
        }
        VSIFCloseL(fp);
    }
    return FALSE;
#endif
}