Skip to content
GitLab
Menu
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
1780e99c
Commit
1780e99c
authored
Jul 25, 2012
by
Jelte Jansen
Browse files
[2148] 'extendable' labelsequence constructor
parent
626757dd
Changes
3
Hide whitespace changes
Inline
Side-by-side
src/lib/dns/labelsequence.cc
View file @
1780e99c
...
...
@@ -55,6 +55,25 @@ LabelSequence::LabelSequence(const void* buf) {
}
}
LabelSequence
::
LabelSequence
(
const
LabelSequence
&
src
,
uint8_t
buf
[
MAX_SERIALIZED_LENGTH
])
{
size_t
data_len
;
const
uint8_t
*
data
=
src
.
getData
(
&
data_len
);
memcpy
(
buf
,
data
,
data_len
);
for
(
size_t
i
=
0
;
i
<
src
.
getLabelCount
();
++
i
)
{
buf
[
Name
::
MAX_WIRE
+
i
]
=
src
.
offsets_
[
i
+
src
.
first_label_
]
-
src
.
offsets_
[
src
.
first_label_
];
}
first_label_
=
0
;
last_label_
=
src
.
last_label_
-
src
.
first_label_
;
data_
=
buf
;
offsets_
=
&
buf
[
Name
::
MAX_WIRE
];
}
const
uint8_t
*
LabelSequence
::
getData
(
size_t
*
len
)
const
{
*
len
=
getDataLength
();
...
...
src/lib/dns/labelsequence.h
View file @
1780e99c
...
...
@@ -45,6 +45,14 @@ class LabelSequence {
friend
std
::
string
Name
::
toText
(
bool
)
const
;
public:
/// \brief Max possible size of serialized image generated by \c serialize
///
/// A fixed length buffer of this size can be always passed to
/// \c serialize() safely. (But the application shouldn't use the
/// specific size value; it must use this constant variable).
static
const
size_t
MAX_SERIALIZED_LENGTH
=
Name
::
MAX_WIRE
+
Name
::
MAX_LABELS
+
1
;
/// \brief Constructs a LabelSequence for the given name
///
/// \note The associated Name MUST remain in scope during the lifetime
...
...
@@ -78,6 +86,16 @@ public:
/// \param buf Pointer to the serialized image generated by \c serialize().
explicit
LabelSequence
(
const
void
*
buf
);
/// \brief Construct 'extendable' LabelSequence
///
/// This form of LabelSequence copies the data from the given
/// labelsequence into the given external buffer, which is subsequently
/// extendable by calling extend()
///
/// \param src LabelSequence to copy the initial data from
/// \param buf external buffer to store this labelsequence's data in
LabelSequence
(
const
LabelSequence
&
src
,
uint8_t
buf
[
MAX_SERIALIZED_LENGTH
]);
/// \brief Copy constructor.
///
/// \note The associated data MUST remain in scope during the lifetime
...
...
@@ -125,14 +143,6 @@ public:
/// \return The length of the data of the label sequence in octets.
size_t
getDataLength
()
const
;
/// \brief Max possible size of serialized image generated by \c serialize
///
/// A fixed length buffer of this size can be always passed to
/// \c serialize() safely. (But the application shouldn't use the
/// specific size value; it must use this constant variable).
static
const
size_t
MAX_SERIALIZED_LENGTH
=
Name
::
MAX_WIRE
+
Name
::
MAX_LABELS
+
1
;
/// \brief Return the size of serialized image of the \c LabelSequence.
///
/// This method calculates the size of necessary storage to store
...
...
src/lib/dns/tests/labelsequence_unittest.cc
View file @
1780e99c
...
...
@@ -34,6 +34,25 @@ const size_t LabelSequence::MAX_SERIALIZED_LENGTH;
namespace
{
// Common check that two labelsequences are equal
void
check_equal
(
const
LabelSequence
&
ls1
,
const
LabelSequence
&
ls2
)
{
NameComparisonResult
result
=
ls1
.
compare
(
ls2
);
EXPECT_EQ
(
isc
::
dns
::
NameComparisonResult
::
EQUAL
,
result
.
getRelation
())
<<
ls1
.
toText
()
<<
" <> "
<<
ls2
.
toText
();
EXPECT_EQ
(
0
,
result
.
getOrder
())
<<
ls1
.
toText
()
<<
" <> "
<<
ls2
.
toText
();
EXPECT_EQ
(
ls1
.
getLabelCount
(),
result
.
getCommonLabels
());
}
// Common check for general comparison of two labelsequences
void
check_compare
(
const
LabelSequence
&
ls1
,
const
LabelSequence
&
ls2
,
isc
::
dns
::
NameComparisonResult
::
NameRelation
relation
,
size_t
common_labels
)
{
NameComparisonResult
result
=
ls1
.
compare
(
ls2
);
EXPECT_EQ
(
relation
,
result
.
getRelation
());
EXPECT_EQ
(
common_labels
,
result
.
getCommonLabels
());
}
class
LabelSequenceTest
:
public
::
testing
::
Test
{
public:
LabelSequenceTest
()
:
n1
(
"example.org"
),
n2
(
"example.com"
),
...
...
@@ -784,4 +803,119 @@ TEST_F(LabelSequenceTest, badDeserialize) {
EXPECT_THROW
(
LabelSequence
ls
(
offsets_noincrease
),
isc
::
BadValue
);
}
namespace
{
// Helper function; repeatedly calls
// - Initially, all three labelsequences should be the same
// - repeatedly performs:
// - checks all three are equal
// - stripLeft on ls1
// - checks ls1 and ls2 are different, and ls2 and ls3 are equal
// - stripLeft on ls2
// - checks ls1 and ls2 are equal, and ls2 and ls3 are different
// - stripLeft on ls3
//
// (this test makes sure the stripLeft of one has no effect on the other
// two, and that the strip properties hold regardless of how they were
// constructed)
//
void
stripLeftCheck
(
LabelSequence
ls1
,
LabelSequence
ls2
,
LabelSequence
ls3
)
{
ASSERT_LT
(
1
,
ls1
.
getLabelCount
());
while
(
ls1
.
getLabelCount
()
>
1
)
{
check_equal
(
ls1
,
ls2
);
check_equal
(
ls2
,
ls3
);
ls1
.
stripLeft
(
1
);
check_compare
(
ls1
,
ls2
,
isc
::
dns
::
NameComparisonResult
::
SUPERDOMAIN
,
ls1
.
getLabelCount
());
check_equal
(
ls2
,
ls3
);
ls2
.
stripLeft
(
1
);
check_equal
(
ls1
,
ls2
);
check_compare
(
ls2
,
ls3
,
isc
::
dns
::
NameComparisonResult
::
SUPERDOMAIN
,
ls1
.
getLabelCount
());
ls3
.
stripLeft
(
1
);
}
}
// Similar to stripLeftCheck, but using stripRight()
void
stripRightCheck
(
LabelSequence
ls1
,
LabelSequence
ls2
,
LabelSequence
ls3
)
{
ASSERT_LT
(
1
,
ls1
.
getLabelCount
());
while
(
ls1
.
getLabelCount
()
>
1
)
{
check_equal
(
ls1
,
ls2
);
check_equal
(
ls2
,
ls3
);
ls1
.
stripRight
(
1
);
check_compare
(
ls1
,
ls2
,
isc
::
dns
::
NameComparisonResult
::
NONE
,
0
);
check_equal
(
ls2
,
ls3
);
ls2
.
stripRight
(
1
);
check_equal
(
ls1
,
ls2
);
check_compare
(
ls2
,
ls3
,
isc
::
dns
::
NameComparisonResult
::
NONE
,
0
);
ls3
.
stripRight
(
1
);
}
}
}
// end anonymous namespace
// Test that 'extendable' labelsequences behave correctly when using
// stripLeft() and stripRight()
TEST
(
LabelSequence
,
extendableLabelSequence
)
{
Name
n1
(
"example.org."
);
LabelSequence
ls1
(
n1
);
LabelSequence
ls2
(
n1
);
uint8_t
buf
[
LabelSequence
::
MAX_SERIALIZED_LENGTH
];
memset
(
buf
,
0
,
LabelSequence
::
MAX_SERIALIZED_LENGTH
);
LabelSequence
els
(
ls1
,
buf
);
ASSERT_EQ
(
ls1
.
getDataLength
(),
els
.
getDataLength
());
stripLeftCheck
(
ls1
,
els
,
ls2
);
stripRightCheck
(
ls1
,
els
,
ls2
);
}
// Test that 'extendable' LabelSequences behave correctly when initialized
// with a stripped source LabelSequence
TEST
(
LabelSequence
,
extendableLabelSequenceStrippedSource
)
{
Name
n1
(
"foo.bar.example.org."
);
LabelSequence
ls1
(
n1
);
LabelSequence
ls2
(
n1
);
while
(
ls1
.
getLabelCount
()
>
2
)
{
ls1
.
stripLeft
(
1
);
ls2
.
stripLeft
(
1
);
uint8_t
buf
[
LabelSequence
::
MAX_SERIALIZED_LENGTH
];
memset
(
buf
,
0
,
LabelSequence
::
MAX_SERIALIZED_LENGTH
);
LabelSequence
els
(
ls1
,
buf
);
ASSERT_EQ
(
ls1
.
getDataLength
(),
els
.
getDataLength
());
stripLeftCheck
(
ls1
,
els
,
ls2
);
stripRightCheck
(
ls1
,
els
,
ls2
);
}
}
TEST
(
LabelSequence
,
extendableLabelSequenceRightStrippedSource
)
{
Name
n1
(
"foo.bar.example.org."
);
LabelSequence
ls1
(
n1
);
LabelSequence
ls2
(
n1
);
while
(
ls1
.
getLabelCount
()
>
2
)
{
ls1
.
stripRight
(
1
);
ls2
.
stripRight
(
1
);
uint8_t
buf
[
LabelSequence
::
MAX_SERIALIZED_LENGTH
];
memset
(
buf
,
0
,
LabelSequence
::
MAX_SERIALIZED_LENGTH
);
LabelSequence
els
(
ls1
,
buf
);
ASSERT_EQ
(
ls1
.
getDataLength
(),
els
.
getDataLength
());
stripLeftCheck
(
ls1
,
els
,
ls2
);
stripRightCheck
(
ls1
,
els
,
ls2
);
}
}
}
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a 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