using System;
using System.IO;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Numerics;
namespace Anonymus
{
public struct BracketHelper
{
public bool InZ;
public int ZDepth;
public bool Ok;
public BracketHelper(bool InZ)
{
this.InZ = InZ;
ZDepth = 0;
Ok = true;
}
public bool OnChar(char Char, bool nZJ = false)
{
if (InZ)
{
if (Char == '\"')
{
Ok = !Ok;
return false;
}
if (Ok)
{
var LastZ = GetZNum(Char);
var OldDepth = ZDepth;
ZDepth += LastZ;
if (nZJ) return false;
else if (OldDepth == 0)
return true;
}
else
{
return false;
}
}
return ZDepth == 0;
}
public static int ZPos(string String, int Pos = -1, bool RightToLeft = false)
{
if (string.IsNullOrEmpty(String)) return -1;
if (Pos == -1) Pos = RightToLeft ? String.Length - 1 : 0;
var ZNum = new int[] { 0, 0, 0, 0 }; // ( [ { <
var SType = -1;
var InStr = false;
for (var i = Pos; true; )
{
var c = String[i];
var tp = -1;
var zt = false;
if (c == '\"') InStr = !InStr;
else if (!InStr)
{
if (c == '(') tp = 0;
else if (c == ')') { tp = 0; zt = true; }
else if (c == '[') tp = 1;
else if (c == ']') { tp = 1; zt = true; }
else if (c == '{') tp = 2;
else if (c == '}') { tp = 2; zt = true; }
else if (c == '<') tp = 3; else if (c == '>') { tp = 3; zt = true; }
if (tp != -1)
{
if (SType == -1) SType = tp;
if (zt) ZNum[tp]--; else ZNum[tp]++;
if (SType == tp && ZNum[tp] == 0) return i;
}
else
{
if (Pos == i) return Pos;
}
}
if (RightToLeft) { i--; if (i < 0) break; }
else { i++; if (i >= String.Length) break; }
}
return -1;
}
public static int GetZNum(char c)
{
if (c == '(' || c == '[' || c == '{') return 1;
if (c == ')' || c == ']' || c == '}') return -1;
return 0;
}
public static int FZNum(string Str)
{
int slen = Str.Length, lnum = 0, lpos = 0,
rnum = 0, rpos = 0;
for (int i = 0; i < slen; i++)
{
var c = Str[i];
if (c == '(') lnum++;
else if (!char.IsWhiteSpace(c))
{ lpos = i; break; }
}
for (int i = slen - 1; i >= 0; i--)
{
var c = Str[i];
if (c == ')') rnum++;
else if (!char.IsWhiteSpace(c))
{ rpos = i; break; }
}
int ret = lnum < rnum ? lnum : rnum;
for (int i = lpos; i <= rpos; i++)
{
int r = GetZNum(Str[i]);
if (r != 0)// && ZPos(str, i, r < 0) != -1)
{
lnum += r;
if (lnum < ret) ret = lnum;
}
}
return ret;
}
static int LZPos(string str, int znum)
{
int b = 0;
for (int i = 0; i < str.Length; i++)
{
char c = str[i];
if (c == '(')
{
b++;
if (b == znum) return i;
}
}
return -1;
}
static int RZPos(string str, int znum)
{
int b = 0;
for (int i = str.Length - 1; i >= 0; i--)
{
char c = str[i];
if (c == ')')
{
b++;
if (b == znum) return i;
}
}
return -1;
}
public static string TrimFZ(string str)
{
var znum = FZNum(str);
if (znum <= 0) return str;
var l = LZPos(str, znum);
var r = RZPos(str, znum);
return str.Substring(l + 1, r - l - 1).Trim();
}
public static PString TrimFZ(PString str)
{
var znum = FZNum(str.String);
if (znum <= 0) return str;
var l = LZPos(str.String, znum);
var r = RZPos(str.String, znum);
return str.TrimmedSubstring(l + 1, r - l - 1);
}
public static string TrimOneBracket(string String)
{
if (String.Length > 0 && String[0] == '(' && BracketHelper.ZPos(String) == String.Length - 1)
return String.Substring(1, String.Length - 2).Trim();
return String;
}
public static PString TrimOneBracket(PString String)
{
if (String.StrLen > 0 && String[0] == '(' && BracketHelper.ZPos(String.String) == String.StrLen - 1)
return String.TrimmedSubstring(1, String.StrLen - 2);
return String;
}
}
[Flags]
public enum LetterCase
{
Lower,
Upper,
Both = Lower | Upper,
}
public struct FindRes
{
public int Index;
public int Position;
public string String;
public FindRes(int Index, int Position, string String)
{
this.Index = Index;
this.Position = Position;
this.String = String;
}
}
public static class StringHelper
{
public static bool IsIdChar(char c)
{
return char.IsLetterOrDigit(c) || c == '_';
}
public static string CutEndStr(this string String, LetterCase Case = LetterCase.Both)
{
var Count = StrEndLetterCount(String, Case);
if (Count == 0) return String;
else return String.Substring(0, String.Length - Count);
}
public static string EndStr(this string String, LetterCase Case = LetterCase.Both)
{
var Count = StrEndLetterCount(String, Case);
if (Count == 0) return "";
return String.Substring(String.Length - Count);
}
public static int StrEndLetterCount(this string String, LetterCase Case = LetterCase.Both)
{
var Count = 0;
for (var i = String.Length - 1; i >= 0; i--)
{
var C = String[i];
if (Char.IsLetter(C))
{
if ((Char.IsUpper(C) && Case.HasFlag(LetterCase.Upper)) ||
(Char.IsLower(C) && Case.HasFlag(LetterCase.Lower)))
{
Count++;
continue;
}
}
break;
}
return Count;
}
public static bool SubstringEqualsS(this string Self, int Index, string CmpWith,
bool NotIdChar = false, Func<char, bool> Func = null)
{
if (Index < 0 || CmpWith.Length + Index > Self.Length)
return false;
if (Func == null) Func = IsIdChar;
for (var m = 0; m < CmpWith.Length; m++)
{
if (NotIdChar)
{
if (m == 0 && Index > 0)
{
var SelfRes = Func(Self[Index - 1]);
var CmpWithRes = Func(CmpWith[m]);
if (SelfRes && CmpWithRes) return false;
}
else if (m == CmpWith.Length - 1 && m + Index + 1 < Self.Length)
{
var SelfRes = Func(Self[m + Index + 1]);
var CmpWithRes = Func(CmpWith[CmpWith.Length - 1]);
if (SelfRes && CmpWithRes) return false;
}
}
if (Self[m + Index] != CmpWith[m])
return false;
}
return true;
}
public static bool StartsWith(this string Self, string CmpWith,
bool NotIdChar = false, Func<char, bool> Func = null)
{
return SubstringEqualsS(Self, 0, CmpWith, NotIdChar, Func);
}
public static bool EndsWith(this string Self, string CmpWith,
bool NotIdChar = false, Func<char, bool> Func = null)
{
return SubstringEqualsS(Self, Self.Length - CmpWith.Length, CmpWith, NotIdChar, Func);
}
public static FindRes StartsWith(this string Self, IEnumerable<string> CmpWith, IEnumerable<string> Skip = null,
bool NotIdChar = false, Func<char, bool> Func = null)
{
return SubstringEquals(Self, 0, CmpWith, Skip, NotIdChar, Func);
}
public static FindRes EndsWith(this string Self, IEnumerable<string> CmpWith, IEnumerable<string> Skip = null,
bool NotIdChar = false, Func<char, bool> Func = null)
{
return SubstringEquals(Self, Self.Length - 1, CmpWith, Skip, NotIdChar, Func, true);
}
public static int SubstringEquals(this string Self, int Pos, string CmpWith,
IEnumerable<string> Skip = null, bool NotIdChar = false, Func<char, bool> Func = null, bool Back = false)
{
var RPos = Pos;
if (Back) RPos -= CmpWith.Length - 1;
if (SubstringEqualsS(Self, RPos, CmpWith, NotIdChar, Func))
{
if (Skip != null)
{
foreach (var SkipStr in Skip)
{
for (var SkipPos = -SkipStr.Length + 1; SkipPos < CmpWith.Length; SkipPos++)
if (SubstringEquals(Self, RPos + SkipPos, Skip).Position != -1) return -1;
}
}
return RPos;
}
return -1;
}
public static FindRes SubstringEquals(this string Self, int Pos, IEnumerable<string> CmpWith,
IEnumerable<string> Skip = null, bool NotIdChar = false, Func<char, bool> Func = null, bool Back = false)
{
var CmpWithIndex = 0;
foreach (var e in CmpWith)
{
var Res = SubstringEquals(Self, Pos, e, Skip, NotIdChar, Func, Back);
if (Res != -1) return new FindRes(CmpWithIndex, Res, e);
CmpWithIndex++;
}
return new FindRes(-1, -1, null);
}
public static IEnumerable<FindRes> EnumFind(this string Self, IEnumerable<string> CmpWith,
IEnumerable<string> Skip = null, bool InZ = false, bool NotIdChar = false,
Func<char, bool> Func = null, bool Back = false, int Start = -1, int End = -1)
{
var ZHlp = new BracketHelper(InZ);
if (Back)
{
if (Start == -1) Start = Self.Length - 1;
if (End == -1) End = 0;
for (var i = Start; i >= End; i--)
if (ZHlp.OnChar(Self[i]))
{
var Res = SubstringEquals(Self, i, CmpWith, Skip, NotIdChar, Func, true);
if (Res.Position != -1)
{
yield return Res;
i = Res.Position;
}
}
}
else
{
if (Start == -1) Start = 0;
if (End == -1) End = Self.Length;
for (var i = Start; i < End; i++)
if (ZHlp.OnChar(Self[i]))
{
var Res = SubstringEquals(Self, i, CmpWith, Skip, NotIdChar, Func);
if (Res.Position != -1)
{
yield return Res;
i = Res.Position;
}
}
}
}
public static FindRes Find(this string Self, IEnumerable<string> CmpWith,
IEnumerable<string> Skip = null, bool InZ = false, bool NotIdChar = false,
Func<char, bool> Func = null, bool Back = false, int Start = -1, int End = -1)
{
foreach (var e in EnumFind(Self, CmpWith, Skip, InZ, NotIdChar, Func, Back, Start, End))
return e;
return new FindRes(-1, -1, null);
}
public static int Find(this string Self, char CmpWith, bool InZ = false,
bool Back = false, int Start = -1, int End = -1)
{
var ZHlp = new BracketHelper(InZ);
if (Back)
{
if (Start == -1) Start = Self.Length - 1;
if (End == -1) End = 0;
for (var i = Start; i >= End; i--)
if (ZHlp.OnChar(Self[i]) && Self[i] == CmpWith)
return i;
}
else
{
if (Start == -1) Start = 0;
if (End == -1) End = Self.Length;
for (var i = Start; i < End; i++)
if (ZHlp.OnChar(Self[i]) && Self[i] == CmpWith)
return i;
}
return -1;
}
public static bool IsNum(this string String)
{
if (String.Length == 0)
return false;
foreach (var Chr in String)
if (!Char.IsLetterOrDigit(Chr) || Char.IsLower(Chr))
return false;
return true;
}
public static bool ConvertToDec(this string String, int Radix, LetterCase Case, out BigInteger Ret)
{
Ret = 0UL;
for (var i = 0; i < String.Length; i++)
{
var Chr = String[i];
var Num = -1;
if (Chr >= '0' && Chr <= '9')
Num = Chr - '0';
else if (Chr >= 'a' && Chr <= 'z' && Case.HasFlag(LetterCase.Lower))
Num = Chr - 'a' + 10;
else if (Chr >= 'A' && Chr <= 'Z' && Case.HasFlag(LetterCase.Upper))
Num = Chr - 'A' + 10;
if (Num == -1) return false;
else Ret = Ret * (ulong)Radix + (ulong)Num;
}
return true;
}
public static int LWhiteSpaceCount(this string s, int Start = 0)
{
int l = s.Length;
for (int i = Start; i < l; i++)
{
var c = s[i];
if (c != ' ' && c != '\t' && !char.IsWhiteSpace(c))
return i - Start;
}
return l - Start;
}
public static int RWhiteSpaceCount(this string s, int Start = -1)
{
int l = s.Length;
if (Start == -1) Start = l - 1;
for (int i = Start; i >= 0; i--)
{
var c = s[i];
if (c != ' ' && c != '\t' && !char.IsWhiteSpace(c))
return Start - i;
}
return l == 0 ? 0 : l - Start;
}
}
unsafe public static class Helper
{
public static string[] Str_SizeMask = new string[] { "", "FF", "FFFF", "FFFFFF",
"FFFFFFFF", "FFFFFFFFFF", "FFFFFFFFFFFF", "FFFFFFFFFFFFFF", "FFFFFFFFFFFFFFFF" };
public static ulong[] Ulong_SizeMask = new ulong[] { 0x0, 0xFF, 0xFFFF, 0xFFFFFF,
0xFFFFFFFF, 0xFFFFFFFFFF, 0xFFFFFFFFFFFF, 0xFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF };
public static void RemoveSameObject<T>(List<T> List) where T : class
{
for (var i = 0; i < List.Count; i++)
for (var j = i + 1; j < List.Count; j++)
if (List[j] == List[i])
{
List.RemoveAt(j);
j--;
}
}
public static int AdjustVarPos(int Pos, int Align)
{
var m = Pos % Align;
if (m > 0) return Pos + (Align - m);
else return Pos;
}
public static int AdjustVarPos(int Pos, Type Type)
{
var Align = Type.Arch.GetAlign(Type);
return AdjustVarPos(Pos, Align);
}
public static int Pow2Sqrt(ulong a)
{
var Val = 1UL;
var Ret = 0;
while (a > Val)
{
Val *= 2;
Ret++;
}
return Ret;
}
public static ulong Pow2(ulong a)
{
var Ret = 1UL;
while (a > Ret)
Ret *= 2;
return Ret;
}
public static uint Pow2(uint a)
{
var Ret = 1U;
while (a > Ret)
Ret *= 2;
return Ret;
}
public static BigInteger Pow(BigInteger a, BigInteger b)
{
BigInteger Ret = 1;
for (ulong i = 0; i < b; i++)
Ret *= a;
return Ret;
}
public static ulong Pow(ulong a, ulong b)
{
ulong Ret = 1;
for (ulong i = 0; i < b; i++)
Ret *= a;
return Ret;
}
public static long Pow(long a, long b)
{
long Ret = 1;
for (long i = 0; i < b; i++)
Ret *= a;
return Ret;
}
public static int Pow(int a, int b)
{
int Ret = 1;
for (int i = 0; i < b; i++)
Ret *= a;
return Ret;
}
public static T[] Slice<T>(this T[] Arr, int Index, int Count)
{
T[] Ret = new T[Count];
for (int i = 0; i < Count; i++)
Ret[i] = Arr[i + Index];
return Ret;
}
public static string[] SplitToLines(string Source)
{
return Source.Split(new string[] { "\n" }, StringSplitOptions.None);
}
public static PString[] StrToPStrArr(string FileName, string[] Lines)
{
var PLines = new PString[Lines.Length];
for (int i = 0; i < Lines.Length; i++)
PLines[i] = new PString(FileName, i, 0, Lines[i]);
return PLines;
}
public static PString[] StrToPStrArr(string FileName)
{
return StrToPStrArr(FileName, File.ReadAllLines(FileName));
}
public static void SaveString(string FileName, string str)
{
if (File.Exists(FileName))
File.Delete(FileName);
var sw = new StreamWriter(FileName);
sw.Write(str);
sw.Dispose();
}
public static void SaveLines(string FileName, string[] str)
{
if (File.Exists(FileName))
File.Delete(FileName);
var sw = new StreamWriter(FileName);
foreach (var e in str)
sw.WriteLine(e);
sw.Dispose();
}
public static void SaveData(string FileName, byte[] data)
{
if (File.Exists(FileName))
File.Delete(FileName);
var fs = new FileStream(FileName, FileMode.CreateNew, FileAccess.Write, FileShare.Read);
var bw = new BinaryWriter(fs);
bw.Write(data);
bw.Dispose();
fs.Dispose();
}
public static bool IsValidIdentifierName(string Name)
{
if (string.IsNullOrEmpty(Name)) return false;
if (char.IsDigit(Name[0])) return false;
foreach (var c in Name)
if (!StringHelper.IsIdChar(c))
return false;
return true;
}
public unsafe static double ULToDbl(ulong T)
{
return ((double*)(&T))[0];
}
public unsafe static ulong DblToUL(double T)
{
return ((ulong*)(&T))[0];
}
public unsafe static float ULToFlt(ulong T)
{
return ((float*)(&T))[0];
}
public unsafe static ulong FltToUL(float T)
{
ulong Ret = 0;
*(float*)&Ret = T;
return Ret;
}
public static IEnumerable<T> ObjToEnumable<T>(T Obj)
{
yield return Obj;
}
public static ulong ConvertDoubleToFloat(ulong Double)
{
var dbl = Helper.ULToDbl(Double);
return Helper.FltToUL((float)dbl);
}
}
}