www.pudn.com > mitab.rar > cpl_vsil_win32.cpp


/********************************************************************** 
 * $Id: cpl_vsil_win32.cpp,v 1.10 2004/03/10 18:17:47 warmerda Exp $ 
 * 
 * Project:  CPL - Common Portability Library 
 * Purpose:  Implement VSI large file api for Win32. 
 * Author:   Frank Warmerdam, warmerdam@pobox.com 
 * 
 ********************************************************************** 
 * Copyright (c) 2000, Frank Warmerdam 
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a 
 * copy of this software and associated documentation files (the "Software"), 
 * to deal in the Software without restriction, including without limitation 
 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 
 * and/or sell copies of the Software, and to permit persons to whom the 
 * Software is furnished to do so, subject to the following conditions: 
 *  
 * The above copyright notice and this permission notice shall be included 
 * in all copies or substantial portions of the Software. 
 *  
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL 
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER  
 * DEALINGS IN THE SOFTWARE. 
 ********************************************************************** 
 * 
 * $Log: cpl_vsil_win32.cpp,v $ 
 * Revision 1.10  2004/03/10 18:17:47  warmerda 
 * Hopefully corrected type casting warnings without breaking anything. 
 * 
 * Revision 1.9  2003/05/27 20:45:33  warmerda 
 * added VSI IO debugging stuff 
 * 
 * Revision 1.8  2002/06/17 14:10:14  warmerda 
 * no stat64 on Win32 
 * 
 * Revision 1.7  2002/06/17 14:00:16  warmerda 
 * segregate VSIStatL() and VSIStatBufL. 
 * 
 * Revision 1.6  2002/06/12 02:11:58  warmerda 
 * Removed unused variables. 
 * 
 * Revision 1.5  2001/07/18 04:00:49  warmerda 
 * added CPL_CVSID 
 * 
 * Revision 1.4  2001/06/21 20:40:31  warmerda 
 * *** empty log message *** 
 * 
 * Revision 1.3  2001/06/11 13:47:07  warmerda 
 * initialize HighPart in VSIFTellL() 
 * 
 * Revision 1.2  2001/01/19 21:16:41  warmerda 
 * expanded tabs 
 * 
 * Revision 1.1  2001/01/03 16:16:59  warmerda 
 * New 
 * 
 */ 
 
#include "cpl_vsi.h" 
 
#if defined(WIN32) 
 
CPL_CVSID("$Id: cpl_vsil_win32.cpp,v 1.10 2004/03/10 18:17:47 warmerda Exp $"); 
 
#include  
 
typedef struct { 
    HANDLE       hFile; 
    vsi_l_offset nLastOffset; 
} VSIWin32File; 
 
/************************************************************************/ 
/*                              VSIFOpen()                              */ 
/************************************************************************/ 
 
FILE *VSIFOpenL( const char * pszFilename, const char * pszAccess ) 
 
{ 
    DWORD dwDesiredAccess, dwCreationDisposition; 
    HANDLE hFile; 
 
    if( strchr(pszAccess, '+') != NULL || strchr(pszAccess, 'w') != 0 ) 
        dwDesiredAccess = GENERIC_READ | GENERIC_WRITE; 
    else 
        dwDesiredAccess = GENERIC_READ; 
 
    if( strstr(pszAccess, "w") != NULL ) 
        dwCreationDisposition = CREATE_ALWAYS; 
    else 
        dwCreationDisposition = OPEN_EXISTING; 
         
    hFile = CreateFile( pszFilename, dwDesiredAccess,  
                        FILE_SHARE_READ | FILE_SHARE_WRITE,  
                        NULL, dwCreationDisposition,  
                        (dwDesiredAccess == GENERIC_READ) ?  
                        FILE_ATTRIBUTE_READONLY : FILE_ATTRIBUTE_NORMAL,  
                        NULL ); 
 
    VSIDebug3( "VSIFOpenL(%s,%s) = %p", pszFilename, pszAccess, hFile ); 
     
    if( hFile == INVALID_HANDLE_VALUE ) 
    { 
        return NULL; 
    } 
    else 
    { 
        return (FILE *) hFile; 
    } 
} 
 
/************************************************************************/ 
/*                             VSIFCloseL()                             */ 
/************************************************************************/ 
 
int VSIFCloseL( FILE * fp ) 
 
{ 
    HANDLE hFile = (HANDLE) fp; 
 
    VSIDebug1( "VSIFCloseL(%p)", fp ); 
 
    return CloseHandle( hFile ) ? 0 : -1; 
} 
 
/************************************************************************/ 
/*                             VSIFSeekL()                              */ 
/************************************************************************/ 
 
int VSIFSeekL( FILE * fp, vsi_l_offset nOffset, int nWhence ) 
 
