📄 prstrms.cpp
字号:
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- *//* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is the Netscape Portable Runtime (NSPR). * * The Initial Developer of the Original Code is Netscape * Communications Corporation. Portions created by Netscape are * Copyright (C) 1998-2000 Netscape Communications Corporation. All * Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. *//* * Robin J. Maxwell 11-22-96 */#include "prstrms.h"#include <string.h> // memmove//// Definition of macros _PRSTR_BP, _PRSTR_DELBUF, and _PRSTR_DELBUF_C.//// _PRSTR_BP is the protected member of class ios that is returned// by the public method rdbuf().//// _PRSTR_DELBUF is the method or data member of class ios, if available,// with which we can ensure that the ios destructor does not delete// the associated streambuf. If such a method or data member does not// exist, define _PRSTR_DELBUF to be empty.//// _PRSTR_DELBUF_C is just _PRSTR_DELBUF qualified by a base class.//#if defined(__GNUC__)#define _PRSTR_BP _strbuf#define _PRSTR_DELBUF(x) /* as nothing */#define _PRSTR_DELBUF_C(c, x) /* as nothing */#elif defined(WIN32)#define _PRSTR_BP bp#define _PRSTR_DELBUF(x) delbuf(x)#define _PRSTR_DELBUF_C(c, x) c::_PRSTR_DELBUF(x)#elif defined(VMS)#undef _PRSTR_BP#define _PRSTR_DELBUF(x) /* as nothing */#define _PRSTR_DELBUF_C(c, x) /* as nothing */#elif defined(OSF1)#define _PRSTR_BP m_psb#define _PRSTR_DELBUF(x) /* as nothing */#define _PRSTR_DELBUF_C(c, x) /* as nothing */#elif defined(QNX)#define PRFSTREAMS_BROKEN#else#define _PRSTR_BP bp// Unix compilers don't believe in encapsulation// At least on Solaris this is also ignored#define _PRSTR_DELBUF(x) delbuf = x#define _PRSTR_DELBUF_C(c, x) c::_PRSTR_DELBUF(x)#endifconst PRIntn STRM_BUFSIZ = 8192;#if !defined (PRFSTREAMS_BROKEN) PRfilebuf::PRfilebuf():_fd(0),_opened(PR_FALSE),_allocated(PR_FALSE){}PRfilebuf::PRfilebuf(PRFileDesc *fd):streambuf(),_fd(fd),_opened(PR_FALSE),_allocated(PR_FALSE){}PRfilebuf::PRfilebuf(PRFileDesc *fd, char * buffptr, int bufflen):_fd(fd),_opened(PR_FALSE),_allocated(PR_FALSE){ PRfilebuf::setbuf(buffptr, bufflen);}PRfilebuf::~PRfilebuf(){ if (_opened){ close(); }else sync(); if (_allocated) delete base();}PRfilebuf* PRfilebuf::open(const char *name, int mode, int flags){ if (_fd != 0) return 0; // error if already open PRIntn PRmode = 0; // translate mode argument if (!(mode & ios::nocreate)) PRmode |= PR_CREATE_FILE; //if (mode & ios::noreplace) // PRmode |= O_EXCL; if (mode & ios::app){ mode |= ios::out; PRmode |= PR_APPEND; } if (mode & ios::trunc){ mode |= ios::out; // IMPLIED PRmode |= PR_TRUNCATE; } if (mode & ios::out){ if (mode & ios::in) PRmode |= PR_RDWR; else PRmode |= PR_WRONLY; if (!(mode & (ios::in|ios::app|ios::ate|ios::noreplace))){ mode |= ios::trunc; // IMPLIED PRmode |= PR_TRUNCATE; } }else if (mode & ios::in) PRmode |= PR_RDONLY; else return 0; // error if not ios:in or ios::out // // The usual portable across unix crap... // NT gets a hokey piece of junk layer that prevents // access to the API.#ifdef WIN32 _fd = PR_Open(name, PRmode, PRmode);#else _fd = PR_Open(name, PRmode, flags);#endif if (_fd == 0) return 0; _opened = PR_TRUE; if ((!unbuffered()) && (!ebuf())){ char * sbuf = new char[STRM_BUFSIZ]; if (!sbuf) unbuffered(1); else{ _allocated = PR_TRUE; streambuf::setb(sbuf,sbuf+STRM_BUFSIZ,0); } } if (mode & ios::ate){ if (seekoff(0,ios::end,mode)==EOF){ close(); return 0; } } return this;}PRfilebuf* PRfilebuf::attach(PRFileDesc *fd){ _opened = PR_FALSE; _fd = fd; return this;}int PRfilebuf::overflow(int c){ if (allocate()==EOF) // make sure there is a reserve area return EOF; if (PRfilebuf::sync()==EOF) // sync before new buffer created below return EOF; if (!unbuffered()) setp(base(),ebuf()); if (c!=EOF){ if ((!unbuffered()) && (pptr() < epptr())) // guard against recursion sputc(c); else{ if (PR_Write(_fd, &c, 1)!=1) return(EOF); } } return(1); // return something other than EOF if successful}int PRfilebuf::underflow(){ int count; unsigned char tbuf; if (in_avail()) return (int)(unsigned char) *gptr(); if (allocate()==EOF) // make sure there is a reserve area return EOF; if (PRfilebuf::sync()==EOF) return EOF; if (unbuffered()) { if (PR_Read(_fd,(void *)&tbuf,1)<=0) return EOF; return (int)tbuf; } if ((count=PR_Read(_fd,(void *)base(),blen())) <= 0) return EOF; // reached EOF setg(base(),base(),base()+count); return (int)(unsigned char) *gptr();}streambuf* PRfilebuf::setbuf(char *buffptr, PRstreambuflen bufflen){ if (is_open() && (ebuf())) return 0; if ((!buffptr) || (bufflen <= 0)) unbuffered(1); else setb(buffptr, buffptr+bufflen, 0); return this;}streampos PRfilebuf::seekoff(streamoff offset, ios::seek_dir dir, int /* mode */){ if (PR_GetDescType(_fd) == PR_DESC_FILE){ PRSeekWhence fdir; PRInt32 retpos; switch (dir) { case ios::beg : fdir = PR_SEEK_SET; break; case ios::cur : fdir = PR_SEEK_CUR; break; case ios::end : fdir = PR_SEEK_END; break; default: // error return(EOF); } if (PRfilebuf::sync()==EOF) return EOF; if ((retpos=PR_Seek(_fd, offset, fdir))==-1L) return (EOF); return((streampos)retpos); }else return (EOF);}int PRfilebuf::sync(){ PRInt32 count; if (_fd==0) return(EOF); if (!unbuffered()){ // Sync write area if ((count=out_waiting())!=0){ PRInt32 nout; if ((nout =PR_Write(_fd, (void *) pbase(), (unsigned int)count)) != count){ if (nout > 0) { // should set _pptr -= nout pbump(-(int)nout); memmove(pbase(), pbase()+nout, (int)(count-nout)); } return(EOF); } } setp(0,0); // empty put area if (PR_GetDescType(_fd) == PR_DESC_FILE){ // Sockets can't seek; don't need this if ((count=in_avail()) > 0){ if (PR_Seek(_fd, -count, PR_SEEK_CUR)!=-1L) { return (EOF); } } } setg(0,0,0); // empty get area } return(0);}PRfilebuf * PRfilebuf::close(){ int retval; if (_fd==0) return 0; retval = sync(); if ((PR_Close(_fd)==0) || (retval==EOF)) return 0; _fd = 0; return this;}PRifstream::PRifstream():istream(new PRfilebuf){ _PRSTR_DELBUF(0);}PRifstream::PRifstream(PRFileDesc *fd):istream(new PRfilebuf(fd)){ _PRSTR_DELBUF(0);}PRifstream::PRifstream(PRFileDesc *fd, char *buff, int bufflen):istream(new PRfilebuf(fd, buff, bufflen)){ _PRSTR_DELBUF(0);}PRifstream::PRifstream(const char * name, int mode, int flags):istream(new PRfilebuf){ _PRSTR_DELBUF(0); if (!rdbuf()->open(name, (mode|ios::in), flags)) clear(rdstate() | ios::failbit);}PRifstream::~PRifstream(){ sync(); delete rdbuf();#ifdef _PRSTR_BP _PRSTR_BP = 0;#endif}streambuf * PRifstream::setbuf(char * ptr, int len){ if ((is_open()) || (!(rdbuf()->setbuf(ptr, len)))){ clear(rdstate() | ios::failbit); return 0; } return rdbuf();}void PRifstream::attach(PRFileDesc *fd){ if (!(rdbuf()->attach(fd))) clear(rdstate() | ios::failbit);}void PRifstream::open(const char * name, int mode, int flags){ if (is_open() || !(rdbuf()->open(name, (mode|ios::in), flags))) clear(rdstate() | ios::failbit);}void PRifstream::close(){ clear((rdbuf()->close()) ? 0 : (rdstate() | ios::failbit));}PRofstream::PRofstream():ostream(new PRfilebuf){ _PRSTR_DELBUF(0);}PRofstream::PRofstream(PRFileDesc *fd):ostream(new PRfilebuf(fd)){ _PRSTR_DELBUF(0);}PRofstream::PRofstream(PRFileDesc *fd, char *buff, int bufflen):ostream(new PRfilebuf(fd, buff, bufflen)){ _PRSTR_DELBUF(0);}PRofstream::PRofstream(const char *name, int mode, int flags):ostream(new PRfilebuf){ _PRSTR_DELBUF(0); if (!rdbuf()->open(name, (mode|ios::out), flags)) clear(rdstate() | ios::failbit);}PRofstream::~PRofstream(){ flush(); delete rdbuf();#ifdef _PRSTR_BP _PRSTR_BP = 0;#endif}streambuf * PRofstream::setbuf(char * ptr, int len){ if ((is_open()) || (!(rdbuf()->setbuf(ptr, len)))){ clear(rdstate() | ios::failbit); return 0; } return rdbuf();}void PRofstream::attach(PRFileDesc *fd){ if (!(rdbuf()->attach(fd))) clear(rdstate() | ios::failbit);}void PRofstream::open(const char * name, int mode, int flags){ if (is_open() || !(rdbuf()->open(name, (mode|ios::out), flags))) clear(rdstate() | ios::failbit);}void PRofstream::close(){ clear((rdbuf()->close()) ? 0 : (rdstate() | ios::failbit));}PRfstream::PRfstream():iostream(new PRfilebuf){ _PRSTR_DELBUF_C(istream, 0); _PRSTR_DELBUF_C(ostream, 0);}PRfstream::PRfstream(PRFileDesc *fd):iostream(new PRfilebuf(fd)){ _PRSTR_DELBUF_C(istream, 0); _PRSTR_DELBUF_C(ostream, 0);}PRfstream::PRfstream(PRFileDesc *fd, char *buff, int bufflen):iostream(new PRfilebuf(fd, buff, bufflen)){ _PRSTR_DELBUF_C(istream, 0); _PRSTR_DELBUF_C(ostream, 0);}PRfstream::PRfstream(const char *name, int mode, int flags):iostream(new PRfilebuf){ _PRSTR_DELBUF_C(istream, 0); _PRSTR_DELBUF_C(ostream, 0); if (!rdbuf()->open(name, (mode|(ios::in|ios::out)), flags)) clear(rdstate() | ios::failbit);}PRfstream::~PRfstream(){ sync(); flush(); delete rdbuf();#ifdef _PRSTR_BP istream::_PRSTR_BP = 0; ostream::_PRSTR_BP = 0;#endif}streambuf * PRfstream::setbuf(char * ptr, int len){ if ((is_open()) || (!(rdbuf()->setbuf(ptr, len)))){ clear(rdstate() | ios::failbit); return 0; } return rdbuf();}void PRfstream::attach(PRFileDesc *fd){ if (!(rdbuf()->attach(fd))) clear(rdstate() | ios::failbit);}void PRfstream::open(const char * name, int mode, int flags){ if (is_open() || !(rdbuf()->open(name, (mode|(ios::in|ios::out)), flags))) clear(rdstate() | ios::failbit);}void PRfstream::close(){ clear((rdbuf()->close()) ? 0 : (rdstate() | ios::failbit));}#else// fix it sometimeint fix_prfstreams () { return 0; }#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -