From ef095d48713a0b151e5b79962de9400d161783ad Mon Sep 17 00:00:00 2001 From: Leonard Lyubich Date: Mon, 30 Nov 2020 18:56:32 +0300 Subject: [PATCH] [#220] blobovnicza: Implement GetRange operation Signed-off-by: Leonard Lyubich --- .../blobovnicza/get_range.go | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 pkg/local_object_storage/blobovnicza/get_range.go diff --git a/pkg/local_object_storage/blobovnicza/get_range.go b/pkg/local_object_storage/blobovnicza/get_range.go new file mode 100644 index 000000000..4fc89c401 --- /dev/null +++ b/pkg/local_object_storage/blobovnicza/get_range.go @@ -0,0 +1,62 @@ +package blobovnicza + +import ( + objectSDK "github.com/nspcc-dev/neofs-api-go/pkg/object" + "github.com/pkg/errors" +) + +// GetRangePrm groups the parameters of GetRange operation. +type GetRangePrm struct { + addr *objectSDK.Address + + rng *objectSDK.Range +} + +// GetRangeRes groups resulting values of GetRange operation. +type GetRangeRes struct { + rngData []byte +} + +var ErrRangeOutOfBounds = errors.New("payload range is out of bounds") + +// SetAddress sets address of the requested object. +func (p *GetRangePrm) SetAddress(addr *objectSDK.Address) { + p.addr = addr +} + +// SetAddress sets range of the requested payload data . +func (p *GetRangePrm) SetRange(rng *objectSDK.Range) { + p.rng = rng +} + +// RangeData returns the requested payload data range. +func (p *GetRangeRes) RangeData() []byte { + return p.rngData +} + +// Get reads the object from Blobovnicza by address. +// +// Returns any error encountered that +// did not allow to completely read the object. +func (b *Blobovnicza) GetRange(prm *GetRangePrm) (*GetRangeRes, error) { + res, err := b.Get(&GetPrm{ + addr: prm.addr, + }) + if err != nil { + return nil, err + } + + from := prm.rng.GetOffset() + to := from + prm.rng.GetLength() + payload := res.obj.Payload() + + if from > to { + return nil, errors.Errorf("invalid range [%d:%d]", from, to) + } else if uint64(len(payload)) < to { + return nil, ErrRangeOutOfBounds + } + + return &GetRangeRes{ + rngData: payload[from:to], + }, nil +}