unsigned int getBitsFirstPartCode(EXIOptions opts, EXIGrammar* grammar, GrammarRule* currentRule, SmallIndex currentRuleIndx, boolean isNilType) { unsigned char secondLevelExists = 0; if(IS_BUILT_IN_ELEM(grammar->props)) { // Built-in element grammar // There is always a second level production return getBitsNumber(currentRule->pCount); } else if(IS_DOCUMENT(grammar->props)) { // Document grammar if(IS_PRESERVED(opts.preserve, PRESERVE_COMMENTS) || IS_PRESERVED(opts.preserve, PRESERVE_PIS)) secondLevelExists = 1; else if(currentRuleIndx == 0 && IS_PRESERVED(opts.preserve, PRESERVE_DTD)) secondLevelExists = 1; return getBitsNumber(currentRule->pCount - 1 + secondLevelExists); } else if(IS_FRAGMENT(grammar->props)) { // Fragment grammar if(IS_PRESERVED(opts.preserve, PRESERVE_COMMENTS) || IS_PRESERVED(opts.preserve, PRESERVE_PIS)) secondLevelExists = 1; return getBitsNumber(currentRule->pCount - 1 + secondLevelExists); } else { // Schema-informed element/type grammar Index prodCount; if(isNilType == FALSE) prodCount = currentRule->pCount; else prodCount = RULE_GET_AT_COUNT(currentRule->meta) + RULE_CONTAIN_EE(currentRule->meta); if(WITH_STRICT(opts.enumOpt)) { // Strict mode if(isNilType == FALSE && currentRuleIndx == 0 && (HAS_NAMED_SUB_TYPE_OR_UNION(grammar->props) || IS_NILLABLE(grammar->props))) secondLevelExists = 1; return getBitsNumber(prodCount - 1 + secondLevelExists); } else // Non-strict mode { // There is always a second level production return getBitsNumber(prodCount); } } }
errorCode processNextProduction(EXIStream* strm, SmallIndex* nonTermID_out, ContentHandler* handler, void* app_data) { errorCode tmp_err_code = UNEXPECTED_ERROR; unsigned int tmp_bits_val = 0; unsigned char b = 0; GrammarRule* currentRule; DEBUG_MSG(INFO, DEBUG_GRAMMAR, (">Next production non-term-id: %u\n", (unsigned int) strm->context.currNonTermID)); if(strm->context.currNonTermID >= strm->gStack->grammar->count) return INCONSISTENT_PROC_STATE; if(IS_BUILT_IN_ELEM(strm->gStack->grammar->props)) // If the current grammar is build-in Element grammar ... currentRule = (GrammarRule*) &((DynGrammarRule*) strm->gStack->grammar->rule)[strm->context.currNonTermID]; else currentRule = &strm->gStack->grammar->rule[strm->context.currNonTermID]; #if DEBUG_GRAMMAR == ON { tmp_err_code = printGrammarRule(strm->context.currNonTermID, currentRule, strm->schema); if(tmp_err_code != ERR_OK) { DEBUG_MSG(INFO, DEBUG_GRAMMAR, (">Error printing grammar rule\n")); } } #endif for(b = 0; b < 3; b++) { if(currentRule->part[b].count == 0) // No productions available with this length code continue; if(currentRule->part[b].bits == 0) // encoded with zero bits return handleProduction(strm, currentRule, ¤tRule->part[b].prod[0], nonTermID_out, handler, app_data, b + 1); tmp_err_code = decodeNBitUnsignedInteger(strm, currentRule->part[b].bits, &tmp_bits_val); if(tmp_err_code != ERR_OK) return tmp_err_code; if(tmp_bits_val == currentRule->part[b].count) // The code has more parts continue; return handleProduction(strm, currentRule, ¤tRule->part[b].prod[currentRule->part[b].count - 1 - tmp_bits_val], nonTermID_out, handler, app_data, b + 1); } return tmp_err_code; }
static errorCode handleProduction(EXIStream* strm, GrammarRule* currentRule, Production* prodHit, SmallIndex* nonTermID_out, ContentHandler* handler, void* app_data, unsigned int codeLength) { errorCode tmp_err_code = UNEXPECTED_ERROR; QNameID qnameID = {URI_MAX, LN_MAX}; *nonTermID_out = prodHit->nonTermID; switch(prodHit->eventType) { case EVENT_SD: if(handler->startDocument != NULL) { if(handler->startDocument(app_data) == EXIP_HANDLER_STOP) return HANDLER_STOP_RECEIVED; } break; case EVENT_ED: if(handler->endDocument != NULL) { if(handler->endDocument(app_data) == EXIP_HANDLER_STOP) return HANDLER_STOP_RECEIVED; } break; case EVENT_EE: if(handler->endElement != NULL) { if(handler->endElement(app_data) == EXIP_HANDLER_STOP) return HANDLER_STOP_RECEIVED; } if(codeLength > 1 && IS_BUILT_IN_ELEM(strm->gStack->grammar->props)) // #1# COMMENT { tmp_err_code = insertZeroProduction((DynGrammarRule*) currentRule, EVENT_EE, GR_VOID_NON_TERMINAL, &qnameID); if(tmp_err_code != ERR_OK) return tmp_err_code; } break; case EVENT_SC: if(handler->selfContained != NULL) { if(handler->selfContained(app_data) == EXIP_HANDLER_STOP) return HANDLER_STOP_RECEIVED; } break; default: // The event has content! if(prodHit->eventType == EVENT_CH) { if(codeLength > 1 && IS_BUILT_IN_ELEM(strm->gStack->grammar->props)) // #2# COMMENT { tmp_err_code = insertZeroProduction((DynGrammarRule*) currentRule, EVENT_CH, *nonTermID_out, &qnameID); if(tmp_err_code != ERR_OK) return tmp_err_code; } } tmp_err_code = decodeEventContent(strm, prodHit, handler, nonTermID_out, currentRule, app_data); if(tmp_err_code != ERR_OK) return tmp_err_code; break; } return ERR_OK; }