+ unsigned flags,
+ struct berval *v1, /* stored value */
+ struct berval *v2, /* assertion */
+ const char ** text )
+{
+ struct berval bv1, bv2;
+
+ /* X-ORDERED VALUES equality matching:
+ * If (SLAP_MR_IS_VALUE_OF_ATTRIBUTE_SYNTAX) that means we are
+ * comparing two attribute values. In this case, we want to ignore
+ * the ordering index of both values, we just want to know if their
+ * main values are equal.
+ *
+ * If (SLAP_MR_IS_VALUE_OF_ASSERTION_SYNTAX) then we are comparing
+ * an assertion against an attribute value.
+ * If the assertion has no index, the index of the value is ignored.
+ * If the assertion has only an index, the remainder of the value is
+ * ignored.
+ * If the assertion has index and value, both are compared.
+ */
+ if ( ad->ad_type->sat_flags & SLAP_AT_ORDERED ) {
+ char *ptr;
+ struct berval iv;
+
+ bv1 = *v1;
+ bv2 = *v2;
+ iv = bv2;
+
+ /* Skip past the assertion index */
+ if ( bv2.bv_val[0] == '{' ) {
+ ptr = ber_bvchr( &bv2, '}' );
+ if ( ptr == NULL ) {
+ return LDAP_INVALID_SYNTAX;
+ }
+ ptr++;
+ bv2.bv_len -= ptr - bv2.bv_val;
+ bv2.bv_val = ptr;
+ v2 = &bv2;
+ }
+
+ if ( SLAP_MR_IS_VALUE_OF_ASSERTION_SYNTAX( flags )) {
+ if ( iv.bv_val[0] == '{' && bv1.bv_val[0] == '{' ) {
+ /* compare index values first */
+ long l1, l2, ret;
+
+ l1 = strtol( bv1.bv_val+1, NULL, 0 );
+ l2 = strtol( iv.bv_val+1, &ptr, 0 );
+
+ ret = l1 - l2;
+
+ /* If not equal, or we're only comparing the index,
+ * return result now.
+ */
+ if ( ret || ptr == iv.bv_val + iv.bv_len - 1 ) {
+ *match = ( ret < 0 ) ? -1 : (ret > 0 );
+ return LDAP_SUCCESS;
+ }
+ }
+ }
+ /* Skip past the attribute index */
+ if ( bv1.bv_val[0] == '{' ) {
+ ptr = ber_bvchr( &bv1, '}' );
+ if ( ptr == NULL ) {
+ return LDAP_INVALID_SYNTAX;
+ }
+ ptr++;
+ bv1.bv_len -= ptr - bv1.bv_val;
+ bv1.bv_val = ptr;
+ v1 = &bv1;
+ }
+ }
+
+ if ( !mr || !mr->smr_match ) {
+ *match = ber_bvcmp( v1, v2 );
+ return LDAP_SUCCESS;
+ }
+
+ return value_match( match, ad, mr, flags, v1, v2, text );
+}
+