void KisMemoryWindowTest::testWindow()
{
    KisMemoryWindow memory(QString(), 1024);

    quint8 oddValue = 0xee;
    const quint8 chunkLength = 10;

    quint8 oddBuf[chunkLength];
    memset(oddBuf, oddValue, chunkLength);


    KisChunkData chunk1(0, chunkLength);
    KisChunkData chunk2(1025, chunkLength);

    quint8 *ptr;

    ptr = memory.getWriteChunkPtr(chunk1);
    memcpy(ptr, oddBuf, chunkLength);

    ptr = memory.getWriteChunkPtr(chunk2);
    memcpy(ptr, oddBuf, chunkLength);

    ptr = memory.getReadChunkPtr(chunk2);
    QVERIFY(!memcmp(ptr, oddBuf, chunkLength));

    ptr = memory.getWriteChunkPtr(chunk1);
    QVERIFY(!memcmp(ptr, oddBuf, chunkLength));
}
Exemple #2
0
bool compareBlocks(HWND view1, HWND view2, const UserSettings& settings, diff_info& blockDiff1, diff_info& blockDiff2)
{
	diff_info* pBlockDiff1 = &blockDiff1;
	diff_info* pBlockDiff2 = &blockDiff2;

	if (blockDiff1.len > blockDiff2.len)
	{
		std::swap(view1, view2);
		std::swap(pBlockDiff1, pBlockDiff2);
	}

	chunk_info chunk1(pBlockDiff1->off, pBlockDiff1->len);
	chunk_info chunk2(pBlockDiff2->off, pBlockDiff2->len);

	getWords(view1, settings, chunk1);
	getWords(view2, settings, chunk2);

	// Compare the two chunks
	const std::vector<diff_info> chunkDiff = DiffCalc<Word>(chunk1.words, chunk2.words)();

	const int chunkDiffSize = static_cast<int>(chunkDiff.size());

	if (chunkDiffSize == 0)
		return false;

	std::vector<std::vector<int>> linesConvergence(chunk1.lineCount, std::vector<int>(chunk2.lineCount, 0));

	// Use the MATCH results to synchronize line numbers (count the match length of each line)
	int wordOffset = 0;
	for (int i = 0; i < chunkDiffSize; ++i)
	{
		const diff_info& cd = chunkDiff[i];

		if (cd.type == diff_type::DIFF_DELETE)
		{
			wordOffset -= cd.len;
		}
		else if (cd.type == diff_type::DIFF_INSERT)
		{
			wordOffset += cd.len;
		}
		else // diff_type::DIFF_MATCH
		{
			for (int wordIdx = cd.off; wordIdx < (cd.off + cd.len); ++wordIdx)
			{
				const Word& word1 = chunk1.words[wordIdx];
				const Word& word2 = chunk2.words[wordIdx + wordOffset];

				if (word1.type != charType::SPACECHAR)
					linesConvergence[word1.line][word2.line] += word1.length;
			}
		}
	}

	// Select the line with the most matches (as length)
	for (int line1 = 0; line1 < chunk1.lineCount; ++line1)
	{
		if (pBlockDiff1->isMoved(line1))
			continue;

		int maxConvergence = 0;
		int line2 = 0;

		for (int i = 0; i < chunk2.lineCount; ++i)
		{
			if (!pBlockDiff2->isMoved(i) && linesConvergence[line1][i] > maxConvergence)
			{
				line2 = i;
				maxConvergence = linesConvergence[line1][i];
			}
		}

		// Make sure that the line is matched and the other line is not already matched
		if (maxConvergence == 0 || chunk2.lineMappings[line2] != -1)
			continue;

		int line1Size = 0;
		for (int i = chunk1.lineStartWordIdx[line1]; i < chunk1.lineEndWordIdx[line1]; ++i)
		{
			const Word& word1 = chunk1.words[i];

			if (word1.type != charType::SPACECHAR)
				line1Size += word1.length;
		}

		// Is enough portion of the line matched to be significant?
		if (line1Size && maxConvergence > (line1Size / 3))
		{
			chunk1.lineMappings[line1] = line2;
			chunk2.lineMappings[line2] = line1;
		}
	}

	compareLines(*pBlockDiff1, *pBlockDiff2, chunk1, chunk2);

	return true;
}
Exemple #3
0
bool compareWords(diff_edit& e1, diff_edit& e2, const DocLines_t& doc1, const DocLines_t& doc2, bool IgnoreSpaces)
{
	unsigned int i, j;

	chunk_info chunk1(e1.off, e1.len);
	chunk_info chunk2(e2.off, e2.len);

	getWords(doc1, chunk1, IgnoreSpaces);
	getWords(doc2, chunk2, IgnoreSpaces);

	// Compare the two chunks
	std::vector<diff_edit> diff = DiffCalc<Word>(chunk1.words, chunk2.words)();

	chunk1.changes.reset(new varray<diff_change>);
	chunk2.changes.reset(new varray<diff_change>);

	std::vector<std::vector<int>> lineMappings1(chunk1.lineCount);

	for (i = 0; i < chunk1.lineCount; ++i)
		lineMappings1[i].resize(chunk2.lineCount, 0);

	// Use the MATCH results to synchronize line numbers
	// count how many are on each line, then select the line with the most matches
	const std::size_t diffSize = diff.size();

	int offset = 0;
	for (i = 0; i < diffSize; ++i)
	{
		diff_edit& e = diff[i];

		if (e.op == DIFF_DELETE)
		{
			offset -= e.len;
		}
		else if (e.op == DIFF_INSERT)
		{
			offset += e.len;
		}
		else
		{
			for (unsigned int index = e.off; index < (e.off + e.len); ++index)
			{
				Word *word1 = &chunk1.words[index];
				Word *word2 = &chunk2.words[index + offset];

				if (word1->type != SPACECHAR && word1->type != EOLCHAR)
				{
					int line1a = word1->line;
					int line2a = word2->line;
					lineMappings1[line1a][line2a] += word1->length;
				}
			}
		}
	}

	// go through each line, and select the line with the highest strength
	for (i = 0; i < chunk1.lineCount; ++i)
	{
		int line = -1;
		int max = 0;

		for (j = 0; j <chunk2.lineCount; ++j)
		{
			if (lineMappings1[i][j] > max && (e2.moves.empty() || e2.moves[j] == -1))
			{
				line = j;
				max = lineMappings1[i][j];
			}
		}

		// make sure that the line isn't already matched to another line,
		// and that enough of the line is matched to be significant
		const int size = doc1[e1.off + i].size();

		if (line != -1 && chunk2.lineMappings[line] == -1 && max > (size / 3) &&
				(e1.moves.empty() || e1.moves[i] == -1))
		{
			chunk1.lineMappings[i] = line;
			chunk2.lineMappings[line] = i;
		}
	}

	// find all the differences between the lines
	chunk1.changeCount = 0;
	chunk2.changeCount = 0;

	for (i = 0; i < diffSize; ++i)
	{
		diff_edit& e = diff[i];

		if (e.op == DIFF_DELETE)
		{
			// Differences for Doc 1
			checkWords(e, chunk1, chunk2);
		}
		else if (e.op == DIFF_INSERT)
		{
			// Differences for Doc2
			checkWords(e, chunk2, chunk1);
		}
	}

	e1.changeCount = chunk1.changeCount;
	e1.changes = chunk1.changes;
	e2.changeCount = chunk2.changeCount;
	e2.changes = chunk2.changes;

	return (chunk1.changeCount + chunk2.changeCount > 0);
}