}
}
-Attribute *
-attr_dup( Attribute *a )
-{
- Attribute *tmp;
-
- if ( a == NULL) return NULL;
-
- tmp = attr_alloc( a->a_desc );
+static void
+attr_dup2( Attribute *tmp, Attribute *a )
+{
if ( a->a_vals != NULL ) {
int i;
} else {
tmp->a_nvals = tmp->a_vals;
}
-
- } else {
- tmp->a_vals = NULL;
- tmp->a_nvals = NULL;
}
+}
+
+Attribute *
+attr_dup( Attribute *a )
+{
+ Attribute *tmp;
+
+ if ( a == NULL) return NULL;
+
+ tmp = attr_alloc( a->a_desc );
+ attr_dup2( tmp, a );
return tmp;
}
Attribute *
attrs_dup( Attribute *a )
{
- Attribute *tmp, **next;
+ int i;
+ Attribute *tmp, *anew;
if( a == NULL ) return NULL;
- tmp = NULL;
- next = &tmp;
+ /* count them */
+ for( tmp=a,i=0; tmp; tmp=tmp->a_next ) {
+ i++;
+ }
+
+ anew = attrs_alloc( i );
- for( ; a != NULL ; a = a->a_next ) {
- *next = attr_dup( a );
- next = &((*next)->a_next);
+ for( tmp=anew; a; a=a->a_next ) {
+ attr_dup2( tmp, a );
+ tmp=tmp->a_next;
}
- *next = NULL;
- return tmp;
+ return anew;
}
return ret;
}
+#if 1
+/* Duplicates an entry using a single malloc. Saves CPU time, increases
+ * heap usage because a single large malloc is harder to satisfy than
+ * lots of small ones, and the freed space isn't as easily reusable.
+ *
+ * Probably not worth using this function.
+ */
+Entry *entry_dup_bv( Entry *e )
+{
+ ber_len_t len;
+ int nattrs, nvals;
+ Entry *ret;
+ struct berval *bvl;
+ char *ptr;
+ Attribute *src, *dst;
+
+ ret = entry_alloc();
+
+ entry_partsize(e, &len, &nattrs, &nvals, 1);
+ ret->e_id = e->e_id;
+ ret->e_attrs = attrs_alloc( nattrs );
+ ret->e_ocflags = e->e_ocflags;
+ ret->e_bv.bv_len = len + nvals * sizeof(struct berval);
+ ret->e_bv.bv_val = ch_malloc( ret->e_bv.bv_len );
+
+ bvl = (struct berval *)ret->e_bv.bv_val;
+ ptr = (char *)(bvl + nvals);
+
+ ret->e_name.bv_len = e->e_name.bv_len;
+ ret->e_name.bv_val = ptr;
+ AC_MEMCPY( ptr, e->e_name.bv_val, e->e_name.bv_len );
+ ptr += e->e_name.bv_len;
+ *ptr++ = '\0';
+
+ ret->e_nname.bv_len = e->e_nname.bv_len;
+ ret->e_nname.bv_val = ptr;
+ AC_MEMCPY( ptr, e->e_nname.bv_val, e->e_nname.bv_len );
+ ptr += e->e_name.bv_len;
+ *ptr++ = '\0';
+
+ dst = ret->e_attrs;
+ for (src = e->e_attrs; src; src=src->a_next,dst=dst->a_next ) {
+ int i;
+ dst->a_desc = src->a_desc;
+ dst->a_flags = SLAP_ATTR_DONT_FREE_DATA | SLAP_ATTR_DONT_FREE_VALS;
+ dst->a_vals = bvl;
+ for ( i=0; src->a_vals[i].bv_val; i++ ) {
+ bvl->bv_len = src->a_vals[i].bv_len;
+ bvl->bv_val = ptr;
+ AC_MEMCPY( ptr, src->a_vals[i].bv_val, bvl->bv_len );
+ ptr += bvl->bv_len;
+ *ptr++ = '\0';
+ bvl++;
+ }
+ BER_BVZERO(bvl);
+ bvl++;
+ if ( src->a_vals != src->a_nvals ) {
+ dst->a_nvals = bvl;
+ for ( i=0; src->a_nvals[i].bv_val; i++ ) {
+ bvl->bv_len = src->a_nvals[i].bv_len;
+ bvl->bv_val = ptr;
+ AC_MEMCPY( ptr, src->a_nvals[i].bv_val, bvl->bv_len );
+ ptr += bvl->bv_len;
+ *ptr++ = '\0';
+ bvl++;
+ }
+ BER_BVZERO(bvl);
+ bvl++;
+ }
+ }
+ return ret;
+}
+#endif
LDAP_SLAPD_F (int) entry_dn_cmp LDAP_P(( const void *v_a, const void *v_b ));
LDAP_SLAPD_F (int) entry_id_cmp LDAP_P(( const void *v_a, const void *v_b ));
LDAP_SLAPD_F (Entry *) entry_dup LDAP_P(( Entry *e ));
+LDAP_SLAPD_F (Entry *) entry_dup_bv LDAP_P(( Entry *e ));
LDAP_SLAPD_F (Entry *) entry_alloc LDAP_P((void));
LDAP_SLAPD_F (int) entry_prealloc LDAP_P((int num));