- int i;
-
- /* tell the other guy how many we are going to be doing and how many
- bytes there are in the last chunk */
- write_int(f_out,s?s->count:0);
- write_int(f_out,s?s->n:block_size);
- write_int(f_out,s?s->remainder:0);
-
- if (!s) return;
-
- for (i=0;i<s->count;i++) {
- write_int(f_out,s->sums[i].sum1);
- write_buf(f_out,s->sums[i].sum2,csum_length);
+ int32 blength;
+ int s2length;
+
+ if (block_size)
+ blength = block_size;
+ else if (len <= BLOCK_SIZE * BLOCK_SIZE)
+ blength = BLOCK_SIZE;
+ else {
+ int32 c;
+ uint64 l;
+ for (c = 1, l = len; l >>= 2; c <<= 1) {
+ assert(c > 0);
+ }
+ blength = 0;
+ do {
+ blength |= c;
+ if (len < (uint64)blength * blength)
+ blength &= ~c;
+ c >>= 1;
+ } while (c >= 8); /* round to multiple of 8 */
+ blength = MAX(blength, BLOCK_SIZE);
+ }
+
+ if (protocol_version < 27) {
+ s2length = csum_length;
+ } else if (csum_length == SUM_LENGTH) {
+ s2length = SUM_LENGTH;
+ } else {
+ int32 c;
+ uint64 l;
+ int b = BLOCKSUM_BIAS;
+ for (l = len; l >>= 1; b += 2) {}
+ for (c = blength; c >>= 1 && b; b--) {}
+ /* add a bit, subtract rollsum, round up. */
+ s2length = (b + 1 - 32 + 7) / 8; /* --optimize in compiler-- */
+ s2length = MAX(s2length, csum_length);
+ s2length = MIN(s2length, SUM_LENGTH);
+ }
+
+ sum->flength = len;
+ sum->blength = blength;
+ sum->s2length = s2length;
+ sum->count = (len + (blength - 1)) / blength;
+ sum->remainder = (len % blength);
+
+ if (sum->count && verbose > 2) {
+ rprintf(FINFO,
+ "count=%.0f rem=%ld blength=%ld s2length=%d flength=%.0f\n",
+ (double)sum->count, (long)sum->remainder, (long)sum->blength,
+ sum->s2length, (double)sum->flength);