Beispiel #1
0
void SearchTree::compile()
{
    assert(!m_ready);

    // at the top level assign root as the failure node
    std::queue<SearchNode*> nodesByLevel;
    for (std::size_t i = 0; i < m_rootNode.getNextSize(); ++i)
    {
        SearchNode* next = m_rootNode.getNext(static_cast<const unsigned char>(i));
        if (!next)
        {
            m_rootNode.setNext(static_cast<const unsigned char>(i), &m_rootNode);
        }
        else
        {
            next->setFailure(&m_rootNode);
            nodesByLevel.push(next);
        }
    }

    // now loop through all levels computing failure nodes. Push more on as needed
    while (!nodesByLevel.empty())
    {
        SearchNode* currentNode = nodesByLevel.front();
        for (std::size_t i = 0; i < currentNode->getNextSize(); ++i)
        {
            SearchNode* next = currentNode->getNext(static_cast<const unsigned char>(i));
            if (next)
            {
                nodesByLevel.push(next);
                next->setFailure(
                    currentNode->getFailure()->getNext(
                        static_cast<const unsigned char>(i)));
                if (!next->getFailure()->getStoredData().empty())
                {
                    next->addReturnValues(next->getFailure()->getStoredData());
                }
            }
            else
            {
                currentNode->setNext(static_cast<const unsigned char>(i),
                                     currentNode->getFailure()->getNext(
                                         static_cast<const unsigned char>(i)));
            }
        }
        nodesByLevel.pop();
    }

    m_ready = true;
}
Beispiel #2
0
std::set<const char*> SearchTree::findOffsets(const char* const p_inputString,
                                              const std::size_t p_inputLength)
{
    std::set<const char*> returnValue;
    SearchNode* currentNode = &m_rootNode;
    const char* end = p_inputString + p_inputLength;
    for (const char* start = p_inputString; start < end; ++start)
    {
        currentNode = currentNode->getNext(*start);
        if (!currentNode->getStoredData().empty())
        {
            returnValue.insert(start - 3);
        }
    }
    return returnValue;
}
Beispiel #3
0
std::set<void*> SearchTree::search(const unsigned char* const p_inputString,
                                          const std::size_t p_inputLength)
{
    assert(m_ready && p_inputString != NULL);

    std::set<void*> returnValue;
    SearchNode* currentNode = &m_rootNode;
    const unsigned char* end = p_inputString + p_inputLength;
    for (const unsigned char* start = p_inputString; start < end; ++start)
    {
        currentNode = currentNode->getNext(*start);
        if (!currentNode->getStoredData().empty())
        {
            const std::set<void*>& mergeThis(currentNode->getStoredData());
            returnValue.insert(mergeThis.begin(), mergeThis.end());
        }
    }

    return returnValue;
}