fElemMap = new QName[fLeafCount];
fElemMapType = new int[fLeafCount];
fElemMapSize = 0;
for (int outIndex = 0; outIndex < fLeafCount; outIndex++)
{
fElemMap[outIndex] = new QName();
if ( (fLeafListType[outIndex] & 0x0f) != 0 ) {
if (fLeafNameTypeVector == null) {
fLeafNameTypeVector = new ContentLeafNameTypeVector();
}
}
// Get the current leaf's element index
final QName element = fLeafList[outIndex].getElement();
// See if the current leaf node's element index is in the list
int inIndex = 0;
for (; inIndex < fElemMapSize; inIndex++)
{
if (fDTD) {
if (fElemMap[inIndex].rawname == element.rawname) {
break;
}
}
else {
if (fElemMap[inIndex].uri == element.uri &&
fElemMap[inIndex].localpart == element.localpart &&
fElemMapType[inIndex] == fLeafListType[outIndex] )
break;
}
}
// If it was not in the list, then add it, if not the EOC node
if (inIndex == fElemMapSize) {
//if (fDTD) {
// fElemMap[fElemMapSize].setValues(-1, element.rawname, element.rawname, -1);
//}
//else {
fElemMap[fElemMapSize].setValues(element);
//}
fElemMapType[fElemMapSize] = fLeafListType[outIndex];
fElemMapSize++;
}
}
// set up the fLeafNameTypeVector object if there is one.
if (fLeafNameTypeVector != null) {
fLeafNameTypeVector.setValues(fElemMap, fElemMapType, fElemMapSize);
}
//
// Next lets create some arrays, some that that hold transient
// information during the DFA build and some that are permament.
// These are kind of sticky since we cannot know how big they will
// get, but we don't want to use any Java collections because of
// performance.
//
// Basically they will probably be about fLeafCount*2 on average,
// but can be as large as 2^(fLeafCount*2), worst case. So we start
// with fLeafCount*4 as a middle ground. This will be very unlikely
// to ever have to expand, though it if does, the overhead will be
// somewhat ugly.
//
int curArraySize = fLeafCount * 4;
CMStateSet[] statesToDo = new CMStateSet[curArraySize];
fFinalStateFlags = new boolean[curArraySize];
fTransTable = new int[curArraySize][];
//
// Ok we start with the initial set as the first pos set of the
// head node (which is the seq node that holds the content model
// and the EOC node.)
//
CMStateSet setT = fHeadNode.firstPos();
//
// Init our two state flags. Basically the unmarked state counter
// is always chasing the current state counter. When it catches up,
// that means we made a pass through that did not add any new states
// to the lists, at which time we are done. We could have used a
// expanding array of flags which we used to mark off states as we
// complete them, but this is easier though less readable maybe.
//
int unmarkedState = 0;
int curState = 0;
//
// Init the first transition table entry, and put the initial state
// into the states to do list, then bump the current state.
//
fTransTable[curState] = makeDefStateList();
statesToDo[curState] = setT;
curState++;
//
// Ok, almost done with the algorithm... We now enter the
// loop where we go until the states done counter catches up with
// the states to do counter.
//
while (unmarkedState < curState)
{
//
// Get the first unmarked state out of the list of states to do.
// And get the associated transition table entry.
//
setT = statesToDo[unmarkedState];
int[] transEntry = fTransTable[unmarkedState];
// Mark this one final if it contains the EOC state
fFinalStateFlags[unmarkedState] = setT.getBit(fEOCPos);
// Bump up the unmarked state count, marking this state done
unmarkedState++;
// Loop through each possible input symbol in the element map
CMStateSet newSet = null;
for (int elemIndex = 0; elemIndex < fElemMapSize; elemIndex++)
{
//
// Build up a set of states which is the union of all of
// the follow sets of DFA positions that are in the current
// state. If we gave away the new set last time through then
// create a new one. Otherwise, zero out the existing one.
//
if (newSet == null)
newSet = new CMStateSet(fLeafCount);
else
newSet.zeroBits();
for (int leafIndex = 0; leafIndex < fLeafCount; leafIndex++)
{
// If this leaf index (DFA position) is in the current set...
if (setT.getBit(leafIndex))
{
//
// If this leaf is the current input symbol, then we
// want to add its follow list to the set of states to
// transition to from the current state.
//
final QName leaf = fLeafList[leafIndex].getElement();
final QName element = fElemMap[elemIndex];
if (fDTD) {
if (leaf.rawname == element.rawname) {
newSet.union(fFollowList[leafIndex]);
}
}