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 }