Dave - that's a great idea.
Thanks
Ben.
On 12 May 2009, at 20:11, David Bertoni wrote:
Ben Griffin wrote:
For the last few weeks, we have been using XMLString::catString()
for fast appends to textnodes; something like:
//Only reachable by nodes that support setNodeValue()
append(DOMNode*& pt,XMLCh*& addon) {
if (addon != NULL and *addon != 0 ) {
XMLCh* orig = XMLString::replicate(pt->getNodeValue());
XMLString::catString(orig, addon);
pt->setNodeValue(orig);
XMLString::release(&orig);
XMLString::release(&addon);
}
}
However, we began to notice occasional crashes, and worked out that
XMLString::catString does not check for memory overflow.
How could it check for memory overflow? It has no idea how much
memory was allocated, and XMLString::replicate() doesn't allocated
extra memory anyway. Here's the documentation of the function:
/** Concatenates two strings.
*
* catString appends src to target and
* terminates the resulting string with a null character. The
initial character of
* src overwrites the terminating character of target.
* No overflow checking is performed when strings are copied or
appended.
* The behavior of catString is undefined if source and destination
* strings overlap.
*
* @param target Null-terminated destination string
* @param src Null-terminated source string
*/
Is there a means of being able to guarantee additional memory for
catString, so that we do not have to transcode everything first?
There is no need to do any transcoding here, since all of the
strings are encoded in UTF-16.
You could use std::vector:
const XMLCh* const base = pt->getNodeValue();
const XMLSize_t baseLength = XMLString::strLength(base);
const XMLSize_t addonLength = XMLString::strLength(addon);
std::vector<XMLCh> buffer;
buffer.reserve(baseLength + addonLength + 1);
buffer.append(
buffer.end(),
base,
base + baseLength);
buffer.append(
buffer.end(),
addon,
addon + addonLength + 1);
pt->setNodeValue(&*buffer.begin());
XMLString::release(&addon);
Dave