< prev index next >
src/hotspot/share/utilities/formatBuffer.hpp
Print this page
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
@@ -61,14 +61,37 @@
char* buffer() { return _buf; }
int size() { return bufsz; }
private:
FormatBuffer(const FormatBuffer &); // prevent copies
- char _buffer[bufsz];
protected:
+ char _buffer[bufsz];
inline FormatBuffer();
+ inline void appendv(const char* format, va_list ap) ATTRIBUTE_PRINTF(2, 0);
+};
+
+// Use malloc'ed buffer if static buffer is not enough.
+template <size_t bufsz = FormatBufferBase::BufferSize>
+class FormatBufferEx : public FormatBuffer<bufsz> {
+ public:
+ inline FormatBufferEx();
+ ~FormatBufferEx(){
+ if (_dyn_buffer != NULL) {
+ ::free(_dyn_buffer);
+ }
+ }
+ inline void append(const char* format, ...) ATTRIBUTE_PRINTF(2, 3);
+ inline void print(const char* format, ...) ATTRIBUTE_PRINTF(2, 3);
+ inline void printv(const char* format, va_list argp) ATTRIBUTE_PRINTF(2, 0);
+
+ int size() { return _buffer_size; }
+
+ private:
+ inline void prepare_buffer(bool is_append, const char* format, va_list argp);
+ char *_dyn_buffer;
+ size_t _buffer_size;
};
template <size_t bufsz>
FormatBuffer<bufsz>::FormatBuffer(const char * format, ...) : FormatBufferBase(_buffer) {
va_list argp;
@@ -100,18 +123,72 @@
jio_vsnprintf(_buf, bufsz, format, argp);
}
template <size_t bufsz>
void FormatBuffer<bufsz>::append(const char* format, ...) {
+ va_list argp;
+ va_start(argp, format);
+ appendv(format, argp);
+ va_end(argp);
+}
+
+template <size_t bufsz>
+void FormatBuffer<bufsz>::appendv(const char* format, va_list argp) {
// Given that the constructor does a vsnprintf we can assume that
// _buf is already initialized.
size_t len = strlen(_buf);
char* buf_end = _buf + len;
+ jio_vsnprintf(buf_end, bufsz - len, format, argp);
+}
+
+template <size_t bufsz>
+FormatBufferEx<bufsz>::FormatBufferEx() : FormatBuffer<bufsz>(), _dyn_buffer(NULL), _buffer_size(bufsz) {
+ // Do nothing.
+}
+
+template <size_t bufsz>
+void FormatBufferEx<bufsz>::print(const char * format, ...) {
va_list argp;
va_start(argp, format);
- jio_vsnprintf(buf_end, bufsz - len, format, argp);
+ printv(format, argp);
+ va_end(argp);
+}
+
+template <size_t bufsz>
+void FormatBufferEx<bufsz>::prepare_buffer(bool is_append, const char * format, va_list argp) {
+ size_t len = jio_vsnprintf(NULL, 0, format, argp) + 1;
+ if (is_append) {
+ len += strlen(FormatBufferBase::_buf);
+ }
+ if (len > _buffer_size) {
+ _dyn_buffer = (_dyn_buffer == NULL) ? (char *)::malloc(len)
+ : (char *)::realloc(_dyn_buffer, len);
+ FormatBufferBase::_buf = _dyn_buffer;
+ _buffer_size = len;
+ }
+}
+
+template <size_t bufsz>
+void FormatBufferEx<bufsz>::printv(const char * format, va_list argp) {
+ va_list argp_local;
+ va_copy(argp_local, argp);
+ prepare_buffer(false, format, argp_local);
+ va_end(argp_local);
+
+ jio_vsnprintf(FormatBufferBase::_buf, _buffer_size, format, argp);
+}
+
+template <size_t bufsz>
+void FormatBufferEx<bufsz>::append(const char* format, ...) {
+ va_list argp, argp_prepare;
+ va_start(argp, format);
+ va_copy(argp_prepare, argp);
+ prepare_buffer(true, format, argp_prepare);
+ va_end(argp_prepare);
+
+ FormatBuffer<bufsz>::appendv(format, argp);
va_end(argp);
}
// Used to format messages.
typedef FormatBuffer<> err_msg;
< prev index next >