Skip to content

Commit

Permalink
nissl-lab#564 avoidance of exceptions for flow control to substantial…
Browse files Browse the repository at this point in the history
…ly reduce time to debug tests.
  • Loading branch information
drmason789 committed May 30, 2021
1 parent 8d701db commit 4ad4323
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 38 deletions.
10 changes: 10 additions & 0 deletions main/POIFS/FileSystem/BlockStore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,16 @@ public abstract class BlockStore
/// <param name="offset"></param>
/// <returns></returns>
public abstract ByteBuffer GetBlockAt(int offset);


/// <summary>
/// Tries to load the block at the given offset.
/// </summary>
/// <param name="offset">An offset in the buffer, 0 or greater.</param>
/// <param name="byteBuffer">The resulting buffer, if possible.</param>
/// <returns>True if it was possible to load the block from the specified offset, false if the offset is beyond the size of the buffer.</returns>
public abstract bool TryGetBlockAt(int offset, out ByteBuffer byteBuffer);

/// <summary>
/// Extends the file if required to hold blocks up to
/// the specified offset, and return the block from there.
Expand Down
12 changes: 2 additions & 10 deletions main/POIFS/FileSystem/DirectoryNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -346,16 +346,8 @@ public Entry GetEntry(String name)
Entry rval = null;

if (name != null)
{
try
{
rval = (Entry)_byname[name];
}
catch (KeyNotFoundException)
{
throw new FileNotFoundException("no such entry: \"" + name + "\"");
}
}
_byname.TryGetValue(name, out rval);

if (rval == null)
{

Expand Down
51 changes: 34 additions & 17 deletions main/POIFS/FileSystem/NPOIFSFileSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -484,18 +484,38 @@ private BATBlock CreateBAT(int offset, bool isBAT)
* Load the block at the given offset.
*/
public override ByteBuffer GetBlockAt(int offset)
{
ByteBuffer output = null;
if (!TryGetBlockAt(offset, out output))
{
throw new IndexOutOfRangeException("Block " + offset + " not found");
}

return output;
}

/**
* Try to load the block at the given offset, and if the offset is beyond the end of the buffer, return false.
*/
public override bool TryGetBlockAt(int offset, out ByteBuffer buffer)
{
// The header block doesn't count, so add one
long startAt = (offset + 1) * bigBlockSize.GetBigBlockSize();

buffer = null;

if (startAt >= _data.Size)
return false;

try
{
return _data.Read(bigBlockSize.GetBigBlockSize(), startAt);
buffer = _data.Read(bigBlockSize.GetBigBlockSize(), startAt);
return true;
}
catch (IndexOutOfRangeException e)
{
throw new IndexOutOfRangeException("Block " + offset + " not found - ", e);
}

}

/**
Expand All @@ -504,21 +524,18 @@ public override ByteBuffer GetBlockAt(int offset)
*/
public override ByteBuffer CreateBlockIfNeeded(int offset)
{
try
{
return GetBlockAt(offset);
}
catch (IndexOutOfRangeException)
{
// The header block doesn't count, so add one
long startAt = (offset + 1) * bigBlockSize.GetBigBlockSize();
// Allocate and write
ByteBuffer buffer = ByteBuffer.CreateBuffer(GetBigBlockSize());
// byte[] buffer = new byte[GetBigBlockSize()];
_data.Write(buffer, startAt);
// Retrieve the properly backed block
return GetBlockAt(offset);
}
if (TryGetBlockAt(offset, out var byteBuffer))
return byteBuffer;

// The header block doesn't count, so add one
long startAt = (offset + 1) * bigBlockSize.GetBigBlockSize();
// Allocate and write
ByteBuffer buffer = ByteBuffer.CreateBuffer(GetBigBlockSize());
// byte[] buffer = new byte[GetBigBlockSize()];
_data.Write(buffer, startAt);
// Retrieve the properly backed block
return GetBlockAt(offset);

}

/**
Expand Down
47 changes: 36 additions & 11 deletions main/POIFS/FileSystem/NPOIFSMiniStore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@ public NPOIFSMiniStore(NPOIFSFileSystem filesystem, RootProperty root,
}

/**
* Load the block at the given offset.
* Load the block at the given offset, optionally throwing an exception if the offset is beyond the limit of the buffer.
*/
public override ByteBuffer GetBlockAt(int offset)
private ByteBuffer GetBlockAt(int offset, bool throwIfNotFound)
{
// Which big block is this?
int byteOffset = offset * POIFSConstants.SMALL_BLOCK_SIZE;
Expand All @@ -67,19 +67,48 @@ public override ByteBuffer GetBlockAt(int offset)
{
it.Next();
}
ByteBuffer dataBlock = it.Next();
if (dataBlock == null)

if (!it.HasNext())
{
throw new IndexOutOfRangeException("Big block " + bigBlockNumber + " outside stream");
if(throwIfNotFound)
throw new IndexOutOfRangeException("Big block " + bigBlockNumber + " outside stream");
return null;
}

// Position ourselves, and take a slice
ByteBuffer dataBlock = it.Next();
dataBlock.Position = dataBlock.Position + bigBlockOffset;
ByteBuffer miniBuffer = dataBlock.Slice();
miniBuffer.Limit = POIFSConstants.SMALL_BLOCK_SIZE;
return miniBuffer;
}

/**
* Load the block at the given offset.
*/
public override ByteBuffer GetBlockAt(int offset)
{
return GetBlockAt(offset, true);
}


/**
* Try to load the block at the given offset, and if the offset is beyond the end of the buffer, return false.
*/
public override bool TryGetBlockAt(int offset, out ByteBuffer byteBuffer)
{
byteBuffer = null;
try
{
byteBuffer = GetBlockAt(offset, false);
return byteBuffer!=null;
}
catch(IndexOutOfRangeException)
{
// Try to avoid getting here. A point of having this TryDoSomething is to avoid the expense of exception handling.
return false;
}
}
/**
* Load the block, extending the underlying stream if needed
*/
Expand All @@ -93,12 +122,8 @@ public override ByteBuffer CreateBlockIfNeeded(int offset)
}

// Try to Get it without extending the stream
if (! firstInStore) {
try
{
return GetBlockAt(offset);
}catch (IndexOutOfRangeException){}
}
if (!firstInStore && TryGetBlockAt(offset, out var result))
return result;

// Need to extend the stream
// TODO Replace this with proper append support
Expand Down

0 comments on commit 4ad4323

Please sign in to comment.