Saturday, November 17, 2007

Converting a file from big endian to little endian (or vice versa)

Suppose you have a file of 4-byte cells and you wish to reverse each cell. What do you do? Fire up Factor, the latest code from git at least!
USING: io.mmap io.files math.functions splitting sequences ;

: byte-swap ( file -- )
dup file-length 4 align [
4 <sliced-groups> [ reverse-here ] each
] with-mapped-file ;

Given a sequence, 4 <groups> creates a virtual sequence of 4-element slices of the underlying sequence. We apply reverse-here to each slice. Since slices share storage with their underlying sequene, this has the effect of reversing a portion of the underlying sequence in-place. But here, the underlying sequence is a memory-mapped file's bytes.

The interesting thing here is that we're composing two orthogonal features: memory mapped files, and sequence operations.

Also note that error handling is at least half way there: if an error is thrown for whatever reason, the memory mapping is closed and cleaned up for you.

I just got mmap working on Windows CE, too. So the above code will work any supported platform.

No comments: