82 // Return a pointer to the formatted string.
83 const char* outputStream::do_vsnprintf(char* buffer, size_t buflen,
84 const char* format, va_list ap,
85 bool add_cr,
86 size_t& result_len) {
87 assert(buflen >= 2, "buffer too small");
88
89 const char* result;
90 if (add_cr) buflen--;
91 if (!strchr(format, '%')) {
92 // constant format string
93 result = format;
94 result_len = strlen(result);
95 if (add_cr && result_len >= buflen) result_len = buflen-1; // truncate
96 } else if (format[0] == '%' && format[1] == 's' && format[2] == '\0') {
97 // trivial copy-through format string
98 result = va_arg(ap, const char*);
99 result_len = strlen(result);
100 if (add_cr && result_len >= buflen) result_len = buflen-1; // truncate
101 } else {
102 int written = os::vsnprintf(buffer, buflen, format, ap);
103 assert(written >= 0, "vsnprintf encoding error");
104 result = buffer;
105 if ((size_t)written < buflen) {
106 result_len = written;
107 } else {
108 DEBUG_ONLY(warning("increase O_BUFLEN in ostream.hpp -- output truncated");)
109 result_len = buflen - 1;
110 }
111 }
112 if (add_cr) {
113 if (result != buffer) {
114 memcpy(buffer, result, result_len);
115 result = buffer;
116 }
117 buffer[result_len++] = '\n';
118 buffer[result_len] = 0;
119 }
120 return result;
121 }
122
123 void outputStream::do_vsnprintf_and_write_with_automatic_buffer(const char* format, va_list ap, bool add_cr) {
124 char buffer[O_BUFLEN];
125 size_t len;
126 const char* str = do_vsnprintf(buffer, sizeof(buffer), format, ap, add_cr, len);
127 write(str, len);
128 }
|
82 // Return a pointer to the formatted string.
83 const char* outputStream::do_vsnprintf(char* buffer, size_t buflen,
84 const char* format, va_list ap,
85 bool add_cr,
86 size_t& result_len) {
87 assert(buflen >= 2, "buffer too small");
88
89 const char* result;
90 if (add_cr) buflen--;
91 if (!strchr(format, '%')) {
92 // constant format string
93 result = format;
94 result_len = strlen(result);
95 if (add_cr && result_len >= buflen) result_len = buflen-1; // truncate
96 } else if (format[0] == '%' && format[1] == 's' && format[2] == '\0') {
97 // trivial copy-through format string
98 result = va_arg(ap, const char*);
99 result_len = strlen(result);
100 if (add_cr && result_len >= buflen) result_len = buflen-1; // truncate
101 } else {
102 int required_len = os::vsnprintf(buffer, buflen, format, ap);
103 assert(required_len >= 0, "vsnprintf encoding error");
104 result = buffer;
105 if ((size_t)required_len < buflen) {
106 result_len = required_len;
107 } else {
108 DEBUG_ONLY(warning("outputStream::do_vsnprintf output truncated -- buffer length is %d bytes but %d bytes are needed.",
109 add_cr ? (int)buflen + 1 : (int)buflen, add_cr ? required_len + 2 : required_len + 1);)
110 result_len = buflen - 1;
111 }
112 }
113 if (add_cr) {
114 if (result != buffer) {
115 memcpy(buffer, result, result_len);
116 result = buffer;
117 }
118 buffer[result_len++] = '\n';
119 buffer[result_len] = 0;
120 }
121 return result;
122 }
123
124 void outputStream::do_vsnprintf_and_write_with_automatic_buffer(const char* format, va_list ap, bool add_cr) {
125 char buffer[O_BUFLEN];
126 size_t len;
127 const char* str = do_vsnprintf(buffer, sizeof(buffer), format, ap, add_cr, len);
128 write(str, len);
129 }
|