Some code cleanup.

lua-bytecode
Icedream 2014-10-22 19:48:30 +02:00
parent 5582debcee
commit f67b95007a
13 changed files with 266 additions and 251 deletions

View File

@ -1,5 +1,4 @@
 using System;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
@ -12,18 +11,68 @@ namespace GarrysMod.AddonCreator
{ {
public class Addon public class Addon
{ {
private static readonly byte[] FormatIdent = Encoding.ASCII.GetBytes("GMAD");
private const byte FormatVersion = 3; private const byte FormatVersion = 3;
private const uint AppID = 4000; private const uint AppID = 4000;
private const uint CompressionSignature = 0xbeefcace; private const uint CompressionSignature = 0xbeefcace;
private static readonly byte[] FormatIdent = Encoding.ASCII.GetBytes("GMAD");
public static void CreateFromFolder() /// <summary>
/// Initializes a new instance of <see cref="Addon" />
/// </summary>
public Addon()
{ {
Files = new Dictionary<string, AddonFileInfo>();
RequiredContent = new List<string>();
Version = 1;
} }
/// <summary> /// <summary>
/// Imports a gmod addon into this instance. /// Returns the timestamp of when the addon was built. This data is retrieved from full imports and for new (unsaved)
/// addons this is 0.
/// </summary>
public ulong BuildTimestamp { get; private set; }
/// <summary>
/// The name of this addon.
/// </summary>
public string Title { get; set; }
/// <summary>
/// The author of this addon.
/// </summary>
public string Author { get; set; }
/// <summary>
/// A description of this addon.
/// </summary>
public string Description { get; set; }
/// <summary>
/// This addon's version.
/// </summary>
public int Version { get; set; }
/// <summary>
/// The files to include in the addon.
/// </summary>
public Dictionary<string, AddonFileInfo> Files { get; private set; }
/// <summary>
/// Currently unused.
/// </summary>
public ulong SteamID { get; set; }
/// <summary>
/// Content that needs to exist in order to run this addon.
/// </summary>
public List<string> RequiredContent { get; private set; }
public static void CreateFromFolder()
{
}
/// <summary>
/// Imports a gmod addon into this instance.
/// </summary> /// </summary>
/// <param name="path">Path to a gmod addon file.</param> /// <param name="path">Path to a gmod addon file.</param>
/// <param name="withMetadata">Import all metadata (title, description, creator, timestamp, etc.) as well?</param> /// <param name="withMetadata">Import all metadata (title, description, creator, timestamp, etc.) as well?</param>
@ -105,7 +154,7 @@ namespace GarrysMod.AddonCreator
var fileSize = sr.ReadInt64(); var fileSize = sr.ReadInt64();
var fileHash = sr.ReadInt32(); var fileHash = sr.ReadInt32();
Debug.WriteLine("\t#{2} : {0} ({1:0.0} kB)", filePath, fileSize / 1024, fileId); Debug.WriteLine("\t#{2} : {0} ({1:0.0} kB)", filePath, fileSize/1024, fileId);
Debug.Assert(fileId == expectedFileId); Debug.Assert(fileId == expectedFileId);
expectedFileId++; expectedFileId++;
@ -113,7 +162,8 @@ namespace GarrysMod.AddonCreator
// avoid duplicates // avoid duplicates
if (newFilesList.ContainsKey(filePath)) if (newFilesList.ContainsKey(filePath))
{ {
throw new IOException("Found duplicate file path in addon file. Contact the addon creator and tell him to build a new proper addon file."); throw new IOException(
"Found duplicate file path in addon file. Contact the addon creator and tell him to build a new proper addon file.");
} }
newFilesList.Add(filePath, new Tuple<long, int>(fileSize, fileHash)); newFilesList.Add(filePath, new Tuple<long, int>(fileSize, fileHash));
@ -127,14 +177,14 @@ namespace GarrysMod.AddonCreator
var fileSize = file.Value.Item1; var fileSize = file.Value.Item1;
var fileHash = file.Value.Item2; var fileHash = file.Value.Item2;
Debug.WriteLine("Extracting: {0} ({1:0.00} kB)", filePath, fileSize / 1024); Debug.WriteLine("Extracting: {0} ({1:0.00} kB)", filePath, fileSize/1024);
var fileContent = new byte[fileSize]; var fileContent = new byte[fileSize];
// long-compatible file reading // long-compatible file reading
for (long i = 0; i < fileSize; i += int.MaxValue) for (long i = 0; i < fileSize; i += int.MaxValue)
{ {
var tempContent = sr.ReadBytes((int)Math.Min(int.MaxValue, fileSize)); var tempContent = sr.ReadBytes((int) Math.Min(int.MaxValue, fileSize));
tempContent.CopyTo(fileContent, i); tempContent.CopyTo(fileContent, i);
} }
@ -151,12 +201,7 @@ namespace GarrysMod.AddonCreator
} }
/// <summary> /// <summary>
/// Returns the timestamp of when the addon was built. This data is retrieved from full imports and for new (unsaved) addons this is 0. /// Exports this addon into a GMA file.
/// </summary>
public ulong BuildTimestamp { get; private set; }
/// <summary>
/// Exports this addon into a GMA file.
/// </summary> /// </summary>
/// <param name="path">The output file path, should be pointing to a writable location ending with ".gma".</param> /// <param name="path">The output file path, should be pointing to a writable location ending with ".gma".</param>
public void Export(string path) public void Export(string path)
@ -178,7 +223,8 @@ namespace GarrysMod.AddonCreator
var files = Files; var files = Files;
// Check for errors and ignores in addon.json // Check for errors and ignores in addon.json
var addonJson = JsonConvert.DeserializeObject<AddonJson>(Encoding.UTF8.GetString(Files["addon.json"].GetContents())); var addonJson =
JsonConvert.DeserializeObject<AddonJson>(Encoding.UTF8.GetString(Files["addon.json"].GetContents()));
addonJson.CheckForErrors(); addonJson.CheckForErrors();
addonJson.RemoveIgnoredFiles(ref files); addonJson.RemoveIgnoredFiles(ref files);
@ -186,7 +232,7 @@ namespace GarrysMod.AddonCreator
Title = addonJson.Title; Title = addonJson.Title;
Description = string.IsNullOrEmpty(addonJson.Description) ? string.Empty : addonJson.Description; Description = string.IsNullOrEmpty(addonJson.Description) ? string.Empty : addonJson.Description;
Version = addonJson.Version; Version = addonJson.Version;
// Create a stripped down version of addon.json for the output gma, it will replace the Description field // Create a stripped down version of addon.json for the output gma, it will replace the Description field
var newDescription = JsonConvert.SerializeObject(new AddonJson var newDescription = JsonConvert.SerializeObject(new AddonJson
{ {
@ -206,8 +252,8 @@ namespace GarrysMod.AddonCreator
if (blacklistedFiles.Any()) if (blacklistedFiles.Any())
{ {
throw new InvalidOperationException("Found files which aren't whitelisted. Remove or ignore those files before you retry packing your addon:" throw new InvalidOperationException("Found files which aren't whitelisted. Remove or ignore those files before you retry packing your addon:"
+ Environment.NewLine + Environment.NewLine + Environment.NewLine + Environment.NewLine
+ string.Join(Environment.NewLine, blacklistedFiles)); + string.Join(Environment.NewLine, blacklistedFiles));
} }
using (var stream = new MemoryStream()) using (var stream = new MemoryStream())
@ -223,14 +269,15 @@ namespace GarrysMod.AddonCreator
sw.Write(SteamID); sw.Write(SteamID);
// Build timestamp // Build timestamp
sw.Write(BuildTimestamp = (ulong)(DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0)).TotalSeconds); sw.Write(BuildTimestamp = (ulong) (DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0)).TotalSeconds);
// Required content // Required content
if (RequiredContent.Count > byte.MaxValue) if (RequiredContent.Count > byte.MaxValue)
{ {
throw new IndexOutOfRangeException("Required content count must not exceed " + byte.MaxValue + " entries."); throw new IndexOutOfRangeException("Required content count must not exceed " + byte.MaxValue +
" entries.");
} }
sw.Write((byte)RequiredContent.Count); sw.Write((byte) RequiredContent.Count);
foreach (var content in RequiredContent) foreach (var content in RequiredContent)
{ {
sw.Write(content, true); sw.Write(content, true);
@ -245,7 +292,8 @@ namespace GarrysMod.AddonCreator
// File list // File list
if (Files.Count > uint.MaxValue) if (Files.Count > uint.MaxValue)
{ {
throw new IndexOutOfRangeException("Number of addon files must not exceed " + uint.MaxValue + " elements."); throw new IndexOutOfRangeException("Number of addon files must not exceed " + uint.MaxValue +
" elements.");
} }
uint fileNum = 0; uint fileNum = 0;
foreach (var file in resultingFiles) foreach (var file in resultingFiles)
@ -256,7 +304,7 @@ namespace GarrysMod.AddonCreator
sw.Write(file.Value.Size); sw.Write(file.Value.Size);
sw.Write(file.Value.Crc32Hash); sw.Write(file.Value.Crc32Hash);
} }
sw.Write((uint)0); // End of file list sw.Write((uint) 0); // End of file list
// File contents // File contents
foreach (var file in resultingFiles) foreach (var file in resultingFiles)
@ -278,50 +326,5 @@ namespace GarrysMod.AddonCreator
} }
} }
} }
/// <summary>
/// The name of this addon.
/// </summary>
public string Title { get; set; }
/// <summary>
/// The author of this addon.
/// </summary>
public string Author { get; set; }
/// <summary>
/// A description of this addon.
/// </summary>
public string Description { get; set; }
/// <summary>
/// This addon's version.
/// </summary>
public int Version { get; set; }
/// <summary>
/// The files to include in the addon.
/// </summary>
public Dictionary<string, AddonFileInfo> Files { get; private set; }
/// <summary>
/// Currently unused.
/// </summary>
public ulong SteamID { get; set; }
/// <summary>
/// Content that needs to exist in order to run this addon.
/// </summary>
public List<string> RequiredContent { get; private set; }
/// <summary>
/// Initializes a new instance of <see cref="Addon"/>
/// </summary>
public Addon()
{
Files = new Dictionary<string, AddonFileInfo>();
RequiredContent = new List<string>();
Version = 1;
}
} }
} }

