aboutsummaryrefslogtreecommitdiff
path: root/object
diff options
context:
space:
mode:
Diffstat (limited to 'object')
-rw-r--r--object/blob.go2
-rw-r--r--object/blob_serialize.go4
-rw-r--r--object/commit.go2
-rw-r--r--object/commit_serialize.go4
-rw-r--r--object/header/append.go29
-rw-r--r--object/header/encode.go8
-rw-r--r--object/header/parse.go43
-rw-r--r--object/object.go2
-rw-r--r--object/parse.go4
-rw-r--r--object/resolve/exact_blob_reader.go2
-rw-r--r--object/resolve/exact_commit_reader.go2
-rw-r--r--object/resolve/exact_reader.go2
-rw-r--r--object/resolve/exact_tag_reader.go2
-rw-r--r--object/resolve/exact_tree_reader.go2
-rw-r--r--object/resolve/object_parse.go2
-rw-r--r--object/resolve/peel_to_blob_id.go2
-rw-r--r--object/resolve/peel_to_commit_id.go2
-rw-r--r--object/resolve/peel_to_tree_id.go2
-rw-r--r--object/tag.go2
-rw-r--r--object/tag_parse.go2
-rw-r--r--object/tag_parse_test.go2
-rw-r--r--object/tag_serialize.go4
-rw-r--r--object/tree.go2
-rw-r--r--object/tree_serialize.go4
-rw-r--r--object/type.go2
-rw-r--r--object/type/name.go42
-rw-r--r--object/type/objecttype.go16
27 files changed, 165 insertions, 27 deletions
diff --git a/object/blob.go b/object/blob.go
index bd26ed1d..8f607074 100644
--- a/object/blob.go
+++ b/object/blob.go
@@ -1,6 +1,6 @@
package object
-import "codeberg.org/lindenii/furgit/objecttype"
+import objecttype "codeberg.org/lindenii/furgit/object/type"
// Blob represents a Git blob object.
//
diff --git a/object/blob_serialize.go b/object/blob_serialize.go
index e9c0ac5e..2acc4c11 100644
--- a/object/blob_serialize.go
+++ b/object/blob_serialize.go
@@ -3,8 +3,8 @@ package object
import (
"errors"
- "codeberg.org/lindenii/furgit/objectheader"
- "codeberg.org/lindenii/furgit/objecttype"
+ objectheader "codeberg.org/lindenii/furgit/object/header"
+ objecttype "codeberg.org/lindenii/furgit/object/type"
)
// SerializeWithoutHeader renders the raw blob body bytes.
diff --git a/object/commit.go b/object/commit.go
index 34e89033..214b9c99 100644
--- a/object/commit.go
+++ b/object/commit.go
@@ -2,7 +2,7 @@ package object
import (
"codeberg.org/lindenii/furgit/objectid"
- "codeberg.org/lindenii/furgit/objecttype"
+ objecttype "codeberg.org/lindenii/furgit/object/type"
)
// Commit represents a Git commit object.
diff --git a/object/commit_serialize.go b/object/commit_serialize.go
index eef45ef4..ed81b1d6 100644
--- a/object/commit_serialize.go
+++ b/object/commit_serialize.go
@@ -5,8 +5,8 @@ import (
"errors"
"fmt"
- "codeberg.org/lindenii/furgit/objectheader"
- "codeberg.org/lindenii/furgit/objecttype"
+ objectheader "codeberg.org/lindenii/furgit/object/header"
+ objecttype "codeberg.org/lindenii/furgit/object/type"
)
// SerializeWithoutHeader renders the raw commit body bytes.
diff --git a/object/header/append.go b/object/header/append.go
new file mode 100644
index 00000000..8c0d928c
--- /dev/null
+++ b/object/header/append.go
@@ -0,0 +1,29 @@
+package objectheader
+
+import (
+ "strconv"
+
+ objecttype "codeberg.org/lindenii/furgit/object/type"
+)
+
+// Append appends a canonical loose-object header ("type size\\x00") to dst.
+func Append(dst []byte, ty objecttype.Type, size int64) ([]byte, bool) {
+ if size < 0 {
+ return nil, false
+ }
+
+ tyName, ok := objecttype.Name(ty)
+ if !ok {
+ return nil, false
+ }
+
+ sizeStr := strconv.FormatInt(size, 10)
+ out := make([]byte, 0, len(dst)+len(tyName)+len(sizeStr)+2)
+ out = append(out, dst...)
+ out = append(out, tyName...)
+ out = append(out, ' ')
+ out = append(out, sizeStr...)
+ out = append(out, 0)
+
+ return out, true
+}
diff --git a/object/header/encode.go b/object/header/encode.go
new file mode 100644
index 00000000..a03c1f05
--- /dev/null
+++ b/object/header/encode.go
@@ -0,0 +1,8 @@
+package objectheader
+
+import objecttype "codeberg.org/lindenii/furgit/object/type"
+
+// Encode returns a canonical loose-object header ("type size\\x00").
+func Encode(ty objecttype.Type, size int64) ([]byte, bool) {
+ return Append(nil, ty, size)
+}
diff --git a/object/header/parse.go b/object/header/parse.go
new file mode 100644
index 00000000..3751cafc
--- /dev/null
+++ b/object/header/parse.go
@@ -0,0 +1,43 @@
+// Package objectheader parses and serializes object headers ("type size\0").
+package objectheader
+
+import (
+ "bytes"
+ "strconv"
+
+ objecttype "codeberg.org/lindenii/furgit/object/type"
+)
+
+// Parse parses a canonical loose-object header ("type size\\x00").
+// It returns the parsed type, size, bytes consumed (including trailing NUL),
+// and whether parsing succeeded.
+func Parse(data []byte) (objecttype.Type, int64, int, bool) {
+ space := bytes.IndexByte(data, ' ')
+ if space <= 0 {
+ return objecttype.TypeInvalid, 0, 0, false
+ }
+
+ nulRel := bytes.IndexByte(data[space+1:], 0)
+ if nulRel < 0 {
+ return objecttype.TypeInvalid, 0, 0, false
+ }
+
+ nul := space + 1 + nulRel
+
+ ty, ok := objecttype.ParseName(string(data[:space]))
+ if !ok {
+ return objecttype.TypeInvalid, 0, 0, false
+ }
+
+ sizeBytes := data[space+1 : nul]
+ if len(sizeBytes) == 0 {
+ return objecttype.TypeInvalid, 0, 0, false
+ }
+
+ size, err := strconv.ParseInt(string(sizeBytes), 10, 64)
+ if err != nil || size < 0 {
+ return objecttype.TypeInvalid, 0, 0, false
+ }
+
+ return ty, size, nul + 1, true
+}
diff --git a/object/object.go b/object/object.go
index 9a402336..70d418df 100644
--- a/object/object.go
+++ b/object/object.go
@@ -2,7 +2,7 @@
// tag.
package object
-import "codeberg.org/lindenii/furgit/objecttype"
+import objecttype "codeberg.org/lindenii/furgit/object/type"
// Object is a Git object that can serialize itself.
type Object interface {
diff --git a/object/parse.go b/object/parse.go
index 9afe5cb8..4a396517 100644
--- a/object/parse.go
+++ b/object/parse.go
@@ -3,9 +3,9 @@ package object
import (
"fmt"
- "codeberg.org/lindenii/furgit/objectheader"
+ objectheader "codeberg.org/lindenii/furgit/object/header"
"codeberg.org/lindenii/furgit/objectid"
- "codeberg.org/lindenii/furgit/objecttype"
+ objecttype "codeberg.org/lindenii/furgit/object/type"
)
// ParseObjectWithHeader parses a loose object in "type size\x00body" format.
diff --git a/object/resolve/exact_blob_reader.go b/object/resolve/exact_blob_reader.go
index 760b7d90..5524dfcb 100644
--- a/object/resolve/exact_blob_reader.go
+++ b/object/resolve/exact_blob_reader.go
@@ -4,7 +4,7 @@ import (
"io"
"codeberg.org/lindenii/furgit/objectid"
- "codeberg.org/lindenii/furgit/objecttype"
+ objecttype "codeberg.org/lindenii/furgit/object/type"
)
// ExactBlobReader returns a reader for the content of the blob at id,
diff --git a/object/resolve/exact_commit_reader.go b/object/resolve/exact_commit_reader.go
index b012c485..dc8a563a 100644
--- a/object/resolve/exact_commit_reader.go
+++ b/object/resolve/exact_commit_reader.go
@@ -4,7 +4,7 @@ import (
"io"
"codeberg.org/lindenii/furgit/objectid"
- "codeberg.org/lindenii/furgit/objecttype"
+ objecttype "codeberg.org/lindenii/furgit/object/type"
)
// ExactCommitReader returns a reader for the content of the commit at id,
diff --git a/object/resolve/exact_reader.go b/object/resolve/exact_reader.go
index 10734f5f..0e7a6112 100644
--- a/object/resolve/exact_reader.go
+++ b/object/resolve/exact_reader.go
@@ -5,7 +5,7 @@ import (
"io"
"codeberg.org/lindenii/furgit/objectid"
- "codeberg.org/lindenii/furgit/objecttype"
+ objecttype "codeberg.org/lindenii/furgit/object/type"
)
// exactReader reads one object's content stream and verifies that its header
diff --git a/object/resolve/exact_tag_reader.go b/object/resolve/exact_tag_reader.go
index 2c057b02..d673237f 100644
--- a/object/resolve/exact_tag_reader.go
+++ b/object/resolve/exact_tag_reader.go
@@ -4,7 +4,7 @@ import (
"io"
"codeberg.org/lindenii/furgit/objectid"
- "codeberg.org/lindenii/furgit/objecttype"
+ objecttype "codeberg.org/lindenii/furgit/object/type"
)
// ExactTagReader returns a reader for the content of the tag at id,
diff --git a/object/resolve/exact_tree_reader.go b/object/resolve/exact_tree_reader.go
index b66b3d3f..b4e34dd2 100644
--- a/object/resolve/exact_tree_reader.go
+++ b/object/resolve/exact_tree_reader.go
@@ -4,7 +4,7 @@ import (
"io"
"codeberg.org/lindenii/furgit/objectid"
- "codeberg.org/lindenii/furgit/objecttype"
+ objecttype "codeberg.org/lindenii/furgit/object/type"
)
// ExactTreeReader returns a reader for the content of the tree at id,
diff --git a/object/resolve/object_parse.go b/object/resolve/object_parse.go
index 8b624c5d..bc814988 100644
--- a/object/resolve/object_parse.go
+++ b/object/resolve/object_parse.go
@@ -5,7 +5,7 @@ import (
"codeberg.org/lindenii/furgit/object"
"codeberg.org/lindenii/furgit/objectid"
- "codeberg.org/lindenii/furgit/objecttype"
+ objecttype "codeberg.org/lindenii/furgit/object/type"
)
func (r *Resolver) parseObject(id objectid.ObjectID) (object.Object, error) {
diff --git a/object/resolve/peel_to_blob_id.go b/object/resolve/peel_to_blob_id.go
index d06fd675..3fcd9bc8 100644
--- a/object/resolve/peel_to_blob_id.go
+++ b/object/resolve/peel_to_blob_id.go
@@ -4,7 +4,7 @@ import (
"fmt"
"codeberg.org/lindenii/furgit/objectid"
- "codeberg.org/lindenii/furgit/objecttype"
+ objecttype "codeberg.org/lindenii/furgit/object/type"
)
// PeelToBlobID peels tags until it reaches a blob object ID.
diff --git a/object/resolve/peel_to_commit_id.go b/object/resolve/peel_to_commit_id.go
index 330e2a86..5d02ec1a 100644
--- a/object/resolve/peel_to_commit_id.go
+++ b/object/resolve/peel_to_commit_id.go
@@ -4,7 +4,7 @@ import (
"fmt"
"codeberg.org/lindenii/furgit/objectid"
- "codeberg.org/lindenii/furgit/objecttype"
+ objecttype "codeberg.org/lindenii/furgit/object/type"
)
// PeelToCommitID peels tags until it reaches a commit object ID.
diff --git a/object/resolve/peel_to_tree_id.go b/object/resolve/peel_to_tree_id.go
index 54891aa4..79730d4f 100644
--- a/object/resolve/peel_to_tree_id.go
+++ b/object/resolve/peel_to_tree_id.go
@@ -4,7 +4,7 @@ import (
"fmt"
"codeberg.org/lindenii/furgit/objectid"
- "codeberg.org/lindenii/furgit/objecttype"
+ objecttype "codeberg.org/lindenii/furgit/object/type"
)
// PeelToTreeID peels tags until it reaches a tree object ID, or a commit whose
diff --git a/object/tag.go b/object/tag.go
index 0da3e4a8..6b2c7eb1 100644
--- a/object/tag.go
+++ b/object/tag.go
@@ -2,7 +2,7 @@ package object
import (
"codeberg.org/lindenii/furgit/objectid"
- "codeberg.org/lindenii/furgit/objecttype"
+ objecttype "codeberg.org/lindenii/furgit/object/type"
)
// Tag represents a Git annotated tag object.
diff --git a/object/tag_parse.go b/object/tag_parse.go
index c2fee81a..3def4101 100644
--- a/object/tag_parse.go
+++ b/object/tag_parse.go
@@ -6,7 +6,7 @@ import (
"fmt"
"codeberg.org/lindenii/furgit/objectid"
- "codeberg.org/lindenii/furgit/objecttype"
+ objecttype "codeberg.org/lindenii/furgit/object/type"
)
// ParseTag decodes a tag object body.
diff --git a/object/tag_parse_test.go b/object/tag_parse_test.go
index 456d2f63..d360f3ef 100644
--- a/object/tag_parse_test.go
+++ b/object/tag_parse_test.go
@@ -7,7 +7,7 @@ import (
"codeberg.org/lindenii/furgit/internal/testgit"
"codeberg.org/lindenii/furgit/object"
"codeberg.org/lindenii/furgit/objectid"
- "codeberg.org/lindenii/furgit/objecttype"
+ objecttype "codeberg.org/lindenii/furgit/object/type"
)
func TestTagParseFromGit(t *testing.T) {
diff --git a/object/tag_serialize.go b/object/tag_serialize.go
index 1e016cdb..c914e8dd 100644
--- a/object/tag_serialize.go
+++ b/object/tag_serialize.go
@@ -5,8 +5,8 @@ import (
"errors"
"fmt"
- "codeberg.org/lindenii/furgit/objectheader"
- "codeberg.org/lindenii/furgit/objecttype"
+ objectheader "codeberg.org/lindenii/furgit/object/header"
+ objecttype "codeberg.org/lindenii/furgit/object/type"
)
// SerializeWithoutHeader renders the raw tag body bytes.
diff --git a/object/tree.go b/object/tree.go
index ad4b8f34..2abd2914 100644
--- a/object/tree.go
+++ b/object/tree.go
@@ -6,7 +6,7 @@ import (
"sort"
"codeberg.org/lindenii/furgit/objectid"
- "codeberg.org/lindenii/furgit/objecttype"
+ objecttype "codeberg.org/lindenii/furgit/object/type"
)
// FileMode represents the mode of a file in a Git tree.
diff --git a/object/tree_serialize.go b/object/tree_serialize.go
index 42f60f72..849738a9 100644
--- a/object/tree_serialize.go
+++ b/object/tree_serialize.go
@@ -4,8 +4,8 @@ import (
"errors"
"strconv"
- "codeberg.org/lindenii/furgit/objectheader"
- "codeberg.org/lindenii/furgit/objecttype"
+ objectheader "codeberg.org/lindenii/furgit/object/header"
+ objecttype "codeberg.org/lindenii/furgit/object/type"
)
// SerializeWithoutHeader renders the raw tree body bytes.
diff --git a/object/type.go b/object/type.go
index 70cc46bc..d44b83fa 100644
--- a/object/type.go
+++ b/object/type.go
@@ -1,6 +1,6 @@
package object
-import "codeberg.org/lindenii/furgit/objecttype"
+import objecttype "codeberg.org/lindenii/furgit/object/type"
// TypeFor returns the Git object type for T when T is one of the standard
// parsed object types.
diff --git a/object/type/name.go b/object/type/name.go
new file mode 100644
index 00000000..870ac1e4
--- /dev/null
+++ b/object/type/name.go
@@ -0,0 +1,42 @@
+package objecttype
+
+const (
+ typeNameBlob = "blob"
+ typeNameTree = "tree"
+ typeNameCommit = "commit"
+ typeNameTag = "tag"
+)
+
+// ParseName parses a canonical Git object type name.
+func ParseName(name string) (Type, bool) {
+ switch name {
+ case typeNameBlob:
+ return TypeBlob, true
+ case typeNameTree:
+ return TypeTree, true
+ case typeNameCommit:
+ return TypeCommit, true
+ case typeNameTag:
+ return TypeTag, true
+ default:
+ return TypeInvalid, false
+ }
+}
+
+// Name returns the canonical Git object type name.
+func Name(ty Type) (string, bool) {
+ switch ty {
+ case TypeBlob:
+ return typeNameBlob, true
+ case TypeTree:
+ return typeNameTree, true
+ case TypeCommit:
+ return typeNameCommit, true
+ case TypeTag:
+ return typeNameTag, true
+ case TypeInvalid, TypeFuture, TypeOfsDelta, TypeRefDelta:
+ return "", false
+ default:
+ return "", false
+ }
+}
diff --git a/object/type/objecttype.go b/object/type/objecttype.go
new file mode 100644
index 00000000..2e12dadc
--- /dev/null
+++ b/object/type/objecttype.go
@@ -0,0 +1,16 @@
+// Package objecttype provides object type constants and names.
+package objecttype
+
+// Type mirrors Git object type tags in packfiles.
+type Type uint8
+
+const (
+ TypeInvalid Type = 0
+ TypeCommit Type = 1
+ TypeTree Type = 2
+ TypeBlob Type = 3
+ TypeTag Type = 4
+ TypeFuture Type = 5
+ TypeOfsDelta Type = 6
+ TypeRefDelta Type = 7
+)