jevering b44966774c More debug robot work. I added some statistic gathering information
as well as hooking up the context vector validation stuff.  The
debug robot now makes two files in the root verification directory
for mapping context vector to debug source dumps as well as occurance
tracking of good and bad context vectors.


git-svn-id: svn://10.0.0.236/trunk@3701 18797224-902f-48f8-a5cc-f745e15eee43
1998-06-12 01:34:49 +00:00

344 lines
7.5 KiB
C++

/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (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/NPL/
*
* 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 Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are Copyright (C) 1998
* Netscape Communications Corporation. All Rights Reserved.
*/
#include "prtypes.h"
#include "prstrm.h"
#include <string.h>
const PRIntn STRM_BUFSIZ = 8192;
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, int 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;
}
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));
}