2 * Copyright (C) 2013 FooProject
\r
3 * * This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by
\r
4 * the Free Software Foundation; either version 3 of the License, or (at your option) any later version.
\r
6 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
7 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
\r
9 You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.
\r
12 //#define TEST_ASYNC
\r
17 using System.Threading;
\r
18 using System.Threading.Tasks;
\r
20 namespace FooEditEngine
\r
25 public static class DocumentExtend
\r
27 static Progress<ProgressEventArgs> _Progress = new Progress<ProgressEventArgs>();
\r
31 public static event EventHandler<ProgressEventArgs> Progress
\r
35 _Progress.ProgressChanged += value;
\r
39 _Progress.ProgressChanged -= value;
\r
45 /// ファイルからドキュメントを構築します
\r
47 /// <param name="doc">Documentオブジェクト</param>
\r
48 /// <param name="filepath">読み取り先のファイル</param>
\r
49 /// <param name="enc">エンコーディング</param>
\r
51 /// 非同期操作中はこのメソッドを実行することはできません。
\r
53 public static void Load(this Document doc, string filepath, Encoding enc)
\r
55 if (doc.State != AsyncState.None)
\r
56 throw new InvalidOperationException();
\r
57 using (StreamReader sr = new StreamReader(filepath, enc))
\r
64 /// ファイルからドキュメントを非同期的に構築します
\r
66 /// <param name="doc">Documentオブジェクト</param>
\r
67 /// <param name="filepath">読み取り先のファイル</param>
\r
68 /// <param name="enc">エンコーディング</param>
\r
69 /// <param name="token">キャンセル用のトークン</param>
\r
71 /// 読み取り操作は別スレッドで行われます。
\r
72 /// また、非同期操作中にこのメソッドを読みだすことはできません
\r
74 public static async Task LoadAsync(this Document doc, string filepath, Encoding enc, CancellationTokenSource token)
\r
76 if (doc.State != AsyncState.None)
\r
77 throw new InvalidOperationException();
\r
78 using (StreamReader sr = new StreamReader(filepath, enc))
\r
80 await LoadAsync(doc,sr, token);
\r
86 /// ストリームからドキュメントを構築します
\r
88 /// <param name="doc">Documentオブジェクト</param>
\r
89 /// <param name="sr">読み取り先のストリーム</param>
\r
91 /// 非同期操作中はこのメソッドを実行することはできません
\r
93 public static void Load(this Document doc, TextReader sr)
\r
95 Task t = LoadAsync(doc,sr, null);
\r
100 /// ストリームからドキュメントを非同期的に構築します
\r
102 /// <param name="doc">Documentオブジェクト</param>
\r
103 /// <param name="sr">読み取り先のストリーム</param>
\r
104 /// <param name="tokenSource">キャンセルトークン</param>
\r
105 /// <returns>Taskオブジェクト</returns>
\r
107 /// 読み取り操作は別スレッドで行われます。
\r
108 /// また、非同期操作中はこのメソッドを実行することはできません。
\r
110 public static async Task LoadAsync(this Document doc, TextReader sr, CancellationTokenSource tokenSource = null)
\r
112 if (doc.State != AsyncState.None)
\r
113 throw new InvalidOperationException();
\r
114 if (sr.Peek() == -1)
\r
119 IProgress<ProgressEventArgs> progress = _Progress;
\r
122 progress.Report(new ProgressEventArgs(ProgressState.Start));
\r
123 doc.State = AsyncState.Loading;
\r
124 doc.FireUpdateEvent = false;
\r
125 doc.StringBuffer.Clear();
\r
126 doc.UndoManager.BeginLock();
\r
128 for (int i = 0; (str = await sr.ReadLineAsync().ConfigureAwait(false)) != null; i++)
\r
130 int index = doc.StringBuffer.Length;
\r
134 doc.StringBuffer.Replace(index, 0, Util.GetEnumrator(str + Document.NewLine),str.Length + 1);
\r
136 if (tokenSource != null)
\r
137 tokenSource.Token.ThrowIfCancellationRequested();
\r
139 System.Threading.Thread.Sleep(10);
\r
145 doc.FireUpdateEvent = true;
\r
146 doc.UndoManager.EndLock();
\r
147 doc.State = AsyncState.None;
\r
148 progress.Report(new ProgressEventArgs(ProgressState.Complete));
\r
154 /// ドキュメントをファイルに保存します
\r
156 /// <param name="doc">Documentオブジェクト</param>
\r
157 /// <param name="filepath">保存先のファイル</param>
\r
158 /// <param name="enc">保存したいエンコード</param>
\r
159 /// <param name="newline">改行を表す文字列</param>
\r
160 /// <remarks>非同期操作中はこのメソッドを実行することはできません</remarks>
\r
161 public static void Save(this Document doc, string filepath, Encoding enc, string newline)
\r
163 if (doc.State != AsyncState.None)
\r
164 throw new InvalidOperationException();
\r
165 using (StreamWriter sw = new StreamWriter(filepath, false, enc))
\r
167 sw.NewLine = newline;
\r
173 /// ドキュメントをファイルに保存します
\r
175 /// <param name="doc">Documentオブジェクト</param>
\r
176 /// <param name="filepath">保存先のファイル</param>
\r
177 /// <param name="enc">保存したいエンコード</param>
\r
178 /// <param name="newline">改行を表す文字列</param>
\r
179 /// <param name="token">CancellationTokenSourceオブジェクト</param>
\r
180 /// <remarks>非同期操作中はこのメソッドを実行することはできません</remarks>
\r
181 public static async Task SaveAsync(this Document doc, string filepath, Encoding enc, string newline,CancellationTokenSource token)
\r
183 if (doc.State != AsyncState.None)
\r
184 throw new InvalidOperationException();
\r
185 using (StreamWriter sw = new StreamWriter(filepath, false, enc))
\r
187 sw.NewLine = newline;
\r
188 await SaveAsync(doc,sw, token);
\r
196 /// <param name="doc">Documentオブジェクト</param>
\r
197 /// <param name="sw">保存先のストリーム</param>
\r
198 /// <returns>Taskオブジェクト</returns>
\r
199 /// <remarks>非同期操作中はこのメソッドを実行することはできません</remarks>
\r
200 public static void Save(this Document doc, StreamWriter sw)
\r
202 Task t = SaveAsync(doc,sw, null);
\r
207 /// ストリームに非同期モードで保存します
\r
209 /// <param name="doc">Documentオブジェクト</param>
\r
210 /// <param name="sw">保存先のストリーム</param>
\r
211 /// <param name="tokenSource">キャンセルトークン</param>
\r
212 /// <returns>Taskオブジェクト</returns>
\r
213 /// <remarks>非同期操作中はこのメソッドを実行することはできません</remarks>
\r
214 public static async Task SaveAsync(this Document doc,StreamWriter sw, CancellationTokenSource tokenSource = null)
\r
216 if (doc.State != AsyncState.None)
\r
217 throw new InvalidOperationException();
\r
218 IProgress<ProgressEventArgs> progress = _Progress;
\r
221 progress.Report(new ProgressEventArgs(ProgressState.Start));
\r
222 doc.State = AsyncState.Saving;
\r
223 StringBuilder line = new StringBuilder();
\r
224 for (int i = 0; i < doc.Length; i++)
\r
228 if (c == Document.NewLine || i == doc.Length - 1)
\r
230 string str = line.ToString();
\r
231 str = str.Replace(Document.NewLine.ToString(), sw.NewLine);
\r
232 await sw.WriteAsync(str).ConfigureAwait(false);
\r
234 if (tokenSource != null)
\r
235 tokenSource.Token.ThrowIfCancellationRequested();
\r
237 System.Threading.Thread.Sleep(10);
\r
244 doc.State = AsyncState.None;
\r
245 progress.Report(new ProgressEventArgs(ProgressState.Complete));
\r