⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 file.cc

📁 早期freebsd实现
💻 CC
字号:
/* Copyright (C) 1988 Free Software Foundation    written by Doug Lea (dl@rocky.oswego.edu)This file is part of the GNU C++ Library.  This library is freesoftware; you can redistribute it and/or modify it under the terms ofthe GNU Library General Public License as published by the FreeSoftware Foundation; either version 2 of the License, or (at youroption) any later version.  This library is distributed in the hopethat it will be useful, but WITHOUT ANY WARRANTY; without even theimplied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULARPURPOSE.  See the GNU Library General Public License for more details.You should have received a copy of the GNU Library General PublicLicense along with this library; if not, write to the Free SoftwareFoundation, 675 Mass Ave, Cambridge, MA 02139, USA.*/#ifdef __GNUG__#pragma implementation#endif#include <File.h>#include <std.h>#include <stdarg.h>#include <values.h>#include <sys/file.h>           // needed to determine values of O_RDONLY...#ifdef VMS#include <errno.h>	// needed to get the psect magic loaded#define	FP	(*fp)#else#define	FP	fp#endif// error handlersvoid verbose_File_error_handler(const char* msg){  perror(msg);  errno = 0;}void quiet_File_error_handler(const char*){  errno = 0;}void fatal_File_error_handler(const char* msg){  perror(msg);  exit(1);}one_arg_error_handler_t File_error_handler = verbose_File_error_handler;one_arg_error_handler_t set_File_error_handler(one_arg_error_handler_t f){  one_arg_error_handler_t old = File_error_handler;  File_error_handler = f;  return old;}/* Opening files.  open(filename, io_mode, access_mode) is done via system open  command since fopen doesn't handle all of the cases possible  with sys open. After a successful open, fdopen is called to  attach an _iobuf to the file descriptor. All this requires a few decoding routines that can translate among our enumerated types, system flags, and fopen modes.*/enum sys_open_cmd_io_mode  // These should be correct for most systems{                          sio_read      = O_RDONLY,  sio_write     = O_WRONLY,  sio_readwrite = O_RDWR,  sio_append    = O_APPEND};enum sys_open_cmd_access_mode{  sa_create     = O_CREAT,  sa_truncate   = O_TRUNC,  sa_createonly = O_EXCL | O_CREAT};  static int open_cmd_arg(io_mode i, access_mode a) // decode modes{  int arg;  switch(i)  {  case io_readonly:   arg = sio_read;                   break;  case io_writeonly:  arg = sio_write;                  break;  case io_readwrite:  arg = sio_readwrite;              break;  case io_appendonly: arg = sio_append | sio_write;     break;  case io_append:     arg = sio_append | sio_readwrite; break;  default:            return -1;  };  switch(a)  {  case a_createonly:  return arg | sa_createonly;  case a_create:      return arg | sa_create | sa_truncate;  case a_useonly:     return arg;  case a_use:         return arg | sa_create;  default:            return -1;  }}static char* fopen_cmd_arg(io_mode i){  switch(i)  {  case io_readonly:  return "r";  case io_writeonly: return "w";  case io_readwrite: return "r+";  case io_appendonly:return "a";  case io_append:    return "a+";  default:           return 0;  }}void File::initialize() {   fp = 0; nm = 0; stat = 0; state = _bad; rw = 0;}// reset class vars after open// fp->_flag inspection is isolated herevoid File::reinitialize(const char* filename){  if (filename != 0)     setname(filename);  else if (fp == stdin)  setname("(stdin)");  else if (fp == stdout) setname("(stdout)");  else if (fp == stderr) setname("(stderr)");  else if (rw & 4)       setname("(string)");  else setname(0);  if (fp != 0)  {    state = _good;    if (FP->_flag & (_IOREAD|_IORW))      rw |= 01;    if (FP->_flag & (_IOWRT|_IORW))      rw |= 02;    check_state();  }  else  {    set(_fail); set(_bad);    error();  }}File& File::open(const char* filename, io_mode m, access_mode a){                                     close();  int open_arg = open_cmd_arg(m, a);  if (open_arg != -1)  {    int fd = ::open(filename, open_arg, 0666);    if (fd >= 0)      fp = fdopen(fd, fopen_cmd_arg(m));  }  reinitialize(filename);  return *this;}File& File::open(const char* filename, const char* m){                                     close();  fp = fopen(filename, m);  reinitialize(filename);  return *this;}File& File::open(FILE* fileptr){  close();  fp = fileptr;  reinitialize(0);  return *this;}File& File::open(int filedesc, io_mode m){  close();  fp = fdopen(filedesc, fopen_cmd_arg(m));  reinitialize(0);  return *this;}File& File::close(){  if (fp != 0)  {#ifdef VMS    if (rw & 4)                 // we own the iobuf, kill it      delete(*fp);	// kill the _iobuf#endif    if (rw & 4)                 // we own the iobuf, kill it      delete fp;    else if (fp == stdin || fp == stdout || fp == stderr)      flush();    else      fclose(fp);  }  fp = 0;  rw = 0;  set(_bad);  return *this;}File& File::remove(){  close();  return failif (nm == 0 || unlink(nm) != 0);}File::File(){   initialize(); }File::File(const char* filename, io_mode m, access_mode a)   {   initialize();   open(filename, m, a); }File::File(const char* filename, const char* m)   {   initialize();   open(filename, m); }File::File(int filedesc, io_mode m){   initialize();   open(filedesc, m); }File::File(FILE* fileptr){   initialize();   open(fileptr); }File::File(int sz, char* buf, io_mode m){  if (m != io_readonly && m != io_writeonly)    (*File_error_handler) ("invalid io_mode for string IO");  initialize();  rw = 4;#ifdef VMS  _iobuf	*iob;  FILE		*f;  iob = new _iobuf;  f = new(FILE);  *f = iob;  fp = f;#else  fp = new _iobuf;#endif#ifndef _NFILE  FP->_file = 255;          // any illegal value#else  FP->_file = _NFILE-1;       // The last filedescriptor...#ifdef BUFEND_ENTRY_TYPE  _bufendtab[FP->_file] = (BUFEND_ENTRY_TYPE)buf+sz-1;#endif#endif  FP->_ptr = FP->_base = buf;#ifdef HAVE_BUFSIZ  FP->_bufsiz = sz;#endif  if (m == io_readonly)  {    int len = 0;    while (len < sz && buf[len] != 0) ++len;    if (len == sz)      buf[sz - 1] = 0;            // force null-termination!    FP->_cnt = len;    FP->_flag = _IOREAD | _IOSTRG | _IOMYBUF;  }  else  {    bzero(buf, sz);             // so any result will be null-terminated    FP->_cnt = sz - 1;          // leave at least one null at end    FP->_flag = _IOWRT | _IOSTRG | _IOMYBUF;  }  reinitialize(0);}File::~File(){  delete(nm);  close();}void File::setname(const char* newname){  if (nm == newname) return;  if (nm != 0)    delete(nm);  if (newname != 0)  {    nm = new char[strlen(newname) + 1];    strcpy(nm, newname);  }  else    nm = 0;}File& File::setbuf(int buffer_kind){                    if (!is_open())  {    set(_fail);    return *this;  }  switch(buffer_kind)  {  case _IOFBF:       #ifdef HAVE_SETVBUF    setvbuf(fp, 0, _IOFBF, 0);#endif    break;             case _IONBF:           ::setbuf(fp, 0);     break;  case _IOLBF:#ifdef HAVE_SETLINEBUF    setlinebuf(fp);#else#ifdef HAVE_SETVBUF    setvbuf(fp, 0, _IOLBF, 0);#endif#endif        break;  default:    break;  }  return *this;}File& File::setbuf(int size, char* buf){  if (!is_open())  {    set(_fail);    return *this;  }#ifdef HAVE_SETVBUF  setvbuf(fp, buf, _IOFBF, size);#else  setbuffer(fp, buf, size);#endif  return *this;}void File::error(){  check_state();  set(_fail);  if (errno != 0)  {    char error_string[400];    strcpy(error_string, "\nerror in File ");    if (nm != 0)      strcat(error_string, nm);    (*File_error_handler)(error_string);  }}//------------------------------------------------------------------void File::check_state() // ensure fp & state agree about eof{  if (fp != 0)  {    if (feof(fp))      set(_eof);    else      unset(_eof);    if (ferror(fp))      set(_bad);  }}File& File::put(const char* s){   return failif(!writable() || fputs(s, fp) == EOF);}File& File::get(char* s, int n, char terminator){  if (!readable())  {    set(_fail);    return *this;  }  char ch;  stat = --n;  if (n > 0 && (get(ch)))  {    if (ch == terminator) {      unget(ch);      stat= 0;	// This is not an error condition !    }    else    {      *s++ = ch; --n;      while (n > 0 && (get(ch)))      {        if (ch == terminator)        {          unget(ch);          break;        }        else        {          *s++ = ch; --n;        }      }    }  }  *s = 0;  return failif((stat != 0) && ((stat -= n) == 0));}File& File::getline(char* s, int n, char terminator){  if (!readable())  {    set(_fail);    return *this;  }  char ch;  stat = --n;  while (n > 0 && (get(ch)))  {    --n;    if ((*s++ = ch) == terminator)      break;  }  *s = 0;  return failif((stat != 0) && ((stat -= n) == 0));}// from Doug Schmidt// This should probably be a page size....#define CHUNK_SIZE 512/* Reads an arbitrarily long input line terminated by a user-specified   TERMINATOR.  Super-nifty trick using recursion avoids unnecessary calls   to NEW! */char *File::readline (int chunk_number, char terminator) {  char buf[CHUNK_SIZE];  register char *bufptr = buf;  register char *ptr;  char ch;  int continu;  while ((continu = !!get(ch)) && ch != terminator) /* fill the current buffer */    {      *bufptr++ = ch;      if (bufptr - buf >= CHUNK_SIZE) /* prepend remainder to ptr buffer */        {          if (ptr = readline (chunk_number + 1, terminator))            for (; bufptr != buf; *--ptr = *--bufptr);          return ptr;        }    }  if (!continu && bufptr == buf)    return NULL;  int size = (chunk_number * CHUNK_SIZE + bufptr - buf) + 1;  if (ptr = new char[stat = size])    {      for (*(ptr += (size - 1)) = '\0'; bufptr != buf; *--ptr = *--bufptr)        ;      return ptr;    }   else     return NULL;}/* Reads an arbitrarily long input line terminated by TERMINATOR.   This routine allocates its own memory, so the user should   only supply the address of a (char *). */File& File::gets(char **s, char terminator){  if (!readable())  {    set(_fail);    return *this;  }  return failif(!(*s = readline (0, terminator)));}  #ifndef VMSFile& File::scan(const char* fmt ...){  if (readable())  {    va_list args;    va_start(args, fmt);#ifndef HAVE_VSCANF    stat = _doscan(fp, fmt, args);#else    stat = vfscanf(fp, fmt, args);#endif    va_end(args);    failif(stat <= 0);  }  return *this;}#endifFile& File::form(const char* fmt ...){  va_list args;  va_start(args, fmt);#ifndef HAVE_VPRINTF  stat = _doprnt(fmt, args, fp);#ifdef HAVE_VOID_DOPRNT  stat = ferror(fp) ? -1 : 0;#endif#else  stat = vfprintf(fp, fmt, args);#endif  va_end(args);  failif(stat < 0);  return *this;}#ifdef VMSextern "C" {    unlink(const char *s)    {        int remove(const char *);    	return remove(s);    }}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -