- tree.c parser.c encoding.c: spent a bit more time looking
  at the parsing speed and DOM handling. Added a few more
  speedups.
Daniel
diff --git a/ChangeLog b/ChangeLog
index 3473744..ac42d42 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+Mon Apr 30 13:44:48 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
+
+	* tree.c parser.c encoding.c: spent a bit more time looking
+	  at the parsing speed and DOM handling. Added a few more
+	  speedups.
+
 Sun Apr 29 21:53:47 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
 
 	* parser.c: small but effective parsing speed improvement
diff --git a/aclocal.m4 b/aclocal.m4
index 869e5fc..e372675 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -620,31 +620,35 @@
 ])
 
 # AC_LIBLTDL_CONVENIENCE[(dir)] - sets LIBLTDL to the link flags for
-# the libltdl convenience library, adds --enable-ltdl-convenience to
-# the configure arguments.  Note that LIBLTDL is not AC_SUBSTed, nor
-# is AC_CONFIG_SUBDIRS called.  If DIR is not provided, it is assumed
-# to be `${top_builddir}/libltdl'.  Make sure you start DIR with
-# '${top_builddir}/' (note the single quotes!) if your package is not
-# flat, and, if you're not using automake, define top_builddir as
-# appropriate in the Makefiles.
+# the libltdl convenience library and INCLTDL to the include flags for
+# the libltdl header and adds --enable-ltdl-convenience to the
+# configure arguments.  Note that LIBLTDL and INCLTDL are not
+# AC_SUBSTed, nor is AC_CONFIG_SUBDIRS called.  If DIR is not
+# provided, it is assumed to be `libltdl'.  LIBLTDL will be prefixed
+# with '${top_builddir}/' and INCLTDL will be prefixed with
+# '${top_srcdir}/' (note the single quotes!).  If your package is not
+# flat and you're not using automake, define top_builddir and
+# top_srcdir appropriately in the Makefiles.
 AC_DEFUN(AC_LIBLTDL_CONVENIENCE, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
   case "$enable_ltdl_convenience" in
   no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;;
   "") enable_ltdl_convenience=yes
       ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;;
   esac
-  LIBLTDL=ifelse($#,1,$1,['${top_builddir}/libltdl'])/libltdlc.la
-  INCLTDL=ifelse($#,1,-I$1,['-I${top_builddir}/libltdl'])
+  LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdlc.la
+  INCLTDL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl'])
 ])
 
 # AC_LIBLTDL_INSTALLABLE[(dir)] - sets LIBLTDL to the link flags for
-# the libltdl installable library, and adds --enable-ltdl-install to
-# the configure arguments.  Note that LIBLTDL is not AC_SUBSTed, nor
-# is AC_CONFIG_SUBDIRS called.  If DIR is not provided, it is assumed
-# to be `${top_builddir}/libltdl'.  Make sure you start DIR with
-# '${top_builddir}/' (note the single quotes!) if your package is not
-# flat, and, if you're not using automake, define top_builddir as
-# appropriate in the Makefiles.
+# the libltdl installable library and INCLTDL to the include flags for
+# the libltdl header and adds --enable-ltdl-install to the configure
+# arguments.  Note that LIBLTDL and INCLTDL are not AC_SUBSTed, nor is
+# AC_CONFIG_SUBDIRS called.  If DIR is not provided and an installed
+# libltdl is not found, it is assumed to be `libltdl'.  LIBLTDL will
+# be prefixed with '${top_builddir}/' and INCLTDL will be prefixed
+# with '${top_srcdir}/' (note the single quotes!).  If your package is
+# not flat and you're not using automake, define top_builddir and
+# top_srcdir appropriately in the Makefiles.
 # In the future, this macro may have to be called after AC_PROG_LIBTOOL.
 AC_DEFUN(AC_LIBLTDL_INSTALLABLE, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
   AC_CHECK_LIB(ltdl, main,
@@ -657,8 +661,8 @@
   ])
   if test x"$enable_ltdl_install" = x"yes"; then
     ac_configure_args="$ac_configure_args --enable-ltdl-install"
