*** empty log message ***

This commit is contained in:
David Rose 2000-11-28 00:32:28 +00:00
parent ad1326e180
commit 56dd8577d9
7 changed files with 401 additions and 2 deletions

View File

@ -18,7 +18,9 @@
indent.I indent.cxx indent.h littleEndian.I \
littleEndian.cxx littleEndian.h memoryUsage.I memoryUsage.cxx \
memoryUsage.h memoryUsagePointers.I memoryUsagePointers.cxx \
memoryUsagePointers.h multifile.I multifile.cxx multifile.h \
memoryUsagePointers.h multifile.I multifile.cxx multifile.h \
multiplexStream.I multiplexStream.cxx multiplexStream.h \
multiplexStreamBuf.I multiplexStreamBuf.cxx multiplexStreamBuf.h \
namable.I namable.cxx namable.h numeric_types.h patchfile.I \
patchfile.cxx patchfile.h pointerTo.I pointerTo.h referenceCount.I \
referenceCount.cxx referenceCount.h tokenBoard.I tokenBoard.h \
@ -35,7 +37,10 @@
datagramGenerator.h get_config_path.h \
indent.I indent.h littleEndian.I littleEndian.h \
memoryUsage.I memoryUsage.h memoryUsagePointers.I \
memoryUsagePointers.h multifile.I multifile.h numeric_types.h \
memoryUsagePointers.h multifile.I multifile.h \
multiplexStream.I multiplexStream.h \
multiplexStreamBuf.I multiplexStreamBuf.I \
numeric_types.h \
pointerTo.I pointerTo.h referenceCount.I referenceCount.h \
tokenBoard.h trueClock.I trueClock.h typeHandle.I typeHandle.h \
typedReferenceCount.I typedReferenceCount.h typedef.h \

View File

@ -0,0 +1,90 @@
// Filename: multiplexStream.I
// Created by: drose (27Nov00)
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: MultiplexStream::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE MultiplexStream::
MultiplexStream() : ostream(&_msb) {
setf(ios::unitbuf);
}
////////////////////////////////////////////////////////////////////
// Function: MultiplexStream::add_ostream
// Access: Public
// Description: Adds the indicated generic ostream to the multiplex
// output. The ostream will receive whatever data is
// sent to the pipe.
////////////////////////////////////////////////////////////////////
INLINE void MultiplexStream::
add_ostream(ostream *out, bool delete_later) {
_msb.add_output(MultiplexStreamBuf::BT_none,
MultiplexStreamBuf::OT_ostream,
out, delete_later);
}
////////////////////////////////////////////////////////////////////
// Function: MultiplexStream::add_standard_output
// Access: Public
// Description: Adds the standard output channel.
////////////////////////////////////////////////////////////////////
INLINE void MultiplexStream::
add_standard_output() {
_msb.add_output(MultiplexStreamBuf::BT_none,
MultiplexStreamBuf::OT_ostream,
&cout, false);
}
////////////////////////////////////////////////////////////////////
// Function: MultiplexStream::add_file
// Access: Public
// Description: Adds the given file to the multiplex output. The
// file is opened in append mode with line buffering.
// Returns false if the file cannot be opened.
////////////////////////////////////////////////////////////////////
INLINE bool MultiplexStream::
add_file(Filename file) {
file.set_text();
ofstream *out = new ofstream;
if (!file.open_append(*out)) {
delete out;
return false;
}
out->setf(ios::unitbuf);
_msb.add_output(MultiplexStreamBuf::BT_line,
MultiplexStreamBuf::OT_ostream,
out, true);
return true;
}
////////////////////////////////////////////////////////////////////
// Function: MultiplexStream::add_system_debug
// Access: Public
// Description: Adds the system debug output the the multiplex
// output. This may map to a syslog or some such
// os-specific output system. It may do nothing on a
// particular system.
//
// Presently, this maps only to OutputDebugString() on
// Windows.
////////////////////////////////////////////////////////////////////
INLINE void MultiplexStream::
add_system_debug() {
_msb.add_output(MultiplexStreamBuf::BT_line,
MultiplexStreamBuf::OT_system_debug);
}
////////////////////////////////////////////////////////////////////
// Function: MultiplexStream::flush
// Access: Public
// Description: Forces out all output that hasn't yet been written.
////////////////////////////////////////////////////////////////////
INLINE void MultiplexStream::
flush() {
_msb.flush();
}

