in blingfireclient.library/src/FARSDfa_pack_triv.cpp [141:399]
const int FARSDfa_pack_triv::GetDest (const int State, const int Iw) const
{
if (0 > State) {
return -1;
}
int NewIw;
if (m_RemapIws) {
NewIw = m_iw2iw.GetNewIw (Iw);
if (-1 == NewIw)
return -1;
} else {
NewIw = Iw;
}
const unsigned char * pCurrPtr = m_pAutImage + State;
const unsigned char info = *pCurrPtr;
// skip info
pCurrPtr++;
const int IwSize = ((info & 0x18) >> 3) + 1;
DebugLogAssert (sizeof (char) <= (unsigned int) IwSize && \
sizeof (int) >= (unsigned int) IwSize);
const char TrType = info & 0x07;
switch (TrType) {
// prallel arrays
case FAFsmConst::TRS_PARA:
{
int Idx;
unsigned int DstCount;
if (sizeof (char) == IwSize) {
// check whether NewIw is out of bounds for this state
if (0xFFFFFF00 & NewIw) {
return -1;
}
// as DstCount - 1 was actually encoded
DstCount = 1 + *pCurrPtr;
// skip DstCount
pCurrPtr += sizeof (char);
// find outgoing transition index, if any
const unsigned char * pIws = pCurrPtr;
Idx = FAFind_log (pIws, DstCount, (unsigned char) NewIw);
// skip Iws array
pCurrPtr += (DstCount * sizeof (char));
} else if (sizeof (short) == IwSize) {
// check whether NewIw is out of bounds for this state
if (0xFFFF0000 & NewIw) {
return -1;
}
// as DstCount - 1 was actually encoded
DstCount = 1 + *(const unsigned short *)pCurrPtr;
// skip DstCount
pCurrPtr += sizeof (short);
// find outgoing transition index, if any
const unsigned short * pIws = (const unsigned short*) pCurrPtr;
Idx = FAFind_log (pIws, DstCount, (unsigned short) NewIw);
// skip Iws array
pCurrPtr += (DstCount * sizeof (short));
} else {
DebugLogAssert (sizeof (int) == IwSize);
// as DstCount - 1 was actually encoded
DstCount = 1 + *(const unsigned int *)pCurrPtr;
// skip DstCount
pCurrPtr += sizeof (int);
// find outgoing transition index, if any
const unsigned int * pIws = (const unsigned int *) pCurrPtr;
Idx = FAFind_log (pIws, DstCount, (unsigned int) NewIw);
// skip Iws array
pCurrPtr += (DstCount * sizeof (int));
}
// transition with NewIw does not exist
if (-1 == Idx)
return -1;
// position pointer to the destination state
int Dst;
FADecodeDst_idx (pCurrPtr, Idx, Dst, m_DstSize);
return Dst;
} // of case
// Iw-index array
case FAFsmConst::TRS_IWIA:
{
unsigned int IwBase;
unsigned int IwMax;
FADecode_UC_US_UI(pCurrPtr, 0, IwBase, IwSize);
pCurrPtr += IwSize;
FADecode_UC_US_UI(pCurrPtr, 0, IwMax, IwSize);
pCurrPtr += IwSize;
if (NewIw < (int) IwBase || NewIw > (int) IwMax) {
return -1;
}
const int Idx = NewIw - IwBase;
// position pointer to the destination state
int Dst;
FADecodeDst_idx (pCurrPtr, Idx, Dst, m_DstSize);
// see whether transition does not exist
if (0 == Dst) {
return -1;
} else {
return Dst;
}
} // of case
// rangse if Iws
case FAFsmConst::TRS_RANGE:
{
int Idx;
unsigned int RangeCount;
if (sizeof (char) == IwSize) {
// check whether NewIw is out of bounds for this state
if (0xFFFFFF00 & NewIw) {
return -1;
}
// as RangeCount - 1 was actually encoded
RangeCount = 1 + *pCurrPtr;
// skip RangeCount
pCurrPtr += sizeof (char);
// find range index
const unsigned char * pFromIws = pCurrPtr;
Idx = FAFindEqualOrLess_log \
(pFromIws, RangeCount, (unsigned char) NewIw);
// smaller than smallest range beginning
if (-1 == Idx) {
return -1;
}
// skip FromIws array
pCurrPtr += (RangeCount * sizeof (char));
// find range index
const unsigned char * pToIws = pCurrPtr;
// the NewIw is outside the range
if (pToIws [Idx] < (unsigned char) NewIw) {
return -1;
}
// skip ToIws array
pCurrPtr += (RangeCount * sizeof (char));
} else if (sizeof (short) == IwSize) {
// check whether NewIw is out of bounds for this state
if (0xFFFF0000 & NewIw) {
return -1;
}
// as RangeCount - 1 was actually encoded
RangeCount = 1 + *(const unsigned short *)pCurrPtr;
// skip RangeCount
pCurrPtr += sizeof (short);
// find range index
const unsigned short * pFromIws = (const unsigned short*)pCurrPtr;
Idx = FAFindEqualOrLess_log \
(pFromIws, RangeCount, (unsigned short) NewIw);
// smaller than smallest range beginning
if (-1 == Idx) {
return -1;
}
// skip FromIws array
pCurrPtr += (RangeCount * sizeof (short));
// find range index
const unsigned short * pToIws = (const unsigned short*)pCurrPtr;
// the NewIw is outside the range
if (pToIws [Idx] < (unsigned short) NewIw) {
return -1;
}
// skip ToIws array
pCurrPtr += (RangeCount * sizeof (short));
} else {
DebugLogAssert (sizeof (int) == IwSize);
// as RangeCount - 1 was actually encoded
RangeCount = 1 + *(const unsigned int *)pCurrPtr;
// skip RangeCount
pCurrPtr += sizeof (int);
// find range index
const unsigned int * pFromIws = (const unsigned int*)pCurrPtr;
Idx = FAFindEqualOrLess_log \
(pFromIws, RangeCount, (unsigned int) NewIw);
// smaller than smallest range beginning
if (-1 == Idx) {
return -1;
}
// skip FromIws array
pCurrPtr += (RangeCount * sizeof (int));
// find range index
const unsigned int * pToIws = (const unsigned int*)pCurrPtr;
// the NewIw is outside the range
if (pToIws [Idx] < (unsigned int) NewIw) {
return -1;
}
// skip ToIws array
pCurrPtr += (RangeCount * sizeof (int));
}
// position pointer to the destination state
int Dst;
FADecodeDst_idx (pCurrPtr, Idx, Dst, m_DstSize);
return Dst;
}
// implicit transition
case FAFsmConst::TRS_IMPL:
{
// get output weight size code, 0 if there are no Ow
const int OwSizeCode = (info & 0x60) >> 5;
// convert size code into size in bytes
int OwSize = OwSizeCode;
if (3 == OwSizeCode) {
OwSize = sizeof (int);
}
// return destination state offset
if (sizeof (char) == IwSize) {
if (NewIw == *pCurrPtr)
return State + sizeof (char) + sizeof (char) + OwSize;
} else if (sizeof (short) == IwSize) {
if (NewIw == *(const unsigned short *)pCurrPtr)
return State + sizeof (char) + sizeof (short) + OwSize;
} else {
DebugLogAssert (sizeof (int) == IwSize);
if ((unsigned int) NewIw == *(const unsigned int *)pCurrPtr)
return State + sizeof (char) + sizeof (int) + OwSize;
}
return -1;
} // of case
}; // of switch (TrType)
DebugLogAssert (FAFsmConst::TRS_NONE == TrType);
return -1;
}