int VSISubFileFilesystemHandler::Stat( const char * pszFilename, 
                                       VSIStatBufL * psStatBuf )
    
{
    CPLString osSubFilePath;
    vsi_l_offset nOff, nSize;

    if( !DecomposePath( pszFilename, osSubFilePath, nOff, nSize ) )
    {
        errno = ENOENT;
        return -1;
    }

    int nResult = VSIStatL( osSubFilePath, psStatBuf );
    
    if( nResult == 0 )
    {
        if( nSize != 0 )
            psStatBuf->st_size = (long)nSize;
        else
            psStatBuf->st_size -= (long)nOff;
    }

    return nResult;
}
VSIVirtualHandle *
VSISubFileFilesystemHandler::Open( const char *pszFilename, 
                                   const char *pszAccess )

{
    CPLString osSubFilePath;
    vsi_l_offset nOff, nSize;

    if( !DecomposePath( pszFilename, osSubFilePath, nOff, nSize ) )
    {
        errno = ENOENT;
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Open the underlying file.                                       */
/* -------------------------------------------------------------------- */
    FILE *fp = VSIFOpenL( osSubFilePath, pszAccess );
    
    if( fp == NULL )
        return NULL;

/* -------------------------------------------------------------------- */
/*      Setup the file handle on this file.                             */
/* -------------------------------------------------------------------- */
    VSISubFileHandle *poHandle = new VSISubFileHandle;

    poHandle->fp = fp;
    poHandle->nSubregionOffset = nOff;
    poHandle->nSubregionSize = nSize;

    VSIFSeekL( fp, nOff, SEEK_SET );

    return poHandle;
}
Exemplo n.º 3
0
int VSISubFileFilesystemHandler::Stat( const char * pszFilename,
                                       VSIStatBufL * psStatBuf,
                                       int nFlags )

{
    if( !STARTS_WITH_CI(pszFilename, "/vsisubfile/") )
        return -1;

    CPLString osSubFilePath;
    vsi_l_offset nOff = 0;
    vsi_l_offset nSize = 0;

    memset( psStatBuf, 0, sizeof(VSIStatBufL) );

    if( !DecomposePath( pszFilename, osSubFilePath, nOff, nSize ) )
    {
        errno = ENOENT;
        return -1;
    }

    const int nResult = VSIStatExL( osSubFilePath, psStatBuf, nFlags );

    if( nResult == 0 )
    {
        if( nSize != 0 )
            psStatBuf->st_size = nSize;
        else
            psStatBuf->st_size -= nOff;
    }

    return nResult;
}
Exemplo n.º 4
0
VSIVirtualHandle *
VSISubFileFilesystemHandler::Open( const char *pszFilename,
                                   const char *pszAccess )

{
    CPLString osSubFilePath;
    vsi_l_offset nOff, nSize;

    if( !DecomposePath( pszFilename, osSubFilePath, nOff, nSize ) )
    {
        errno = ENOENT;
        return NULL;
    }

    /* -------------------------------------------------------------------- */
    /*      We can't open the containing file with "w" access, so if tht    */
    /*      is requested use "r+" instead to update in place.               */
    /* -------------------------------------------------------------------- */
    if( pszAccess[0] == 'w' )
        pszAccess = "r+";

    /* -------------------------------------------------------------------- */
    /*      Open the underlying file.                                       */
    /* -------------------------------------------------------------------- */
    VSILFILE *fp = VSIFOpenL( osSubFilePath, pszAccess );

    if( fp == NULL )
        return NULL;

    /* -------------------------------------------------------------------- */
    /*      Setup the file handle on this file.                             */
    /* -------------------------------------------------------------------- */
    VSISubFileHandle *poHandle = new VSISubFileHandle;

    poHandle->fp = fp;
    poHandle->nSubregionOffset = nOff;
    poHandle->nSubregionSize = nSize;

    VSIFSeekL( fp, nOff, SEEK_SET );

    return poHandle;
}
Exemplo n.º 5
0
VSIVirtualHandle *
VSISubFileFilesystemHandler::Open( const char *pszFilename,
                                   const char *pszAccess,
                                   bool /* bSetError */ )

{
    if( !STARTS_WITH_CI(pszFilename, "/vsisubfile/") )
        return nullptr;

    CPLString osSubFilePath;
    vsi_l_offset nOff = 0;
    vsi_l_offset nSize = 0;

    if( !DecomposePath( pszFilename, osSubFilePath, nOff, nSize ) )
    {
        errno = ENOENT;
        return nullptr;
    }
    if( nOff + nSize < nOff )
    {
        return nullptr;
    }

/* -------------------------------------------------------------------- */
/*      We can't open the containing file with "w" access, so if tht    */
/*      is requested use "r+" instead to update in place.               */
/* -------------------------------------------------------------------- */
    if( pszAccess[0] == 'w' )
        pszAccess = "r+";

/* -------------------------------------------------------------------- */
/*      Open the underlying file.                                       */
/* -------------------------------------------------------------------- */
    VSILFILE *fp = VSIFOpenL( osSubFilePath, pszAccess );

    if( fp == nullptr )
        return nullptr;

/* -------------------------------------------------------------------- */
/*      Setup the file handle on this file.                             */
/* -------------------------------------------------------------------- */
    VSISubFileHandle *poHandle = new VSISubFileHandle;

    poHandle->fp = fp;
    poHandle->nSubregionOffset = nOff;
    poHandle->nSubregionSize = nSize;

    // In read-only mode validate (offset, size) against underlying file size
    if( strchr(pszAccess, 'r') != nullptr && strchr(pszAccess, '+') == nullptr )
    {
        if( VSIFSeekL( fp, 0, SEEK_END ) != 0 )
        {
            poHandle->Close();
            delete poHandle;
            return nullptr;
        }
        vsi_l_offset nFpSize = VSIFTellL(fp);
        // For a directory, the size will be max(vsi_l_offset) / 2
        if( nFpSize == ~(static_cast<vsi_l_offset>(0)) / 2 || nOff > nFpSize )
        {
            poHandle->Close();
            delete poHandle;
            return nullptr;
        }
        if( nOff + nSize > nFpSize )
        {
            nSize = nFpSize - nOff;
            poHandle->nSubregionSize = nSize;
        }
    }

    if( VSIFSeekL( fp, nOff, SEEK_SET ) != 0 )
    {
        poHandle->Close();
        delete poHandle;
        poHandle = nullptr;
    }

    return poHandle;
}