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 long? _size;
/// <summary>
/// The file size.
/// </summary>
public virtual long Size
{
get { return _size.HasValue ? _size.Value : (_size = GetContents().Length).Value; }
}
/// <summary>
/// The CRC32 hash of this file.
/// </summary>
public virtual int Crc32Hash
{
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();
}
}

View File

@ -6,34 +6,64 @@ using Newtonsoft.Json;
namespace GarrysMod.AddonCreator.Addon
{
/// <summary>
/// Represents information about an addon.
/// </summary>
public class AddonJson
{
/// <summary>
/// Creates an instance of <see cref="AddonJson"/>.
/// </summary>
public AddonJson()
{
Version = 1;
}
/// <summary>
/// The title of the addon.
/// </summary>
[JsonProperty("title", NullValueHandling = NullValueHandling.Ignore)]
public string Title { get; set; }
/// <summary>
/// A description of the addon.
/// </summary>
[JsonProperty("description")]
public string Description { get; set; }
/// <summary>
/// The type of the addon.
/// </summary>
[JsonProperty("type")]
public string Type { get; set; }
/// <summary>
/// The assigned tags of the addon.
/// </summary>
[JsonProperty("tags")]
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)]
public List<string> Ignores { get; set; }
/// <summary>
/// The addon's version.
/// </summary>
[JsonProperty("version")]
public int Version { get; set; }
/// <summary>
/// The author of the addon.
/// </summary>
[JsonProperty("author")]
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()
{
if (string.IsNullOrEmpty(Title))
@ -50,8 +80,14 @@ namespace GarrysMod.AddonCreator.Addon
{
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)
{
foreach (var key in files.Keys.ToArray())

View File

@ -4,8 +4,14 @@ using System.Text.RegularExpressions;
namespace GarrysMod.AddonCreator.Addon
{
/// <summary>
/// Handles file whitelisting.
/// </summary>
public static class AddonWhitelist
{
/// <summary>
/// Contains all allowed file patterns.
/// </summary>
private static readonly string[] Whitelist =
{
"addon.json",
@ -77,6 +83,11 @@ namespace GarrysMod.AddonCreator.Addon
_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)
{
ConvertWhitelist();

View File

@ -3,15 +3,26 @@ using Newtonsoft.Json;
namespace GarrysMod.AddonCreator.Addon
{
/// <summary>
/// Represents a JSON-serialized object, prepared for inclusion in <see cref="AddonFile"/> instances.
/// </summary>
public class JsonAddonFileInfo : AddonFileInfo
{
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)
{
_serializedJson = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(obj));
}
/// <summary>
/// Returns the serialized object as a byte array.
/// </summary>
/// <returns></returns>
public override byte[] GetContents()
{
return _serializedJson;

View File

@ -2,20 +2,42 @@
namespace GarrysMod.AddonCreator.Addon
{
/// <summary>
/// Represents an addon file which exists on the harddisk as a separate file.
/// </summary>
public class PhysicalAddonFileInfo : AddonFileInfo
{
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
{
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()
{
return File.ReadAllBytes(_fi.FullName);

View File

@ -3,6 +3,9 @@ using System.IO;
namespace GarrysMod.AddonCreator.Addon
{
/// <summary>
/// Represents an imported segment from another file.
/// </summary>
public class SegmentedAddonFileInfo : AddonFileInfo
{
private readonly int _hash;
@ -10,7 +13,14 @@ namespace GarrysMod.AddonCreator.Addon
private readonly long _pos;
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;
_pos = pos;
@ -18,16 +28,26 @@ namespace GarrysMod.AddonCreator.Addon
_hash = fileHash;
}
/// <summary>
/// The file segment size.
/// </summary>
public override long Size
{
get { return _len; }
}
/// <summary>
/// The file segment's CRC32 hash.
/// </summary>
public override int Crc32Hash
{
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()
{
lock (_stream)

View File

@ -6,6 +6,11 @@ namespace GarrysMod.AddonCreator
{
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)
{
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)
{
if (!nullTerminated)
@ -30,6 +41,12 @@ namespace GarrysMod.AddonCreator
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)
{
if (!nullTerminated)