4 Commits
1.2.0 ... 1.3.0

Author SHA1 Message Date
Matt Nadareski
75cc8376a8 Bump version 2023-11-21 11:24:19 -05:00
Matt Nadareski
0dea1fb437 Use Linq bridge library 2023-11-21 00:22:56 -05:00
Matt Nadareski
92df6b21e3 Support .NET Framework 2.0 2023-11-21 00:12:40 -05:00
Matt Nadareski
7da7967762 Support .NET Framework 3.5 2023-11-20 22:00:32 -05:00
13 changed files with 93 additions and 117 deletions

View File

@@ -74,7 +74,7 @@ namespace SabreTools.IO
int i3 = BitConverter.ToInt32(retval, 8);
int i4 = BitConverter.ToInt32(retval, 12);
return new decimal(new int[] { i1, i2, i3, i4 });
return new decimal([i1, i2, i3, i4]);
}
/// <summary>

View File

@@ -266,7 +266,7 @@ namespace SabreTools.IO
byte[] nullTerminator = encoding.GetBytes(new char[] { '\0' });
int charWidth = nullTerminator.Length;
List<char> keyChars = new List<char>();
var keyChars = new List<char>();
while (offset < content.Length)
{
char c = encoding.GetChars(content, offset, charWidth)[0];
@@ -277,7 +277,7 @@ namespace SabreTools.IO
break;
}
return new string(keyChars.ToArray()).TrimEnd('\0');
return new string([.. keyChars]).TrimEnd('\0');
}
}
}

View File

@@ -118,13 +118,23 @@ namespace SabreTools.IO
return null;
// If it does and it is empty, return a blank enumerable
#if NET20 || NET35
if (!Directory.GetFiles(root, "*", SearchOption.AllDirectories).Any())
#else
if (!Directory.EnumerateFileSystemEntries(root, "*", SearchOption.AllDirectories).Any())
return new List<string>();
#endif
return [];
// Otherwise, get the complete list
#if NET20 || NET35
return Directory.GetDirectories(root, "*", SearchOption.AllDirectories)
.Where(dir => !Directory.GetFiles(dir, "*", SearchOption.AllDirectories).Any())
.ToList();
#else
return Directory.EnumerateDirectories(root, "*", SearchOption.AllDirectories)
.Where(dir => !Directory.EnumerateFileSystemEntries(dir, "*", SearchOption.AllDirectories).Any())
.ToList();
#endif
}
}
}

View File

