aboutsummaryrefslogtreecommitdiff
path: root/object/store/memory/write_reader.go
blob: 0fa6a13f05f140696b2f03bc30e73b5cfd9d3f79 (about) (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
package memory

import (
	"errors"
	"fmt"
	"io"

	objectheader "codeberg.org/lindenii/furgit/object/header"
	objectid "codeberg.org/lindenii/furgit/object/id"
	objecttype "codeberg.org/lindenii/furgit/object/type"
)

// WriteReaderContent writes one typed object content stream.
func (store *Store) WriteReaderContent(ty objecttype.Type, size int64, src io.Reader) (objectid.ObjectID, error) {
	if size < 0 {
		return objectid.ObjectID{}, fmt.Errorf("objectstore/memory: negative content size: %d", size)
	}

	content, err := io.ReadAll(io.LimitReader(src, size+1))
	if err != nil {
		return objectid.ObjectID{}, err
	}

	switch {
	case int64(len(content)) > size:
		return objectid.ObjectID{}, errors.New("objectstore/memory: object content longer than declared size")
	case int64(len(content)) < size:
		return objectid.ObjectID{}, errors.New("objectstore/memory: object content shorter than declared size")
	}

	return store.WriteBytesContent(ty, content)
}

// WriteReaderFull writes one full serialized object stream as "type size\0content".
func (store *Store) WriteReaderFull(src io.Reader) (objectid.ObjectID, error) {
	raw, err := io.ReadAll(src)
	if err != nil {
		return objectid.ObjectID{}, err
	}

	ty, size, headerLen, ok := objectheader.Parse(raw)
	if !ok {
		return objectid.ObjectID{}, errors.New("objectstore/memory: malformed object header")
	}

	content := raw[headerLen:]
	if int64(len(content)) != size {
		return objectid.ObjectID{}, errors.New("objectstore/memory: object header size/content mismatch")
	}

	id := store.algo.Sum(raw)
	store.objects[id] = storedObject{ty: ty, content: append([]byte(nil), content...)}

	return id, nil
}