Leaked source code of windows server 2003
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.

259 lines
6.9 KiB

  1. /***
  2. *stdiostr.cpp -
  3. *
  4. * Copyright (c) 1991-2001, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. *
  8. *Revision History:
  9. * 07-10-91 KRS Created.
  10. * 08-26-91 KRS Switch out cout/cerr. etc. for Windows non-QuickWin.
  11. * 09-09-91 KRS Modify sync_with_stdio() for filebuf defaults.
  12. * 09-12-91 KRS Add stdiostream class.
  13. * 09-19-91 KRS Use delbuf(1) in stdiostream constructor.
  14. * 09-20-91 KRS C700 #4453: Improve efficiency in overflow().
  15. * 10-21-91 KRS Eliminate last use of default iostream constructor.
  16. * 10-24-91 KRS Avoid virtual calls from virtual functions.
  17. * 11-13-91 KRS Split out streambuf::dbp() into separate file.
  18. * Improve default buffer handling in underflow/overflow.
  19. * Fix bug in sync().
  20. * 01-20-92 KRS C700 #5803: account for CR/LF pairs in ssync().
  21. * 01-12-95 CFW Debug CRT allocs.
  22. * 01-26-95 CFW Win32s objects now exist.
  23. * 06-14-95 CFW Comment cleanup.
  24. * 06-19-95 GJF Replaced _osfile[] with _osfile() (which references
  25. * a field in the ioinfo struct).
  26. * 07-28-95 GJF Replaced _osfile() with _osfile_safe().
  27. * 01-05-99 GJF Changes for 64-bit size_t.
  28. * 05-17-99 PML Remove all Macintosh support.
  29. *
  30. *******************************************************************************/
  31. #include <cruntime.h>
  32. #include <internal.h>
  33. #include <string.h>
  34. #include <stdiostr.h>
  35. #include <dbgint.h>
  36. #pragma hdrstop
  37. extern "C" {
  38. #include <file2.h>
  39. #include <msdos.h>
  40. }
  41. #include <dos.h>
  42. stdiobuf::stdiobuf(FILE * f)
  43. : streambuf()
  44. {
  45. unbuffered(1); // initially unbuffered
  46. _str = f;
  47. }
  48. stdiobuf::~stdiobuf()
  49. // : ~streambuf()
  50. {
  51. stdiobuf::sync(); // make sure buffer flushed
  52. }
  53. int stdiobuf::setrwbuf(int readsize, int writesize)
  54. {
  55. char * tbuf;
  56. unbuffered(!(readsize+writesize));
  57. if (unbuffered())
  58. return(0);
  59. tbuf = _new_crt char[(readsize+writesize)];
  60. if (!tbuf)
  61. return(EOF);
  62. setb( tbuf, tbuf + (readsize+writesize), 1);
  63. if (readsize)
  64. {
  65. setg(base(),base()+readsize,base()+readsize);
  66. }
  67. else
  68. {
  69. setg(0,0,0);
  70. }
  71. if (writesize)
  72. {
  73. setp(base()+readsize,ebuf());
  74. }
  75. else
  76. {
  77. setp(0,0);
  78. }
  79. return(1);
  80. }
  81. int stdiobuf::overflow(int c) {
  82. long count, nout;
  83. if (allocate()==EOF) // make sure there is a reserve area
  84. return EOF;
  85. if (!unbuffered() && epptr())
  86. {
  87. if ((count = (long)(pptr() - pbase())) > 0)
  88. {
  89. nout=(long)fwrite((void *) pbase(), 1, (int)count, _str);
  90. pbump(-(int)nout);
  91. if (nout != count)
  92. {
  93. memmove(pbase(),pbase()+nout,(int)(count-nout));
  94. return(EOF);
  95. }
  96. }
  97. }
  98. if ((!unbuffered()) && (!epptr()))
  99. setp(base()+(blen()>>1),ebuf());
  100. if (c!=EOF)
  101. {
  102. if ((!unbuffered()) && (pptr() < epptr())) // guard against recursion
  103. sputc(c);
  104. else
  105. return fputc(c, _str);
  106. }
  107. return(1); // return something other than EOF if successful
  108. }
  109. int stdiobuf::underflow()
  110. {
  111. int count;
  112. if (allocate()==EOF) // make sure there is a reserve area
  113. return EOF;
  114. if ((!unbuffered()) && (!egptr()))
  115. setg(base(),(base()+(blen()>>1)),(base()+(blen()>>1)));
  116. if (unbuffered() || (!egptr()))
  117. return fgetc(_str);
  118. if (gptr() >= egptr())
  119. // buffer empty, try for more
  120. {
  121. if (!(count = (int)fread((void *)eback(), 1, (size_t)(egptr()-eback()), _str)))
  122. return(EOF); // reach EOF, nothing read
  123. setg(eback(),(egptr()-count),egptr()); // _gptr = _egptr - count
  124. if (gptr()!=eback())
  125. {
  126. memmove(gptr(), eback(), count); // overlapping memory!
  127. }
  128. }
  129. return sbumpc();
  130. }
  131. streampos stdiobuf::seekoff(streamoff off, ios::seek_dir dir, int)
  132. {
  133. int fdir;
  134. long retpos;
  135. switch (dir) {
  136. case ios::beg :
  137. fdir = SEEK_SET;
  138. break;
  139. case ios::cur :
  140. fdir = SEEK_CUR;
  141. break;
  142. case ios::end :
  143. fdir = SEEK_END;
  144. break;
  145. default:
  146. // error
  147. return(EOF);
  148. }
  149. stdiobuf::overflow(EOF);
  150. if (fseek(_str, off, fdir))
  151. return (EOF);
  152. if ((retpos=ftell(_str))==-1L)
  153. return(EOF);
  154. return((streampos)retpos);
  155. }
  156. int stdiobuf::pbackfail(int c)
  157. {
  158. if (eback()<gptr()) return sputbackc((char)c);
  159. if (stdiobuf::seekoff( -1, ios::cur, ios::in)==EOF)
  160. return EOF;
  161. if (!unbuffered() && egptr())
  162. {
  163. memmove((gptr()+1),gptr(),(size_t)(egptr()-(gptr()+1)));
  164. *gptr()=(char)c;
  165. }
  166. return(c);
  167. }
  168. int stdiobuf::sync()
  169. {
  170. long count;
  171. char * p;
  172. char flags;
  173. if (!unbuffered())
  174. {
  175. if (stdiobuf::overflow(EOF)==EOF)
  176. return(EOF);
  177. if ((count=in_avail())>0)
  178. {
  179. flags = _osfile_safe(_fileno(_str));
  180. if (flags & FTEXT)
  181. {
  182. // If text mode, need to account for CR/LF etc.
  183. for (p = gptr(); p < egptr(); p++)
  184. if (*p == '\n')
  185. count++;
  186. // account for EOF if read, not counted by _read
  187. if (_str->_flag & _IOCTRLZ)
  188. count++;
  189. }
  190. if (stdiobuf::seekoff( -count, ios::cur, ios::in)==EOF)
  191. return(EOF);
  192. setg(eback(),egptr(),egptr()); // empty get area (_gptr = _egptr;)
  193. }
  194. }
  195. return(0);
  196. }
  197. stdiostream::stdiostream(FILE * file)
  198. : iostream(_new_crt stdiobuf(file))
  199. {
  200. istream::delbuf(1);
  201. ostream::delbuf(1);
  202. }
  203. stdiostream::~stdiostream()
  204. {
  205. }
  206. // include here for better granularity
  207. int ios::sunk_with_stdio = 0;
  208. void ios::sync_with_stdio()
  209. {
  210. if (!sunk_with_stdio) // first time only
  211. {
  212. cin = _new_crt stdiobuf(stdin);
  213. cin.delbuf(1);
  214. cin.setf(ios::stdio);
  215. cout = _new_crt stdiobuf(stdout);
  216. cout.delbuf(1);
  217. cout.setf(ios::stdio|ios::unitbuf);
  218. ((stdiobuf*)(cout.rdbuf()))->setrwbuf(0,80);
  219. cerr = _new_crt stdiobuf(stderr);
  220. cerr.delbuf(1);
  221. cerr.setf(ios::stdio|ios::unitbuf);
  222. ((stdiobuf*)(cerr.rdbuf()))->setrwbuf(0,80);
  223. clog = _new_crt stdiobuf(stderr);
  224. clog.delbuf(1);
  225. clog.setf(ios::stdio);
  226. ((stdiobuf*)(clog.rdbuf()))->setrwbuf(0,BUFSIZ);
  227. sunk_with_stdio++;
  228. }
  229. }