errorCode addProtoRule(ProtoGrammar* pg, Index prodDim, ProtoRuleEntry** ruleEntry) { errorCode tmp_err_code = EXIP_UNEXPECTED_ERROR; Index ruleId; TRY(addEmptyDynEntry(&pg->dynArray, (void **) ruleEntry, &ruleId)); return createDynArray(&((*ruleEntry)->dynArray), sizeof(Production), prodDim); }
errorCode addDynEntry(DynArray* dynArray, void* entry, Index* entryID) { errorCode tmp_err_code; void *emptyEntry; tmp_err_code = addEmptyDynEntry(dynArray, &emptyEntry, entryID); if(tmp_err_code != ERR_OK) return tmp_err_code; memcpy(emptyEntry, entry, dynArray->entrySize); return ERR_OK; }
errorCode addProduction(ProtoRuleEntry* ruleEntry, EventType eventType, Index typeId, QNameID qnameID, SmallIndex nonTermID) { errorCode tmp_err_code = UNEXPECTED_ERROR; Production *newProd; Index newProdId; tmp_err_code = addEmptyDynEntry(&ruleEntry->dynArray, (void**)&newProd, &newProdId); newProd->eventType = eventType; newProd->typeId = typeId; newProd->qnameId = qnameID; newProd->nonTermID = nonTermID; return ERR_OK; }
errorCode addProduction(ProtoRuleEntry* ruleEntry, EventType eventType, Index typeId, QNameID qnameID, SmallIndex nonTermID) { errorCode tmp_err_code = EXIP_UNEXPECTED_ERROR; Production *newProd; Index newProdId; TRY(addEmptyDynEntry(&ruleEntry->dynArray, (void**)&newProd, &newProdId)); SET_PROD_EXI_EVENT(newProd->content, eventType); newProd->typeId = typeId; newProd->qnameId = qnameID; SET_PROD_NON_TERM(newProd->content, nonTermID); return EXIP_OK; }
errorCode addLnEntry(LnTable* lnTable, String lnStr, Index* lnEntryId) { errorCode tmp_err_code; LnEntry* lnEntry; TRY(addEmptyDynEntry(&lnTable->dynArray, (void**)&lnEntry, lnEntryId)); // Fill in local names entry lnEntry->lnStr = lnStr; lnEntry->elemGrammar = INDEX_MAX; lnEntry->typeGrammar = INDEX_MAX; #if VALUE_CROSSTABLE_USE // The Vx table is created on-demand (additions to value cross table are done when a value is inserted in the value table) lnEntry->vxTable = NULL; #endif return EXIP_OK; }
errorCode addUriEntry(UriTable* uriTable, String uriStr, SmallIndex* uriEntryId) { errorCode tmp_err_code; UriEntry* uriEntry; Index uriLEntryId; TRY(addEmptyDynEntry(&uriTable->dynArray, (void**)&uriEntry, &uriLEntryId)); // Fill in URI entry uriEntry->uriStr = uriStr; // Prefix table is created independently uriEntry->pfxTable = NULL; // Create local names table for this URI // TODO RCC 20120201: Should this be separate (empty string URI has no local names)? TRY(createDynArray(&uriEntry->lnTable.dynArray, sizeof(LnEntry), DEFAULT_LN_ENTRIES_NUMBER)); *uriEntryId = (SmallIndex)uriLEntryId; return EXIP_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; }