View File

@ -0,0 +1,6 @@
// Filename: multiplexStream.cxx
// Created by: drose (27Nov00)
//
////////////////////////////////////////////////////////////////////
#include "multiplexStream.h"

View File

@ -0,0 +1,41 @@
// Filename: multiplexStream.h
// Created by: drose (27Nov00)
//
////////////////////////////////////////////////////////////////////
#ifndef MULTIPLEXSTREAM_H
#define MULTIPLEXSTREAM_H
#include <pandabase.h>
#include "multiplexStreamBuf.h"
#include <filename.h>
////////////////////////////////////////////////////////////////////
// Class : MultiplexStream
// Description : This is a special ostream that forwards the data that
// is written to it to any number of other sources, for
// instance other ostreams, or explicitly to a disk file
// or to system logging utilities. It's a very handy
// thing to set Notify to refer to when running in batch
// mode.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA MultiplexStream : public ostream {
PUBLISHED:
INLINE MultiplexStream();
INLINE void add_ostream(ostream *out, bool delete_later = false);
INLINE void add_standard_output();
INLINE bool add_file(Filename file);
INLINE void add_system_debug();
INLINE void flush();
private:
MultiplexStreamBuf _msb;
};
#include "multiplexStream.I"
#endif

View File

@ -0,0 +1,35 @@
// Filename: multiplexStreamBuf.I
// Created by: drose (27Nov00)
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: MultiplexStreamBuf::add_output
// Access: Public
// Description: Adds the indicated output destinition to the set of
// things that will be written to when characters are
// output to the MultiplexStream.
////////////////////////////////////////////////////////////////////
INLINE void MultiplexStreamBuf::
add_output(MultiplexStreamBuf::BufferType buffer_type,
MultiplexStreamBuf::OutputType output_type,
ostream *out, bool owns_ostream) {
Output o;
o._buffer_type = buffer_type;
o._output_type = output_type;
o._out = out;
o._owns_ostream = owns_ostream;
_outputs.push_back(o);
}
////////////////////////////////////////////////////////////////////
// Function: MultiplexStreamBuf::flush
// Access: Public
// Description: Forces out all output that hasn't yet been written.
////////////////////////////////////////////////////////////////////
INLINE void MultiplexStreamBuf::
flush() {
write_chars("", 0, true);
}

View File

