Writing for all save file layers

This commit is contained in:
Alex Barney 2018-10-17 17:15:57 -05:00
parent c0393449f1
commit da5eec1b3d
11 changed files with 116 additions and 33 deletions

View file

@ -82,7 +82,7 @@ namespace LibHac
public override void Flush()
{
throw new NotImplementedException();
DataLevel.Flush();
}
public override long Seek(long offset, SeekOrigin origin)
@ -115,7 +115,7 @@ namespace LibHac
public override void Write(byte[] buffer, int offset, int count)
{
throw new NotImplementedException();
DataLevel.Write(buffer, offset, count);
}
public override bool CanRead => DataLevel.CanRead;

View file

@ -30,11 +30,6 @@ namespace LibHac
BlockValidities = new Validity[SectorCount];
}
public override void Flush()
{
throw new NotImplementedException();
}
public override long Seek(long offset, SeekOrigin origin)
{
switch (origin)
@ -119,6 +114,11 @@ namespace LibHac
int toWrite = (int)Math.Min(count, Length - Position);
byte[] hash = DoHash(buffer, offset, toWrite);
if (Type == IntegrityStreamType.Save && buffer.IsEmpty())
{
Array.Clear(hash, 0, DigestSize);
}
base.Write(buffer, offset, count);
HashStream.Position = blockNum * DigestSize;
@ -148,6 +148,12 @@ namespace LibHac
return hash;
}
public override void Flush()
{
HashStream.Flush();
base.Flush();
}
public override bool CanRead => true;
public override bool CanSeek => true;
public override bool CanWrite => false;

View file

@ -22,7 +22,7 @@ namespace LibHac.Save
public override void Flush()
{
throw new NotImplementedException();
Data.Flush();
}
public override int Read(byte[] buffer, int offset, int count)
@ -125,5 +125,11 @@ namespace LibHac.Save
Data.Position = Iterator.PhysicalBlock * BlockSize + segmentPos;
}
}
protected override void Dispose(bool disposing)
{
Flush();
base.Dispose(disposing);
}
}
}

View file

@ -28,7 +28,9 @@ namespace LibHac.Save
public override void Flush()
{
throw new NotImplementedException();
BitmapStream?.Flush();
DataA?.Flush();
DataB?.Flush();
}
public override int Read(byte[] buffer, int offset, int count)
@ -57,6 +59,30 @@ namespace LibHac.Save
return totalBytesRead;
}
public override void Write(byte[] buffer, int offset, int count)
{
long remaining = Math.Min(count, Length - Position);
if (remaining <= 0) return;
int inOffset = offset;
while (remaining > 0)
{
int blockNum = (int)(Position / BlockSize);
int blockPos = (int)(Position % BlockSize);
int bytesToWrite = (int)Math.Min(remaining, BlockSize - blockPos);
Stream data = Bitmap.Bitmap[blockNum] ? DataB : DataA;
data.Position = blockNum * BlockSize + blockPos;
data.Write(buffer, inOffset, bytesToWrite);
inOffset += bytesToWrite;
remaining -= bytesToWrite;
Position += bytesToWrite;
}
}
public override long Seek(long offset, SeekOrigin origin)
{
switch (origin)
@ -80,11 +106,6 @@ namespace LibHac.Save
throw new NotImplementedException();
}
public override void Write(byte[] buffer, int offset, int count)
{
throw new NotImplementedException();
}
public override bool CanRead => true;
public override bool CanSeek => true;
public override bool CanWrite => false;

View file

