+void move_pos_slow(struct stream_pos *pos, size_t offset);
+
+void init_pos(struct stream_pos *pos, int fd);
+void fini_pos(struct stream_pos *pos);
+
+/*
+ * move_pos - move position of a relative bit offset
+ *
+ * TODO: allow larger files by updating base too.
+ */
+static inline
+void move_pos(struct stream_pos *pos, size_t bit_offset)
+{
+ if (pos->fd >= 0) {
+ if (((pos->prot == PROT_READ)
+ && (pos->offset + bit_offset >= pos->content_size))
+ || ((pos->prot == PROT_WRITE)
+ && (pos->offset + bit_offset >= pos->packet_size))) {
+ move_pos_slow(pos, bit_offset);
+ return;
+ }
+ }
+ pos->offset += bit_offset;
+}
+
+/*
+ * align_pos - align position on a bit offset (> 0)
+ *
+ * TODO: allow larger files by updating base too.
+ */
+static inline
+void align_pos(struct stream_pos *pos, size_t bit_offset)
+{
+ move_pos(pos, offset_align(pos->offset, bit_offset));
+}
+
+static inline
+char *get_pos_addr(struct stream_pos *pos)
+{
+ /* Only makes sense to get the address after aligning on CHAR_BIT */
+ assert(!(pos->offset % CHAR_BIT));
+ return pos->base + (pos->offset / CHAR_BIT);
+}
+
+static inline
+void dummy_pos(struct stream_pos *pos, struct stream_pos *dummy)
+{
+ memcpy(dummy, pos, sizeof(struct stream_pos));
+ dummy->dummy = 1;
+ dummy->fd = -1;
+}
+
+/*
+ * Check if current packet can hold data.
+ * Returns 0 for success, negative error otherwise.
+ */
+static inline
+int pos_packet(struct stream_pos *dummy)
+{
+ if (dummy->offset > dummy->packet_size)
+ return -ENOSPC;
+ return 0;
+}
+
+static inline
+void pos_pad_packet(struct stream_pos *pos)
+{
+ move_pos(pos, pos->packet_size - pos->offset);
+}
+