Files
OpenRA/OpenRA.Game/FileFormats/Format40.cs
RoosterDragon e63f330717 Improved efficiency of startup methods.
- ShpReader will copy the input stream into memory just once rather than for every header.
- ShpReader.CopyImageData switched to use Array.Copy since that uses some unsafe magic for speed.
- In ActorInfo, cache a GetType call and prevent needless materialization in PrerequisitesOf.
- In ObjectCreator, cache type and ctor lookups since these are expensive and often repeated.
- Implement IReadOnlyDictionary<T, U> on Cache<T, U> to provide some supplementary functions.
- In TechTree.GatherOwnedPrerequisites, rearrange a Boolean 'and' expression to evaluate expensive functions later in the chain, and use ContainsKey to speed up name check.
2014-06-09 17:13:01 +01:00

79 lines
1.7 KiB
C#

#region Copyright & License Information
/*
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation. For more information,
* see COPYING.
*/
#endregion
namespace OpenRA.FileFormats
{
public static class Format40
{
public static int DecodeInto(byte[] src, byte[] dest, int srcOffset)
{
var ctx = new FastByteReader(src, srcOffset);
int destIndex = 0;
while (true)
{
byte i = ctx.ReadByte();
if ((i & 0x80) == 0)
{
int count = i & 0x7F;
if (count == 0)
{
// case 6
count = ctx.ReadByte();
byte value = ctx.ReadByte();
for (int end = destIndex + count; destIndex < end; destIndex++)
dest[destIndex] ^= value;
}
else
{
// case 5
for (int end = destIndex + count; destIndex < end; destIndex++)
dest[destIndex] ^= ctx.ReadByte();
}
}
else
{
int count = i & 0x7F;
if (count == 0)
{
count = ctx.ReadWord();
if (count == 0)
return destIndex;
if ((count & 0x8000) == 0)
{
// case 2
destIndex += (count & 0x7FFF);
}
else if ((count & 0x4000) == 0)
{
// case 3
for (int end = destIndex + (count & 0x3FFF); destIndex < end; destIndex++)
dest[destIndex] ^= ctx.ReadByte();
}
else
{
// case 4
byte value = ctx.ReadByte();
for (int end = destIndex + (count & 0x3FFF); destIndex < end; destIndex++)
dest[destIndex] ^= value;
}
}
else
{
// case 1
destIndex += count;
}
}
}
}
}
}