using System;
using System.IO;
namespace NTERA.EmuEra.Game.EraEmu.Sub
{
///
/// 文字列を1文字ずつ評価するためのクラス
///
internal sealed class StringStream
{
public StringStream(string s)
{
source = s ?? "";
CurrentPosition = 0;
}
string source;
public const char EndOfString = '\0';
public string RowString => source;
public int CurrentPosition { get; set; }
public char Current
{
get
{
if (CurrentPosition >= source.Length)
return EndOfString;
return source[CurrentPosition];
}
}
public void AppendString(string str)
{
if (CurrentPosition > source.Length)
CurrentPosition = source.Length;
source += " " + str;
}
///
/// 文字列終端に達した
///
public bool EOS => CurrentPosition >= source.Length;
///変数の区切りである"[["と"]]"の先読みなどに使用
public char Next
{
get
{
if (CurrentPosition + 1 >= source.Length)
return EndOfString;
return source[CurrentPosition + 1];
}
}
public string Substring()
{
if (CurrentPosition >= source.Length)
return "";
if (CurrentPosition == 0)
return source;
return source.Substring(CurrentPosition);
}
public string Substring(int start, int length)
{
if (start >= source.Length || length == 0)
return "";
if (start + length > source.Length)
length = source.Length - start;
return source.Substring(start, length);
}
internal void Replace(int start, int count, string src)
{
//引数に正しい数字が送られてくること前提
source = (source.Remove(start, count)).Insert(start, src);
CurrentPosition = start;
}
public void ShiftNext()
{
CurrentPosition++;
}
public void Jump(int skip)
{
CurrentPosition += skip;
}
///
/// 検索文字列の相対位置を返す。見つからない場合、負の値。
///
///
public int Find(string str)
{
return source.IndexOf(str, CurrentPosition) - CurrentPosition;
}
///
/// 検索文字列の相対位置を返す。見つからない場合、負の値。
///
public int Find(char c)
{
return source.IndexOf(c, CurrentPosition) - CurrentPosition;
}
public override string ToString()
{
if (source == null)
return "";
return source;
}
public bool CurrentEqualTo(string rother)
{
if (CurrentPosition + rother.Length > source.Length)
return false;
for (int i = 0; i < rother.Length;i++)
{
if (source[CurrentPosition + i] != rother[i])
return false;
}
return true;
}
public bool TripleSymbol()
{
if (CurrentPosition + 3 > source.Length)
return false;
return (source[CurrentPosition] == source[CurrentPosition + 1]) && (source[CurrentPosition] == source[CurrentPosition + 2]);
}
public bool CurrentEqualTo(string rother, StringComparison comp)
{
if (CurrentPosition + rother.Length > source.Length)
return false;
string sub = source.Substring(CurrentPosition, rother.Length);
return sub.Equals(rother, comp);
}
public void Seek(int offset, SeekOrigin origin)
{
if (origin == SeekOrigin.Begin)
CurrentPosition = offset;
else if (origin == SeekOrigin.Current)
CurrentPosition = CurrentPosition + offset;
else if (origin == SeekOrigin.End)
CurrentPosition = source.Length + offset;
if (CurrentPosition < 0)
CurrentPosition = 0;
}
}
}