using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Anonymus
{
public static class PStringExtensions
{
public static IEnumerable<PString> TrimElements(this IEnumerable<PString> self)
{
foreach (var e in self)
yield return e.Trim();
}
}
public class SplitRes
{
public bool IsSeparator;
public PString String;
public SplitRes(PString String, bool IsSeparator)
{
this.String = String;
this.IsSeparator = IsSeparator;
}
}
public class PString
{
public string File = null;
public int Line = 0;
public int Char = 0;
public string String = null;
public int StrLen
{
get
{
return String != null ? String.Length : 0;
}
}
public int _Length = -1;
public int Length
{
get
{
if (_Length == -1) return StrLen;
else return _Length;
}
}
public char this[int index]
{
get
{
return String[index];
}
}
public PString Copy()
{
return new PString(File, Line, Char, String);
}
public static explicit operator string(PString str)
{
return str.String;
}
public override string ToString()
{
return String;
}
public PString(string String)
{
this.String = String;
}
public PString(int Char, string String)
{
this.Char = Char;
this.String = String;
}
public PString(int Line, int Char, string String)
{
this.Line = Line;
this.Char = Char;
this.String = String;
}
public PString(string File, int Line, int Char, string String)
{
this.File = File;
this.Line = Line;
this.Char = Char;
this.String = String;
}
public PString(string File, int Line, int Char, int Len, string String)
{
this.Line = Line;
this.Char = Char;
this.String = String;
this._Length = Len;
}
void UpdatePos(int Index)
{
var Pos = IndexOf('\n');
var Last = 0;
while (Pos != -1 && Pos < Index)
{
Line++;
Char = -1;
Last = Pos;
Pos = IndexOf('\n', Start: Last + 1);
}
Char += Index - Last;
}
public PString Substring(int Index, int Length)
{
if (Index + Length > StrLen) return null;
var Ret = Copy();
Ret.UpdatePos(Index);
Ret.String = String.Substring(Index, Length);
return Ret;
}
public PString Substring(int Index)
{
if (Index > StrLen) return null;
var Ret = Copy();
Ret.UpdatePos(Index);
Ret.String = String.Substring(Index);
return Ret;
}
public PString TrimmedSubstring(int Index, int Length)
{
var i = String.LWhiteSpaceCount(Index);
if (i >= Length) return Substring(Index, 0);
var j = String.RWhiteSpaceCount(Index + Length - 1);
return Substring(Index + i, Length - i - j);
}
public PString TrimmedSubstring(int Index)
{
var i = String.LWhiteSpaceCount(Index);
if (i >= StrLen - Index) return Substring(Index, 0);
var j = String.RWhiteSpaceCount();
return Substring(Index + i, StrLen - i - j - Index);
}
public PString Trim()
{
return TrimmedSubstring(0);
}
public void TrimThis()
{
var i = String.LWhiteSpaceCount();
if (i == String.Length) { String = ""; return; }
var j = String.RWhiteSpaceCount();
if (i != 0 || j != 0)
{
UpdatePos(i);
String = String.Substring(i, String.Length - i - j);
}
}
public IEnumerable<SplitRes> EnumSplit(String Separator, StringSplitOptions SplitOptions = StringSplitOptions.None,
bool InZ = false, bool Trim = false)
{
var SeparatorLen = Separator.Length;
var Until = StrLen - SeparatorLen + 1;
if (Until > StrLen) Until = StrLen;
var ZHlp = new BracketHelper(InZ);
var BeginOfLast = 0;
var SubStr = (PString)null;
for (var i = 0; i < Until; i++)
if (ZHlp.OnChar(this[i]) && String.SubstringEqualsS(i, Separator))
{
if (SplitOptions != StringSplitOptions.RemoveEmptyEntries || i > BeginOfLast)
{
SubStr = Trim ? TrimmedSubstring(BeginOfLast, i - BeginOfLast) :
Substring(BeginOfLast, i - BeginOfLast);
if (SubStr.StrLen > 0) yield return new SplitRes(SubStr, false);
}
yield return new SplitRes(Substring(i, SeparatorLen), true);
BeginOfLast = i + SeparatorLen;
i += SeparatorLen - 1;
}
SubStr = Trim ? TrimmedSubstring(BeginOfLast) : Substring(BeginOfLast);
if (SubStr.StrLen > 0) yield return new SplitRes(SubStr, false);
}
public List<PString> Split(String Separator, StringSplitOptions SplitOptions = StringSplitOptions.None, bool InZ = false)
{
var Ret = new List<PString>();
foreach (var e in EnumSplit(Separator, SplitOptions, InZ, false))
if (!e.IsSeparator) Ret.Add(e.String);
return Ret;
}
public int IndexOf(char Value, int Start = 0, bool InZ = false, bool Back = false)
{
return String.Find(Value, Start: Start, InZ: InZ, Back: Back);
}
public int WordEnd(int Start = -1, bool WordStart = false,
bool InZ = false, bool Back = false, Func<char, bool> Func = null)
{
if (Func == null) Func = StringHelper.IsIdChar;
if (Start == -1) Start = Back ? StrLen - 1 : 0;
if (StrLen == 0) return -1;
var Exit = false;
var ZHlp = new BracketHelper(InZ);
var Prev = -1;
for (var i = Start; true; )
{
var Chr = this[i];
var Res = ZHlp.OnChar(Chr) && Func(Chr);
if (Prev != -1)
{
if (WordStart)
{
if (!Res) Exit = true;
else if (Exit) return Prev;
}
else
{
if (!Res) return Prev;
}
}
Prev = i;
if (Back) { i--; if (i == -1) return Prev; }
else { i++; if (i >= StrLen) return Prev; }
}
}
public PString Word(int Start = -1, bool WordStart = false, bool InZ = false,
bool Back = false, Func<char, bool> Func = null, bool ModThis = true)
{
var p = WordEnd(Start, WordStart, InZ, Back, Func);
if (p == -1) return Copy();
var Ret = (PString)null;
if (!Back) Ret = TrimmedSubstring(0, p + 1);
else Ret = TrimmedSubstring(p);
if (ModThis)
{
var Line = (PString)null;
if (!Back) Line = TrimmedSubstring(p + 1);
else Line = TrimmedSubstring(0, p);
this.String = Line.String;
this.Line = Line.Line;
this.Char = Line.Char;
}
return Ret;
}
}
}