From 71fda149812a8dc8caaf2c20126641a8f79a8f40 Mon Sep 17 00:00:00 2001 From: Laurence Withers Date: Fri, 29 Sep 2006 10:51:10 +0100 Subject: [PATCH] Update internal state before callback; that way, if during the callback we inject some more data into the parser (e.g. it's an tag or something), the parser is in the correct state. --- src/libCStreamedXML/parser.c | 30 +++++++++++++++--------------- src/libStreamedXML/Parser.cpp | 30 +++++++++++++++--------------- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/src/libCStreamedXML/parser.c b/src/libCStreamedXML/parser.c index 752c714..d0332eb 100644 --- a/src/libCStreamedXML/parser.c +++ b/src/libCStreamedXML/parser.c @@ -141,8 +141,8 @@ int csxml_feedChar(struct csxml* ctx, char ch) if(ch == xmlRestartMarker[ctx->restartCount]) { if(++ctx->restartCount == 11) { - csxml_reset(ctx); ctx->state = StateRestartMarker; + csxml_reset(ctx); return 0; } } else { @@ -179,8 +179,8 @@ int csxml_feedChar(struct csxml* ctx, char ch) break; case ClassOpenTag: - if(ctx->buffer.len) TRY(ctx->whiteSpace(ctx, ctx->buffer.data)); ctx->state = StateOpen; + if(ctx->buffer.len) TRY(ctx->whiteSpace(ctx, ctx->buffer.data)); CLEAR_BUFFER(buffer); break; @@ -197,8 +197,8 @@ int csxml_feedChar(struct csxml* ctx, char ch) // fall through default: if(!ctx->elementDepth) ERROR("Content cannot appear at stream level."); - if(ctx->buffer.len) TRY(ctx->whiteSpace(ctx, ctx->buffer.data)); ctx->state = StateData; + if(ctx->buffer.len) TRY(ctx->whiteSpace(ctx, ctx->buffer.data)); CLEAR_BUFFER(buffer); APPEND_CH(buffer, ch); break; @@ -208,9 +208,9 @@ int csxml_feedChar(struct csxml* ctx, char ch) case StateData: switch(c) { case ClassOpenTag: + ctx->state = StateOpen; TRY(ctx->content(ctx, ctx->buffer.data)); CLEAR_BUFFER(buffer); - ctx->state = StateOpen; break; case ClassEntity: @@ -240,9 +240,9 @@ int csxml_feedChar(struct csxml* ctx, char ch) case StateCDATA2: if(ch == '>') { + ctx->state = StateNone; TRY(ctx->cdata(ctx, ctx->buffer.data)); CLEAR_BUFFER(buffer); - ctx->state = StateNone; } else if(ch == ']') { APPEND_CH(buffer, ']'); } else { @@ -317,8 +317,8 @@ int csxml_feedChar(struct csxml* ctx, char ch) case StatePI2: if(ch != '>') ERROR("Invalid target for PI"); else { - TRY(ctx->PI(ctx, ctx->buffer2.data, 0)); ctx->state = StateNone; + TRY(ctx->PI(ctx, ctx->buffer2.data, 0)); } break; @@ -329,9 +329,9 @@ int csxml_feedChar(struct csxml* ctx, char ch) case StatePI3: if(ch == '>') { + ctx->state = StateNone; TRY(ctx->PI(ctx, ctx->buffer2.data, ctx->buffer.data)); CLEAR_BUFFER(buffer); - ctx->state = StateNone; } else if(ch == '?') { APPEND_CH(buffer, '?'); } else { @@ -378,9 +378,9 @@ int csxml_feedChar(struct csxml* ctx, char ch) case StateComment3: if(ch != '>') ERROR("`--' not valid in comments"); + ctx->state = StateNone; TRY(ctx->comment(ctx, ctx->buffer.data)); CLEAR_BUFFER(buffer); - ctx->state = StateNone; break; case StateElemName: @@ -399,8 +399,8 @@ int csxml_feedChar(struct csxml* ctx, char ch) switch(ch) { case L'>': TRY(list_push(ctx, &ctx->elemStack, &ctx->elemName)); - TRY(ctx->element(ctx, ctx->elemName.data, 0)); ctx->state = StateNone; + TRY(ctx->element(ctx, ctx->elemName.data, 0)); ++ctx->elementDepth; CLEAR_BUFFER(buffer); break; @@ -430,8 +430,8 @@ int csxml_feedChar(struct csxml* ctx, char ch) switch(ch) { case '>': TRY(list_push(ctx, &ctx->elemStack, &ctx->elemName)); - TRY(ctx->element(ctx, ctx->elemName.data, ctx->elemAttrNames.len)); ctx->state = StateNone; + TRY(ctx->element(ctx, ctx->elemName.data, ctx->elemAttrNames.len)); ++ctx->elementDepth; break; @@ -488,10 +488,10 @@ int csxml_feedChar(struct csxml* ctx, char ch) if(ch == '/') { ctx->state = StateNeedClose; } else if(ch == '>') { + ctx->state = StateNone; TRY(ctx->element(ctx, ctx->elemName.data, ctx->elemAttrVals.len)); TRY(list_push(ctx, &ctx->elemStack, &ctx->elemName)); CLEAR_BUFFER(buffer); - ctx->state = StateNone; ++ctx->elementDepth; } else ERROR("Invalid character after attribute."); break; @@ -500,10 +500,10 @@ int csxml_feedChar(struct csxml* ctx, char ch) case StateNeedClose: if(ch != '>') ERROR("Stray `/' in open tag."); + ctx->state = StateNone; TRY(ctx->element(ctx, ctx->elemName.data, ctx->elemAttrVals.len)); TRY(ctx->closeTag(ctx, ctx->elemName.data)); CLEAR_BUFFER(buffer); - ctx->state = StateNone; break; case StateClose: @@ -527,8 +527,8 @@ int csxml_feedChar(struct csxml* ctx, char ch) if(ch != '>') ERROR("Invalid character in close tag name."); TRY(buffer_copy(ctx, &ctx->elemName, list_pop(&ctx->elemStack))); if(strcmp(ctx->elemName.data, ctx->buffer.data)) ERROR("Mismatched close tag."); - TRY(ctx->closeTag(ctx, ctx->elemName.data)); ctx->state = StateNone; + TRY(ctx->closeTag(ctx, ctx->elemName.data)); --ctx->elementDepth; CLEAR_BUFFER(buffer); @@ -540,8 +540,8 @@ int csxml_feedChar(struct csxml* ctx, char ch) if(ch != '>') ERROR("Invalid data in close tag."); TRY(buffer_copy(ctx, &ctx->elemName, list_pop(&ctx->elemStack))); if(strcmp(ctx->elemName.data, ctx->buffer.data)) ERROR("Mismatched close tag."); - TRY(ctx->closeTag(ctx, ctx->elemName.data)); ctx->state = StateNone; + TRY(ctx->closeTag(ctx, ctx->elemName.data)); --ctx->elementDepth; CLEAR_BUFFER(buffer); break; @@ -598,8 +598,8 @@ const char* csxml_entityRef(struct csxml* ctx, const char* ent) q = ctx->entityRef(ctx, ent); if(!q) { - ctx->unknownEntity(ctx, ent); ctx->state = StateError; + ctx->unknownEntity(ctx, ent); return 0; } diff --git a/src/libStreamedXML/Parser.cpp b/src/libStreamedXML/Parser.cpp index b043282..3dcc9a9 100644 --- a/src/libStreamedXML/Parser.cpp +++ b/src/libStreamedXML/Parser.cpp @@ -163,26 +163,26 @@ doBuffer: break; case ClassOpenTag: - if(!buffer.empty()) callback->whiteSpace(buffer); state = StateOpen; + if(!buffer.empty()) callback->whiteSpace(buffer); buffer.clear(); break; case ClassEntity: if(expandEntities) { if(!elementDepth) ERROR(L"Entities cannot appear at stream level."); + state = StateEntity; if(!buffer.empty()) callback->whiteSpace(buffer); buffer.clear(); parsingAttr = false; - state = StateEntity; break; } // fall through default: if(!elementDepth) ERROR(L"Content cannot appear at stream level."); - if(!buffer.empty()) callback->whiteSpace(buffer); state = StateData; + if(!buffer.empty()) callback->whiteSpace(buffer); buffer = ch; break; } @@ -191,16 +191,16 @@ doBuffer: case StateData: switch(c) { case ClassOpenTag: + state = StateOpen; callback->content(buffer); buffer.clear(); - state = StateOpen; break; case ClassEntity: + state = StateEntity; callback->content(buffer); buffer.clear(); parsingAttr = false; - state = StateEntity; break; default: @@ -225,9 +225,9 @@ doBuffer: case StateCDATA2: if(ch == L'>') { + state = StateNone; callback->cdata(buffer); buffer.clear(); - state = StateNone; } else if(ch == L']') { buffer += ch; } else { @@ -298,9 +298,9 @@ doBuffer: case StatePI2: if(ch != L'>') ERROR(L"Invalid target for PI"); else { + state = StateNone; callback->PI(buffer2, L""); buffer.clear(); - state = StateNone; } break; @@ -311,9 +311,9 @@ doBuffer: case StatePI3: if(ch == L'>') { + state = StateNone; callback->PI(buffer2, buffer); buffer.clear(); - state = StateNone; } else if(ch == '?') { buffer += L'?'; } else { @@ -360,9 +360,9 @@ doBuffer: case StateComment3: if(ch != L'>') ERROR(L"`--' not valid in comments"); + state = StateNone; callback->comment(buffer); buffer.clear(); - state = StateNone; break; case StateElemName: @@ -382,8 +382,8 @@ doBuffer: switch(ch) { case L'>': elemStack.push_back(buffer); - callback->element(buffer, elemAttrs); state = StateNone; + callback->element(buffer, elemAttrs); ++elementDepth; buffer.clear(); break; @@ -412,9 +412,9 @@ doBuffer: switch(ch) { case L'>': elemStack.push_back(elemName); + state = StateNone; callback->element(elemName, elemAttrs); buffer.clear(); - state = StateNone; ++elementDepth; break; @@ -474,10 +474,10 @@ doBuffer: if(ch == L'/') { state = StateNeedClose; } else if(ch == L'>') { + state = StateNone; callback->element(elemName, elemAttrs); elemStack.push_back(elemName); buffer.clear(); - state = StateNone; ++elementDepth; } else ERROR(L"Invalid character after attribute."); break; @@ -486,10 +486,10 @@ doBuffer: case StateNeedClose: if(ch != L'>') ERROR(L"Stray `/' in open tag."); + state = StateNone; callback->element(elemName, elemAttrs); callback->closeTag(elemName); buffer.clear(); - state = StateNone; break; case StateClose: @@ -513,9 +513,9 @@ doBuffer: if(ch != L'>') ERROR(L"Invalid character in close tag name."); if(elemStack.back() != buffer) ERROR(L"Mismatched close tag."); elemStack.pop_back(); + state = StateNone; callback->closeTag(buffer); buffer.clear(); - state = StateNone; --elementDepth; } break; @@ -525,9 +525,9 @@ doBuffer: if(ch != L'>') ERROR(L"Invalid data in close tag."); if(elemStack.back() != elemName) ERROR(L"Mismatched close tag."); elemStack.pop_back(); + state = StateNone; callback->closeTag(elemName); buffer.clear(); - state = StateNone; --elementDepth; break;