mirror of
https://github.com/SabreTools/SabreTools.IO.git
synced 2026-02-08 13:49:55 +00:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8924a50432 | ||
|
|
97f00a2565 | ||
|
|
f35231d95b | ||
|
|
96c6bba93e | ||
|
|
b0d81f225b |
@@ -1,4 +1,4 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net6.0;net8.0</TargetFrameworks>
|
||||
@@ -10,13 +10,13 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="coverlet.collector" Version="6.0.0">
|
||||
<PackageReference Include="coverlet.collector" Version="6.0.2">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
|
||||
<PackageReference Include="xunit" Version="2.6.2" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.4">
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.1" />
|
||||
<PackageReference Include="xunit" Version="2.9.2" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
#if NET40_OR_GREATER || NETCOREAPP
|
||||
using System.Linq;
|
||||
#endif
|
||||
#if NET7_0_OR_GREATER
|
||||
using System.Numerics;
|
||||
#endif
|
||||
@@ -638,7 +640,18 @@ namespace SabreTools.IO.Extensions
|
||||
/// </summary>
|
||||
private static string? ReadStringType(BinaryReader reader, Encoding encoding, FieldInfo? fi)
|
||||
{
|
||||
var marshalAsAttr = fi?.GetCustomAttributes(typeof(MarshalAsAttribute), true)?.FirstOrDefault() as MarshalAsAttribute;
|
||||
#if NET20 || NET35
|
||||
var attributes = fi?.GetCustomAttributes(typeof(MarshalAsAttribute), true);
|
||||
MarshalAsAttribute? marshalAsAttr;
|
||||
if (attributes == null || attributes.Length == 0)
|
||||
marshalAsAttr = default;
|
||||
else
|
||||
marshalAsAttr = attributes[0] as MarshalAsAttribute;
|
||||
#else
|
||||
var marshalAsAttr = fi?
|
||||
.GetCustomAttributes(typeof(MarshalAsAttribute), true)?
|
||||
.FirstOrDefault() as MarshalAsAttribute;
|
||||
#endif
|
||||
|
||||
switch (marshalAsAttr?.Value)
|
||||
{
|
||||
|
||||
@@ -862,7 +862,7 @@ namespace SabreTools.IO.Extensions
|
||||
{
|
||||
// If we have an invalid length
|
||||
if (length < 0)
|
||||
throw new ArgumentOutOfRangeException($"{nameof(length)} must be 0 or a positive value");
|
||||
throw new ArgumentOutOfRangeException($"{nameof(length)} must be 0 or a positive value, {length} requested");
|
||||
|
||||
// Handle the 0-byte case
|
||||
if (length == 0)
|
||||
@@ -870,7 +870,7 @@ namespace SabreTools.IO.Extensions
|
||||
|
||||
// If there are not enough bytes
|
||||
if (offset + length > content.Length)
|
||||
throw new System.IO.EndOfStreamException($"Requested to read {nameof(length)} bytes from {nameof(content)}, {content.Length - offset} returned");
|
||||
throw new System.IO.EndOfStreamException($"Requested to read {length} bytes from {nameof(content)}, {content.Length - offset} returned");
|
||||
|
||||
// Handle the general case, forcing a read of the correct length
|
||||
byte[] buffer = new byte[length];
|
||||
|
||||
@@ -3,10 +3,9 @@ using System;
|
||||
#endif
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
#if NETCOREAPP3_1_OR_GREATER
|
||||
using System.IO.Enumeration;
|
||||
#endif
|
||||
#if NET40_OR_GREATER || NETCOREAPP
|
||||
using System.Linq;
|
||||
#endif
|
||||
using System.Text;
|
||||
|
||||
namespace SabreTools.IO.Extensions
|
||||
@@ -124,13 +123,28 @@ namespace SabreTools.IO.Extensions
|
||||
return null;
|
||||
|
||||
// If it does and it is empty, return a blank enumerable
|
||||
#if NET20 || NET35
|
||||
if (new List<string>(root!.SafeEnumerateFileSystemEntries("*", SearchOption.AllDirectories)).Count == 0)
|
||||
#else
|
||||
if (!root!.SafeEnumerateFileSystemEntries("*", SearchOption.AllDirectories).Any())
|
||||
#endif
|
||||
return [];
|
||||
|
||||
// Otherwise, get the complete list
|
||||
#if NET20 || NET35
|
||||
var empty = new List<string>();
|
||||
foreach (var dir in root!.SafeEnumerateDirectories("*", SearchOption.AllDirectories))
|
||||
{
|
||||
if (new List<string>(dir!.SafeEnumerateFileSystemEntries("*", SearchOption.AllDirectories)).Count == 0)
|
||||
empty.Add(dir);
|
||||
}
|
||||
|
||||
return empty;
|
||||
#else
|
||||
return root!.SafeEnumerateDirectories("*", SearchOption.AllDirectories)
|
||||
.Where(dir => !dir.SafeEnumerateFileSystemEntries("*", SearchOption.AllDirectories).Any())
|
||||
.ToList();
|
||||
#endif
|
||||
}
|
||||
|
||||
#region Safe Directory Enumeration
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
#if NET40_OR_GREATER || NETCOREAPP
|
||||
using System.Linq;
|
||||
#endif
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
@@ -27,7 +29,7 @@ namespace SabreTools.IO.Extensions
|
||||
return null;
|
||||
|
||||
// Get the first attribute that matches
|
||||
return attributes.First() as T;
|
||||
return attributes[0] as T;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -45,7 +47,7 @@ namespace SabreTools.IO.Extensions
|
||||
return null;
|
||||
|
||||
// Get the first attribute that matches
|
||||
return attributes.First() as T;
|
||||
return attributes[0] as T;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -115,7 +117,21 @@ namespace SabreTools.IO.Extensions
|
||||
var nextFields = nextType.GetFields();
|
||||
foreach (var field in nextFields)
|
||||
{
|
||||
#if NET20 || NET35
|
||||
bool any = false;
|
||||
foreach (var f in fieldsList)
|
||||
{
|
||||
if (f.Name == field.Name && f.FieldType == field.FieldType)
|
||||
{
|
||||
any = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!any)
|
||||
#else
|
||||
if (!fieldsList.Any(f => f.Name == field.Name && f.FieldType == field.FieldType))
|
||||
#endif
|
||||
fieldsList.Add(field);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -846,7 +846,7 @@ namespace SabreTools.IO.Extensions
|
||||
{
|
||||
// If we have an invalid length
|
||||
if (length < 0)
|
||||
throw new ArgumentOutOfRangeException($"{nameof(length)} must be 0 or a positive value");
|
||||
throw new ArgumentOutOfRangeException($"{nameof(length)} must be 0 or a positive value, {length} requested");
|
||||
|
||||
// Handle the 0-byte case
|
||||
if (length == 0)
|
||||
@@ -856,7 +856,7 @@ namespace SabreTools.IO.Extensions
|
||||
byte[] buffer = new byte[length];
|
||||
int read = stream.Read(buffer, 0, length);
|
||||
if (read < length)
|
||||
throw new EndOfStreamException($"Requested to read {nameof(length)} bytes from {nameof(stream)}, {read} returned");
|
||||
throw new EndOfStreamException($"Requested to read {length} bytes from {nameof(stream)}, {read} returned");
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
#if NET40_OR_GREATER || NETCOREAPP
|
||||
using System.Linq;
|
||||
#endif
|
||||
using System.Text;
|
||||
using SabreTools.IO.Readers;
|
||||
using SabreTools.IO.Writers;
|
||||
@@ -179,7 +181,17 @@ namespace SabreTools.IO
|
||||
using IniWriter writer = new(stream, Encoding.UTF8);
|
||||
|
||||
// Order the dictionary by keys to link sections together
|
||||
#if NET20 || NET35
|
||||
var orderedKeyValuePairs = new List<KeyValuePair<string, string?>>();
|
||||
foreach (var kvp in _keyValuePairs)
|
||||
{
|
||||
orderedKeyValuePairs.Add(kvp);
|
||||
}
|
||||
|
||||
orderedKeyValuePairs.Sort((x, y) => x.Key.CompareTo(y.Key));
|
||||
#else
|
||||
var orderedKeyValuePairs = _keyValuePairs.OrderBy(kvp => kvp.Key);
|
||||
#endif
|
||||
|
||||
string section = string.Empty;
|
||||
foreach (var keyValuePair in orderedKeyValuePairs)
|
||||
@@ -196,7 +208,13 @@ namespace SabreTools.IO
|
||||
|
||||
// If the key contains an '.', we need to put them back in
|
||||
string newSection = data[0].Trim();
|
||||
#if NET20 || NET35
|
||||
string[] dataKey = new string[data.Length - 1];
|
||||
Array.Copy(data, 1, dataKey, 0, dataKey.Length);
|
||||
key = string.Join(".", dataKey).Trim();
|
||||
#else
|
||||
key = string.Join(".", data.Skip(1).ToArray()).Trim();
|
||||
#endif
|
||||
|
||||
// If we have a new section, write it out
|
||||
if (!string.Equals(newSection, section, StringComparison.OrdinalIgnoreCase))
|
||||
@@ -221,9 +239,39 @@ namespace SabreTools.IO
|
||||
|
||||
#region IDictionary Impelementations
|
||||
|
||||
#if NET20 || NET35
|
||||
public ICollection<string> Keys
|
||||
{
|
||||
get
|
||||
{
|
||||
var keys = _keyValuePairs?.Keys;
|
||||
if (keys == null || keys.Count == 0)
|
||||
return [];
|
||||
|
||||
var keyArr = new string[keys.Count];
|
||||
keys.CopyTo(keyArr, 0);
|
||||
return keyArr;
|
||||
}
|
||||
}
|
||||
|
||||
public ICollection<string?> Values
|
||||
{
|
||||
get
|
||||
{
|
||||
var values = _keyValuePairs?.Values;
|
||||
if (values == null || values.Count == 0)
|
||||
return [];
|
||||
|
||||
var valueArr = new string[values.Count];
|
||||
values.CopyTo(valueArr, 0);
|
||||
return valueArr;
|
||||
}
|
||||
}
|
||||
#else
|
||||
public ICollection<string> Keys => _keyValuePairs?.Keys?.ToArray() ?? [];
|
||||
|
||||
public ICollection<string?> Values => _keyValuePairs?.Values?.ToArray() ?? [];
|
||||
#endif
|
||||
|
||||
public int Count => (_keyValuePairs as ICollection<KeyValuePair<string, string>>)?.Count ?? 0;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using SabreTools.IO.Extensions;
|
||||
using SabreTools.Matching;
|
||||
using SabreTools.Matching.Compare;
|
||||
|
||||
namespace SabreTools.IO
|
||||
{
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
#if NET40_OR_GREATER || NETCOREAPP
|
||||
using System.Linq;
|
||||
#endif
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
@@ -295,11 +297,22 @@ namespace SabreTools.IO.Readers
|
||||
s = s.Trim();
|
||||
|
||||
// Now we get each string, divided up as cleanly as possible
|
||||
#if NET20 || NET35
|
||||
var matchList = Regex.Matches(s, InternalPatternAttributesCMP);
|
||||
var matchStrings = new List<string>();
|
||||
foreach (Match m in matchList)
|
||||
{
|
||||
matchStrings.Add(m.Groups[0].Value);
|
||||
}
|
||||
|
||||
string[] matches = matchStrings.ToArray();
|
||||
#else
|
||||
string[] matches = Regex
|
||||
.Matches(s, InternalPatternAttributesCMP)
|
||||
.Cast<Match>()
|
||||
.Select(m => m.Groups[0].Value)
|
||||
.ToArray();
|
||||
#endif
|
||||
|
||||
return matches;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
#if NET40_OR_GREATER || NETCOREAPP
|
||||
using System.Linq;
|
||||
#endif
|
||||
using System.Text;
|
||||
|
||||
namespace SabreTools.IO.Readers
|
||||
@@ -118,7 +120,13 @@ namespace SabreTools.IO.Readers
|
||||
|
||||
// If the value field contains an '=', we need to put them back in
|
||||
string key = data[0].Trim();
|
||||
#if NET20 || NET35
|
||||
var valueArr = new string[data.Length - 1];
|
||||
Array.Copy(data, 1, valueArr, 0, valueArr.Length);
|
||||
string value = string.Join("=", valueArr).Trim();
|
||||
#else
|
||||
string value = string.Join("=", data.Skip(1).ToArray()).Trim();
|
||||
#endif
|
||||
|
||||
KeyValuePair = new KeyValuePair<string, string>(key, value);
|
||||
RowType = IniRowType.KeyValue;
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
#if NET40_OR_GREATER || NETCOREAPP
|
||||
using System.Linq;
|
||||
#endif
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
@@ -124,7 +126,11 @@ 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>();
|
||||
#if NET20 || NET35
|
||||
foreach (Match? match in lineSplitRegex.Matches(fullLine))
|
||||
#else
|
||||
foreach (Match? match in lineSplitRegex.Matches(fullLine).Cast<Match?>())
|
||||
#endif
|
||||
{
|
||||
string? curr = match?.Value;
|
||||
if (curr == null)
|
||||
@@ -143,7 +149,17 @@ namespace SabreTools.IO.Readers
|
||||
// Otherwise, just split on the delimiter
|
||||
else
|
||||
{
|
||||
Line = fullLine.Split(Separator).Select(f => f.Trim()).ToList();
|
||||
#if NET20 || NET35
|
||||
Line = new List<string>();
|
||||
foreach (string f in fullLine.Split(Separator))
|
||||
{
|
||||
Line.Add(f.Trim());
|
||||
}
|
||||
#else
|
||||
Line = fullLine.Split(Separator)
|
||||
.Select(f => f.Trim())
|
||||
.ToList();
|
||||
#endif
|
||||
}
|
||||
|
||||
// If we don't have a header yet and are expecting one, read this as the header
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<!-- Assembly Properties -->
|
||||
@@ -7,7 +7,7 @@
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<Version>1.4.10</Version>
|
||||
<Version>1.4.12</Version>
|
||||
<WarningsNotAsErrors>CS0618</WarningsNotAsErrors>
|
||||
|
||||
<!-- Package Properties -->
|
||||
@@ -23,16 +23,11 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<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" />
|
||||
<None Include="../README.md" Pack="true" PackagePath="" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="SabreTools.Matching" Version="1.3.1" />
|
||||
<PackageReference Include="SabreTools.Matching" Version="1.3.2" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
#if NET40_OR_GREATER || NETCOREAPP
|
||||
using System.Linq;
|
||||
#endif
|
||||
|
||||
namespace SabreTools.IO.Streams
|
||||
{
|
||||
@@ -110,7 +112,11 @@ namespace SabreTools.IO.Streams
|
||||
/// </summary>
|
||||
public ReadOnlyCompositeStream(IEnumerable<Stream> streams)
|
||||
{
|
||||
#if NET20 || NET35
|
||||
_streams = new List<Stream>(streams);
|
||||
#else
|
||||
_streams = streams.ToList();
|
||||
#endif
|
||||
_length = 0;
|
||||
_position = 0;
|
||||
|
||||
@@ -148,7 +154,7 @@ namespace SabreTools.IO.Streams
|
||||
public override int Read(byte[] buffer, int offset, int count)
|
||||
{
|
||||
// Determine which stream we start reading from
|
||||
(int streamIndex, long streamOffset) = DetermineStreamIndex(_position);
|
||||
int streamIndex = DetermineStreamIndex(_position, out long streamOffset);
|
||||
if (streamIndex == -1)
|
||||
return 0;
|
||||
|
||||
@@ -227,12 +233,16 @@ namespace SabreTools.IO.Streams
|
||||
/// <summary>
|
||||
/// Determine the index of the stream that contains a particular offset
|
||||
/// </summary>
|
||||
/// <returns>Index of the stream containing the offset and the real offset in the stream, (-1, -1) on error</returns>
|
||||
private (int index, long realOffset) DetermineStreamIndex(long offset)
|
||||
/// <param name="realOffset">Output parameter representing the real offset in the stream, -1 on error</param>
|
||||
/// <returns>Index of the stream containing the offset, -1 on error</returns>
|
||||
private int DetermineStreamIndex(long offset, out long realOffset)
|
||||
{
|
||||
// If the offset is out of bounds
|
||||
if (offset < 0 || offset >= _length)
|
||||
return (-1, -1);
|
||||
{
|
||||
realOffset = -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Seek through until we hit the correct offset
|
||||
long currentLength = 0;
|
||||
@@ -241,13 +251,14 @@ namespace SabreTools.IO.Streams
|
||||
currentLength += _streams[i].Length;
|
||||
if (currentLength > offset)
|
||||
{
|
||||
long realOffset = offset - (currentLength - _streams[i].Length);
|
||||
return (i, realOffset);
|
||||
realOffset = offset - (currentLength - _streams[i].Length);
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
// Should never happen
|
||||
return (-1, -1);
|
||||
realOffset = -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
Reference in New Issue
Block a user