diff options
Diffstat (limited to 'storage')
-rw-r--r-- | storage/storage.go | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/storage/storage.go b/storage/storage.go index 424661c..45b1973 100644 --- a/storage/storage.go +++ b/storage/storage.go @@ -4,6 +4,8 @@ import ( "bytes" "code.laria.me/petrific/objects" "errors" + "fmt" + "io" ) var ( @@ -35,3 +37,45 @@ func SetObject(s Storage, o objects.RawObject) (id objects.ObjectId, err error) } return } + +type IdMismatchErr struct { + Want, Have objects.ObjectId +} + +func (iderr IdMismatchErr) Error() string { + return fmt.Sprintf("ID verification failed: want %s, have %s", iderr.Want, iderr.Have) +} + +// GetObjects gets an object from a Storage and parses and verifies it (check it's checksum/id) +func GetObject(s Storage, id objects.ObjectId) (objects.RawObject, error) { + raw, err := s.Get(id) + if err != nil { + return objects.RawObject{}, err + } + + idgen := id.Algo.Generator() + r := io.TeeReader(bytes.NewReader(raw), idgen) + + obj, err := objects.Unserialize(r) + if err != nil { + return objects.RawObject{}, err + } + + if have_id := idgen.GetId(); !have_id.Equals(id) { + return objects.RawObject{}, IdMismatchErr{id, have_id} + } + return obj, nil +} + +func GetObjectOfType(s Storage, id objects.ObjectId, t objects.ObjectType) (objects.Object, error) { + rawobj, err := GetObject(s, id) + if err != nil { + return nil, err + } + + if rawobj.Type != t { + return nil, fmt.Errorf("GetObjectOfType: Wrong object type %s (want %s)", rawobj.Type, t) + } + + return rawobj.Object() +} |