Integrate hash algorithm support with repo setup
[gitweb.git] / sha1_file.c
index d7de8184edba767f0ffced8e3bd29db92b4e68af..a04389be71dc27f18106226d3c24624e4b62434b 100644 (file)
@@ -39,6 +39,64 @@ const struct object_id empty_blob_oid = {
        EMPTY_BLOB_SHA1_BIN_LITERAL
 };
 
+static void git_hash_sha1_init(void *ctx)
+{
+       git_SHA1_Init((git_SHA_CTX *)ctx);
+}
+
+static void git_hash_sha1_update(void *ctx, const void *data, size_t len)
+{
+       git_SHA1_Update((git_SHA_CTX *)ctx, data, len);
+}
+
+static void git_hash_sha1_final(unsigned char *hash, void *ctx)
+{
+       git_SHA1_Final(hash, (git_SHA_CTX *)ctx);
+}
+
+static void git_hash_unknown_init(void *ctx)
+{
+       die("trying to init unknown hash");
+}
+
+static void git_hash_unknown_update(void *ctx, const void *data, size_t len)
+{
+       die("trying to update unknown hash");
+}
+
+static void git_hash_unknown_final(unsigned char *hash, void *ctx)
+{
+       die("trying to finalize unknown hash");
+}
+
+const struct git_hash_algo hash_algos[GIT_HASH_NALGOS] = {
+       {
+               NULL,
+               0x00000000,
+               0,
+               0,
+               0,
+               git_hash_unknown_init,
+               git_hash_unknown_update,
+               git_hash_unknown_final,
+               NULL,
+               NULL,
+       },
+       {
+               "sha-1",
+               /* "sha1", big-endian */
+               0x73686131,
+               sizeof(git_SHA_CTX),
+               GIT_SHA1_RAWSZ,
+               GIT_SHA1_HEXSZ,
+               git_hash_sha1_init,
+               git_hash_sha1_update,
+               git_hash_sha1_final,
+               &empty_tree_oid,
+               &empty_blob_oid,
+       },
+};
+
 /*
  * This is meant to hold a *small* number of objects that you would
  * want read_sha1_file() to be able to return, but yet you do not want
@@ -1881,6 +1939,7 @@ int for_each_file_in_obj_subdir(unsigned int subdir_nr,
        DIR *dir;
        struct dirent *de;
        int r = 0;
+       struct object_id oid;
 
        if (subdir_nr > 0xff)
                BUG("invalid loose object subdirectory: %x", subdir_nr);
@@ -1898,6 +1957,8 @@ int for_each_file_in_obj_subdir(unsigned int subdir_nr,
                return r;
        }
 
+       oid.hash[0] = subdir_nr;
+
        while ((de = readdir(dir))) {
                if (is_dot_or_dotdot(de->d_name))
                        continue;
@@ -1905,20 +1966,15 @@ int for_each_file_in_obj_subdir(unsigned int subdir_nr,
                strbuf_setlen(path, baselen);
                strbuf_addf(path, "/%s", de->d_name);
 
-               if (strlen(de->d_name) == GIT_SHA1_HEXSZ - 2)  {
-                       char hex[GIT_MAX_HEXSZ+1];
-                       struct object_id oid;
-
-                       xsnprintf(hex, sizeof(hex), "%02x%s",
-                                 subdir_nr, de->d_name);
-                       if (!get_oid_hex(hex, &oid)) {
-                               if (obj_cb) {
-                                       r = obj_cb(&oid, path->buf, data);
-                                       if (r)
-                                               break;
-                               }
-                               continue;
+               if (strlen(de->d_name) == GIT_SHA1_HEXSZ - 2 &&
+                   !hex_to_bytes(oid.hash + 1, de->d_name,
+                                 GIT_SHA1_RAWSZ - 1)) {
+                       if (obj_cb) {
+                               r = obj_cb(&oid, path->buf, data);
+                               if (r)
+                                       break;
                        }
+                       continue;
                }
 
                if (cruft_cb) {