using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using NTERA.EmuEra.Game.EraEmu.GameData;
namespace NTERA.EmuEra.Game.EraEmu.Sub
{
internal sealed class EraStreamReader : IDisposable
{
public EraStreamReader(bool useRename)
{
this.useRename = useRename;
}
string filepath;
string filename;
bool useRename;
int curNo;
int nextNo;
StreamReader reader;
FileStream stream;
public bool Open(string path)
{
return Open(path, Path.GetFileName(path));
}
public bool Open(string path, string name)
{
//そんなお行儀の悪いことはしていない
//if (disposed)
// throw new ExeEE("破棄したオブジェクトを再利用しようとした");
//if ((reader != null) || (stream != null) || (filepath != null))
// throw new ExeEE("使用中のオブジェクトを別用途に再利用しようとした");
filepath = path;
filename = name;
nextNo = 0;
curNo = 0;
try
{
stream = new FileStream(filepath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
reader = new StreamReader(stream, Config.Config.Encode);
}
catch
{
Dispose();
return false;
}
return true;
}
public string ReadLine()
{
nextNo++;
curNo = nextNo;
return reader.ReadLine();
}
///
/// 次の有効な行を読む。LexicalAnalyzer経由でConfigを参照するのでConfig完成までつかわないこと。
///
public StringStream ReadEnabledLine()
{
string line = null;
StringStream st = null;
curNo = nextNo;
while (true)
{
line = reader.ReadLine();
curNo++;
nextNo++;
if (line == null)
return null;
if (line.Length == 0)
continue;
if (useRename && (line.IndexOf("[[") >= 0) && (line.IndexOf("]]") >= 0))
{
foreach (KeyValuePair pair in ParserMediator.RenameDic)
line = line.Replace(pair.Key, pair.Value);
}
st = new StringStream(line);
LexicalAnalyzer.SkipWhiteSpace(st);
if (st.EOS)
continue;
if (st.Current == '}')
throw new CodeEE("予期しない行連結終端記号'}'が見つかりました");
if (st.Current == '{')
{
if (line.Trim() != "{")
throw new CodeEE("行連結始端記号'{'の行に'{'以外の文字を含めることはできません");
break;
}
return st;
}
//curNoはこの後加算しない(始端記号の行を行番号とする)
StringBuilder b = new StringBuilder();
while (true)
{
line = reader.ReadLine();
nextNo++;
if (line == null)
{
throw new CodeEE("行連結始端記号'{'が使われましたが終端記号'}'が見つかりません");
}
if (useRename && (line.IndexOf("[[") >= 0) && (line.IndexOf("]]") >= 0))
{
foreach (KeyValuePair pair in ParserMediator.RenameDic)
line = line.Replace(pair.Key, pair.Value);
}
string test = line.TrimStart();
if (test.Length > 0)
{
if (test[0] == '}')
{
if (test.Trim() != "}")
throw new CodeEE("行連結終端記号'}'の行に'}'以外の文字を含めることはできません");
break;
}
if (test[0] == '{')
throw new CodeEE("予期しない行連結始端記号'{'が見つかりました");
}
b.Append(line);
b.Append(" ");
}
st = new StringStream(b.ToString());
LexicalAnalyzer.SkipWhiteSpace(st);
return st;
}
///
/// 直前に読んだ行の行番号
///
public int LineNo => curNo;
public string Filename => filename;
//public string Filepath
//{
// get
// {
// return filepath;
// }
//}
public void Close() { Dispose(); }
bool disposed;
#region IDisposable メンバ
public void Dispose()
{
if (disposed)
return;
if (reader != null)
reader.Close();
else if (stream != null)
stream.Close();
filepath = null;
filename = null;
reader = null;
stream = null;
disposed = true;
}
#endregion
}
}