diff options
Diffstat (limited to 'object')
| -rw-r--r-- | object/blob.go | 2 | ||||
| -rw-r--r-- | object/blob_serialize.go | 4 | ||||
| -rw-r--r-- | object/commit.go | 2 | ||||
| -rw-r--r-- | object/commit_serialize.go | 4 | ||||
| -rw-r--r-- | object/header/append.go | 29 | ||||
| -rw-r--r-- | object/header/encode.go | 8 | ||||
| -rw-r--r-- | object/header/parse.go | 43 | ||||
| -rw-r--r-- | object/object.go | 2 | ||||
| -rw-r--r-- | object/parse.go | 4 | ||||
| -rw-r--r-- | object/resolve/exact_blob_reader.go | 2 | ||||
| -rw-r--r-- | object/resolve/exact_commit_reader.go | 2 | ||||
| -rw-r--r-- | object/resolve/exact_reader.go | 2 | ||||
| -rw-r--r-- | object/resolve/exact_tag_reader.go | 2 | ||||
| -rw-r--r-- | object/resolve/exact_tree_reader.go | 2 | ||||
| -rw-r--r-- | object/resolve/object_parse.go | 2 | ||||
| -rw-r--r-- | object/resolve/peel_to_blob_id.go | 2 | ||||
| -rw-r--r-- | object/resolve/peel_to_commit_id.go | 2 | ||||
| -rw-r--r-- | object/resolve/peel_to_tree_id.go | 2 | ||||
| -rw-r--r-- | object/tag.go | 2 | ||||
| -rw-r--r-- | object/tag_parse.go | 2 | ||||
| -rw-r--r-- | object/tag_parse_test.go | 2 | ||||
| -rw-r--r-- | object/tag_serialize.go | 4 | ||||
| -rw-r--r-- | object/tree.go | 2 | ||||
| -rw-r--r-- | object/tree_serialize.go | 4 | ||||
| -rw-r--r-- | object/type.go | 2 | ||||
| -rw-r--r-- | object/type/name.go | 42 | ||||
| -rw-r--r-- | object/type/objecttype.go | 16 |
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 +) |
