mirror of
https://github.com/go-gitea/gitea
synced 2024-09-19 18:26:04 +00:00
08bf443016
* Inital routes to git refs api * Git refs API implementation * Update swagger * Fix copyright * Make swagger happy add basic test * Fix test * Fix test again :)
143 lines
2.4 KiB
Go
143 lines
2.4 KiB
Go
package idxfile
|
|
|
|
import (
|
|
"crypto/sha1"
|
|
"hash"
|
|
"io"
|
|
|
|
"gopkg.in/src-d/go-git.v4/utils/binary"
|
|
)
|
|
|
|
// Encoder writes MemoryIndex structs to an output stream.
|
|
type Encoder struct {
|
|
io.Writer
|
|
hash hash.Hash
|
|
}
|
|
|
|
// NewEncoder returns a new stream encoder that writes to w.
|
|
func NewEncoder(w io.Writer) *Encoder {
|
|
h := sha1.New()
|
|
mw := io.MultiWriter(w, h)
|
|
return &Encoder{mw, h}
|
|
}
|
|
|
|
// Encode encodes an MemoryIndex to the encoder writer.
|
|
func (e *Encoder) Encode(idx *MemoryIndex) (int, error) {
|
|
flow := []func(*MemoryIndex) (int, error){
|
|
e.encodeHeader,
|
|
e.encodeFanout,
|
|
e.encodeHashes,
|
|
e.encodeCRC32,
|
|
e.encodeOffsets,
|
|
e.encodeChecksums,
|
|
}
|
|
|
|
sz := 0
|
|
for _, f := range flow {
|
|
i, err := f(idx)
|
|
sz += i
|
|
|
|
if err != nil {
|
|
return sz, err
|
|
}
|
|
}
|
|
|
|
return sz, nil
|
|
}
|
|
|
|
func (e *Encoder) encodeHeader(idx *MemoryIndex) (int, error) {
|
|
c, err := e.Write(idxHeader)
|
|
if err != nil {
|
|
return c, err
|
|
}
|
|
|
|
return c + 4, binary.WriteUint32(e, idx.Version)
|
|
}
|
|
|
|
func (e *Encoder) encodeFanout(idx *MemoryIndex) (int, error) {
|
|
for _, c := range idx.Fanout {
|
|
if err := binary.WriteUint32(e, c); err != nil {
|
|
return 0, err
|
|
}
|
|
}
|
|
|
|
return fanout * 4, nil
|
|
}
|
|
|
|
func (e *Encoder) encodeHashes(idx *MemoryIndex) (int, error) {
|
|
var size int
|
|
for k := 0; k < fanout; k++ {
|
|
pos := idx.FanoutMapping[k]
|
|
if pos == noMapping {
|
|
continue
|
|
}
|
|
|
|
n, err := e.Write(idx.Names[pos])
|
|
if err != nil {
|
|
return size, err
|
|
}
|
|
size += n
|
|
}
|
|
return size, nil
|
|
}
|
|
|
|
func (e *Encoder) encodeCRC32(idx *MemoryIndex) (int, error) {
|
|
var size int
|
|
for k := 0; k < fanout; k++ {
|
|
pos := idx.FanoutMapping[k]
|
|
if pos == noMapping {
|
|
continue
|
|
}
|
|
|
|
n, err := e.Write(idx.CRC32[pos])
|
|
if err != nil {
|
|
return size, err
|
|
}
|
|
|
|
size += n
|
|
}
|
|
|
|
return size, nil
|
|
}
|
|
|
|
func (e *Encoder) encodeOffsets(idx *MemoryIndex) (int, error) {
|
|
var size int
|
|
for k := 0; k < fanout; k++ {
|
|
pos := idx.FanoutMapping[k]
|
|
if pos == noMapping {
|
|
continue
|
|
}
|
|
|
|
n, err := e.Write(idx.Offset32[pos])
|
|
if err != nil {
|
|
return size, err
|
|
}
|
|
|
|
size += n
|
|
}
|
|
|
|
if len(idx.Offset64) > 0 {
|
|
n, err := e.Write(idx.Offset64)
|
|
if err != nil {
|
|
return size, err
|
|
}
|
|
|
|
size += n
|
|
}
|
|
|
|
return size, nil
|
|
}
|
|
|
|
func (e *Encoder) encodeChecksums(idx *MemoryIndex) (int, error) {
|
|
if _, err := e.Write(idx.PackfileChecksum[:]); err != nil {
|
|
return 0, err
|
|
}
|
|
|
|
copy(idx.IdxChecksum[:], e.hash.Sum(nil)[:20])
|
|
if _, err := e.Write(idx.IdxChecksum[:]); err != nil {
|
|
return 0, err
|
|
}
|
|
|
|
return 40, nil
|
|
}
|