92 result_len = strlen(result);
93 if (add_cr && result_len >= buflen) result_len = buflen-1; // truncate
94 } else {
95 // Handle truncation:
96 // posix: upon truncation, vsnprintf returns number of bytes which
97 // would have been written (excluding terminating zero) had the buffer
98 // been large enough
99 // windows: upon truncation, vsnprintf returns -1
100 const int written = vsnprintf(buffer, buflen, format, ap);
101 result = buffer;
102 if (written < (int) buflen && written >= 0) {
103 result_len = written;
104 } else {
105 DEBUG_ONLY(warning("increase O_BUFLEN in ostream.hpp -- output truncated");)
106 result_len = buflen - 1;
107 buffer[result_len] = 0;
108 }
109 }
110 if (add_cr) {
111 if (result != buffer) {
112 strncpy(buffer, result, buflen);
113 result = buffer;
114 }
115 buffer[result_len++] = '\n';
116 buffer[result_len] = 0;
117 }
118 return result;
119 }
120
121 void outputStream::print(const char* format, ...) {
122 char buffer[O_BUFLEN];
123 va_list ap;
124 va_start(ap, format);
125 size_t len;
126 const char* str = do_vsnprintf(buffer, O_BUFLEN, format, ap, false, len);
127 write(str, len);
128 va_end(ap);
129 }
130
131 void outputStream::print_cr(const char* format, ...) {
132 char buffer[O_BUFLEN];
317 }
318
319 void stringStream::write(const char* s, size_t len) {
320 size_t write_len = len; // number of non-null bytes to write
321 size_t end = buffer_pos + len + 1; // position after write and final '\0'
322 if (end > buffer_length) {
323 if (buffer_fixed) {
324 // if buffer cannot resize, silently truncate
325 end = buffer_length;
326 write_len = end - buffer_pos - 1; // leave room for the final '\0'
327 } else {
328 // For small overruns, double the buffer. For larger ones,
329 // increase to the requested size.
330 if (end < buffer_length * 2) {
331 end = buffer_length * 2;
332 }
333 char* oldbuf = buffer;
334 assert(rm == NULL || Thread::current()->current_resource_mark() == rm,
335 "stringStream is re-allocated with a different ResourceMark");
336 buffer = NEW_RESOURCE_ARRAY(char, end);
337 strncpy(buffer, oldbuf, buffer_pos);
338 buffer_length = end;
339 }
340 }
341 // invariant: buffer is always null-terminated
342 guarantee(buffer_pos + write_len + 1 <= buffer_length, "stringStream oob");
343 buffer[buffer_pos + write_len] = 0;
344 strncpy(buffer + buffer_pos, s, write_len);
345 buffer_pos += write_len;
346
347 // Note that the following does not depend on write_len.
348 // This means that position and count get updated
349 // even when overflow occurs.
350 update_position(s, len);
351 }
352
353 char* stringStream::as_string() {
354 char* copy = NEW_RESOURCE_ARRAY(char, buffer_pos + 1);
355 strncpy(copy, buffer, buffer_pos);
356 copy[buffer_pos] = 0; // terminating null
357 return copy;
358 }
359
360 stringStream::~stringStream() {}
361
362 xmlStream* xtty;
363 outputStream* tty;
364 outputStream* gclog_or_tty;
365 CDS_ONLY(fileStream* classlist_file;) // Only dump the classes that can be stored into the CDS archive
|
92 result_len = strlen(result);
93 if (add_cr && result_len >= buflen) result_len = buflen-1; // truncate
94 } else {
95 // Handle truncation:
96 // posix: upon truncation, vsnprintf returns number of bytes which
97 // would have been written (excluding terminating zero) had the buffer
98 // been large enough
99 // windows: upon truncation, vsnprintf returns -1
100 const int written = vsnprintf(buffer, buflen, format, ap);
101 result = buffer;
102 if (written < (int) buflen && written >= 0) {
103 result_len = written;
104 } else {
105 DEBUG_ONLY(warning("increase O_BUFLEN in ostream.hpp -- output truncated");)
106 result_len = buflen - 1;
107 buffer[result_len] = 0;
108 }
109 }
110 if (add_cr) {
111 if (result != buffer) {
112 memcpy(buffer, result, result_len);
113 result = buffer;
114 }
115 buffer[result_len++] = '\n';
116 buffer[result_len] = 0;
117 }
118 return result;
119 }
120
121 void outputStream::print(const char* format, ...) {
122 char buffer[O_BUFLEN];
123 va_list ap;
124 va_start(ap, format);
125 size_t len;
126 const char* str = do_vsnprintf(buffer, O_BUFLEN, format, ap, false, len);
127 write(str, len);
128 va_end(ap);
129 }
130
131 void outputStream::print_cr(const char* format, ...) {
132 char buffer[O_BUFLEN];
317 }
318
319 void stringStream::write(const char* s, size_t len) {
320 size_t write_len = len; // number of non-null bytes to write
321 size_t end = buffer_pos + len + 1; // position after write and final '\0'
322 if (end > buffer_length) {
323 if (buffer_fixed) {
324 // if buffer cannot resize, silently truncate
325 end = buffer_length;
326 write_len = end - buffer_pos - 1; // leave room for the final '\0'
327 } else {
328 // For small overruns, double the buffer. For larger ones,
329 // increase to the requested size.
330 if (end < buffer_length * 2) {
331 end = buffer_length * 2;
332 }
333 char* oldbuf = buffer;
334 assert(rm == NULL || Thread::current()->current_resource_mark() == rm,
335 "stringStream is re-allocated with a different ResourceMark");
336 buffer = NEW_RESOURCE_ARRAY(char, end);
337 if (buffer_pos > 0) {
338 memcpy(buffer, oldbuf, buffer_pos);
339 }
340 buffer_length = end;
341 }
342 }
343 // invariant: buffer is always null-terminated
344 guarantee(buffer_pos + write_len + 1 <= buffer_length, "stringStream oob");
345 if (write_len > 0) {
346 buffer[buffer_pos + write_len] = 0;
347 memcpy(buffer + buffer_pos, s, write_len);
348 buffer_pos += write_len;
349 }
350
351 // Note that the following does not depend on write_len.
352 // This means that position and count get updated
353 // even when overflow occurs.
354 update_position(s, len);
355 }
356
357 char* stringStream::as_string() {
358 char* copy = NEW_RESOURCE_ARRAY(char, buffer_pos + 1);
359 strncpy(copy, buffer, buffer_pos);
360 copy[buffer_pos] = 0; // terminating null
361 return copy;
362 }
363
364 stringStream::~stringStream() {}
365
366 xmlStream* xtty;
367 outputStream* tty;
368 outputStream* gclog_or_tty;
369 CDS_ONLY(fileStream* classlist_file;) // Only dump the classes that can be stored into the CDS archive
|