|
|
| 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; |