diff --git a/object/convert.go b/object/convert.go index 8d6c73f..3a680ac 100644 --- a/object/convert.go +++ b/object/convert.go @@ -662,11 +662,7 @@ func (s *ECInfo) ToGRPCMessage() grpc.Message { if s.Chunks != nil { chunks := make([]*object.ECInfo_Chunk, len(s.Chunks)) for i := range chunks { - chunks[i] = &object.ECInfo_Chunk{ - Id: s.Chunks[i].ID.ToGRPCMessage().(*refsGRPC.ObjectID), - Index: s.Chunks[i].Index, - Total: s.Chunks[i].Total, - } + chunks[i] = s.Chunks[i].ToGRPCMessage().(*object.ECInfo_Chunk) } m.Chunks = chunks } @@ -687,16 +683,43 @@ func (s *ECInfo) FromGRPCMessage(m grpc.Message) error { } else { s.Chunks = make([]ECChunk, len(chunks)) for i := range chunks { - if err := s.Chunks[i].ID.FromGRPCMessage(chunks[i].Id); err != nil { + if err := s.Chunks[i].FromGRPCMessage(chunks[i]); err != nil { return err } - s.Chunks[i].Index = chunks[i].Index - s.Chunks[i].Total = chunks[i].Total } } return nil } +func (c *ECChunk) ToGRPCMessage() grpc.Message { + var m *object.ECInfo_Chunk + + if c != nil { + m = new(object.ECInfo_Chunk) + + m.Total = c.Total + m.Index = c.Index + m.Id = c.ID.ToGRPCMessage().(*refsGRPC.ObjectID) + } + + return m +} + +func (c *ECChunk) FromGRPCMessage(m grpc.Message) error { + v, ok := m.(*object.ECInfo_Chunk) + if !ok { + return message.NewUnexpectedMessageType(m, v) + } + + if err := c.ID.FromGRPCMessage(v.GetId()); err != nil { + return err + } + c.Index = v.Index + c.Total = v.Total + + return nil +} + func (r *GetRequestBody) ToGRPCMessage() grpc.Message { var m *object.GetRequest_Body @@ -877,6 +900,8 @@ func (r *GetResponseBody) ToGRPCMessage() grpc.Message { m.SetChunk(t.ToGRPCMessage().(*object.GetResponse_Body_Chunk)) case *SplitInfo: m.SetSplitInfo(t.ToGRPCMessage().(*object.SplitInfo)) + case *ECInfo: + m.SetECInfo(t.ToGRPCMessage().(*object.ECInfo)) default: panic(fmt.Sprintf("unknown get object part %T", t)) } @@ -915,6 +940,12 @@ func (r *GetResponseBody) FromGRPCMessage(m grpc.Message) error { r.objPart = partSplit err = partSplit.FromGRPCMessage(pt.SplitInfo) } + case *object.GetResponse_Body_EcInfo: + if pt != nil { + partEC := new(ECInfo) + r.objPart = partEC + err = partEC.FromGRPCMessage(pt.EcInfo) + } default: err = fmt.Errorf("unknown get object part %T", pt) } @@ -1454,6 +1485,8 @@ func (r *HeadResponseBody) ToGRPCMessage() grpc.Message { m.SetShortHeader(v.ToGRPCMessage().(*object.ShortHeader)) case *SplitInfo: m.SetSplitInfo(v.ToGRPCMessage().(*object.SplitInfo)) + case *ECInfo: + m.SetECInfo(v.ToGRPCMessage().(*object.ECInfo)) default: panic(fmt.Sprintf("unknown head part %T", v)) } @@ -1492,6 +1525,12 @@ func (r *HeadResponseBody) FromGRPCMessage(m grpc.Message) error { r.hdrPart = partSplit err = partSplit.FromGRPCMessage(pt.SplitInfo) } + case *object.HeadResponse_Body_EcInfo: + if pt != nil { + partEC := new(ECInfo) + r.hdrPart = partEC + err = partEC.FromGRPCMessage(pt.EcInfo) + } default: err = fmt.Errorf("unknown head part %T", pt) } diff --git a/object/grpc/service.go b/object/grpc/service.go index 27645dd..fa7cf45 100644 --- a/object/grpc/service.go +++ b/object/grpc/service.go @@ -78,6 +78,13 @@ func (m *GetResponse_Body) SetSplitInfo(v *SplitInfo) { } } +// SetECInfo sets part of the object payload. +func (m *GetResponse_Body) SetECInfo(v *ECInfo) { + m.ObjectPart = &GetResponse_Body_EcInfo{ + EcInfo: v, + } +} + // SetBody sets body of the response. func (m *GetResponse) SetBody(v *GetResponse_Body) { m.Body = v @@ -275,6 +282,13 @@ func (m *HeadResponse_Body) SetSplitInfo(v *SplitInfo) { } } +// SetECInfo sets meta info about the erasure coded object. +func (m *HeadResponse_Body) SetECInfo(v *ECInfo) { + m.Head = &HeadResponse_Body_EcInfo{ + EcInfo: v, + } +} + // SetBody sets body of the response. func (m *HeadResponse) SetBody(v *HeadResponse_Body) { m.Body = v diff --git a/object/json.go b/object/json.go index 1a04031..98030bb 100644 --- a/object/json.go +++ b/object/json.go @@ -61,6 +61,22 @@ func (s *SplitInfo) UnmarshalJSON(data []byte) error { return message.UnmarshalJSON(s, data, new(object.SplitInfo)) } +func (e *ECInfo) MarshalJSON() ([]byte, error) { + return message.MarshalJSON(e) +} + +func (e *ECInfo) UnmarshalJSON(data []byte) error { + return message.UnmarshalJSON(e, data, new(object.ECInfo)) +} + +func (e *ECChunk) MarshalJSON() ([]byte, error) { + return message.MarshalJSON(e) +} + +func (e *ECChunk) UnmarshalJSON(data []byte) error { + return message.UnmarshalJSON(e, data, new(object.ECInfo_Chunk)) +} + func (f *SearchFilter) MarshalJSON() ([]byte, error) { return message.MarshalJSON(f) } diff --git a/object/marshal.go b/object/marshal.go index 989dd43..c02ae83 100644 --- a/object/marshal.go +++ b/object/marshal.go @@ -57,6 +57,12 @@ const ( splitInfoLastPartField = 2 splitInfoLinkField = 3 + ecInfoChunksField = 1 + + ecChunkIDField = 1 + ecChunkIndexField = 2 + ecChunkTotalField = 3 + getReqBodyAddressField = 1 getReqBodyRawFlagField = 2 @@ -67,6 +73,7 @@ const ( getRespBodyInitField = 1 getRespBodyChunkField = 2 getRespBodySplitInfoField = 3 + getRespBodyECInfoField = 4 putReqInitObjectIDField = 1 putReqInitSignatureField = 2 @@ -89,6 +96,7 @@ const ( headRespBodyHeaderField = 1 headRespBodyShortHeaderField = 2 headRespBodySplitInfoField = 3 + headRespBodyECInfoField = 4 searchFilterMatchField = 1 searchFilterNameField = 2 @@ -451,6 +459,74 @@ func (s *SplitInfo) Unmarshal(data []byte) error { return message.Unmarshal(s, data, new(object.SplitInfo)) } +func (e *ECInfo) StableMarshal(buf []byte) []byte { + if e == nil { + return []byte{} + } + + if buf == nil { + buf = make([]byte, e.StableSize()) + } + + var offset int + + for i := range e.Chunks { + offset += proto.NestedStructureMarshal(ecInfoChunksField, buf[offset:], &e.Chunks[i]) + } + + return buf +} + +func (e *ECInfo) StableSize() (size int) { + if e == nil { + return 0 + } + + for i := range e.Chunks { + size += proto.NestedStructureSize(ecInfoChunksField, &e.Chunks[i]) + } + + return size +} + +func (e *ECInfo) Unmarshal(data []byte) error { + return message.Unmarshal(e, data, new(object.ECInfo)) +} + +func (c *ECChunk) StableMarshal(buf []byte) []byte { + if c == nil { + return []byte{} + } + + if buf == nil { + buf = make([]byte, c.StableSize()) + } + + var offset int + + offset += proto.NestedStructureMarshal(ecChunkIDField, buf[offset:], &c.ID) + offset += proto.UInt32Marshal(ecChunkIndexField, buf[offset:], c.Index) + proto.UInt32Marshal(ecChunkTotalField, buf[offset:], c.Total) + + return buf +} + +func (c *ECChunk) StableSize() (size int) { + if c == nil { + return 0 + } + + size += proto.NestedStructureSize(ecChunkIDField, &c.ID) + size += proto.UInt32Size(ecChunkIndexField, c.Index) + size += proto.UInt32Size(ecChunkTotalField, c.Total) + + return size +} + +func (c *ECChunk) Unmarshal(data []byte) error { + return message.Unmarshal(c, data, new(object.ECInfo_Chunk)) +} + func (r *GetRequestBody) StableMarshal(buf []byte) []byte { if r == nil { return []byte{} @@ -536,6 +612,8 @@ func (r *GetResponseBody) StableMarshal(buf []byte) []byte { } case *SplitInfo: proto.NestedStructureMarshal(getRespBodySplitInfoField, buf, v) + case *ECInfo: + proto.NestedStructureMarshal(getRespBodyECInfoField, buf, v) default: panic("unknown one of object get response body type") } @@ -558,6 +636,8 @@ func (r *GetResponseBody) StableSize() (size int) { } case *SplitInfo: size += proto.NestedStructureSize(getRespBodySplitInfoField, v) + case *ECInfo: + size += proto.NestedStructureSize(getRespBodyECInfoField, v) default: panic("unknown one of object get response body type") } @@ -796,6 +876,10 @@ func (r *HeadResponseBody) StableMarshal(buf []byte) []byte { if v != nil { proto.NestedStructureMarshal(headRespBodySplitInfoField, buf, v) } + case *ECInfo: + if v != nil { + proto.NestedStructureMarshal(headRespBodyECInfoField, buf, v) + } default: panic("unknown one of object put request body type") } @@ -822,6 +906,10 @@ func (r *HeadResponseBody) StableSize() (size int) { if v != nil { size += proto.NestedStructureSize(headRespBodySplitInfoField, v) } + case *ECInfo: + if v != nil { + size += proto.NestedStructureSize(headRespBodyECInfoField, v) + } default: panic("unknown one of object put request body type") } diff --git a/object/types.go b/object/types.go index 3af08b6..4588f13 100644 --- a/object/types.go +++ b/object/types.go @@ -1508,3 +1508,9 @@ func (r *PutSingleResponse) GetBody() *PutSingleResponseBody { func (r *PutSingleResponse) SetBody(v *PutSingleResponseBody) { r.body = v } + +func (s *ECInfo) getObjectPart() {} + +func (s *ECInfo) getHeaderPart() {} + +func (s *ECInfo) getRangePart() {}