| 10595 | } |
| 10596 | |
| 10597 | xpath_string eval_string_concat(const xpath_context& c, const xpath_stack& stack) |
| 10598 | { |
| 10599 | assert(_type == ast_func_concat); |
| 10600 | |
| 10601 | xpath_allocator_capture ct(stack.temp); |
| 10602 | |
| 10603 | // count the string number |
| 10604 | size_t count = 1; |
| 10605 | for (xpath_ast_node* nc = _right; nc; nc = nc->_next) count++; |
| 10606 | |
| 10607 | // allocate a buffer for temporary string objects |
| 10608 | xpath_string* buffer = static_cast<xpath_string*>(stack.temp->allocate(count * sizeof(xpath_string))); |
| 10609 | if (!buffer) return xpath_string(); |
| 10610 | |
| 10611 | // evaluate all strings to temporary stack |
| 10612 | xpath_stack swapped_stack = {stack.temp, stack.result}; |
| 10613 | |
| 10614 | buffer[0] = _left->eval_string(c, swapped_stack); |
| 10615 | |
| 10616 | size_t pos = 1; |
| 10617 | for (xpath_ast_node* n = _right; n; n = n->_next, ++pos) buffer[pos] = n->eval_string(c, swapped_stack); |
| 10618 | assert(pos == count); |
| 10619 | |
| 10620 | // get total length |
| 10621 | size_t length = 0; |
| 10622 | for (size_t i = 0; i < count; ++i) length += buffer[i].length(); |
| 10623 | |
| 10624 | // create final string |
| 10625 | char_t* result = static_cast<char_t*>(stack.result->allocate((length + 1) * sizeof(char_t))); |
| 10626 | if (!result) return xpath_string(); |
| 10627 | |
| 10628 | char_t* ri = result; |
| 10629 | |
| 10630 | for (size_t j = 0; j < count; ++j) |
| 10631 | for (const char_t* bi = buffer[j].c_str(); *bi; ++bi) |
| 10632 | *ri++ = *bi; |
| 10633 | |
| 10634 | *ri = 0; |
| 10635 | |
| 10636 | return xpath_string::from_heap_preallocated(result, ri); |
| 10637 | } |
| 10638 | |
| 10639 | xpath_string eval_string(const xpath_context& c, const xpath_stack& stack) |
| 10640 | { |
nothing calls this directly
no test coverage detected