11package git
22
33import (
4+ "bytes"
5+ "crypto/sha1" //nolint:gosec
6+ "crypto/sha256"
47 "encoding/hex"
58 "errors"
69)
710
11+ const (
12+ HashSizeSHA256 = sha256 .Size
13+ HashSizeSHA1 = sha1 .Size
14+ HashSizeMax = HashSizeSHA256
15+ )
16+
17+ type HashAlgo int
18+
19+ const (
20+ HashUnknown HashAlgo = iota
21+ HashSHA1
22+ HashSHA256
23+ )
24+
825// OID represents the SHA-1 object ID of a Git object, in binary
926// format.
1027type OID struct {
11- v [20 ]byte
28+ v [HashSizeMax ]byte
29+ hashSize int
1230}
1331
14- // NullOID is the null object ID; i.e., all zeros.
15- var NullOID OID
32+ func (h HashAlgo ) NullOID () OID {
33+ switch h {
34+ case HashSHA1 :
35+ return OID {hashSize : HashSizeSHA1 }
36+ case HashSHA256 :
37+ return OID {hashSize : HashSizeSHA256 }
38+ }
39+ return OID {}
40+ }
41+
42+ func (h HashAlgo ) HashSize () int {
43+ switch h {
44+ case HashSHA1 :
45+ return HashSizeSHA1
46+ case HashSHA256 :
47+ return HashSizeSHA256
48+ }
49+ return 0
50+ }
51+
52+ // defaultNullOID is the null object ID; i.e., all zeros.
53+ var defaultNullOID OID
54+
55+ func IsNullOID (o OID ) bool {
56+ return bytes .Equal (o .v [:], defaultNullOID .v [:])
57+ }
1658
1759// OIDFromBytes converts a byte slice containing an object ID in
1860// binary format into an `OID`.
1961func OIDFromBytes (oidBytes []byte ) (OID , error ) {
2062 var oid OID
21- if len (oidBytes ) != len (oid .v ) {
63+ oidSize := len (oidBytes )
64+ if oidSize != HashSizeSHA1 && oidSize != HashSizeSHA256 {
2265 return OID {}, errors .New ("bytes oid has the wrong length" )
2366 }
24- copy (oid .v [0 :20 ], oidBytes )
67+ oid .hashSize = oidSize
68+ copy (oid .v [0 :oidSize ], oidBytes )
2569 return oid , nil
2670}
2771
28- // NewOID converts an object ID in hex format (i.e., `[0-9a-f]{40}`)
29- // into an `OID`.
72+ // NewOID converts an object ID in hex format (i.e., `[0-9a-f]{40,64}`) into an `OID`.
3073func NewOID (s string ) (OID , error ) {
3174 oidBytes , err := hex .DecodeString (s )
3275 if err != nil {
@@ -37,18 +80,18 @@ func NewOID(s string) (OID, error) {
3780
3881// String formats `oid` as a string in hex format.
3982func (oid OID ) String () string {
40- return hex .EncodeToString (oid .v [:])
83+ return hex .EncodeToString (oid .v [:oid . hashSize ])
4184}
4285
4386// Bytes returns a byte slice view of `oid`, in binary format.
4487func (oid OID ) Bytes () []byte {
45- return oid .v [:]
88+ return oid .v [:oid . hashSize ]
4689}
4790
4891// MarshalJSON expresses `oid` as a JSON string with its enclosing
4992// quotation marks.
5093func (oid OID ) MarshalJSON () ([]byte , error ) {
51- src := oid .v [:]
94+ src := oid .v [:oid . hashSize ]
5295 dst := make ([]byte , hex .EncodedLen (len (src ))+ 2 )
5396 dst [0 ] = '"'
5497 dst [len (dst )- 1 ] = '"'
0 commit comments