/* * Copyright (c) 1991 Stanford University * Copyright (c) 1991 Silicon Graphics, Inc. * * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Stanford and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Stanford and Silicon Graphics. * * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. * * IN NO EVENT SHALL STANFORD OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ #include #include #include #include #include #include #include #ifdef sgi #include #endif #ifdef __alpha extern "C" { #include } #endif /* no standard place for these */ extern "C" { #ifdef __P extern int close __P ((int)); #else extern int close (int); #endif #if defined(sgi) extern int read(int, void*, unsigned int); #endif #if defined(sun) && !defined(__SYSENT_H) #if !defined(__svr4__) extern int read(int, void*, unsigned int); #endif #endif #if defined(AIXV3) extern int read(int, char*, unsigned int); #endif #if defined(apollo) extern long read(int, void*, unsigned int); #endif #if defined(__DECCXX) extern int read(int, void*, unsigned int); #endif } #if defined(hpux) || defined(__GNUC__) #include #endif class FileInfo { public: CopyString* name_; int fd_; char* map_; struct stat info_; off_t pos_; char* buf_; unsigned int limit_; FileInfo(CopyString*, int fd); }; FileInfo::FileInfo(CopyString* s, int fd) { name_ = s; fd_ = fd; pos_ = 0; limit_ = 0; map_ = nil; buf_ = nil; } File::File(FileInfo* i) { #if !defined(hpux) assert(i != nil); #endif rep_ = i; } File::~File() { close(); delete rep_->name_; delete rep_; } const String* File::name() const { return rep_->name_; } long File::length() const { return rep_->info_.st_size; } void File::close() { FileInfo* i = rep_; if (i->fd_ >= 0) { if (i->map_ != nil) { #if defined(sgi) || defined(__alpha) munmap(i->map_, int(i->info_.st_size)); #endif } if (i->buf_ != nil) { delete[] i->buf_; } ::close(i->fd_); i->fd_ = -1; } } void File::limit(unsigned int buffersize) { rep_->limit_ = buffersize; } FileInfo* File::rep() const { return rep_; } /* class InputFile */ InputFile::InputFile(FileInfo* i) : File(i) { } InputFile::~InputFile() { } InputFile* InputFile::open(const String& name) { CopyString* s = new CopyString(name); /* cast to workaround DEC C++ prototype bug */ int fd = ::open((char*)s->string(), O_RDONLY); if (fd < 0) { delete s; return nil; } FileInfo* i = new FileInfo(s, fd); if (fstat(fd, &i->info_) < 0) { delete s; delete i; return nil; } return new InputFile(i); } int InputFile::read(const char*& start) { FileInfo* i = rep(); int len = (int)(i->info_.st_size); if (i->pos_ >= len) { return 0; } if (i->limit_ != 0 && len > i->limit_) { len = (int)(i->limit_); } #if defined(sgi) || defined(__alpha) i->map_ = (char*)mmap(0, len, PROT_READ, MAP_PRIVATE, i->fd_, i->pos_); if ((unsigned long)(i->map_) == (unsigned long)-1) { return -1; } start = i->map_; #else if (i->buf_ == nil) { i->buf_ = new char[len]; } start = i->buf_; len = ::read(i->fd_, i->buf_, len); #endif i->pos_ += len; return len; } /* class StdInput */ StdInput::StdInput() : InputFile(new FileInfo(new CopyString("-stdin"), 0)) { } StdInput::~StdInput() { } long StdInput::length() const { return -1; } int StdInput::read(const char*& start) { FileInfo* i = rep(); if (i->buf_ == nil) { if (i->limit_ == 0) { i->limit_ = BUFSIZ; } i->buf_ = new char[i->limit_]; } int nbytes = ::read(i->fd_, (char*)i->buf_, i->limit_); if (nbytes > 0) { start = (const char*)(i->buf_); } return nbytes; }