+ assert( SLAP_IS_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH( flags ) != 0 );
+
+ if( !SLAP_IS_MR_ASSERTED_VALUE_NORMALIZED_MATCH( flags ) &&
+ mr->smr_normalize )
+ {
+ rc = (mr->smr_normalize)(
+ flags & (SLAP_MR_TYPE_MASK|SLAP_MR_SUBTYPE_MASK|SLAP_MR_VALUE_OF_SYNTAX),
+ ad->ad_type->sat_syntax,
+ mr, val, &nval, ctx );
+
+ if( rc != LDAP_SUCCESS ) {
+ return LDAP_INVALID_SYNTAX;
+ }
+ }
+
+ for ( i = 0; vals[i].bv_val != NULL; i++ ) {
+ int match;
+ const char *text;
+
+ rc = value_match( &match, ad, mr, flags,
+ &vals[i], nval.bv_val == NULL ? val : &nval, &text );
+
+ if( rc == LDAP_SUCCESS && match == 0 ) {
+ slap_sl_free( nval.bv_val, ctx );
+ return rc;
+ }
+ }
+
+ slap_sl_free( nval.bv_val, ctx );
+ return LDAP_NO_SUCH_ATTRIBUTE;
+}
+
+/* assign new indexes to an attribute's ordered values */
+void
+ordered_value_renumber( Attribute *a, int vals )
+{
+ char *ptr, ibuf[64]; /* many digits */
+ struct berval ibv, tmp, vtmp;
+ int i;
+
+ ibv.bv_val = ibuf;
+
+ for (i=0; i<vals; i++) {
+ ibv.bv_len = sprintf(ibv.bv_val, "{%d}", i);
+ vtmp = a->a_vals[i];
+ if ( vtmp.bv_val[0] == '{' ) {
+ ptr = ber_bvchr(&vtmp, '}');
+ assert( ptr != NULL );
+ ++ptr;
+ vtmp.bv_len -= ptr - vtmp.bv_val;
+ vtmp.bv_val = ptr;
+ }
+ tmp.bv_len = ibv.bv_len + vtmp.bv_len;
+ tmp.bv_val = ch_malloc( tmp.bv_len + 1 );
+ strcpy( tmp.bv_val, ibv.bv_val );
+ AC_MEMCPY( tmp.bv_val + ibv.bv_len, vtmp.bv_val, vtmp.bv_len );
+ tmp.bv_val[tmp.bv_len] = '\0';
+ ch_free( a->a_vals[i].bv_val );
+ a->a_vals[i] = tmp;
+
+ if ( a->a_nvals && a->a_nvals != a->a_vals ) {
+ vtmp = a->a_nvals[i];
+ if ( vtmp.bv_val[0] == '{' ) {
+ ptr = ber_bvchr(&vtmp, '}');
+ assert( ptr != NULL );
+ ++ptr;
+ vtmp.bv_len -= ptr - vtmp.bv_val;
+ vtmp.bv_val = ptr;
+ }
+ tmp.bv_len = ibv.bv_len + vtmp.bv_len;
+ tmp.bv_val = ch_malloc( tmp.bv_len + 1 );
+ strcpy( tmp.bv_val, ibv.bv_val );
+ AC_MEMCPY( tmp.bv_val + ibv.bv_len, vtmp.bv_val, vtmp.bv_len );
+ tmp.bv_val[tmp.bv_len] = '\0';
+ ch_free( a->a_nvals[i].bv_val );
+ a->a_nvals[i] = tmp;