| 416 | } |
| 417 | |
| 418 | char_t* allocate_string(size_t length) |
| 419 | { |
| 420 | // allocate memory for string and header block |
| 421 | size_t size = sizeof(xml_memory_string_header) + length * sizeof(char_t); |
| 422 | |
| 423 | // round size up to pointer alignment boundary |
| 424 | size_t full_size = (size + (sizeof(void*) - 1)) & ~(sizeof(void*) - 1); |
| 425 | |
| 426 | xml_memory_page* page; |
| 427 | xml_memory_string_header* header = static_cast<xml_memory_string_header*>(allocate_memory(full_size, page)); |
| 428 | |
| 429 | if (!header) |
| 430 | return 0; |
| 431 | |
| 432 | // setup header |
| 433 | ptrdiff_t page_offset = reinterpret_cast<char*>(header) - page->data; |
| 434 | |
| 435 | assert(page_offset >= 0 && page_offset < (1 << 16)); |
| 436 | header->page_offset = static_cast<uint16_t>(page_offset); |
| 437 | |
| 438 | // full_size == 0 for large strings that occupy the whole page |
| 439 | assert(full_size < (1 << 16) || (page->busy_size == full_size && page_offset == 0)); |
| 440 | header->full_size = static_cast<uint16_t>(full_size < (1 << 16) ? full_size : 0); |
| 441 | |
| 442 | // round-trip through void* to avoid 'cast increases required alignment of target type' warning |
| 443 | // header is guaranteed a pointer-sized alignment, which should be enough for char_t |
| 444 | return static_cast<char_t*>(static_cast<void*>(header + 1)); |
| 445 | } |
| 446 | |
| 447 | void deallocate_string(char_t* string) |
| 448 | { |