| 7662 | } |
| 7663 | |
| 7664 | void* reallocate(void* ptr, size_t old_size, size_t new_size) |
| 7665 | { |
| 7666 | // round size up to block alignment boundary |
| 7667 | old_size = (old_size + xpath_memory_block_alignment - 1) & ~(xpath_memory_block_alignment - 1); |
| 7668 | new_size = (new_size + xpath_memory_block_alignment - 1) & ~(xpath_memory_block_alignment - 1); |
| 7669 | |
| 7670 | // we can only reallocate the last object |
| 7671 | assert(ptr == 0 || static_cast<char*>(ptr) + old_size == &_root->data[0] + _root_size); |
| 7672 | |
| 7673 | // try to reallocate the object inplace |
| 7674 | if (ptr && _root_size - old_size + new_size <= _root->capacity) |
| 7675 | { |
| 7676 | _root_size = _root_size - old_size + new_size; |
| 7677 | return ptr; |
| 7678 | } |
| 7679 | |
| 7680 | // allocate a new block |
| 7681 | void* result = allocate(new_size); |
| 7682 | if (!result) return 0; |
| 7683 | |
| 7684 | // we have a new block |
| 7685 | if (ptr) |
| 7686 | { |
| 7687 | // copy old data (we only support growing) |
| 7688 | assert(new_size >= old_size); |
| 7689 | memcpy(result, ptr, old_size); |
| 7690 | |
| 7691 | // free the previous page if it had no other objects |
| 7692 | assert(_root->data == result); |
| 7693 | assert(_root->next); |
| 7694 | |
| 7695 | if (_root->next->data == ptr) |
| 7696 | { |
| 7697 | // deallocate the whole page, unless it was the first one |
| 7698 | xpath_memory_block* next = _root->next->next; |
| 7699 | |
| 7700 | if (next) |
| 7701 | { |
| 7702 | xml_memory::deallocate(_root->next); |
| 7703 | _root->next = next; |
| 7704 | } |
| 7705 | } |
| 7706 | } |
| 7707 | |
| 7708 | return result; |
| 7709 | } |
| 7710 | |
| 7711 | void revert(const xpath_allocator& state) |
| 7712 | { |
no test coverage detected