Index: uspace/app/bithenge/Makefile
===================================================================
--- uspace/app/bithenge/Makefile	(revision a54bd98c747d436ac3c8c8d96b5ba234d90c7f3e)
+++ uspace/app/bithenge/Makefile	(revision 743ce51407c2a076fa30bb9302d283626219a3d4)
@@ -1,4 +1,4 @@
 #
-# Copyright (c) 2011 Vojtech Horky
+# Copyright (c) 2012 Sean Bartell
 # All rights reserved.
 #
Index: uspace/app/bithenge/blob.c
===================================================================
--- uspace/app/bithenge/blob.c	(revision a54bd98c747d436ac3c8c8d96b5ba234d90c7f3e)
+++ uspace/app/bithenge/blob.c	(revision 743ce51407c2a076fa30bb9302d283626219a3d4)
@@ -35,4 +35,5 @@
  */
 
+#include <assert.h>
 #include <bool.h>
 #include <errno.h>
@@ -45,16 +46,23 @@
  * @memberof bithenge_blob_t
  * @param[out] blob The blob to initialize.
- * @param[in] ops Operations provided random access support. This pointer must
+ * @param[in] ops Operations providing random access support. This pointer must
  * be valid until the blob is destroyed.
  * @return EOK on success or an error code from errno.h.
  */
