예제 #1
0
errorCode initSchema(EXIPSchema* schema, InitSchemaType initializationType)
{
	errorCode tmp_err_code = UNEXPECTED_ERROR;

	TRY(initAllocList(&schema->memList));

	schema->staticGrCount = 0;
	SET_CONTENT_INDEX(schema->docGrammar.props, 0);
	schema->docGrammar.count = 0;
	schema->docGrammar.props = 0;
	schema->docGrammar.rule = NULL;
	schema->simpleTypeTable.count = 0;
	schema->simpleTypeTable.sType = NULL;
	schema->grammarTable.count = 0;
	schema->grammarTable.grammar = NULL;
	schema->enumTable.count = 0;
	schema->enumTable.enumDef = NULL;

	/* Create and initialize initial string table entries */
	TRY_CATCH(createDynArray(&schema->uriTable.dynArray, sizeof(UriEntry), DEFAULT_URI_ENTRIES_NUMBER), freeAllocList(&schema->memList));
	TRY_CATCH(createUriTableEntries(&schema->uriTable, initializationType != INIT_SCHEMA_SCHEMA_LESS_MODE), freeAllocList(&schema->memList));

	if(initializationType == INIT_SCHEMA_SCHEMA_ENABLED)
	{
		/* Create and initialize enumDef table */
		TRY_CATCH(createDynArray(&schema->enumTable.dynArray, sizeof(EnumDefinition), DEFAULT_ENUM_TABLE), freeAllocList(&schema->memList));
	}

	/* Create the schema grammar table */
	TRY_CATCH(createDynArray(&schema->grammarTable.dynArray, sizeof(EXIGrammar), DEFAULT_GRAMMAR_TABLE), freeAllocList(&schema->memList));

	if(initializationType != INIT_SCHEMA_SCHEMA_LESS_MODE)
	{
		/* Create and initialize simple type table */
		TRY_CATCH(createDynArray(&schema->simpleTypeTable.dynArray, sizeof(SimpleType), DEFAULT_SIMPLE_GRAMMAR_TABLE), freeAllocList(&schema->memList));
		TRY_CATCH(createBuiltInTypesDefinitions(&schema->simpleTypeTable, &schema->memList), freeAllocList(&schema->memList));

		// Must be done after createBuiltInTypesDefinitions()
		TRY_CATCH(generateBuiltInTypesGrammars(schema), freeAllocList(&schema->memList));

		schema->staticGrCount = SIMPLE_TYPE_COUNT;
	}

	return tmp_err_code;
}
예제 #2
0
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);
}
예제 #3
0
errorCode createValueTable(ValueTable* valueTable)
{
	errorCode tmp_err_code;

	TRY(createDynArray(&valueTable->dynArray, sizeof(ValueEntry), DEFAULT_VALUE_ENTRIES_NUMBER));

	valueTable->globalId = 0;
#if HASH_TABLE_USE
	valueTable->hashTbl = NULL;
#endif
	return EXIP_OK;
}
예제 #4
0
END_TEST

START_TEST (test_addLnEntry)
{
	errorCode err = EXIP_UNEXPECTED_ERROR;
	LnTable lnTable;
	Index entryId = 55;
	String test_ln = {"test_ln_string", 14};

	err = createDynArray(&lnTable.dynArray, sizeof(LnEntry), DEFAULT_LN_ENTRIES_NUMBER);
	fail_if(err != EXIP_OK);

	err = addLnEntry(&lnTable, test_ln, &entryId);

	fail_unless (err == EXIP_OK, "addLnEntry returns error code %d", err);
	fail_unless (lnTable.dynArray.arrayEntries == DEFAULT_LN_ENTRIES_NUMBER,
				"addLnEntry changed the dynArray.arrayEntries unnecessary");
	fail_unless (lnTable.count == 1,
					"addLnEntry did not update rowCount properly");
	fail_unless (stringEqual(lnTable.ln[0].lnStr, test_ln) == 1,
						"addLnEntry changed the lnStr");
	fail_unless (entryId == 0,
				"addLnEntry returned wrong entryId: %d", entryId);

#if VALUE_CROSSTABLE_USE
	fail_if(lnTable.ln[0].vxTable != NULL);
#endif

	lnTable.count = DEFAULT_LN_ENTRIES_NUMBER;

	err = addLnEntry(&lnTable, test_ln, &entryId);

	fail_unless (err == EXIP_OK, "addLnEntry returns error code %d", err);
	fail_unless (lnTable.dynArray.arrayEntries == DEFAULT_LN_ENTRIES_NUMBER*2,
				"addLnEntry did not update the dynArray.arrayEntries properly");
	fail_unless (lnTable.count == DEFAULT_LN_ENTRIES_NUMBER + 1,
					"addLnEntry did not update count properly");
	fail_unless (stringEqual(lnTable.ln[DEFAULT_LN_ENTRIES_NUMBER].lnStr, test_ln) == 1,
						"addLnEntry changed the lnStr");
	fail_unless (entryId == DEFAULT_LN_ENTRIES_NUMBER,
				"addLnEntry returned wrong entryId: %d", entryId);
#if VALUE_CROSSTABLE_USE
	fail_if(lnTable.ln[DEFAULT_LN_ENTRIES_NUMBER].vxTable != NULL);
#endif
	destroyDynArray(&lnTable.dynArray);
}
예제 #5
0
END_TEST

