Bunch More Work on VCDIFF code. Still lots to do. default tip
authorRyan C. Gordon <icculus@icculus.org>
Sat, 24 Jan 2009 02:04:45 -0500
changeset 111 c7a7992c1636
parent 110 f7462c703a54
Bunch More Work on VCDIFF code. Still lots to do.
vcdiff.c
vcdiff.h
--- a/vcdiff.c	Mon Apr 14 03:42:09 2008 +0000
+++ b/vcdiff.c	Sat Jan 24 02:04:45 2009 -0500
@@ -11,14 +11,11 @@
  * Written based on the RFC: http://www.faqs.org/rfcs/rfc3284.html
  */
 
-#include <stdio.h>
 #include <stdlib.h>
-#include <sys/types.h>
+#include <string.h>
+//#include <sys/types.h>
 
-#if (defined(_MSC_VER) && !defined(inline))
-#define inline _inline
-#endif
-
+#include "vcdiff.h"
 
 static inline uint32 swapui32(uint32 x)
 {
@@ -88,17 +85,42 @@
 } /* Read_ui32 */
 
 
+static inline int Read_ui8(vcdiff_io *io, uint8 *ui8)
+{
+    return Read(io, ui8, sizeof (*ui8));
+} /* Read_ui8 */
+
+
+
 typedef struct
 {
-    vcdiff_io *src;
-    vcdiff_io *delta;
-    vcdiff_io *dst;
+    /* allocator. */
+    vcdiff_malloc malloc;
+    vcdiff_free free;
+    void *malloc_data;
+
+    /* i/o streams. */
+    vcdiff_io *iosrc;
+    vcdiff_io *iodelta;
+    vcdiff_io *iodst;
+
+    /* Data from header. */
     uint8 compressor;
     uint32 tablelen;
     uint8 *codetable;
-    vcdiff_malloc malloc;
-    vcdiff_free free;
-    void *malloc_data;
+
+    /* Data from current target window. */
+    uint8 deltaindicator;
+    uint32 srcdatalen;
+    uint32 encodinglen;
+    uint32 targetwinlen;
+    uint32 addrunlen;
+    uint32 instlen;
+    uint32 copylen;
+    uint8 *srcdata;
+    uint8 *copys;
+    uint8 *insts;
+    uint8 *addruns;
 } vcdiff_ctx;
 
 
@@ -110,16 +132,43 @@
 } /* Malloc */
 
 
-static inline void Free(const Context *ctx, void *ptr)
+static inline void Free(const vcdiff_ctx *ctx, void *ptr)
 {
     if (ptr != NULL) /* check for NULL in case of dumb free() impl. */
         ctx->free(ptr, ctx->malloc_data);
 } /* Free */
 
 
+static void free_delta_window_data(vcdiff_ctx *ctx)
+{
+    Free(ctx, ctx->copys);
+    Free(ctx, ctx->insts);
+    Free(ctx, ctx->addruns);
+    Free(ctx, ctx->srcdata);
+    ctx->copys = NULL;
+    ctx->insts = NULL;
+    ctx->addruns = NULL;
+    ctx->srcdata = NULL;
+    ctx->deltaindicator = 0;
+    ctx->srcdatalen = 0;
+    ctx->encodinglen = 0;
+    ctx->targetwinlen = 0;
+    ctx->addrunlen = 0;
+    ctx->instlen = 0;
+    ctx->copylen = 0;
+} /* free_delta_window_data */
+
+
+static int process_delta_window(vcdiff_ctx *ctx)
+{
+    /* !!! FIXME: write me. */
+    return 0;
+} /* process_delta_window */
+
+
 static int read_delta_header(vcdiff_ctx *ctx)
 {
-    vcdiff_io *io = ctx->delta;
+    vcdiff_io *io = ctx->iodelta;
     uint8 sig[5];
     if (!Read(io, sig, sizeof (sig)))
         return 0;
@@ -138,7 +187,7 @@
 
         if (has_compressor)
         {
-            if (!Read(io, &ctx->compressor, sizeof (compressor)))
+            if (!Read(io, &ctx->compressor, sizeof (ctx->compressor)))
                 return 0;
             return 0;  /* !!! FIXME: unsupported at the moment. */
         } /* if */
@@ -159,15 +208,12 @@
     return 1;
 } /* read_delta_header */
 
+
 static int _read_delta_window(vcdiff_ctx *ctx, const uint8 indicator)
 {
-    vcdiff_io *io = ctx->delta;
+    vcdiff_io *io = ctx->iodelta;
     const int source = (indicator & (1 << 0)) ? 1 : 0;
     const int target = (indicator & (1 << 1)) ? 1 : 0;
-    uint32 len = 0;
-    uint32 pos = 0;
-    vcdiff_io *srcio = NULL;
-    uint8 *srcdata = NULL;
 
     if ((indicator & 0xFC) != 0)
         return 0;  /* bits we weren't expecting are set. */
@@ -175,36 +221,73 @@
         return 0;  /* can't have both! */
     else if ((source) || (target))
     {
-        if (!Read_ui32(io, &len))
+        uint32 pos = 0;
+        if (!Read_ui32(io, &ctx->srcdatalen))
             return 0;
         else if (!Read_ui32(io, &pos))
             return 0;
-        srcio = (source) ? ctx->src : ctx->dst;
-        srcdata = (uint8 *) Malloc(ctx, len);
-        if (srcdata == NULL)
-            return 0;
-        if ( (!Seek(srcio, pos)) || (!Read(srcio, srcdata, len)) )
+        else
         {
-            Free(src, srcdata);
-            return 0;
-        } /* if */
+            vcdiff_io *srcio = (source) ? ctx->iosrc : ctx->iodst;
+            ctx->srcdata = (uint8 *) Malloc(ctx, ctx->srcdatalen);
+            if (ctx->srcdata == NULL)
+                return 0;
+            else if (!Seek(srcio, pos))
+                return 0;
+            else if (!Read(srcio, ctx->srcdata, ctx->srcdatalen))
+                return 0;
+        } /* else */
     } /* else if */
 