@@ -14,15 +14,13 @@ namespace SabreTools.IO
/// </summary>
public class IniFile : IDictionary<string, string?>
{
private Dictionary<string, string?>? _keyValuePairs = new Dictionary<string, string?>();
private Dictionary<string, string?>? _keyValuePairs = [];
public string? this[string? key]
{
get
{
if (_keyValuePairs == null)
_keyValuePairs = new Dictionary<string, string?>();
_keyValuePairs ??= [];
key = key?.ToLowerInvariant() ?? string.Empty;
if (_keyValuePairs.ContainsKey(key))
return _keyValuePairs[key];
@@ -31,9 +29,7 @@ namespace SabreTools.IO
}
set
{
if (_keyValuePairs == null)
_keyValuePairs = new Dictionary<string, string?>();
_keyValuePairs ??= [];
key = key?.ToLowerInvariant() ?? string.Empty;
_keyValuePairs[key] = value;
}
@@ -93,10 +89,8 @@ namespace SabreTools.IO
if (!File.Exists(path))
return false;
using (var fileStream = File.OpenRead(path))
{
return Parse(fileStream);
}
using var fileStream = File.OpenRead(path);
return Parse(fileStream);
}
/// <summary>
@@ -111,38 +105,37 @@ namespace SabreTools.IO
// Keys are case-insensitive by default
try
{
using (var reader = new IniReader(stream, Encoding.UTF8))
// TODO: Can we use the section header in the reader?
using var reader = new IniReader(stream, Encoding.UTF8);
string? section = string.Empty;
while (!reader.EndOfStream)
{
// TODO: Can we use the section header in the reader?
string? section = string.Empty;
while (!reader.EndOfStream)
// If we dont have a next line
if (!reader.ReadNextLine())
break;
// Process the row according to type
switch (reader.RowType)
{
// If we dont have a next line
if (!reader.ReadNextLine())
case IniRowType.SectionHeader:
section = reader.Section;
break;
// Process the row according to type
switch (reader.RowType)
{
case IniRowType.SectionHeader:
section = reader.Section;
break;
case IniRowType.KeyValue:
string? key = reader.KeyValuePair?.Key;
case IniRowType.KeyValue:
string? key = reader.KeyValuePair?.Key;
// Section names are prepended to the key with a '.' separating
if (!string.IsNullOrEmpty(section))
key = $"{section}.{key}";
// Section names are prepended to the key with a '.' separating
if (!string.IsNullOrEmpty(section))
key = $"{section}.{key}";
// Set or overwrite keys in the returned dictionary
this[key] = reader.KeyValuePair?.Value;
break;
// Set or overwrite keys in the returned dictionary
this[key] = reader.KeyValuePair?.Value;
break;
default:
// No-op
break;
}
default:
// No-op
break;
}
}
}
@@ -164,10 +157,8 @@ namespace SabreTools.IO
if (_keyValuePairs == null || _keyValuePairs.Count == 0)
return false;
using (var fileStream = File.OpenWrite(path))
{
return Write(fileStream);
}
using var fileStream = File.OpenWrite(path);
return Write(fileStream);
}
/// <summary>
@@ -185,39 +176,38 @@ namespace SabreTools.IO
try
{
using (IniWriter writer = new IniWriter(stream, Encoding.UTF8))
using IniWriter writer = new(stream, Encoding.UTF8);
// Order the dictionary by keys to link sections together
var orderedKeyValuePairs = _keyValuePairs.OrderBy(kvp => kvp.Key);
string section = string.Empty;
foreach (var keyValuePair in orderedKeyValuePairs)
{
// Order the dictionary by keys to link sections together
var orderedKeyValuePairs = _keyValuePairs.OrderBy(kvp => kvp.Key);
// Extract the key and value
string key = keyValuePair.Key;
string? value = keyValuePair.Value;
string section = string.Empty;
foreach (var keyValuePair in orderedKeyValuePairs)
// We assume '.' is a section name separator
if (key.Contains("."))
{
// Extract the key and value
string key = keyValuePair.Key;
string? value = keyValuePair.Value;
// Split the key by '.'
string[] data = keyValuePair.Key.Split('.');
// We assume '.' is a section name separator
if (key.Contains("."))
// If the key contains an '.', we need to put them back in
string newSection = data[0].Trim();
key = string.Join(".", data.Skip(1).ToArray()).Trim();
// If we have a new section, write it out
if (!string.Equals(newSection, section, StringComparison.OrdinalIgnoreCase))
{
// Split the key by '.'
string[] data = keyValuePair.Key.Split('.');
// If the key contains an '.', we need to put them back in
string newSection = data[0].Trim();
key = string.Join(".", data.Skip(1).ToArray()).Trim();
// If we have a new section, write it out
if (!string.Equals(newSection, section, StringComparison.OrdinalIgnoreCase))
{
writer.WriteSection(newSection);
section = newSection;
}
writer.WriteSection(newSection);
section = newSection;
}
// Now write out the key and value in a standardized way
writer.WriteKeyValuePair(key, value);
}
// Now write out the key and value in a standardized way
writer.WriteKeyValuePair(key, value);
}
}
catch
@@ -231,18 +221,9 @@ namespace SabreTools.IO
#region IDictionary Impelementations
#if NET40 || NET452
public ICollection<string> Keys => _keyValuePairs?.Keys?.ToArray() ?? new string[0];
#else
public ICollection<string> Keys => _keyValuePairs?.Keys?.ToArray() ?? Array.Empty<string>();
#endif
public ICollection<string> Keys => _keyValuePairs?.Keys?.ToArray() ?? [];
#if NET40 || NET452
public ICollection<string?> Values => _keyValuePairs?.Values?.ToArray() ?? new string[0];
#else
public ICollection<string?> Values => _keyValuePairs?.Values?.ToArray() ?? Array.Empty<string?>();
#endif
public ICollection<string?> Values => _keyValuePairs?.Values?.ToArray() ?? [];
public int Count => (_keyValuePairs as ICollection<KeyValuePair<string, string>>)?.Count ?? 0;

