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    // Append strings returned by gen, separating each with separator.
170    // Stops when gen returns null.
171    template <typename Generator>
172    void join(Generator gen, const char* separator) {
173      bool first = true;
174      const char* str = gen();
175      while (str != nullptr) {
176        const char* sep = first ? "" : separator;
177        print("%s%s", sep, str);
178        first = false;
179        str = gen();
180      }
181    }
182 };
183 
184 // standard output
185 // ANSI C++ name collision
186 extern outputStream* tty;           // tty output
187 
188 // outputStream indentation. When used, indentation is automatically applied
189 // when printing on the stream using the following APIs:
190 // print(), print_cr(), print_raw(), print_raw_cr()
191 class StreamIndentor {
192  private:
193   outputStream* const _stream;
194   const int           _indentation;
195   const bool          _old_autoindent;
196   NONCOPYABLE(StreamIndentor);
197 
198  public:
199   StreamIndentor(outputStream* os, int indentation) :
200     _stream(os),
201     _indentation(indentation),
202     _old_autoindent(_stream->set_autoindent(true)) {
203 
204     _stream->inc(_indentation);
205   }
206 
207   ~StreamIndentor() {
208     _stream->dec(_indentation);
209     _stream->set_autoindent(_old_autoindent);
210   }
211 };
212 
213 // advisory locking for the shared tty stream:
214 class ttyLocker: StackObj {
215   friend class ttyUnlocker;
216  private:
217   intx _holder;
218 
219  public:
220   static intx  hold_tty();                // returns a "holder" token
221   static void  release_tty(intx holder);  // must witness same token
222   static bool  release_tty_if_locked();   // returns true if lock was released
223   static void  break_tty_lock_for_safepoint(intx holder);
224 
225   ttyLocker()  { _holder = hold_tty(); }
226   ~ttyLocker() { release_tty(_holder); }
227 };
228 
229 // Release the tty lock if it's held and reacquire it if it was
230 // locked.  Used to avoid lock ordering problems.
231 class ttyUnlocker: StackObj {
232  private:
233   bool _was_locked;
234  public:
235   ttyUnlocker()  {
236     _was_locked = ttyLocker::release_tty_if_locked();
237   }
238   ~ttyUnlocker() {
239     if (_was_locked) {
240       ttyLocker::hold_tty();
241     }
242   }
243 };
244 
245 // for writing to strings; buffer will expand automatically.
246 // Buffer will always be zero-terminated.
247 class stringStream : public outputStream {
248   DEBUG_ONLY(bool _is_frozen = false);
249   char*  _buffer;
250   size_t _written;  // Number of characters written, excluding termin. zero
251   size_t _capacity;
252   const bool _is_fixed;
253   char   _small_buffer[48];
254 
255   // Grow backing buffer to desired capacity.
256   void grow(size_t new_capacity);
257 
258   // zero terminate at buffer_pos.
259   void zero_terminate();
260 
261  public:
262   // Create a stringStream using an internal buffer of initially initial_bufsize size;
263   // will be enlarged on demand. There is no maximum cap.
264   stringStream(size_t initial_capacity = 0);
265   // Creates a stringStream using a caller-provided buffer. Will truncate silently if
266   // it overflows.
267   stringStream(char* fixed_buffer, size_t fixed_buffer_size);
268   ~stringStream();
269   virtual void write(const char* c, size_t len);
270   // Return number of characters written into buffer, excluding terminating zero and
271   // subject to truncation in static buffer mode.
272   size_t      size() const { return _written; }
273   // Returns internal buffer containing the accumulated string.
274   // Returned buffer is only guaranteed to be valid as long as stream is not modified
275   const char* base() const { return _buffer; }
276   // Freezes stringStream (no further modifications possible) and returns pointer to it.
277   // No-op if stream is frozen already.
278   // Returns the internal buffer containing the accumulated string.
279   const char* freeze() NOT_DEBUG(const) {
280     DEBUG_ONLY(_is_frozen = true);
281     return _buffer;
282   };
283   void  reset();
284   bool is_empty() const { return _buffer[0] == '\0'; }
285   // Copy to a resource, or C-heap, array as requested
286   char* as_string(bool c_heap = false) const;
287   char* as_string(Arena* arena) const;
288 };
289 
290 class fileStream : public outputStream {
291  protected:
292   FILE* _file;
293   bool  _need_close;
294  public:
295   fileStream() { _file = nullptr; _need_close = false; }
296   fileStream(const char* file_name);
297   fileStream(const char* file_name, const char* opentype);
298   fileStream(FILE* file, bool need_close = false) { _file = file; _need_close = need_close; }
299   ~fileStream();
300   bool is_open() const { return _file != nullptr; }
301   virtual void write(const char* c, size_t len);
302   // unlike other classes in this file, fileStream can perform input as well as output
303   size_t read(void* data, size_t size) {
304     if (_file == nullptr)  return 0;
305     return ::fread(data, 1, size, _file);
306   }
307   size_t read(void *data, size_t size, size_t count) {
308     return read(data, size * count);
309   }
310   void close() {
311     if (_file == nullptr || !_need_close)  return;
312     fclose(_file);
313     _need_close = false;
314   }
315   long fileSize();
316   void flush();
317 };
318 
319 // unlike fileStream, fdStream does unbuffered I/O by calling
320 // open() and write() directly. It is async-safe, but output
321 // from multiple thread may be mixed together. Used by fatal
322 // error handler.
323 class fdStream : public outputStream {
324  protected:
325   int  _fd;
326   static fdStream _stdout_stream;
327   static fdStream _stderr_stream;
328  public:
329   fdStream(int fd = -1) : _fd(fd) { }
330   bool is_open() const { return _fd != -1; }
331   void set_fd(int fd) { _fd = fd; }
332   int fd() const { return _fd; }
333   virtual void write(const char* c, size_t len);
334   void flush() {};
335 
336   // predefined streams for unbuffered IO to stdout, stderr
337   static fdStream* stdout_stream() { return &_stdout_stream; }
338   static fdStream* stderr_stream() { return &_stderr_stream; }
339 };
340 
341 // A /dev/null equivalent stream
342 class nullStream : public outputStream {
343 public:
344   void write(const char* c, size_t len) {}
345   void flush() {};
346 };
347 
348 void ostream_init();
349 void ostream_init_log();
350 void ostream_exit();
351 void ostream_abort();
352 const char* make_log_name(const char* log_name, const char* force_directory);
353 
354 // In the non-fixed buffer case an underlying buffer will be created and
355 // managed in C heap. Not MT-safe.
356 class bufferedStream : public outputStream {
357  protected:
358   char*  buffer;
359   size_t buffer_pos;
360   size_t buffer_max;
361   size_t buffer_length;
362   bool   truncated;
363  public:
364   bufferedStream(size_t initial_bufsize = 256, size_t bufmax = 1024*1024*10);
365   ~bufferedStream();
366   virtual void write(const char* c, size_t len);
367   size_t      size() { return buffer_pos; }
368   const char* base() { return buffer; }
369   void  reset() { buffer_pos = 0; _precount = 0; _position = 0; }
370   char* as_string();
371 };
372 
373 #define O_BUFLEN 2000   // max size of output of individual print() methods
374 
375 #ifndef PRODUCT
376 
377 class networkStream : public bufferedStream {
378 
379   private:
380     int _socket;
381 
382   public:
383     networkStream();
384     ~networkStream();
385 
386     bool connect(const char *host, short port);
387     bool is_open() const { return _socket != -1; }
388     ssize_t read(char *buf, size_t len);
389     void close();
390     virtual void flush();
391 };
392 
393 #endif
394 
395 #endif // SHARE_UTILITIES_OSTREAM_HPP