errorCode textGrammarOutput(QNameID qnameid, Index grIndex, EXIGrammar* gr, EXIPSchema* schema, FILE* out) { Index ruleIter, prodIter; Production* tmpProd; EXIType exiType = VALUE_TYPE_NONE; fprintf(out, "Grammar %d [%d:%d] ", (int) grIndex, (int) qnameid.uriId, (int) qnameid.lnId); fwrite(schema->uriTable.uri[qnameid.uriId].uriStr.str, sizeof(CharType), schema->uriTable.uri[qnameid.uriId].uriStr.length, out); fprintf(out, ":"); fwrite(GET_LN_URI_QNAME(schema->uriTable, qnameid).lnStr.str, sizeof(CharType), GET_LN_URI_QNAME(schema->uriTable, qnameid).lnStr.length, out); fprintf(out, "\n"); for(ruleIter = 0; ruleIter < gr->count; ruleIter++) { fprintf(out, "NT-%d: \n", (int) ruleIter); for(prodIter = 0; prodIter < gr->rule[ruleIter].pCount; prodIter++) { tmpProd = &gr->rule[ruleIter].production[gr->rule[ruleIter].pCount - 1 - prodIter]; if(GET_PROD_EXI_EVENT(tmpProd->content) != EVENT_SE_QNAME && tmpProd->typeId != INDEX_MAX) exiType = GET_EXI_TYPE(schema->simpleTypeTable.sType[tmpProd->typeId].content); else exiType = VALUE_TYPE_NONE; switch(GET_PROD_EXI_EVENT(tmpProd->content)) { case EVENT_SD: fprintf(out, "\tSD "); break; case EVENT_ED: fprintf(out, "\tED "); break; case EVENT_SE_QNAME: fprintf(out, "\tSE ([%d:%d]", (int) tmpProd->qnameId.uriId, (int) tmpProd->qnameId.lnId); fwrite(schema->uriTable.uri[tmpProd->qnameId.uriId].uriStr.str, sizeof(CharType), schema->uriTable.uri[tmpProd->qnameId.uriId].uriStr.length, out); fprintf(out, ":"); fwrite(GET_LN_URI_QNAME(schema->uriTable, tmpProd->qnameId).lnStr.str, sizeof(CharType), GET_LN_URI_QNAME(schema->uriTable, tmpProd->qnameId).lnStr.length, out); fprintf(out, ") "); break; case EVENT_SE_URI: fprintf(out, "\tSE (uri) "); break; case EVENT_SE_ALL: fprintf(out, "\tSE (*) "); break; case EVENT_EE: fprintf(out, "\tEE "); break; case EVENT_AT_QNAME: fprintf(out, "\tAT ([%d:%d]", (int) tmpProd->qnameId.uriId, (int) tmpProd->qnameId.lnId); fwrite(schema->uriTable.uri[tmpProd->qnameId.uriId].uriStr.str, sizeof(CharType), schema->uriTable.uri[tmpProd->qnameId.uriId].uriStr.length, out); fprintf(out, ":"); fwrite(GET_LN_URI_QNAME(schema->uriTable, tmpProd->qnameId).lnStr.str, sizeof(CharType), GET_LN_URI_QNAME(schema->uriTable, tmpProd->qnameId).lnStr.length, out); fprintf(out, ") "); writeValueTypeString(out, exiType); break; case EVENT_AT_URI: fprintf(out, "\tAT (uri) "); break; case EVENT_AT_ALL: fprintf(out, "\tAT (*) "); writeValueTypeString(out, exiType); break; case EVENT_CH: fprintf(out, "\tCH "); writeValueTypeString(out, exiType); break; case EVENT_NS: fprintf(out, "\tNS "); break; case EVENT_CM: fprintf(out, "\tCM "); break; case EVENT_PI: fprintf(out, "\tPI "); break; case EVENT_DT: fprintf(out, "\tDT "); break; case EVENT_ER: fprintf(out, "\tER "); break; case EVENT_SC: fprintf(out, "\tSC "); break; case EVENT_VOID: fprintf(out, " "); break; default: return UNEXPECTED_ERROR; } if(GET_PROD_NON_TERM(tmpProd->content) != GR_VOID_NON_TERMINAL) { fprintf(out, "\tNT-%u\t", (unsigned int) GET_PROD_NON_TERM(tmpProd->content)); } fprintf(out, "%d\n", (int) prodIter); } fprintf(out, "\n"); } return ERR_OK; }
errorCode addValueEntry(EXIStream* strm, String valueStr, QNameID qnameID) { errorCode tmp_err_code = EXIP_UNEXPECTED_ERROR; ValueEntry* valueEntry = NULL; Index valueEntryId; #if VALUE_CROSSTABLE_USE Index vxEntryId; { struct LnEntry* lnEntry; VxEntry vxEntry; // Find the local name entry from QNameID lnEntry = &GET_LN_URI_QNAME(strm->schema->uriTable, qnameID); // Add entry to the local name entry's value cross table (vxTable) if(lnEntry->vxTable == NULL) { lnEntry->vxTable = memManagedAllocate(&strm->memList, sizeof(VxTable)); if(lnEntry->vxTable == NULL) return EXIP_MEMORY_ALLOCATION_ERROR; // First value entry - create the vxTable TRY(createDynArray(&lnEntry->vxTable->dynArray, sizeof(VxEntry), DEFAULT_VX_ENTRIES_NUMBER)); } assert(lnEntry->vxTable->vx); // Set the global ID in the value cross table entry vxEntry.globalId = strm->valueTable.globalId; // Add the entry TRY(addDynEntry(&lnEntry->vxTable->dynArray, (void*) &vxEntry, &vxEntryId)); } #endif // If the global ID is less than the actual array size, we must have wrapped around // In this case, we must reuse an existing entry if(strm->valueTable.globalId < strm->valueTable.count) { // Get the existing value entry valueEntry = &strm->valueTable.value[strm->valueTable.globalId]; #if VALUE_CROSSTABLE_USE assert(GET_LN_URI_QNAME(strm->schema->uriTable, valueEntry->locValuePartition.forQNameId).vxTable); // Null out the existing cross table entry GET_LN_URI_QNAME(strm->schema->uriTable, valueEntry->locValuePartition.forQNameId).vxTable->vx[valueEntry->locValuePartition.vxEntryId].globalId = INDEX_MAX; #endif #if HASH_TABLE_USE // Remove existing value string from hash table (if present) if(strm->valueTable.hashTbl != NULL) { hashtable_remove(strm->valueTable.hashTbl, valueEntry->valueStr); } #endif // Free the memory allocated by the previous string entry EXIP_MFREE(valueEntry->valueStr.str); } else { // We are filling up the array and have not wrapped round yet // See http://www.w3.org/TR/exi/#encodingOptimizedForMisses TRY(addEmptyDynEntry(&strm->valueTable.dynArray, (void**)&valueEntry, &valueEntryId)); } // Set the value entry fields valueEntry->valueStr = valueStr; #if VALUE_CROSSTABLE_USE valueEntry->locValuePartition.forQNameId = qnameID; valueEntry->locValuePartition.vxEntryId = vxEntryId; #endif #if HASH_TABLE_USE // Add value string to hash table (if present) if(strm->valueTable.hashTbl != NULL) { TRY(hashtable_insert(strm->valueTable.hashTbl, valueStr, strm->valueTable.globalId)); } #endif // Increment global ID strm->valueTable.globalId++; // The value table is limited by valuePartitionCapacity. If we have exceeded, we wrap around // to the beginning of the value table and null out existing IDs in the corresponding // cross table IDs if(strm->valueTable.globalId == strm->header.opts.valuePartitionCapacity) strm->valueTable.globalId = 0; return EXIP_OK; }
errorCode createFragmentGrammar(EXIPSchema* schema, QNameID* elQnameArr, Index qnameCount) { GrammarRule* tmp_rule; schema->docGrammar.count = DEF_FRAG_GRAMMAR_RULE_NUMBER; schema->docGrammar.props = 0; schema->docGrammar.contentIndex = 0; schema->docGrammar.rule = (GrammarRule*) memManagedAllocate(&schema->memList, sizeof(GrammarRule)*DEF_FRAG_GRAMMAR_RULE_NUMBER); if(schema->docGrammar.rule == NULL) return MEMORY_ALLOCATION_ERROR; /* Rule for Fragment */ /* Fragment : SD FragmentContent 0 */ tmp_rule = &schema->docGrammar.rule[GR_FRAGMENT]; /* Part 1 */ tmp_rule->part[0].prod = static_prod_start_doc_part0; tmp_rule->part[0].count = 1; tmp_rule->part[0].bits = 0; /* Initialize Part 2 */ tmp_rule->part[1].prod = NULL; tmp_rule->part[1].count = 0; tmp_rule->part[1].bits = 0; /* Initialize Part 3 */ tmp_rule->part[2].prod = NULL; tmp_rule->part[2].count = 0; tmp_rule->part[2].bits = 0; /* Rule for Fragment content */ tmp_rule = &schema->docGrammar.rule[GR_FRAGMENT_CONTENT]; /* Initialize Part 2 */ tmp_rule->part[1].prod = NULL; tmp_rule->part[1].count = 0; tmp_rule->part[1].bits = 0; /* Initialize Part 3 */ tmp_rule->part[2].prod = NULL; tmp_rule->part[2].count = 0; tmp_rule->part[2].bits = 0; /* Part 1 */ if(elQnameArr != NULL) // Creates Schema Informed Grammar { unsigned int e = 0; Index tmp_code1; SET_SCHEMA(schema->docGrammar.props); tmp_code1 = qnameCount + 2; tmp_rule->part[0].prod = (Production*) memManagedAllocate(&schema->memList, sizeof(Production)*tmp_code1); if(tmp_rule->part[0].prod == NULL) return MEMORY_ALLOCATION_ERROR; /* * FragmentContent : * SE (F-0) FragmentContent 0 * SE (F-1) FragmentContent 1 * ⋮ ⋮ ⋮ * SE (F-n−1) FragmentContent n-1 * // SE (*) FragmentContent n // This is created as part of the Build-In grammar further on * // ED n+1 // This is created as part of the Build-In grammar further on */ for(e = 0; e < qnameCount; e++) { tmp_rule->part[0].prod[qnameCount - e].eventType = EVENT_SE_QNAME; tmp_rule->part[0].prod[qnameCount - e].typeId = GET_LN_URI_QNAME(schema->uriTable, elQnameArr[e]).elemGrammar; tmp_rule->part[0].prod[qnameCount - e].nonTermID = GR_FRAGMENT_CONTENT; tmp_rule->part[0].prod[qnameCount - e].qnameId = elQnameArr[e]; } tmp_rule->part[0].count = tmp_code1; tmp_rule->part[0].bits = getBitsNumber(tmp_code1 - 1); } else { tmp_rule->part[0].prod = (Production*) memManagedAllocate(&schema->memList, sizeof(Production)*2); if(tmp_rule->part[0].prod == NULL) return MEMORY_ALLOCATION_ERROR; /* Productions further on... */ tmp_rule->part[0].count = 2; tmp_rule->part[0].bits = 1; } /* * FragmentContent : * SE (*) FragmentContent 0 * ED 1 */ tmp_rule->part[0].prod[0].eventType = EVENT_ED; tmp_rule->part[0].prod[0].typeId = INDEX_MAX; tmp_rule->part[0].prod[0].nonTermID = GR_VOID_NON_TERMINAL; tmp_rule->part[0].prod[0].qnameId.uriId = SMALL_INDEX_MAX; tmp_rule->part[0].prod[0].qnameId.lnId = INDEX_MAX; tmp_rule->part[0].prod[1].eventType = EVENT_SE_ALL; tmp_rule->part[0].prod[1].typeId = INDEX_MAX; tmp_rule->part[0].prod[1].nonTermID = GR_FRAGMENT_CONTENT; tmp_rule->part[0].prod[1].qnameId.uriId = SMALL_INDEX_MAX; tmp_rule->part[0].prod[1].qnameId.lnId = INDEX_MAX; return ERR_OK; }
errorCode createDocGrammar(EXIPSchema* schema, QNameID* elQnameArr, Index qnameCount) { GrammarRule* tmp_rule; schema->docGrammar.count = DEF_DOC_GRAMMAR_RULE_NUMBER; schema->docGrammar.props = 0; schema->docGrammar.contentIndex = 0; schema->docGrammar.rule = (GrammarRule*) memManagedAllocate(&schema->memList, sizeof(GrammarRule)*DEF_DOC_GRAMMAR_RULE_NUMBER); if(schema->docGrammar.rule == NULL) return MEMORY_ALLOCATION_ERROR; /* Rule for Document */ /* * Document : * SD DocContent 0 */ tmp_rule = &schema->docGrammar.rule[GR_DOCUMENT]; /* Part 1 */ tmp_rule->part[0].prod = static_prod_start_doc_part0; tmp_rule->part[0].count = 1; tmp_rule->part[0].bits = 0; /* Initialize Part 2 */ tmp_rule->part[1].prod = NULL; tmp_rule->part[1].count = 0; tmp_rule->part[1].bits = 0; /* Initialize Part 3 */ tmp_rule->part[2].prod = NULL; tmp_rule->part[2].count = 0; tmp_rule->part[2].bits = 0; /* Rule for document content */ tmp_rule = &schema->docGrammar.rule[GR_DOC_CONTENT]; /* Initialize Part 2 */ tmp_rule->part[1].prod = NULL; tmp_rule->part[1].count = 0; tmp_rule->part[1].bits = 0; /* Initialize Part 3 */ tmp_rule->part[2].prod = NULL; tmp_rule->part[2].count = 0; tmp_rule->part[2].bits = 0; /* Part 1 */ if(elQnameArr != NULL) // Creates Schema Informed Grammar { unsigned int e = 0; Index tmp_code1; SET_SCHEMA(schema->docGrammar.props); tmp_code1 = qnameCount + 1; tmp_rule->part[0].prod = (Production*) memManagedAllocate(&schema->memList, sizeof(Production)*tmp_code1); if(tmp_rule->part[0].prod == NULL) return MEMORY_ALLOCATION_ERROR; /* * DocContent : * SE (G-0) DocEnd 0 * SE (G-1) DocEnd 1 * ⋮ ⋮ ⋮ * SE (G-n−1) DocEnd n-1 * // SE (*) DocEnd n // This is created as part of the Built-In grammar further on */ for(e = 0; e < qnameCount; e++) { tmp_rule->part[0].prod[qnameCount - e].eventType = EVENT_SE_QNAME; tmp_rule->part[0].prod[qnameCount - e].typeId = GET_LN_URI_QNAME(schema->uriTable, elQnameArr[e]).elemGrammar; tmp_rule->part[0].prod[qnameCount - e].nonTermID = GR_DOC_END; tmp_rule->part[0].prod[qnameCount - e].qnameId = elQnameArr[e]; } tmp_rule->part[0].count = tmp_code1; tmp_rule->part[0].bits = getBitsNumber(qnameCount); } else { tmp_rule->part[0].prod = (Production*) memManagedAllocate(&schema->memList, sizeof(Production)); if(tmp_rule->part[0].prod == NULL) return MEMORY_ALLOCATION_ERROR; tmp_rule->part[0].count = 1; tmp_rule->part[0].bits = 0; } /* * DocContent : * SE (*) DocEnd 0 */ tmp_rule->part[0].prod[0].eventType = EVENT_SE_ALL; tmp_rule->part[0].prod[0].typeId = INDEX_MAX; tmp_rule->part[0].prod[0].nonTermID = GR_DOC_END; tmp_rule->part[0].prod[0].qnameId.uriId = SMALL_INDEX_MAX; tmp_rule->part[0].prod[0].qnameId.lnId = INDEX_MAX; /* Rule for Document end */ /* * DocEnd : * ED 0 */ tmp_rule = &schema->docGrammar.rule[GR_DOC_END]; /* Part 1 */ tmp_rule->part[0].prod = static_prod_doc_end_part0; tmp_rule->part[0].count = 1; tmp_rule->part[0].bits = 0; /* Initialize Part 2 */ tmp_rule->part[1].prod = NULL; tmp_rule->part[1].count = 0; tmp_rule->part[1].bits = 0; /* Initialize Part 3 */ tmp_rule->part[2].prod = NULL; tmp_rule->part[2].count = 0; tmp_rule->part[2].bits = 0; return ERR_OK; }
errorCode createDocGrammar(EXIPSchema* schema, QNameID* elQnameArr, Index qnameCount) { GrammarRule* tmp_rule; schema->docGrammar.count = DEF_DOC_GRAMMAR_RULE_NUMBER; schema->docGrammar.props = 0; SET_DOCUMENT_GR(schema->docGrammar.props); schema->docGrammar.rule = (GrammarRule*) memManagedAllocate(&schema->memList, sizeof(GrammarRule)*DEF_DOC_GRAMMAR_RULE_NUMBER); if(schema->docGrammar.rule == NULL) return MEMORY_ALLOCATION_ERROR; /* Rule for Document */ /* * Document : * SD DocContent 0 */ // IGNORED! /* Rule for document content */ tmp_rule = &schema->docGrammar.rule[GR_DOC_CONTENT]; if(elQnameArr != NULL) // Creates Schema Informed Grammar { unsigned int e = 0; Index tmp_code1; SET_SCHEMA_GR(schema->docGrammar.props); tmp_code1 = qnameCount + 1; tmp_rule->production = (Production*) memManagedAllocate(&schema->memList, sizeof(Production)*tmp_code1); if(tmp_rule->production == NULL) return MEMORY_ALLOCATION_ERROR; /* * DocContent : * SE (G-0) DocEnd 0 * SE (G-1) DocEnd 1 * ⋮ ⋮ ⋮ * SE (G-n−1) DocEnd n-1 * // SE (*) DocEnd n // This is created as part of the Built-In grammar further on */ for(e = 0; e < qnameCount; e++) { SET_PROD_EXI_EVENT(tmp_rule->production[qnameCount - e].content, EVENT_SE_QNAME); SET_PROD_NON_TERM(tmp_rule->production[qnameCount - e].content, GR_DOC_END); tmp_rule->production[qnameCount - e].typeId = GET_LN_URI_QNAME(schema->uriTable, elQnameArr[e]).elemGrammar; tmp_rule->production[qnameCount - e].qnameId = elQnameArr[e]; } tmp_rule->pCount = tmp_code1; } else { tmp_rule->production = (Production*) memManagedAllocate(&schema->memList, sizeof(Production)); if(tmp_rule->production == NULL) return MEMORY_ALLOCATION_ERROR; tmp_rule->pCount = 1; tmp_rule->meta = 0; } /* * DocContent : * SE (*) DocEnd 0 */ SET_PROD_EXI_EVENT(tmp_rule->production[0].content, EVENT_SE_ALL); SET_PROD_NON_TERM(tmp_rule->production[0].content, GR_DOC_END); tmp_rule->production[0].typeId = INDEX_MAX; tmp_rule->production[0].qnameId.uriId = URI_MAX; tmp_rule->production[0].qnameId.lnId = LN_MAX; /* Rule for Document end */ /* * DocEnd : * ED 0 */ tmp_rule = &schema->docGrammar.rule[GR_DOC_END]; // TODO: consider ignoring this rule as well. In exipg generation as well ... /* Part 1 */ tmp_rule->production = (Production*) memManagedAllocate(&schema->memList, sizeof(Production)); if(tmp_rule->production == NULL) return MEMORY_ALLOCATION_ERROR; SET_PROD_EXI_EVENT(tmp_rule->production[0].content, EVENT_ED); SET_PROD_NON_TERM(tmp_rule->production[0].content, GR_VOID_NON_TERMINAL); tmp_rule->production[0].typeId = INDEX_MAX; tmp_rule->production[0].qnameId.uriId = URI_MAX; tmp_rule->production[0].qnameId.lnId = LN_MAX; tmp_rule->pCount = 1; tmp_rule->meta = 0; return ERR_OK; }
errorCode createFragmentGrammar(EXIPSchema* schema, QNameID* elQnameArr, Index qnameCount) { GrammarRule* tmp_rule; schema->docGrammar.count = DEF_FRAG_GRAMMAR_RULE_NUMBER; schema->docGrammar.props = 0; schema->docGrammar.rule = (GrammarRule*) memManagedAllocate(&schema->memList, sizeof(GrammarRule)*DEF_FRAG_GRAMMAR_RULE_NUMBER); if(schema->docGrammar.rule == NULL) return MEMORY_ALLOCATION_ERROR; /* Rule for Fragment */ /* Fragment : SD FragmentContent 0 */ // IGNORED! /* Rule for Fragment content */ tmp_rule = &schema->docGrammar.rule[GR_FRAGMENT_CONTENT]; /* Part 1 */ if(elQnameArr != NULL) // Creates Schema Informed Grammar { unsigned int e = 0; Index tmp_code1; SET_SCHEMA_GR(schema->docGrammar.props); tmp_code1 = qnameCount + 2; tmp_rule->production = (Production*) memManagedAllocate(&schema->memList, sizeof(Production)*tmp_code1); if(tmp_rule->production == NULL) return MEMORY_ALLOCATION_ERROR; /* * FragmentContent : * SE (F-0) FragmentContent 0 * SE (F-1) FragmentContent 1 * ⋮ ⋮ ⋮ * SE (F-n−1) FragmentContent n-1 * // SE (*) FragmentContent n // This is created as part of the Build-In grammar further on * // ED n+1 // This is created as part of the Build-In grammar further on */ for(e = 0; e < qnameCount; e++) { SET_PROD_EXI_EVENT(tmp_rule->production[qnameCount - e].content, EVENT_SE_QNAME); SET_PROD_NON_TERM(tmp_rule->production[qnameCount - e].content, GR_FRAGMENT_CONTENT); tmp_rule->production[qnameCount - e].typeId = GET_LN_URI_QNAME(schema->uriTable, elQnameArr[e]).elemGrammar; tmp_rule->production[qnameCount - e].qnameId = elQnameArr[e]; } tmp_rule->pCount = tmp_code1; } else { tmp_rule->production = (Production*) memManagedAllocate(&schema->memList, sizeof(Production)*2); if(tmp_rule->production == NULL) return MEMORY_ALLOCATION_ERROR; /* Productions further on... */ tmp_rule->pCount = 2; } /* * FragmentContent : * SE (*) FragmentContent 0 * ED 1 */ SET_PROD_EXI_EVENT(tmp_rule->production[0].content, EVENT_ED); SET_PROD_NON_TERM(tmp_rule->production[0].content, GR_VOID_NON_TERMINAL); tmp_rule->production[0].typeId = INDEX_MAX; tmp_rule->production[0].qnameId.uriId = URI_MAX; tmp_rule->production[0].qnameId.lnId = LN_MAX; SET_PROD_EXI_EVENT(tmp_rule->production[1].content, EVENT_SE_ALL); SET_PROD_NON_TERM(tmp_rule->production[1].content, GR_FRAGMENT_CONTENT); tmp_rule->production[1].typeId = INDEX_MAX; tmp_rule->production[1].qnameId.uriId = URI_MAX; tmp_rule->production[1].qnameId.lnId = LN_MAX; return ERR_OK; }