| 10802 | } |
| 10803 | |
| 10804 | xpath_string eval_string_concat(const xpath_context& c, const xpath_stack& stack) |
| 10805 | { |
| 10806 | assert(_type == ast_func_concat); |
| 10807 | |
| 10808 | xpath_allocator_capture ct(stack.temp); |
| 10809 | |
| 10810 | // count the string number |
| 10811 | size_t count = 1; |
| 10812 | for (xpath_ast_node* nc = _right; nc; nc = nc->_next) count++; |
| 10813 | |
| 10814 | // allocate a buffer for temporary string objects |
| 10815 | xpath_string* buffer = static_cast<xpath_string*>(stack.temp->allocate(count * sizeof(xpath_string))); |
| 10816 | if (!buffer) return xpath_string(); |
| 10817 | |
| 10818 | // evaluate all strings to temporary stack |
| 10819 | xpath_stack swapped_stack = {stack.temp, stack.result}; |
| 10820 | |
| 10821 | buffer[0] = _left->eval_string(c, swapped_stack); |
| 10822 | |
| 10823 | size_t pos = 1; |
| 10824 | for (xpath_ast_node* n = _right; n; n = n->_next, ++pos) buffer[pos] = n->eval_string(c, swapped_stack); |
| 10825 | assert(pos == count); |
| 10826 | |
| 10827 | // get total length |
| 10828 | size_t length = 0; |
| 10829 | for (size_t i = 0; i < count; ++i) length += buffer[i].length(); |
| 10830 | |
| 10831 | // create final string |
| 10832 | char_t* result = static_cast<char_t*>(stack.result->allocate((length + 1) * sizeof(char_t))); |
| 10833 | if (!result) return xpath_string(); |
| 10834 | |
| 10835 | char_t* ri = result; |
| 10836 | |
| 10837 | for (size_t j = 0; j < count; ++j) |
| 10838 | for (const char_t* bi = buffer[j].c_str(); *bi; ++bi) |
| 10839 | *ri++ = *bi; |
| 10840 | |
| 10841 | *ri = 0; |
| 10842 | |
| 10843 | return xpath_string::from_heap_preallocated(result, ri); |
| 10844 | } |
| 10845 | |
| 10846 | xpath_string eval_string(const xpath_context& c, const xpath_stack& stack) |
| 10847 | { |
nothing calls this directly
no test coverage detected