+#include <string.h>
+
+#include "lib/unaligned.h"
+
+/*
+ * Generic buffered I/O. You supply hooks to be called for low-level operations
+ * (swapping of buffers, seeking and closing), we do the rest.
+ *
+ * Buffer layout when reading:
+ *
+ * +----------------+---------------------------+
+ * | read data | free space |
+ * +----------------+---------------------------+
+ * ^ ^ ^ ^
+ * buffer bptr bstop bufend
+ *
+ * After the last character is read, bptr == bstop and buffer refill
+ * is deferred to the next read attempt. This gives us an easy way
+ * how to implement bungetc().
+ *
+ * When writing:
+ *
+ * +--------+--------------+--------------------+
+ * | unused | written data | free space |
+ * +--------+--------------+--------------------+
+ * ^ ^ ^ ^
+ * buffer bstop bptr bufend
+ *
+ * Dirty tricks:
+ *
+ * - You can mix reads and writes on the same stream, but you must
+ * call bflush() in between and remember that the file position
+ * points after the flushed buffer which is not necessarily the same
+ * as after the data you've read.
+ * - The spout/refill hooks can change not only bptr and bstop, but also
+ * the location of the buffer; fb-mem.c takes advantage of it.
+ * - In some cases, the user of the bdirect interface can be allowed to modify
+ * the data in the buffer to avoid unnecessary copying. If the back-end
+ * allows such modifications, it can set can_overwrite_buffer accordingly:
+ * * 0 if no modification is allowed,
+ * * 1 if the user can modify the buffer on the condition that
+ * the modifications will be undone before calling the next
+ * fastbuf operation
+ * * 2 if the user is allowed to overwrite the data in the buffer
+ * if bdirect_read_commit_modified() is called afterwards.
+ * In this case, the back-end must be prepared for trimming
+ * of the buffer which is done by the commit function.
+ */
+