@ -45,6 +45,25 @@ namespace LibHac.Save
return count;
}
public override void Write(byte[] buffer, int offset, int count)
{
long remaining = Math.Min(Length - Position, count);
if (remaining <= 0) return;
int inPos = offset;
while (remaining > 0)
{
long remainInEntry = BlockSize - Position % BlockSize;
int toRead = (int)Math.Min(remaining, remainInEntry);
BaseStream.Write(buffer, inPos, toRead);
inPos += toRead;
remaining -= toRead;
Position += toRead;
}
}
public override long Seek(long offset, SeekOrigin origin)
{
switch (origin)
@ -64,11 +83,15 @@ namespace LibHac.Save
}
public override void SetLength(long value) => throw new NotSupportedException();
public override void Write(byte[] buffer, int offset, int count) => throw new NotSupportedException();
public override void Flush() => throw new NotSupportedException();
public override void Flush()
{
BaseStream.Flush();
}
public override bool CanRead => true;
public override bool CanSeek => true;
public override bool CanWrite => false;
public override bool CanWrite => true;
public override long Length { get; }
public override long Position
{

View file

@ -32,7 +32,7 @@ namespace LibHac.Save
public override void Flush()
{
throw new System.NotImplementedException();
DataLayer.Flush();
}
public override int Read(byte[] buffer, int offset, int count)
@ -52,7 +52,7 @@ namespace LibHac.Save
public override void Write(byte[] buffer, int offset, int count)
{
throw new System.NotImplementedException();
DataLayer.Write(buffer, offset, count);
}
public override bool CanRead => DataLayer.CanRead;

View file

@ -43,6 +43,27 @@ namespace LibHac.Save
return count;
}
public override void Write(byte[] buffer, int offset, int count)
{
if (CurrentEntry == null) throw new EndOfStreamException();
long remaining = Math.Min(CurrentEntry.VirtualOffsetEnd - Position, count);
if (remaining <= 0) return;
int inPos = offset;
while (remaining > 0)
{
long remainInEntry = CurrentEntry.VirtualOffsetEnd - Position;
int toWrite = (int)Math.Min(remaining, remainInEntry);
BaseStream.Write(buffer, inPos, toWrite);
inPos += toWrite;
remaining -= toWrite;
Position += toWrite;
}
}
public override long Seek(long offset, SeekOrigin origin)
{
switch (origin)
@ -66,14 +87,9 @@ namespace LibHac.Save
throw new NotSupportedException();
}
public override void Write(byte[] buffer, int offset, int count)
{
throw new NotSupportedException();
}
public override void Flush()
{
throw new NotImplementedException();
BaseStream.Flush();
}
private MapEntry GetMapEntry(long offset)

View file

@ -46,6 +46,7 @@ namespace LibHac.Streams
_baseStream.Position = _currentSector * _bufferSize;
_baseStream.Write(_buffer, 0, _bufferSize);
_bufferPos = 0;
_readBytes = 0;
_bufferDirty = false;
}
@ -53,6 +54,7 @@ namespace LibHac.Streams
public override void Flush()
{
WriteSectorIfDirty();
_baseStream.Flush();
}
public override int Read(byte[] buffer, int offset, int count)

View file

@ -32,7 +32,13 @@ namespace LibHac.Streams
return new SharedStream(this, offset, length);
}
public void Flush() => BaseStream.Flush();
public void Flush()
{
lock (Locker)
{
BaseStream.Flush();
}
}
public int Read(long readOffset, byte[] buffer, int bufferOffset, int count)
{

View file

@ -21,7 +21,7 @@ namespace LibHac.Streams
baseStream.Seek(offset, SeekOrigin.Begin);
}
public SubStream(Stream baseStream, long offset)
public SubStream(Stream baseStream, long offset)
: this(baseStream, offset, baseStream.Length - offset) { }
public override int Read(byte[] buffer, int offset, int count)
@ -32,6 +32,14 @@ namespace LibHac.Streams
return BaseStream.Read(buffer, offset, count);
}
public override void Write(byte[] buffer, int offset, int count)
{
long remaining = Math.Min(Length - Position, count);
if (remaining <= 0) return;
BaseStream.Write(buffer, offset, (int)remaining);
}
public override long Length { get; }
public override bool CanRead => BaseStream.CanRead;
public override bool CanWrite => BaseStream.CanWrite;
@ -70,10 +78,5 @@ namespace LibHac.Streams
public override void SetLength(long value) => throw new NotSupportedException();
public override void Flush() => BaseStream.Flush();
public override void Write(byte[] buffer, int offset, int count)
{
throw new NotImplementedException();
}
}
}

View file

@ -90,7 +90,7 @@ namespace hactoolnet
sb.AppendLine();
sb.AppendLine("Savefile:");
PrintItem(sb, colLen, "CMAC Signature:", save.Header.Cmac);
PrintItem(sb, colLen, $"CMAC Signature{save.Header.SignatureValidity.GetValidityString()}:", save.Header.Cmac);
PrintItem(sb, colLen, "Title ID:", $"{save.Header.ExtraData.TitleId:x16}");
PrintItem(sb, colLen, "User ID:", save.Header.ExtraData.UserId);
PrintItem(sb, colLen, "Save ID:", $"{save.Header.ExtraData.SaveId:x16}");