If we are handling a file, then we proceed to io_read_file(), which has changed slightly from the previous version:
... // 1) odd inodes are GIF files, even inodes are text files if (ocb -> base.attr -> base.inode & 1) { if (!ocb -> output) { ... // 2) allocate the input and output structures as before ... sprintf (string, "%0*d", optd, ocb -> base.attr -> count++); (*ocb -> render) (string, input, optx, opty); ocb -> size = ocb -> base.attr -> base.nbytes = encode_image ( input, optx, opty, ocb -> output); // 3) note the changes to write_file() if (optS) { write_file (optS, ocb -> base.attr -> base.inode / 2 - 1, ocb -> base.attr -> count); } } } else { // 4) even, so must be the text attribute int tmp; // limited scope ocb -> base.attr -> count = attr_gif [ocb -> base.attr -> base.inode / 2 - 1].count; tmp = sprintf (string, "%0*d\n", optd, ocb -> base.attr -> count); if (ocb -> output) { free (ocb -> output); } ocb -> output = strdup (string); ocb -> size = tmp; }
Notice a few things:
What might appear to be clever use of inodes is in fact standard programming practice. When you think about it, a disk-based filesystem makes use of the inodes in a similar manner; it uses them to find the disk blocks on the media.