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