void membuf::resize(int new_size) { assert(!m_read_only); if (new_size == m_size) { return; } int new_capacity = capacity(new_size); if (m_data == NULL) { m_data = tu_malloc(new_capacity); } else { if (new_capacity != m_capacity) { m_data = tu_realloc(m_data, new_capacity, m_capacity); } } assert(m_data); m_capacity = new_capacity; assert(m_capacity >= new_size); m_size = new_size; }
void tu_string::resize(int new_size) { assert(new_size >= 0); if (new_size == size()) { return; } int old_size = size(); if (using_heap() == false) { if (new_size <= sizeof(m_union.m_local.m_buffer)) { // Stay with internal storage. m_union.m_local.m_bufsize_minus_length = (char) (sizeof(m_union.m_local.m_buffer) - new_size); m_union.m_local.m_buffer[new_size] = 0; // terminate } else { // need to allocate heap buffer. int capacity = new_size + 1; // round up. // TODO: test to see if this rounding-up is actually a performance win. capacity = (capacity + 15) & ~15; char* buf = (char*) tu_malloc(capacity); memset(buf, 0, capacity); // Copy existing data. memcpy(buf, m_union.m_local.m_buffer, old_size); // Set the heap state. m_union.m_local.m_bufsize_minus_length = char(~0); m_union.m_heap.m_buffer = buf; m_union.m_heap.m_size = new_size; m_union.m_heap.m_capacity = capacity; } } else { // Currently using heap storage. if (new_size <= sizeof(m_union.m_local.m_buffer)) { // Switch to local storage. // Be sure to get stack copies of m_heap info, before we overwrite it. char* old_buffer = m_union.m_heap.m_buffer; int old_capacity = m_union.m_heap.m_capacity; UNUSED(old_capacity); // Copy existing string info. m_union.m_local.m_bufsize_minus_length = (char) (sizeof(m_union.m_local.m_buffer) - new_size); assert(old_size >= new_size); memcpy(m_union.m_local.m_buffer, old_buffer, new_size); m_union.m_local.m_buffer[new_size] = 0; // ensure termination. tu_free(old_buffer, old_capacity); } else { // Changing size of heap buffer. int capacity = new_size + 1; // Round up. capacity = (capacity + 15) & ~15; if (capacity != m_union.m_heap.m_capacity) // @@ TODO should use hysteresis when resizing { m_union.m_heap.m_buffer = (char*) tu_realloc(m_union.m_heap.m_buffer, capacity, m_heap.m_capacity); m_union.m_heap.m_capacity = capacity; } // else we're OK with existing buffer. m_union.m_heap.m_size = new_size; // Ensure termination. m_union.m_heap.m_buffer[new_size] = 0; assert(m_union.m_local.m_bufsize_minus_length == (char) ~0); } } }
void tu_string::resize(int new_size) { assert(new_size >= 0); if (new_size == size()) { return; } if (using_heap() == false) { if (new_size < 15) { // Stay with internal storage. m_local.m_size = (char) (new_size + 1); m_local.m_buffer[new_size] = 0; // terminate } else { // need to allocate heap buffer. int capacity = new_size + 1; // round up. capacity = (capacity + 15) & ~15; char* buf = (char*) tu_malloc(capacity); memset(buf, 0, capacity); // Copy existing data. strcpy(buf, m_local.m_buffer); // Set the heap state. m_heap.m_buffer = buf; m_heap.m_all_ones = char(~0); m_heap.m_size = new_size + 1; m_heap.m_capacity = capacity; } } else { // Currently using heap storage. if (new_size < 15) { // Switch to local storage. // Be sure to get stack copies of m_heap info, before we overwrite it. char* old_buffer = m_heap.m_buffer; int old_capacity = m_heap.m_capacity; UNUSED(old_capacity); // Copy existing string info. m_local.m_size = (char) (new_size + 1); strncpy(m_local.m_buffer, old_buffer, 15); m_local.m_buffer[new_size] = 0; // ensure termination. tu_free(old_buffer, old_capacity); } else { // Changing size of heap buffer. int capacity = new_size + 1; // Round up. capacity = (capacity + 15) & ~15; if (capacity != m_heap.m_capacity) // @@ TODO should use hysteresis when resizing { m_heap.m_buffer = (char*) tu_realloc(m_heap.m_buffer, capacity, m_heap.m_capacity); m_heap.m_capacity = capacity; } // else we're OK with existing buffer. m_heap.m_size = new_size + 1; // Ensure termination. m_heap.m_buffer[new_size] = 0; } } }