1 /*
  2  * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.
  8  *
  9  * This code is distributed in the hope that it will be useful, but WITHOUT
 10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 12  * version 2 for more details (a copy is included in the LICENSE file that
 13  * accompanied this code).
 14  *
 15  * You should have received a copy of the GNU General Public License version
 16  * 2 along with this work; if not, write to the Free Software Foundation,
 17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 18  *
 19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 20  * or visit www.oracle.com if you need additional information or have any
 21  * questions.
 22  *
 23  */
 24 
 25 #ifndef SHARE_UTILITIES_OSTREAM_HPP
 26 #define SHARE_UTILITIES_OSTREAM_HPP
 27 
 28 #include "memory/allocation.hpp"
 29 #include "runtime/timer.hpp"
 30 #include "utilities/globalDefinitions.hpp"
 31 #include "utilities/macros.hpp"
 32 
 33 DEBUG_ONLY(class ResourceMark;)
 34 
 35 // Output streams for printing
 36 //
 37 // Printing guidelines:
 38 // Where possible, please use tty->print() and tty->print_cr().
 39 // For product mode VM warnings use warning() which internally uses tty.
 40 // In places where tty is not initialized yet or too much overhead,
 41 // we may use jio_printf:
 42 //     jio_fprintf(defaultStream::output_stream(), "Message");
 43 // This allows for redirection via -XX:+DisplayVMOutputToStdout and
 44 // -XX:+DisplayVMOutputToStderr.
 45 
 46 class outputStream : public CHeapObjBase {
 47   friend class StreamIndentor;
 48 
 49  private:
 50    NONCOPYABLE(outputStream);
 51    int _indentation; // current indentation
 52    bool _autoindent; // if true, every line starts with indentation
 53 
 54  protected:
 55    int _position;    // visual position on the current line
 56    uint64_t _precount; // number of chars output, less than _position
 57    TimeStamp _stamp; // for time stamps
 58    char* _scratch;   // internal scratch buffer for printf
 59    size_t _scratch_len; // size of internal scratch buffer
 60 
 61   // Returns whether a newline was seen or not
 62    bool update_position(const char* s, size_t len);
 63 
 64   // Processes the given format string and the supplied arguments
 65   // to produce a formatted string in the supplied buffer. Returns
 66   // the formatted string (in the buffer). If the formatted string
 67   // would be longer than the buffer, it is truncated.
 68   //
 69   // If the format string is a plain string (no format specifiers)
 70   // or is exactly "%s" to print a supplied argument string, then
 71   // the buffer is ignored, and we return the string directly.
 72   // However, if `add_cr` is true then we have to copy the string
 73   // into the buffer, which risks truncation if the string is too long.
 74   //
 75   // The `result_len` reference is always set to the length of the returned string.
 76   //
 77   // If add_cr is true then the cr will always be placed in the buffer (buffer minimum size is 2).
 78   //
 79   // In a debug build, if truncation occurs a VM warning is issued.
 80    static const char* do_vsnprintf(char* buffer, size_t buflen,
 81                                    const char* format, va_list ap,
 82                                    bool add_cr,
 83                                    size_t& result_len)  ATTRIBUTE_PRINTF(3, 0);
 84 
 85    // calls do_vsnprintf and writes output to stream; uses an on-stack buffer.
 86    void do_vsnprintf_and_write_with_automatic_buffer(const char* format, va_list ap, bool add_cr) ATTRIBUTE_PRINTF(2, 0);
 87    // calls do_vsnprintf and writes output to stream; uses the user-provided buffer;
 88    void do_vsnprintf_and_write_with_scratch_buffer(const char* format, va_list ap, bool add_cr) ATTRIBUTE_PRINTF(2, 0);
 89    // calls do_vsnprintf, then writes output to stream.
 90    void do_vsnprintf_and_write(const char* format, va_list ap, bool add_cr) ATTRIBUTE_PRINTF(2, 0);
 91 
 92    // Automatic indentation. Returns old autoindent state.
 93    bool set_autoindent(bool value);
 94 
 95  public:
 96    class TestSupport;  // Unit test support
 97 
 98    // creation
 99    outputStream(bool has_time_stamps = false);
100 
101    // indentation
102    outputStream& indent();
103    void inc() { _indentation++; };
104    void dec() { _indentation--; };
105    void inc(int n) { _indentation += n; };
106    void dec(int n) { _indentation -= n; };
107    int  indentation() const    { return _indentation; }
108    void set_indentation(int i) { _indentation = i;    }
109    int fill_to(int col);
110    void move_to(int col, int slop = 6, int min_space = 2);
111 
112    // sizing
113    int position() const { return _position; }
114    julong count() const { return _precount + _position; }
115    void set_count(julong count) { _precount = count - _position; }
116    void set_position(int pos)   { _position = pos; }
117 
118    // printing
119    // Note that (v)print_cr forces the use of internal buffering to allow
120    // appending of the "cr". This can lead to truncation if the buffer is
121    // too small.
122 
123    void print(const char* format, ...) ATTRIBUTE_PRINTF(2, 3);
124    void print_cr(const char* format, ...) ATTRIBUTE_PRINTF(2, 3);
125    void vprint(const char *format, va_list argptr) ATTRIBUTE_PRINTF(2, 0);
126    void vprint_cr(const char* format, va_list argptr) ATTRIBUTE_PRINTF(2, 0);
127    void print_raw(const char* str)                { print_raw(str, strlen(str)); }
128    void print_raw(const char* str, size_t len);
129    void print_raw_cr(const char* str)             { print_raw(str); cr(); }
130    void print_raw_cr(const char* str, size_t len) { print_raw(str, len); cr(); }
131    void print_data(void* data, size_t len, bool with_ascii, bool rel_addr=true);
132    void put(char ch);
133    void sp(int count = 1);
134    void cr();
135    void bol() { if (_position > 0)  cr(); }
136 
137 
138    // Time stamp
139    TimeStamp& time_stamp() { return _stamp; }
140    void stamp();
141    void stamp(bool guard, const char* prefix, const char* suffix);
142    void stamp(bool guard) {
143      stamp(guard, "", ": ");
144    }
145    // Date stamp
146    void date_stamp(bool guard, const char* prefix, const char* suffix);
147    // A simplified call that includes a suffix of ": "
148    void date_stamp(bool guard) {
149      date_stamp(guard, "", ": ");
150    }
151 
152    // portable printing of 64 bit integers
153    void print_jlong(jlong value);
154    void print_julong(julong value);
155 
156    // flushing
157    virtual void flush() {}
158    virtual void write(const char* str, size_t len) = 0;
159    virtual void rotate_log(bool force, outputStream* out = nullptr) {} // GC log rotation
160    virtual ~outputStream() {}   // close properly on deletion
161 
162    // Caller may specify their own scratch buffer to use for printing; otherwise,
163    // an automatic buffer on the stack (with O_BUFLEN len) is used.
164    void set_scratch_buffer(char* p, size_t len) { _scratch = p; _scratch_len = len; }
165 
166    void dec_cr() { dec(); cr(); }
167    void inc_cr() { inc(); cr(); }
168 };
169 
170 // standard output
171 // ANSI C++ name collision
172 extern outputStream* tty;           // tty output
173 
174 // outputStream indentation. When used, indentation is automatically applied
175 // when printing on the stream using the following APIs:
176 // print(), print_cr(), print_raw(), print_raw_cr()
177 class StreamIndentor {
178  private:
179   outputStream* const _stream;
180   const int           _indentation;
181   const bool          _old_autoindent;
182   NONCOPYABLE(StreamIndentor);
183 
184  public:
185   StreamIndentor(outputStream* os, int indentation) :
186     _stream(os),
187     _indentation(indentation),
188     _old_autoindent(_stream->set_autoindent(true)) {
189 
190     _stream->inc(_indentation);
191   }
192 
193   ~StreamIndentor() {
194     _stream->dec(_indentation);
195     _stream->set_autoindent(_old_autoindent);
196   }
197 };
198 
199 // advisory locking for the shared tty stream:
200 class ttyLocker: StackObj {
201   friend class ttyUnlocker;
202  private:
203   intx _holder;
204 
205  public:
206   static intx  hold_tty();                // returns a "holder" token
207   static void  release_tty(intx holder);  // must witness same token
208   static bool  release_tty_if_locked();   // returns true if lock was released
209   static void  break_tty_lock_for_safepoint(intx holder);
210 
211   ttyLocker()  { _holder = hold_tty(); }
212   ~ttyLocker() { release_tty(_holder); }
213 };
214 
215 // Release the tty lock if it's held and reacquire it if it was
216 // locked.  Used to avoid lock ordering problems.
217 class ttyUnlocker: StackObj {
218  private:
219   bool _was_locked;
220  public:
221   ttyUnlocker()  {
222     _was_locked = ttyLocker::release_tty_if_locked();
223   }
224   ~ttyUnlocker() {
225     if (_was_locked) {
226       ttyLocker::hold_tty();
227     }
228   }
229 };
230 
231 // for writing to strings; buffer will expand automatically.
232 // Buffer will always be zero-terminated.
233 class stringStream : public outputStream {
234   DEBUG_ONLY(bool _is_frozen = false);
235   char*  _buffer;
236   size_t _written;  // Number of characters written, excluding termin. zero
237   size_t _capacity;
238   const bool _is_fixed;
239   char   _small_buffer[48];
240 
241   // Grow backing buffer to desired capacity.
242   void grow(size_t new_capacity);
243 
244   // zero terminate at buffer_pos.
245   void zero_terminate();
246 
247  public:
248   // Create a stringStream using an internal buffer of initially initial_bufsize size;
249   // will be enlarged on demand. There is no maximum cap.
250   stringStream(size_t initial_capacity = 0);
251   // Creates a stringStream using a caller-provided buffer. Will truncate silently if
252   // it overflows.
253   stringStream(char* fixed_buffer, size_t fixed_buffer_size);
254   ~stringStream();
255   virtual void write(const char* c, size_t len);
256   // Return number of characters written into buffer, excluding terminating zero and
257   // subject to truncation in static buffer mode.
258   size_t      size() const { return _written; }
259   // Returns internal buffer containing the accumulated string.
260   // Returned buffer is only guaranteed to be valid as long as stream is not modified
261   const char* base() const { return _buffer; }
262   // Freezes stringStream (no further modifications possible) and returns pointer to it.
263   // No-op if stream is frozen already.
264   // Returns the internal buffer containing the accumulated string.
265   const char* freeze() NOT_DEBUG(const) {
266     DEBUG_ONLY(_is_frozen = true);
267     return _buffer;
268   };
269   void  reset();
270   bool is_empty() const { return _buffer[0] == '\0'; }
271   // Copy to a resource, or C-heap, array as requested
272   char* as_string(bool c_heap = false) const;
273   char* as_string(Arena* arena) const;
274 };
275 
276 class fileStream : public outputStream {
277  protected:
278   FILE* _file;
279   bool  _need_close;
280  public:
281   fileStream() { _file = nullptr; _need_close = false; }
282   fileStream(const char* file_name);
283   fileStream(const char* file_name, const char* opentype);
284   fileStream(FILE* file, bool need_close = false) { _file = file; _need_close = need_close; }
285   ~fileStream();
286   bool is_open() const { return _file != nullptr; }
287   virtual void write(const char* c, size_t len);
288   // unlike other classes in this file, fileStream can perform input as well as output
289   size_t read(void* data, size_t size) {
290     if (_file == nullptr)  return 0;
291     return ::fread(data, 1, size, _file);
292   }
293   size_t read(void *data, size_t size, size_t count) {
294     return read(data, size * count);
295   }
296   void close() {
297     if (_file == nullptr || !_need_close)  return;
298     fclose(_file);
299     _need_close = false;
300   }
301   long fileSize();
302   void flush();
303 };
304 
305 // unlike fileStream, fdStream does unbuffered I/O by calling
306 // open() and write() directly. It is async-safe, but output
307 // from multiple thread may be mixed together. Used by fatal
308 // error handler.
309 class fdStream : public outputStream {
310  protected:
311   int  _fd;
312   static fdStream _stdout_stream;
313   static fdStream _stderr_stream;
314  public:
315   fdStream(int fd = -1) : _fd(fd) { }
316   bool is_open() const { return _fd != -1; }
317   void set_fd(int fd) { _fd = fd; }
318   int fd() const { return _fd; }
319   virtual void write(const char* c, size_t len);
320   void flush() {};
321 
322   // predefined streams for unbuffered IO to stdout, stderr
323   static fdStream* stdout_stream() { return &_stdout_stream; }
324   static fdStream* stderr_stream() { return &_stderr_stream; }
325 };
326 
327 // A /dev/null equivalent stream
328 class nullStream : public outputStream {
329 public:
330   void write(const char* c, size_t len) {}
331   void flush() {};
332 };
333 
334 void ostream_init();
335 void ostream_init_log();
336 void ostream_exit();
337 void ostream_abort();
338 const char* make_log_name(const char* log_name, const char* force_directory);
339 
340 // In the non-fixed buffer case an underlying buffer will be created and
341 // managed in C heap. Not MT-safe.
342 class bufferedStream : public outputStream {
343  protected:
344   char*  buffer;
345   size_t buffer_pos;
346   size_t buffer_max;
347   size_t buffer_length;
348   bool   truncated;
349  public:
350   bufferedStream(size_t initial_bufsize = 256, size_t bufmax = 1024*1024*10);
351   ~bufferedStream();
352   virtual void write(const char* c, size_t len);
353   size_t      size() { return buffer_pos; }
354   const char* base() { return buffer; }
355   void  reset() { buffer_pos = 0; _precount = 0; _position = 0; }
356   char* as_string();
357 };
358 
359 #define O_BUFLEN 2000   // max size of output of individual print() methods
360 
361 #ifndef PRODUCT
362 
363 class networkStream : public bufferedStream {
364 
365   private:
366     int _socket;
367 
368   public:
369     networkStream();
370     ~networkStream();
371 
372     bool connect(const char *host, short port);
373     bool is_open() const { return _socket != -1; }
374     ssize_t read(char *buf, size_t len);
375     void close();
376     virtual void flush();
377 };
378 
379 #endif
380 
381 #endif // SHARE_UTILITIES_OSTREAM_HPP