forked from shibukawa/git4go
-
Notifications
You must be signed in to change notification settings - Fork 0
/
oid.go
112 lines (96 loc) · 2.17 KB
/
oid.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
package git4go
import (
"bytes"
"encoding/hex"
"errors"
)
type Oid [GitOidRawSize]byte
func NewOidFromBytes(b []byte) *Oid {
oid := new(Oid)
copy(oid[0:GitOidRawSize], b[0:GitOidRawSize])
return oid
}
func NewOid(s string) (*Oid, error) {
if len(s) > GitOidHexSize {
return nil, errors.New("string is too long for oid")
}
o := new(Oid)
slice, err := hex.DecodeString(s)
if err != nil {
return nil, err
}
if len(slice) != GitOidRawSize {
return nil, errors.New("Invalid Oid")
}
copy(o[:], slice[:GitOidRawSize])
return o, nil
}
func NewOidFromPrefix(s string) (*Oid, error) {
if len(s) > GitOidHexSize {
return nil, errors.New("string is too long for oid")
}
slice, err := hex.DecodeString(s)
if err != nil {
return nil, err
}
length := len(s)
shortOid := new(Oid)
copy(shortOid[:], slice[:(length+1)/2])
if (length % 2) == 1 {
shortOid[length/2] &= 0xF0
}
return shortOid, nil
}
func parseOidWithPrefix(buffer []byte, index int, prefix []byte) (*Oid, int) {
prefixLength := len(prefix)
if len(buffer)-index < prefixLength+GitOidHexSize+1 {
return nil, index
}
if bytes.Compare(buffer[index:index+prefixLength], prefix) != 0 {
return nil, index
}
if buffer[index+prefixLength+GitOidHexSize] != '\n' {
return nil, index
}
oid, err := NewOid(string(buffer[index+prefixLength : index+prefixLength+GitOidHexSize]))
if err != nil {
return nil, index
}
return oid, index + prefixLength + GitOidHexSize + 1
}
func (oid *Oid) String() string {
return hex.EncodeToString(oid[:])
}
func (oid *Oid) PathFormat() (string, string) {
idString := oid.String()
return idString[:2], idString[2:]
}
func (oid *Oid) Cmp(oid2 *Oid) int {
return bytes.Compare(oid[:], oid2[:])
}
func (oid *Oid) Copy() *Oid {
ret := new(Oid)
copy(ret[:], oid[:])
return ret
}
func (oid *Oid) Equal(oid2 *Oid) bool {
return bytes.Equal(oid[:], oid2[:])
}
func (oid *Oid) IsZero() bool {
for _, a := range oid {
if a != 0 {
return false
}
}
return true
}
func (oid *Oid) NCmp(oid2 *Oid, n uint) int {
result := bytes.Compare(oid[:n/2], oid2[:n/2])
if result == 0 && n%2 == 1 {
if (oid[n/2+1]^oid2[n/2+1])&0xf0 != 0 {
return 1
}
return 0
}
return result
}