-    
+    if (!Read_ui32(io, &ctx->encodinglen))
+        return 0;
+    else if (!Read_ui32(io, &ctx->targetwinlen))
+        return 0;
+    else if (!Read_ui8(io, &ctx->deltaindicator))
+        return 0;
+    else if (!Read_ui32(io, &ctx->addrunlen))
+        return 0;
+    else if (!Read_ui32(io, &ctx->instlen))
+        return 0;
+    else if (!Read_ui32(io, &ctx->copylen))
+        return 0;
 
-    Free(ctx, srcdata);
+    if (ctx->deltaindicator != 0x00)   /* !!! FIXME: decompression bits. */
+        return 0;
+
+    if ((ctx->addruns = (uint8 *) Malloc(ctx, ctx->addrunlen)) == NULL)
+        return 0;
+    else if (!Read(io, ctx->addruns, ctx->addrunlen))
+        return 0;
+
+    else if ((ctx->insts = (uint8 *) Malloc(ctx, ctx->instlen)) == NULL)
+        return 0;
+    else if (!Read(io, ctx->insts, ctx->instlen))
+        return 0;
+
+    else if ((ctx->copys = (uint8 *) Malloc(ctx, ctx->copylen)) == NULL)
+        return 0;
+    else if (!Read(io, ctx->copys, ctx->copylen))
+        return 0;
+
+    return 1;  /* success. */
 } /* _read_delta_window */
 
+
 static int read_delta_window(vcdiff_ctx *ctx)
 {
-    vcdiff_io *io = ctx->delta;
+    vcdiff_io *io = ctx->iodelta;
     uint8 indicator;
-    int64 br = io->read(io->ctx, &indicator, sizeof (indicator));
+    int64 br = 0;
+
+    free_delta_window_data(ctx);
+
+    br = io->read(io->ctx, &indicator, sizeof (indicator));
     if (br == 0)
         return 0;  /* EOF. We're done! */
     else if (br == -1)
         return -1; /* Error. We're also done. */
-    return _read_delta_window(ctx, indicator);
+    return (_read_delta_window(ctx, indicator) ? 1 : -1);
 } /* read_delta_window */
 
 
@@ -216,7 +299,8 @@
     else
     {
         int rc;
-        while ((rc = read_delta_window(ctx)) == 1) { /* keep looping. */ }
+        while ((rc = read_delta_window(ctx)) == 1)
+            rc = process_delta_window(ctx);
         if (rc == -1)
             return 0;  /* error, not successful EOF. */
     } /* else */
@@ -238,6 +322,7 @@
     ctx.free = (f != NULL) ? f : internal_free;
     ctx.malloc_data = d;
     retval = _vcdiff(&ctx);
+    free_delta_window_data(&ctx);
     Free(&ctx, ctx.codetable);
     return retval;
 } /* vcdiff */
@@ -269,7 +354,7 @@
     fclose(iodst);
 
     if (!rc)
-        unlink(dst);
+        remove(dst);
 
     return rc;
 } /* vcdiff_fname */
--- a/vcdiff.h	Mon Apr 14 03:42:09 2008 +0000
+++ b/vcdiff.h	Sat Jan 24 02:04:45 2009 -0500
@@ -1,18 +1,24 @@
 #ifndef _INCL_VCDIFF_H_
 #define _INCL_VCDIFF_H_
 
+#if !defined(VCDIFF_NO_STDIO)
 #include <stdio.h>
+#endif
 
-#ifdef _MSC_VER
-#define inline _inline
-typedef unsigned char uint8;
-typedef unsigned int uint32;
-typedef __int64 int64;
+#if defined(_MSC_VER)
+    #if !defined(inline)
+    #define inline _inline
+    #endif
+    typedef __int64 int64;
+    typedef unsigned __int64 uint64;
+    typedef unsigned __int32 uint32;
+    typedef unsigned __int8 uint8;
 #else
-#include <stdint.h>
-typedef uint8_t uint8;
-typedef uint32_t uint32;
-typedef int64_t int64;
+    #include <stdint.h>
+    typedef uint64_t uint64;
+    typedef int64_t int64;
+    typedef uint32_t uint32;
+    typedef uint8_t uint8;
 #endif
 
 /*
@@ -50,6 +56,7 @@
            vcdiff_malloc m, vcdiff_free f, void *d);
 
 
+#if !defined(VCDIFF_NO_STDIO)
 /* !!! FIXME: documentation. */
 /*
  *(fiosrc) and (fiodelta) need read access, (fiodst) needs read
@@ -57,6 +64,7 @@
  */
 int vcdiff_stdio(FILE *fiosrc, FILE *fiodelta, FILE *fiodst,
                  vcdiff_malloc m, vcdiff_free f, void *d);
+#endif
 
 
 /* !!! FIXME: documentation. */