another peroformance patch from Peter Jacobi, that time on parsing

* parser.c: another peroformance patch from Peter Jacobi, that
  time on parsing attribute values.
Daniel
diff --git a/ChangeLog b/ChangeLog
index f7c78b6..533c9ef 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Fri May 31 11:47:12 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: another peroformance patch from Peter Jacobi, that
+	  time on parsing attribute values.
+
 Thu May 30 23:34:27 2002  Aleksey Sanin  <aleksey@aleksey.com>
 
 	* Makefile.am result/c14n/* test/c14n/*: C14N tests integrated
diff --git a/encoding.c b/encoding.c
index 8e2397a..08dda58 100644
--- a/encoding.c
+++ b/encoding.c
@@ -560,39 +560,38 @@
               const unsigned char* in, int *inlen) {
     unsigned char* outstart = out;
     const unsigned char* base = in;
-    const unsigned char* processed = in;
     unsigned char* outend = out + *outlen;
     const unsigned char* inend;
-    unsigned int c;
+    const unsigned char* instop;
+    xmlChar c = *in;
 
     inend = in + (*inlen);
-    while (in < inend) {
-	c = *in++;
-
-        if (out >= outend)
-	    break;
-
-        if (c < 0x80) {
-	    *out++ =  c;
-	    processed++;
-	    continue;
-	} else {
-	    /*
-	     * make sure there is 2 chars left in advance
-	     */
-            if (out + 1 >= outend) {
-		break;
-	    }
+    instop = inend;
+    
+    while (in < inend && out < outend - 1) {
+    	if (c >= 0x80) {
 	    *out++= ((c >>  6) & 0x1F) | 0xC0;
             *out++= (c & 0x3F) | 0x80;
-	    processed++;
-        }
+	    ++in;
+	    c = *in;
+	}
+	if (instop - in > outend - out) instop = in + (outend - out); 
+	while (c < 0x80 && in < instop) {
+	    *out++ =  c;
+	    ++in;
+	    c = *in;
+	}
+    }	
+    if (in < inend && out < outend && c < 0x80) {
+        *out++ =  c;
+	++in;
     }
     *outlen = out - outstart;
-    *inlen = processed - base;
+    *inlen = in - base;
     return(0);
 }
 
+
 /**
  * UTF8Toisolat1:
  * @out:  a pointer to an array of bytes to store the result
diff --git a/parser.c b/parser.c
index a3f7786..4abdb9d 100644
--- a/parser.c
+++ b/parser.c
@@ -2226,9 +2226,47 @@
  */
 
 xmlChar *
+xmlParseAttValueComplex(xmlParserCtxtPtr ctxt);
+
+xmlChar *
 xmlParseAttValue(xmlParserCtxtPtr ctxt) {
     xmlChar limit = 0;
     xmlChar *buf = NULL;
+    xmlChar *in = NULL;
+    xmlChar *ret = NULL;
+    SHRINK;
+    GROW;
+    in = CUR_PTR;
+    if (*in != '"' && *in != '\'') {
+      ctxt->errNo = XML_ERR_ATTRIBUTE_NOT_STARTED;
+      if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
+          ctxt->sax->error(ctxt->userData, "AttValue: \" or ' expected\n");
+      ctxt->wellFormed = 0;
+      ctxt->disableSAX = 1;
+      return(NULL);
+    } 
+    ctxt->instate = XML_PARSER_ATTRIBUTE_VALUE;
+    limit = *in;
+    ++in;
+    
+    while (*in != limit && *in >= 0x20 && *in <= 0x7f && 
+      *in != '&' && *in != '<'
+    ) {
+      ++in;
+    }
+    if (*in != limit) {
+      return xmlParseAttValueComplex(ctxt);
+    }
+    ++in;
+    ret = xmlStrndup (CUR_PTR + 1, in - CUR_PTR - 2);
+    CUR_PTR = in;
+    return ret;
+}
+
+xmlChar *
+xmlParseAttValueComplex(xmlParserCtxtPtr ctxt) {
+    xmlChar limit = 0;
+    xmlChar *buf = NULL;
     int len = 0;
     int buf_size = 0;
     int c, l;