@ -5,26 +5,17 @@ package git
import (
import (
"crypto/sha1"
"crypto/sha1"
"fmt"
"regexp"
"regexp"
"strings"
)
type ObjectFormatID int
const (
Sha1 ObjectFormatID = iota
)
)
// sha1Pattern can be used to determine if a string is an valid sha
// sha1Pattern can be used to determine if a string is an valid sha
var sha1Pattern = regexp . MustCompile ( ` ^[0-9a-f] { 4,40}$ ` )
var sha1Pattern = regexp . MustCompile ( ` ^[0-9a-f] { 4,40}$ ` )
type ObjectFormat interface {
type ObjectFormat interface {
ID ( ) ObjectFormatID
// Name returns the name of the object format
String ( ) string
Name ( ) string
// EmptyObjectID creates a new empty ObjectID from an object format hash name
// Empty is the hash of empty git
EmptyObjectID ( ) ObjectID
Empty ( ) ObjectID
// EmptyTree is the hash of an empty tree
// EmptyTree is the hash of an empty tree
EmptyTree ( ) ObjectID
EmptyTree ( ) ObjectID
// FullLength is the length of the hash's hex string
// FullLength is the length of the hash's hex string
@ -35,67 +26,71 @@ type ObjectFormat interface {
MustIDFromString ( s string ) ObjectID
MustIDFromString ( s string ) ObjectID
NewID ( b [ ] byte ) ( ObjectID , error )
NewID ( b [ ] byte ) ( ObjectID , error )
NewIDFromString ( s string ) ( ObjectID , error )
NewIDFromString ( s string ) ( ObjectID , error )
NewEmptyID ( ) ObjectID
NewHasher ( ) HasherInterface
NewHasher ( ) HasherInterface
}
}
type Sha1ObjectFormat struct { }
type Sha1ObjectFormatImpl struct { }
func ( * Sha1ObjectFormat ) ID ( ) ObjectFormatID { return Sha1 }
var (
func ( * Sha1ObjectFormat ) String ( ) string { return "sha1" }
emptyObjectID = & Sha1Hash { }
func ( * Sha1ObjectFormat ) Empty ( ) ObjectID { return & Sha1Hash { } }
emptyTree = & Sha1Hash {
func ( * Sha1ObjectFormat ) EmptyTree ( ) ObjectID {
return & Sha1Hash {
0x4b , 0x82 , 0x5d , 0xc6 , 0x42 , 0xcb , 0x6e , 0xb9 , 0xa0 , 0x60 ,
0x4b , 0x82 , 0x5d , 0xc6 , 0x42 , 0xcb , 0x6e , 0xb9 , 0xa0 , 0x60 ,
0xe5 , 0x4b , 0xf8 , 0xd6 , 0x92 , 0x88 , 0xfb , 0xee , 0x49 , 0x04 ,
0xe5 , 0x4b , 0xf8 , 0xd6 , 0x92 , 0x88 , 0xfb , 0xee , 0x49 , 0x04 ,
}
}
)
func ( Sha1ObjectFormatImpl ) Name ( ) string { return "sha1" }
func ( Sha1ObjectFormatImpl ) EmptyObjectID ( ) ObjectID {
return emptyObjectID
}
func ( Sha1ObjectFormatImpl ) EmptyTree ( ) ObjectID {
return emptyTree
}
}
func ( * Sha1ObjectFormat ) FullLength ( ) int { return 40 }
func ( Sha1ObjectFormatImpl ) FullLength ( ) int { return 40 }
func ( * Sha1ObjectFormat ) IsValid ( input string ) bool {
func ( Sha1ObjectFormatImpl ) IsValid ( input string ) bool {
return sha1Pattern . MatchString ( input )
return sha1Pattern . MatchString ( input )
}
}
func ( * Sha1ObjectFormat ) MustID ( b [ ] byte ) ObjectID {
func ( Sha1ObjectFormatImpl ) MustID ( b [ ] byte ) ObjectID {
var id Sha1Hash
var id Sha1Hash
copy ( id [ 0 : 20 ] , b )
copy ( id [ 0 : 20 ] , b )
return & id
return & id
}
}
func ( h * Sha1ObjectFormat ) MustIDFromString ( s string ) ObjectID {
func ( h Sha1ObjectFormatImpl ) MustIDFromString ( s string ) ObjectID {
return MustIDFromString ( h , s )
return MustIDFromString ( h , s )
}
}
func ( h * Sha1ObjectFormat ) NewID ( b [ ] byte ) ( ObjectID , error ) {
func ( h Sha1ObjectFormatImpl ) NewID ( b [ ] byte ) ( ObjectID , error ) {
return IDFromRaw ( h , b )
return IDFromRaw ( h , b )
}
}
func ( h * Sha1ObjectFormat ) NewIDFromString ( s string ) ( ObjectID , error ) {
func ( h Sha1ObjectFormatImpl ) NewIDFromString ( s string ) ( ObjectID , error ) {
return genericIDFromString ( h , s )
return genericIDFromString ( h , s )
}
}
func ( * Sha1ObjectFormat ) NewEmptyID ( ) ObjectID {
func ( h Sha1ObjectFormatImpl ) NewHasher ( ) HasherInterface {
return NewSha1 ( )
}
func ( h * Sha1ObjectFormat ) NewHasher ( ) HasherInterface {
return & Sha1Hasher { sha1 . New ( ) }
return & Sha1Hasher { sha1 . New ( ) }
}
}
func ObjectFormatFromID ( id ObjectFormatID ) ObjectFormat {
var Sha1ObjectFormat ObjectFormat = Sha1ObjectFormatImpl { }
switch id {
case Sha1 :
return & Sha1ObjectFormat { }
}
return nil
var SupportedObjectFormats = [ ] ObjectFormat {
Sha1ObjectFormat ,
// TODO: add sha256
}
}
func ObjectFormatFromString ( hash string ) ( ObjectFormat , error ) {
func ObjectFormatFromName ( name string ) ObjectFormat {
switch strings . ToLower ( hash ) {
for _ , objectFormat := range SupportedObjectFormats {
case "sha1" :
if name == objectFormat . Name ( ) {
return & Sha1ObjectFormat { } , nil
return objectFormat
}
}
}
return nil
}
return nil , fmt . Errorf ( "unknown hash type: %s" , hash )
func IsValidObjectFormat ( name string ) bool {
return ObjectFormatFromName ( name ) != nil
}
}