Panda3D
 All Classes Functions Variables Enumerations
wordWrapStreamBuf.cxx
00001 // Filename: wordWrapStreamBuf.cxx
00002 // Created by:  drose (28Jun00)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 #include "wordWrapStreamBuf.h"
00016 #include "wordWrapStream.h"
00017 #include "programBase.h"
00018 
00019 #include "pnotify.h"
00020 
00021 #ifndef HAVE_STREAMSIZE
00022 // Some compilers--notably SGI--don't define this for us.
00023 typedef int streamsize;
00024 #endif
00025 
00026 ////////////////////////////////////////////////////////////////////
00027 //     Function: WordWrapStreamBuf::Constructor
00028 //       Access: Public
00029 //  Description:
00030 ////////////////////////////////////////////////////////////////////
00031 WordWrapStreamBuf::
00032 WordWrapStreamBuf(WordWrapStream *owner, ProgramBase *program) :
00033   _owner(owner),
00034   _program(program)
00035 {
00036   _literal_mode = false;
00037 }
00038 
00039 ////////////////////////////////////////////////////////////////////
00040 //     Function: WordWrapStreamBuf::Destructor
00041 //       Access: Public, Virtual
00042 //  Description:
00043 ////////////////////////////////////////////////////////////////////
00044 WordWrapStreamBuf::
00045 ~WordWrapStreamBuf() {
00046   sync();
00047 }
00048 
00049 ////////////////////////////////////////////////////////////////////
00050 //     Function: WordWrapStreamBuf::sync
00051 //       Access: Public, Virtual
00052 //  Description: Called by the system ostream implementation when the
00053 //               buffer should be flushed to output (for instance, on
00054 //               destruction).
00055 ////////////////////////////////////////////////////////////////////
00056 int WordWrapStreamBuf::
00057 sync() {
00058   streamsize n = pptr() - pbase();
00059   write_chars(pbase(), n);
00060 
00061   // Send all the data out now.
00062   flush_data();
00063 
00064   return 0;  // EOF to indicate write full.
00065 }
00066 
00067 ////////////////////////////////////////////////////////////////////
00068 //     Function: WordWrapStreamBuf::overflow
00069 //       Access: Public, Virtual
00070 //  Description: Called by the system ostream implementation when its
00071 //               internal buffer is filled, plus one character.
00072 ////////////////////////////////////////////////////////////////////
00073 int WordWrapStreamBuf::
00074 overflow(int ch) {
00075   streamsize n = pptr() - pbase();
00076 
00077   if (n != 0 && sync() != 0) {
00078     return EOF;
00079   }
00080 
00081   if (ch != EOF) {
00082     // Write one more character.
00083     char c = ch;
00084     write_chars(&c, 1);
00085   }
00086 
00087   pbump(-n);  // Reset pptr().
00088   return 0;
00089 }
00090 
00091 ////////////////////////////////////////////////////////////////////
00092 //     Function: WordWrapStreamBuf::write_chars
00093 //       Access: Public
00094 //  Description: An internal function called by sync() and overflow()
00095 //               to store one or more characters written to the stream
00096 //               into the memory buffer.
00097 ////////////////////////////////////////////////////////////////////
00098 void WordWrapStreamBuf::
00099 write_chars(const char *start, int length) {
00100   if (length > 0) {
00101     set_literal_mode((_owner->flags() & Notify::get_literal_flag()) != 0);
00102     string new_data(start, length);
00103     size_t newline = new_data.find_first_of("\n\r");
00104     size_t p = 0;
00105     while (newline != string::npos) {
00106       // The new data contains a newline; flush our data to that point.
00107       _data += new_data.substr(p, newline - p + 1);
00108       flush_data();
00109       p = newline + 1;
00110       newline = new_data.find_first_of("\n\r", p);
00111     }
00112 
00113     // Save the rest for the next write.
00114     _data += new_data.substr(p);
00115   }
00116 }
00117 
00118 ////////////////////////////////////////////////////////////////////
00119 //     Function: WordWrapStreamBuf::flush_data
00120 //       Access: Private
00121 //  Description: Writes the contents of _data to the actual output
00122 //               stream, either word-wrapped or not as appropriate,
00123 //               and empties the contents of _data.
00124 ////////////////////////////////////////////////////////////////////
00125 void WordWrapStreamBuf::
00126 flush_data() {
00127   if (!_data.empty()) {
00128     if (_literal_mode) {
00129       cerr << _data;
00130     } else {
00131       _program->show_text(_data);
00132     }
00133     _data = "";
00134   }
00135 }
 All Classes Functions Variables Enumerations