+/* Flatten an Entry into a buffer. The buffer is filled with just the
+ * strings/bervals of all the entry components. Each field is preceded
+ * by its length, encoded the way ber_put_len works. Every field is NUL
+ * terminated. The entire buffer size is precomputed so that a single
+ * malloc can be performed. The entry size is also recorded,
+ * to aid in entry_decode.
+ */
+int entry_encode(Entry *e, struct berval *bv)
+{
+ ber_len_t siz = sizeof(Entry);
+ ber_len_t len, dnlen, ndnlen;
+ int i;
+ Attribute *a;
+ unsigned char *ptr;
+
+#ifdef NEW_LOGGING
+ LDAP_LOG( OPERATION, DETAIL1, "entry_encode: id: 0x%08lx \"%s\"\n",
+ (long) e->e_id, e->e_dn, 0 );
+#else
+ Debug( LDAP_DEBUG_TRACE, "=> entry_encode(0x%08lx): %s\n",
+ (long) e->e_id, e->e_dn, 0 );
+#endif
+ dnlen = e->e_name.bv_len;
+ ndnlen = e->e_nname.bv_len;
+
+ entry_flatsize( e, &siz, &len, 1 );
+
+ bv->bv_len = len;
+ bv->bv_val = ch_malloc(len);
+ ptr = (unsigned char *)bv->bv_val;
+ entry_putlen(&ptr, siz);
+ entry_putlen(&ptr, dnlen);
+ AC_MEMCPY(ptr, e->e_dn, dnlen);
+ ptr += dnlen;
+ *ptr++ = '\0';
+ entry_putlen(&ptr, ndnlen);
+ AC_MEMCPY(ptr, e->e_ndn, ndnlen);
+ ptr += ndnlen;
+ *ptr++ = '\0';
+
+ for (a=e->e_attrs; a; a=a->a_next) {
+ entry_putlen(&ptr, a->a_desc->ad_cname.bv_len);
+ AC_MEMCPY(ptr, a->a_desc->ad_cname.bv_val,
+ a->a_desc->ad_cname.bv_len);
+ ptr += a->a_desc->ad_cname.bv_len;
+ *ptr++ = '\0';
+ if (a->a_vals) {
+ for (i=0; a->a_vals[i].bv_val; i++);
+ entry_putlen(&ptr, i);
+ for (i=0; a->a_vals[i].bv_val; i++) {
+ entry_putlen(&ptr, a->a_vals[i].bv_len);
+ AC_MEMCPY(ptr, a->a_vals[i].bv_val,
+ a->a_vals[i].bv_len);
+ ptr += a->a_vals[i].bv_len;
+ *ptr++ = '\0';
+ }
+ if (a->a_nvals != a->a_vals) {
+ entry_putlen(&ptr, i);
+ for (i=0; a->a_nvals[i].bv_val; i++) {
+ entry_putlen(&ptr, a->a_nvals[i].bv_len);
+ AC_MEMCPY(ptr, a->a_nvals[i].bv_val,
+ a->a_nvals[i].bv_len);
+ ptr += a->a_nvals[i].bv_len;
+ *ptr++ = '\0';
+ }
+ } else {
+ entry_putlen(&ptr, 0);
+ }