Beispiel #1
0
size_t VSIMemHandle::Write( const void * pBuffer, size_t nSize, size_t nCount )

{
    if( !bUpdate )
    {
        errno = EACCES;
        return 0;
    }
    if( bExtendFileAtNextWrite )
    {
        bExtendFileAtNextWrite = FALSE;
        if( !poFile->SetLength( nOffset ) )
            return 0;
    }

    // FIXME: Integer overflow check should be placed here:
    const size_t nBytesToWrite = nSize * nCount;

    if( nBytesToWrite + nOffset > poFile->nLength )
    {
        if( !poFile->SetLength( nBytesToWrite + nOffset ) )
            return 0;
    }

    if( nBytesToWrite )
        memcpy( poFile->pabyData + nOffset, pBuffer, nBytesToWrite );
    nOffset += nBytesToWrite;

    time(&poFile->mTime);

    return nCount;
}
Beispiel #2
0
size_t VSIMemHandle::Write( const void * pBuffer, size_t nSize, size_t nCount )

{
    if( !bUpdate )
    {
        errno = EACCES;
        return 0;
    }
    if( bExtendFileAtNextWrite )
    {
        bExtendFileAtNextWrite = FALSE;
        if( !poFile->SetLength( nOffset ) )
            return 0;
    }

    // FIXME: Integer overflow check should be placed here:
    size_t nBytesToWrite = nSize * nCount; 
    //if( CSLTestBoolean(CPLGetConfigOption("VERBOSE_IO", "FALSE")) )
    //    CPLDebug("MEM", "Write(%d bytes in [%d,%d[)", (int)nBytesToWrite, (int)nOffset, (int)(nOffset+nBytesToWrite));

    if( nBytesToWrite + nOffset > poFile->nLength )
    {
        if( !poFile->SetLength( nBytesToWrite + nOffset ) )
            return 0;
    }

    memcpy( poFile->pabyData + nOffset, pBuffer, nBytesToWrite );
    nOffset += nBytesToWrite;

    time(&poFile->mTime);

    return nCount;
}
Beispiel #3
0
int VSIMemHandle::Truncate( vsi_l_offset nNewSize )
{
    if( !bUpdate )
    {
        errno = EACCES;
        return -1;
    }

    if (poFile->SetLength( nNewSize ))
        return 0;
    else
        return -1;
}
Beispiel #4
0
size_t VSIMemHandle::Write( const void * pBuffer, size_t nSize, size_t nCount )

{
    if( !bUpdate )
    {
        errno = EACCES;
        return 0;
    }
    if( bExtendFileAtNextWrite )
    {
        bExtendFileAtNextWrite = false;
        if( !poFile->SetLength( m_nOffset ) )
            return 0;
    }

    const size_t nBytesToWrite = nSize * nCount;
    if( nCount > 0 && nBytesToWrite / nCount != nSize )
    {
        return 0;
    }
    if( nBytesToWrite + m_nOffset < nBytesToWrite )
    {
        return 0;
    }

    if( nBytesToWrite + m_nOffset > poFile->nLength )
    {
        if( !poFile->SetLength( nBytesToWrite + m_nOffset ) )
            return 0;
    }

    if( nBytesToWrite )
        memcpy( poFile->pabyData + m_nOffset, pBuffer, nBytesToWrite );
    m_nOffset += nBytesToWrite;

    time(&poFile->mTime);

    return nCount;
}
Beispiel #5
0
int VSIMemHandle::Truncate( vsi_l_offset nNewSize )
{
    if( !bUpdate )
    {
        errno = EACCES;
        return -1;
    }

    bExtendFileAtNextWrite = FALSE;
    if (poFile->SetLength( nNewSize ))
        return 0;
    else
        return -1;
}
Beispiel #6
0
int VSIMemHandle::Seek( vsi_l_offset nOffset, int nWhence )

{
    if( nWhence == SEEK_CUR )
        this->nOffset += nOffset;
    else if( nWhence == SEEK_SET )
        this->nOffset = nOffset;
    else if( nWhence == SEEK_END )
        this->nOffset = poFile->nLength + nOffset;
    else
    {
        errno = EINVAL;
        return -1;
    }

    if( this->nOffset < 0 )
    {
        this->nOffset = 0;
        return -1;
    }
    
    if( this->nOffset > poFile->nLength )
    {
        if( !bUpdate ) // Read-only files cannot be extended by seek.
        {
            CPLDebug( "VSIMemHandle", 
                      "Attempt to extend read-only file '%s' to length %d from %d, .", 
                      poFile->osFilename.c_str(), 
                      (int) this->nOffset, (int) poFile->nLength );

            this->nOffset = poFile->nLength;
            errno = EACCES;
            return -1;
        }
        else // Writeable files are zero-extended by seek past end.
        {
            if( !poFile->SetLength( this->nOffset ) )
                return -1;
        }
    }

    return 0;
}
Beispiel #7
0
VSIVirtualHandle *
VSIMemFilesystemHandler::Open( const char *pszFilename, 
                               const char *pszAccess )