START_TEST (test_addUriEntry)
{
	errorCode err = EXIP_UNEXPECTED_ERROR;
	UriTable uriTable;
	SmallIndex entryId = 55;
	String test_uri = {"test_uri_string", 15};

	// Create the URI table
	err = createDynArray(&uriTable.dynArray, sizeof(UriEntry), DEFAULT_URI_ENTRIES_NUMBER);
	fail_if(err != EXIP_OK);

	err = addUriEntry(&uriTable, test_uri, &entryId);

	fail_unless (err == EXIP_OK, "addUriEntry returns error code %d", err);
	fail_unless (uriTable.dynArray.arrayEntries == DEFAULT_URI_ENTRIES_NUMBER,
				"addUriEntry changed the dynArray.arrayEntries unnecessary");
	fail_unless (uriTable.count == 1,
					"addUriEntry did not update count properly");
	fail_unless (stringEqual(uriTable.uri[0].uriStr, test_uri) == 1,
						"addUriEntry changed the uriStr");
	fail_unless (entryId == 0,
				"addUriEntry returned wrong entryId: %d", entryId);

	fail_if(uriTable.uri[0].lnTable.ln == NULL);

	uriTable.count = DEFAULT_URI_ENTRIES_NUMBER;

	err = addUriEntry(&uriTable, test_uri, &entryId);

	fail_unless (err == EXIP_OK, "addUriEntry returns error code %d", err);
	fail_unless (uriTable.dynArray.arrayEntries == DEFAULT_URI_ENTRIES_NUMBER*2,
				"addUriEntry did not update the dynArray.arrayEntries properly");
	fail_unless (uriTable.count == DEFAULT_URI_ENTRIES_NUMBER + 1,
					"addUriEntry did not update rowCount properly");
	fail_unless (stringEqual(uriTable.uri[DEFAULT_URI_ENTRIES_NUMBER].uriStr, test_uri) == 1,
						"addUriEntry changed the uriStr");
	fail_unless (entryId == DEFAULT_URI_ENTRIES_NUMBER,
				"addUriEntry returned wrong entryId: %d", entryId);

	fail_if(uriTable.uri[DEFAULT_URI_ENTRIES_NUMBER].lnTable.ln == NULL);

	destroyDynArray(&uriTable.dynArray);
}
예제 #6
0
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;
}
예제 #7
0
END_TEST

