Opened 18 years ago

Closed 16 years ago

#1070 closed defect (fixed)

Can't GDALOpen "in memory" VRT

Reported by: dem@… Owned by: warmerdam
Priority: high Milestone: 1.6.0
Component: GDAL_Raster Version: unspecified
Severity: normal Keywords: vrt vsimem
Cc:

Description

Hi,

I try to GDALOpen a "in memory" VRT file and I think there is a bug:

GDALOpen call GDALOpenInfo (gdalopeninfo.cpp:110):
                fp = VSIFOpenL( pszFilename, "rb" );
                if( fp != NULL )
                {
                    nHeaderBytes = (int) VSIFReadL( pabyHeader, 1, 1024, fp );
                    VSIFCloseL( fp );
                    fp = NULL;
                }

So all works, but fp is closed and set to NULL, and after we go in
VRTDataset::Open (vrtdataset.cpp:614):

    if( poOpenInfo->fp != NULL )
    {
/***** READ the file into pszXML using standard VSISimple interface ******/
    }
/* -------------------------------------------------------------------- */
/*      Or use the filename as the XML input.                           */
/* -------------------------------------------------------------------- */
    else
    {
        pszXML = CPLStrdup( poOpenInfo->pszFilename );
    }

    OpenXML( pszXML, pszVRTPath );

I go in the else case which fails because trying to XMLParse the string
"/vsimem/file.vrt" (I don't understand the goal of the else code, does it handle
some cases ?)

The fix I think is open and read the file into pszXML using the VSIL interface
when poOpenInfo->fp == NULL.
It's also possible to don't vsilclose fp in gdalopeninfo.cpp in VSIL case and
set some flag to VSICloseL in destructor...

Regards,

Julien

Change History (4)

comment:1 by warmerdam, 18 years ago

Julien,

Yes, I see your point. 

I'm hesitant to change the interpretation of "fp" in the 
openinfo as all drivers will need to be reviewed.  But I can
modify the vrt driver to open with "L" api. 

The else case is handling when the entire XML VRT document is actually the
datasetname.  

eg. 

GDALOpen("<VRTDataset>...")

a bit of a weird thing, but it might be much more convenient for
anyways. 

comment:2 by Mateusz Łoskot, 18 years ago

(In reply to comment #0)
> I try to GDALOpen a "in memory" VRT file 

Could you give some details about parameters you passed to GDALOpen to open
in-memory raster?
I tried to reproduce your problem but without success, so I suppose this case
may be uncommon and I'd need to know with what params you feed the GDALOpen.

For now, I suppose the problem is with opening large files with VRT driver, so
I'd need to know MEM arguments you use.

In GDALOpenInfo ctor, VSIFOpen fails with errno=27 (too large file).
And then, following code is executed (what you've also discovered):

fp = VSIFOpenL( pszFilename, "rb" );
if( fp != NULL )
{
   nHeaderBytes = (int) VSIFReadL( pabyHeader, 1, 1024, fp );
   VSIFCloseL( fp );
   fp = NULL; /* XXX - mloskot - Why here fp is closed? */
}

GDALOpenInfo tries to use L-interface for large files but I'm not sure why
VSIFCloseL is called in following line.

So, this line with XXX is suspicious.

Frank, would you confirm if my assumptions are correct?

comment:3 by warmerdam, 18 years ago

Mateusz,

the GDALOpenInfo closes the file after opening it with VSIFOpenL() because
we have to know whether poOpenInfo->fp is a file handle from the large
file API or not since they are incompatible.

For historical reasons, it is assumed that poOpenInfo->fp is opened with
the regular file API (VSIFOpen() which is normally fopen()) and so we can't
promulgate VSIFOpenL() handles through the same item. 

However, "savvy" drivers are not supposed to depend on poOpenInfo->fp any 
more.  I think you just need to modify the VSI API to function properly 
even if fp is NULL. 

comment:4 by Even Rouault, 16 years ago

Keywords: vrt vsimem added
Milestone: 1.6.0
Resolution: fixed
Status: assignedclosed

I've changed VRTDataset::Open to use the VSIF large API. That solves this bug. Fix commited in r13685

Note: See TracTickets for help on using tickets.