Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes #51. Chess Symbols (U+1fa00-1fa0f) not returning Column Width bigger than 1. #52

Merged
merged 6 commits into from
Dec 8, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 4 additions & 7 deletions NStack/NStack.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,8 @@ Added ustring.ColumnWidth to return number of columns that a ustring takes in a
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<LangVersion>Latest</LangVersion>
</PropertyGroup>
<ItemGroup>
<Reference Include="System.ValueTuple">
<HintPath>..\packages\System.ValueTuple.4.3.1\lib\netstandard1.0\System.ValueTuple.dll</HintPath>
<Private>False</Private>
</Reference>
</ItemGroup>
<Import Project="..\packages\NuGet.Build.Packaging.0.1.248\build\NuGet.Build.Packaging.targets" Condition="Exists('..\packages\NuGet.Build.Packaging.0.1.248\build\NuGet.Build.Packaging.targets')" />
<Import Project="..\packages\NuGet.Build.Packaging.0.1.248\build\NuGet.Build.Packaging.targets" Condition="Exists('..\packages\NuGet.Build.Packaging.0.1.248\build\NuGet.Build.Packaging.targets')" />
<ItemGroup>
<PackageReference Include="System.ValueTuple" Version="4.5.0" />
</ItemGroup>
</Project>
2 changes: 1 addition & 1 deletion NStack/packages.config
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="NuGet.Build.Packaging" version="0.1.248" targetFramework="net461" developmentDependency="true" />
<package id="System.ValueTuple" version="4.3.1" targetFramework="net461" />
<package id="System.ValueTuple" version="4.5.0" targetFramework="net462" />
</packages>
19 changes: 13 additions & 6 deletions NStack/strings/ustring.cs
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,7 @@ public static ustring Make (IEnumerable<Rune> runes)
return Make (runes.ToList ());
}

/// <summary>
/// Initializes a new instance of the <see cref="T:NStack.ustring"/> class from an array of uints, which contain CodePoints.
/// </summary>
/// <returns>The make.</returns>
Expand Down Expand Up @@ -779,7 +780,7 @@ public bool Equals (ustring other)
/// <summary>
/// Reports whether this string and the provided string, when interpreted as UTF-8 strings, are equal under Unicode case-folding
/// </summary>
/// <returns><c>true</c>, if fold was equalsed, <c>false</c> otherwise.</returns>
/// <returns><c>true</c>, if fold was equaled, <c>false</c> otherwise.</returns>
/// <param name="other">Other.</param>
public bool EqualsFold (ustring other)
{
Expand Down Expand Up @@ -888,7 +889,7 @@ public static ustring Make (byte [] buffer, int start, int count)
/// Returns the byte at the specified position.
/// </summary>
/// <value>The byte encoded at the specified position.</value>
/// <remarks>The index value shoudl be between 0 and Length-1.</remarks>
/// <remarks>The index value should be between 0 and Length-1.</remarks>
public abstract byte this [int index] { get; }

/// <summary>
Expand All @@ -903,7 +904,7 @@ public static ustring Make (byte [] buffer, int start, int count)
/// Returns a slice of the ustring delimited by the [start, end) range. If the range is invalid, the return is the Empty string.
/// </summary>
/// <param name="start">Start index, this value is inclusive. If the value is negative, the value is added to the length, allowing this parameter to count to count from the end of the string.</param>
/// <param name="iend">End index, this value is exclusive. If the value is negative, the value is added to the length, plus one, allowing this parameter to count from the end of the string.</param>
/// <param name="end">End index, this value is exclusive. If the value is negative, the value is added to the length, plus one, allowing this parameter to count from the end of the string.</param>
/// <remarks>
/// <para>
/// Some examples given the string "1234567890":
Expand Down Expand Up @@ -1011,7 +1012,7 @@ public static ustring Make (byte [] buffer, int start, int count)
/// Utf8 encoded string.
/// </summary>
/// <returns>The substring starting at the specified offset.</returns>
/// <param name="start">Starting point, the value is .</param>
/// <param name="byteStart">Starting point, the value is .</param>
public ustring Substring (int byteStart)
{
int len = Length;
Expand Down Expand Up @@ -1166,6 +1167,7 @@ public List<Rune> ToRuneList ()
return result;
}

/// <summary>
/// Converts a ustring into a rune array.
/// </summary>
/// <returns>An array containing the runes for the string up to the specified limit.</returns>
Expand Down Expand Up @@ -1541,7 +1543,7 @@ public int IndexOfAny (params uint [] runes)
}