START_TEST (test_addValueEntry)
{
	EXIStream testStrm;
	errorCode tmp_err_code = EXIP_UNEXPECTED_ERROR;
	String testStr = {"TEST-007", 8};

	// IV: Initialize the stream
	{
		tmp_err_code = initAllocList(&(testStrm.memList));

		testStrm.context.bitPointer = 0;
		testStrm.buffer.bufLen = 0;
		testStrm.buffer.bufContent = 0;
		tmp_err_code += createValueTable(&testStrm.valueTable);
		testStrm.schema = memManagedAllocate(&testStrm.memList, sizeof(EXIPSchema));
		fail_unless (testStrm.schema != NULL, "Memory alloc error");
		/* Create and initialize initial string table entries */
		tmp_err_code += createDynArray(&testStrm.schema->uriTable.dynArray, sizeof(UriEntry), DEFAULT_URI_ENTRIES_NUMBER);
		tmp_err_code += createUriTableEntries(&testStrm.schema->uriTable, FALSE);
	}
	fail_unless (tmp_err_code == EXIP_OK, "initStream returns an error code %d", tmp_err_code);

	testStrm.gStack->currQNameID.uriId = 1; // http://www.w3.org/XML/1998/namespace
	testStrm.gStack->currQNameID.lnId = 2; // lang

	tmp_err_code = addValueEntry(&testStrm, testStr, testStrm.gStack->currQNameID);

	fail_unless (tmp_err_code == EXIP_OK, "addValueEntry returns an error code %d", tmp_err_code);
#if VALUE_CROSSTABLE_USE
	fail_unless (testStrm.schema->uriTable.uri[testStrm.gStack->currQNameID.uriId].lnTable.ln[testStrm.gStack->currQNameID.lnId].vxTable != NULL, "addValueEntry does not create vxTable");
	fail_unless (testStrm.schema->uriTable.uri[testStrm.gStack->currQNameID.uriId].lnTable.ln[testStrm.gStack->currQNameID.lnId].vxTable->count == 1, "addValueEntry does not create correct vxTable");
#endif
	fail_unless (testStrm.valueTable.count == 1, "addValueEntry does not create global value entry");

	destroyDynArray(&testStrm.valueTable.dynArray);
	destroyDynArray(&testStrm.schema->uriTable.dynArray);
	freeAllocList(&testStrm.memList);
}
예제 #8
0
errorCode initSchema(EXIPSchema* schema, unsigned char initializationType)
{
	errorCode tmp_err_code = UNEXPECTED_ERROR;

	tmp_err_code = initAllocList(&schema->memList);
	if(tmp_err_code != ERR_OK)
		return tmp_err_code;

	schema->staticGrCount = 0;
	schema->docGrammar.contentIndex = 0;
	schema->docGrammar.count = 0;
	schema->docGrammar.props = 0;
	schema->docGrammar.rule = NULL;
	schema->simpleTypeTable.count = 0;
	schema->simpleTypeTable.sType = NULL;
	schema->grammarTable.count = 0;
	schema->grammarTable.grammar = NULL;
	schema->enumTable.count = 0;
	schema->enumTable.enumDef = NULL;

	/* Create and initialize initial string table entries */
	tmp_err_code = createDynArray(&schema->uriTable.dynArray, sizeof(UriEntry), DEFAULT_URI_ENTRIES_NUMBER);
	if(tmp_err_code != ERR_OK)
	{
		freeAllocList(&schema->memList);
		return tmp_err_code;
	}

	tmp_err_code = createUriTableEntries(&schema->uriTable, initializationType != INIT_SCHEMA_SCHEMA_LESS_MODE);
	if(tmp_err_code != ERR_OK)
	{
		freeAllocList(&schema->memList);
		return tmp_err_code;
	}

	if(initializationType == INIT_SCHEMA_SCHEMA_ENABLED)
	{
		/* Create and initialize enumDef table */
		tmp_err_code = createDynArray(&schema->enumTable.dynArray, sizeof(EnumDefinition), DEFAULT_ENUM_TABLE);
		if(tmp_err_code != ERR_OK)
		{
			freeAllocList(&schema->memList);
			return tmp_err_code;
		}
	}

	/* Create the schema grammar table */
	tmp_err_code = createDynArray(&schema->grammarTable.dynArray, sizeof(EXIGrammar), DEFAULT_GRAMMAR_TABLE);
	if(tmp_err_code != ERR_OK)
	{
		freeAllocList(&schema->memList);
		return tmp_err_code;
	}

	if(initializationType != INIT_SCHEMA_SCHEMA_LESS_MODE)
	{
		/* Create and initialize simple type table */
		tmp_err_code = createDynArray(&schema->simpleTypeTable.dynArray, sizeof(SimpleType), DEFAULT_SIMPLE_GRAMMAR_TABLE);
		if(tmp_err_code != ERR_OK)
		{
			freeAllocList(&schema->memList);
			return tmp_err_code;
		}

		tmp_err_code = createBuiltInTypesDefinitions(&schema->simpleTypeTable, &schema->memList);
		if(tmp_err_code != ERR_OK)
		{
			freeAllocList(&schema->memList);
			return tmp_err_code;
		}

		// Must be done after createBuiltInTypesDefinitions()
		tmp_err_code = generateBuiltInTypesGrammars(schema);
		if(tmp_err_code != ERR_OK)
		{
			freeAllocList(&schema->memList);
		}

		schema->staticGrCount = SIMPLE_TYPE_COUNT;
	}

	return tmp_err_code;
}
예제 #9
0
errorCode createProtoGrammar(Index rulesDim, ProtoGrammar* pg)
{
	pg->contentIndex = 0;

	return createDynArray(&pg->dynArray, sizeof(ProtoRuleEntry), rulesDim);
}
예제 #10
0
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;
}