Piotr Caban : msxml: Rewrite ISAXContentHandler_characters.

Alexandre Julliard julliard at winehq.org
Wed Oct 8 08:33:10 CDT 2008


Module: wine
Branch: master
Commit: c801c18ad29a1d0351be94cb0e388c6ee6cc5323
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=c801c18ad29a1d0351be94cb0e388c6ee6cc5323

Author: Piotr Caban <piotr.caban at gmail.com>
Date:   Tue Oct  7 22:10:43 2008 +0200

msxml: Rewrite ISAXContentHandler_characters.

---

 dlls/msxml3/saxreader.c |  167 ++++++++++++++++++++++-------------------------
 1 files changed, 77 insertions(+), 90 deletions(-)

diff --git a/dlls/msxml3/saxreader.c b/dlls/msxml3/saxreader.c
index 62058d1..72c66b5 100644
--- a/dlls/msxml3/saxreader.c
+++ b/dlls/msxml3/saxreader.c
@@ -75,7 +75,9 @@ typedef struct _saxlocator
     WCHAR *systemId;
     xmlChar *lastCur;
     int line;
+    int realLine;
     int column;
+    int realColumn;
     BOOL vbInterface;
     int nsStackSize;
     int nsStackLast;
@@ -197,23 +199,6 @@ static BSTR QName_from_xmlChar(const xmlChar *prefix, const xmlChar *name)
     return bstr;
 }
 
-BSTR bstr_from_xmlChar_wn(const xmlChar *buf, int len)
-{
-    DWORD size;
-    LPWSTR str;
-    BSTR bstr;
-
-    if(!buf) return NULL;
-
-    size = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)buf, len, NULL, 0);
-    str = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, size*sizeof(WCHAR));
-    if(!str) return NULL;
-    MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)buf, len, str, size);
-    bstr = SysAllocStringLen(str, size);
-    HeapFree(GetProcessHeap(), 0, str);
-    return bstr;
-}
-
 static void format_error_message_from_id(saxlocator *This, HRESULT hr)
 {
     xmlStopParser(This->pParserCtxt);
@@ -247,14 +232,21 @@ static void update_position(saxlocator *This, xmlChar *end)
     if(This->lastCur == NULL)
     {
         This->lastCur = (xmlChar*)This->pParserCtxt->input->base;
-        This->line = 1;
-        This->column = 1;
+        This->realLine = 1;
+        This->realColumn = 1;
     }
     else if(This->lastCur < This->pParserCtxt->input->base)
     {
         This->lastCur = (xmlChar*)This->pParserCtxt->input->base;
-        This->line = 1;
-        This->column = 1;
+        This->realLine = 1;
+        This->realColumn = 1;
+    }
+
+    if(This->pParserCtxt->input->cur<This->lastCur)
+    {
+        This->lastCur = (xmlChar*)This->pParserCtxt->input->base;
+        This->realLine -= 1;
+        This->realColumn = 1;
     }
 
     if(!end) end = (xmlChar*)This->pParserCtxt->input->cur;
@@ -263,18 +255,26 @@ static void update_position(saxlocator *This, xmlChar *end)
     {
         if(*(This->lastCur) == '\n')
         {
-            This->line++;
-            This->column = 1;
+            This->realLine++;
+            This->realColumn = 1;
         }
-        else if(*(This->lastCur) == '\r' && (This->lastCur==This->pParserCtxt->input->end || *(This->lastCur+1)!='\n'))
+        else if(*(This->lastCur) == '\r' &&
+                (This->lastCur==This->pParserCtxt->input->end ||
+                 *(This->lastCur+1)!='\n'))
         {
-            This->line++;
-            This->column = 1;
+            This->realLine++;
+            This->realColumn = 1;
         }
-        else This->column++;
+        else This->realColumn++;
 
         This->lastCur++;
+
+        /* Count multibyte UTF8 encoded characters once */
+        while((*(This->lastCur)&0xC0) == 0x80) This->lastCur++;
     }
+
+    This->line = This->realLine;
+    This->column = This->realColumn;
 }
 
 /*** IVBSAXAttributes interface ***/
@@ -1115,9 +1115,11 @@ static void libxmlEndElementNS(
     xmlChar *end;
     int nsNr, index;
 
-    end = This->lastCur;
-    while(*end != '<' && *(end+1) != '/') end++;
-    update_position(This, end+2);
+    end = (xmlChar*)This->pParserCtxt->input->cur;
+    if(*(end-1) != '>' || *(end-2) != '/')
+        while(*(end-2)!='<' && *(end-1)!='/') end--;
+
+    update_position(This, end);
 
     nsNr = namespacePop(This);
 
@@ -1165,6 +1167,8 @@ static void libxmlEndElementNS(
             SysFreeString(Prefix);
         }
     }
