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