delta.con commit [PATCH] Constness fix for pickaxe option. (057c7d3)
   1#include "object.h"
   2#include "blob.h"
   3#include "tree.h"
   4#include "commit.h"
   5#include "tag.h"
   6#include "delta.h"
   7#include "cache.h"
   8#include <string.h>
   9
  10/* the delta object definition (it can alias any other object) */
  11struct delta {
  12        union {
  13                struct object object;
  14                struct blob blob;
  15                struct tree tree;
  16                struct commit commit;
  17                struct tag tag;
  18        } u;
  19};
  20
  21struct delta *lookup_delta(unsigned char *sha1)
  22{
  23        struct object *obj = lookup_object(sha1);
  24        if (!obj) {
  25                struct delta *ret = xmalloc(sizeof(struct delta));
  26                memset(ret, 0, sizeof(struct delta));
  27                created_object(sha1, &ret->u.object);
  28                return ret;
  29        }
  30        return (struct delta *) obj;
  31}
  32
  33int parse_delta_buffer(struct delta *item, void *buffer, unsigned long size)
  34{
  35        struct object *reference;
  36        struct object_list *p;
  37
  38        if (item->u.object.delta)
  39                return 0;
  40        item->u.object.delta = 1;
  41        if (size <= 20)
  42                return -1;
  43        reference = lookup_object(buffer);
  44        if (!reference) {
  45                struct delta *ref = xmalloc(sizeof(struct delta));
  46                memset(ref, 0, sizeof(struct delta));
  47                created_object(buffer, &ref->u.object);
  48                reference = &ref->u.object;
  49        }
  50
  51        p = xmalloc(sizeof(*p));
  52        p->item = &item->u.object;
  53        p->next = reference->attached_deltas;
  54        reference->attached_deltas = p;
  55        return 0;
  56}
  57
  58int process_deltas(void *src, unsigned long src_size, const char *src_type,
  59                   struct object_list *delta_list)
  60{
  61        int deepest = 0;
  62        do {
  63                struct object *obj = delta_list->item;
  64                static char type[10];
  65                void *map, *delta, *buf;
  66                unsigned long map_size, delta_size, buf_size;
  67                map = map_sha1_file(obj->sha1, &map_size);
  68                if (!map)
  69                        continue;
  70                delta = unpack_sha1_file(map, map_size, type, &delta_size);
  71                munmap(map, map_size);
  72                if (!delta)
  73                        continue;
  74                if (strcmp(type, "delta") || delta_size <= 20) {
  75                        free(delta);
  76                        continue;
  77                }
  78                buf = patch_delta(src, src_size,
  79                                  delta+20, delta_size-20,
  80                                  &buf_size);
  81                free(delta);
  82                if (!buf)
  83                        continue;
  84                if (check_sha1_signature(obj->sha1, buf, buf_size, src_type) < 0)
  85                        printf("sha1 mismatch for delta %s\n", sha1_to_hex(obj->sha1));
  86                if (obj->type && obj->type != src_type) {
  87                        error("got %s when expecting %s for delta %s",
  88                              src_type, obj->type, sha1_to_hex(obj->sha1));
  89                        free(buf);
  90                        continue;
  91                }
  92                obj->type = src_type;
  93                if (src_type == blob_type) {
  94                        parse_blob_buffer((struct blob *)obj, buf, buf_size);
  95                } else if (src_type == tree_type) {
  96                        parse_tree_buffer((struct tree *)obj, buf, buf_size);
  97                } else if (src_type == commit_type) {
  98                        parse_commit_buffer((struct commit *)obj, buf, buf_size);
  99                } else if (src_type == tag_type) {
 100                        parse_tag_buffer((struct tag *)obj, buf, buf_size);
 101                } else {
 102                        error("unknown object type %s", src_type);
 103                        free(buf);
 104                        continue;
 105                }
 106                if (obj->attached_deltas) {
 107                        int depth = process_deltas(buf, buf_size, src_type,
 108                                                   obj->attached_deltas);
 109                        if (deepest < depth)
 110                                deepest = depth;
 111                }
 112                free(buf);
 113        } while ((delta_list = delta_list->next));
 114        return deepest + 1;
 115}