View File

@ -4,12 +4,18 @@ namespace GarrysMod.AddonCreator
{ {
public abstract class AddonFileInfo public abstract class AddonFileInfo
{ {
private long? _size;
private int? _hash; private int? _hash;
private long? _size;
public virtual long Size { get { return _size.HasValue ? _size.Value : (_size = GetContents().Length).Value; } } public virtual long Size
{
get { return _size.HasValue ? _size.Value : (_size = GetContents().Length).Value; }
}
public virtual int Crc32Hash { get { return _hash.HasValue ? _hash.Value : (_hash = ParallelCRC.Compute(GetContents())).Value; } } public virtual int Crc32Hash
{
get { return _hash.HasValue ? _hash.Value : (_hash = ParallelCRC.Compute(GetContents())).Value; }
}
public abstract byte[] GetContents(); public abstract byte[] GetContents();
} }

View File

@ -2,7 +2,6 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Text;
using Newtonsoft.Json; using Newtonsoft.Json;
namespace GarrysMod.AddonCreator namespace GarrysMod.AddonCreator
@ -14,7 +13,7 @@ namespace GarrysMod.AddonCreator
Version = 1; Version = 1;
} }
[JsonProperty("title", NullValueHandling=NullValueHandling.Ignore)] [JsonProperty("title", NullValueHandling = NullValueHandling.Ignore)]
public string Title { get; set; } public string Title { get; set; }
[JsonProperty("description")] [JsonProperty("description")]
@ -60,4 +59,4 @@ namespace GarrysMod.AddonCreator
} }
} }
} }
} }