{ 
    HANDLE hFile = (HANDLE) fp; 
    GUInt32       dwMoveMethod, dwMoveHigh; 
    GUInt32       nMoveLow; 
    LARGE_INTEGER li; 
 
    switch(nWhence) 
    { 
        case SEEK_CUR: 
            dwMoveMethod = FILE_CURRENT; 
            break; 
        case SEEK_END: 
            dwMoveMethod = FILE_END; 
            break; 
        case SEEK_SET: 
        default: 
            dwMoveMethod = FILE_BEGIN; 
            break; 
    } 
 
    li.QuadPart = nOffset; 
    nMoveLow = li.LowPart; 
    dwMoveHigh = li.HighPart; 
 
#ifdef VSI_DEBUG 
    if( nWhence == SEEK_SET ) 
    { 
        VSIDebug3( "VSIFSeekL(%p,%d:%lu,SEEK_SET)",  
                   fp, (int) dwMoveHigh, (unsigned long) nMoveLow ); 
    } 
    else if( nWhence == SEEK_END ) 
    { 
        VSIDebug3( "VSIFSeekL(%p,%d:%lu,SEEK_END)", 
                   fp, (int) dwMoveHigh, (unsigned long) nMoveLow ); 
    } 
    else if( nWhence == SEEK_CUR ) 
    { 
        VSIDebug3( "VSIFSeekL(%p,%d:%lu,SEEK_CUR)", 
                   fp, (int) dwMoveHigh, (unsigned long) nMoveLow ); 
    } 
    else 
    { 
        VSIDebug4( "VSIFSeekL(%p,%d:%lu,%d-Unknown)", 
                   fp, (int) dwMoveHigh, (unsigned long) nMoveLow, 
                   nWhence ); 
    } 
#endif  
 
    SetLastError( 0 ); 
    SetFilePointer(hFile, (LONG) nMoveLow, (PLONG)&dwMoveHigh, 
                       dwMoveMethod); 
 
    if( GetLastError() != NO_ERROR ) 
    { 
#ifdef notdef 
        LPVOID      lpMsgBuf = NULL; 
         
        FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER  
                       | FORMAT_MESSAGE_FROM_SYSTEM 
                       | FORMAT_MESSAGE_IGNORE_INSERTS, 
                       NULL, GetLastError(),  
                       MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),  
                       (LPTSTR) &lpMsgBuf, 0, NULL ); 
  
        printf( "[ERROR %d]\n %s\n", GetLastError(), (char *) lpMsgBuf ); 
        printf( "nOffset=%u, nMoveLow=%u, dwMoveHigh=%u\n",  
                (GUInt32) nOffset, nMoveLow, dwMoveHigh ); 
#endif 
         
        return -1; 
    } 
    else 
        return 0; 
} 
 
/************************************************************************/ 
/*                             VSIFTellL()                              */ 
/************************************************************************/ 
 
vsi_l_offset VSIFTellL( FILE * fp ) 
 
{ 
    HANDLE hFile = (HANDLE) fp; 
    LARGE_INTEGER   li; 
 
    li.HighPart = 0; 
    li.LowPart = SetFilePointer( hFile, 0, (PLONG) &(li.HighPart),  
                                 FILE_CURRENT ); 
 
    VSIDebug3( "VSIFTellL(%p) = %ld:%ld", fp, li.HighPart, li.LowPart ); 
 
    return li.QuadPart; 
} 
 
/************************************************************************/ 
/*                             VSIRewindL()                             */ 
/************************************************************************/ 
 
void VSIRewindL( FILE * fp ) 
 
{ 
    VSIFSeekL( fp, 0, SEEK_SET ); 
} 
 
/************************************************************************/ 
/*                             VSIFFlushL()                             */ 
/************************************************************************/ 
 
void VSIFFlushL( FILE * fp ) 
 
{ 
    HANDLE hFile = (HANDLE) fp; 
 
    VSIDebug1( "VSIFFlushL(%p)", fp ); 
 
    FlushFileBuffers( hFile ); 
} 
 
/************************************************************************/ 
/*                             VSIFReadL()                              */ 
/************************************************************************/ 
 
size_t VSIFReadL( void * pBuffer, size_t nSize, size_t nCount, FILE * fp ) 
 
{ 
    HANDLE      hFile = (HANDLE) fp; 
    DWORD       dwSizeRead; 
    size_t      nResult; 
 
    if( !ReadFile( hFile, pBuffer, (DWORD)(nSize*nCount), &dwSizeRead, NULL ) ) 
        nResult = 0; 
    else 
        nResult = dwSizeRead / nSize; 
 
    VSIDebug3( "VSIFReadL(%p,%ld) = %ld",  
               fp, (long) nSize * nCount, (long) dwSizeRead ); 
 
    return nResult; 
} 
 
/************************************************************************/ 
/*                             VSIFWriteL()                             */ 
/************************************************************************/ 
 
size_t VSIFWriteL( void * pBuffer, size_t nSize, size_t nCount, FILE * fp ) 
 
{ 
    HANDLE      hFile = (HANDLE) fp; 
    DWORD       dwSizeWritten; 
    size_t      nResult; 
 
    if( !WriteFile(hFile,pBuffer,(DWORD)(nSize*nCount),&dwSizeWritten,NULL) ) 
        nResult = 0; 
    else 
        nResult = dwSizeWritten / nSize; 
 
    VSIDebug3( "VSIFWriteL(%p,%ld) = %ld",  
               fp, (long) nSize * nCount, (long) dwSizeWritten ); 
 
    return nResult; 
} 
 
/************************************************************************/ 
/*                              VSIFEofL()                              */ 
/************************************************************************/ 
 
int VSIFEofL( FILE * fp ) 
 
{ 
    vsi_l_offset       nCur, nEnd; 
 
    nCur = VSIFTell( fp ); 
    VSIFSeekL( fp, 0, SEEK_END ); 
    nEnd = VSIFTell( fp ); 
    VSIFSeekL( fp, nCur, SEEK_SET ); 
 
    return (nCur == nEnd); 
} 
 
#endif /* defined WIN32 */