ReactOS 0.4.16-dev-927-g467dec4
fseek.cpp File Reference
Include dependency graph for fseek.cpp:

Go to the source code of this file.

Macros

#define ENABLE_INTSAFE_SIGNED_FUNCTIONS
 

Functions

static bool __cdecl common_fseek_binary_mode_read_only_fast_track_nolock (__crt_stdio_stream const stream, __int64 offset, int whence) throw ()
 
static int __cdecl common_fseek_nolock (__crt_stdio_stream const stream, __int64 offset, int whence, __crt_cached_ptd_host &ptd) throw ()
 
static int __cdecl common_fseek (__crt_stdio_stream const stream, __int64 const offset, int const whence, __crt_cached_ptd_host &ptd) throw ()
 
int __cdecl fseek (FILE *const public_stream, long const offset, int const whence)
 
int __cdecl _fseek_nolock (FILE *const public_stream, long const offset, int const whence)
 
int __cdecl _fseeki64 (FILE *const public_stream, __int64 const offset, int const whence)
 
int __cdecl _fseeki64_nolock (FILE *const public_stream, __int64 const offset, int const whence)
 

Macro Definition Documentation

◆ ENABLE_INTSAFE_SIGNED_FUNCTIONS

#define ENABLE_INTSAFE_SIGNED_FUNCTIONS

Definition at line 12 of file fseek.cpp.

Function Documentation

◆ _fseek_nolock()

int __cdecl _fseek_nolock ( FILE *const  public_stream,
long const  offset,
int const  whence 
)

Definition at line 216 of file fseek.cpp.

221{
222 __crt_cached_ptd_host ptd;
223 return common_fseek_nolock(__crt_stdio_stream(public_stream), offset, whence, ptd);
224}
_In_ size_t const _In_ int _In_ bool const _In_ unsigned const _In_ __acrt_rounding_mode const _Inout_ __crt_cached_ptd_host & ptd
Definition: cvt.cpp:355
static int __cdecl common_fseek_nolock(__crt_stdio_stream const stream, __int64 offset, int whence, __crt_cached_ptd_host &ptd)
Definition: fseek.cpp:111
GLintptr offset
Definition: glext.h:5920

◆ _fseeki64()

int __cdecl _fseeki64 ( FILE *const  public_stream,
__int64 const  offset,
int const  whence 
)

Definition at line 228 of file fseek.cpp.

233{
234 __crt_cached_ptd_host ptd;
235 return common_fseek(__crt_stdio_stream(public_stream), offset, whence, ptd);
236}
static int __cdecl common_fseek(__crt_stdio_stream const stream, __int64 const offset, int const whence, __crt_cached_ptd_host &ptd)
Definition: fseek.cpp:176

◆ _fseeki64_nolock()

int __cdecl _fseeki64_nolock ( FILE *const  public_stream,
__int64 const  offset,
int const  whence 
)

Definition at line 240 of file fseek.cpp.

245{
246 __crt_cached_ptd_host ptd;
247 return common_fseek_nolock(__crt_stdio_stream(public_stream), offset, whence, ptd);
248}

◆ common_fseek()

static int __cdecl common_fseek ( __crt_stdio_stream const  stream,
__int64 const  offset,
int const  whence,
__crt_cached_ptd_host &  ptd 
)
throw (
)
static

Definition at line 176 of file fseek.cpp.

