+static void rec_encode_unsigned (unsigned n, unsigned char *buf, int *len)
+{
+ (*len) = 0;
+ while (n > 127)
+ {
+ buf[*len] = 128 + (n & 127);
+ n = n >> 7;
+ (*len)++;
+ }
+ buf[*len] = n;
+ (*len)++;
+}
+
+static void rec_decode_unsigned(unsigned *np, unsigned char *buf, int *len)
+{
+ unsigned n = 0;
+ unsigned w = 1;
+ (*len) = 0;
+
+ while (buf[*len] > 127)
+ {
+ n += w*(buf[*len] & 127);
+ w = w << 7;
+ (*len)++;
+ }
+ n += w * buf[*len];
+ (*len)++;
+ *np = n;
+}
+static void rec_cache_flush_block1 (Records p, Record rec, Record last_rec,
+ char **out_buf, int *out_size,
+ int *out_offset)
+{
+ int i;
+ int len;
+
+ for (i = 0; i<REC_NO_INFO; i++)
+ {
+ if (*out_offset + (int) rec->size[i] + 20 > *out_size)
+ {
+ int new_size = *out_offset + rec->size[i] + 65536;
+ char *np = (char *) xmalloc (new_size);
+ if (*out_offset)
+ memcpy (np, *out_buf, *out_offset);
+ xfree (*out_buf);
+ *out_size = new_size;
+ *out_buf = np;
+ }
+ if (i == 0)
+ {
+ rec_encode_unsigned (rec->sysno, *out_buf + *out_offset, &len);
+ (*out_offset) += len;
+ }
+ if (rec->size[i] == 0)
+ {
+ rec_encode_unsigned (1, *out_buf + *out_offset, &len);
+ (*out_offset) += len;
+ }
+ else if (last_rec && rec->size[i] == last_rec->size[i] &&
+ !memcmp (rec->info[i], last_rec->info[i], rec->size[i]))
+ {
+ rec_encode_unsigned (0, *out_buf + *out_offset, &len);
+ (*out_offset) += len;
+ }
+ else
+ {
+ rec_encode_unsigned (rec->size[i]+1, *out_buf + *out_offset, &len);
+ (*out_offset) += len;
+ memcpy (*out_buf + *out_offset, rec->info[i], rec->size[i]);
+ (*out_offset) += rec->size[i];
+ }
+ }
+}
+
+static void rec_write_multiple (Records p, int saveCount)
+{
+ int i;
+ int ref_count = 0;
+ Record last_rec = 0;
+ int out_size = 1000;
+ int out_offset = 0;
+ char *out_buf = (char *) xmalloc (out_size);
+ int *sysnos = (int *) xmalloc (sizeof(*sysnos) * (p->cache_cur + 1));
+ int *sysnop = sysnos;
+
+ for (i = 0; i<p->cache_cur - saveCount; i++)
+ {
+ struct record_cache_entry *e = p->record_cache + i;
+ switch (e->flag)
+ {
+ case recordFlagNew:
+ rec_cache_flush_block1 (p, e->rec, last_rec, &out_buf,
+ &out_size, &out_offset);
+ *sysnop++ = e->rec->sysno;
+ ref_count++;
+ e->flag = recordFlagNop;
+ last_rec = e->rec;
+ break;
+ case recordFlagWrite:
+ rec_release_blocks (p, e->rec->sysno);
+ rec_cache_flush_block1 (p, e->rec, last_rec, &out_buf,
+ &out_size, &out_offset);
+ *sysnop++ = e->rec->sysno;
+ ref_count++;
+ e->flag = recordFlagNop;
+ last_rec = e->rec;
+ break;
+ default:
+ break;
+ }
+ }
+ *sysnop = -1;
+ if (ref_count)
+ {
+ int csize = out_offset + (out_offset >> 6) + 620;
+
+ rec_tmp_expand (p, csize);
+#if HAVE_BZLIB_H
+ i = bzBuffToBuffCompress (p->tmp_buf+2*sizeof(int), &csize,
+ out_buf, out_offset, 9, 0, 30);
+ if (i != BZ_OK)
+ {
+ logf (LOG_FATAL, "bzBuffToCompress error code=%d", i);
+ exit (1);
+ }
+#else
+ memcpy (p->tmp_buf + 2*sizeof(int), out_buf, out_offset);
+ csize = out_offset;
+#endif
+ memcpy (p->tmp_buf + sizeof(int), &ref_count, sizeof(ref_count));
+ /* -------- compression */
+ rec_write_tmp_buf (p, csize + sizeof(int), sysnos);
+ }
+ xfree (out_buf);
+ xfree (sysnos);
+}
+