version 1.1.1.1, 2012/02/21 23:37:57
|
version 1.1.1.2, 2013/07/22 01:22:19
|
Line 682 try_complex:
|
Line 682 try_complex:
|
void |
void |
xmlSetBufferAllocationScheme(xmlBufferAllocationScheme scheme) { |
xmlSetBufferAllocationScheme(xmlBufferAllocationScheme scheme) { |
if ((scheme == XML_BUFFER_ALLOC_EXACT) || |
if ((scheme == XML_BUFFER_ALLOC_EXACT) || |
(scheme == XML_BUFFER_ALLOC_DOUBLEIT)) | (scheme == XML_BUFFER_ALLOC_DOUBLEIT) || |
| (scheme == XML_BUFFER_ALLOC_HYBRID)) |
xmlBufferAllocScheme = scheme; |
xmlBufferAllocScheme = scheme; |
} |
} |
|
|
Line 693 xmlSetBufferAllocationScheme(xmlBufferAllocationScheme
|
Line 694 xmlSetBufferAllocationScheme(xmlBufferAllocationScheme
|
* XML_BUFFER_ALLOC_EXACT - use exact sizes, keeps memory usage down |
* XML_BUFFER_ALLOC_EXACT - use exact sizes, keeps memory usage down |
* XML_BUFFER_ALLOC_DOUBLEIT - double buffer when extra needed, |
* XML_BUFFER_ALLOC_DOUBLEIT - double buffer when extra needed, |
* improves performance |
* improves performance |
|
* XML_BUFFER_ALLOC_HYBRID - use exact sizes on small strings to keep memory usage tight |
|
* in normal usage, and doubleit on large strings to avoid |
|
* pathological performance. |
* |
* |
* Returns the current allocation scheme |
* Returns the current allocation scheme |
*/ |
*/ |
Line 1261 xmlStringLenGetNodeList(xmlDocPtr doc, const xmlChar *
|
Line 1265 xmlStringLenGetNodeList(xmlDocPtr doc, const xmlChar *
|
const xmlChar *cur = value, *end = cur + len; |
const xmlChar *cur = value, *end = cur + len; |
const xmlChar *q; |
const xmlChar *q; |
xmlEntityPtr ent; |
xmlEntityPtr ent; |
|
xmlBufferPtr buffer; |
|
|
if (value == NULL) return(NULL); |
if (value == NULL) return(NULL); |
|
|
|
buffer = xmlBufferCreateSize(0); |
|
if (buffer == NULL) return(NULL); |
|
xmlBufferSetAllocationScheme(buffer, XML_BUFFER_ALLOC_HYBRID); |
|
|
q = cur; |
q = cur; |
while ((cur < end) && (*cur != 0)) { |
while ((cur < end) && (*cur != 0)) { |
if (cur[0] == '&') { |
if (cur[0] == '&') { |
Line 1274 xmlStringLenGetNodeList(xmlDocPtr doc, const xmlChar *
|
Line 1283 xmlStringLenGetNodeList(xmlDocPtr doc, const xmlChar *
|
* Save the current text. |
* Save the current text. |
*/ |
*/ |
if (cur != q) { |
if (cur != q) { |
if ((last != NULL) && (last->type == XML_TEXT_NODE)) { | if (xmlBufferAdd(buffer, q, cur - q)) |
xmlNodeAddContentLen(last, q, cur - q); | goto out; |
} else { | |
node = xmlNewDocTextLen(doc, q, cur - q); | |
if (node == NULL) return(ret); | |
if (last == NULL) | |
last = ret = node; | |
else { | |
last->next = node; | |
node->prev = last; | |
last = node; | |
} | |
} | |
} |
} |
q = cur; |
q = cur; |
if ((cur + 2 < end) && (cur[1] == '#') && (cur[2] == 'x')) { |
if ((cur + 2 < end) && (cur[1] == '#') && (cur[2] == 'x')) { |
Line 1351 xmlStringLenGetNodeList(xmlDocPtr doc, const xmlChar *
|
Line 1349 xmlStringLenGetNodeList(xmlDocPtr doc, const xmlChar *
|
if ((cur >= end) || (*cur == 0)) { |
if ((cur >= end) || (*cur == 0)) { |
xmlTreeErr(XML_TREE_UNTERMINATED_ENTITY, (xmlNodePtr) doc, |
xmlTreeErr(XML_TREE_UNTERMINATED_ENTITY, (xmlNodePtr) doc, |
(const char *) q); |
(const char *) q); |
return(ret); | goto out; |
} |
} |
if (cur != q) { |
if (cur != q) { |
/* |
/* |
Line 1361 xmlStringLenGetNodeList(xmlDocPtr doc, const xmlChar *
|
Line 1359 xmlStringLenGetNodeList(xmlDocPtr doc, const xmlChar *
|
ent = xmlGetDocEntity(doc, val); |
ent = xmlGetDocEntity(doc, val); |
if ((ent != NULL) && |
if ((ent != NULL) && |
(ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) { |
(ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) { |
if (last == NULL) { |
|
node = xmlNewDocText(doc, ent->content); |
|
last = ret = node; |
|
} else if (last->type != XML_TEXT_NODE) { |
|
node = xmlNewDocText(doc, ent->content); |
|
last = xmlAddNextSibling(last, node); |
|
} else |
|
xmlNodeAddContent(last, ent->content); |
|
|
|
|
if (xmlBufferCat(buffer, ent->content)) |
|
goto out; |
|
|
} else { |
} else { |
/* |
/* |
|
* Flush buffer so far |
|
*/ |
|
if (buffer->use) { |
|
node = xmlNewDocText(doc, NULL); |
|
if (node == NULL) { |
|
if (val != NULL) xmlFree(val); |
|
goto out; |
|
} |
|
node->content = xmlBufferDetach(buffer); |
|
|
|
if (last == NULL) { |
|
last = ret = node; |
|
} else { |
|
last = xmlAddNextSibling(last, node); |
|
} |
|
} |
|
|
|
/* |
* Create a new REFERENCE_REF node |
* Create a new REFERENCE_REF node |
*/ |
*/ |
node = xmlNewReference(doc, val); |
node = xmlNewReference(doc, val); |
if (node == NULL) { |
if (node == NULL) { |
if (val != NULL) xmlFree(val); |
if (val != NULL) xmlFree(val); |
return(ret); | goto out; |
} |
} |
else if ((ent != NULL) && (ent->children == NULL)) { |
else if ((ent != NULL) && (ent->children == NULL)) { |
xmlNodePtr temp; |
xmlNodePtr temp; |
Line 1409 xmlStringLenGetNodeList(xmlDocPtr doc, const xmlChar *
|
Line 1420 xmlStringLenGetNodeList(xmlDocPtr doc, const xmlChar *
|
|
|
l = xmlCopyCharMultiByte(buf, charval); |
l = xmlCopyCharMultiByte(buf, charval); |
buf[l] = 0; |
buf[l] = 0; |
node = xmlNewDocText(doc, buf); | |
if (node != NULL) { | if (xmlBufferCat(buffer, buf)) |
if (last == NULL) { | goto out; |
last = ret = node; | |
} else { | |
last = xmlAddNextSibling(last, node); | |
} | |
} | |
charval = 0; |
charval = 0; |
} |
} |
} else |
} else |
cur++; |
cur++; |
} |
} |
if ((cur != q) || (ret == NULL)) { | |
| if (cur != q) { |
/* |
/* |
* Handle the last piece of text. |
* Handle the last piece of text. |
*/ |
*/ |
if ((last != NULL) && (last->type == XML_TEXT_NODE)) { | if (xmlBufferAdd(buffer, q, cur - q)) |
xmlNodeAddContentLen(last, q, cur - q); | goto out; |
| } |
| |
| if (buffer->use) { |
| node = xmlNewDocText(doc, NULL); |
| if (node == NULL) goto out; |
| node->content = xmlBufferDetach(buffer); |
| |
| if (last == NULL) { |
| last = ret = node; |
} else { |
} else { |
node = xmlNewDocTextLen(doc, q, cur - q); | last = xmlAddNextSibling(last, node); |
if (node == NULL) return(ret); | |
if (last == NULL) { | |
ret = node; | |
} else { | |
xmlAddNextSibling(last, node); | |
} | |
} |
} |
|
} else if (ret == NULL) { |
|
ret = xmlNewDocText(doc, BAD_CAST ""); |
} |
} |
|
|
|
out: |
|
xmlBufferFree(buffer); |
return(ret); |
return(ret); |
} |
} |
|
|
Line 1458 xmlStringGetNodeList(xmlDocPtr doc, const xmlChar *val
|
Line 1473 xmlStringGetNodeList(xmlDocPtr doc, const xmlChar *val
|
const xmlChar *cur = value; |
const xmlChar *cur = value; |
const xmlChar *q; |
const xmlChar *q; |
xmlEntityPtr ent; |
xmlEntityPtr ent; |
|
xmlBufferPtr buffer; |
|
|
if (value == NULL) return(NULL); |
if (value == NULL) return(NULL); |
|
|
|
buffer = xmlBufferCreateSize(0); |
|
if (buffer == NULL) return(NULL); |
|
xmlBufferSetAllocationScheme(buffer, XML_BUFFER_ALLOC_HYBRID); |
|
|
q = cur; |
q = cur; |
while (*cur != 0) { |
while (*cur != 0) { |
if (cur[0] == '&') { |
if (cur[0] == '&') { |
Line 1471 xmlStringGetNodeList(xmlDocPtr doc, const xmlChar *val
|
Line 1491 xmlStringGetNodeList(xmlDocPtr doc, const xmlChar *val
|
* Save the current text. |
* Save the current text. |
*/ |
*/ |
if (cur != q) { |
if (cur != q) { |
if ((last != NULL) && (last->type == XML_TEXT_NODE)) { | if (xmlBufferAdd(buffer, q, cur - q)) |
xmlNodeAddContentLen(last, q, cur - q); | goto out; |
} else { | |
node = xmlNewDocTextLen(doc, q, cur - q); | |
if (node == NULL) return(ret); | |
if (last == NULL) | |
last = ret = node; | |
else { | |
last->next = node; | |
node->prev = last; | |
last = node; | |
} | |
} | |
} |
} |
q = cur; |
q = cur; |
if ((cur[1] == '#') && (cur[2] == 'x')) { |
if ((cur[1] == '#') && (cur[2] == 'x')) { |
Line 1536 xmlStringGetNodeList(xmlDocPtr doc, const xmlChar *val
|
Line 1545 xmlStringGetNodeList(xmlDocPtr doc, const xmlChar *val
|
if (*cur == 0) { |
if (*cur == 0) { |
xmlTreeErr(XML_TREE_UNTERMINATED_ENTITY, |
xmlTreeErr(XML_TREE_UNTERMINATED_ENTITY, |
(xmlNodePtr) doc, (const char *) q); |
(xmlNodePtr) doc, (const char *) q); |
return(ret); | goto out; |
} |
} |
if (cur != q) { |
if (cur != q) { |
/* |
/* |
Line 1546 xmlStringGetNodeList(xmlDocPtr doc, const xmlChar *val
|
Line 1555 xmlStringGetNodeList(xmlDocPtr doc, const xmlChar *val
|
ent = xmlGetDocEntity(doc, val); |
ent = xmlGetDocEntity(doc, val); |
if ((ent != NULL) && |
if ((ent != NULL) && |
(ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) { |
(ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) { |
if (last == NULL) { |
|
node = xmlNewDocText(doc, ent->content); |
|
last = ret = node; |
|
} else if (last->type != XML_TEXT_NODE) { |
|
node = xmlNewDocText(doc, ent->content); |
|
last = xmlAddNextSibling(last, node); |
|
} else |
|
xmlNodeAddContent(last, ent->content); |
|
|
|
|
if (xmlBufferCat(buffer, ent->content)) |
|
goto out; |
|
|
} else { |
} else { |
/* |
/* |
|
* Flush buffer so far |
|
*/ |
|
if (buffer->use) { |
|
node = xmlNewDocText(doc, NULL); |
|
node->content = xmlBufferDetach(buffer); |
|
|
|
if (last == NULL) { |
|
last = ret = node; |
|
} else { |
|
last = xmlAddNextSibling(last, node); |
|
} |
|
} |
|
|
|
/* |
* Create a new REFERENCE_REF node |
* Create a new REFERENCE_REF node |
*/ |
*/ |
node = xmlNewReference(doc, val); |
node = xmlNewReference(doc, val); |
if (node == NULL) { |
if (node == NULL) { |
if (val != NULL) xmlFree(val); |
if (val != NULL) xmlFree(val); |
return(ret); | goto out; |
} |
} |
else if ((ent != NULL) && (ent->children == NULL)) { |
else if ((ent != NULL) && (ent->children == NULL)) { |
xmlNodePtr temp; |
xmlNodePtr temp; |
Line 1593 xmlStringGetNodeList(xmlDocPtr doc, const xmlChar *val
|
Line 1611 xmlStringGetNodeList(xmlDocPtr doc, const xmlChar *val
|
|
|
len = xmlCopyCharMultiByte(buf, charval); |
len = xmlCopyCharMultiByte(buf, charval); |
buf[len] = 0; |
buf[len] = 0; |
node = xmlNewDocText(doc, buf); | |
if (node != NULL) { | if (xmlBufferCat(buffer, buf)) |
if (last == NULL) { | goto out; |
last = ret = node; | charval = 0; |
} else { | |
last = xmlAddNextSibling(last, node); | |
} | |
} | |
} |
} |
} else |
} else |
cur++; |
cur++; |
Line 1609 xmlStringGetNodeList(xmlDocPtr doc, const xmlChar *val
|
Line 1623 xmlStringGetNodeList(xmlDocPtr doc, const xmlChar *val
|
/* |
/* |
* Handle the last piece of text. |
* Handle the last piece of text. |
*/ |
*/ |
if ((last != NULL) && (last->type == XML_TEXT_NODE)) { | xmlBufferAdd(buffer, q, cur - q); |
xmlNodeAddContentLen(last, q, cur - q); | } |
| |
| if (buffer->use) { |
| node = xmlNewDocText(doc, NULL); |
| node->content = xmlBufferDetach(buffer); |
| |
| if (last == NULL) { |
| last = ret = node; |
} else { |
} else { |
node = xmlNewDocTextLen(doc, q, cur - q); | last = xmlAddNextSibling(last, node); |
if (node == NULL) return(ret); | |
if (last == NULL) { | |
last = ret = node; | |
} else { | |
last = xmlAddNextSibling(last, node); | |
} | |
} |
} |
} |
} |
|
|
|
out: |
|
xmlBufferFree(buffer); |
return(ret); |
return(ret); |
} |
} |
|
|
Line 3732 xmlFreeNode(xmlNodePtr cur) {
|
Line 3750 xmlFreeNode(xmlNodePtr cur) {
|
* @cur: the node |
* @cur: the node |
* |
* |
* Unlink a node from it's current context, the node is not freed |
* Unlink a node from it's current context, the node is not freed |
|
* If one need to free the node, use xmlFreeNode() routine after the |
|
* unlink to discard it. |
*/ |
*/ |
void |
void |
xmlUnlinkNode(xmlNodePtr cur) { |
xmlUnlinkNode(xmlNodePtr cur) { |
Line 6914 xmlBufferCreateSize(size_t size) {
|
Line 6934 xmlBufferCreateSize(size_t size) {
|
} |
} |
|
|
/** |
/** |
|
* xmlBufferDetach: |
|
* @buf: the buffer |
|
* |
|
* Remove the string contained in a buffer and gie it back to the |
|
* caller. The buffer is reset to an empty content. |
|
* This doesn't work with immutable buffers as they can't be reset. |
|
* |
|
* Returns the previous string contained by the buffer. |
|
*/ |
|
xmlChar * |
|
xmlBufferDetach(xmlBufferPtr buf) { |
|
xmlChar *ret; |
|
|
|
if (buf == NULL) |
|
return(NULL); |
|
if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) |
|
return(NULL); |
|
|
|
ret = buf->content; |
|
buf->content = NULL; |
|
buf->size = 0; |
|
buf->use = 0; |
|
|
|
return ret; |
|
} |
|
|
|
|
|
/** |
* xmlBufferCreateStatic: |
* xmlBufferCreateStatic: |
* @mem: the memory area |
* @mem: the memory area |
* @size: the size in byte |
* @size: the size in byte |
Line 6964 xmlBufferSetAllocationScheme(xmlBufferPtr buf,
|
Line 7012 xmlBufferSetAllocationScheme(xmlBufferPtr buf,
|
(buf->alloc == XML_BUFFER_ALLOC_IO)) return; |
(buf->alloc == XML_BUFFER_ALLOC_IO)) return; |
if ((scheme == XML_BUFFER_ALLOC_DOUBLEIT) || |
if ((scheme == XML_BUFFER_ALLOC_DOUBLEIT) || |
(scheme == XML_BUFFER_ALLOC_EXACT) || |
(scheme == XML_BUFFER_ALLOC_EXACT) || |
|
(scheme == XML_BUFFER_ALLOC_HYBRID) || |
(scheme == XML_BUFFER_ALLOC_IMMUTABLE)) |
(scheme == XML_BUFFER_ALLOC_IMMUTABLE)) |
buf->alloc = scheme; |
buf->alloc = scheme; |
} |
} |
Line 7231 xmlBufferResize(xmlBufferPtr buf, unsigned int size)
|
Line 7280 xmlBufferResize(xmlBufferPtr buf, unsigned int size)
|
case XML_BUFFER_ALLOC_EXACT: |
case XML_BUFFER_ALLOC_EXACT: |
newSize = size+10; |
newSize = size+10; |
break; |
break; |
|
case XML_BUFFER_ALLOC_HYBRID: |
|
if (buf->use < BASE_BUFFER_SIZE) |
|
newSize = size; |
|
else { |
|
newSize = buf->size * 2; |
|
while (size > newSize) { |
|
if (newSize > UINT_MAX / 2) { |
|
xmlTreeErrMemory("growing buffer"); |
|
return 0; |
|
} |
|
newSize *= 2; |
|
} |
|
} |
|
break; |
|
|
default: |
default: |
newSize = size+10; |
newSize = size+10; |
break; |
break; |