int32 * TextbookBoyerMooreSetup<C>::GetGoodSuffix(ArenaAllocator* allocator, const Char * pat, CharCount patLen, int skip)
    {
        // pat offset q |-> longest prefix of pat which is a proper suffix of pat[0..q]
        // (thanks to equivalence classes being in canonical order we only need to look at the first
        //  character of each skip grouping in the pattern)
        int32* prefix = AnewArray(allocator, int32, patLen);
        prefix[0] = 0;
        int32 k = 0;
        for (CharCount q = 1; q < patLen; q++)
        {
            while (k > 0 && pat[k * skip] != pat[q * skip])
                k = prefix[k - 1];
            if (pat[k * skip] == pat[q * skip])
                k++;
            prefix[q] = k;
        }

        // As above, but for rev(pat)
        int32* revPrefix = AnewArray(allocator, int32, patLen);
        revPrefix[0] = 0;
        k = 0;
        for (CharCount q = 1; q < patLen; q++)
        {
            while (k > 0 && pat[(patLen - k - 1) * skip] != pat[(patLen - q - 1) * skip])
                k = revPrefix[k - 1];
            if (pat[(patLen - k - 1) * skip] == pat[(patLen - q - 1) * skip])
                k++;
            revPrefix[q] = k;
        }

        // pat prefix length l |-> least shift s.t. pat[0..l-1] is not mismatched
        int32 * goodSuffix = AnewArray(allocator, int32, patLen + 1);
        for (CharCount j = 0; j <= patLen; j++)
            goodSuffix[j] = patLen - prefix[patLen - 1];
        for (CharCount l = 1; l <= patLen; l++)
        {
            CharCount j = patLen - revPrefix[l - 1];
            int32 s = l - revPrefix[l - 1];
            if (goodSuffix[j] > s)
                goodSuffix[j] = s;
        }
        // shift above one to the left
        for (CharCount j = 0; j < patLen; j++)
            goodSuffix[j] = goodSuffix[j + 1];

        AdeleteArray(allocator, patLen, prefix);
        AdeleteArray(allocator, patLen, revPrefix);

        return goodSuffix;
    }
    void TextbookBoyerMooreWithLinearMap<C>::FreeBody(ArenaAllocator* allocator, CharCount patLen)
    {
        if(goodSuffix)
        {
            AdeleteArray(allocator, patLen + 1, goodSuffix);
#if DBG
            goodSuffix = 0;
#endif
        }
    }
示例#3
0
    void RuntimeCharTrie::FreeBody(ArenaAllocator* allocator)
    {
        for (int i = 0; i < count; i++)
            children[i].node.FreeBody(allocator);
        if (count > 0)
            AdeleteArray(allocator, count, children);
#if DBG
        count = 0;
        children = 0;
#endif
    }
    void TextbookBoyerMoore<C>::FreeBody(ArenaAllocator* allocator, CharCount patLen)
    {
        if(goodSuffix)
        {
            AdeleteArray(allocator, patLen + 1, goodSuffix);
#if DBG
            goodSuffix = 0;
#endif
        }
        lastOccurrence.FreeBody(allocator);
    }
示例#5
0
void JSONScanner::BuildUnescapedString(bool shouldSkipLastCharacter)
{
    AssertMsg(this->allocator != nullptr, "We must have built the allocator");
    AssertMsg(this->currentRangeCharacterPairList != nullptr, "We must have built the currentRangeCharacterPairList");
    AssertMsg(this->currentRangeCharacterPairList->Count() > 0, "We need to build the current string only because we have escaped characters");

    // Step 1: Ensure the buffer has sufficient space
    int requiredSize = this->GetCurrentStringLen();
    if (requiredSize > this->stringBufferLength)
    {
        if (this->stringBuffer)
        {
            AdeleteArray(this->allocator, this->stringBufferLength, this->stringBuffer);
            this->stringBuffer = nullptr;
        }

        this->stringBuffer = AnewArray(this->allocator, char16, requiredSize);
        this->stringBufferLength = requiredSize;
    }

    // Step 2: Copy the data to the buffer
    int totalCopied = 0;
    char16* begin_copy = this->stringBuffer;
    int lastCharacterIndex = this->currentRangeCharacterPairList->Count() - 1;
    for (int i = 0; i <= lastCharacterIndex; i++)
    {
        RangeCharacterPair data = this->currentRangeCharacterPairList->Item(i);
        int charactersToCopy = data.m_rangeLength;
        js_wmemcpy_s(begin_copy, charactersToCopy, this->inputText + data.m_rangeStart, charactersToCopy);
        begin_copy += charactersToCopy;
        totalCopied += charactersToCopy;

        if (i == lastCharacterIndex && shouldSkipLastCharacter)
        {
            continue;
        }

        *begin_copy = data.m_char;
        begin_copy++;
        totalCopied++;
    }

    if (totalCopied != requiredSize)
    {
        OUTPUT_TRACE_DEBUGONLY(Js::JSONPhase, _u("BuildUnescapedString(): allocated size = %d != copying size %d\n"), requiredSize, totalCopied);
        AssertMsg(totalCopied == requiredSize, "BuildUnescapedString(): The allocated size and copying size should match.");
    }

    OUTPUT_TRACE_DEBUGONLY(Js::JSONPhase, _u("BuildUnescapedString(): unescaped string as '%.*s'\n"), GetCurrentStringLen(), this->stringBuffer);
}