// // aegis - project change supervisor // Copyright (C) 1999-2006, 2008, 2012 Peter Miller // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see // . // #include #include #include #include #include #include #include #include wide_output::~wide_output() { trace(("wide_output::~wide_output(this = %p)\n{\n", this)); // // run any delete callbacks specified // callback(); // // now get rid of it // delete [] buffer; buffer = 0; buffer_size = 0; buffer_position = 0; buffer_end = 0; trace(("}\n")); } wide_output::wide_output() : buffer(0), buffer_size(0), buffer_position(0), buffer_end(0) { buffer_size = (size_t)1 << 11; buffer = (wchar_t *)mem_alloc(buffer_size * sizeof(wchar_t)); buffer_position = buffer; buffer_end = buffer + buffer_size; } void wide_output::overflow(wchar_t wc) { trace(("wide_output::overflow(this = %p, wc = %04lX)\n{\n", this, (long)wc)); assert(buffer); assert(buffer_size); assert(buffer_position >= buffer); assert(buffer_end == buffer + buffer_size); assert(buffer_position <= buffer_end); if (buffer_position >= buffer_end) { write_inner(buffer, buffer_size); buffer_position = buffer; } *buffer_position++ = wc; trace(("}\n")); } void wide_output::put_ws(const wchar_t *s) { trace(("wide_output::put_ws(fp = %p, s = %p)\n{\n", this, s)); if (s) { const wchar_t *wse = s; while (*wse) ++wse; if (wse > s) write(s, wse - s); } trace(("}\n")); } void wide_output::write(const wstring &s) { trace(("wide_output::write(this = %p)\n{\n", this)); write(s.c_str(), s.size()); trace(("}\n")); } void wide_output::write(const wchar_t *data, size_t len) { trace(("wide_output::write(this = %p, data = %p, len = %ld)\n{\n", this, data, (long)len)); assert(data); // assert(len); ideal, but not necessary if (buffer_position + len <= buffer_end) { memcpy(buffer_position, data, len * sizeof(wchar_t)); buffer_position += len; } else { size_t nwc = buffer_position - buffer; write_inner(buffer, nwc); buffer_position = buffer; if (len < buffer_size) { memcpy(buffer, data, len * sizeof(wchar_t)); buffer_position += len; } else write_inner(data, len); } trace(("}\n")); } void wide_output::flush() { trace(("wide_output::flush(this = %p)\n{\n", this)); if (buffer_position > buffer) { size_t nwc = buffer_position - buffer; write_inner(buffer, nwc); buffer_position = buffer; } flush_inner(); trace(("}\n")); } void wide_output::end_of_line() { // // If possible, just stuff a newline into the buffer and bail. // This results in the fewest deeper calls. // trace(("wide_output::end_of_line(this = %p)\n{\n", this)); if ( buffer_position > buffer && buffer_position[-1] != '\n' && buffer_position < buffer_end ) { *buffer_position++ = '\n'; trace(("}\n")); return; } // // If there is something in the buffer, we need to flush it, // so that the deeper eoln will have the current state. // if (buffer_position > buffer) { size_t nwc = buffer_position - buffer; write_inner(buffer, nwc); buffer_position = buffer; } // // Now ask the deeper instance to do it's end of line thing. // end_of_line_inner(); trace(("}\n")); } void wide_output::register_delete_callback(functor::pointer cb) { callback.push_back(cb); } void wide_output::unregister_delete_callback(functor::pointer cb) { callback.remove(cb); } void wide_output::put_wstr(wstring_ty *wsp) { if (!wsp || !wsp->wstr_length) return; write(wsp->wstr_text, wsp->wstr_length); } void wide_output::fputs(string_ty *s) { if (!s || !s->str_length) return; wstring_ty *s2 = wstr_n_from_c(s->str_text, s->str_length); put_wstr(s2); wstr_free(s2); } void wide_output::put_cstr(const char *s) { if (!s || !*s) return; wstring_ty *s2 = wstr_from_c(s); put_wstr(s2); wstr_free(s2); } int wide_output::page_width() { return page_width_get(-1) - 1; } int wide_output::page_length() { return page_length_get(-1); } // vim: set ts=8 sw=4 et :