// Copyright Epic Games, Inc. All Rights Reserved. #include #include #include #include #include #include namespace zen { const IoHash IoHash::Zero{}; // Initialized to all zeros IoHash IoHash::HashBuffer(const void* data, size_t byteCount) { BLAKE3 b3 = BLAKE3::HashMemory(data, byteCount); IoHash io; memcpy(io.Hash, b3.Hash, sizeof io.Hash); return io; } IoHash IoHash::HashBuffer(const CompositeBuffer& Buffer) { IoHashStream Hasher; for (const SharedBuffer& Segment : Buffer.GetSegments()) { size_t SegmentSize = Segment.GetSize(); static const size_t BufferingSize = 512 * 1024; if (SegmentSize >= (BufferingSize + BufferingSize / 2) && Segment.IsFileReference()) { const IoBuffer SegmentBuffer = Segment.AsIoBuffer(); size_t Offset = 0; while (Offset < SegmentSize) { size_t ChunkSize = Min(SegmentSize - Offset, BufferingSize); IoBuffer SubRange(SegmentBuffer, Offset, ChunkSize); Hasher.Append(SubRange.GetData(), ChunkSize); Offset += ChunkSize; } } else { Hasher.Append(Segment.GetData(), SegmentSize); } } return Hasher.GetHash(); } IoHash IoHash::FromHexString(const char* string) { return FromHexString({string, sizeof(IoHash::Hash) * 2}); } IoHash IoHash::FromHexString(std::string_view string) { ZEN_ASSERT(string.size() == 2 * sizeof(IoHash::Hash)); IoHash io; ParseHexBytes(string.data(), string.size(), io.Hash); return io; } const char* IoHash::ToHexString(char* outString /* 40 characters + NUL terminator */) const { ToHexBytes(Hash, sizeof(IoHash), outString); outString[2 * sizeof(IoHash)] = '\0'; return outString; } StringBuilderBase& IoHash::ToHexString(StringBuilderBase& outBuilder) const { String_t Str; ToHexString(Str); outBuilder.AppendRange(Str, &Str[StringLength]); return outBuilder; } std::string IoHash::ToHexString() const { String_t Str; ToHexString(Str); return Str; } } // namespace zen