aboutsummaryrefslogtreecommitdiffstats
path: root/core/object.go
blob: 4e8a587ace04fe179187483f8617ae8c96f6c20e (plain) (blame)
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
113
package core

import (
	"bytes"
	"io"
)

// Object is a generic representation of any git object
type Object interface {
	Type() ObjectType
	SetType(ObjectType)
	Size() int64
	SetSize(int64)
	Hash() Hash
	Reader() io.Reader
	Writer() io.Writer
}

// ObjectStorage generic storage of objects
type ObjectStorage interface {
	New() Object
	Set(Object) Hash
	Get(Hash) (Object, bool)
}

// ObjectType internal object type's
type ObjectType int8

const (
	CommitObject   ObjectType = 1
	TreeObject     ObjectType = 2
	BlobObject     ObjectType = 3
	TagObject      ObjectType = 4
	OFSDeltaObject ObjectType = 6
	REFDeltaObject ObjectType = 7
)

func (t ObjectType) String() string {
	switch t {
	case CommitObject:
		return "commit"
	case TreeObject:
		return "tree"
	case BlobObject:
		return "blob"
	default:
		return "-"
	}
}

func (t ObjectType) Bytes() []byte {
	return []byte(t.String())
}

type RAWObject struct {
	b []byte
	t ObjectType
	s int64
}

func (o *RAWObject) Type() ObjectType     { return o.t }
func (o *RAWObject) SetType(t ObjectType) { o.t = t }
func (o *RAWObject) Size() int64          { return o.s }
func (o *RAWObject) SetSize(s int64)      { o.s = s }
func (o *RAWObject) Reader() io.Reader    { return bytes.NewBuffer(o.b) }
func (o *RAWObject) Hash() Hash           { return ComputeHash(o.t, o.b) }
func (o *RAWObject) Writer() io.Writer    { return o }
func (o *RAWObject) Write(p []byte) (n int, err error) {
	o.b = append(o.b, p...)
	return len(p), nil
}

type RAWObjectStorage struct {
	Objects map[Hash]Object
	Commits map[Hash]Object
	Trees   map[Hash]Object
	Blobs   map[Hash]Object
}

func NewRAWObjectStorage() *RAWObjectStorage {
	return &RAWObjectStorage{
		Objects: make(map[Hash]Object, 0),
		Commits: make(map[Hash]Object, 0),
		Trees:   make(map[Hash]Object, 0),
		Blobs:   make(map[Hash]Object, 0),
	}
}

func (o *RAWObjectStorage) New() Object {
	return &RAWObject{}
}

func (o *RAWObjectStorage) Set(obj Object) Hash {
	h := obj.Hash()
	o.Objects[h] = obj

	switch obj.Type() {
	case CommitObject:
		o.Commits[h] = o.Objects[h]
	case TreeObject:
		o.Trees[h] = o.Objects[h]
	case BlobObject:
		o.Blobs[h] = o.Objects[h]
	}

	return h
}

func (o *RAWObjectStorage) Get(h Hash) (Object, bool) {
	obj, ok := o.Objects[h]

	return obj, ok
}