310 stringStream::stringStream(size_t initial_size) : outputStream() { |
310 stringStream::stringStream(size_t initial_size) : outputStream() { |
311 buffer_length = initial_size; |
311 buffer_length = initial_size; |
312 buffer = NEW_C_HEAP_ARRAY(char, buffer_length, mtInternal); |
312 buffer = NEW_C_HEAP_ARRAY(char, buffer_length, mtInternal); |
313 buffer_pos = 0; |
313 buffer_pos = 0; |
314 buffer_fixed = false; |
314 buffer_fixed = false; |
|
315 zero_terminate(); |
315 } |
316 } |
316 |
317 |
317 // useful for output to fixed chunks of memory, such as performance counters |
318 // useful for output to fixed chunks of memory, such as performance counters |
318 stringStream::stringStream(char* fixed_buffer, size_t fixed_buffer_size) : outputStream() { |
319 stringStream::stringStream(char* fixed_buffer, size_t fixed_buffer_size) : outputStream() { |
319 buffer_length = fixed_buffer_size; |
320 buffer_length = fixed_buffer_size; |
320 buffer = fixed_buffer; |
321 buffer = fixed_buffer; |
321 buffer_pos = 0; |
322 buffer_pos = 0; |
322 buffer_fixed = true; |
323 buffer_fixed = true; |
|
324 zero_terminate(); |
323 } |
325 } |
324 |
326 |
325 void stringStream::write(const char* s, size_t len) { |
327 void stringStream::write(const char* s, size_t len) { |
326 size_t write_len = len; // number of non-null bytes to write |
328 size_t write_len = len; // number of non-null bytes to write |
327 size_t end = buffer_pos + len + 1; // position after write and final '\0' |
329 size_t end = buffer_pos + len + 1; // position after write and final '\0' |
341 } |
343 } |
342 } |
344 } |
343 // invariant: buffer is always null-terminated |
345 // invariant: buffer is always null-terminated |
344 guarantee(buffer_pos + write_len + 1 <= buffer_length, "stringStream oob"); |
346 guarantee(buffer_pos + write_len + 1 <= buffer_length, "stringStream oob"); |
345 if (write_len > 0) { |
347 if (write_len > 0) { |
346 buffer[buffer_pos + write_len] = 0; |
|
347 memcpy(buffer + buffer_pos, s, write_len); |
348 memcpy(buffer + buffer_pos, s, write_len); |
348 buffer_pos += write_len; |
349 buffer_pos += write_len; |
|
350 zero_terminate(); |
349 } |
351 } |
350 |
352 |
351 // Note that the following does not depend on write_len. |
353 // Note that the following does not depend on write_len. |
352 // This means that position and count get updated |
354 // This means that position and count get updated |
353 // even when overflow occurs. |
355 // even when overflow occurs. |
354 update_position(s, len); |
356 update_position(s, len); |
355 } |
357 } |
356 |
358 |
357 char* stringStream::as_string() { |
359 void stringStream::zero_terminate() { |
|
360 assert(buffer != NULL && |
|
361 buffer_pos < buffer_length, "sanity"); |
|
362 buffer[buffer_pos] = '\0'; |
|
363 } |
|
364 |
|
365 void stringStream::reset() { |
|
366 buffer_pos = 0; _precount = 0; _position = 0; |
|
367 zero_terminate(); |
|
368 } |
|
369 |
|
370 char* stringStream::as_string() const { |
358 char* copy = NEW_RESOURCE_ARRAY(char, buffer_pos + 1); |
371 char* copy = NEW_RESOURCE_ARRAY(char, buffer_pos + 1); |
359 strncpy(copy, buffer, buffer_pos); |
372 strncpy(copy, buffer, buffer_pos); |
360 copy[buffer_pos] = 0; // terminating null |
373 copy[buffer_pos] = 0; // terminating null |
361 return copy; |
374 return copy; |
362 } |
375 } |