0

I have a file in a byte[], and I need to remove 0x1000 bytes at every x offset (I have a list of offsets). I have some code to do it, but I'm wondering if there is a better way to do it;

private byte[] RemoveHashBlocks(byte[] fileArray, STFSExplorer stfs)
{
    long startOffset = StartingOffset;
    long endOffset = StartingOffset + Size;

    List<long> hashBlockOffsets = new List<long>();
    foreach (xBlockEntry block in stfs._stfsBlockEntry) 
        if (block.IsHashBlock && (block.BlockOffset >= startOffset && block.BlockOffset <= endOffset))
            hashBlockOffsets.Add(block.BlockOffset - (hashBlockOffsets.Count * 0x1000));

    byte[] newFileAray = new byte[fileArray.Length - (hashBlockOffsets.Count * 0x1000)];

    for (int offset = 0; offset < fileArray.Length; offset++)
        if (hashBlockOffsets[0] == offset)
        {
            offset += 0x1000;
            hashBlockOffsets.RemoveAt(0);
        }
        else
            newFileAray[offset] = fileArray[offset];

    return newFileAray;
}
GSerg
  • 76,472
  • 17
  • 159
  • 346
Alexander Forbes-Reed
  • 2,823
  • 4
  • 27
  • 44
  • 1
    RemoveAt for List or array relocate them. Rather than removing something form the array make a new one and copy only those values that are needed. – Lukasz Madon Jul 08 '12 at 14:07
  • 1
    Using LINQ - `array.Skip(0x1000).Take(N).ToArray();` - from: http://stackoverflow.com/questions/943635/c-sharp-arrays-getting-a-sub-array-from-an-existing-array – Tisho Jul 08 '12 at 14:11

1 Answers1

0
private byte[] RemoveHashBlocks(byte[] fileArray, STFSExplorer stfs)
{
    long startOffset = StartingOffset;
    long size = Size;

    MemoryStream ms = new MemoryStream();
    long lastBlockEnd = 0;

    foreach (xBlockEntry block in stfs._stfsBlockEntry)
    {
        if (block.IsHashBlock)
        {
            long offset = block.BlockOffset - startOffset;
            if (offset + 0x1000 > 0 && offset < size)
            {
                if (offset > lastBlockEnd)
                {
                    ms.Write(fileArray, (int) lastBlockEnd,
                            (int) (offset - lastBlockEnd));
                }
                lastBlockEnd = offset + 0x1000;
            }
        }
    }

    if (lastBlockEnd < size)
    {
        ms.Write(fileArray, (int) lastBlockEnd, (int) (size - lastBlockEnd));
    }

    return ms.ToArray();
}

This assumes stfs._stfsBlockEntry is sorted by BlockOffset.

Markus Jarderot
  • 86,735
  • 21
  • 136
  • 138