using System; using System.Security.Cryptography; using FrostFS.SDK.ModelsV2.Enums; namespace FrostFS.SDK.ModelsV2; public class FrostFsObject { /// /// Creates new instance from ObjectHeader /// /// public FrostFsObject(ObjectHeader header) { Header = header; } /// /// Creates new instance with specified parameters /// /// /// public FrostFsObject(ContainerId container, ObjectType objectType = ObjectType.Regular) { Header = new ObjectHeader(containerId: container, type: objectType); } /// /// Header contains metadata for the object /// /// public ObjectHeader Header { get; set; } /// /// The value is calculated internally as a hash of ObjectHeader. Do not use pre-calculated value is the object has been changed. /// public ObjectId? ObjectId { get; internal set; } /// /// The size of payload cannot exceed MaxObjectSize value from NetworkSettings /// Used only for PutSingleObject method /// /// Buffer for output data public byte[] Payload { get; set; } = []; /// /// A payload is obtained via stream reader /// /// Reader for received data public IObjectReader? ObjectReader { get; set; } /// /// Applied only for the last Object in chain in case of manual multipart uploading /// /// Parent for multipart object public void SetParent(LargeObject largeObject) { if (Header?.Split == null) throw new Exception("The object is not initialized properly"); Header.Split.ParentHeader = largeObject.Header; } } public class LargeObject(ContainerId container) : FrostFsObject(container) { private readonly SHA256 payloadHash = SHA256.Create(); public void AppendBlock(byte[] bytes, int count) { Header!.PayloadLength += (ulong)count; this.payloadHash.TransformBlock(bytes, 0, count, bytes, 0); } public LargeObject CalculateHash() { this.payloadHash.TransformFinalBlock([], 0, 0); Header!.PayloadCheckSum = this.payloadHash.Hash; return this; } public ulong PayloadLength { get { return Header!.PayloadLength; } } } public class LinkObject : FrostFsObject { public LinkObject(ContainerId containerId, SplitId splitId, LargeObject largeObject) : base (containerId) { Header!.Split = new Split(splitId) { ParentHeader = largeObject.Header }; } }