forked from TrueCloudLab/frostfs-sdk-go
88 lines
2.2 KiB
Go
88 lines
2.2 KiB
Go
package client
|
|
|
|
import (
|
|
"context"
|
|
|
|
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
|
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/transformer"
|
|
)
|
|
|
|
func (c *Client) objectPutInitTransformer(prm PrmObjectPutInit) (*objectWriterTransformer, error) {
|
|
var w objectWriterTransformer
|
|
w.it = internalTarget{
|
|
client: c,
|
|
prm: prm,
|
|
}
|
|
key := &c.prm.key
|
|
if prm.key != nil {
|
|
key = prm.key
|
|
}
|
|
w.ot = transformer.NewPayloadSizeLimiter(transformer.Params{
|
|
Key: key,
|
|
NextTargetInit: func() transformer.ObjectTarget { return &w.it },
|
|
MaxSize: prm.maxSize,
|
|
WithoutHomomorphicHash: prm.withoutHomomorphicHash,
|
|
NetworkState: prm.epochSource,
|
|
})
|
|
return &w, nil
|
|
}
|
|
|
|
type objectWriterTransformer struct {
|
|
ot transformer.ObjectTarget
|
|
it internalTarget
|
|
err error
|
|
}
|
|
|
|
func (x *objectWriterTransformer) WriteHeader(ctx context.Context, hdr object.Object) bool {
|
|
x.err = x.ot.WriteHeader(ctx, &hdr)
|
|
return x.err == nil
|
|
}
|
|
|
|
func (x *objectWriterTransformer) WritePayloadChunk(ctx context.Context, chunk []byte) bool {
|
|
_, x.err = x.ot.Write(ctx, chunk)
|
|
return x.err == nil
|
|
}
|
|
|
|
func (x *objectWriterTransformer) Close(ctx context.Context) (*ResObjectPut, error) {
|
|
if ai, err := x.ot.Close(ctx); err != nil {
|
|
return nil, err
|
|
} else {
|
|
if ai != nil && ai.ParentID != nil {
|
|
x.it.res.obj = *ai.ParentID
|
|
}
|
|
return x.it.res, nil
|
|
}
|
|
}
|
|
|
|
type internalTarget struct {
|
|
current *object.Object
|
|
client *Client
|
|
res *ResObjectPut
|
|
prm PrmObjectPutInit
|
|
payload []byte
|
|
}
|
|
|
|
func (it *internalTarget) WriteHeader(_ context.Context, object *object.Object) error {
|
|
it.current = object
|
|
return nil
|
|
}
|
|
|
|
func (it *internalTarget) Write(_ context.Context, p []byte) (n int, err error) {
|
|
it.payload = append(it.payload, p...)
|
|
return len(p), nil
|
|
}
|
|
|
|
func (it *internalTarget) Close(ctx context.Context) (*transformer.AccessIdentifiers, error) {
|
|
it.current.SetPayload(it.payload)
|
|
wrt, err := it.client.objectPutInitRaw(ctx, it.prm)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if wrt.WriteHeader(ctx, *it.current) {
|
|
wrt.WritePayloadChunk(ctx, it.current.Payload())
|
|
}
|
|
it.res, err = wrt.Close(ctx)
|
|
it.current = nil
|
|
it.payload = nil
|
|
return nil, err
|
|
}
|