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

  1. /***
  2. *filebuf1.cpp - non-core filebuf member functions.
  3. *
  4. *       Copyright (c) 1991-1997, Microsoft Corporation.  All rights reserved.
  5. *
  6. *Purpose:
  7. *       Contains optional member functions for filebuf class.
  8. *
  9. *******************************************************************************/
  10.  
  11. #include <cruntime.h>
  12. #include <internal.h>
  13. #include <string.h>
  14. #include <stdlib.h>
  15. #include <stdio.h>
  16. #include <fcntl.h>
  17. #include <share.h>
  18. #include <sys\types.h>
  19. #include <io.h>
  20. #include <fstream.h>
  21. #include <dbgint.h>
  22. #pragma hdrstop
  23.  
  24. #include <sys\stat.h>
  25.  
  26. /***
  27. *filebuf* filebuf::attach(filedesc fd) - filebuf attach function
  28. *
  29. *Purpose:
  30. *       filebuf attach() member function.  Attach filebuf object to the
  31. *       given file descriptor previously obtained from _open() or _sopen().
  32. *
  33. *Entry:
  34. *       fd = file descriptor.
  35. *
  36. *Exit:
  37. *       Returns this pointer or NULL if error.
  38. *
  39. *Exceptions:
  40. *       Returns NULL if fd = -1.
  41. *
  42. *******************************************************************************/
  43. filebuf* filebuf::attach(filedesc fd)
  44. {
  45.     if (x_fd!=-1)
  46.         return NULL;    // error if already attached
  47.  
  48.     lock();
  49.     x_fd = fd;
  50.     if ((fd!=-1) && (!unbuffered()) && (!ebuf()))
  51.         {
  52.         char * sbuf = _new_crt char[BUFSIZ];
  53.         if (!sbuf)
  54.             {
  55.             unbuffered(1);
  56.             }
  57.         else
  58.             {
  59.             streambuf::setb(sbuf,sbuf+BUFSIZ,1);
  60.             }
  61.         }
  62.     unlock();
  63.     return this;
  64. }
  65.  
  66. /***
  67. *filebuf* filebuf::open(const char* name, int mode, int share) - filebuf open
  68. *
  69. *Purpose:
  70. *       filebuf open() member function.  Open a file and attach to filebuf
  71. *       object.
  72. *
  73. *Entry:
  74. *       name  = file name string.
  75. *       mode  = open mode: Combination of ios:: in, out, binary, nocreate, app,
  76. *               ate, noreplace and trunc.  See spec. for details on behavior.
  77. *       share = share mode (optional).  sh_compat, sh_none, sh_read, sh_write.
  78. *
  79. *Exit:
  80. *       Returns this pointer or NULL if error.
  81. *
  82. *Exceptions:
  83. *       Returns NULL if filebuf is already attached to an open file, or if
  84. *       invalid mode options, or if call to _sopen or filebuf::seekoff() fails.
  85. *
  86. *******************************************************************************/
  87. filebuf* filebuf::open(const char* name, int mode, int share)
  88. {
  89.     int dos_mode;
  90.     int smode;
  91.     if (x_fd!=-1)
  92.         return NULL;    // error if already open
  93. // translate mode argument
  94.     dos_mode = (mode & ios::binary) ? O_BINARY : O_TEXT;
  95.     if (!(mode & ios::nocreate))
  96.         dos_mode |= O_CREAT;
  97.     if (mode & ios::noreplace)
  98.         dos_mode |= O_EXCL;
  99.     if (mode & ios::app)
  100.         {
  101.         mode |= ios::out;
  102.         dos_mode |= O_APPEND;
  103.         }
  104.     if (mode & ios::trunc)
  105.         {
  106.         mode |= ios::out;  // IMPLIED
  107.         dos_mode |= O_TRUNC;
  108.         }
  109.     if (mode & ios::out)
  110.         {
  111.         if (mode & ios::in)
  112.             {
  113.             dos_mode |= O_RDWR;
  114.             }
  115.         else
  116.             {
  117.             dos_mode |= O_WRONLY;
  118.             }
  119.         if (!(mode & (ios::in|ios::app|ios::ate|ios::noreplace)))
  120.             {
  121.             mode |= ios::trunc; // IMPLIED
  122.             dos_mode |= O_TRUNC;
  123.             }
  124.         }
  125.     else if (mode & ios::in)
  126.         dos_mode |= O_RDONLY;
  127.     else
  128.         return NULL;    // error if not ios:in or ios::out
  129.  
  130.     smode = _SH_DENYNO; // default for NT
  131.     share &= (sh_read|sh_write|sh_none); // ignore other bits
  132.     if (share)  // optimization  openprot serves as default
  133.         {
  134.         switch (share)
  135.             {
  136. /*          case 03000 : Reserved for sh_compat  */
  137.  
  138. //          case sh_none :
  139.             case 04000 :
  140.                 smode = _SH_DENYRW;
  141.                 break;
  142. //          case sh_read :
  143.             case 05000 :
  144.                 smode = _SH_DENYWR;
  145.                 break;
  146. //          case sh_write :
  147.             case 06000 :
  148.                 smode = _SH_DENYRD;
  149.                 break;
  150. //          case (sh_read|sh_write) :
  151.             case 07000 :
  152.                 smode = _SH_DENYNO;
  153.                 break;
  154.             default :   // unrecognized value same as default
  155.                 break;
  156.             };
  157.         }
  158.  
  159.     x_fd = _sopen(name, dos_mode, smode, S_IREAD|S_IWRITE);
  160.     if (x_fd==-1)
  161.         return NULL;
  162.     lock();
  163.     x_fOpened = 1;
  164.     if ((!unbuffered()) && (!ebuf()))
  165.         {
  166.         char * sbuf = _new_crt char[BUFSIZ];
  167.         if (!sbuf)
  168.             {
  169.             unbuffered(1);
  170.             }
  171.         else
  172.             {
  173.             streambuf::setb(sbuf,sbuf+BUFSIZ,1);
  174.             }
  175.         }
  176.     if (mode & ios::ate)
  177.         if (seekoff(0,ios::end,mode)==EOF)
  178.             {
  179.             close();
  180.             unlock();
  181.             return NULL;
  182.             }
  183.     unlock();
  184.     return this;
  185. }
  186.  
  187. /***
  188. *int filebuf::setmode(int mode) - filebuf setmode function
  189. *
  190. *Purpose:
  191. *       filebuf setmode() member function.  Set binary or text access mode.
  192. *       Calls _setmode().
  193. *
  194. *       MS-specific extension.
  195. *
  196. *Entry:
  197. *       mode = filebuf::binary or filebuf::text.
  198. *
  199. *Exit:
  200. *       Returns previous mode, or -1 error.
  201. *
  202. *Exceptions:
  203. *       Return -1 (EOF) if invalid argument or _setmode fails.
  204. *
  205. *******************************************************************************/
  206. int filebuf::setmode(int mode)
  207. {
  208.     int retval;
  209.     if ((mode!=filebuf::binary) && (mode!=filebuf::text))
  210.         return -1;
  211.  
  212.     lock();
  213.     if ((x_fd==-1) || (sync()==EOF))
  214.         {
  215.         retval = -1;
  216.         }
  217.     else
  218.         {
  219.         retval = _setmode(x_fd,mode);
  220.         }
  221.  
  222.     unlock();
  223.     return retval;
  224. }
  225.