Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ISC Open Source Projects
Kea
Commits
57c61f2f
Commit
57c61f2f
authored
Jun 25, 2012
by
Mukund Sivaraman
Browse files
[2052] Add implementation and unit tests for dns::LabelSequence::compare()
parent
61fdb18f
Changes
6
Hide whitespace changes
Inline
Side-by-side
src/lib/datasrc/rbtree.h
View file @
57c61f2f
...
...
@@ -1260,6 +1260,9 @@ RBTree<T>::previousNode(RBTreeNodeChain<T>& node_path) const {
// already, which located the exact node. The rest of the function
// goes one domain left and returns it for us.
break
;
default:
// This must not happen as Name::compare() never returns NONE.
isc_throw
(
isc
::
Unexpected
,
"Name::compare() returned unexpected result"
);
}
// So, the node_path now contains the path to a node we want previous for.
...
...
src/lib/dns/labelsequence.cc
View file @
57c61f2f
...
...
@@ -71,6 +71,19 @@ LabelSequence::equals(const LabelSequence& other, bool case_sensitive) const {
return
(
true
);
}
NameComparisonResult
LabelSequence
::
compare
(
const
LabelSequence
&
other
,
bool
case_sensitive
)
const
{
if
((
!
isAbsolute
())
||
(
!
other
.
isAbsolute
()))
{
return
(
NameComparisonResult
(
0
,
0
,
NameComparisonResult
::
NONE
));
}
return
(
name_
.
partial_compare
(
other
.
name_
,
first_label_
,
other
.
first_label_
,
case_sensitive
));
}
void
LabelSequence
::
stripLeft
(
size_t
i
)
{
if
(
i
>=
getLabelCount
())
{
...
...
src/lib/dns/labelsequence.h
View file @
57c61f2f
...
...
@@ -85,10 +85,10 @@ public:
/// \return The length of the data of the label sequence in octets.
size_t
getDataLength
()
const
;
/// \brief Compares two label sequences.
/// \brief Compares two label sequences
for equality
.
///
/// Performs a (optionally case-insensitive) comparison between this
/// LabelSequence and another LabelSequence.
/// LabelSequence and another LabelSequence
for equality
.
///
/// \param other The LabelSequence to compare with
/// \param case_sensitive If true, comparison is case-insensitive
...
...
@@ -96,6 +96,18 @@ public:
/// and contain the same data.
bool
equals
(
const
LabelSequence
&
other
,
bool
case_sensitive
=
false
)
const
;
/// \brief Compares two label sequences.
///
/// Performs a (optionally case-insensitive) comparison between this
/// LabelSequence and another LabelSequence.
///
/// \param other The LabelSequence to compare with
/// \param case_sensitive If true, comparison is case-insensitive
/// \return a <code>NameComparisonResult</code> object representing the
/// comparison result.
NameComparisonResult
compare
(
const
LabelSequence
&
other
,
bool
case_sensitive
=
false
)
const
;
/// \brief Remove labels from the front of this LabelSequence
///
/// \note No actual memory is changed, this operation merely updates the
...
...
src/lib/dns/name.cc
View file @
57c61f2f
...
...
@@ -507,13 +507,26 @@ Name::toText(bool omit_final_dot) const {
NameComparisonResult
Name
::
compare
(
const
Name
&
other
)
const
{
return
(
partial_compare
(
other
,
0
,
0
));
}
NameComparisonResult
Name
::
partial_compare
(
const
Name
&
other
,
unsigned
int
first_label
,
unsigned
int
first_label_other
,
bool
case_sensitive
)
const
{
// Determine the relative ordering under the DNSSEC order relation of
// 'this' and 'other', and also determine the hierarchical relationship
// of the names.
if
((
first_label
>
labelcount_
)
||
(
first_label_other
>
other
.
labelcount_
))
{
isc_throw
(
BadValue
,
"Bad first label indices were passed"
);
}
unsigned
int
nlabels
=
0
;
unsigned
int
l1
=
labelcount_
;
unsigned
int
l2
=
other
.
labelcount_
;
int
l1
=
labelcount_
-
first_label
;
int
l2
=
other
.
labelcount_
-
first_label_other
;
int
ldiff
=
(
int
)
l1
-
(
int
)
l2
;
unsigned
int
l
=
(
ldiff
<
0
)
?
l1
:
l2
;
...
...
@@ -521,8 +534,8 @@ Name::compare(const Name& other) const {
--
l
;
--
l1
;
--
l2
;
size_t
pos1
=
offsets_
[
l1
];
size_t
pos2
=
other
.
offsets_
[
l2
];
size_t
pos1
=
offsets_
[
l1
+
first_label
];
size_t
pos2
=
other
.
offsets_
[
l2
+
first_label_other
];
unsigned
int
count1
=
ndata_
[
pos1
++
];
unsigned
int
count2
=
other
.
ndata_
[
pos2
++
];
...
...
@@ -536,11 +549,17 @@ Name::compare(const Name& other) const {
while
(
count
>
0
)
{
unsigned
char
label1
=
ndata_
[
pos1
];
unsigned
char
label2
=
other
.
ndata_
[
pos2
];
int
chdiff
;
if
(
case_sensitive
)
{
chdiff
=
(
int
)
label1
-
(
int
)
label2
;
}
else
{
chdiff
=
(
int
)
maptolower
[
label1
]
-
(
int
)
maptolower
[
label2
];
}
int
chdiff
=
(
int
)
maptolower
[
label1
]
-
(
int
)
maptolower
[
label2
];
if
(
chdiff
!=
0
)
{
return
(
NameComparisonResult
(
chdiff
,
nlabels
,
NameComparisonResult
::
COMMONANCESTOR
));
NameComparisonResult
::
COMMONANCESTOR
));
}
--
count
;
++
pos1
;
...
...
src/lib/dns/name.h
View file @
57c61f2f
...
...
@@ -142,7 +142,8 @@ public:
SUPERDOMAIN
=
0
,
SUBDOMAIN
=
1
,
EQUAL
=
2
,
COMMONANCESTOR
=
3
COMMONANCESTOR
=
3
,
NONE
=
4
};
///
...
...
@@ -399,6 +400,29 @@ public:
/// comparison result.
NameComparisonResult
compare
(
const
Name
&
other
)
const
;
private:
/// \brief Partially compare two <code>Name</code>s.
///
/// This method performs a partial comparison of the
/// <code>Name</code> and <code>other</code> and returns the result
/// in the form of a <code>NameComparisonResult</code> object.
///
/// This method never throws an exception.
///
/// \param other the right-hand operand to compare against.
/// \param first_label the leftmost label of <code>Name</code> to
/// begin comparing from.
/// \param first_label_other the leftmost label of
/// <code>other</code> to begin comparing from.
/// \param case_sensitive If true, comparison is case-insensitive
/// \return a <code>NameComparisonResult</code> object representing the
/// comparison result.
NameComparisonResult
partial_compare
(
const
Name
&
other
,
unsigned
int
first_label
,
unsigned
int
first_label_other
,
bool
case_sensitive
=
false
)
const
;
public:
/// \brief Return true iff two names are equal.
///
/// Semantically this could be implemented based on the result of the
...
...
src/lib/dns/tests/labelsequence_unittest.cc
View file @
57c61f2f
...
...
@@ -125,6 +125,117 @@ TEST_F(LabelSequenceTest, equals_insensitive) {
EXPECT_FALSE
(
ls5
.
equals
(
ls7
));
}
// Compare tests
TEST_F
(
LabelSequenceTest
,
compare
)
{
// "example.org." and "example.org.", case sensitive
NameComparisonResult
result
=
ls1
.
compare
(
ls3
,
true
);
EXPECT_EQ
(
isc
::
dns
::
NameComparisonResult
::
EQUAL
,
result
.
getRelation
());
EXPECT_EQ
(
3
,
result
.
getCommonLabels
());
// "example.org." and "example.ORG.", case sensitive
result
=
ls3
.
compare
(
ls5
,
true
);
EXPECT_EQ
(
isc
::
dns
::
NameComparisonResult
::
COMMONANCESTOR
,
result
.
getRelation
());
EXPECT_EQ
(
1
,
result
.
getCommonLabels
());
// "example.org." and "example.ORG.", case in-sensitive
result
=
ls3
.
compare
(
ls5
);
EXPECT_EQ
(
isc
::
dns
::
NameComparisonResult
::
EQUAL
,
result
.
getRelation
());
EXPECT_EQ
(
3
,
result
.
getCommonLabels
());
Name
na
(
"a.example.org"
);
Name
nb
(
"b.example.org"
);
LabelSequence
lsa
(
na
);
LabelSequence
lsb
(
nb
);
// "a.example.org." and "b.example.org.", case in-sensitive
result
=
lsa
.
compare
(
lsb
);
EXPECT_EQ
(
isc
::
dns
::
NameComparisonResult
::
COMMONANCESTOR
,
result
.
getRelation
());
EXPECT_EQ
(
3
,
result
.
getCommonLabels
());
// "example.org." and "b.example.org.", case in-sensitive
lsa
.
stripLeft
(
1
);
result
=
lsa
.
compare
(
lsb
);
EXPECT_EQ
(
isc
::
dns
::
NameComparisonResult
::
SUPERDOMAIN
,
result
.
getRelation
());
EXPECT_EQ
(
3
,
result
.
getCommonLabels
());
Name
nc
(
"g.f.e.d.c.example.org"
);
LabelSequence
lsc
(
nc
);
// "g.f.e.d.c.example.org." and "b.example.org" (no hierarchy), case
// in-sensitive
lsb
.
stripRight
(
1
);
result
=
lsc
.
compare
(
lsb
);
EXPECT_EQ
(
isc
::
dns
::
NameComparisonResult
::
NONE
,
result
.
getRelation
());
EXPECT_EQ
(
0
,
result
.
getCommonLabels
());
EXPECT_EQ
(
0
,
result
.
getOrder
());
// "g.f.e.d.c.example.org." and "example.org.", case in-sensitive
result
=
lsc
.
compare
(
ls1
);
EXPECT_EQ
(
isc
::
dns
::
NameComparisonResult
::
SUBDOMAIN
,
result
.
getRelation
());
EXPECT_EQ
(
3
,
result
.
getCommonLabels
());
// "e.d.c.example.org." and "example.org.", case in-sensitive
lsc
.
stripLeft
(
2
);
result
=
lsc
.
compare
(
ls1
);
EXPECT_EQ
(
isc
::
dns
::
NameComparisonResult
::
SUBDOMAIN
,
result
.
getRelation
());
EXPECT_EQ
(
3
,
result
.
getCommonLabels
());
// "example.org." and "example.org.", case in-sensitive
lsc
.
stripLeft
(
3
);
result
=
lsc
.
compare
(
ls1
);
EXPECT_EQ
(
isc
::
dns
::
NameComparisonResult
::
EQUAL
,
result
.
getRelation
());
EXPECT_EQ
(
3
,
result
.
getCommonLabels
());
// "." and "example.org.", case in-sensitive
lsc
.
stripLeft
(
2
);
result
=
lsc
.
compare
(
ls1
);
EXPECT_EQ
(
isc
::
dns
::
NameComparisonResult
::
SUPERDOMAIN
,
result
.
getRelation
());
EXPECT_EQ
(
1
,
result
.
getCommonLabels
());
Name
nd
(
"a.b.c.isc.example.org"
);
LabelSequence
lsd
(
nd
);
Name
ne
(
"w.x.y.isc.EXAMPLE.org"
);
LabelSequence
lse
(
ne
);
// "a.b.c.isc.example.org." and "w.x.y.isc.EXAMPLE.org.",
// case sensitive
result
=
lsd
.
compare
(
lse
,
true
);
EXPECT_EQ
(
isc
::
dns
::
NameComparisonResult
::
COMMONANCESTOR
,
result
.
getRelation
());
EXPECT_EQ
(
2
,
result
.
getCommonLabels
());
// "a.b.c.isc.example.org." and "w.x.y.isc.EXAMPLE.org.",
// case in-sensitive
result
=
lsd
.
compare
(
lse
);
EXPECT_EQ
(
isc
::
dns
::
NameComparisonResult
::
COMMONANCESTOR
,
result
.
getRelation
());
EXPECT_EQ
(
4
,
result
.
getCommonLabels
());
// "isc.example.org." and "isc.EXAMPLE.org.", case sensitive
lsd
.
stripLeft
(
3
);
lse
.
stripLeft
(
3
);
result
=
lsd
.
compare
(
lse
,
true
);
EXPECT_EQ
(
isc
::
dns
::
NameComparisonResult
::
COMMONANCESTOR
,
result
.
getRelation
());
EXPECT_EQ
(
2
,
result
.
getCommonLabels
());
// "isc.example.org." and "isc.EXAMPLE.org.", case in-sensitive
result
=
lsd
.
compare
(
lse
);
EXPECT_EQ
(
isc
::
dns
::
NameComparisonResult
::
EQUAL
,
result
.
getRelation
());
EXPECT_EQ
(
4
,
result
.
getCommonLabels
());
}
void
getDataCheck
(
const
char
*
expected_data
,
size_t
expected_len
,
const
LabelSequence
&
ls
)
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment