home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / vc98 / crt / src / _filbuf.c < prev    next >
C/C++ Source or Header  |  1998-06-17  |  8KB  |  252 lines

  1. /***
  2. *_filbuf.c - fill buffer and get character
  3. *
  4. *       Copyright (c) 1985-1997, 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. *******************************************************************************/
  13.  
  14. #ifdef _WIN32
  15.  
  16.  
  17. #include <cruntime.h>
  18. #include <stdio.h>
  19. #include <file2.h>
  20. #include <io.h>
  21. #include <dbgint.h>
  22. #include <malloc.h>
  23. #include <internal.h>
  24. #include <msdos.h>
  25. #include <wchar.h>
  26. #ifdef _MT
  27. #include <mtdll.h>
  28. #endif  /* _MT */
  29. #include <tchar.h>
  30.  
  31. #ifndef _UNICODE
  32.  
  33. /***
  34. *int _filbuf(stream) - fill buffer and get first character
  35. *
  36. *Purpose:
  37. *       get a buffer if the file doesn't have one, read into it, return first
  38. *       char. try to get a buffer, if a user buffer is not assigned. called
  39. *       only from getc; intended for use only within library. assume no input
  40. *       stream is to remain unbuffered when memory is available unless it is
  41. *       marked _IONBF. at worst, give it a single char buffer. the need for a
  42. *       buffer, no matter how small, becomes evident when we consider the
  43. *       ungetc's necessary in scanf
  44. *
  45. *       [NOTE: Multi-thread - _filbuf() assumes that the caller has aquired
  46. *       the stream lock, if needed.]
  47. *
  48. *Entry:
  49. *       FILE *stream - stream to read from
  50. *
  51. *Exit:
  52. *       returns first character from buffer (next character to be read)
  53. *       returns EOF if the FILE is actually a string, or not open for reading,
  54. *       or if open for writing or if no more chars to read.
  55. *       all fields in FILE structure may be changed except _file.
  56. *
  57. *Exceptions:
  58. *
  59. *******************************************************************************/
  60.  
  61. int __cdecl _filbuf (
  62.         FILE *str
  63.         )
  64.  
  65. #else  /* _UNICODE */
  66.  
  67. /***
  68. *int _filwbuf(stream) - fill buffer and get first wide character
  69. *
  70. *Purpose:
  71. *       get a buffer if the file doesn't have one, read into it, return first
  72. *       char. try to get a buffer, if a user buffer is not assigned. called
  73. *       only from getc; intended for use only within library. assume no input
  74. *       stream is to remain unbuffered when memory is available unless it is
  75. *       marked _IONBF. at worst, give it a single char buffer. the need for a
  76. *       buffer, no matter how small, becomes evident when we consider the
  77. *       ungetc's necessary in scanf
  78. *
  79. *       [NOTE: Multi-thread - _filwbuf() assumes that the caller has aquired
  80. *       the stream lock, if needed.]
  81. *
  82. *Entry:
  83. *       FILE *stream - stream to read from
  84. *
  85. *Exit:
  86. *       returns first wide character from buffer (next character to be read)
  87. *       returns WEOF if the FILE is actually a string, or not open for reading,
  88. *       or if open for writing or if no more chars to read.
  89. *       all fields in FILE structure may be changed except _file.
  90. *
  91. *Exceptions:
  92. *
  93. *******************************************************************************/
  94.  
  95. int __cdecl _filwbuf (
  96.         FILE *str
  97.         )
  98.  
  99. #endif  /* _UNICODE */
  100.  
  101. {
  102.  
  103.         REG1 FILE *stream;
  104.  
  105.         _ASSERTE(str != NULL);
  106.  
  107.         /* Init pointer to _iob2 entry. */
  108.         stream = str;
  109.  
  110.         if (!inuse(stream) || stream->_flag & _IOSTRG)
  111.                 return(_TEOF);
  112.  
  113.         if (stream->_flag & _IOWRT) {
  114.                 stream->_flag |= _IOERR;
  115.                 return(_TEOF);
  116.         }
  117.  
  118.         stream->_flag |= _IOREAD;
  119.  
  120.         /* Get a buffer, if necessary. */
  121.  
  122.         if (!anybuf(stream))
  123.                 _getbuf(stream);
  124.         else
  125.                 stream->_ptr = stream->_base;
  126.  
  127.         stream->_cnt = _read(_fileno(stream), stream->_base, stream->_bufsiz);
  128.  
  129. #ifndef _UNICODE
  130.         if ((stream->_cnt == 0) || (stream->_cnt == -1)) {
  131. #else  /* _UNICODE */
  132.         if ((stream->_cnt == 0) || (stream->_cnt == 1) || stream->_cnt == -1) {
  133. #endif  /* _UNICODE */
  134.                 stream->_flag |= stream->_cnt ? _IOERR : _IOEOF;
  135.                 stream->_cnt = 0;
  136.                 return(_TEOF);
  137.         }
  138.  
  139.         if (  !(stream->_flag & (_IOWRT|_IORW)) &&
  140.               ((_osfile_safe(_fileno(stream)) & (FTEXT|FEOFLAG)) ==
  141.                 (FTEXT|FEOFLAG)) )
  142.                 stream->_flag |= _IOCTRLZ;
  143.         /* Check for small _bufsiz (_SMALL_BUFSIZ). If it is small and
  144.            if it is our buffer, then this must be the first _filbuf after
  145.            an fseek on a read-access-only stream. Restore _bufsiz to its
  146.            larger value (_INTERNAL_BUFSIZ) so that the next _filbuf call,
  147.            if one is made, will fill the whole buffer. */
  148.         if ( (stream->_bufsiz == _SMALL_BUFSIZ) && (stream->_flag &
  149.               _IOMYBUF) && !(stream->_flag & _IOSETVBUF) )
  150.         {
  151.                 stream->_bufsiz = _INTERNAL_BUFSIZ;
  152.         }
  153. #ifndef _UNICODE
  154.         stream->_cnt--;
  155.         return(0xff & *stream->_ptr++);
  156. #else  /* _UNICODE */
  157.         stream->_cnt -= sizeof(wchar_t);
  158.         return (0xffff & *((wchar_t *)(stream->_ptr))++);
  159. #endif  /* _UNICODE */
  160.  
  161. }
  162.  
  163.  
  164. #else  /* _WIN32 */
  165.  
  166. #if defined (_M_MPPC) || defined (_M_M68K)
  167.  
  168.  
  169. #include <cruntime.h>
  170. #include <stdio.h>
  171. #include <file2.h>
  172. #include <io.h>
  173. #include <dbgint.h>
  174. #include <malloc.h>
  175. #include <internal.h>
  176. #include <msdos.h>
  177.  
  178. /***
  179. *int _filbuf(stream) - fill buffer and get first character
  180. *
  181. *Purpose:
  182. *       get a buffer if the file doesn't have one, read into it, return first
  183. *       char. try to get a buffer, if a user buffer is not assigned. called
  184. *       only from getc; intended for use only within library. assume no input
  185. *       stream is to remain unbuffered when memory is available unless it is
  186. *       marked _IONBF. at worst, give it a single char buffer. the need for a
  187. *       buffer, no matter how small, becomes evident when we consider the
  188. *       ungetc's necessary in scanf
  189. *
  190. *Entry:
  191. *       FILE *stream - stream to read from
  192. *
  193. *Exit:
  194. *       returns first character from buffer (next character to be read)
  195. *       returns EOF if the FILE is actually a string, or not open for reading,
  196. *       or if open for writing or if no more chars to read.
  197. *       all fields in FILE structure may be changed except _file.
  198. *
  199. *Exceptions:
  200. *
  201. *******************************************************************************/
  202.  
  203. int __cdecl _filbuf (
  204.         FILE *str
  205.         )
  206. {
  207.         REG1 FILE *stream;
  208.  
  209.         _ASSERTE(str != NULL);
  210.  
  211.         /* Init pointer to _iob2 entry. */
  212.         stream = str;
  213.  
  214.         if (!inuse(stream) || stream->_flag & _IOSTRG)
  215.                 return(EOF);
  216.  
  217.         if (stream->_flag & _IOWRT) {
  218.                 stream->_flag |= _IOERR;
  219.                 return(EOF);
  220.         }
  221.  
  222.         stream->_flag |= _IOREAD;
  223.  
  224.         /* Get a buffer, if necessary. */
  225.  
  226.         if (!anybuf(stream))
  227.                 _getbuf(stream);
  228.         else
  229.                 stream->_ptr = stream->_base;
  230.  
  231.         stream->_cnt = _read(_fileno(stream), stream->_base, stream->_bufsiz);
  232.  
  233.         if ((stream->_cnt == 0) || (stream->_cnt == -1)) {
  234.                 stream->_flag |= stream->_cnt ? _IOERR : _IOEOF;
  235.                 stream->_cnt = 0;
  236.                 return(EOF);
  237.         }
  238.  
  239.         if (  !(stream->_flag & (_IOWRT|_IORW)) &&
  240.         ((_osfile[_fileno(stream)] & (FTEXT|FEOFLAG)) == (FTEXT|FEOFLAG)) )
  241.                 stream->_flag |= _IOCTRLZ;
  242.  
  243.         stream->_cnt--;
  244.  
  245.         return(0xff & *stream->_ptr++);
  246. }
  247.  
  248.  
  249. #endif  /* defined (_M_MPPC) || defined (_M_M68K) */
  250.  
  251. #endif  /* _WIN32 */
  252.