msvcrt: Improved ftell implementation.

This commit is contained in:
Piotr Caban 2013-01-10 11:44:18 +01:00 committed by Alexandre Julliard
parent 4ffa9364eb
commit eeb7d0a649
1 changed files with 37 additions and 32 deletions

View File

@ -60,7 +60,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(msvcrt);
/* values for wxflag in file descriptor */ /* values for wxflag in file descriptor */
#define WX_OPEN 0x01 #define WX_OPEN 0x01
#define WX_ATEOF 0x02 #define WX_ATEOF 0x02
#define WX_READCR 0x04 /* underlying file is at \r */ #define WX_READNL 0x04 /* read started with \n */
#define WX_PIPE 0x08 #define WX_PIPE 0x08
#define WX_DONTINHERIT 0x10 #define WX_DONTINHERIT 0x10
#define WX_APPEND 0x20 #define WX_APPEND 0x20
@ -2151,21 +2151,12 @@ static int read_i(int fd, void *buf, unsigned int count)
else if (fdinfo->wxflag & WX_TEXT) else if (fdinfo->wxflag & WX_TEXT)
{ {
DWORD i, j; DWORD i, j;
if (bufstart[num_read-1] == '\r')
{ if (bufstart[0] == '\n')
if(count == 1) fdinfo->wxflag |= WX_READNL;
{ else
fdinfo->wxflag &= ~WX_READCR; fdinfo->wxflag &= ~WX_READNL;
ReadFile(hand, bufstart, 1, &num_read, NULL);
}
else
{
fdinfo->wxflag |= WX_READCR;
num_read--;
}
}
else
fdinfo->wxflag &= ~WX_READCR;
for (i=0, j=0; i<num_read; i++) for (i=0, j=0; i<num_read; i++)
{ {
/* in text mode, a ctrl-z signals EOF */ /* in text mode, a ctrl-z signals EOF */
@ -3536,8 +3527,6 @@ int CDECL MSVCRT_fsetpos(MSVCRT_FILE* file, MSVCRT_fpos_t *pos)
*/ */
__int64 CDECL MSVCRT__ftelli64(MSVCRT_FILE* file) __int64 CDECL MSVCRT__ftelli64(MSVCRT_FILE* file)
{ {
/* TODO: just call fgetpos and return lower half of result */
int off=0;
__int64 pos; __int64 pos;
MSVCRT__lock_file(file); MSVCRT__lock_file(file);
@ -3547,26 +3536,42 @@ __int64 CDECL MSVCRT__ftelli64(MSVCRT_FILE* file)
return -1; return -1;
} }
if(file->_bufsiz) { if(file->_bufsiz) {
if( file->_flag & MSVCRT__IOWRT ) { if(file->_flag & MSVCRT__IOWRT) {
off = file->_ptr - file->_base; pos += file->_ptr - file->_base;
} else if(!file->_cnt) { /* nothing to do */
} else if(MSVCRT__lseeki64(file->_file, 0, SEEK_END)==pos) {
int i;
pos -= file->_cnt;
if(msvcrt_get_ioinfo(file->_file)->wxflag & WX_TEXT) {
for(i=0; i<file->_cnt; i++)
if(file->_ptr[i] == '\n')
pos--;
}
} else { } else {
off = -file->_cnt; char *p;
if (msvcrt_get_ioinfo(file->_file)->wxflag & WX_TEXT) {
/* Black magic correction for CR removal */ if(MSVCRT__lseeki64(file->_file, pos, SEEK_SET) != pos) {
int i; MSVCRT__unlock_file(file);
for (i=0; i<file->_cnt; i++) { return -1;
if (file->_ptr[i] == '\n') }
off--;
} pos -= file->_bufsiz;
/* Black magic when reading CR at buffer boundary*/ pos += file->_ptr - file->_base;
if(msvcrt_get_ioinfo(file->_file)->wxflag & WX_READCR)
off--; if(msvcrt_get_ioinfo(file->_file)->wxflag & WX_TEXT) {
if(msvcrt_get_ioinfo(file->_file)->wxflag & WX_READNL)
pos--;
for(p=file->_base; p<file->_ptr; p++)
if(*p == '\n')
pos++;
} }
} }
} }
MSVCRT__unlock_file(file); MSVCRT__unlock_file(file);
return off + pos; return pos;
} }
/********************************************************************* /*********************************************************************