-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmanualdiff.cpp
More file actions
130 lines (107 loc) · 3.39 KB
/
manualdiff.cpp
File metadata and controls
130 lines (107 loc) · 3.39 KB
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
#include "manualdiff.h"
#include "ipv4.h"
#include "ipv4int.h"
TextEditState ManualDiff::fixup_inserted_separator() const
{
TextEditState result = m_cur;
const auto inserted_char = ch;
const int inserted_index = index;
if (!inserted || inserted_char != IpV4::octet_separator)
throw std::runtime_error("can't fixup the input");
const IpV4Int prev_ip{m_prev.val};
const bool is_the_first_separator = prev_ip.is_valid();
if (m_prev.val.isEmpty())
result.val = "...";
else if (is_the_first_separator)
{
if(!prev_ip.can_insert_first_separtor_to(inserted_index))
throw std::runtime_error("can't fixup the input");
result.val = prev_ip.insert_separators(inserted_index);
}
else
{
result = m_prev;
result.move_separator_to(inserted_index);
}
return result;
}
/* move the cursor (0.|0.0.0 -> 0.0|.0.0)
* instead inserting invalid zero (0.|0.0.0 -> 0.0|0.0.0)
*/
TextEditState ManualDiff::fixup_inserted_zero() const
{
TextEditState result = m_cur;
if (!inserted || ch != '0')
throw std::runtime_error("can't fixup the input");
const auto result_val_beg = result.val.begin();
const auto result_val_end = result.val.end();
const auto it = result_val_beg + index;
const auto it_next = it+1;
const auto it_next2 = it+2;
if ( // is the first digit inserted to the octet
(it == result_val_beg || *(it-1) == IpV4::octet_separator)
&& // and next digit is zero too
(it_next != result_val_end && *it_next == '0')
&& // and next digit is last digit in the octet
(it_next2 == result_val_end || *it_next2 == IpV4::octet_separator)
)
result.val.erase(it);
return result;
}
bool ManualDiff::valid() const
{
return index >= 0;
}
void ManualDiff::init_removed()
{
const int removed_char_index = m_cur.pos;
if (removed_char_index <= m_prev.val.length() -1)
{
const auto _removed_char = m_prev.val.at(removed_char_index);
QString temp = QString(m_cur.val);
temp.insert(m_cur.pos, _removed_char);
if (temp == m_prev.val)
{
removed = true;
index = removed_char_index;
remove_dir = m_cur.pos != m_prev.pos ? Backward : Forward;
ch = _removed_char;
}
}
}
void ManualDiff::init_inserted()
{
const int inserted_char_index = m_prev.pos;
if (inserted_char_index <= m_cur.val.length() -1)
{
const auto inserted_char = m_cur.val.at(inserted_char_index);
QString temp(m_cur.val);
temp.erase(temp.cbegin() + inserted_char_index);
if (temp == m_prev.val)
{
inserted = true;
index = inserted_char_index;
ch = inserted_char;
}
}
}
ManualDiff::ManualDiff(const TextEditState &prev, const TextEditState &cur)
: m_prev(prev), m_cur(cur)
{
init_removed();
init_inserted();
}
TextEditState ManualDiff::fixup_separators_count() const
{
TextEditState result = m_cur;
if (inserted && ch == IpV4::octet_separator)
return fixup_inserted_separator();
else if (removed && ch == IpV4::octet_separator)
{
result.val = m_prev.val;
result.pos += remove_dir == Backward ? 0 : 1;
}
else if (removed && ch != IpV4::octet_separator && result.val == "...")
result.val.clear();
return result;
}