182{
183 _UCRT_VALIDATE_RETURN(ptd, stream.valid(), EINVAL, -1);
184 _UCRT_VALIDATE_RETURN(ptd, whence == SEEK_SET || whence == SEEK_CUR || whence == SEEK_END, EINVAL, -1);
185
186 int return_value = -1;
187
188 _lock_file(stream.public_stream());
189 __try
190 {
191 return_value = common_fseek_nolock(stream, offset, whence, ptd);
192 }
194 {
195 _unlock_file(stream.public_stream());
196 }
198
199 return return_value;
200}
#define EINVAL
Definition: acclib.h:90
#define SEEK_END
Definition: cabinet.c:29
#define _UCRT_VALIDATE_RETURN(ptd, expr, errorcode, retexpr)
_CRTIMP void __cdecl _unlock_file(_Inout_ FILE *_File)
_CRTIMP void __cdecl _lock_file(_Inout_ FILE *_File)
#define SEEK_SET
Definition: jmemansi.c:26
#define SEEK_CUR
Definition: util.h:63
#define __try
Definition: pseh2_64.h:188
#define __endtry
Definition: pseh2_64.h:191
#define __finally
Definition: pseh2_64.h:190
Definition: parse.h:23

Referenced by _fseeki64(), and fseek().

◆ common_fseek_binary_mode_read_only_fast_track_nolock()

static bool __cdecl common_fseek_binary_mode_read_only_fast_track_nolock ( __crt_stdio_stream const  stream,
__int64  offset,
int  whence 
)
throw (
)
static

Definition at line 23 of file fseek.cpp.

28{
29 // This fast-track path does not handle the seek-from-end case (this is not
30 // nearly as commonly used as seeking from the beginning or from the current
31 // position).
32 if (whence == SEEK_END)
33 {
34 return false;
35 }
36
37 // This fast-track path is only useful if the stream is buffered.
38 if (!stream.has_any_buffer())
39 {
40 return false;
41 }
42
43 // This fast-track path requires a stream opened only for reading. It may
44 // be possible to handle streams opened for writing or update similarly;
45 // further investigation would be required.
46 if (stream.has_any_of(_IOWRITE | _IOUPDATE))
47 {
48 return false;
49 }
50
51 // The ftell function handles a case where _cnt is negative. It isn't clear
52 // why _cnt may be negative, so if _cnt is negative, fall back to the
53 // expensive path. If the _cnt is zero, do not assume that the buffer
54 // contents contain the immediately preceding file content; data may have
55 // been read from the file bypassing the buffer. Fall back to the expensive
56 // path to be sure.
57 if (stream->_cnt <= 0)
58 {
59 return false;
60 }
61
62 // This fast-track path requires a binary mode file handle. When text mode
63 // or UTF transformations are enabled, the contents of the buffer do not
64 // exactly match the contents of the underlying file.
65 int const fh = stream.lowio_handle();
66 if ((_osfile(fh) & FTEXT) != 0 || _textmode(fh) != __crt_lowio_text_mode::ansi)
67 {
68 return false;
69 }
70
71 // Handle the SEEK_SET case by transforming the SEEK_SET offset into a
72 // SEEK_CUR offset:
73 if (whence == SEEK_SET)
74 {
75 __int64 const lowio_position = _lseeki64_nolock(fh, 0, SEEK_CUR);
76 if (lowio_position < 0)
77 {
78 return false;
79 }
80
81 __int64 const stdio_position = lowio_position - stream->_cnt;
82 if (FAILED(LongLongSub(offset, stdio_position, &offset)))
83 {
84 return false;
85 }
86 whence = SEEK_CUR;
87 }
88
89 // Compute the maximum number of bytes that we can seek in each direction
90 // within the buffer and verify that the requested offset is within that
91 // range. Note that the minimum reverse seek is a negative value.
92 __int64 const minimum_reverse_seek = -(stream->_ptr - stream->_base);
93 __int64 const maximum_forward_seek = stream->_cnt;
94
95 bool const seek_is_within_buffer = minimum_reverse_seek <= offset && offset <= maximum_forward_seek;
96 if (!seek_is_within_buffer)
97 {
98 return false;
99 }
100
101 stream->_ptr += offset;
102
103 // Note that the cast here is safe: The buffer will never be larger than
104 // INT_MAX bytes in size. The setvbuf function validates this constraint.
105 stream->_cnt -= static_cast<int>(offset);
106 return true;
107}
#define __int64
Definition: basetyps.h:16
_Check_return_opt_ __int64 __cdecl _lseeki64_nolock(_In_ int _FileHandle, _In_ __int64 _Offset, _In_ int _Origin)
#define FAILED(hr)
Definition: intsafe.h:51
#define _osfile(i)
Definition: internal.h:72
#define _textmode(i)
Definition: internal.h:74

