const int FARSDfa_pack_triv::GetDest()

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;
}