@@ -109,23 +109,41 @@ view::const_iterator view::end() const {
109
109
110
110
view::const_iterator view::find (stdx::string_view key) const {
111
111
bson_t b;
112
- bson_iter_t iter;
113
-
114
112
if (!bson_init_static (&b, _data, _length)) {
115
113
return cend ();
116
114
}
117
115
116
+ bson_iter_t iter;
118
117
if (!bson_iter_init (&iter, &b)) {
119
118
return cend ();
120
119
}
121
120
122
- if (key.empty ()) {
123
- return cend ();
124
- }
121
+ // See CDRIVER-2414: If we had a bson_iter_find_init that accepted
122
+ // the key length, then we could call it without needing to make a
123
+ // temporary std::string from the 'key', obviating the need for
124
+ // most of the rest of this method.
125
+
126
+ // Logically, a default constructed string_view represents the
127
+ // empty string just as does string_view(""), but they have,
128
+ // potentially, different represntations, the former having .data
129
+ // returning nullptr though the latter probably does not. But the
130
+ // C functions like strncmp below can't be called with nullptr. If
131
+ // we were called with a string_data such that its .data() member
132
+ // returns nullptr, then, barring undefined behavior, its length
133
+ // is known to be zero, and it is equivalent to the empty string,
134
+ // an instance of which we reset it to.
135
+ if (key.data () == nullptr )
136
+ key = " " ;
125
137
126
138
while (bson_iter_next (&iter)) {
127
- const char * ikey = bson_iter_key (&iter);
128
- if (0 == strncmp (key.data (), ikey, key.size ()) && strlen (ikey) == key.size ()) {
139
+ // See CDRIVER-2414: If bson_iter_key returned the length, we
140
+ // could avoid the strlen, or, better still, not use strncmp
141
+ // by using an O(1) promotion to stdx::string view, and then
142
+ // using the relops for that class on both sides.
143
+ const auto ikey = bson_iter_key (&iter);
144
+ if ((0 == strncmp (key.data (), ikey, key.size ())) && (strlen (ikey) == key.size ())) {
145
+ // NOTE: Technically, we are here accessing internals of bson_iter_t, which
146
+ // we should not do.
129
147
return const_iterator (element (iter.raw , iter.len , iter.off ));
130
148
}
131
149
}
0 commit comments