View File

@ -1,8 +1,5 @@
using System; using System.Collections.Generic;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
namespace GarrysMod.AddonCreator namespace GarrysMod.AddonCreator
@ -10,69 +7,69 @@ namespace GarrysMod.AddonCreator
public static class AddonWhitelist public static class AddonWhitelist
{ {
private static readonly string[] Whitelist = private static readonly string[] Whitelist =
{ {
"addon.json", "addon.json",
"lua/*.lua", "lua/*.lua",
"scenes/*.vcd", "scenes/*.vcd",
"particles/*.pcf", "particles/*.pcf",
"resource/fonts/*.ttf", "resource/fonts/*.ttf",
"scripts/vehicles/*.txt", "scripts/vehicles/*.txt",
"resource/localization/*/*.properties", "resource/localization/*/*.properties",
"maps/*.bsp", "maps/*.bsp",
"maps/*.nav", "maps/*.nav",
"maps/*.ain", "maps/*.ain",
"maps/thumb/*.png", "maps/thumb/*.png",
"sound/*.wav", "sound/*.wav",
"sound/*.mp3", "sound/*.mp3",
"sound/*.ogg", "sound/*.ogg",
"materials/*.vmt", "materials/*.vmt",
"materials/*.vtf", "materials/*.vtf",
"materials/*.png", "materials/*.png",
"materials/*.jpg", "materials/*.jpg",
"materials/*.jpeg", "materials/*.jpeg",
"models/*.mdl", "models/*.mdl",
"models/*.vtx", "models/*.vtx",
"models/*.phy", "models/*.phy",
"models/*.ani", "models/*.ani",
"models/*.vvd", "models/*.vvd",
"gamemodes/*/*.txt", "gamemodes/*/*.txt",
"gamemodes/*/*.fgd", "gamemodes/*/*.fgd",
"gamemodes/*/logo.png", "gamemodes/*/logo.png",
"gamemodes/*/icon24.png", "gamemodes/*/icon24.png",
"gamemodes/*/gamemode/*.lua", "gamemodes/*/gamemode/*.lua",
"gamemodes/*/entities/effects/*.lua", "gamemodes/*/entities/effects/*.lua",
"gamemodes/*/entities/weapons/*.lua", "gamemodes/*/entities/weapons/*.lua",
"gamemodes/*/entities/entities/*.lua", "gamemodes/*/entities/entities/*.lua",
"gamemodes/*/backgrounds/*.png", "gamemodes/*/backgrounds/*.png",
"gamemodes/*/backgrounds/*.jpg", "gamemodes/*/backgrounds/*.jpg",
"gamemodes/*/backgrounds/*.jpeg", "gamemodes/*/backgrounds/*.jpeg",
"gamemodes/*/content/models/*.mdl", "gamemodes/*/content/models/*.mdl",
"gamemodes/*/content/models/*.vtx", "gamemodes/*/content/models/*.vtx",
"gamemodes/*/content/models/*.phy", "gamemodes/*/content/models/*.phy",
"gamemodes/*/content/models/*.ani", "gamemodes/*/content/models/*.ani",
"gamemodes/*/content/models/*.vvd", "gamemodes/*/content/models/*.vvd",
"gamemodes/*/content/materials/*.vmt", "gamemodes/*/content/materials/*.vmt",
"gamemodes/*/content/materials/*.vtf", "gamemodes/*/content/materials/*.vtf",
"gamemodes/*/content/materials/*.png", "gamemodes/*/content/materials/*.png",
"gamemodes/*/content/materials/*.jpg", "gamemodes/*/content/materials/*.jpg",
"gamemodes/*/content/materials/*.jpeg", "gamemodes/*/content/materials/*.jpeg",
"gamemodes/*/content/scenes/*.vcd", "gamemodes/*/content/scenes/*.vcd",
"gamemodes/*/content/particles/*.pcf", "gamemodes/*/content/particles/*.pcf",
"gamemodes/*/content/resource/fonts/*.ttf", "gamemodes/*/content/resource/fonts/*.ttf",
"gamemodes/*/content/scripts/vehicles/*.txt", "gamemodes/*/content/scripts/vehicles/*.txt",
"gamemodes/*/content/resource/localization/*/*.properties", "gamemodes/*/content/resource/localization/*/*.properties",
"gamemodes/*/content/maps/*.bsp", "gamemodes/*/content/maps/*.bsp",
"gamemodes/*/content/maps/*.nav", "gamemodes/*/content/maps/*.nav",
"gamemodes/*/content/maps/*.ain", "gamemodes/*/content/maps/*.ain",
"gamemodes/*/content/maps/thumb/*.png", "gamemodes/*/content/maps/thumb/*.png",
"gamemodes/*/content/sound/*.wav", "gamemodes/*/content/sound/*.wav",
"gamemodes/*/content/sound/*.mp3", "gamemodes/*/content/sound/*.mp3",
"gamemodes/*/content/sound/*.ogg" "gamemodes/*/content/sound/*.ogg"
}; };
private static Regex[] _regularExpressions; private static Regex[] _regularExpressions;
static void ConvertWhitelist() private static void ConvertWhitelist()
{ {
if (_regularExpressions != null) if (_regularExpressions != null)
return; return;
@ -86,4 +83,4 @@ namespace GarrysMod.AddonCreator
return files.Where(f => !_regularExpressions.Any(rx => rx.IsMatch(f))); return files.Where(f => !_regularExpressions.Any(rx => rx.IsMatch(f)));
} }
} }
} }

