mirror of
https://github.com/Thealexbarney/LibHac.git
synced 2024-11-14 10:49:41 +01:00
Implement some Bitmap code
This commit is contained in:
parent
037c5ace9e
commit
257cf57d0b
3 changed files with 372 additions and 34 deletions
|
@ -144,7 +144,13 @@ public class ChunkSizeCalculator : IDisposable
|
||||||
|
|
||||||
public ChunkSizeCalculator(long totalSize, ulong divisionAlignment, int divisionCount)
|
public ChunkSizeCalculator(long totalSize, ulong divisionAlignment, int divisionCount)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
_divisionAlignment = divisionAlignment;
|
||||||
|
_divisionCount = divisionCount;
|
||||||
|
_chunkSize = Alignment.AlignDown(totalSize / _divisionCount, _divisionAlignment);
|
||||||
|
|
||||||
|
long extraSize = totalSize - _divisionCount * _chunkSize;
|
||||||
|
ulong extraSizeAligned = (ulong)Alignment.AlignUp(extraSize, _divisionAlignment);
|
||||||
|
_longChunkCount = (int)(extraSizeAligned / _divisionAlignment);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
|
@ -152,11 +158,22 @@ public class ChunkSizeCalculator : IDisposable
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int GetDivisionCount() => throw new NotImplementedException();
|
public int GetDivisionCount() => _divisionCount;
|
||||||
|
|
||||||
public void GetOffsetAndSize(out long outOffset, out long outSize, int chunkId)
|
public void GetOffsetAndSize(out long outOffset, out long outSize, int chunkId)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
int normalChunkCount = _divisionCount - _longChunkCount;
|
||||||
|
|
||||||
|
if (chunkId < normalChunkCount)
|
||||||
|
{
|
||||||
|
outSize = _chunkSize;
|
||||||
|
outOffset = _chunkSize * chunkId;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
outSize = (long)_divisionAlignment + _chunkSize;
|
||||||
|
outOffset = (chunkId - normalChunkCount) * outSize + normalChunkCount * _chunkSize;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
// ReSharper disable UnusedMember.Local UnusedType.Local
|
using System;
|
||||||
#pragma warning disable CS0169 // Field is never used
|
using System.Runtime.CompilerServices;
|
||||||
using System;
|
using System.Runtime.InteropServices;
|
||||||
|
using LibHac.Common;
|
||||||
|
using LibHac.Diag;
|
||||||
using LibHac.Fs;
|
using LibHac.Fs;
|
||||||
|
using LibHac.Util;
|
||||||
|
|
||||||
namespace LibHac.FsSystem;
|
namespace LibHac.FsSystem;
|
||||||
|
|
||||||
|
@ -21,71 +24,346 @@ public class Bitmap : IDisposable
|
||||||
|
|
||||||
public Bitmap()
|
public Bitmap()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
_bitCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
_storage?.Dispose();
|
||||||
|
_storage = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static long QuerySize(uint bitCount)
|
public static long QuerySize(uint bitCount)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
return Alignment.AlignUp(bitCount, BitmapSizeAlignment);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Initialize(uint bitCount, SubStorage bitmapStorage)
|
public void Initialize(uint bitCount, SubStorage bitmapStorage)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
_bitCount = bitCount;
|
||||||
|
_storage = bitmapStorage;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Result Format(uint bitCount, SubStorage storage)
|
public static Result Format(uint bitCount, SubStorage storage)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
Span<byte> bits = stackalloc byte[IterateCacheSize];
|
||||||
|
bits.Clear();
|
||||||
|
|
||||||
|
long size = QuerySize(bitCount);
|
||||||
|
long offset = 0;
|
||||||
|
|
||||||
|
while (size != 0)
|
||||||
|
{
|
||||||
|
int iterationSize = (int)Math.Min(bits.Length, size);
|
||||||
|
|
||||||
|
Result res = storage.Write(offset, bits.Slice(0, iterationSize));
|
||||||
|
if (res.IsFailure()) return res.Miss();
|
||||||
|
|
||||||
|
size -= iterationSize;
|
||||||
|
offset += iterationSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Result.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Result Expand(uint bitCountOld, uint bitCountNew, SubStorage storage)
|
public static Result Expand(uint bitCountOld, uint bitCountNew, SubStorage storage)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
Assert.SdkRequiresGreater(bitCountNew, bitCountOld);
|
||||||
|
|
||||||
|
Span<byte> bits = stackalloc byte[IterateCacheSize];
|
||||||
|
|
||||||
|
long sizeOld = QuerySize(bitCountOld);
|
||||||
|
long sizeNew = QuerySize(bitCountNew);
|
||||||
|
|
||||||
|
if (sizeNew > sizeOld)
|
||||||
|
{
|
||||||
|
bits.Clear();
|
||||||
|
long expandSize = sizeNew - sizeOld;
|
||||||
|
long offset = sizeOld;
|
||||||
|
|
||||||
|
while (expandSize != 0)
|
||||||
|
{
|
||||||
|
int iterationSize = (int)Math.Min(bits.Length, expandSize);
|
||||||
|
|
||||||
|
Result res = storage.Write(offset, bits.Slice(0, iterationSize));
|
||||||
|
if (res.IsFailure()) return res.Miss();
|
||||||
|
|
||||||
|
expandSize -= iterationSize;
|
||||||
|
offset += iterationSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Result.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result IterateBegin(ref Iterator it, uint index)
|
public Result IterateBegin(ref Iterator it, uint index)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
Assert.SdkRequiresNotNull(ref it);
|
||||||
|
Assert.SdkRequiresLessEqual(index, _bitCount);
|
||||||
|
|
||||||
|
it.Index = index;
|
||||||
|
return Result.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Result ReadBlock(Span<byte> buffer, uint index)
|
private Result ReadBlock(Span<byte> buffer, uint index)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
Assert.SdkRequiresNotNull(buffer);
|
||||||
|
Assert.SdkAssert((buffer.Length & 3) == 0);
|
||||||
|
|
||||||
|
uint blockIndex = Alignment.AlignDown(index, BitmapSizeAlignment);
|
||||||
|
|
||||||
|
Result res = _storage.Read(blockIndex / BlockSize, buffer);
|
||||||
|
if (res.IsFailure()) return res.Miss();
|
||||||
|
|
||||||
|
return Result.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result IterateNext(out uint outZeroCount, out uint outOneCount, ref Iterator it)
|
public Result IterateNext(out uint outZeroCount, out uint outOneCount, ref Iterator it)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
return LimitedIterateNext(out outZeroCount, out outOneCount, ref it, 0, 0).Ret();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result LimitedIterateNext(out uint outZeroCount, out uint outOneCount, ref Iterator it, uint maxZeroCount, uint maxOneCount)
|
public Result LimitedIterateNext(out uint outZeroCount, out uint outOneCount, ref Iterator it, uint maxZeroCount, uint maxOneCount)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
Assert.SdkNotNullOut(out outZeroCount);
|
||||||
|
Assert.SdkNotNullOut(out outOneCount);
|
||||||
|
Assert.SdkNotNull(ref it);
|
||||||
|
Assert.SdkAssert(it.Index <= _bitCount);
|
||||||
|
|
||||||
|
outZeroCount = 0;
|
||||||
|
outOneCount = 0;
|
||||||
|
|
||||||
|
if (it.Index >= _bitCount)
|
||||||
|
return Result.Success;
|
||||||
|
|
||||||
|
Span<byte> buffer = stackalloc byte[IterateCacheSize];
|
||||||
|
|
||||||
|
uint totalCount = 0;
|
||||||
|
bool countingZeros = true;
|
||||||
|
bool isLastIteration = false;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (it.Index >= _bitCount)
|
||||||
|
break;
|
||||||
|
|
||||||
|
int readRequestBytes =
|
||||||
|
(int)Math.Min(
|
||||||
|
(Alignment.AlignUp(_bitCount, BitmapSizeAlignment) -
|
||||||
|
Alignment.AlignDown(it.Index, BitmapSizeAlignment)) / 8, IterateCacheSize);
|
||||||
|
|
||||||
|
Result res = ReadBlock(buffer.Slice(0, readRequestBytes), it.Index);
|
||||||
|
if (res.IsFailure()) return res.Miss();
|
||||||
|
|
||||||
|
for (int i = 0; i < readRequestBytes; i += 4)
|
||||||
|
{
|
||||||
|
uint value = BitmapUtils.ReadU32(buffer, i);
|
||||||
|
uint positionInValue = it.Index % BitmapSizeAlignment;
|
||||||
|
value <<= (int)positionInValue;
|
||||||
|
|
||||||
|
int currentIterationCount = 0;
|
||||||
|
|
||||||
|
if (totalCount == 0)
|
||||||
|
{
|
||||||
|
currentIterationCount = BitmapUtils.CountLeadingZeros(value);
|
||||||
|
if (currentIterationCount != 0)
|
||||||
|
{
|
||||||
|
countingZeros = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
currentIterationCount = BitmapUtils.CountLeadingOnes(value);
|
||||||
|
if (currentIterationCount != 0)
|
||||||
|
{
|
||||||
|
countingZeros = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Assert.SdkAssert(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (countingZeros)
|
||||||
|
{
|
||||||
|
currentIterationCount = BitmapUtils.CountLeadingZeros(value);
|
||||||
|
if (currentIterationCount == 0)
|
||||||
|
{
|
||||||
|
outZeroCount = totalCount;
|
||||||
|
isLastIteration = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
currentIterationCount = BitmapUtils.CountLeadingOnes(value);
|
||||||
|
if (currentIterationCount == 0)
|
||||||
|
{
|
||||||
|
outOneCount = totalCount;
|
||||||
|
isLastIteration = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
isLastIteration = false;
|
||||||
|
|
||||||
|
if (currentIterationCount >= 32 - positionInValue)
|
||||||
|
{
|
||||||
|
currentIterationCount = (int)(32 - positionInValue);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
isLastIteration = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int bitsRemainingInBitmap = (int)(_bitCount - it.Index);
|
||||||
|
if (currentIterationCount >= bitsRemainingInBitmap)
|
||||||
|
{
|
||||||
|
currentIterationCount = bitsRemainingInBitmap;
|
||||||
|
isLastIteration = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
totalCount += (uint)currentIterationCount;
|
||||||
|
it.Index += (uint)currentIterationCount;
|
||||||
|
|
||||||
|
if (countingZeros)
|
||||||
|
{
|
||||||
|
if (maxZeroCount != 0 && totalCount >= maxZeroCount)
|
||||||
|
{
|
||||||
|
it.Index -= totalCount - maxZeroCount;
|
||||||
|
totalCount = maxZeroCount;
|
||||||
|
isLastIteration = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (maxOneCount != 0 && totalCount >= maxOneCount)
|
||||||
|
{
|
||||||
|
it.Index -= totalCount - maxOneCount;
|
||||||
|
totalCount = maxOneCount;
|
||||||
|
isLastIteration = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isLastIteration)
|
||||||
|
{
|
||||||
|
if (countingZeros)
|
||||||
|
{
|
||||||
|
outZeroCount = totalCount;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
outOneCount = totalCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (!isLastIteration);
|
||||||
|
|
||||||
|
return Result.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result Reverse(uint index, uint count)
|
public Result Reverse(uint index, uint count)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
if (index + count > _bitCount)
|
||||||
|
return ResultFs.InvalidBitmapIndex.Log();
|
||||||
|
|
||||||
|
uint remaining = count;
|
||||||
|
uint currentIndex = count;
|
||||||
|
uint startBit = index % 0x20;
|
||||||
|
Span<byte> bits = stackalloc byte[4];
|
||||||
|
|
||||||
|
while (remaining != 0)
|
||||||
|
{
|
||||||
|
Result res = _storage.Read(4 * (currentIndex / 0x20), bits);
|
||||||
|
if (res.IsFailure()) return res.Miss();
|
||||||
|
|
||||||
|
uint value = BitmapUtils.ReadU32(bits, 0);
|
||||||
|
|
||||||
|
uint mask = remaining < 0x20 ? ~((1u << (0x20 - (int)remaining)) - 1) : uint.MaxValue;
|
||||||
|
|
||||||
|
if (startBit != 0)
|
||||||
|
{
|
||||||
|
mask >>= (int)startBit;
|
||||||
|
}
|
||||||
|
|
||||||
|
BitmapUtils.WriteU32(bits, 0, value ^ mask);
|
||||||
|
|
||||||
|
res = _storage.Write(4 * (currentIndex / 0x20), bits);
|
||||||
|
if (res.IsFailure()) return res.Miss();
|
||||||
|
|
||||||
|
currentIndex += 0x20 - startBit;
|
||||||
|
|
||||||
|
if (remaining + startBit > 0x20)
|
||||||
|
{
|
||||||
|
remaining -= 0x20 - startBit;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
remaining = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
startBit = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Result.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result Clear()
|
public Result Clear()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
Span<byte> bits = stackalloc byte[128];
|
||||||
|
Span<byte> bitsOriginal = stackalloc byte[128];
|
||||||
|
bits.Clear();
|
||||||
|
|
||||||
|
long size = QuerySize(_bitCount);
|
||||||
|
long offset = 0;
|
||||||
|
|
||||||
|
while (size != 0)
|
||||||
|
{
|
||||||
|
int iterationSize = (int)Math.Min(bits.Length, size);
|
||||||
|
|
||||||
|
Result res = _storage.Read(offset, bitsOriginal.Slice(0, iterationSize));
|
||||||
|
if (res.IsFailure()) return res.Miss();
|
||||||
|
|
||||||
|
if (!bitsOriginal.Slice(0, iterationSize).IsZeros())
|
||||||
|
{
|
||||||
|
res = _storage.Write(offset, bits.Slice(0, iterationSize));
|
||||||
|
if (res.IsFailure()) return res.Miss();
|
||||||
|
}
|
||||||
|
|
||||||
|
size -= iterationSize;
|
||||||
|
offset += iterationSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Result.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Result GetBitmap32(out uint outValue, uint index)
|
private Result GetBitmap32(out uint outValue, uint index)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
Assert.SdkRequiresNotNullOut(out outValue);
|
||||||
|
Assert.SdkRequires((index & 0x1F) == 0);
|
||||||
|
|
||||||
|
Span<byte> bits = stackalloc byte[4];
|
||||||
|
|
||||||
|
Result res = ReadBlock(bits, index);
|
||||||
|
if (res.IsFailure()) return res.Miss();
|
||||||
|
|
||||||
|
outValue = Unsafe.As<byte, uint>(ref MemoryMarshal.GetReference(bits));
|
||||||
|
return Result.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Result GetBit(out bool outValue, uint index)
|
private Result GetBit(out bool outValue, uint index)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
Assert.SdkRequiresNotNullOut(out outValue);
|
||||||
|
|
||||||
|
Span<byte> bits = stackalloc byte[4];
|
||||||
|
|
||||||
|
if (index >= _bitCount)
|
||||||
|
return ResultFs.InvalidBitmapIndex.Log();
|
||||||
|
|
||||||
|
Result res = ReadBlock(bits, index);
|
||||||
|
if (res.IsFailure()) return res.Miss();
|
||||||
|
|
||||||
|
uint value = Unsafe.As<byte, uint>(ref MemoryMarshal.GetReference(bits)) << (int)(index & 0x1F);
|
||||||
|
outValue = (value & 0x80000000) != 0;
|
||||||
|
|
||||||
|
return Result.Success;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,6 +1,5 @@
|
||||||
// ReSharper disable UnusedMember.Local UnusedType.Local
|
using System;
|
||||||
#pragma warning disable CS0169 // Field is never used
|
using LibHac.Diag;
|
||||||
using System;
|
|
||||||
using LibHac.Fs;
|
using LibHac.Fs;
|
||||||
|
|
||||||
namespace LibHac.FsSystem;
|
namespace LibHac.FsSystem;
|
||||||
|
@ -14,45 +13,89 @@ public class DuplexBitmapHolder : IDisposable
|
||||||
|
|
||||||
public DuplexBitmapHolder()
|
public DuplexBitmapHolder()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
_bitmap = new DuplexBitmap();
|
||||||
|
_updateStorage = new ValueSubStorage();
|
||||||
|
_originalStorage = new ValueSubStorage();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
_originalStorage.Dispose();
|
||||||
|
_updateStorage.Dispose();
|
||||||
|
_bitmap.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
public uint GetBlockCount() => throw new NotImplementedException();
|
public uint GetBlockCount() => _blockCount;
|
||||||
public ref readonly ValueSubStorage GetOriginalStorage() => throw new NotImplementedException();
|
public ref readonly ValueSubStorage GetOriginalStorage() => ref _originalStorage;
|
||||||
public ref readonly ValueSubStorage GetUpdateStorage() => throw new NotImplementedException();
|
public ref readonly ValueSubStorage GetUpdateStorage() => ref _updateStorage;
|
||||||
|
|
||||||
public static Result Format(uint size, SubStorage storage, SubStorage storageOriginal)
|
public static Result Format(uint size, SubStorage storage, SubStorage storageOriginal)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
long bitmapSize = DuplexBitmap.QuerySize(size);
|
||||||
|
|
||||||
|
using var subStorage = new ValueSubStorage(storage, 0, bitmapSize);
|
||||||
|
using var subStorageOriginal = new ValueSubStorage(storageOriginal, 0, bitmapSize);
|
||||||
|
|
||||||
|
Result res = DuplexBitmap.Format(size, in subStorage, in subStorageOriginal);
|
||||||
|
if (res.IsFailure()) return res.Miss();
|
||||||
|
|
||||||
|
return Result.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Result Expand(uint bitCountOld, uint bitCountNew, in ValueSubStorage storage, in ValueSubStorage storageOriginal)
|
public static Result Expand(uint bitCountOld, uint bitCountNew, in ValueSubStorage storage, in ValueSubStorage storageOriginal)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
long bitmapSize = DuplexBitmap.QuerySize(bitCountNew);
|
||||||
|
|
||||||
|
using var subStorage = new ValueSubStorage(in storage, 0, bitmapSize);
|
||||||
|
using var subStorageOriginal = new ValueSubStorage(in storageOriginal, 0, bitmapSize);
|
||||||
|
|
||||||
|
Result res = DuplexBitmap.Expand(bitCountOld, bitCountNew, in subStorage, in subStorageOriginal);
|
||||||
|
if (res.IsFailure()) return res.Miss();
|
||||||
|
|
||||||
|
return Result.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Initialize(uint blockCount, in ValueSubStorage storage1, in ValueSubStorage storage2)
|
public void Initialize(uint blockCount, in ValueSubStorage storage1, in ValueSubStorage storage2)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
long size = DuplexBitmap.QuerySize(blockCount);
|
||||||
|
_blockCount = blockCount;
|
||||||
|
|
||||||
|
_updateStorage.Set(in storage1, offset: 0, size);
|
||||||
|
_originalStorage.Set(in storage2, offset: 0, size);
|
||||||
|
|
||||||
|
_bitmap.Initialize(blockCount, in _updateStorage, in _originalStorage);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void InitializeForRead(uint blockCount, in ValueSubStorage storage1, in ValueSubStorage storage2)
|
public void InitializeForRead(uint blockCount, in ValueSubStorage storage1, in ValueSubStorage storage2)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
long size = DuplexBitmap.QuerySize(blockCount);
|
||||||
|
_blockCount = blockCount;
|
||||||
|
|
||||||
|
_updateStorage.Set(in storage1, offset: 0, size);
|
||||||
|
_originalStorage.Set(in storage2, offset: 0, size);
|
||||||
|
|
||||||
|
_bitmap.Initialize(blockCount, in _originalStorage, in _originalStorage);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemountForWrite()
|
public void RemountForWrite()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
_bitmap.FinalizeObject();
|
||||||
|
_bitmap.Initialize(_blockCount, in _updateStorage, in _originalStorage);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SwapDuplexBitmapForHierarchicalDuplexStorage(ref DuplexBitmapHolder outBitmap)
|
private void SwapDuplexBitmapForHierarchicalDuplexStorage(ref DuplexBitmapHolder outBitmap)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
uint blockCount = GetBlockCount();
|
||||||
|
|
||||||
|
Assert.SdkAssert(GetBlockCount() == outBitmap.GetBlockCount());
|
||||||
|
|
||||||
|
using var storageUpdate = new ValueSubStorage(in outBitmap.GetUpdateStorage());
|
||||||
|
using var storageOriginal = new ValueSubStorage(in outBitmap.GetOriginalStorage());
|
||||||
|
|
||||||
|
outBitmap._bitmap.FinalizeObject();
|
||||||
|
outBitmap.InitializeForRead(blockCount, in storageOriginal, in storageUpdate);
|
||||||
|
|
||||||
|
_bitmap.FinalizeObject();
|
||||||
|
Initialize(blockCount, in storageUpdate, in storageUpdate);
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in a new issue