2 * @file BinaryCompare.cpp
4 * @brief Implementation file for BinaryCompare
8 #include "BinaryCompare.h"
10 #include "PathContext.h"
11 #include "IAbortable.h"
14 namespace CompareEngines
17 BinaryCompare::BinaryCompare() : m_piAbortable(nullptr)
21 BinaryCompare::~BinaryCompare() = default;
24 * @brief Set Abortable-interface.
25 * @param [in] piAbortable Pointer to abortable interface.
27 void BinaryCompare::SetAbortable(const IAbortable * piAbortable)
29 m_piAbortable = const_cast<IAbortable*>(piAbortable);
32 static int compare_files(const String& file1, const String& file2, IAbortable *piAbortable)
34 const size_t bufsize = 1024 * 256;
36 int fd1 = -1, fd2 = -1;
38 cio::tsopen_s(&fd1, file1, O_BINARY | O_RDONLY, _SH_DENYNO, _S_IREAD);
39 cio::tsopen_s(&fd2, file2, O_BINARY | O_RDONLY, _SH_DENYNO, _S_IREAD);
40 if (fd1 != -1 && fd2 != -1)
44 if (piAbortable && piAbortable->ShouldAbort())
46 code = DIFFCODE::CMPABORT;
51 int size1 = cio::read_i(fd1, buf1, sizeof(buf1));
52 int size2 = cio::read_i(fd2, buf2, sizeof(buf2));
53 if (size1 <= 0 || size2 <= 0)
55 if (size1 < 0 || size2 < 0)
56 code = DIFFCODE::CMPERR;
57 else if (size1 == size2)
58 code = DIFFCODE::SAME;
60 code = DIFFCODE::DIFF;
63 if (size1 != size2 || memcmp(buf1, buf2, size1) != 0)
65 code = DIFFCODE::DIFF;
72 code = DIFFCODE::CMPERR;
83 * @brief Compare two specified files, byte-by-byte
84 * @param [in] di Diffitem info.
87 int BinaryCompare::CompareFiles(const PathContext& files, const DIFFITEM &di) const
89 switch (files.GetSize())
92 // If the file size is 0, don't immediately assume that there is a difference even if the files have different sizes, because of possible symlinks.
93 return (di.diffFileInfo[0].size != di.diffFileInfo[1].size &&
94 di.diffFileInfo[0].size != 0 && di.diffFileInfo[1].size != 0) ?
95 DIFFCODE::DIFF : compare_files(files[0], files[1], m_piAbortable);
97 unsigned code10 = (di.diffFileInfo[1].size != di.diffFileInfo[0].size &&
98 di.diffFileInfo[1].size != 0 && di.diffFileInfo[0].size != 0) ?
99 DIFFCODE::DIFF : compare_files(files[1], files[0], m_piAbortable);
100 unsigned code12 = (di.diffFileInfo[1].size != di.diffFileInfo[2].size &&
101 di.diffFileInfo[1].size != 0 && di.diffFileInfo[2].size != 0) ?
102 DIFFCODE::DIFF : compare_files(files[1], files[2], m_piAbortable);
103 unsigned code02 = DIFFCODE::SAME;
104 if (code10 == DIFFCODE::SAME && code12 == DIFFCODE::SAME)
105 return DIFFCODE::SAME;
106 else if (code10 == DIFFCODE::SAME && code12 == DIFFCODE::DIFF)
107 return DIFFCODE::DIFF | DIFFCODE::DIFF3RDONLY;
108 else if (code10 == DIFFCODE::DIFF && code12 == DIFFCODE::SAME)
109 return DIFFCODE::DIFF | DIFFCODE::DIFF1STONLY;
110 else if (code10 == DIFFCODE::DIFF && code12 == DIFFCODE::DIFF)
112 code02 = (di.diffFileInfo[0].size != di.diffFileInfo[2].size &&
113 di.diffFileInfo[0].size != 0 && di.diffFileInfo[2].size != 0) ?
114 DIFFCODE::DIFF : compare_files(files[0], files[2], m_piAbortable);
115 if (code02 == DIFFCODE::SAME)
116 return DIFFCODE::DIFF | DIFFCODE::DIFF2NDONLY;
118 if (code10 == DIFFCODE::CMPERR || code12 == DIFFCODE::CMPERR || code02 == DIFFCODE::CMPERR)
119 return DIFFCODE::CMPERR;
120 return DIFFCODE::DIFF;
122 return DIFFCODE::CMPERR;
125 } // namespace CompareEngines