]> git.ipfire.org Git - thirdparty/git.git/blobdiff - hex.c
t1503: mark symlink test as REFFILES
[thirdparty/git.git] / hex.c
diff --git a/hex.c b/hex.c
index fd7f00c43f969a30a76fe8ac8bf2255ac0320676..4f64d34696379d35e7ace281a5d471f55f1737ad 100644 (file)
--- a/hex.c
+++ b/hex.c
@@ -47,32 +47,76 @@ int hex_to_bytes(unsigned char *binary, const char *hex, size_t len)
        return 0;
 }
 
-int get_sha1_hex(const char *hex, unsigned char *sha1)
+static int get_hash_hex_algop(const char *hex, unsigned char *hash,
+                             const struct git_hash_algo *algop)
 {
        int i;
-       for (i = 0; i < the_hash_algo->rawsz; i++) {
+       for (i = 0; i < algop->rawsz; i++) {
                int val = hex2chr(hex);
                if (val < 0)
                        return -1;
-               *sha1++ = val;
+               *hash++ = val;
                hex += 2;
        }
        return 0;
 }
 
+int get_sha1_hex(const char *hex, unsigned char *sha1)
+{
+       return get_hash_hex_algop(hex, sha1, the_hash_algo);
+}
+
+int get_oid_hex_algop(const char *hex, struct object_id *oid,
+                     const struct git_hash_algo *algop)
+{
+       int ret = get_hash_hex_algop(hex, oid->hash, algop);
+       if (!ret)
+               oid_set_algo(oid, algop);
+       return ret;
+}
+
+/*
+ * NOTE: This function relies on hash algorithms being in order from shortest
+ * length to longest length.
+ */
+int get_oid_hex_any(const char *hex, struct object_id *oid)
+{
+       int i;
+       for (i = GIT_HASH_NALGOS - 1; i > 0; i--) {
+               if (!get_oid_hex_algop(hex, oid, &hash_algos[i]))
+                       return i;
+       }
+       return GIT_HASH_UNKNOWN;
+}
+
 int get_oid_hex(const char *hex, struct object_id *oid)
 {
-       return get_sha1_hex(hex, oid->hash);
+       return get_oid_hex_algop(hex, oid, the_hash_algo);
 }
 
-int parse_oid_hex(const char *hex, struct object_id *oid, const char **end)
+int parse_oid_hex_algop(const char *hex, struct object_id *oid,
+                       const char **end,
+                       const struct git_hash_algo *algop)
 {
-       int ret = get_oid_hex(hex, oid);
+       int ret = get_oid_hex_algop(hex, oid, algop);
        if (!ret)
-               *end = hex + the_hash_algo->hexsz;
+               *end = hex + algop->hexsz;
        return ret;
 }
 
+int parse_oid_hex_any(const char *hex, struct object_id *oid, const char **end)
+{
+       int ret = get_oid_hex_any(hex, oid);
+       if (ret)
+               *end = hex + hash_algos[ret].hexsz;
+       return ret;
+}
+
+int parse_oid_hex(const char *hex, struct object_id *oid, const char **end)
+{
+       return parse_oid_hex_algop(hex, oid, end, the_hash_algo);
+}
+
 char *hash_to_hex_algop_r(char *buffer, const unsigned char *hash,
                          const struct git_hash_algo *algop)
 {
@@ -80,6 +124,13 @@ char *hash_to_hex_algop_r(char *buffer, const unsigned char *hash,
        char *buf = buffer;
        int i;
 
+       /*
+        * Our struct object_id has been memset to 0, so default to printing
+        * using the default hash.
+        */
+       if (algop == &hash_algos[0])
+               algop = the_hash_algo;
+
        for (i = 0; i < algop->rawsz; i++) {
                unsigned int val = *hash++;
                *buf++ = hex[val >> 4];
@@ -92,7 +143,7 @@ char *hash_to_hex_algop_r(char *buffer, const unsigned char *hash,
 
 char *oid_to_hex_r(char *buffer, const struct object_id *oid)
 {
-       return hash_to_hex_algop_r(buffer, oid->hash, the_hash_algo);
+       return hash_to_hex_algop_r(buffer, oid->hash, &hash_algos[oid->algo]);
 }
 
 char *hash_to_hex_algop(const unsigned char *hash, const struct git_hash_algo *algop)
@@ -110,5 +161,5 @@ char *hash_to_hex(const unsigned char *hash)
 
 char *oid_to_hex(const struct object_id *oid)
 {
-       return hash_to_hex_algop(oid->hash, the_hash_algo);
+       return hash_to_hex_algop(oid->hash, &hash_algos[oid->algo]);
 }