Branch data Line data Source code
1 : : // Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
2 : : //
3 : : // Permission to use, copy, modify, and/or distribute this software for any
4 : : // purpose with or without fee is hereby granted, provided that the above
5 : : // copyright notice and this permission notice appear in all copies.
6 : : //
7 : : // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
8 : : // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
9 : : // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
10 : : // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
11 : : // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
12 : : // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
13 : : // PERFORMANCE OF THIS SOFTWARE.
14 : :
15 : : #include <dns/labelsequence.h>
16 : : #include <dns/name_internal.h>
17 : : #include <exceptions/exceptions.h>
18 : :
19 : : #include <boost/functional/hash.hpp>
20 : :
21 : : #include <cstring>
22 : :
23 : : namespace isc {
24 : : namespace dns {
25 : :
26 : : const char*
27 : 16194 : LabelSequence::getData(size_t *len) const {
28 : 16194 : *len = getDataLength();
29 : 16194 : return (&name_.ndata_[name_.offsets_[first_label_]]);
30 : : }
31 : :
32 : : size_t
33 : 16211 : LabelSequence::getDataLength() const {
34 : : // If the labelsequence is absolute, the current last_label_ falls
35 : : // out of the vector (since it points to the 'label' after the
36 : : // root label, which doesn't exist; in that case, return
37 : : // the length for the 'previous' label (the root label) plus
38 : : // one (for the root label zero octet)
39 [ + + ]: 16211 : if (isAbsolute()) {
40 : 14857 : return (name_.offsets_[last_label_ - 1] -
41 : 14857 : name_.offsets_[first_label_] + 1);
42 : : } else {
43 : 16211 : return (name_.offsets_[last_label_] - name_.offsets_[first_label_]);
44 : : }
45 : : }
46 : :
47 : : bool
48 : 79 : LabelSequence::equals(const LabelSequence& other, bool case_sensitive) const {
49 : : size_t len, other_len;
50 : 79 : const char* data = getData(&len);
51 : 79 : const char* other_data = other.getData(&other_len);
52 : :
53 [ + + ]: 79 : if (len != other_len) {
54 : : return (false);
55 : : }
56 [ + + ]: 44 : if (case_sensitive) {
57 : 16 : return (std::strncmp(data, other_data, len) == 0);
58 : : }
59 : :
60 : : // As long as the data was originally validated as (part of) a name,
61 : : // label length must never be a capital ascii character, so we can
62 : : // simply compare them after converting to lower characters.
63 [ + + ]: 401 : for (size_t i = 0; i < len; ++i) {
64 : 322 : const unsigned char ch = data[i];
65 : 322 : const unsigned char other_ch = other_data[i];
66 [ + + ]: 322 : if (isc::dns::name::internal::maptolower[ch] !=
67 : 322 : isc::dns::name::internal::maptolower[other_ch]) {
68 : : return (false);
69 : : }
70 : : }
71 : : return (true);
72 : : }
73 : :
74 : : void
75 : 3809 : LabelSequence::stripLeft(size_t i) {
76 [ + + ]: 3809 : if (i >= getLabelCount()) {
77 [ + - ][ + - ]: 16 : isc_throw(OutOfRange, "Cannot strip to zero or less labels; " << i <<
[ + - ]
78 : : " (labelcount: " << getLabelCount() << ")");
79 : : }
80 : 3805 : first_label_ += i;
81 : 3805 : }
82 : :
83 : : void
84 : 1353 : LabelSequence::stripRight(size_t i) {
85 [ + + ]: 1353 : if (i >= getLabelCount()) {
86 [ + - ][ + - ]: 16 : isc_throw(OutOfRange, "Cannot strip to zero or less labels; " << i <<
[ + - ]
87 : : " (labelcount: " << getLabelCount() << ")");
88 : : }
89 : 1349 : last_label_ -= i;
90 : 1349 : }
91 : :
92 : : bool
93 : 16218 : LabelSequence::isAbsolute() const {
94 : 16218 : return (last_label_ == name_.offsets_.size());
95 : : }
96 : :
97 : : size_t
98 : 6123 : LabelSequence::getHash(bool case_sensitive) const {
99 : : size_t length;
100 : 6123 : const char* s = getData(&length);
101 [ + + ]: 6123 : if (length > 16) {
102 : 6123 : length = 16;
103 : : }
104 : :
105 : : size_t hash_val = 0;
106 [ + + ]: 76792 : while (length > 0) {
107 : 70669 : const unsigned char c = *s++;
108 : : boost::hash_combine(hash_val, case_sensitive ? c :
109 [ + + ]: 70669 : isc::dns::name::internal::maptolower[c]);
110 : 70669 : --length;
111 : : }
112 : 6123 : return (hash_val);
113 : : }
114 : :
115 : : } // end namespace dns
116 : 140673 : } // end namespace isc
|