Move ZIP_CODEC defines to zipint.h (not public). Add zip_source_seek_compute_offset
to simplify ZIP_SOURCE_SEEK implementations.
diff --git a/TODO b/TODO
index 9a1cecb..606543c 100644
--- a/TODO
+++ b/TODO
@@ -75,6 +75,9 @@
 
 Cleanup
 =======
+* use bool
+* use ZIP_SOURCE_SUPPORTS_{READABLE,SEEKABLE,WRITABLE}
+* use zip_source_seek_compute_offset
 * move compat refs from zipint.h to own file, and include that in zipint.h and src
 * get rid of zip_get_{compression,encryption}_implementation
 * use zip_*int*_t internally
@@ -275,6 +278,7 @@
 ** int zip_source_commit_write(zip_source_t *);
 ** void zip_source_rollback_write(zip_source_t *);
 ** zip_int64_t zip_source_write(zip_source_t *, const void *, zip_uint64_t);
+** zip_int64_t zip_source_seek_compute_offset(zip_uint64_t offset, zip_uint64_t length, void *data, zip_uint64_t data_length, zip_error_t *error);
 - document deprecations
 ** int zip_error_get_sys_type(int); /* use zip_error_system_type */
 ** void zip_error_get(zip_t *, int *, int *); /* use zip_get_error, zip_error_code_zip / zip_error_code_system */
diff --git a/lib/zip.h b/lib/zip.h
index 5539930..aa9b683 100644
--- a/lib/zip.h
+++ b/lib/zip.h
@@ -100,11 +100,6 @@
 #define ZIP_EXTRA_FIELD_ALL	ZIP_UINT16_MAX
 #define ZIP_EXTRA_FIELD_NEW	ZIP_UINT16_MAX
 
-/* flags for compression and encryption sources */
-
-#define ZIP_CODEC_DECODE	0 /* decompress/decrypt (encode flag not set) */
-#define ZIP_CODEC_ENCODE	1 /* compress/encrypt */
-
 
 /* libzip error codes */
 
@@ -396,6 +391,7 @@
 ZIP_EXTERN int zip_source_open(zip_source_t *);
 ZIP_EXTERN zip_int64_t zip_source_read(zip_source_t *, void *, zip_uint64_t);
 ZIP_EXTERN void zip_source_rollback_write(zip_source_t *);
+ZIP_EXTERN zip_int64_t zip_source_seek_compute_offset(zip_uint64_t, zip_uint64_t, void *, zip_uint64_t, zip_error_t *);
 ZIP_EXTERN int zip_source_stat(zip_source_t *, zip_stat_t *);
 ZIP_EXTERN zip_int64_t zip_source_write(zip_source_t *, const void *, zip_uint64_t);
 ZIP_EXTERN zip_source_t *zip_source_zip(zip_t *, zip_t *, zip_uint64_t, zip_flags_t, zip_uint64_t, zip_int64_t);
diff --git a/lib/zip_set_file_compression.c b/lib/zip_set_file_compression.c
index 1e45f24..7bb0bf9 100644
--- a/lib/zip_set_file_compression.c
+++ b/lib/zip_set_file_compression.c
@@ -36,8 +36,7 @@
 
 
 ZIP_EXTERN int
