| 6629 | } |
| 6630 | |
| 6631 | void* reallocate(void* ptr, size_t old_size, size_t new_size) |
| 6632 | { |
| 6633 | // align size so that we're able to store pointers in subsequent blocks |
| 6634 | old_size = (old_size + sizeof(void*) - 1) & ~(sizeof(void*) - 1); |
| 6635 | new_size = (new_size + sizeof(void*) - 1) & ~(sizeof(void*) - 1); |
| 6636 | |
| 6637 | // we can only reallocate the last object |
| 6638 | assert(ptr == 0 || static_cast<char*>(ptr) + old_size == _root->data + _root_size); |
| 6639 | |
| 6640 | // adjust root size so that we have not allocated the object at all |
| 6641 | bool only_object = (_root_size == old_size); |
| 6642 | |
| 6643 | if (ptr) _root_size -= old_size; |
| 6644 | |
| 6645 | // allocate a new version (this will obviously reuse the memory if possible) |
| 6646 | void* result = allocate(new_size); |
| 6647 | assert(result); |
| 6648 | |
| 6649 | // we have a new block |
| 6650 | if (result != ptr && ptr) |
| 6651 | { |
| 6652 | // copy old data |
| 6653 | assert(new_size >= old_size); |
| 6654 | memcpy(result, ptr, old_size); |
| 6655 | |
| 6656 | // free the previous page if it had no other objects |
| 6657 | if (only_object) |
| 6658 | { |
| 6659 | assert(_root->data == result); |
| 6660 | assert(_root->next); |
| 6661 | |
| 6662 | xpath_memory_block* next = _root->next->next; |
| 6663 | |
| 6664 | if (next) |
| 6665 | { |
| 6666 | // deallocate the whole page, unless it was the first one |
| 6667 | xml_memory::deallocate(_root->next); |
| 6668 | _root->next = next; |
| 6669 | } |
| 6670 | } |
| 6671 | } |
| 6672 | |
| 6673 | return result; |
| 6674 | } |
| 6675 | |
| 6676 | void revert(const xpath_allocator& state) |
| 6677 | { |
no test coverage detected