View File

@@ -23,7 +23,7 @@ namespace NaturalSort
public NaturalComparer()
{
table = new Dictionary<string, string[]>();
table = [];
}
public void Dispose()

View File

@@ -23,7 +23,7 @@ namespace NaturalSort
public NaturalReversedComparer()
{
table = new Dictionary<string, string[]>();
table = [];
}
public void Dispose()

View File

@@ -1,20 +0,0 @@
using System;
using System.Collections.Generic;
#if NET40
namespace SabreTools.IO
{
internal delegate U LinqOrderByDelegate<T, U>(T str);
internal static partial class EnumerationExtensions
{
public static IEnumerable<T> OrderBy<T, U>(this IEnumerable<T> arr, LinqOrderByDelegate<T, U> func)
{
// TODO: Implement ordering
return arr;
}
}
}
#endif

View File

@@ -58,7 +58,7 @@ namespace SabreTools.IO
/// <returns>List with all new files</returns>
private static List<string> GetDirectoriesOrdered(string dir, string pattern = "*")
{
return GetDirectoriesOrderedHelper(dir, new List<string>(), pattern);
return GetDirectoriesOrderedHelper(dir, [], pattern);
}
/// <summary>
@@ -71,7 +71,7 @@ namespace SabreTools.IO
private static List<string> GetDirectoriesOrderedHelper(string dir, List<string> infiles, string pattern)
{
// Take care of the files in the top directory
List<string> toadd = Directory.EnumerateDirectories(dir, pattern, SearchOption.TopDirectoryOnly).ToList();
List<string> toadd = [.. Directory.GetDirectories(dir, pattern, SearchOption.TopDirectoryOnly)];
toadd.Sort(new NaturalComparer());
infiles.AddRange(toadd);
@@ -137,7 +137,7 @@ namespace SabreTools.IO
/// <returns>List with all new files</returns>
public static List<string> GetFilesOrdered(string dir, string pattern = "*")
{
return GetFilesOrderedHelper(dir, new List<string>(), pattern);
return GetFilesOrderedHelper(dir, [], pattern);
}
/// <summary>
@@ -150,12 +150,12 @@ namespace SabreTools.IO
private static List<string> GetFilesOrderedHelper(string dir, List<string> infiles, string pattern)
{
// Take care of the files in the top directory
List<string> toadd = Directory.EnumerateFiles(dir, pattern, SearchOption.TopDirectoryOnly).ToList();
List<string> toadd = [.. Directory.GetFiles(dir, pattern, SearchOption.TopDirectoryOnly)];
toadd.Sort(new NaturalComparer());
infiles.AddRange(toadd);
// Then recurse through and add from the directories
List<string> subDirs = Directory.EnumerateDirectories(dir, pattern, SearchOption.TopDirectoryOnly).ToList();
List<string> subDirs = [.. Directory.GetDirectories(dir, pattern, SearchOption.TopDirectoryOnly)];
subDirs.Sort(new NaturalComparer());
foreach (string subdir in subDirs)
{

View File

@@ -49,7 +49,7 @@ namespace SabreTools.IO.Readers
/// <summary>
/// Contents of the currently read line as an internal item
/// </summary>
public Dictionary<string, string>? Internal { get; private set; } = new Dictionary<string, string>();
public Dictionary<string, string>? Internal { get; private set; } = [];
/// <summary>
/// Current internal item name
@@ -164,7 +164,7 @@ namespace SabreTools.IO.Readers
string normalizedValue = gc[1].Value.ToLowerInvariant();
string[] linegc = SplitLineAsCMP(gc[2].Value);
Internal = new Dictionary<string, string>();
Internal = [];
for (int i = 0; i < linegc.Length; i++)
{
string key = linegc[i].Replace("\"", string.Empty);

View File

@@ -124,7 +124,7 @@ namespace SabreTools.IO.Readers
// https://stackoverflow.com/questions/3776458/split-a-comma-separated-string-with-both-quoted-and-unquoted-strings
var lineSplitRegex = new Regex($"(?:^|{Separator})(\"(?:[^\"]+|\"\")*\"|[^{Separator}]*)");
var temp = new List<string>();
foreach (Match? match in lineSplitRegex.Matches(fullLine))
foreach (Match? match in lineSplitRegex.Matches(fullLine).Cast<Match?>())
{
string? curr = match?.Value;
if (curr == null)

View File

@@ -2,12 +2,12 @@
<PropertyGroup>
<!-- Assembly Properties -->
<TargetFrameworks>net40;net452;net462;net472;net48;netcoreapp3.1;net5.0;net6.0;net7.0;net8.0</TargetFrameworks>
<TargetFrameworks>net20;net35;net40;net452;net462;net472;net48;netcoreapp3.1;net5.0;net6.0;net7.0;net8.0</TargetFrameworks>
<RuntimeIdentifiers>win-x86;win-x64;win-arm64;linux-x64;linux-arm64;osx-x64;osx-arm64</RuntimeIdentifiers>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<Version>1.2.0</Version>
<Version>1.3.0</Version>
<!-- Package Properties -->
<Authors>Matt Nadareski</Authors>
@@ -25,4 +25,9 @@
<None Include="README.md" Pack="true" PackagePath=""/>
</ItemGroup>
<!-- Support for old .NET versions -->
<ItemGroup Condition="$(TargetFramework.StartsWith(`net2`)) OR $(TargetFramework.StartsWith(`net3`))">
<PackageReference Include="Net30.LinqBridge" Version="1.3.0" />
</ItemGroup>
</Project>

View File

@@ -219,7 +219,7 @@ namespace SabreTools.IO
byte[] nullTerminator = encoding.GetBytes(new char[] { '\0' });
int charWidth = nullTerminator.Length;
List<byte> tempBuffer = new List<byte>();
var tempBuffer = new List<byte>();
byte[] buffer = new byte[charWidth];
while (stream.Position < stream.Length && stream.Read(buffer, 0, charWidth) != 0 && !buffer.SequenceEqual(nullTerminator))
@@ -227,7 +227,7 @@ namespace SabreTools.IO
tempBuffer.AddRange(buffer);
}
return encoding.GetString(tempBuffer.ToArray());
return encoding.GetString([.. tempBuffer]);
}
/// <summary>

View File

@@ -71,7 +71,7 @@ namespace SabreTools.IO.Writers
/// <summary>
/// State table for determining the state machine
/// </summary>
private readonly State[] stateTable = {
private readonly State[] stateTable = [
// State.Start State.Prolog State.Element State.Attribute State.Content State.AttrOnly State.Epilog
//
/* Token.None */ State.Prolog, State.Prolog, State.Content, State.Content, State.Content, State.Error, State.Epilog,
@@ -82,7 +82,7 @@ namespace SabreTools.IO.Writers
/* Token.StartAttribute */ State.AttrOnly, State.Error, State.Attribute, State.Attribute, State.Error, State.Error, State.Error,
/* Token.EndAttribute */ State.Error, State.Error, State.Error, State.Element, State.Error, State.Epilog, State.Error,
/* Token.Content */ State.Content, State.Content, State.Content, State.Attribute, State.Content, State.Attribute, State.Epilog,
};
];
/// <summary>
/// Current state in the machine