103 lines
3.6 KiB
C#
103 lines
3.6 KiB
C#
|
using System;
|
||
|
using System.IO;
|
||
|
using System.Text;
|
||
|
|
||
|
namespace Poiyomi.ModularShaderSystem
|
||
|
{
|
||
|
public static class ShaderStringBuilderExtensions
|
||
|
{
|
||
|
public static StringBuilder Prepend(this StringBuilder builder, string value) => builder.Insert(0, value);
|
||
|
|
||
|
public static StringBuilder PrependLine(this StringBuilder builder, string value) => builder.Prepend(Environment.NewLine).Prepend(value);
|
||
|
|
||
|
public static StringBuilder AppendLineTabbed(this StringBuilder builder, int tabLevel, string value)
|
||
|
{
|
||
|
return builder.Append(Tabs(tabLevel)).AppendLine(value);
|
||
|
}
|
||
|
|
||
|
public static StringBuilder PrependLineTabbed(this StringBuilder builder, int tabLevel, string value)
|
||
|
{
|
||
|
return builder.PrependLine(value).Prepend(Tabs(tabLevel));
|
||
|
}
|
||
|
|
||
|
public static StringBuilder AppendTabbed(this StringBuilder builder, int tabLevel, string value)
|
||
|
{
|
||
|
return builder.Append(Tabs(tabLevel)).Append(value);
|
||
|
}
|
||
|
|
||
|
public static StringBuilder PrependTabbed(this StringBuilder builder, int tabLevel, string value)
|
||
|
{
|
||
|
return builder.Prepend(value).Prepend(Tabs(tabLevel));
|
||
|
}
|
||
|
|
||
|
public static StringBuilder AppendMultilineTabbed(this StringBuilder builder, int tabLevel, string value)
|
||
|
{
|
||
|
var sr = new StringReader(value);
|
||
|
string line;
|
||
|
while ((line = sr.ReadLine()) != null)
|
||
|
builder.AppendLineTabbed(tabLevel, line);
|
||
|
return builder;
|
||
|
}
|
||
|
|
||
|
static string Tabs(int n)
|
||
|
{
|
||
|
if (n < 0) n = 0;
|
||
|
return new string('\t', n);
|
||
|
}
|
||
|
|
||
|
public static bool Contains(this StringBuilder haystack, string needle)
|
||
|
{
|
||
|
return haystack.IndexOf(needle) != -1;
|
||
|
}
|
||
|
|
||
|
public static int IndexOf(this StringBuilder haystack, string needle)
|
||
|
{
|
||
|
if (haystack == null || needle == null)
|
||
|
throw new ArgumentNullException();
|
||
|
if (needle.Length == 0)
|
||
|
return 0;//empty strings are everywhere!
|
||
|
if (needle.Length == 1)//can't beat just spinning through for it
|
||
|
{
|
||
|
char c = needle[0];
|
||
|
for (int idx = 0; idx != haystack.Length; ++idx)
|
||
|
if (haystack[idx] == c)
|
||
|
return idx;
|
||
|
return -1;
|
||
|
}
|
||
|
int m = 0;
|
||
|
int i = 0;
|
||
|
int[] T = KmpTable(needle);
|
||
|
while (m + i < haystack.Length)
|
||
|
{
|
||
|
if (needle[i] == haystack[m + i])
|
||
|
{
|
||
|
if (i == needle.Length - 1)
|
||
|
return m == needle.Length ? -1 : m;//match -1 = failure to find conventional in .NET
|
||
|
++i;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m = m + i - T[i];
|
||
|
i = T[i] > -1 ? T[i] : 0;
|
||
|
}
|
||
|
}
|
||
|
return -1;
|
||
|
}
|
||
|
private static int[] KmpTable(string sought)
|
||
|
{
|
||
|
int[] table = new int[sought.Length];
|
||
|
int pos = 2;
|
||
|
int cnd = 0;
|
||
|
table[0] = -1;
|
||
|
table[1] = 0;
|
||
|
while (pos < table.Length)
|
||
|
if (sought[pos - 1] == sought[cnd])
|
||
|
table[pos++] = ++cnd;
|
||
|
else if (cnd > 0)
|
||
|
cnd = table[cnd];
|
||
|
else
|
||
|
table[pos++] = 0;
|
||
|
return table;
|
||
|
}
|
||
|
}
|
||
|
}
|