Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
c80e16ae
Commit
c80e16ae
authored
Nov 07, 2019
by
Jacek Caban
Committed by
Alexandre Julliard
Nov 07, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
scrrun: Rewrite text stream to use read ahead buffer.
Signed-off-by:
Jacek Caban
<
jacek@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
7c29f5a3
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
120 additions
and
111 deletions
+120
-111
filesystem.c
dlls/scrrun/filesystem.c
+120
-111
No files found.
dlls/scrrun/filesystem.c
View file @
c80e16ae
...
...
@@ -20,6 +20,7 @@
#include <stdarg.h>
#include <limits.h>
#include <assert.h>
#include "windef.h"
#include "winbase.h"
...
...
@@ -122,9 +123,12 @@ struct textstream {
IOMode
mode
;
BOOL
unicode
;
BOOL
first_read
;
LARGE_INTEGER
size
;
HANDLE
file
;
BOOL
eof
;
WCHAR
*
read_buf
;
size_t
read_buf_size
;
};
enum
iotype
{
...
...
@@ -272,6 +276,7 @@ static ULONG WINAPI textstream_Release(ITextStream *iface)
if
(
!
ref
)
{
if
(
This
->
read_buf_size
)
heap_free
(
This
->
read_buf
);
CloseHandle
(
This
->
file
);
heap_free
(
This
);
}
...
...
@@ -355,7 +360,6 @@ static HRESULT WINAPI textstream_get_Column(ITextStream *iface, LONG *column)
static
HRESULT
WINAPI
textstream_get_AtEndOfStream
(
ITextStream
*
iface
,
VARIANT_BOOL
*
eos
)
{
struct
textstream
*
This
=
impl_from_ITextStream
(
iface
);
LARGE_INTEGER
pos
,
dist
;
TRACE
(
"(%p)->(%p)
\n
"
,
This
,
eos
);
...
...
@@ -367,11 +371,7 @@ static HRESULT WINAPI textstream_get_AtEndOfStream(ITextStream *iface, VARIANT_B
return
CTL_E_BADFILEMODE
;
}
dist
.
QuadPart
=
0
;
if
(
!
SetFilePointerEx
(
This
->
file
,
dist
,
&
pos
,
FILE_CURRENT
))
return
E_FAIL
;
*
eos
=
This
->
size
.
QuadPart
==
pos
.
QuadPart
?
VARIANT_TRUE
:
VARIANT_FALSE
;
*
eos
=
(
This
->
eof
&&
!
This
->
read_buf_size
)
?
VARIANT_TRUE
:
VARIANT_FALSE
;
return
S_OK
;
}
...
...
@@ -382,67 +382,89 @@ static HRESULT WINAPI textstream_get_AtEndOfLine(ITextStream *iface, VARIANT_BOO
return
E_NOTIMPL
;
}
/*
Reads 'toread' bytes from a file, converts if needed
BOM is skipped if 'bof' is set.
*/
static
HRESULT
textstream_read
(
struct
textstream
*
stream
,
LONG
toread
,
BOOL
bof
,
BSTR
*
text
)
static
HRESULT
append_read_data
(
struct
textstream
*
stream
,
const
char
*
buf
,
size_t
buf_size
)
{
HRESULT
hr
=
S_OK
;
DWORD
read
;
char
*
buff
;
BOOL
ret
;
LARGE_INTEGER
revert
;
size_t
len
;
WCHAR
*
new_buf
;
if
(
toread
==
0
)
{
*
text
=
SysAllocStringLen
(
NULL
,
0
);
return
*
text
?
S_FALSE
:
E_OUTOFMEMORY
;
revert
.
QuadPart
=
0
;
if
(
stream
->
unicode
)
{
len
=
buf_size
/
sizeof
(
WCHAR
);
if
(
buf_size
&
1
)
revert
.
QuadPart
=
-
1
;
}
else
{
for
(
len
=
0
;
len
<
buf_size
;
len
++
)
{
if
(
!
IsDBCSLeadByte
(
buf
[
len
]))
continue
;
if
(
len
+
1
==
buf_size
)
{
revert
.
QuadPart
=
-
1
;
buf_size
--
;
break
;
}
len
++
;
}
len
=
MultiByteToWideChar
(
CP_ACP
,
0
,
buf
,
buf_size
,
NULL
,
0
);
}
if
(
!
len
)
return
S_OK
;
if
(
revert
.
QuadPart
)
SetFilePointerEx
(
stream
->
file
,
revert
,
NULL
,
FILE_CURRENT
);
if
(
toread
<
sizeof
(
WCHAR
))
return
CTL_E_ENDOFFILE
;
if
(
!
stream
->
read_buf_size
)
new_buf
=
heap_alloc
(
len
*
sizeof
(
WCHAR
));
else
new_buf
=
heap_realloc
(
stream
->
read_buf
,
(
len
+
stream
->
read_buf_size
)
*
sizeof
(
WCHAR
));
if
(
!
new_buf
)
return
E_OUTOFMEMORY
;
buff
=
heap_alloc
(
toread
);
if
(
!
buff
)
return
E_OUTOFMEMORY
;
if
(
stream
->
unicode
)
memcpy
(
new_buf
+
stream
->
read_buf_size
,
buf
,
len
*
sizeof
(
WCHAR
));
else
MultiByteToWideChar
(
CP_ACP
,
0
,
buf
,
buf_size
,
new_buf
+
stream
->
read_buf_size
,
len
);
stream
->
read_buf
=
new_buf
;
stream
->
read_buf_size
+=
len
;
return
S_OK
;
}
ret
=
ReadFile
(
stream
->
file
,
buff
,
toread
,
&
read
,
NULL
);
if
(
!
ret
||
toread
!=
read
)
{
WARN
(
"failed to read from file %d, %d, error %d
\n
"
,
read
,
toread
,
GetLastError
());
heap_free
(
buff
);
return
E_FAIL
;
static
HRESULT
read_more_data
(
struct
textstream
*
stream
)
{
char
buf
[
256
];
DWORD
read
;
if
(
stream
->
eof
)
return
S_OK
;
if
(
!
ReadFile
(
stream
->
file
,
buf
,
sizeof
(
buf
),
&
read
,
NULL
))
{
ITextStream_Release
(
&
stream
->
ITextStream_iface
);
return
create_error
(
GetLastError
());
}
if
(
stream
->
unicode
)
{
int
i
=
0
;
stream
->
eof
=
read
!=
sizeof
(
buf
);
return
append_read_data
(
stream
,
buf
,
read
);
}
/* skip BOM */
if
(
bof
&&
*
(
WCHAR
*
)
buff
==
utf16bom
)
{
read
-=
sizeof
(
WCHAR
);
i
+=
sizeof
(
WCHAR
);
}
static
BOOL
read_from_buffer
(
struct
textstream
*
stream
,
size_t
len
,
BSTR
*
ret
,
size_t
skip
)
{
assert
(
len
+
skip
<=
stream
->
read_buf_size
);
*
text
=
SysAllocStringLen
(
read
?
(
WCHAR
*
)
&
buff
[
i
]
:
NULL
,
read
/
sizeof
(
WCHAR
));
if
(
!*
text
)
hr
=
E_OUTOFMEMORY
;
}
else
{
INT
len
=
MultiByteToWideChar
(
CP_ACP
,
0
,
buff
,
read
,
NULL
,
0
);
*
text
=
SysAllocStringLen
(
NULL
,
len
);
if
(
*
text
)
MultiByteToWideChar
(
CP_ACP
,
0
,
buff
,
read
,
*
text
,
len
);
else
hr
=
E_OUTOFMEMORY
;
}
heap_free
(
buff
);
if
(
!
(
*
ret
=
SysAllocStringLen
(
stream
->
read_buf
,
len
)))
return
FALSE
;
return
hr
;
len
+=
skip
;
stream
->
read_buf_size
-=
len
;
if
(
stream
->
read_buf_size
)
memmove
(
stream
->
read_buf
,
stream
->
read_buf
+
len
,
stream
->
read_buf_size
*
sizeof
(
WCHAR
));
else
heap_free
(
stream
->
read_buf
);
return
TRUE
;
}
static
HRESULT
WINAPI
textstream_Read
(
ITextStream
*
iface
,
LONG
len
,
BSTR
*
text
)
{
struct
textstream
*
This
=
impl_from_ITextStream
(
iface
);
LARGE_INTEGER
start
,
end
,
dist
;
DWORD
toread
;
HRESULT
hr
;
HRESULT
hr
=
S_OK
;
TRACE
(
"(%p)->(%d %p)
\n
"
,
This
,
len
,
text
);
...
...
@@ -456,35 +478,22 @@ static HRESULT WINAPI textstream_Read(ITextStream *iface, LONG len, BSTR *text)
if
(
textstream_check_iomode
(
This
,
IORead
))
return
CTL_E_BADFILEMODE
;
if
(
!
This
->
first_read
)
{
VARIANT_BOOL
eos
;
/* check for EOF */
hr
=
ITextStream_get_AtEndOfStream
(
iface
,
&
eos
);
if
(
FAILED
(
hr
))
while
(
!
This
->
eof
&&
len
>
This
->
read_buf_size
)
{
if
(
FAILED
(
hr
=
read_more_data
(
This
)))
return
hr
;
if
(
eos
==
VARIANT_TRUE
)
return
CTL_E_ENDOFFILE
;
}
/* read everything from current position */
dist
.
QuadPart
=
0
;
SetFilePointerEx
(
This
->
file
,
dist
,
&
start
,
FILE_CURRENT
);
SetFilePointerEx
(
This
->
file
,
dist
,
&
end
,
FILE_END
);
toread
=
end
.
QuadPart
-
start
.
QuadPart
;
/* rewind back */
dist
.
QuadPart
=
start
.
QuadPart
;
SetFilePointerEx
(
This
->
file
,
dist
,
NULL
,
FILE_BEGIN
);
if
(
This
->
eof
&&
!
This
->
read_buf_size
)
return
CTL_E_ENDOFFILE
;
This
->
first_read
=
FALSE
;
if
(
This
->
unicode
)
len
*=
sizeof
(
WCHAR
);
if
(
len
>
This
->
read_buf_size
)
{
len
=
This
->
read_buf_size
;
hr
=
S_FALSE
;
}
hr
=
textstream_read
(
This
,
min
(
toread
,
len
),
start
.
QuadPart
==
0
,
text
);
if
(
FAILED
(
hr
))
return
hr
;
else
return
toread
<=
len
?
S_FALSE
:
S_OK
;
return
read_from_buffer
(
This
,
len
,
text
,
0
)
?
hr
:
E_OUTOFMEMORY
;
}
static
HRESULT
WINAPI
textstream_ReadLine
(
ITextStream
*
iface
,
BSTR
*
text
)
...
...
@@ -516,8 +525,6 @@ static HRESULT WINAPI textstream_ReadLine(ITextStream *iface, BSTR *text)
static
HRESULT
WINAPI
textstream_ReadAll
(
ITextStream
*
iface
,
BSTR
*
text
)
{
struct
textstream
*
This
=
impl_from_ITextStream
(
iface
);
LARGE_INTEGER
start
,
end
,
dist
;
DWORD
toread
;
HRESULT
hr
;
TRACE
(
"(%p)->(%p)
\n
"
,
This
,
text
);
...
...
@@ -529,31 +536,16 @@ static HRESULT WINAPI textstream_ReadAll(ITextStream *iface, BSTR *text)
if
(
textstream_check_iomode
(
This
,
IORead
))
return
CTL_E_BADFILEMODE
;
if
(
!
This
->
first_read
)
{
VARIANT_BOOL
eos
;
/* check for EOF */
hr
=
ITextStream_get_AtEndOfStream
(
iface
,
&
eos
);
if
(
FAILED
(
hr
))
while
(
!
This
->
eof
)
{
if
(
FAILED
(
hr
=
read_more_data
(
This
)))
return
hr
;
if
(
eos
==
VARIANT_TRUE
)
return
CTL_E_ENDOFFILE
;
}
/* read everything from current position */
dist
.
QuadPart
=
0
;
SetFilePointerEx
(
This
->
file
,
dist
,
&
start
,
FILE_CURRENT
);
SetFilePointerEx
(
This
->
file
,
dist
,
&
end
,
FILE_END
);
toread
=
end
.
QuadPart
-
start
.
QuadPart
;
/* rewind back */
dist
.
QuadPart
=
start
.
QuadPart
;
SetFilePointerEx
(
This
->
file
,
dist
,
NULL
,
FILE_BEGIN
);
This
->
first_read
=
FALSE
;
if
(
This
->
eof
&&
!
This
->
read_buf_size
)
return
CTL_E_ENDOFFILE
;
hr
=
textstream_read
(
This
,
toread
,
start
.
QuadPart
==
0
,
text
);
return
FAILED
(
hr
)
?
hr
:
S_FALSE
;
return
read_from_buffer
(
This
,
This
->
read_buf_size
,
text
,
0
)
?
S_FALSE
:
E_OUTOFMEMORY
;
}
static
HRESULT
textstream_writestr
(
struct
textstream
*
stream
,
BSTR
text
)
...
...
@@ -693,6 +685,7 @@ static HRESULT create_textstream(const WCHAR *filename, DWORD disposition, IOMod
{
struct
textstream
*
stream
;
DWORD
access
=
0
;
HRESULT
hr
;
/* map access mode */
switch
(
mode
)
...
...
@@ -716,7 +709,9 @@ static HRESULT create_textstream(const WCHAR *filename, DWORD disposition, IOMod
stream
->
ITextStream_iface
.
lpVtbl
=
&
textstreamvtbl
;
stream
->
ref
=
1
;
stream
->
mode
=
mode
;
stream
->
first_read
=
TRUE
;
stream
->
eof
=
FALSE
;
stream
->
read_buf
=
NULL
;
stream
->
read_buf_size
=
0
;
stream
->
file
=
CreateFileW
(
filename
,
access
,
0
,
NULL
,
disposition
,
FILE_ATTRIBUTE_NORMAL
,
NULL
);
if
(
stream
->
file
==
INVALID_HANDLE_VALUE
)
...
...
@@ -746,24 +741,38 @@ static HRESULT create_textstream(const WCHAR *filename, DWORD disposition, IOMod
}
else
{
if
(
format
==
TristateUseDefault
)
{
BYTE
buf
[
64
];
DWORD
read
;
BOOL
ret
;
DWORD
read
,
buf_offset
=
0
;
BYTE
buf
[
64
];
ret
=
ReadFile
(
stream
->
file
,
buf
,
sizeof
(
buf
),
&
read
,
NULL
);
if
(
!
ret
)
{
if
(
format
==
TristateUseDefault
||
mode
==
ForReading
)
{
if
(
!
ReadFile
(
stream
->
file
,
buf
,
sizeof
(
buf
),
&
read
,
NULL
))
{
ITextStream_Release
(
&
stream
->
ITextStream_iface
);
return
create_error
(
GetLastError
());
}
}
if
(
format
==
TristateUseDefault
)
stream
->
unicode
=
IsTextUnicode
(
buf
,
read
,
NULL
);
if
(
mode
==
ForReading
)
SetFilePointer
(
stream
->
file
,
0
,
0
,
FILE_BEGIN
);
}
else
stream
->
unicode
=
format
!=
TristateFalse
;
else
stream
->
unicode
=
format
!=
TristateFalse
;
if
(
mode
==
ForAppending
)
SetFilePointer
(
stream
->
file
,
0
,
0
,
FILE_END
);
if
(
mode
==
ForReading
)
{
if
(
stream
->
unicode
&&
read
>=
2
&&
buf
[
0
]
==
0xff
&&
buf
[
1
]
==
0xfe
)
buf_offset
+=
2
;
/* skip utf16 BOM */
hr
=
append_read_data
(
stream
,
(
const
char
*
)
buf
+
buf_offset
,
read
-
buf_offset
);
if
(
FAILED
(
hr
))
{
ITextStream_Release
(
&
stream
->
ITextStream_iface
);
return
hr
;
}
stream
->
eof
=
read
!=
sizeof
(
buf
);
}
else
SetFilePointer
(
stream
->
file
,
0
,
0
,
FILE_END
);
}
init_classinfo
(
&
CLSID_TextStream
,
(
IUnknown
*
)
&
stream
->
ITextStream_iface
,
&
stream
->
classinfo
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment