Saturday 2011-10-22

C doesn't seem to have an idiom for looping over something by chunks that might be misaligned.

while ( (c = getc()) != EOF)
	write(c);

VS

for (i = 0; i < file_sz; i += chunk_sz)
	write(i, chunk_sz);

When chunk_sz = 1, the two loops work the same; when chunk_sz = 4096 we might end up with un-handled bits at the end of the file.... So, what are the options?

// correct and verbose
q = file_sz / chunk_sz;
r = file_sz % chunk_sz;
for (i = 0; i < q; i++)
	write(i*chunk_sz, chunk_sz);
if (r)
	write(q*chunk_sz, r);

// give up
if (file_sz % chunk_sz)
	return -1;
for (i = 0; i < file_sz; i += chunk_sz) 
	write(i, chunk_sz);

// write a consumer
int consume(off64_t *b, off64_t *s) { 
	*b -= *s
	if (*b < 0)
		return *b + *s;
	return *s;
}
while ( (c = consume(&remaining, &chunk_sz)) > 0)
	write(total - remaining, c);

#define MIN(x, y) ( (x) < (y) ? (x) : (y) )

// compact, readable? 
for (i = 0; (c = MIN(total, i+chunk_sz) - i) > 0; i += c )
	write(i, c);

With complex data, a consumer function makes sense. With byte sequences, I prefer the last as we don't reduplicate the call to our imaginary write(), however we need to introduce a macro MIN for type-agnostic comparison (fmin() casts to double = path to hell).