/// <summary>
/// Reports the zero-based index position of the last occurrence in this instance of one or more characters specified in the uustring.
/// Reports the zero-based index position of the last occurrence in this instance of one or more characters specified in the ustring.
/// </summary>
/// <returns>The index position of the last occurrence in this instance where any character in <paramref name="chars" /> was found; -1 if no character in <paramref name="chars" /> was found.</returns>
/// <param name="chars">The string containing characters to seek.</param>
Expand Down Expand Up @@ -2170,7 +2172,7 @@ public ustring Replace (ustring oldValue, ustring newValue, int maxReplacements
var oldLen = oldValue.Length;
var newLen = newValue.Length;

// Apply replcements to buffer
// Apply replacements to buffer
var result = new byte [Length + maxReplacements * (newValue.Length - oldValue.Length)];
int w = 0, start = 0;
for (int i = 0; i < maxReplacements; i++) {
Expand All @@ -2196,6 +2198,11 @@ public ustring Replace (ustring oldValue, ustring newValue, int maxReplacements
return new ByteBufferUString (result);
}

/// <summary>
/// Represent the null or empty value related to the ustring.
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public static bool IsNullOrEmpty (ustring value)
{
if (value == null)
Expand Down
8 changes: 4 additions & 4 deletions NStack/unicode/Graphic.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ internal enum CharClass : byte {
/// <summary>
/// Determines if a rune is on a set of ranges.
/// </summary>
/// <returns><c>true</c>, if rune in ranges was ised, <c>false</c> otherwise.</returns>
/// <returns><c>true</c>, if rune in ranges was used, <c>false</c> otherwise.</returns>
/// <param name="rune">Rune.</param>
/// <param name="inRanges">In ranges.</param>
public static bool IsRuneInRanges (uint rune, params RangeTable [] inRanges)
Expand All @@ -47,7 +47,7 @@ public static bool IsRuneInRanges (uint rune, params RangeTable [] inRanges)
/// <summary>
/// IsGraphic reports whether the rune is defined as a Graphic by Unicode.
/// </summary>
/// <returns><c>true</c>, if the rune is a lower case lette, <c>false</c> otherwise.</returns>
/// <returns><c>true</c>, if the rune is a lower case letter, <c>false</c> otherwise.</returns>
/// <param name="rune">The rune to test for.</param>
/// <remarks>
/// Such characters include letters, marks, numbers, punctuation, symbols, and
Expand All @@ -63,7 +63,7 @@ public static bool IsGraphic (uint rune)
/// <summary>
/// IsPrint reports whether the rune is defined as printable.
/// </summary>
/// <returns><c>true</c>, if the rune is a lower case lette, <c>false</c> otherwise.</returns>
/// <returns><c>true</c>, if the rune is a lower case letter, <c>false</c> otherwise.</returns>
/// <param name="rune">The rune to test for.</param>
/// <remarks>
/// Such characters include letters, marks, numbers, punctuation, symbols, and the
Expand All @@ -81,7 +81,7 @@ public static bool IsPrint (uint rune)
/// <summary>
/// IsControl reports whether the rune is a control character.
/// </summary>
/// <returns><c>true</c>, if the rune is a lower case lette, <c>false</c> otherwise.</returns>
/// <returns><c>true</c>, if the rune is a lower case letter, <c>false</c> otherwise.</returns>
/// <param name="rune">The rune to test for.</param>
/// <remarks>
/// The C (Other) Unicode category includes more code points such as surrogates; use C.InRange (r) to test for them.
Expand Down
7 changes: 4 additions & 3 deletions NStack/unicode/Rune.ColumnWidth.cs
Original file line number Diff line number Diff line change
Expand Up @@ -98,15 +98,16 @@ public static int ColumnWidth (Rune rune)
return 1 +
((irune >= 0x1100 &&
(irune <= 0x115f || /* Hangul Jamo init. consonants */
irune == 0x2329 || irune == 0x232a ||
irune == 0x2329 || irune == 0x232a || /* Miscellaneous Technical */
(irune >= 0x2e80 && irune <= 0xa4cf &&
irune != 0x303f) || /* CJK ... Yi */
irune != 0x303f) || /* CJK ... Yi */
(irune >= 0xac00 && irune <= 0xd7a3) || /* Hangul Syllables */
(irune >= 0xf900 && irune <= 0xfaff) || /* CJK Compatibility Ideographs */
(irune >= 0xfe10 && irune <= 0xfe19) || /* Vertical forms */
(irune >= 0xfe30 && irune <= 0xfe6f) || /* CJK Compatibility Forms */
(irune >= 0xff00 && irune <= 0xff60) || /* Fullwidth Forms */
(irune >= 0xffe0 && irune <= 0xffe6) ||
(irune >= 0xffe0 && irune <= 0xffe6) || /* Alphabetic Presentation Forms*/
(irune >= 0x1fa00 && irune <= 0x1facf) || /* Chess Symbols*/
(irune >= 0x20000 && irune <= 0x2fffd) ||
(irune >= 0x30000 && irune <= 0x3fffd))) ? 1 : 0);
}
Expand Down
53 changes: 32 additions & 21 deletions NStack/unicode/Rune.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public partial struct Rune {
/// <summary>
/// Represents invalid code points.
/// </summary>
public static Rune ReplacementChar = new Rune (0xfffd);
public static Rune ReplacementChar = new Rune (0xfffd);

/// <summary>
/// Maximum number of bytes required to encode every unicode code point.
Expand All @@ -44,7 +44,7 @@ public partial struct Rune {
/// <param name="rune">Unsigned integer.</param>
/// <remarks>
/// The value does not have to be a valid Unicode code point, this API
/// will create an instanceof Rune regardless of the whether it is in
/// will create an instance of Rune regardless of the whether it is in
/// range or not.
/// </remarks>
public Rune (uint rune)
Expand Down Expand Up @@ -76,21 +76,32 @@ public Rune (char ch)
/// <param name="sgateMax">The low surrogate code points maximum value.</param>
public Rune (uint sgateMin, uint sgateMax)
{
if (sgateMin < surrogateMin || sgateMax > surrogateMax)
var rune = DecodeSurrogatePair (sgateMin, sgateMax);
if (rune > 0)
{
this.value = rune;
}
else
{
throw new ArgumentOutOfRangeException($"Must be between {surrogateMin:x} and {surrogateMax:x} inclusive!");
}
this.value = DecodeSurrogatePair(sgateMin, sgateMax);
}

/// <summary>
/// Gets a value indicating whether this <see cref="T:System.Rune"/> can be encoded as UTF-8 from a surrogate pair.
/// Gets a value indicating whether this <see cref="T:System.Rune"/> can be encoded as UTF-8 from a surrogate pair or zero otherwise.
/// </summary>
/// <param name="sgateMin">The high surrogate code points minimum value.</param>
/// <param name="sgateMax">The low surrogate code points maximum value.</param>
public static uint DecodeSurrogatePair(uint sgateMin, uint sgateMax)
public static uint DecodeSurrogatePair (uint sgateMin, uint sgateMax)
{
return 0x10000 + ((sgateMin - surrogateMin) * 0x0400) + (sgateMax - lowSurrogateMin);
if (sgateMin < surrogateMin || sgateMax > surrogateMax)
{
return 0;
}
else
{
return 0x10000 + ((sgateMin - surrogateMin) * 0x0400) + (sgateMax - lowSurrogateMin);
}
}

/// <summary>
Expand Down Expand Up @@ -229,7 +240,7 @@ public static bool FullRune (byte [] p)
/// </returns>
/// <param name="buffer">Byte buffer containing the utf8 string.</param>
/// <param name="start">Starting offset to look into..</param>
/// <param name="n">Number of bytes valid in the buffer, or -1 to make it the lenght of the buffer.</param>
/// <param name="n">Number of bytes valid in the buffer, or -1 to make it the length of the buffer.</param>
public static (Rune rune, int Size) DecodeRune (byte [] buffer, int start = 0, int n = -1)
{
if (buffer == null)
Expand Down Expand Up @@ -294,7 +305,7 @@ public static (Rune rune, int Size) DecodeRune (byte [] buffer, int start = 0, i
/// it returns (RuneError, 0). Otherwise, if
/// the encoding is invalid, it returns (RuneError, 1). Both are impossible
/// results for correct, non-empty UTF-8.</param>
/// <param name="end">Scan up to that point, if the value is -1, it sets the value to the lenght of the buffer.</param>
/// <param name="end">Scan up to that point, if the value is -1, it sets the value to the length of the buffer.</param>
/// <remarks>
/// An encoding is invalid if it is incorrect UTF-8, encodes a rune that is
/// out of range, or is not the shortest possible UTF-8 encoding for the
Expand Down Expand Up @@ -402,7 +413,7 @@ public static int EncodeRune (Rune rune, byte [] dest, int offset = 0)
/// <summary>
/// Returns the number of runes in a utf8 encoded buffer
/// </summary>
/// <returns>Numnber of runes.</returns>
/// <returns>Number of runes.</returns>
/// <param name="buffer">Byte buffer containing a utf8 string.</param>
/// <param name="offset">Starting offset in the buffer.</param>
/// <param name="count">Number of bytes to process in buffer, or -1 to process until the end of the buffer.</param>
Expand Down Expand Up @@ -476,7 +487,7 @@ public static bool Valid (byte [] buffer)
/// <summary>
/// Use to find the index of the first invalid utf8 byte sequence in a buffer
/// </summary>
/// <returns>The index of the first insvalid byte sequence or -1 if the entire buffer is valid.</returns>
/// <returns>The index of the first invalid byte sequence or -1 if the entire buffer is valid.</returns>
/// <param name="buffer">Buffer containing the utf8 buffer.</param>
public static int InvalidIndex (byte [] buffer)
{
Expand Down Expand Up @@ -526,7 +537,7 @@ public static int InvalidIndex (byte [] buffer)
/// <summary>
/// ValidRune reports whether a rune can be legally encoded as UTF-8.
/// </summary>
/// <returns><c>true</c>, if rune was valided, <c>false</c> otherwise.</returns>
/// <returns><c>true</c>, if rune was validated, <c>false</c> otherwise.</returns>
/// <param name="rune">The rune to test.</param>
public static bool ValidRune (Rune rune)
{
Expand All @@ -547,7 +558,7 @@ public static bool ValidRune (Rune rune)
/// <summary>
/// IsGraphic reports whether the rune is defined as a Graphic by Unicode.
/// </summary>
/// <returns><c>true</c>, if the rune is a lower case lette, <c>false</c> otherwise.</returns>
/// <returns><c>true</c>, if the rune is a lower case letter, <c>false</c> otherwise.</returns>
/// <param name="rune">The rune to test for.</param>
/// <remarks>
/// Such characters include letters, marks, numbers, punctuation, symbols, and
Expand All @@ -558,7 +569,7 @@ public static bool ValidRune (Rune rune)
/// <summary>
/// IsPrint reports whether the rune is defined as printable.
/// </summary>
/// <returns><c>true</c>, if the rune is a lower case lette, <c>false</c> otherwise.</returns>
/// <returns><c>true</c>, if the rune is a lower case letter, <c>false</c> otherwise.</returns>
/// <param name="rune">The rune to test for.</param>
/// <remarks>
/// Such characters include letters, marks, numbers, punctuation, symbols, and the
Expand All @@ -572,7 +583,7 @@ public static bool ValidRune (Rune rune)
/// <summary>
/// IsControl reports whether the rune is a control character.
/// </summary>
/// <returns><c>true</c>, if the rune is a lower case lette, <c>false</c> otherwise.</returns>
/// <returns><c>true</c>, if the rune is a lower case letter, <c>false</c> otherwise.</returns>
/// <param name="rune">The rune to test for.</param>
/// <remarks>
/// The C (Other) Unicode category includes more code points such as surrogates; use C.InRange (r) to test for them.
Expand All @@ -598,7 +609,7 @@ public static bool ValidRune (Rune rune)
public static bool IsLetterOrDigit (Rune rune) => NStack.Unicode.IsLetter (rune.value) || NStack.Unicode.IsDigit (rune.value);

/// <summary>
/// IsLetterOrDigit reports whether the rune is a letter (category L) or a number (caetegory N).
/// IsLetterOrDigit reports whether the rune is a letter (category L) or a number (category N).
/// </summary>
/// <returns><c>true</c>, if the rune is a letter or number, <c>false</c> otherwise.</returns>
/// <param name="rune">The rune to test for.</param>
Expand Down Expand Up @@ -658,21 +669,21 @@ public static bool ValidRune (Rune rune)
/// <summary>
/// Reports whether the rune is an upper case letter.
/// </summary>
/// <returns><c>true</c>, if the rune is an upper case lette, <c>false</c> otherwise.</returns>
/// <returns><c>true</c>, if the rune is an upper case letter, <c>false</c> otherwise.</returns>
/// <param name="rune">The rune to test for.</param>
public static bool IsUpper (Rune rune) => NStack.Unicode.IsUpper (rune.value);

/// <summary>
/// Reports whether the rune is a lower case letter.
/// </summary>
/// <returns><c>true</c>, if the rune is a lower case lette, <c>false</c> otherwise.</returns>
/// <returns><c>true</c>, if the rune is a lower case letter, <c>false</c> otherwise.</returns>
/// <param name="rune">The rune to test for.</param>
public static bool IsLower (Rune rune) => NStack.Unicode.IsLower (rune.value);

/// <summary>
/// Reports whether the rune is a title case letter.
/// </summary>
/// <returns><c>true</c>, if the rune is a lower case lette, <c>false</c> otherwise.</returns>
/// <returns><c>true</c>, if the rune is a lower case letter, <c>false</c> otherwise.</returns>
/// <param name="rune">The rune to test for.</param>
public static bool IsTitle (Rune rune) => NStack.Unicode.IsTitle (rune.value);

Expand All @@ -691,9 +702,9 @@ public enum Case {
Lower = 1,

/// <summary>
/// Titlecase capitalizes the first letter, and keeps the rest in lowercase.
/// Title case capitalizes the first letter, and keeps the rest in lowercase.
/// Sometimes it is not as straight forward as the uppercase, some characters require special handling, like
/// certain ligatures and greek characters.
/// certain ligatures and Greek characters.
/// </summary>
Title = 2
};
Expand Down
8 changes: 4 additions & 4 deletions NStack/unicode/Rune.extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public static bool FullRune (ustring str)
/// </returns>
/// <param name="str">ustring to decode.</param>
/// <param name="start">Starting offset to look into..</param>
/// <param name="n">Number of bytes valid in the buffer, or -1 to make it the lenght of the buffer.</param>
/// <param name="n">Number of bytes valid in the buffer, or -1 to make it the length of the buffer.</param>
public static (Rune rune, int size) DecodeRune (ustring str, int start = 0, int n = -1)
{
if ((object)str == null)
Expand Down Expand Up @@ -106,7 +106,7 @@ public static (Rune rune, int size) DecodeRune (ustring str, int start = 0, int
/// it returns (RuneError, 0). Otherwise, if
/// the encoding is invalid, it returns (RuneError, 1). Both are impossible
/// results for correct, non-empty UTF-8.</param>
/// <param name="end">Scan up to that point, if the value is -1, it sets the value to the lenght of the buffer.</param>
/// <param name="end">Scan up to that point, if the value is -1, it sets the value to the length of the buffer.</param>
/// <remarks>
/// An encoding is invalid if it is incorrect UTF-8, encodes a rune that is
/// out of range, or is not the shortest possible UTF-8 encoding for the
Expand Down Expand Up @@ -153,7 +153,7 @@ public static (Rune rune, int size) DecodeLastRune (ustring str, int end = -1)
/// <summary>
/// Returns the number of runes in a ustring.
/// </summary>
/// <returns>Numnber of runes.</returns>
/// <returns>Number of runes.</returns>
/// <param name="str">utf8 string.</param>
public static int RuneCount (ustring str)
{
Expand Down Expand Up @@ -216,7 +216,7 @@ public static int RuneCount (ustring str)
/// <summary>
/// Use to find the index of the first invalid utf8 byte sequence in a buffer
/// </summary>
/// <returns>The index of the first insvalid byte sequence or -1 if the entire buffer is valid.</returns>
/// <returns>The index of the first invalid byte sequence or -1 if the entire buffer is valid.</returns>
/// <param name="str">String containing the utf8 buffer.</param>
public static int InvalidIndex (ustring str)
{
Expand Down
Loading