Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

226 lines
8.0 KiB

  1. /***
  2. *_filbuf.c - fill buffer and get character
  3. *
  4. * Copyright (c) 1985-2001, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. * defines _filbuf() - fill buffer and read first character, allocate
  8. * buffer if there is none. Used from getc().
  9. * defines _filwbuf() - fill buffer and read first wide character, allocate
  10. * buffer if there is none. Used from getwc().
  11. *
  12. *Revision History:
  13. * 09-01-83 RN initial version
  14. * 06-26-85 TC added code to handle variable length buffers
  15. * 04-16-87 JCR added _IOUNGETC support
  16. * 08-04-87 JCR added _getbuff routine
  17. * 09-28-87 JCR Corrected _iob2 indexing (now uses _iob_index() macro).
  18. * 11-06-87 JCR Multi-thread support; also, split _getbuf() off
  19. * 12-11-87 JCR Added "_LOAD_DS" to declaration
  20. * 01-11-88 JCR Merged mthread version into normal code
  21. * 01-13-88 SKS Changed bogus "_fileno_lk" to "fileno"
  22. * 03-04-88 JCR Read() return value must be considered unsigned, not
  23. * signed
  24. * 06-06-88 JCR Optimized _iob2 references
  25. * 06-13-88 JCR Use near pointer to reference _iob[] entries
  26. * 08-25-88 GJF Don't use FP_OFF() macro for the 386
  27. * 06-20-89 PHG Re-activate C version, propogated fixes
  28. * 08-28-89 JCR Removed _NEAR_ for 386
  29. * 02-15-90 GJF _iob[], _iob2[] merge. Also, fixed copyright and
  30. * alignment.
  31. * 03-16-90 GJF Replaced cdecl _LOAD_DS with _CALLTYPE1, added #include
  32. * <cruntime.h> and removed #include <register.h>. Also,
  33. * removed some leftover 16-bit support.
  34. * 03-27-90 GJF Added #include <io.h>.
  35. * 07-23-90 SBM Replaced <assertm.h> by <assert.h>
  36. * 10-03-90 GJF New-style function declarator.
  37. * 01-22-91 GJF ANSI naming.
  38. * 03-27-92 DJM POSIX support.
  39. * 08-26-92 GJF Include unistd.h for POSIX build.
  40. * 04-06-93 SKS Replace _CRTAPI* with __cdecl
  41. * 04-26-93 CFW Wide char enable.
  42. * 05-06-93 CFW Optimize wide char conversion.
  43. * 05-24-93 GJF Detect small buffer size (_SMALL_BUFSIZ) resulting
  44. * from fseek call on read-access-only stream and
  45. * restore the larger size (_INTERNAL_BUFSIZ) for the
  46. * next _filbuf call.
  47. * 06-22-93 GJF Check _IOSETVBUF (new) before changing buffer size.
  48. * 11-05-93 GJF Merged with NT SDK version (picked up _NTSUBSET_
  49. * stuff).
  50. * 10-17-94 BWT Move wchar.h to non-POSIX build (ino_t definitions conflict)
  51. * 02-06-94 CFW assert -> _ASSERTE.
  52. * 02-16-95 GJF Appended Mac version of source file (somewhat cleaned
  53. * up), with appropriate #ifdef-s.
  54. * 06-12-95 GJF Replaced _osfile[] with _osfile() (macro referencing
  55. * field in ioinfo struct).
  56. * 07-27-95 GJF Replaced _osfile() with _osfile_safe().
  57. * 12-07-95 SKS Fix misspelling of _NTSUBSET_ (final _ was missing)
  58. * 05-17-99 PML Remove all Macintosh support.
  59. *
  60. *******************************************************************************/
  61. #include <cruntime.h>
  62. #include <stdio.h>
  63. #include <file2.h>
  64. #include <io.h>
  65. #include <dbgint.h>
  66. #include <malloc.h>
  67. #include <internal.h>
  68. #ifdef _POSIX_
  69. #include <unistd.h>
  70. #include <errno.h>
  71. #else
  72. #include <msdos.h>
  73. #include <wchar.h>
  74. #endif
  75. #ifdef _MT
  76. #include <mtdll.h>
  77. #endif
  78. #include <tchar.h>
  79. #ifndef _UNICODE
  80. /***
  81. *int _filbuf(stream) - fill buffer and get first character
  82. *
  83. *Purpose:
  84. * get a buffer if the file doesn't have one, read into it, return first
  85. * char. try to get a buffer, if a user buffer is not assigned. called
  86. * only from getc; intended for use only within library. assume no input
  87. * stream is to remain unbuffered when memory is available unless it is
  88. * marked _IONBF. at worst, give it a single char buffer. the need for a
  89. * buffer, no matter how small, becomes evident when we consider the
  90. * ungetc's necessary in scanf
  91. *
  92. * [NOTE: Multi-thread - _filbuf() assumes that the caller has aquired
  93. * the stream lock, if needed.]
  94. *
  95. *Entry:
  96. * FILE *stream - stream to read from
  97. *
  98. *Exit:
  99. * returns first character from buffer (next character to be read)
  100. * returns EOF if the FILE is actually a string, or not open for reading,
  101. * or if open for writing or if no more chars to read.
  102. * all fields in FILE structure may be changed except _file.
  103. *
  104. *Exceptions:
  105. *
  106. *******************************************************************************/
  107. int __cdecl _filbuf (
  108. FILE *str
  109. )
  110. #else /* _UNICODE */
  111. /***
  112. *int _filwbuf(stream) - fill buffer and get first wide character
  113. *
  114. *Purpose:
  115. * get a buffer if the file doesn't have one, read into it, return first
  116. * char. try to get a buffer, if a user buffer is not assigned. called
  117. * only from getc; intended for use only within library. assume no input
  118. * stream is to remain unbuffered when memory is available unless it is
  119. * marked _IONBF. at worst, give it a single char buffer. the need for a
  120. * buffer, no matter how small, becomes evident when we consider the
  121. * ungetc's necessary in scanf
  122. *
  123. * [NOTE: Multi-thread - _filwbuf() assumes that the caller has aquired
  124. * the stream lock, if needed.]
  125. *
  126. *Entry:
  127. * FILE *stream - stream to read from
  128. *
  129. *Exit:
  130. * returns first wide character from buffer (next character to be read)
  131. * returns WEOF if the FILE is actually a string, or not open for reading,
  132. * or if open for writing or if no more chars to read.
  133. * all fields in FILE structure may be changed except _file.
  134. *
  135. *Exceptions:
  136. *
  137. *******************************************************************************/
  138. int __cdecl _filwbuf (
  139. FILE *str
  140. )
  141. #endif /* _UNICODE */
  142. {
  143. #ifdef _NTSUBSET_
  144. return(_TEOF);
  145. #else /* ndef _NTSUBSET_ */
  146. REG1 FILE *stream;
  147. _ASSERTE(str != NULL);
  148. /* Init pointer to _iob2 entry. */
  149. stream = str;
  150. if (!inuse(stream) || stream->_flag & _IOSTRG)
  151. return(_TEOF);
  152. if (stream->_flag & _IOWRT) {
  153. #ifdef _POSIX_
  154. errno = EBADF;
  155. #endif
  156. stream->_flag |= _IOERR;
  157. return(_TEOF);
  158. }
  159. stream->_flag |= _IOREAD;
  160. /* Get a buffer, if necessary. */
  161. if (!anybuf(stream))
  162. _getbuf(stream);
  163. else
  164. stream->_ptr = stream->_base;
  165. #ifdef _POSIX_
  166. stream->_cnt = read(fileno(stream), stream->_base, stream->_bufsiz);
  167. #else
  168. stream->_cnt = _read(_fileno(stream), stream->_base, stream->_bufsiz);
  169. #endif
  170. #ifndef _UNICODE
  171. if ((stream->_cnt == 0) || (stream->_cnt == -1)) {
  172. #else /* _UNICODE */
  173. if ((stream->_cnt == 0) || (stream->_cnt == 1) || stream->_cnt == -1) {
  174. #endif /* _UNICODE */
  175. stream->_flag |= stream->_cnt ? _IOERR : _IOEOF;
  176. stream->_cnt = 0;
  177. return(_TEOF);
  178. }
  179. #ifndef _POSIX_
  180. if ( !(stream->_flag & (_IOWRT|_IORW)) &&
  181. ((_osfile_safe(_fileno(stream)) & (FTEXT|FEOFLAG)) ==
  182. (FTEXT|FEOFLAG)) )
  183. stream->_flag |= _IOCTRLZ;
  184. #endif
  185. /* Check for small _bufsiz (_SMALL_BUFSIZ). If it is small and
  186. if it is our buffer, then this must be the first _filbuf after
  187. an fseek on a read-access-only stream. Restore _bufsiz to its
  188. larger value (_INTERNAL_BUFSIZ) so that the next _filbuf call,
  189. if one is made, will fill the whole buffer. */
  190. if ( (stream->_bufsiz == _SMALL_BUFSIZ) && (stream->_flag &
  191. _IOMYBUF) && !(stream->_flag & _IOSETVBUF) )
  192. {
  193. stream->_bufsiz = _INTERNAL_BUFSIZ;
  194. }
  195. #ifndef _UNICODE
  196. stream->_cnt--;
  197. return(0xff & *stream->_ptr++);
  198. #else /* _UNICODE */
  199. stream->_cnt -= sizeof(wchar_t);
  200. return (0xffff & *((wchar_t *)(stream->_ptr))++);
  201. #endif /* _UNICODE */
  202. #endif /* _NTSUBSET_ */
  203. }