{
    CPLMutexHolder oHolder( &hMutex );
    VSIMemFile *poFile;
    CPLString osFilename = pszFilename;
    NormalizePath( osFilename );

/* -------------------------------------------------------------------- */
/*      Get the filename we are opening, create if needed.              */
/* -------------------------------------------------------------------- */
    if( oFileList.find(osFilename) == oFileList.end() )
        poFile = NULL;
    else
        poFile = oFileList[osFilename];

    if( strstr(pszAccess,"w") == NULL && poFile == NULL )
    {
        errno = ENOENT;
        return NULL;
    }

    if( strstr(pszAccess,"w") )
    {
        if( poFile )
            poFile->SetLength( 0 );
        else
        {
            poFile = new VSIMemFile;
            poFile->osFilename = osFilename;
            oFileList[poFile->osFilename] = poFile;
            poFile->nRefCount++; // for file list
        }
    }

    if( poFile->bIsDirectory )
    {
        errno = EISDIR;
        return NULL;
    }

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

    poHandle->poFile = poFile;
    poHandle->nOffset = 0;
    if( strstr(pszAccess,"w") || strstr(pszAccess,"+") 
        || strstr(pszAccess,"a") )
        poHandle->bUpdate = TRUE;
    else
        poHandle->bUpdate = FALSE;

    poFile->nRefCount++;

    if( strstr(pszAccess,"a") )
        poHandle->nOffset = poFile->nLength;

    return poHandle;
}
Beispiel #8
0
VSIVirtualHandle *
VSIMemFilesystemHandler::Open( const char *pszFilename,
                               const char *pszAccess,
                               bool bSetError )

{
    CPLMutexHolder oHolder( &hMutex );
    CPLString osFilename = pszFilename;
    NormalizePath( osFilename );
    if( osFilename.empty() )
        return nullptr;

    vsi_l_offset nMaxLength = GUINTBIG_MAX;
    const size_t iPos = osFilename.find("||maxlength=");
    if( iPos != std::string::npos )
    {
        nMaxLength = static_cast<vsi_l_offset>(CPLAtoGIntBig(
                    osFilename.substr(iPos + strlen("||maxlength=")).c_str()));
    }

/* -------------------------------------------------------------------- */
/*      Get the filename we are opening, create if needed.              */
/* -------------------------------------------------------------------- */
    VSIMemFile *poFile = nullptr;
    if( oFileList.find(osFilename) != oFileList.end() )
        poFile = oFileList[osFilename];

    // If no file and opening in read, error out.
    if( strstr(pszAccess, "w") == nullptr
        && strstr(pszAccess, "a") == nullptr
        && poFile == nullptr )
    {
        if( bSetError )
        {
            VSIError(VSIE_FileError, "No such file or directory");
        }
        errno = ENOENT;
        return nullptr;
    }

    // Create.
    if( poFile == nullptr )
    {
        poFile = new VSIMemFile;
        poFile->osFilename = osFilename;
        oFileList[poFile->osFilename] = poFile;
        CPLAtomicInc(&(poFile->nRefCount));  // For file list.
        poFile->nMaxLength = nMaxLength;
    }
    // Overwrite
    else if( strstr(pszAccess, "w") )
    {
        poFile->SetLength(0);
        poFile->nMaxLength = nMaxLength;
    }

    if( poFile->bIsDirectory )
    {
        errno = EISDIR;
        return nullptr;
    }

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

    poHandle->poFile = poFile;
    poHandle->m_nOffset = 0;
    poHandle->bEOF = false;
    poHandle->bUpdate =
        strstr(pszAccess, "w") ||
        strstr(pszAccess, "+") ||
        strstr(pszAccess, "a");

    CPLAtomicInc(&(poFile->nRefCount));

    if( strstr(pszAccess, "a") )
        poHandle->m_nOffset = poFile->nLength;

    return poHandle;
}