+
+    update_position(This, NULL);
 }
 
 static void libxmlCharacters(
@@ -1172,82 +1176,65 @@ static void libxmlCharacters(
         const xmlChar *ch,
         int len)
 {
-    BSTR Chars;
     saxlocator *This = ctx;
+    BSTR Chars;
     HRESULT hr;
+    xmlChar *cur;
     xmlChar *end;
-    xmlChar *lastCurCopy;
-    xmlChar *chEnd;
-    int columnCopy;
-    int lineCopy;
-
-    if(*(This->lastCur-1) != '>' && *(This->lastCur-1) != '/') return;
+    BOOL lastEvent = FALSE;
 
-    if(*(This->lastCur-1) != '>')
-    {
-        end = (xmlChar*)This->pParserCtxt->input->cur-len;
-        while(*(end-1) != '>') end--;
-        update_position(This, end);
-    }
+    if((This->vbInterface && !This->saxreader->vbcontentHandler)
+            || (!This->vbInterface && !This->saxreader->contentHandler))
+        return;
 
-    chEnd = This->lastCur+len;
-    while(*chEnd != '<') chEnd++;
+    cur = (xmlChar*)ch;
+    if(*(ch-1)=='\r') cur--;
+    end = cur;
 
-    lastCurCopy = This->lastCur;
-    columnCopy = This->column;
-    lineCopy = This->line;
-    end = This->lastCur;
+    if(ch<This->pParserCtxt->input->base || ch>This->pParserCtxt->input->end)
+        This->column++;
 
-    if((This->vbInterface && This->saxreader->vbcontentHandler)
-            || (!This->vbInterface && This->saxreader->contentHandler))
+    while(1)
     {
-        while(This->lastCur < chEnd)
+        while(end-ch<len && *end!='\r') end++;
+        if(end-ch==len)
         {
-            end = This->lastCur;
-            while(end < chEnd-1)
-            {
-                if(*end == '\r') break;
-                end++;
-            }
-
-            Chars = bstr_from_xmlChar_wn(This->lastCur, end-This->lastCur+2);
+            end--;
+            lastEvent = TRUE;
+        }
 
-            if(*end == '\r' && *(end+1) == '\n')
-            {
-                memmove((WCHAR*)Chars+(end-This->lastCur),
-                        (WCHAR*)Chars+(end-This->lastCur)+1,
-                        (SysStringLen(Chars)-(end-This->lastCur))*sizeof(WCHAR));
-                SysReAllocStringLen(&Chars, Chars, SysStringLen(Chars)-1);
-            }
-            else if(*end == '\r') Chars[end-This->lastCur] = '\n';
+        if(!lastEvent) *end = '\n';
 
-            if(This->vbInterface)
-                hr = IVBSAXContentHandler_characters(
-                        This->saxreader->vbcontentHandler, &Chars);
-            else
-                hr = ISAXContentHandler_characters(
-                        This->saxreader->contentHandler,
-                        Chars, end-This->lastCur+1);
+        Chars = bstr_from_xmlCharN(cur, end-cur+1);
+        if(This->vbInterface)
+            hr = IVBSAXContentHandler_characters(
+                    This->saxreader->vbcontentHandler, &Chars);
+        else
+            hr = ISAXContentHandler_characters(
+                    This->saxreader->contentHandler,
+                    Chars, SysStringLen(Chars));
+        SysFreeString(Chars);
 
-            SysFreeString(Chars);
-            if(hr != S_OK)
-            {
-                format_error_message_from_id(This, hr);
-                return;
-            }
+        This->column += end-cur+1;
 
-            if(*(end+1) == '\n') end++;
-            if(end < chEnd) end++;
+        if(lastEvent)
+            break;
 
-            This->column += end-This->lastCur;
-            This->lastCur = end;
+        *end = '\r';
+        end++;
+        if(*end == '\n')
+        {
+            end++;
+            This->column++;
         }
+        cur = end;
 
-        This->lastCur = lastCurCopy;
-        This->column = columnCopy;
-        This->line = lineCopy;
-        update_position(This, chEnd);
+        if(end-ch == len) break;
     }
+
+    if(ch<This->pParserCtxt->input->base || ch>This->pParserCtxt->input->end)
+        This->column = This->realColumn
+            +This->pParserCtxt->input->cur-This->lastCur;
 }
 
 static void libxmlSetDocumentLocator(
@@ -1270,7 +1257,7 @@ static void libxmlSetDocumentLocator(
         format_error_message_from_id(This, hr);
 }
 
-void libxmlFatalError(void *ctx, const char *msg, ...)
+static void libxmlFatalError(void *ctx, const char *msg, ...)
 {
     saxlocator *This = ctx;
     char message[1024];




More information about the wine-cvs mailing list