forked from WinMerge/winmerge
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDiffItemList.cpp
213 lines (194 loc) · 5.39 KB
/
DiffItemList.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
/**
* @file DiffItemList.cpp
*
* @brief Implementation of DiffItemList
*/
#include "pch.h"
#include "DiffItemList.h"
#include <cassert>
/**
* @brief Constructor
*/
DiffItemList::DiffItemList() : m_pRoot(nullptr)
{
}
/**
* @brief Destructor
*/
DiffItemList::~DiffItemList()
{
RemoveAll();
}
/**
* @brief Add new diffitem to structured DIFFITEM tree.
* @param [in] par Parent item, or `nullptr` if no parent.
* @return Pointer to the added item.
*/
DIFFITEM *DiffItemList::AddNewDiff(DIFFITEM *par)
{
DIFFITEM *p = new DIFFITEM;
if (par == nullptr)
{
// if there is no `parent`, this item becomes a child of `m_pRoot`
assert(m_pRoot != nullptr);
m_pRoot->AddChildToParent(p);
}
else
par->AddChildToParent(p);
return p;
}
/**
* @brief Empty structured DIFFITEM tree
*/
void DiffItemList::RemoveAll()
{
delete m_pRoot;
m_pRoot = nullptr;
}
void DiffItemList::InitDiffItemList()
{
assert(m_pRoot == nullptr);
m_pRoot = new DIFFITEM;
}
void DiffItemList::ClearAllAdditionalProperties()
{
assert(m_pRoot != nullptr);
for (DIFFITEM* p = GetFirstDiffPosition(); p != nullptr; p = p->GetFwdSiblingLink())
p->ClearAllAdditionalProperties();
}
/**
* @brief Get position of first item in structured DIFFITEM tree
*/
DIFFITEM *DiffItemList::GetFirstDiffPosition() const
{
return GetFirstChildDiffPosition(m_pRoot);
}
/**
* @brief Get position of first child item in structured DIFFITEM tree
* @param [in] par Position of parent diff item (maybe `nullptr`)
* @return Position of first child item (or `nullptr` if no children)
*/
DIFFITEM *DiffItemList::GetFirstChildDiffPosition(const DIFFITEM *par) const
{
if (par == nullptr)
{
assert(m_pRoot != nullptr);
return m_pRoot->GetFirstChild();
}
else
return par->GetFirstChild();
}
/**
* @brief Get position of next item in structured DIFFITEM tree
* @param [in,out] diffpos Position of current item, updated to next item position
* @return Diff Item (by reference) in current position
*/
const DIFFITEM &DiffItemList::GetNextDiffPosition(DIFFITEM *&diffpos) const
{
DIFFITEM *p = diffpos;
if (diffpos->HasChildren())
{
diffpos = GetFirstChildDiffPosition(diffpos);
}
else
{
DIFFITEM *cur = diffpos;
do
{
diffpos = cur->GetFwdSiblingLink();
cur = cur->GetParentLink();
assert(cur != nullptr);
} while (diffpos == nullptr && cur->HasParent());
}
return *p;
}
/**
* @brief Get position of next item in structured DIFFITEM tree
* @param [in,out] diffpos Position of current item, updated to next item position
* @return Diff Item (by reference) in current position
*/
DIFFITEM &DiffItemList::GetNextDiffRefPosition(DIFFITEM *&diffpos)
{
return (DIFFITEM &)GetNextDiffPosition(diffpos);
}
/**
* @brief Get position of next sibling item in structured DIFFITEM tree
* @param [in,out] diffpos Position of current item, updated to next sibling item position
* @return Diff Item (by reference) in current position
*/
const DIFFITEM &DiffItemList::GetNextSiblingDiffPosition(DIFFITEM *&diffpos) const
{
DIFFITEM *p = diffpos;
diffpos = p->GetFwdSiblingLink();
assert(p==nullptr || diffpos==nullptr || p->GetParentLink() == diffpos->GetParentLink());
assert(p==nullptr || p->HasParent());
return *p;
}
/**
* @brief Get position of next sibling item in structured DIFFITEM tree
* @param [in,out] diffpos Position of current item, updated to next sibling item position
* @return Diff Item (by reference) in current position
*/
DIFFITEM &DiffItemList::GetNextSiblingDiffRefPosition(DIFFITEM *&diffpos)
{
return (DIFFITEM &)GetNextSiblingDiffPosition(diffpos);
}
/**
* @brief Alter some bit flags of the diffcode.
*
* Examples:
* SetDiffStatusCode(pos, DIFFCODE::SAME, DIFFCODE::COMPAREFLAGS)
* changes the comparison result to be the same.
*
* SetDiffStatusCode(pos, DIFFCODE::BOTH, DIFFCODE::SIDEFLAG)
* changes the side status to be both (sides).
*
* SetDiffStatusCode(pos, DIFFCODE::SAME+DIFFCODE::BOTH, DIFFCODE::COMPAREFLAGS+DIFFCODE::SIDEFLAG);
* changes the comparison result to be the same and the side status to be both
*/
void DiffItemList::SetDiffStatusCode(DIFFITEM *diffpos, unsigned diffcode, unsigned mask)
{
assert(diffpos != nullptr);
DIFFITEM &di = GetDiffRefAt(diffpos);
assert( ((~mask) & diffcode) == 0 ); // make sure they only set flags in their mask
di.diffcode.diffcode &= (~mask); // remove current data
di.diffcode.diffcode |= diffcode; // add new data
}
/**
* @brief Update difference counts.
*/
void DiffItemList::SetDiffCounts(DIFFITEM *diffpos, unsigned diffs, unsigned ignored)
{
assert(diffpos != nullptr);
DIFFITEM &di = GetDiffRefAt(diffpos);
di.nidiffs = ignored; // see StoreDiffResult() in DirScan.cpp
di.nsdiffs = diffs;
}
/**
* @brief Returns item's custom (user) flags.
* @param [in] diffpos Position of item.
* @return Custom flags from item.
*/
unsigned DiffItemList::GetCustomFlags1(DIFFITEM *diffpos) const
{
assert(diffpos != nullptr);
const DIFFITEM &di = GetDiffAt(diffpos);
return di.customFlags;
}
/**
* @brief Sets item's custom (user) flags.
* @param [in] diffpos Position of item.
* @param [in] flag Value of flag to set.
*/
void DiffItemList::SetCustomFlags1(DIFFITEM *diffpos, unsigned flag)
{
assert(diffpos != nullptr);
DIFFITEM &di = GetDiffRefAt(diffpos);
di.customFlags = flag;
}
void DiffItemList::Swap(int idx1, int idx2)
{
assert(m_pRoot != nullptr);
for (DIFFITEM *p = GetFirstDiffPosition(); p != nullptr; p = p->GetFwdSiblingLink())
p->Swap(idx1, idx2);
}