home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / yacl-012.zip / io / binfile.cxx next >
C/C++ Source or Header  |  1995-04-04  |  8KB  |  382 lines

  1.  
  2.  
  3. /*
  4.  *
  5.  *          Copyright (C) 1994, M. A. Sridhar
  6.  *  
  7.  *
  8.  *     This software is Copyright M. A. Sridhar, 1994. You are free
  9.  *     to copy, modify or distribute this software  as you see fit,
  10.  *     and to use  it  for  any  purpose, provided   this copyright
  11.  *     notice and the following   disclaimer are included  with all
  12.  *     copies.
  13.  *
  14.  *                        DISCLAIMER
  15.  *
  16.  *     The author makes no warranties, either expressed or implied,
  17.  *     with respect  to  this  software, its  quality, performance,
  18.  *     merchantability, or fitness for any particular purpose. This
  19.  *     software is distributed  AS IS.  The  user of this  software
  20.  *     assumes all risks  as to its quality  and performance. In no
  21.  *     event shall the author be liable for any direct, indirect or
  22.  *     consequential damages, even if the  author has been  advised
  23.  *     as to the possibility of such damages.
  24.  *
  25.  */
  26.  
  27.  
  28.  
  29. #if defined(__GNUC__)
  30. #pragma implementation
  31. #endif
  32.  
  33.  
  34.  
  35. #if defined(__BORLANDC__)
  36. #include <io.h>
  37. #pragma warn -ncf
  38. #endif
  39.  
  40. #if defined(__GNUC__)
  41. extern "C" {
  42. #include <unistd.h>
  43. #endif
  44. #include <fcntl.h>
  45. #if defined(__OS2__)  // The EMX version of GCC
  46. #include <sys/types.h>
  47. #include <io.h>
  48. #endif
  49. #include <sys/stat.h>
  50. #include <string.h>
  51. #include <errno.h>
  52. #include <stdio.h>
  53. #include <stdlib.h>
  54. #include <stdarg.h>
  55. #ifdef __GNUC__
  56. }
  57. #endif
  58.  
  59. #if defined(__DEC_ULTRIX__)
  60. extern "C" int ftruncate (int, int);
  61. #endif
  62.  
  63. // #ifdef WINDOWS
  64. // #include <windows.h>
  65. // #endif
  66.  
  67. #include "io/binfile.h"
  68. #include "base/error.h"
  69.  
  70.  
  71. #define MAX_LINE_LENGTH 512
  72.  
  73.  
  74.  
  75.  
  76.  
  77. CL_BinaryFile::CL_BinaryFile (const char *pathname, bool createFlag)
  78.     : _pathName (pathname)
  79. {
  80.     struct stat st_buf;
  81.  
  82.     _fd = -1;
  83.     if (createFlag && !Create(_pathName)) {
  84.         _MakeErrorString ("File: create call failed");
  85.         return;
  86.     }
  87.     else if (! Exists (_pathName)) {
  88.         _MakeErrorString ("File: file does not exist");
  89.         return;
  90.     }
  91.  
  92.     if (stat (_pathName, &st_buf) < 0)  {
  93.         _MakeErrorString ("File: stat failed");
  94.         return;
  95.     }
  96.     // #ifndef MS_WINDOWS
  97.     _Open ();
  98.     // #endif
  99.  
  100.  
  101. CL_BinaryFile::~CL_BinaryFile()
  102. {
  103.     _Close();
  104. }
  105.  
  106.  
  107.  
  108. bool CL_BinaryFile::Create (const char* pathName)
  109. {
  110.     int fd;
  111.  
  112.     // #ifndef MS_WINDOWS
  113.     if ((fd = creat (pathName, S_IREAD|S_IWRITE)) <= 0) {
  114.         return FALSE;
  115.     }
  116.     close (fd);
  117. // #else
  118. //     OFSTRUCT    OfStruct;
  119. //  
  120. //     int mode =   OF_READWRITE | OF_CREATE;   //This will truncate the file
  121. //     fd = OpenFile (_pathName, &OfStruct, mode);
  122. //     _lclose (fd);
  123. // #endif
  124.     return TRUE;
  125. }
  126.  
  127.  
  128. long CL_BinaryFile::Size () const
  129. {
  130. // #ifdef __BORLANDC__
  131.     long current = lseek (_fd, 0L, SEEK_CUR);
  132.     if (current == -1)
  133.         return -1;
  134.     long size = lseek  (_fd, 0L, SEEK_END);
  135.     if (size == -1)
  136.         return -1;
  137.     lseek (_fd, current, SEEK_SET);
  138.     return size;
  139. // #else
  140. //     struct stat st_buf;
  141. //     _MakeErrorString ("");
  142. //     if (stat (_pathName, &st_buf) < 0)  {
  143. //         _MakeErrorString ("Size: stat failed");
  144. //         return -1;
  145. //     }
  146. //     unsigned long fileSize =  st_buf.st_size;
  147. //     return fileSize;
  148. // #endif
  149. }
  150.  
  151.  
  152. #if defined(__UNIX__)
  153. #define CHANGESIZE ftruncate
  154. #elif defined(__DOS__) || defined(__OS2__) || defined(__MS_WINDOWS__)
  155. #define CHANGESIZE chsize
  156. #endif
  157.  
  158. bool CL_BinaryFile::ChangeSize (long size)
  159. {
  160.     if (!PrepareToChange())
  161.         return FALSE;
  162. // #ifdef MS_WINDOWS
  163. //     Open ();
  164. // #endif
  165.     _MakeErrorString ("");
  166.     
  167.     if (CHANGESIZE (_fd, size) == -1) {
  168.         _MakeErrorString ("ChangeSize: chsize call failed");
  169.         return FALSE;
  170.     }
  171. // #ifdef MS_WINDOWS
  172. //     Close();
  173. // #endif
  174.     Notify ();
  175.     return TRUE;
  176. }
  177.  
  178.  
  179.  
  180. long CL_BinaryFile::Read (uchar *buffer, long num_bytes)  const
  181. {
  182.     int    nn;
  183.  
  184.     _MakeErrorString ("");
  185. // #ifdef MS_WINDOWS
  186. //     Open();
  187. // #endif
  188.     
  189.     // #ifndef MS_WINDOWS
  190.     if ((nn = read (_fd, buffer, num_bytes)) < 0) {
  191. // #else
  192. //     if ((nn = _lread (fd, buffer, num_bytes)) < 0) {
  193. // #endif
  194.         _MakeErrorString ("Read: read call failed");
  195.     }
  196. // #ifdef MS_WINDOWS
  197. //     Close();
  198. // #endif
  199.     return nn;
  200. }
  201.  
  202.  
  203.  
  204.     
  205.  
  206. bool CL_BinaryFile::Write (uchar *buffer, long num_bytes)
  207. {
  208.  
  209. // #ifdef MS_WINDOWS
  210. //     Open();
  211. // #endif
  212.  
  213.     if (!PrepareToChange())
  214.         return FALSE;
  215.     _MakeErrorString ("");
  216.     // #ifndef MS_WINDOWS
  217.     if ((write (_fd, buffer, num_bytes)) < 0) {
  218.         _MakeErrorString ("Write: write call failed");
  219.         return FALSE;
  220.     }
  221. // #else
  222. //     if ((_lwrite (fd, buffer, num_bytes)) < 0) {
  223. //         CL_Error::Fatal ("CL_BinaryFile::Write: write failed: %s",
  224. //             strerror (errno));
  225. //     }
  226. // #endif
  227. // #ifdef MS_WINDOWS
  228. //     Close();
  229. // #endif
  230.     Notify ();
  231.     return TRUE;
  232.  
  233. }
  234.  
  235.  
  236.  
  237.  
  238. bool CL_BinaryFile::SeekTo (long position) const
  239. {
  240.     _MakeErrorString ("");
  241. // #ifdef MS_WINDOWS
  242. //     if ((retval = _llseek (fd, position, SEEK_SET)) < 0) {
  243. // #else
  244.     if (lseek (_fd, position, SEEK_SET) == -1L) {
  245.         // #endif
  246.         _MakeErrorString ("SeekTo: lseek call failed");
  247.         return FALSE;
  248.     }
  249.     return TRUE;
  250. }
  251.  
  252.  
  253. bool CL_BinaryFile::SeekRelative (long position) const
  254. {
  255.     _MakeErrorString ("");
  256. // #ifdef MS_WINDOWS
  257. //     if ((retval = _llseek (fd, position, SEEK_CUR)) < 0) {
  258. // #else
  259.     if (lseek (_fd, position, SEEK_CUR) == -1L) {
  260. // #endif
  261.         _MakeErrorString ("SeekRelative: lseek call failed");
  262.         return FALSE;
  263.     }
  264.     return TRUE;
  265. }
  266.  
  267.  
  268. bool CL_BinaryFile::Eof () const
  269. {
  270. #if defined(__UNIX__)
  271.     long current = lseek (_fd, 0L, SEEK_CUR);
  272.     if (current == -1)
  273.         return -1;
  274.     long size = lseek  (_fd, 0L, SEEK_END);
  275.     if (size == -1)
  276.         return -1;
  277.     lseek (_fd, current, SEEK_SET);
  278.     return size == current;
  279. #elif defined(__DOS__) || defined(__OS2__) || defined(__MS_WINDOWS__)
  280.     return eof (_fd);
  281. #endif
  282. }
  283.  
  284.  
  285. long CL_BinaryFile::Offset () const
  286. {
  287.     return lseek (_fd, 0, SEEK_CUR);
  288. }
  289.  
  290.  
  291. bool CL_BinaryFile::Exists (const char *pathname)
  292. {
  293.     return (access (pathname, 0) == 0);
  294. }  
  295.  
  296.  
  297.  
  298.  
  299. // Protected methods
  300.  
  301. bool CL_BinaryFile::_Open()
  302. {
  303.     _MakeErrorString ("");
  304.     // #ifndef MS_WINDOWS
  305.     int mode = O_RDWR;
  306.     
  307. #if defined(__DOS__) || defined(__MS_WINDOWS__) || defined(__OS2__)
  308.     mode |= O_BINARY;
  309. #endif
  310.     _fd = open (_pathName.AsPtr(), mode, S_IREAD | S_IWRITE);
  311. // #else
  312. //     OFSTRUCT    OfStruct;
  313. // 
  314. //     int mode =   OF_READWRITE;
  315. //     fd = OpenFile (_pathName.AsPtr(), &OfStruct, mode);
  316. // #endif
  317.     if (_fd < 0) 
  318.         _MakeErrorString ("_Open: open call failed");
  319.     return (_fd >= 0);
  320. }  // End of function Open
  321.  
  322.  
  323. void CL_BinaryFile::_Close()
  324. {
  325.  
  326.     if (_fd < 0)
  327.         return;
  328. // #ifndef MS_WINDOWS
  329.     close (_fd);
  330. // #else
  331. //     _lclose (fd);
  332. // #endif
  333.     _fd = -1;
  334. }  // End of function Close
  335.  
  336.  
  337.  
  338.  
  339. bool CL_BinaryFile::SeekToEnd () const
  340. {
  341.     long retval;
  342.  
  343.     _MakeErrorString ("");
  344. // #ifdef MS_WINDOWS
  345. //     if ((retval = _llseek (fd, 0L, SEEK_END)) < 0) {
  346. // #else
  347.     if ((retval = lseek (_fd, 0L, SEEK_END)) < 0) {
  348.         // #endif
  349.         _MakeErrorString  ("SeekToEnd: seek call failed");
  350.     }
  351.     return retval >= 0;
  352. }
  353.  
  354.  
  355.  
  356. CL_String CL_BinaryFile::ErrorString() const
  357. {
  358.     return _errorString;
  359. }
  360.  
  361.  
  362.  
  363.  
  364. void CL_BinaryFile::_MakeErrorString (const char* msg) const
  365. {
  366.     if (CL_String (msg).Length() > 0) {
  367.         ((CL_BinaryFile*) this)->_errorString.AssignWithFormat
  368.             ("File %s: %s: %s", _pathName.AsPtr(), msg, strerror (errno));
  369.         // Cast away const
  370.         CL_Error::Warning (_errorString);
  371.     }
  372.     else
  373.         ((CL_BinaryFile*) this)->_errorString = "";
  374.         
  375. }
  376.  
  377.  
  378. #ifdef __BORLANDC__
  379. #pragma warn .ncf
  380. #endif
  381.