1 /*
2 * Copyright (c) 2017, 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 *
46 };
47
48 class FormatBufferDummy {};
49
50 // Use stack for buffer
51 template <size_t bufsz = FormatBufferBase::BufferSize>
52 class FormatBuffer : public FormatBufferBase {
53 public:
54 inline FormatBuffer(const char* format, ...) ATTRIBUTE_PRINTF(2, 3);
55 // since va_list is unspecified type (can be char*), we use FormatBufferDummy to disambiguate these constructors
56 inline FormatBuffer(FormatBufferDummy dummy, const char* format, va_list ap) ATTRIBUTE_PRINTF(3, 0);
57 inline void append(const char* format, ...) ATTRIBUTE_PRINTF(2, 3);
58 inline void print(const char* format, ...) ATTRIBUTE_PRINTF(2, 3);
59 inline void printv(const char* format, va_list ap) ATTRIBUTE_PRINTF(2, 0);
60
61 char* buffer() { return _buf; }
62 int size() { return bufsz; }
63
64 private:
65 FormatBuffer(const FormatBuffer &); // prevent copies
66 char _buffer[bufsz];
67
68 protected:
69 inline FormatBuffer();
70 };
71
72 template <size_t bufsz>
73 FormatBuffer<bufsz>::FormatBuffer(const char * format, ...) : FormatBufferBase(_buffer) {
74 va_list argp;
75 va_start(argp, format);
76 jio_vsnprintf(_buf, bufsz, format, argp);
77 va_end(argp);
78 }
79
80 template <size_t bufsz>
81 FormatBuffer<bufsz>::FormatBuffer(FormatBufferDummy dummy, const char * format, va_list ap) : FormatBufferBase(_buffer) {
82 jio_vsnprintf(_buf, bufsz, format, ap);
83 }
84
85 template <size_t bufsz>
86 FormatBuffer<bufsz>::FormatBuffer() : FormatBufferBase(_buffer) {
87 _buf[0] = '\0';
88 }
89
90 template <size_t bufsz>
91 void FormatBuffer<bufsz>::print(const char * format, ...) {
92 va_list argp;
93 va_start(argp, format);
94 jio_vsnprintf(_buf, bufsz, format, argp);
95 va_end(argp);
96 }
97
98 template <size_t bufsz>
99 void FormatBuffer<bufsz>::printv(const char * format, va_list argp) {
100 jio_vsnprintf(_buf, bufsz, format, argp);
101 }
102
103 template <size_t bufsz>
104 void FormatBuffer<bufsz>::append(const char* format, ...) {
105 // Given that the constructor does a vsnprintf we can assume that
106 // _buf is already initialized.
107 size_t len = strlen(_buf);
108 char* buf_end = _buf + len;
109
110 va_list argp;
111 va_start(argp, format);
112 jio_vsnprintf(buf_end, bufsz - len, format, argp);
113 va_end(argp);
114 }
115
116 // Used to format messages.
117 typedef FormatBuffer<> err_msg;
118
119 #endif // SHARE_VM_UTILITIES_FORMATBUFFER_HPP
|
1 /*
2 * Copyright (c) 2017, 2018, 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 *
46 };
47
48 class FormatBufferDummy {};
49
50 // Use stack for buffer
51 template <size_t bufsz = FormatBufferBase::BufferSize>
52 class FormatBuffer : public FormatBufferBase {
53 public:
54 inline FormatBuffer(const char* format, ...) ATTRIBUTE_PRINTF(2, 3);
55 // since va_list is unspecified type (can be char*), we use FormatBufferDummy to disambiguate these constructors
56 inline FormatBuffer(FormatBufferDummy dummy, const char* format, va_list ap) ATTRIBUTE_PRINTF(3, 0);
57 inline void append(const char* format, ...) ATTRIBUTE_PRINTF(2, 3);
58 inline void print(const char* format, ...) ATTRIBUTE_PRINTF(2, 3);
59 inline void printv(const char* format, va_list ap) ATTRIBUTE_PRINTF(2, 0);
60
61 char* buffer() { return _buf; }
62 int size() { return bufsz; }
63
64 private:
65 FormatBuffer(const FormatBuffer &); // prevent copies
66
67 protected:
68 char _buffer[bufsz];
69 inline FormatBuffer();
70 inline void appendv(const char* format, va_list ap) ATTRIBUTE_PRINTF(2, 0);
71 };
72
73 // Use malloc'ed buffer if static buffer is not enough.
74 template <size_t bufsz = FormatBufferBase::BufferSize>
75 class FormatBufferEx : public FormatBuffer<bufsz> {
76 public:
77 inline FormatBufferEx();
78 ~FormatBufferEx(){
79 if (_dyn_buffer != NULL) {
80 ::free(_dyn_buffer);
81 }
82 }
83 inline void append(const char* format, ...) ATTRIBUTE_PRINTF(2, 3);
84 inline void print(const char* format, ...) ATTRIBUTE_PRINTF(2, 3);
85 inline void printv(const char* format, va_list argp) ATTRIBUTE_PRINTF(2, 0);
86
87 int size() { return _buffer_size; }
88
89 private:
90 inline void prepare_buffer(bool is_append, const char* format, va_list argp);
91 char *_dyn_buffer;
92 size_t _buffer_size;
93 };
94
95 template <size_t bufsz>
96 FormatBuffer<bufsz>::FormatBuffer(const char * format, ...) : FormatBufferBase(_buffer) {
97 va_list argp;
98 va_start(argp, format);
99 jio_vsnprintf(_buf, bufsz, format, argp);
100 va_end(argp);
101 }
102
103 template <size_t bufsz>
104 FormatBuffer<bufsz>::FormatBuffer(FormatBufferDummy dummy, const char * format, va_list ap) : FormatBufferBase(_buffer) {
105 jio_vsnprintf(_buf, bufsz, format, ap);
106 }
107
108 template <size_t bufsz>
109 FormatBuffer<bufsz>::FormatBuffer() : FormatBufferBase(_buffer) {
110 _buf[0] = '\0';
111 }
112
113 template <size_t bufsz>
114 void FormatBuffer<bufsz>::print(const char * format, ...) {
115 va_list argp;
116 va_start(argp, format);
117 jio_vsnprintf(_buf, bufsz, format, argp);
118 va_end(argp);
119 }
120
121 template <size_t bufsz>
122 void FormatBuffer<bufsz>::printv(const char * format, va_list argp) {
123 jio_vsnprintf(_buf, bufsz, format, argp);
124 }
125
126 template <size_t bufsz>
127 void FormatBuffer<bufsz>::append(const char* format, ...) {
128 va_list argp;
129 va_start(argp, format);
130 appendv(format, argp);
131 va_end(argp);
132 }
133
134 template <size_t bufsz>
135 void FormatBuffer<bufsz>::appendv(const char* format, va_list argp) {
136 // Given that the constructor does a vsnprintf we can assume that
137 // _buf is already initialized.
138 size_t len = strlen(_buf);
139 char* buf_end = _buf + len;
140
141 jio_vsnprintf(buf_end, bufsz - len, format, argp);
142 }
143
144 template <size_t bufsz>
145 FormatBufferEx<bufsz>::FormatBufferEx() : FormatBuffer<bufsz>(), _dyn_buffer(NULL), _buffer_size(bufsz) {
146 // Do nothing.
147 }
148
149 template <size_t bufsz>
150 void FormatBufferEx<bufsz>::print(const char * format, ...) {
151 va_list argp;
152 va_start(argp, format);
153 printv(format, argp);
154 va_end(argp);
155 }
156
157 template <size_t bufsz>
158 void FormatBufferEx<bufsz>::prepare_buffer(bool is_append, const char * format, va_list argp) {
159 size_t len = jio_vsnprintf(NULL, 0, format, argp) + 1;
160 if (is_append) {
161 len += strlen(FormatBufferBase::_buf);
162 }
163 if (len > _buffer_size) {
164 _dyn_buffer = (_dyn_buffer == NULL) ? (char *)::malloc(len)
165 : (char *)::realloc(_dyn_buffer, len);
166 FormatBufferBase::_buf = _dyn_buffer;
167 _buffer_size = len;
168 }
169 }
170
171 template <size_t bufsz>
172 void FormatBufferEx<bufsz>::printv(const char * format, va_list argp) {
173 va_list argp_local;
174 va_copy(argp_local, argp);
175 prepare_buffer(false, format, argp_local);
176 va_end(argp_local);
177
178 jio_vsnprintf(FormatBufferBase::_buf, _buffer_size, format, argp);
179 }
180
181 template <size_t bufsz>
182 void FormatBufferEx<bufsz>::append(const char* format, ...) {
183 va_list argp, argp_prepare;
184 va_start(argp, format);
185 va_copy(argp_prepare, argp);
186 prepare_buffer(true, format, argp_prepare);
187 va_end(argp_prepare);
188
189 FormatBuffer<bufsz>::appendv(format, argp);
190 va_end(argp);
191 }
192
193 // Used to format messages.
194 typedef FormatBuffer<> err_msg;
195
196 #endif // SHARE_VM_UTILITIES_FORMATBUFFER_HPP
|