View File

@ -1,13 +1,10 @@
using System; using System.IO;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text; using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
namespace GarrysMod.AddonCreator namespace GarrysMod.AddonCreator
{ {
static class Extensions internal static class Extensions
{ {
public static Regex WildcardRegex(this string pattern) public static Regex WildcardRegex(this string pattern)
{ {
@ -43,4 +40,4 @@ namespace GarrysMod.AddonCreator
bw.Write(value); bw.Write(value);
} }
} }
} }

View File

@ -1,5 +1,4 @@
using System; using System;
using System.IO;
namespace CRC32 namespace CRC32
{ {
@ -7,14 +6,16 @@ namespace CRC32
{ {
private const uint kCrcPoly = 0xEDB88320; private const uint kCrcPoly = 0xEDB88320;
private const uint kInitial = 0xFFFFFFFF; private const uint kInitial = 0xFFFFFFFF;
private static readonly uint[] Table;
private const uint CRC_NUM_TABLES = 8; private const uint CRC_NUM_TABLES = 8;
private static readonly uint[] Table;
private uint value;
static OptimizedCRC() static OptimizedCRC()
{ {
unchecked unchecked
{ {
Table = new uint[256 * CRC_NUM_TABLES]; Table = new uint[256*CRC_NUM_TABLES];
uint i; uint i;
for (i = 0; i < 256; i++) for (i = 0; i < 256; i++)
{ {
@ -23,7 +24,7 @@ namespace CRC32
r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1)); r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1));
Table[i] = r; Table[i] = r;
} }
for (; i < 256 * CRC_NUM_TABLES; i++) for (; i < 256*CRC_NUM_TABLES; i++)
{ {
uint r = Table[i - 256]; uint r = Table[i - 256];
Table[i] = Table[r & 0xFF] ^ (r >> 8); Table[i] = Table[r & 0xFF] ^ (r >> 8);
@ -31,42 +32,40 @@ namespace CRC32
} }
} }
private uint value;
public OptimizedCRC() public OptimizedCRC()
{ {
Init(); Init();
} }
public int Value
{
get { return (int) ~value; }
}
/// <summary> /// <summary>
/// Reset CRC /// Reset CRC
/// </summary> /// </summary>
public void Init() public void Init()
{ {
value = kInitial; value = kInitial;
} }
public int Value
{
get { return (int)~value; }
}
public void UpdateByte(byte b) public void UpdateByte(byte b)
{ {
value = (value >> 8) ^ Table[(byte)value ^ b]; value = (value >> 8) ^ Table[(byte) value ^ b];
} }
public void Update(byte[] data, int offset, int count) public void Update(byte[] data, int offset, int count)
{ {
new ArraySegment<byte>(data, offset, count); // check arguments new ArraySegment<byte>(data, offset, count); // check arguments
if (count == 0) return; if (count == 0) return;
var table = OptimizedCRC.Table; // important for performance! var table = Table; // important for performance!
uint crc = value; uint crc = value;
for (; (offset & 7) != 0 && count != 0; count--) for (; (offset & 7) != 0 && count != 0; count--)
crc = (crc >> 8) ^ table[(byte)crc ^ data[offset++]]; crc = (crc >> 8) ^ table[(byte) crc ^ data[offset++]];
if (count >= 8) if (count >= 8)
{ {
@ -80,40 +79,46 @@ namespace CRC32
while (offset != to) while (offset != to)
{ {
crc ^= (uint)(data[offset] + (data[offset + 1] << 8) + (data[offset + 2] << 16) + (data[offset + 3] << 24)); crc ^=
uint high = (uint)(data[offset + 4] + (data[offset + 5] << 8) + (data[offset + 6] << 16) + (data[offset + 7] << 24)); (uint)
(data[offset] + (data[offset + 1] << 8) + (data[offset + 2] << 16) +
(data[offset + 3] << 24));
var high =
(uint)
(data[offset + 4] + (data[offset + 5] << 8) + (data[offset + 6] << 16) +
(data[offset + 7] << 24));
offset += 8; offset += 8;
crc = table[(byte)crc + 0x700] crc = table[(byte) crc + 0x700]
^ table[(byte)(crc >>= 8) + 0x600] ^ table[(byte) (crc >>= 8) + 0x600]
^ table[(byte)(crc >>= 8) + 0x500] ^ table[(byte) (crc >>= 8) + 0x500]
^ table[/*(byte)*/(crc >> 8) + 0x400] ^ table[ /*(byte)*/(crc >> 8) + 0x400]
^ table[(byte)(high) + 0x300] ^ table[(byte) (high) + 0x300]
^ table[(byte)(high >>= 8) + 0x200] ^ table[(byte) (high >>= 8) + 0x200]
^ table[(byte)(high >>= 8) + 0x100] ^ table[(byte) (high >>= 8) + 0x100]
^ table[/*(byte)*/(high >> 8) + 0x000]; ^ table[ /*(byte)*/(high >> 8) + 0x000];
} }
} }
while (count-- != 0) while (count-- != 0)
crc = (crc >> 8) ^ table[(byte)crc ^ data[offset++]]; crc = (crc >> 8) ^ table[(byte) crc ^ data[offset++]];
value = crc; value = crc;
} }
static public int Compute(byte[] data, int offset, int size) public static int Compute(byte[] data, int offset, int size)
{ {
var crc = new OptimizedCRC(); var crc = new OptimizedCRC();
crc.Update(data, offset, size); crc.Update(data, offset, size);
return crc.Value; return crc.Value;
} }
static public int Compute(byte[] data) public static int Compute(byte[] data)
{ {
return Compute(data, 0, data.Length); return Compute(data, 0, data.Length);
} }
static public int Compute(ArraySegment<byte> block) public static int Compute(ArraySegment<byte> block)
{ {
return Compute(block.Array, block.Offset, block.Count); return Compute(block.Array, block.Offset, block.Count);
} }

View File

@ -1,7 +1,5 @@
using System; using System;
using System.IO;
using System.Threading; using System.Threading;
using System.Collections.Generic;
namespace CRC32 namespace CRC32
{ {
@ -9,27 +7,29 @@ namespace CRC32
{ {
private const uint kCrcPoly = 0xEDB88320; private const uint kCrcPoly = 0xEDB88320;
private const uint kInitial = 0xFFFFFFFF; private const uint kInitial = 0xFFFFFFFF;
private static readonly uint[] Table;
private const int CRC_NUM_TABLES = 8; private const int CRC_NUM_TABLES = 8;
private const int ThreadCost = 256 << 10; private const int ThreadCost = 256 << 10;
private static int ThreadCount = Environment.ProcessorCount; private static readonly uint[] Table;
private static readonly int ThreadCount = Environment.ProcessorCount;
private uint value;
static ParallelCRC() static ParallelCRC()
{ {
unchecked unchecked
{ {
Table = new uint[256 * CRC_NUM_TABLES]; Table = new uint[256*CRC_NUM_TABLES];
int i; int i;
for (i = 0; i < 256; i++) for (i = 0; i < 256; i++)
{ {
uint r = (uint)i; var r = (uint) i;
for (int j = 0; j < 8; j++) for (int j = 0; j < 8; j++)
r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1)); r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1));
Table[i] = r; Table[i] = r;
} }
for (; i < 256 * CRC_NUM_TABLES; i++) for (; i < 256*CRC_NUM_TABLES; i++)
{ {
uint r = Table[i - 256]; uint r = Table[i - 256];
Table[i] = Table[r & 0xFF] ^ (r >> 8); Table[i] = Table[r & 0xFF] ^ (r >> 8);
@ -37,34 +37,32 @@ namespace CRC32
} }
} }
private uint value;
public ParallelCRC() public ParallelCRC()
{ {
Init(); Init();
} }
public int Value
{
get { return (int) ~value; }
}
/// <summary> /// <summary>
/// Reset CRC /// Reset CRC
/// </summary> /// </summary>
public void Init() public void Init()
{ {
value = kInitial; value = kInitial;
} }
public int Value
{
get { return (int)~value; }
}
public void UpdateByte(byte b) public void UpdateByte(byte b)
{ {
value = (value >> 8) ^ Table[(byte)value ^ b]; value = (value >> 8) ^ Table[(byte) value ^ b];
} }
public void Update(byte[] data, int offset, int count) public void Update(byte[] data, int offset, int count)
{ {
new ArraySegment<byte>(data, offset, count); // check arguments new ArraySegment<byte>(data, offset, count); // check arguments
if (count <= ThreadCost || ThreadCount <= 1) if (count <= ThreadCost || ThreadCount <= 1)
{ {
@ -75,8 +73,8 @@ namespace CRC32
// choose optimal number of threads to use // choose optimal number of threads to use
int threadCount = ThreadCount; int threadCount = ThreadCount;
L0: L0:
int bytesPerThread = (count + threadCount - 1) / threadCount; int bytesPerThread = (count + threadCount - 1)/threadCount;
if (bytesPerThread < ThreadCost >> 1) if (bytesPerThread < ThreadCost >> 1)
{ {
threadCount--; threadCount--;
@ -110,10 +108,10 @@ namespace CRC32
if (count < 0) throw new ArgumentOutOfRangeException("count"); if (count < 0) throw new ArgumentOutOfRangeException("count");
if (count == 0) return crc; if (count == 0) return crc;
var table = ParallelCRC.Table; var table = Table;
for (; (offset & 7) != 0 && count != 0; count--) for (; (offset & 7) != 0 && count != 0; count--)
crc = (crc >> 8) ^ table[(byte)crc ^ data[offset++]]; crc = (crc >> 8) ^ table[(byte) crc ^ data[offset++]];
if (count >= 8) if (count >= 8)
{ {
@ -123,40 +121,46 @@ namespace CRC32
while (offset != to) while (offset != to)
{ {
crc ^= (uint)(data[offset] + (data[offset + 1] << 8) + (data[offset + 2] << 16) + (data[offset + 3] << 24)); crc ^=
uint high = (uint)(data[offset + 4] + (data[offset + 5] << 8) + (data[offset + 6] << 16) + (data[offset + 7] << 24)); (uint)
(data[offset] + (data[offset + 1] << 8) + (data[offset + 2] << 16) +
(data[offset + 3] << 24));
var high =
(uint)
(data[offset + 4] + (data[offset + 5] << 8) + (data[offset + 6] << 16) +
(data[offset + 7] << 24));
offset += 8; offset += 8;
crc = table[(byte)crc + 0x700] crc = table[(byte) crc + 0x700]
^ table[(byte)(crc >>= 8) + 0x600] ^ table[(byte) (crc >>= 8) + 0x600]
^ table[(byte)(crc >>= 8) + 0x500] ^ table[(byte) (crc >>= 8) + 0x500]
^ table[/*(byte)*/(crc >> 8) + 0x400] ^ table[ /*(byte)*/(crc >> 8) + 0x400]
^ table[(byte)(high) + 0x300] ^ table[(byte) (high) + 0x300]
^ table[(byte)(high >>= 8) + 0x200] ^ table[(byte) (high >>= 8) + 0x200]
^ table[(byte)(high >>= 8) + 0x100] ^ table[(byte) (high >>= 8) + 0x100]
^ table[/*(byte)*/(high >> 8) + 0x000]; ^ table[ /*(byte)*/(high >> 8) + 0x000];
} }
} }
while (count-- != 0) while (count-- != 0)
crc = (crc >> 8) ^ table[(byte)crc ^ data[offset++]]; crc = (crc >> 8) ^ table[(byte) crc ^ data[offset++]];
return crc; return crc;
} }
static public int Compute(byte[] data, int offset, int count) public static int Compute(byte[] data, int offset, int count)
{ {
var crc = new ParallelCRC(); var crc = new ParallelCRC();
crc.Update(data, offset, count); crc.Update(data, offset, count);
return crc.Value; return crc.Value;
} }
static public int Compute(byte[] data) public static int Compute(byte[] data)
{ {
return Compute(data, 0, data.Length); return Compute(data, 0, data.Length);
} }
static public int Compute(ArraySegment<byte> block) public static int Compute(ArraySegment<byte> block)
{ {
return Compute(block.Array, block.Offset, block.Count); return Compute(block.Array, block.Offset, block.Count);
} }
@ -168,8 +172,11 @@ namespace CRC32
* Taken from DotNetZip project sources (http://dotnetzip.codeplex.com/) * Taken from DotNetZip project sources (http://dotnetzip.codeplex.com/)
*/ */
private static uint[] even_cache;
private static uint[] odd_cache;
/// <summary> /// <summary>
/// This function is thread-safe! /// This function is thread-safe!
/// </summary> /// </summary>
private static uint Combine(uint crc1, uint crc2, int length2) private static uint Combine(uint crc1, uint crc2, int length2)
{ {
@ -187,7 +194,7 @@ namespace CRC32
crc1 = ~crc1; crc1 = ~crc1;
crc2 = ~crc2; crc2 = ~crc2;
uint len2 = (uint)length2; var len2 = (uint) length2;
// apply len2 zeros to crc1 (first square will put the operator for one // apply len2 zeros to crc1 (first square will put the operator for one
// zero byte, eight zero bits, in even) // zero byte, eight zero bits, in even)
@ -211,16 +218,13 @@ namespace CRC32
return ~crc1; return ~crc1;
} }
private static uint[] even_cache = null;
private static uint[] odd_cache;
private static void Prepare_even_odd_Cache() private static void Prepare_even_odd_Cache()
{ {
var even = new uint[32]; // even-power-of-two zeros operator var even = new uint[32]; // even-power-of-two zeros operator
var odd = new uint[32]; // odd-power-of-two zeros operator var odd = new uint[32]; // odd-power-of-two zeros operator
// put operator for one zero bit in odd // put operator for one zero bit in odd
odd[0] = kCrcPoly; // the CRC-32 polynomial odd[0] = kCrcPoly; // the CRC-32 polynomial
for (int i = 1; i < 32; i++) odd[i] = 1U << (i - 1); for (int i = 1; i < 32; i++) odd[i] = 1U << (i - 1);
// put operator for two zero bits in even // put operator for two zero bits in even
@ -258,17 +262,17 @@ namespace CRC32
private static uint[] CopyArray(uint[] a) private static uint[] CopyArray(uint[] a)
{ {
var b = new uint[a.Length]; var b = new uint[a.Length];
Buffer.BlockCopy(a, 0, b, 0, a.Length * sizeof(uint)); Buffer.BlockCopy(a, 0, b, 0, a.Length*sizeof (uint));
return b; return b;
} }
#endregion Combining #endregion Combining
class Job private class Job
{ {
private readonly ParallelCRC accumulator;
private readonly Job waitForJob;
private ArraySegment<byte> data; private ArraySegment<byte> data;
private Job waitForJob;
private ParallelCRC accumulator;
private ManualResetEventSlim finished; private ManualResetEventSlim finished;
@ -277,7 +281,7 @@ namespace CRC32
this.data = data; this.data = data;
this.accumulator = accumulator; this.accumulator = accumulator;
this.waitForJob = waitForJob; this.waitForJob = waitForJob;
this.finished = new ManualResetEventSlim(false); finished = new ManualResetEventSlim(false);
} }
public void Do(object arg) public void Do(object arg)
@ -301,5 +305,4 @@ namespace CRC32
} }
} }
} }
} }

View File

@ -4,13 +4,13 @@ namespace GarrysMod.AddonCreator
{ {
public class PhysicalAddonFileInfo : AddonFileInfo public class PhysicalAddonFileInfo : AddonFileInfo
{ {
private readonly FileInfo _fi;
public PhysicalAddonFileInfo(string path) public PhysicalAddonFileInfo(string path)
{ {
_fi = new FileInfo(path); _fi = new FileInfo(path);
} }
private FileInfo _fi;
public override long Size public override long Size
{ {
get { return _fi.Length; } get { return _fi.Length; }

View File

@ -19,7 +19,8 @@ namespace GarrysMod.AddonCreator
// recursively add files // recursively add files
foreach (var file in folder.EnumerateFiles("*", SearchOption.AllDirectories)) foreach (var file in folder.EnumerateFiles("*", SearchOption.AllDirectories))
{ {
var relpath = MakeRelativePath(folder.FullName, file.FullName).Replace(Path.DirectorySeparatorChar, '/'); var relpath =
MakeRelativePath(folder.FullName, file.FullName).Replace(Path.DirectorySeparatorChar, '/');
Console.WriteLine("Adding: {0}", relpath); Console.WriteLine("Adding: {0}", relpath);
addon.Files.Add(relpath, new PhysicalAddonFileInfo(file.FullName)); addon.Files.Add(relpath, new PhysicalAddonFileInfo(file.FullName));
@ -45,7 +46,8 @@ namespace GarrysMod.AddonCreator
foreach (var file in addon.Files) foreach (var file in addon.Files)
{ {
var relpath = file.Key; var relpath = file.Key;
var targetFile = new FileInfo(Path.Combine(folder.FullName, relpath.Replace('/', Path.DirectorySeparatorChar))); var targetFile =
new FileInfo(Path.Combine(folder.FullName, relpath.Replace('/', Path.DirectorySeparatorChar)));
Console.WriteLine("Extracting: {0}", relpath); Console.WriteLine("Extracting: {0}", relpath);
@ -63,7 +65,7 @@ namespace GarrysMod.AddonCreator
// long-compatible copy algorithm // long-compatible copy algorithm
for (long i = 0; i < buffer.LongLength; i += int.MaxValue) for (long i = 0; i < buffer.LongLength; i += int.MaxValue)
{ {
var toWrite = (int)Math.Min(int.MaxValue, buffer.LongLength - i); var toWrite = (int) Math.Min(int.MaxValue, buffer.LongLength - i);
var toWriteBuf = buffer.AsEnumerable(); var toWriteBuf = buffer.AsEnumerable();
for (long j = 0; j < i; j += int.MaxValue) for (long j = 0; j < i; j += int.MaxValue)
{ {

View File

@ -1,10 +1,10 @@
using System.Reflection; using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
// Allgemeine Informationen über eine Assembly werden über die folgenden // Allgemeine Informationen über eine Assembly werden über die folgenden
// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern, // Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
// die mit einer Assembly verknüpft sind. // die mit einer Assembly verknüpft sind.
[assembly: AssemblyTitle("GarrysMod.AddonCreator")] [assembly: AssemblyTitle("GarrysMod.AddonCreator")]
[assembly: AssemblyDescription("")] [assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")] [assembly: AssemblyConfiguration("")]
@ -17,9 +17,11 @@ using System.Runtime.InteropServices;
// Durch Festlegen von ComVisible auf "false" werden die Typen in dieser Assembly unsichtbar // Durch Festlegen von ComVisible auf "false" werden die Typen in dieser Assembly unsichtbar
// für COM-Komponenten. Wenn Sie auf einen Typ in dieser Assembly von // für COM-Komponenten. Wenn Sie auf einen Typ in dieser Assembly von
// COM zugreifen müssen, legen Sie das ComVisible-Attribut für diesen Typ auf "true" fest. // COM zugreifen müssen, legen Sie das ComVisible-Attribut für diesen Typ auf "true" fest.
[assembly: ComVisible(false)] [assembly: ComVisible(false)]
// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird // Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird
[assembly: Guid("bb585862-950d-415b-b518-eb9c7e3d50f3")] [assembly: Guid("bb585862-950d-415b-b518-eb9c7e3d50f3")]
// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten: // Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten:
@ -32,5 +34,6 @@ using System.Runtime.InteropServices;
// Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern // Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern
// übernehmen, indem Sie "*" eingeben: // übernehmen, indem Sie "*" eingeben:
// [assembly: AssemblyVersion("1.0.*")] // [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")] [assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyFileVersion("1.0.0.0")]

View File

@ -5,9 +5,9 @@ namespace GarrysMod.AddonCreator
{ {
public class SegmentedAddonFileInfo : AddonFileInfo public class SegmentedAddonFileInfo : AddonFileInfo
{ {
private Stream _stream; private readonly long _len;
private long _pos; private readonly long _pos;
private long _len; private readonly Stream _stream;
private int _hash; private int _hash;
public SegmentedAddonFileInfo(Stream stream, long pos, long len, int fileHash) public SegmentedAddonFileInfo(Stream stream, long pos, long len, int fileHash)

View File

@ -1,5 +1,4 @@
using System; using System;
using System.IO;
namespace CRC32 namespace CRC32
{ {
@ -9,6 +8,8 @@ namespace CRC32
private const uint kInitial = 0xFFFFFFFF; private const uint kInitial = 0xFFFFFFFF;
private static readonly uint[] Table; private static readonly uint[] Table;
private uint value;
static TraditionalCRC() static TraditionalCRC()
{ {
unchecked unchecked
@ -24,51 +25,49 @@ namespace CRC32
} }
} }
private uint value;
public TraditionalCRC() public TraditionalCRC()
{ {
Init(); Init();
} }
public int Value
{
get { return (int) ~value; }
}
/// <summary> /// <summary>
/// Reset CRC /// Reset CRC
/// </summary> /// </summary>
public void Init() public void Init()
{ {
value = kInitial; value = kInitial;
} }
public int Value
{
get { return (int)~value; }
}
public void UpdateByte(byte b) public void UpdateByte(byte b)
{ {
value = (value >> 8) ^ Table[(byte)value ^ b]; value = (value >> 8) ^ Table[(byte) value ^ b];
} }
public void Update(byte[] data, int offset, int count) public void Update(byte[] data, int offset, int count)
{ {
if (count < 0) throw new ArgumentOutOfRangeException("count"); if (count < 0) throw new ArgumentOutOfRangeException("count");
while (count-- != 0) while (count-- != 0)
value = (value >> 8) ^ Table[(byte)value ^ data[offset++]]; value = (value >> 8) ^ Table[(byte) value ^ data[offset++]];
} }
static public int Compute(byte[] data, int offset, int count) public static int Compute(byte[] data, int offset, int count)
{ {
var crc = new TraditionalCRC(); var crc = new TraditionalCRC();
crc.Update(data, offset, count); crc.Update(data, offset, count);
return crc.Value; return crc.Value;
} }
static public int Compute(byte[] data) public static int Compute(byte[] data)
{ {
return Compute(data, 0, data.Length); return Compute(data, 0, data.Length);
} }
static public int Compute(ArraySegment<byte> block) public static int Compute(ArraySegment<byte> block)
{ {
return Compute(block.Array, block.Offset, block.Count); return Compute(block.Array, block.Offset, block.Count);
} }

View File

@ -1,4 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<packages> <packages>
<package id="Newtonsoft.Json" version="6.0.5" targetFramework="net40" /> <package id="Newtonsoft.Json" version="6.0.5" targetFramework="net40" />
</packages> </packages>