-zip_set_file_compression(zip_t *za, zip_uint64_t idx,
-			 zip_int32_t method, zip_uint32_t flags)
+zip_set_file_compression(zip_t *za, zip_uint64_t idx, zip_int32_t method, zip_uint32_t flags)
 {
     zip_entry_t *e;
     zip_int32_t old_method;
diff --git a/lib/zip_source_buffer.c b/lib/zip_source_buffer.c
index 3914733..4ecec6b 100644
--- a/lib/zip_source_buffer.c
+++ b/lib/zip_source_buffer.c
@@ -361,36 +361,13 @@
 static int
 buffer_seek(buffer_t *buffer, void *data, zip_uint64_t len, zip_error_t *error)
 {
-    zip_int64_t offset;
-    zip_source_args_seek_t *args = ZIP_SOURCE_GET_ARGS(zip_source_args_seek_t, data, len, error);
-
-    if (args == NULL)
-	return -1;
-
-    switch (args->whence) {
-    case SEEK_CUR:
-	offset = (zip_int64_t)buffer->offset + args->offset;
-	break;
-                    
-    case SEEK_END:
-	offset = (zip_int64_t)buffer->size + args->offset;
-	break;
-
-    case SEEK_SET:
-	offset = (zip_int64_t)args->offset;
-	break;
-
-    default:
-	zip_error_set(error, ZIP_ER_INVAL, 0);
-	return -1;
+    zip_int64_t new_offset = zip_source_seek_compute_offset(buffer->offset, buffer->size, data, len, error);
+    
+    if (new_offset < 0) {
+        return -1;
     }
-
-    if (offset < 0 || (zip_uint64_t)offset > buffer->size) {
-	zip_error_set(error, ZIP_ER_INVAL, 0);
-	return -1;
-    }
-
-    buffer->offset = (zip_uint64_t)offset;
+    
+    buffer->offset = (zip_uint64_t)new_offset;
     return 0;
 }
 
diff --git a/lib/zip_source_seek.c b/lib/zip_source_seek.c
index 24fc05c..6779ad7 100644
--- a/lib/zip_source_seek.c
+++ b/lib/zip_source_seek.c
@@ -53,3 +53,40 @@
     
     return (_zip_source_call(src, &args, sizeof(args), ZIP_SOURCE_SEEK) < 0 ? -1 : 0);
 }
+
+
+zip_int64_t
+zip_source_seek_compute_offset(zip_uint64_t offset, zip_uint64_t length, void *data, zip_uint64_t data_length, zip_error_t *error)
+{
+    zip_int64_t new_offset;
+    zip_source_args_seek_t *args = ZIP_SOURCE_GET_ARGS(zip_source_args_seek_t, data, data_length, error);
+    
+    if (args == NULL) {
+        return -1;
+    }
+    
+    switch (args->whence) {
+        case SEEK_CUR:
+            new_offset = (zip_int64_t)offset + args->offset;
+            break;
+            
+        case SEEK_END:
+            new_offset = (zip_int64_t)length + args->offset;
+            break;
+            
+        case SEEK_SET:
+            new_offset = args->offset;
+            break;
+            
+        default:
+            zip_error_set(error, ZIP_ER_INVAL, 0);
+            return -1;
+    }
+    
+    if (new_offset < 0 || (zip_uint64_t)new_offset > length) {
+        zip_error_set(error, ZIP_ER_INVAL, 0);
+        return -1;
+    }
+    
+    return new_offset;
+}
diff --git a/lib/zip_source_window.c b/lib/zip_source_window.c
index 69a0c91..f02d048 100644
--- a/lib/zip_source_window.c
+++ b/lib/zip_source_window.c
@@ -180,36 +180,13 @@
             
         case ZIP_SOURCE_SEEK:
         {
-            zip_int64_t new_offset;
-	    zip_source_args_seek_t *args = ZIP_SOURCE_GET_ARGS(zip_source_args_seek_t, data, len, &ctx->error);
+            zip_int64_t new_offset = zip_source_seek_compute_offset(ctx->offset - ctx->start, ctx->end - ctx->start, data, len, &ctx->error);
 
-	    if (args == NULL)
-		return -1;
-            
-            switch (args->whence) {
-                case SEEK_CUR:
-                    new_offset = (zip_int64_t)ctx->offset + args->offset;
-                    break;
-                    
-                case SEEK_END:
-                    new_offset = (zip_int64_t)ctx->end + args->offset;
-                    break;
-                    
-                case SEEK_SET:
-                    new_offset = (zip_int64_t)ctx->start + args->offset;
-                    break;
-
-		default:
-                    zip_error_set(&ctx->error, ZIP_ER_INVAL, 0);
-                    return -1;
-            }
-            
-            if (new_offset < (zip_int64_t)ctx->start || (zip_uint64_t)new_offset > ctx->end) {
-                zip_error_set(&ctx->error, ZIP_ER_INVAL, 0);
+            if (new_offset < 0) {
                 return -1;
             }
             
-            ctx->offset = (zip_uint64_t)new_offset;
+            ctx->offset = (zip_uint64_t)new_offset + ctx->start;
             return 0;
         }
 
diff --git a/lib/zipint.h b/lib/zipint.h
index bab9d43..9111949 100644
--- a/lib/zipint.h
+++ b/lib/zipint.h
@@ -180,6 +180,12 @@
 /* This section contains API that won't materialize like this.  It's
    placed in the internal section, pending cleanup. */
 
+/* flags for compression and encryption sources */
+
+#define ZIP_CODEC_DECODE	0 /* decompress/decrypt (encode flag not set) */
+#define ZIP_CODEC_ENCODE	1 /* compress/encrypt */
+
+
 typedef zip_source_t *(*zip_compression_implementation)(zip_t *, zip_source_t *, zip_int32_t, int);
 typedef zip_source_t *(*zip_encryption_implementation)(zip_t *, zip_source_t *, zip_uint16_t, int, const char *);
 
@@ -273,7 +279,7 @@
 
     zip_string_t *comment_orig;         /* archive comment */
     zip_string_t *comment_changes;  /* changed archive comment */
-    int comment_changed;		/* whether archive comment was changed */
+    bool comment_changed;		/* whether archive comment was changed */
 
     zip_uint64_t nentry;		/* number of entries */
     zip_uint64_t nentry_alloc;		/* number of entries allocated */
@@ -291,7 +297,7 @@
 struct zip_file {
     zip_t *za;		/* zip archive containing this file */
     zip_error_t error;	/* error information */
-    int eof;
+    bool eof;
     zip_source_t *src;	/* data source */
 };
 
@@ -307,8 +313,8 @@
 
 struct zip_dirent {
     zip_uint32_t changed;
-    int local_extra_fields_read;	/*      whether we already read in local header extra fields */
-    int cloned;                         /*      whether this instance is cloned, and thus shares non-changed strings */
+    bool local_extra_fields_read;	/*      whether we already read in local header extra fields */
+    bool cloned;                         /*      whether this instance is cloned, and thus shares non-changed strings */
 
     zip_uint16_t version_madeby;	/* (c)  version of creator */
     zip_uint16_t version_needed;	/* (cl) version needed to extract */
@@ -381,7 +387,7 @@
     zip_dirent_t *orig;
     zip_dirent_t *changes;
     zip_source_t *source;
-    int deleted;
+    bool deleted;
 };
 
 
diff --git a/regress/source_hole.c b/regress/source_hole.c
index 29cf888..95d7fa7 100644
--- a/regress/source_hole.c
+++ b/regress/source_hole.c
@@ -268,39 +268,13 @@
 static zip_int64_t
 buffer_seek(buffer_t *buffer, void *data, zip_uint64_t length, zip_error_t *error)
 {
-    zip_source_args_seek_t *args = ZIP_SOURCE_GET_ARGS(zip_source_args_seek_t, data, length, error);
-    zip_int64_t offset;
-    
-    if (args == NULL) {
+    zip_int64_t new_offset = zip_source_seek_compute_offset(buffer->offset, buffer->size, data, length, error);
+
+    if (new_offset < 0) {
         return -1;
     }
     
-    /* TODO: check for overflow */
-    switch (args->whence) {
-        case SEEK_CUR:
-            offset = (zip_int64_t)buffer->offset + args->offset;
-            break;
-            
-        case SEEK_END:
-            offset = (zip_int64_t)buffer->size + args->offset;
-            break;
-            
-        case SEEK_SET:
-            offset = args->offset;
-            break;
-            
-        default:
-            offset = -1;
-            break;
-    }
-    
-    if (offset < 0 || offset > (zip_int64_t)buffer->size) {
-        zip_error_set(error, ZIP_ER_INVAL, 0);
-        return -1;
-    }
-    
-    buffer->offset = (zip_uint64_t)offset;
-    
+    buffer->offset = (zip_uint64_t)new_offset;
     return 0;
 }