ostream.hpp revision 222:2a1a77d3458f
18871Srgrimes/* 21558Srgrimes * Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved. 31558Srgrimes * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 41558Srgrimes * 51558Srgrimes * This code is free software; you can redistribute it and/or modify it 61558Srgrimes * under the terms of the GNU General Public License version 2 only, as 71558Srgrimes * published by the Free Software Foundation. 81558Srgrimes * 91558Srgrimes * This code is distributed in the hope that it will be useful, but WITHOUT 101558Srgrimes * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 111558Srgrimes * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 121558Srgrimes * version 2 for more details (a copy is included in the LICENSE file that 131558Srgrimes * accompanied this code). 141558Srgrimes * 151558Srgrimes * You should have received a copy of the GNU General Public License version 161558Srgrimes * 2 along with this work; if not, write to the Free Software Foundation, 171558Srgrimes * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 181558Srgrimes * 191558Srgrimes * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 201558Srgrimes * CA 95054 USA or visit www.sun.com if you need additional information or 211558Srgrimes * have any questions. 221558Srgrimes * 231558Srgrimes */ 241558Srgrimes 251558Srgrimes// Output streams for printing 261558Srgrimes// 271558Srgrimes// Printing guidelines: 281558Srgrimes// Where possible, please use tty->print() and tty->print_cr(). 291558Srgrimes// For product mode VM warnings use warning() which internally uses tty. 301558Srgrimes// In places where tty is not initialized yet or too much overhead, 311558Srgrimes// we may use jio_printf: 321558Srgrimes// jio_fprintf(defaultStream::output_stream(), "Message"); 331558Srgrimes// This allows for redirection via -XX:+DisplayVMOutputToStdout and 341558Srgrimes// -XX:+DisplayVMOutputToStderr 357585Sbdeclass outputStream : public ResourceObj { 361558Srgrimes protected: 371558Srgrimes int _indentation; // current indentation 381558Srgrimes int _width; // width of the page 391558Srgrimes int _position; // position on the current line 401558Srgrimes int _newlines; // number of '\n' output so far 411558Srgrimes julong _precount; // number of chars output, less _position 421558Srgrimes TimeStamp _stamp; // for time stamps 437585Sbde 441558Srgrimes void update_position(const char* s, size_t len); 451558Srgrimes static const char* do_vsnprintf(char* buffer, size_t buflen, 461558Srgrimes const char* format, va_list ap, 471558Srgrimes bool add_cr, 481558Srgrimes size_t& result_len); 491558Srgrimes 501558Srgrimes public: 517585Sbde // creation 527585Sbde outputStream(int width = 80); 537585Sbde outputStream(int width, bool has_time_stamps); 541558Srgrimes 551558Srgrimes // indentation 561558Srgrimes void indent(); 571558Srgrimes void inc() { _indentation++; }; 581558Srgrimes void dec() { _indentation--; }; 591558Srgrimes int indentation() const { return _indentation; } 601558Srgrimes void set_indentation(int i) { _indentation = i; } 611558Srgrimes void fill_to(int col); 621558Srgrimes void move_to(int col, int slop = 6, int min_space = 2); 631558Srgrimes 641558Srgrimes // sizing 651558Srgrimes int width() const { return _width; } 661558Srgrimes int position() const { return _position; } 671558Srgrimes int newlines() const { return _newlines; } 681558Srgrimes julong count() const { return _precount + _position; } 691558Srgrimes void set_count(julong count) { _precount = count - _position; } 701558Srgrimes void set_position(int pos) { _position = pos; } 711558Srgrimes 721558Srgrimes // printing 731558Srgrimes void print(const char* format, ...); 741558Srgrimes void print_cr(const char* format, ...); 751558Srgrimes void vprint(const char *format, va_list argptr); 761558Srgrimes void vprint_cr(const char* format, va_list argptr); 771558Srgrimes void print_raw(const char* str) { write(str, strlen(str)); } 781558Srgrimes void print_raw(const char* str, int len) { write(str, len); } 791558Srgrimes void print_raw_cr(const char* str) { write(str, strlen(str)); cr(); } 801558Srgrimes void print_raw_cr(const char* str, int len){ write(str, len); cr(); } 811558Srgrimes void put(char ch); 821558Srgrimes void sp(int count = 1); 831558Srgrimes void cr(); 841558Srgrimes void bol() { if (_position > 0) cr(); } 851558Srgrimes 861558Srgrimes // Time stamp 871558Srgrimes TimeStamp& time_stamp() { return _stamp; } 881558Srgrimes void stamp(); 891558Srgrimes // Date stamp 901558Srgrimes void date_stamp(bool guard, const char* prefix, const char* suffix); 911558Srgrimes // A simplified call that includes a suffix of ": " 927585Sbde void date_stamp(bool guard) { 931558Srgrimes date_stamp(guard, "", ": "); 941558Srgrimes } 951558Srgrimes 961558Srgrimes // portable printing of 64 bit integers 971558Srgrimes void print_jlong(jlong value); 981558Srgrimes void print_julong(julong value); 991558Srgrimes 1001558Srgrimes // flushing 1012603Sdg virtual void flush() {} 1021558Srgrimes virtual void write(const char* str, size_t len) = 0; 1031558Srgrimes virtual ~outputStream() {} // close properly on deletion 1041558Srgrimes 1051558Srgrimes void dec_cr() { dec(); cr(); } 1061558Srgrimes void inc_cr() { inc(); cr(); } 1071558Srgrimes}; 1081558Srgrimes 1091558Srgrimes// standard output 1101558Srgrimes // ANSI C++ name collision 1111558Srgrimesextern outputStream* tty; // tty output 1121558Srgrimesextern outputStream* gclog_or_tty; // stream for gc log if -Xloggc:<f>, or tty 1131558Srgrimes 1141558Srgrimes// advisory locking for the shared tty stream: 1151558Srgrimesclass ttyLocker: StackObj { 1161558Srgrimes private: 1171558Srgrimes intx _holder; 1181558Srgrimes 1191558Srgrimes public: 1201558Srgrimes static intx hold_tty(); // returns a "holder" token 1211558Srgrimes static void release_tty(intx holder); // must witness same token 1221558Srgrimes static void break_tty_lock_for_safepoint(intx holder); 1231558Srgrimes 1241558Srgrimes ttyLocker() { _holder = hold_tty(); } 1251558Srgrimes ~ttyLocker() { release_tty(_holder); } 1261558Srgrimes}; 1271558Srgrimes 1281558Srgrimes// for writing to strings; buffer will expand automatically 1291558Srgrimesclass stringStream : public outputStream { 1301558Srgrimes protected: 1311558Srgrimes char* buffer; 1321558Srgrimes size_t buffer_pos; 1331558Srgrimes size_t buffer_length; 1341558Srgrimes bool buffer_fixed; 1351558Srgrimes public: 1361558Srgrimes stringStream(size_t initial_bufsize = 256); 1371558Srgrimes stringStream(char* fixed_buffer, size_t fixed_buffer_size); 1381558Srgrimes ~stringStream(); 1391558Srgrimes virtual void write(const char* c, size_t len); 1401558Srgrimes size_t size() { return buffer_pos; } 1411558Srgrimes const char* base() { return buffer; } 1421558Srgrimes void reset() { buffer_pos = 0; _precount = 0; _position = 0; } 1431558Srgrimes char* as_string(); 1441558Srgrimes}; 1451558Srgrimes 1461558Srgrimesclass fileStream : public outputStream { 1472603Sdg protected: 1481558Srgrimes FILE* _file; 1491558Srgrimes bool _need_close; 1502603Sdg public: 1511558Srgrimes fileStream(const char* file_name); 1521558Srgrimes fileStream(FILE* file) { _file = file; _need_close = false; } 1531558Srgrimes ~fileStream(); 1547585Sbde bool is_open() const { return _file != NULL; } 1551558Srgrimes virtual void write(const char* c, size_t len); 1561558Srgrimes void flush(); 1571558Srgrimes}; 1581558Srgrimes 1591558Srgrimes// unlike fileStream, fdStream does unbuffered I/O by calling 1601558Srgrimes// open() and write() directly. It is async-safe, but output 1611558Srgrimes// from multiple thread may be mixed together. Used by fatal 1621558Srgrimes// error handler. 1631558Srgrimesclass fdStream : public outputStream { 1641558Srgrimes protected: 1651558Srgrimes int _fd; 1661558Srgrimes bool _need_close; 1671820Sdg public: 1681558Srgrimes fdStream(const char* file_name); 1691558Srgrimes fdStream(int fd = -1) { _fd = fd; _need_close = false; } 1701558Srgrimes ~fdStream(); 1711558Srgrimes bool is_open() const { return _fd != -1; } 1721558Srgrimes void set_fd(int fd) { _fd = fd; _need_close = false; } 1731558Srgrimes int fd() const { return _fd; } 1741558Srgrimes virtual void write(const char* c, size_t len); 1751558Srgrimes void flush() {}; 1761558Srgrimes}; 1771558Srgrimes 1781558Srgrimesvoid ostream_init(); 1791558Srgrimesvoid ostream_init_log(); 1801558Srgrimesvoid ostream_exit(); 1811558Srgrimesvoid ostream_abort(); 1821558Srgrimes 1831558Srgrimes// staticBufferStream uses a user-supplied buffer for all formatting. 1841558Srgrimes// Used for safe formatting during fatal error handling. Not MT safe. 1851558Srgrimes// Do not share the stream between multiple threads. 1861558Srgrimesclass staticBufferStream : public outputStream { 1871558Srgrimes private: 1881558Srgrimes char* _buffer; 1891558Srgrimes size_t _buflen; 1901558Srgrimes outputStream* _outer_stream; 1911558Srgrimes public: 1921558Srgrimes staticBufferStream(char* buffer, size_t buflen, 1931558Srgrimes outputStream *outer_stream); 1941558Srgrimes ~staticBufferStream() {}; 1951558Srgrimes virtual void write(const char* c, size_t len); 1961558Srgrimes void flush(); 1971558Srgrimes void print(const char* format, ...); 1981558Srgrimes void print_cr(const char* format, ...); 1991558Srgrimes void vprint(const char *format, va_list argptr); 2001558Srgrimes void vprint_cr(const char* format, va_list argptr); 2011558Srgrimes}; 2021558Srgrimes 2031558Srgrimes// In the non-fixed buffer case an underlying buffer will be created and 2041558Srgrimes// managed in C heap. Not MT-safe. 2051558Srgrimesclass bufferedStream : public outputStream { 2061558Srgrimes protected: 2071558Srgrimes char* buffer; 2081558Srgrimes size_t buffer_pos; 2091558Srgrimes size_t buffer_max; 2101558Srgrimes size_t buffer_length; 2111558Srgrimes bool buffer_fixed; 2121558Srgrimes public: 2131558Srgrimes bufferedStream(size_t initial_bufsize = 256, size_t bufmax = 1024*1024*10); 2141558Srgrimes bufferedStream(char* fixed_buffer, size_t fixed_buffer_size, size_t bufmax = 1024*1024*10); 2151558Srgrimes ~bufferedStream(); 2161558Srgrimes virtual void write(const char* c, size_t len); 2171558Srgrimes size_t size() { return buffer_pos; } 2181558Srgrimes const char* base() { return buffer; } 2191558Srgrimes void reset() { buffer_pos = 0; _precount = 0; _position = 0; } 2201558Srgrimes char* as_string(); 2211558Srgrimes}; 2221558Srgrimes 2231558Srgrimes#define O_BUFLEN 2000 // max size of output of individual print() methods 2241558Srgrimes 2251558Srgrimes#ifndef PRODUCT 2261558Srgrimes 2271558Srgrimesclass networkStream : public bufferedStream { 2281558Srgrimes 2291558Srgrimes private: 2301558Srgrimes int _socket; 2311558Srgrimes 2321558Srgrimes public: 2331558Srgrimes networkStream(); 2341558Srgrimes ~networkStream(); 2351558Srgrimes 2361558Srgrimes bool connect(const char *host, short port); 2371558Srgrimes bool is_open() const { return _socket != -1; } 2381558Srgrimes int read(char *buf, size_t len); 2391558Srgrimes void close(); 2401558Srgrimes virtual void flush(); 2411558Srgrimes}; 2421558Srgrimes 2431558Srgrimes#endif 2441558Srgrimes