More documentation and overriding.

lua-bytecode
Icedream 2014-12-11 02:48:31 +01:00
parent 567f8b7e4a
commit e0a64208b2
7 changed files with 130 additions and 3 deletions

View File

@ -7,16 +7,26 @@ namespace GarrysMod.AddonCreator.Addon
private int? _hash; private int? _hash;
private long? _size; private long? _size;
/// <summary>
/// The file size.
/// </summary>
public virtual long Size public virtual long Size
{ {
get { return _size.HasValue ? _size.Value : (_size = GetContents().Length).Value; } get { return _size.HasValue ? _size.Value : (_size = GetContents().Length).Value; }
} }
/// <summary>
/// The CRC32 hash of this file.
/// </summary>
public virtual int Crc32Hash public virtual int Crc32Hash
{ {
get { return _hash.HasValue ? _hash.Value : (_hash = ParallelCRC.Compute(GetContents())).Value; } get { return _hash.HasValue ? _hash.Value : (_hash = ParallelCRC.Compute(GetContents())).Value; }
} }
/// <summary>
/// Reads all contents of this file and returns it as a byte array.
/// </summary>
/// <returns>Byte array of the file content</returns>
public abstract byte[] GetContents(); public abstract byte[] GetContents();
} }
} }

View File

@ -6,34 +6,64 @@ using Newtonsoft.Json;
namespace GarrysMod.AddonCreator.Addon namespace GarrysMod.AddonCreator.Addon
{ {
/// <summary>
/// Represents information about an addon.
/// </summary>
public class AddonJson public class AddonJson
{ {
/// <summary>
/// Creates an instance of <see cref="AddonJson"/>.
/// </summary>
public AddonJson() public AddonJson()
{ {
Version = 1; Version = 1;
} }
/// <summary>
/// The title of the addon.
/// </summary>
[JsonProperty("title", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("title", NullValueHandling = NullValueHandling.Ignore)]
public string Title { get; set; } public string Title { get; set; }
/// <summary>
/// A description of the addon.
/// </summary>
[JsonProperty("description")] [JsonProperty("description")]
public string Description { get; set; } public string Description { get; set; }
/// <summary>
/// The type of the addon.
/// </summary>
[JsonProperty("type")] [JsonProperty("type")]
public string Type { get; set; } public string Type { get; set; }
/// <summary>
/// The assigned tags of the addon.
/// </summary>
[JsonProperty("tags")] [JsonProperty("tags")]
public List<string> Tags { get; set; } public List<string> Tags { get; set; }
/// <summary>
/// A list of patterns of files to ignore when exporting the addon.
/// </summary>
[JsonProperty("ignore", NullValueHandling = NullValueHandling.Ignore)] [JsonProperty("ignore", NullValueHandling = NullValueHandling.Ignore)]
public List<string> Ignores { get; set; } public List<string> Ignores { get; set; }
/// <summary>
/// The addon's version.
/// </summary>
[JsonProperty("version")] [JsonProperty("version")]
public int Version { get; set; } public int Version { get; set; }
/// <summary>
/// The author of the addon.
/// </summary>
[JsonProperty("author")] [JsonProperty("author")]
public string Author { get; set; } public string Author { get; set; }
/// <summary>
/// Validates the addon information for mistakes. This includes missing/empty title, missing/empty/invalid description and if the type is missing/empty.
/// </summary>
internal void CheckForErrors() internal void CheckForErrors()
{ {
if (string.IsNullOrEmpty(Title)) if (string.IsNullOrEmpty(Title))
@ -50,8 +80,14 @@ namespace GarrysMod.AddonCreator.Addon
{ {
throw new MissingFieldException("Type is empty or not specified."); throw new MissingFieldException("Type is empty or not specified.");
} }
// TODO: Validate tags using a predefined list.
} }
/// <summary>
/// Removes files matching any of the ignore patterns from a prepared file dictionary.
/// </summary>
/// <param name="files">The file dictionary to scan for files to remove</param>
public void RemoveIgnoredFiles(ref Dictionary<string, AddonFileInfo> files) public void RemoveIgnoredFiles(ref Dictionary<string, AddonFileInfo> files)
{ {
foreach (var key in files.Keys.ToArray()) foreach (var key in files.Keys.ToArray())

View File

@ -4,8 +4,14 @@ using System.Text.RegularExpressions;
namespace GarrysMod.AddonCreator.Addon namespace GarrysMod.AddonCreator.Addon
{ {
/// <summary>
/// Handles file whitelisting.
/// </summary>
public static class AddonWhitelist public static class AddonWhitelist
{ {
/// <summary>
/// Contains all allowed file patterns.
/// </summary>
private static readonly string[] Whitelist = private static readonly string[] Whitelist =
{ {
"addon.json", "addon.json",
@ -77,6 +83,11 @@ namespace GarrysMod.AddonCreator.Addon
_regularExpressions = Whitelist.Select(w => w.WildcardRegex()).ToArray(); _regularExpressions = Whitelist.Select(w => w.WildcardRegex()).ToArray();
} }
/// <summary>
/// Scans a list of file paths for files which are not whitelisted and returns the found file paths.
/// </summary>
/// <param name="files">The list of file paths to scan</param>
/// <returns>Found files which are not whitelisted</returns>
public static IEnumerable<string> FindBlacklistedFiles(IEnumerable<string> files) public static IEnumerable<string> FindBlacklistedFiles(IEnumerable<string> files)
{ {
ConvertWhitelist(); ConvertWhitelist();

View File

@ -3,15 +3,26 @@ using Newtonsoft.Json;
namespace GarrysMod.AddonCreator.Addon namespace GarrysMod.AddonCreator.Addon
{ {
/// <summary>
/// Represents a JSON-serialized object, prepared for inclusion in <see cref="AddonFile"/> instances.
/// </summary>
public class JsonAddonFileInfo : AddonFileInfo public class JsonAddonFileInfo : AddonFileInfo
{ {
private readonly byte[] _serializedJson; private readonly byte[] _serializedJson;
/// <summary>
/// JSON-serializes a given object using UTF-8 encoding.
/// </summary>
/// <param name="obj">The object to serialize</param>
public JsonAddonFileInfo(object obj) public JsonAddonFileInfo(object obj)
{ {
_serializedJson = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(obj)); _serializedJson = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(obj));
} }
/// <summary>
/// Returns the serialized object as a byte array.
/// </summary>
/// <returns></returns>
public override byte[] GetContents() public override byte[] GetContents()
{ {
return _serializedJson; return _serializedJson;

View File

@ -2,20 +2,42 @@
namespace GarrysMod.AddonCreator.Addon namespace GarrysMod.AddonCreator.Addon
{ {
/// <summary>
/// Represents an addon file which exists on the harddisk as a separate file.
/// </summary>
public class PhysicalAddonFileInfo : AddonFileInfo public class PhysicalAddonFileInfo : AddonFileInfo
{ {
private readonly FileInfo _fi; private readonly FileInfo _fi;
public PhysicalAddonFileInfo(string path) /// <summary>
/// Creates an instance of <see cref="PhysicalAddonFileInfo"/> from a given file path.
/// </summary>
/// <param name="path">The file path</param>
public PhysicalAddonFileInfo(string path) : this(new FileInfo(path))
{ {
_fi = new FileInfo(path);
} }
/// <summary>
/// Creates an instance of <see cref="PhysicalAddonFileInfo"/> from given file information.
/// </summary>
/// <param name="file">The file info instance</param>
public PhysicalAddonFileInfo(FileInfo file)
{
_fi = file;
}
/// <summary>
/// The size of the file.
/// </summary>
public override long Size public override long Size
{ {
get { return _fi.Length; } get { return _fi.Length; }
} }
/// <summary>
/// Returns the file contents as a byte array.
/// </summary>
/// <returns>A byte array of the file content</returns>
public override byte[] GetContents() public override byte[] GetContents()
{ {
return File.ReadAllBytes(_fi.FullName); return File.ReadAllBytes(_fi.FullName);

View File

@ -3,6 +3,9 @@ using System.IO;
namespace GarrysMod.AddonCreator.Addon namespace GarrysMod.AddonCreator.Addon
{ {
/// <summary>
/// Represents an imported segment from another file.
/// </summary>
public class SegmentedAddonFileInfo : AddonFileInfo public class SegmentedAddonFileInfo : AddonFileInfo
{ {
private readonly int _hash; private readonly int _hash;
@ -10,7 +13,14 @@ namespace GarrysMod.AddonCreator.Addon
private readonly long _pos; private readonly long _pos;
private readonly Stream _stream; private readonly Stream _stream;
public SegmentedAddonFileInfo(Stream stream, long pos, long len, int fileHash) /// <summary>
/// Constructs an instance of <see cref="SegmentedAddonFileInfo" /> using the given parameters.
/// </summary>
/// <param name="stream">The source stream from which to extract the file segment</param>
/// <param name="pos">The offset from which to start reading</param>
/// <param name="len">The length of the segment to read</param>
/// <param name="fileHash">The CRC32 of the segment to read</param>
internal SegmentedAddonFileInfo(Stream stream, long pos, long len, int fileHash)
{ {
_stream = stream; _stream = stream;
_pos = pos; _pos = pos;
@ -18,16 +28,26 @@ namespace GarrysMod.AddonCreator.Addon
_hash = fileHash; _hash = fileHash;
} }
/// <summary>
/// The file segment size.
/// </summary>
public override long Size public override long Size
{ {
get { return _len; } get { return _len; }
} }
/// <summary>
/// The file segment's CRC32 hash.
/// </summary>
public override int Crc32Hash public override int Crc32Hash
{ {
get { return _hash; } get { return _hash; }
} }
/// <summary>
/// Reads the complete segment and returns the content as a byte array.
/// </summary>
/// <returns>The content of the file segment</returns>
public override byte[] GetContents() public override byte[] GetContents()
{ {
lock (_stream) lock (_stream)

View File

@ -6,6 +6,11 @@ namespace GarrysMod.AddonCreator
{ {
internal static class Extensions internal static class Extensions
{ {
/// <summary>
/// Generates a regular expression from a wildcard.
/// </summary>
/// <param name="pattern">The wildcard pattern</param>
/// <returns>A regular expression of the given pattern</returns>
public static Regex WildcardRegex(this string pattern) public static Regex WildcardRegex(this string pattern)
{ {
return new Regex("^" + Regex.Escape(pattern) return new Regex("^" + Regex.Escape(pattern)
@ -14,6 +19,12 @@ namespace GarrysMod.AddonCreator
+ "$"); + "$");
} }
/// <summary>
/// Reads a string. If nullTerminated is true, this will not use native string reading but reads until a NULL char is found.
/// </summary>
/// <param name="br">The binary reader instance</param>
/// <param name="nullTerminated">Use null-terminated reading instead of native string reading</param>
/// <returns>The read string</returns>
public static string ReadString(this BinaryReader br, bool nullTerminated) public static string ReadString(this BinaryReader br, bool nullTerminated)
{ {
if (!nullTerminated) if (!nullTerminated)
@ -30,6 +41,12 @@ namespace GarrysMod.AddonCreator
return sb.ToString(); return sb.ToString();
} }
/// <summary>
/// Writes a string. If nullTerminated is true, the string will not be written using native string writing but without length prefix and with NULL char termination instead.
/// </summary>
/// <param name="bw">The binary writer instance</param>
/// <param name="value">The string to write</param>
/// <param name="nullTerminated">Use null-terminated writing instead of native string writing</param>
public static void Write(this BinaryWriter bw, string value, bool nullTerminated) public static void Write(this BinaryWriter bw, string value, bool nullTerminated)
{ {
if (!nullTerminated) if (!nullTerminated)