@ -0,0 +1,156 @@
// Filename: multiplexStreamBuf.cxx
// Created by: drose (27Nov00)
//
////////////////////////////////////////////////////////////////////
#include "multiplexStreamBuf.h"
// We use real assert() instead of nassert(), because we're likely
// to be invoked directly by notify here, and we don't want to
// risk infinite recursion.
#include <assert.h>
#ifndef HAVE_STREAMSIZE
// Some compilers--notably SGI--don't define this for us.
typedef int streamsize;
#endif
////////////////////////////////////////////////////////////////////
// Function: MultiplexStreamBuf::Output::wrinte_string
// Access: Public
// Description: Dumps the indicated string to the appropriate place.
////////////////////////////////////////////////////////////////////
void MultiplexStreamBuf::Output::
write_string(const string &str) {
switch (_output_type) {
case OT_ostream:
assert(_out != (ostream *)NULL);
_out->write(str.data(), str.length());
break;
case OT_system_debug:
break;
}
}
static char test[1024];
////////////////////////////////////////////////////////////////////
// Function: MultiplexStreamBuf::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
MultiplexStreamBuf::
MultiplexStreamBuf() {
allocate();
setp(base(), ebuf());
}
////////////////////////////////////////////////////////////////////
// Function: MultiplexStreamBuf::Destructor
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
MultiplexStreamBuf::
~MultiplexStreamBuf() {
sync();
}
////////////////////////////////////////////////////////////////////
// Function: MultiplexStreamBuf::sync
// Access: Public, Virtual
// Description: Called by the system ostream implementation when the
// buffer should be flushed to output (for instance, on
// destruction).
////////////////////////////////////////////////////////////////////
int MultiplexStreamBuf::
sync() {
streamsize n = pptr() - pbase();
// We pass in false for the flush value, even though our
// transmitting ostream said to sync. This allows us to get better
// line buffering, since our transmitting ostream is often set
// unitbuf, and might call sync multiple times in one line. We
// still have an explicit flush() call to force the issue.
write_chars(pbase(), n, false);
pbump(-n);
return 0; // Return 0 for success, EOF to indicate write full.
}
////////////////////////////////////////////////////////////////////
// Function: MultiplexStreamBuf::overflow
// Access: Public, Virtual
// Description: Called by the system ostream implementation when its
// internal buffer is filled, plus one character.
////////////////////////////////////////////////////////////////////
int MultiplexStreamBuf::
overflow(int ch) {
streamsize n = pptr() - pbase();
if (n != 0) {
write_chars(pbase(), n, false);
pbump(-n); // Reset pptr().
}
if (ch != EOF) {
// Write one more character.
char c = ch;
write_chars(&c, 1, false);
}
return 0;
}
////////////////////////////////////////////////////////////////////
// Function: MultiplexStreamBuf::write_chars
// Access: Private
// Description: An internal function called by sync() and overflow()
// to store one or more characters written to the stream
// into the memory buffer.
////////////////////////////////////////////////////////////////////
void MultiplexStreamBuf::
write_chars(const char *start, int length, bool flush) {
size_t orig = _line_buffer.length();
string latest(start, length);
string line;
if (flush) {
// If we're to flush the stream now, we dump the whole thing
// regardless of whether we have reached end-of-line.
line = _line_buffer + latest;
_line_buffer = "";
} else {
// Otherwise, we check for the end-of-line character, for our
// ostreams that only want a complete line at a time.
_line_buffer += latest;
size_t eol = _line_buffer.rfind('\n', orig);
if (eol != string::npos) {
line = _line_buffer.substr(0, eol + 1);
_line_buffer = _line_buffer.substr(eol + 1);
}
}
Outputs::iterator oi;
for (oi = _outputs.begin(); oi != _outputs.end(); ++oi) {
Output &out = (*oi);
switch (out._buffer_type) {
case BT_none:
// No buffering: send all new characters directly to the ostream.
if (!latest.empty()) {
out.write_string(latest);
}
break;
case BT_line:
// Line buffering: send only when a complete line has been
// received.
if (!line.empty()) {
out.write_string(line);
}
break;
}
}
}

View File

@ -0,0 +1,66 @@
// Filename: multiplexStreamBuf.h
// Created by: drose (27Nov00)
//
////////////////////////////////////////////////////////////////////
#ifndef MULTIPLEXSTREAMBUF_H
#define MULTIPLEXSTREAMBUF_H
#include <pandabase.h>
#include <vector>
////////////////////////////////////////////////////////////////////
// Class : MultiplexStreamBuf
// Description : Used by MultiplexStream to implement an ostream that
// sends what is written to it to any number of
// additional sources, like other ostreams.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA MultiplexStreamBuf : public streambuf {
public:
MultiplexStreamBuf();
virtual ~MultiplexStreamBuf();
enum BufferType {
BT_none,
BT_line,
};
enum OutputType {
OT_ostream,
OT_system_debug,
};
INLINE void add_output(BufferType buffer_type, OutputType output_type,
ostream *out = (ostream *)NULL,
bool owns_ostream = false);
INLINE void flush();
protected:
virtual int overflow(int c);
virtual int sync();
private:
void write_chars(const char *start, int length, bool flush);
class Output {
public:
void write_string(const string &str);
BufferType _buffer_type;
OutputType _output_type;
ostream *_out;
bool _owns_ostream;
};
typedef vector<Output> Outputs;
Outputs _outputs;
string _line_buffer;
};
#include "multiplexStreamBuf.I"
#endif