Module: wine Branch: master Commit: c801c18ad29a1d0351be94cb0e388c6ee6cc5323 URL: http://source.winehq.org/git/wine.git/?a=commit;h=c801c18ad29a1d0351be94cb0e...
Author: Piotr Caban piotr.caban@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];