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 *
28 #include "jvm.h"
29 #include "utilities/globalDefinitions.hpp"
30 #include <stdarg.h>
31
32 // Simple class to format the ctor arguments into a fixed-sized buffer.
33 class FormatBufferBase {
34 protected:
35 char* _buf;
36 inline FormatBufferBase(char* buf) : _buf(buf) {}
37 public:
38 static const int BufferSize = 256;
39 operator const char *() const { return _buf; }
40 };
41
42 // Use resource area for buffer
43 class FormatBufferResource : public FormatBufferBase {
44 public:
45 FormatBufferResource(const char * format, ...) ATTRIBUTE_PRINTF(2, 3);
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>
|
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 *
28 #include "jvm.h"
29 #include "utilities/globalDefinitions.hpp"
30 #include <stdarg.h>
31
32 // Simple class to format the ctor arguments into a fixed-sized buffer.
33 class FormatBufferBase {
34 protected:
35 char* _buf;
36 inline FormatBufferBase(char* buf) : _buf(buf) {}
37 public:
38 static const int BufferSize = 256;
39 operator const char *() const { return _buf; }
40 };
41
42 // Use resource area for buffer
43 class FormatBufferResource : public FormatBufferBase {
44 public:
45 FormatBufferResource(const char * format, ...) ATTRIBUTE_PRINTF(2, 3);
46 };
47
48 // Use malloc() for buffer
49 class FormatBufferDynamic : public FormatBufferBase {
50 protected:
51 int bufsz;
52
53 public:
54 inline FormatBufferDynamic();
55 ~FormatBufferDynamic();
56 inline void append(const char* format, ...) ATTRIBUTE_PRINTF(2, 3);
57 inline void print(const char* format, ...) ATTRIBUTE_PRINTF(2, 3);
58 inline void printv(const char* format, va_list ap) ATTRIBUTE_PRINTF(2, 0);
59
60 char* buffer() { return _buf; }
61 int size() { return bufsz; }
62 };
63
64 class FormatBufferDummy {};
65
66 // Use stack for buffer
67 template <size_t bufsz = FormatBufferBase::BufferSize>
68 class FormatBuffer : public FormatBufferBase {
69 public:
70 inline FormatBuffer(const char* format, ...) ATTRIBUTE_PRINTF(2, 3);
71 // since va_list is unspecified type (can be char*), we use FormatBufferDummy to disambiguate these constructors
72 inline FormatBuffer(FormatBufferDummy dummy, const char* format, va_list ap) ATTRIBUTE_PRINTF(3, 0);
73 inline void append(const char* format, ...) ATTRIBUTE_PRINTF(2, 3);
74 inline void print(const char* format, ...) ATTRIBUTE_PRINTF(2, 3);
75 inline void printv(const char* format, va_list ap) ATTRIBUTE_PRINTF(2, 0);
76
77 char* buffer() { return _buf; }
78 int size() { return bufsz; }
79
80 private:
81 FormatBuffer(const FormatBuffer &); // prevent copies
82 char _buffer[bufsz];
83
84 protected:
85 inline FormatBuffer();
86 };
87
88 FormatBufferDynamic::FormatBufferDynamic() : FormatBufferBase(NULL), bufsz(-1) {
89 // do nothing
90 }
91
92 void FormatBufferDynamic::append(const char* format, ...) {
93 va_list argp;
94
95 va_start(argp, format);
96 int append_len = jio_vsnprintf(NULL, 0, format, argp) + 1;
97 va_end(argp);
98
99 char *append_str = (char *)os::malloc(append_len, mtInternal);
100 va_start(argp, format);
101 jio_vsnprintf(append_str, append_len, format, argp);
102 va_end(argp);
103
104 if (_buf == NULL) {
105 bufsz = append_len;
106 _buf = append_str;
107 } else {
108 bufsz += append_len - 1;
109 _buf = (char *)os::realloc(_buf, bufsz, mtInternal);
110 strcat(_buf, append_str);
111 os::free(append_str);
112 }
113 }
114
115 void FormatBufferDynamic::print(const char * format, ...) {
116 va_list argp;
117 va_start(argp, format);
118 printv(format, argp);
119 va_end(argp);
120 }
121
122 void FormatBufferDynamic::printv(const char * format, va_list argp) {
123 if (_buf != NULL) {
124 os::free(_buf);
125 bufsz = -1;
126 }
127
128 va_list argp_local;
129 va_copy(argp_local, argp);
130 bufsz = jio_vsnprintf(NULL, 0, format, argp_local) + 1;
131 va_end(argp_local);
132
133 _buf = (char *)os::malloc(bufsz, mtInternal);
134 jio_vsnprintf(_buf, bufsz, format, argp);
135 }
136
137 template <size_t bufsz>
138 FormatBuffer<bufsz>::FormatBuffer(const char * format, ...) : FormatBufferBase(_buffer) {
139 va_list argp;
140 va_start(argp, format);
141 jio_vsnprintf(_buf, bufsz, format, argp);
142 va_end(argp);
143 }
144
145 template <size_t bufsz>
146 FormatBuffer<bufsz>::FormatBuffer(FormatBufferDummy dummy, const char * format, va_list ap) : FormatBufferBase(_buffer) {
147 jio_vsnprintf(_buf, bufsz, format, ap);
148 }
149
150 template <size_t bufsz>
151 FormatBuffer<bufsz>::FormatBuffer() : FormatBufferBase(_buffer) {
152 _buf[0] = '\0';
153 }
154
155 template <size_t bufsz>
|