Referenced by common_fseek_nolock().

◆ common_fseek_nolock()

static int __cdecl common_fseek_nolock ( __crt_stdio_stream const  stream,
__int64  offset,
int  whence,
__crt_cached_ptd_host &  ptd 
)
throw (
)
static

Definition at line 111 of file fseek.cpp.

117{
118 if (!stream.is_in_use())
119 {
120 ptd.get_errno().set(EINVAL);
121 return -1;
122 }
123
124 stream.unset_flags(_IOEOF);
125
127 {
128 return 0;
129 }
130
131 // If seeking relative to the current location, then convert to a seek
132 // relative to the beginning of the file. This accounts for buffering,
133 // etc., by letting fseek() tell us where we are:
134 if (whence == SEEK_CUR)
135 {
136 offset += _ftelli64_nolock_internal(stream.public_stream(), ptd);
137 whence = SEEK_SET;
138 }
139
140 __acrt_stdio_flush_nolock(stream.public_stream(), ptd);
141 // If the stream is opened in update mode and is currently in use for reading,
142 // the buffer must be abandoned to ensure consistency when transitioning from
143 // reading to writing.
144 // __acrt_stdio_flush_nolock will not reset the buffer when _IOWRITE flag
145 // is not set.
147
148 // If the file was opened for read/write, clear flags since we don't know
149 // what the user will do next with the file. If the file was opened for
150 // read only access, decrease the _bufsiz so that the next call to
151 // __acrt_stdio_refill_and_read_{narrow,wide}_nolock won't cost quite so
152 // much:
153 if (stream.has_all_of(_IOUPDATE))
154 {
155 stream.unset_flags(_IOWRITE | _IOREAD);
156 }
157 else if (stream.has_all_of(_IOREAD | _IOBUFFER_CRT) && !stream.has_any_of(_IOBUFFER_SETVBUF))
158 {
159 stream->_bufsiz = _SMALL_BUFSIZ;
160 }
161
162 if (_lseeki64_nolock_internal(stream.lowio_handle(), offset, whence, ptd) == -1)
163 {
164 return -1;
165 }
166
167 return 0;
168}
_Check_return_opt_ __int64 __cdecl _lseeki64_nolock_internal(_In_ int _FileHandle, _In_ __int64 _Offset, _In_ int _Origin, _Inout_ __crt_cached_ptd_host &_Ptd)
#define _SMALL_BUFSIZ
@ _IOBUFFER_CRT
@ _IOBUFFER_SETVBUF
void __cdecl __acrt_stdio_reset_buffer(__crt_stdio_stream const stream)
_Check_return_ __int64 __cdecl _ftelli64_nolock_internal(_Inout_ FILE *_Stream, _Inout_ __crt_cached_ptd_host &_Ptd)
int __cdecl __acrt_stdio_flush_nolock(FILE *const public_stream, __crt_cached_ptd_host &ptd)
Definition: fflush.cpp:222
static bool __cdecl common_fseek_binary_mode_read_only_fast_track_nolock(__crt_stdio_stream const stream, __int64 offset, int whence)
Definition: fseek.cpp:23
#define _IOEOF
Definition: stdio.h:132
#define _IOREAD
Definition: stdio.h:124

Referenced by _fseek_nolock(), _fseeki64_nolock(), and common_fseek().

◆ fseek()

int __cdecl fseek ( FILE *const  public_stream,
long const  offset,
int const  whence 
)

Definition at line 204 of file fseek.cpp.

209{
210 __crt_cached_ptd_host ptd;
211 return common_fseek(__crt_stdio_stream(public_stream), offset, whence, ptd);
212}