-int bithenge_new_random_access_blob(
-		bithenge_blob_t *blob,
-		const bithenge_random_access_blob_ops_t *ops) {
+int bithenge_new_random_access_blob(bithenge_blob_t *blob,
+    const bithenge_random_access_blob_ops_t *ops)
+{
+	assert(blob);
+	assert(ops);
+	assert(ops->destroy);
+	assert(ops->read);
+	assert(ops->size);
+
 	blob->ops = ops;
 	return EOK;
 }
 
-static int sequential_buffer(bithenge_sequential_blob_t *blob, aoff64_t end) {
+static int sequential_buffer(bithenge_sequential_blob_t *blob, aoff64_t end)
+{
 	bool need_realloc = false;
 	while (end > blob->buffer_size) {
@@ -65,8 +73,8 @@
 		char *buffer = realloc(blob->buffer, blob->buffer_size);
 		if (!buffer)
-			return errno;
+			return ENOMEM;
 		blob->buffer = buffer;
 	}
-	size_t size = end - blob->data_size;
+	aoff64_t size = end - blob->data_size;
 	int rc = blob->ops->read(blob, blob->buffer + blob->data_size, &size);
 	if (rc != EOK)
@@ -76,22 +84,28 @@
 }
 
-static int sequential_size(bithenge_blob_t *base, aoff64_t *size) {
+static int sequential_size(bithenge_blob_t *base, aoff64_t *size)
+{
 	bithenge_sequential_blob_t *blob = (bithenge_sequential_blob_t *)base;
-	int rc = blob->ops->size(blob, size);
-	if (rc != EOK) {
-		rc = sequential_buffer(blob, blob->buffer_size);
+	int rc;
+	if (blob->ops->size) {
+		rc = blob->ops->size(blob, size);
+		if (rc == EOK)
+			return EOK;
+	}
+	rc = sequential_buffer(blob, blob->buffer_size);
+	if (rc != EOK)
+		return rc;
+	while (blob->data_size == blob->buffer_size) {
+		rc = sequential_buffer(blob, 2 * blob->buffer_size);
 		if (rc != EOK)
 			return rc;
-		while (blob->data_size == blob->buffer_size) {
-			rc = sequential_buffer(blob, 2 * blob->buffer_size);
-			if (rc != EOK)
-				return rc;
-		}
-		*size = blob->data_size;
 	}
+	*size = blob->data_size;
 	return EOK;
 }
 
-static int sequential_read(bithenge_blob_t *base, aoff64_t offset, char *buffer, aoff64_t *size) {
+static int sequential_read(bithenge_blob_t *base, aoff64_t offset,
+    char *buffer, aoff64_t *size)
+{
 	bithenge_sequential_blob_t *blob = (bithenge_sequential_blob_t *)base;
 	aoff64_t end = offset + *size;
@@ -108,5 +122,6 @@
 }
 
-static int sequential_destroy(bithenge_blob_t *base) {
+static int sequential_destroy(bithenge_blob_t *base)
+{
 	bithenge_sequential_blob_t *blob = (bithenge_sequential_blob_t *)base;
 	free(blob->buffer);
@@ -127,7 +142,13 @@
  * @return EOK on success or an error code from errno.h.
  */
-int bithenge_new_sequential_blob(
-		bithenge_sequential_blob_t *blob,
-		const bithenge_sequential_blob_ops_t *ops) {
+int bithenge_new_sequential_blob(bithenge_sequential_blob_t *blob,
+    const bithenge_sequential_blob_ops_t *ops)
+{
+	assert(blob);
+	assert(ops);
+	assert(ops->destroy);
+	assert(ops->read);
+	// ops->size is optional
+
 	int rc = bithenge_new_random_access_blob(&blob->base, &sequential_ops);
 	if (rc != EOK)
Index: uspace/app/bithenge/blob.h
===================================================================
--- uspace/app/bithenge/blob.h	(revision a54bd98c747d436ac3c8c8d96b5ba234d90c7f3e)
+++ uspace/app/bithenge/blob.h	(revision 743ce51407c2a076fa30bb9302d283626219a3d4)
@@ -78,7 +78,34 @@
  * @memberof bithenge_sequential_blob_t */
 typedef struct bithenge_sequential_blob_ops_t {
+
+	/** Get the total size of the blob. If the total size cannot be
+	 * determined easily, this field may be null or return an error,
+	 * forcing the entire blob to be read to determine its size.
+	 *
+	 * @memberof bithenge_blob_t
+	 * @param blob The blob.
+	 * @param[out] size Total size of the blob.
+	 * @return EOK on success or an error code from errno.h.
+	 */
 	int (*size)(bithenge_sequential_blob_t *blob, aoff64_t *size);
+
+	/** Read the next part of the blob. If the requested data extends
+	 * beyond the end of the blob, the data up until the end of the blob
+	 * will be read.
+	 *
+	 * @param blob The blob.
+	 * @param[out] buffer Buffer to read into. If an error occurs, the contents are
+	 * undefined.
+	 * @param[in,out] size Number of bytes to read; may be 0. If not enough
+	 * data is left in the blob, the actual number of bytes read should be
+	 * stored here. If an error occurs, the contents are undefined.
+	 * @return EOK on success or an error code from errno.h.
+	 */
 	int (*read)(bithenge_sequential_blob_t *blob, char *buffer,
 	    aoff64_t *size);
+
+	/** Destroy the blob.
+	 * @param blob The blob.
+	 * @return EOK on success or an error code from errno.h. */
 	int (*destroy)(bithenge_sequential_blob_t *blob);
 } bithenge_sequential_blob_ops_t;
@@ -91,5 +118,8 @@
  * @return EOK on success or an error code from errno.h.
  */
-static inline int bithenge_blob_size(bithenge_blob_t *blob, aoff64_t *size) {
+static inline int bithenge_blob_size(bithenge_blob_t *blob, aoff64_t *size)
+{
+	assert(blob);
+	assert(blob->ops);
 	return blob->ops->size(blob, size);
 }
@@ -110,5 +140,9 @@
  * @return EOK on success or an error code from errno.h.
  */
-static inline int bithenge_blob_read(bithenge_blob_t *blob, aoff64_t offset, char *buffer, aoff64_t *size) {
+static inline int bithenge_blob_read(bithenge_blob_t *blob, aoff64_t offset,
+    char *buffer, aoff64_t *size)
+{
+	assert(blob);
+	assert(blob->ops);
 	return blob->ops->read(blob, offset, buffer, size);
 }
@@ -119,5 +153,8 @@
  * @return EOK on success or an error code from errno.h.
  */
-static inline int bithenge_blob_destroy(bithenge_blob_t *blob) {
+static inline int bithenge_blob_destroy(bithenge_blob_t *blob)
+{
+	assert(blob);
+	assert(blob->ops);
 	return blob->ops->destroy(blob);
 }
Index: uspace/app/bithenge/block.c
===================================================================
--- uspace/app/bithenge/block.c	(revision a54bd98c747d436ac3c8c8d96b5ba234d90c7f3e)
+++ uspace/app/bithenge/block.c	(revision 743ce51407c2a076fa30bb9302d283626219a3d4)
@@ -36,4 +36,5 @@
  */
 
+#include <assert.h>
 #include <errno.h>
 #include <libblock.h>
@@ -50,5 +51,6 @@
 } block_blob_t;
 
-static int block_size(bithenge_blob_t *base, aoff64_t *size) {
+static int block_size(bithenge_blob_t *base, aoff64_t *size)
+{
 	block_blob_t *blob = (block_blob_t *)base;
 	*size = blob->size;
@@ -56,5 +58,7 @@
 }
 
-static int block_read(bithenge_blob_t *base, aoff64_t offset, char *buffer, aoff64_t *size) {
+static int block_read(bithenge_blob_t *base, aoff64_t offset, char *buffer,
+    aoff64_t *size)
+{
 	block_blob_t *blob = (block_blob_t *)base;
 	if (offset > blob->size)
@@ -64,5 +68,6 @@
 }
 
-static int block_destroy(bithenge_blob_t *base) {
+static int block_destroy(bithenge_blob_t *base)
+{
 	block_blob_t *blob = (block_blob_t *)base;
 	block_fini(blob->service_id);
@@ -82,5 +87,8 @@
  * @param service_id The service ID of the block device.
  * @return EOK on success or an error code from errno.h. */
-int bithenge_new_block_blob(bithenge_blob_t **out, service_id_t service_id) {
+int bithenge_new_block_blob(bithenge_blob_t **out, service_id_t service_id)
+{
+	assert(out);
+
 	// Initialize libblock
 	int rc;
@@ -104,5 +112,5 @@
 	block_blob_t *blob = malloc(sizeof(*blob));
 	if (!blob)
-		return errno;
+		return ENOMEM;
 	rc = bithenge_new_random_access_blob(&blob->base, &block_ops);
 	if (rc != EOK) {
Index: uspace/app/bithenge/block.h
===================================================================
--- uspace/app/bithenge/block.h	(revision a54bd98c747d436ac3c8c8d96b5ba234d90c7f3e)
+++ uspace/app/bithenge/block.h	(revision 743ce51407c2a076fa30bb9302d283626219a3d4)
@@ -38,6 +38,6 @@
 #define BITHENGE_BLOCK_H_
 
+#include <loc.h>
 #include "blob.h"
-#include "loc.h"
 
 int bithenge_new_block_blob(bithenge_blob_t **, service_id_t);
Index: uspace/app/bithenge/test.c
===================================================================
--- uspace/app/bithenge/test.c	(revision a54bd98c747d436ac3c8c8d96b5ba234d90c7f3e)
+++ uspace/app/bithenge/test.c	(revision 743ce51407c2a076fa30bb9302d283626219a3d4)
@@ -42,5 +42,6 @@
 
 static void
-print_data(const char *data, size_t len) {
+print_data(const char *data, size_t len)
+{
 	while (len--)
 		printf("%02x ", (uint8_t)(*data++));
@@ -49,5 +50,6 @@
 
 static void
-print_blob(bithenge_blob_t *blob) {
+print_blob(bithenge_blob_t *blob)
+{
 	aoff64_t size;
 	bithenge_blob_size(blob, &size);
@@ -59,5 +61,6 @@
 }
 
-int main(int argc, char *argv[]) {
+int main(int argc, char *argv[])
+{
 	service_id_t service_id;
 	loc_service_get_id("bd/initrd", &service_id, 0);
