@@ -109,23 +109,41 @@ view::const_iterator view::end() const {
109109
110110view::const_iterator view::find (stdx::string_view key) const {
111111 bson_t b;
112- bson_iter_t iter;
113-
114112 if (!bson_init_static (&b, _data, _length)) {
115113 return cend ();
116114 }
117115
116+ bson_iter_t iter;
118117 if (!bson_iter_init (&iter, &b)) {
119118 return cend ();
120119 }
121120
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 = " " ;
125137
126138 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.
129147 return const_iterator (element (iter.raw , iter.len , iter.off ));
130148 }
131149 }
0 commit comments