-    LIBLTDL=ifelse($#,1,$1,['${top_builddir}/libltdl'])/libltdl.la
-    INCLTDL=ifelse($#,1,-I$1,['-I${top_builddir}/libltdl'])
+    LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdl.la
+    INCLTDL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl'])
   else
     ac_configure_args="$ac_configure_args --enable-ltdl-install=no"
     LIBLTDL="-lltdl"
diff --git a/encoding.c b/encoding.c
index 3d59eb9..f03285d 100644
--- a/encoding.c
+++ b/encoding.c
@@ -384,24 +384,25 @@
     unsigned char* outend = out + *outlen;
     const unsigned char* inend;
     unsigned int c;
-    int bits;
 
     inend = in + (*inlen);
-    while ((in < inend) && (out - outstart + 5 < *outlen)) {
-	c= *in++;
+    while (in < inend) {
+	c = *in++;
 
-	/* assertion: c is a single UTF-4 value */
         if (out >= outend)
 	    break;
-        if      (c <    0x80) {  *out++=  c;                bits= -6; }
-        else                  {  *out++= ((c >>  6) & 0x1F) | 0xC0;  bits=  0; }
- 
-        for ( ; bits >= 0; bits-= 6) {
+
+        if (c < 0x80) {
+	    *out++ =  c;
+	    processed++;
+	    continue;
+	} else {
+	    *out++= ((c >>  6) & 0x1F) | 0xC0;
             if (out >= outend)
-	        break;
-            *out++= ((c >> bits) & 0x3F) | 0x80;
+		break;
+            *out++= (c & 0x3F) | 0x80;
+	    processed++;
         }
-	processed = (const unsigned char*) in;
     }
     *outlen = out - outstart;
     *inlen = processed - base;
diff --git a/parser.c b/parser.c
index 007b2e7..faa2853 100644
--- a/parser.c
+++ b/parser.c
@@ -287,30 +287,57 @@
 
 int
 xmlSkipBlankChars(xmlParserCtxtPtr ctxt) {
-    int cur, res = 0;
+    int res = 0;
 
+    if (ctxt->token != 0) {
+	if (!IS_BLANK(ctxt->token))
+	    return(0);
+	ctxt->token = 0;
+	res++;
+    }
     /*
      * It's Okay to use CUR/NEXT here since all the blanks are on
      * the ASCII range.
      */
-    do {
-	cur = CUR;
-	while (IS_BLANK(cur)) { /* CHECKED tstblanks.xml */
-	    NEXT;
-	    cur = CUR;
-	    res++;
-	}
-	while ((cur == 0) && (ctxt->inputNr > 1) &&
-	       (ctxt->instate != XML_PARSER_COMMENT)) {
-	    xmlPopInput(ctxt);
-	    cur = CUR;
-	}
+    if ((ctxt->inputNr == 1) && (ctxt->instate != XML_PARSER_DTD)) {
+	const xmlChar *cur;
 	/*
-	 * Need to handle support of entities branching here
+	 * if we are in the document content, go really fast
 	 */
-	if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt);
-	/* DEPR if (*ctxt->input->cur == '&') xmlParserHandleReference(ctxt); */
-    } while (IS_BLANK(cur)); /* CHECKED tstblanks.xml */
+	cur = ctxt->input->cur;
+	while (IS_BLANK(*cur)) {
+	    if (*cur == '\n') {
+		ctxt->input->line++; ctxt->input->col = 1;
+	    }
+	    cur++;
+	    res++;
+	    if (*cur == 0) {
+		ctxt->input->cur = cur;
+		xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
+		cur = ctxt->input->cur;
+	    }
+	}
+	ctxt->input->cur = cur;
+    } else {
+	int cur;
+	do {
+	    cur = CUR;
+	    while (IS_BLANK(cur)) { /* CHECKED tstblanks.xml */
+		NEXT;
+		cur = CUR;
+		res++;
+	    }
+	    while ((cur == 0) && (ctxt->inputNr > 1) &&
+		   (ctxt->instate != XML_PARSER_COMMENT)) {
+		xmlPopInput(ctxt);
+		cur = CUR;
+	    }
+	    /*
+	     * Need to handle support of entities branching here
+	     */
+	    if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt);
+	} while (IS_BLANK(cur)); /* CHECKED tstblanks.xml */
+    }
     return(res);
 }
 
diff --git a/tree.c b/tree.c
index f4f2288..d1dfc27 100644
--- a/tree.c
+++ b/tree.c
@@ -2335,7 +2335,28 @@
     }
     while (cur != NULL) {
         next = cur->next;
-        xmlFreeNode(cur);
+	/* unroll to speed up freeing the document */
+	if (cur->type != XML_DTD_NODE) {
+	    if ((cur->children != NULL) &&
+		(cur->type != XML_ENTITY_REF_NODE))
+		xmlFreeNodeList(cur->children);
+	    if (cur->properties != NULL)
+		xmlFreePropList(cur->properties);
+	    if (cur->type != XML_ENTITY_REF_NODE)
+#ifndef XML_USE_BUFFER_CONTENT
+		if (cur->content != NULL) xmlFree(cur->content);
+#else
+		if (cur->content != NULL) xmlBufferFree(cur->content);
+#endif
+	    if ((cur->name != NULL) &&
+		(cur->name != xmlStringText) &&
+		(cur->name != xmlStringTextNoenc) &&
+		(cur->name != xmlStringComment))
+		xmlFree((char *) cur->name);
+	    /* TODO : derecursivate this function */
+	    if (cur->nsDef != NULL) xmlFreeNsList(cur->nsDef);
+	    xmlFree(cur);
+	}
 	cur = next;
     }
 }
@@ -2356,16 +2377,14 @@
 #endif
 	return;
     }
+    /* use xmlFreeDtd for DTD nodes */
     if (cur->type == XML_DTD_NODE)
 	return;
-    cur->doc = NULL;
-    cur->parent = NULL;
-    cur->next = NULL;
-    cur->prev = NULL;
     if ((cur->children != NULL) &&
 	(cur->type != XML_ENTITY_REF_NODE))
 	xmlFreeNodeList(cur->children);
-    if (cur->properties != NULL) xmlFreePropList(cur->properties);
+    if (cur->properties != NULL)
+	xmlFreePropList(cur->properties);
     if (cur->type != XML_ENTITY_REF_NODE)
 #ifndef XML_USE_BUFFER_CONTENT
 	if (cur->content != NULL) xmlFree(cur->content);