root/as3/Utils/src/org/libspark/utils/LineReader.as

リビジョン 833, 6.5 kB (コミッタ: tera, コミット時期: 4 年 前)

--

Line 
1 /*
2  * Licensed under the MIT License
3  *
4  * Copyright (c) 2008 tera
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  *
24  */
25
26 package org.libspark.utils
27 {
28        
29         import flash.errors.IllegalOperationError;
30         import flash.events.EventDispatcher;
31         import flash.events.IEventDispatcher;
32         import flash.events.ProgressEvent;
33         import flash.net.Socket;
34         import flash.utils.ByteArray;
35         import flash.utils.IDataInput;
36        
37         /**
38          * 一行分がバッファに貯まったら送信されます。
39          */
40         [Event(name="progress", type="ProgressEvent.PROGRESS")]
41        
42        
43         /**
44          * LineReader クラスは、 IDataInput インターフェースを実装するクラスに対して、一行ごとにデータを読み込む機能を提供します。<br />
45          * 一行読み込むたびにProgressEvent.PROGRESSを発生させます。
46          *
47          */
48         public class LineReader extends EventDispatcher {
49                
50                 /**
51                  * 新しい LineReader クラスのインスタンスを生成します。
52                  *
53                  * 引数で渡される dataInput オブジェクトは、 IEventDispatcher を実装し、<br />
54                  * flash.events.ProgressEvent.SOCKET_DATA または flash.events.ProgressEvent.PROGRESS イベントを発生させるクラス<br />
55                  * ( flash.net.Socket , flash.net.URLStream , flash.filesystem.FileStream )である必要があります。<br />
56                  * ロード完了時なでではProgressEvent.PROGRESSを発生させないので、<br />
57                  * 最後の一行を得るには読み込みが完了した段階でLineReaderオブジェクトのbufferプロパティを直接取得する必要があります。
58                  *
59                  * @param dataInput 処理対象となる IDataInput インターフェースの実装クラス
60                  */
61                 public function LineReader(dataInput:IDataInput)
62                 {
63                         var dataInputDispatcher:IEventDispatcher = dataInput as IEventDispatcher;
64                        
65                         if (!dataInputDispatcher) {
66                                 throw new IllegalOperationError("dataInput must implements IEventDispatcher");
67                         }
68                         dataInputDispatcher.addEventListener((dataInput is Socket) ? ProgressEvent.SOCKET_DATA : ProgressEvent.PROGRESS, progressHandler, false, 0, true);
69                 }
70                
71                 // 改行コード:キャリッジリターン
72                 private static const CARRIAGE_RETURN:int = 0x0D;
73                
74                 // 改行コード:ラインフィード
75                 private static const LINE_FEED:int = 0x0A;
76                
77                 // 次バイトで検出したLFをスキップするか
78                 private var _skipNextLineFeed:Boolean = false;
79                
80                 // 読み取りバッファ
81                 private var _buffer:ByteArray = new ByteArray();
82                
83                 // 改行コードをバッファに保存するか
84                 private var _trimLineFeed:Boolean = true;
85                
86                 // 空行をスキップするか
87                 private var _skipBlankLine:Boolean = false;
88                
89                 /**
90                  * 現在のバッファ内容を返します。
91                  *
92                  * @return      現在読み込んでいるバッファ内容
93                  */
94                 public function get buffer():ByteArray {
95                         return _buffer;
96                 }
97                
98                 /**
99                  * 改行コードをバッファに保存するかを設定します。
100                  *
101                  * @param flag 現在の設定
102                  */
103                 public function set trimLineFeed(flag:Boolean):void {
104                         _trimLineFeed = flag;
105                 }
106                
107                 /**
108                  * 改行コードをバッファに保存するかを返します。
109                  *
110                  * @return 現在の設定
111                  */
112                 public function get trimLineFeed():Boolean {
113                         return _trimLineFeed;
114                 }
115                
116                 /**
117                  * 空行をスキップするかを設定します。
118                  *
119                  * @param flag 現在の設定
120                  */
121                 public function set skipBlankLine(flag:Boolean):void {
122                         _skipBlankLine = flag;
123                 }
124                
125                 /**
126                  * 空行をスキップするかを返します。
127                  *
128                  * @return 現在の設定
129                  */
130                 public function get skipBlankLine():Boolean {
131                         return _skipBlankLine;
132                 }
133                
134                 /**
135                  * ProgressEvent.PROGRESS または ProgressEvent.SOCKET_DATA イベントを受け取り、一行ごとにバッファに格納します。
136                  *
137                  * @param e ProgressEvent.PROGRESS または ProgressEvent.SOCKET_DATA イベント
138                  * @eventType ProgressEvent.PROGRESS
139                  * @private
140                  */
141                 private function progressHandler(e:ProgressEvent):void
142                 {
143                         // バッファにリード
144                         var dataInput:IDataInput = e.target as IDataInput;
145                         var byte:int;
146                         while (dataInput.bytesAvailable) {
147                                 // 1バイトずつ読み込む
148                                 byte = dataInput.readByte();
149                                
150                                 if (_skipNextLineFeed) {
151                                         _skipNextLineFeed = false;
152                                         if (byte == LINE_FEED) {
153                                                 if (!_trimLineFeed) {
154                                                         _buffer.writeByte(byte);
155                                                         if (!_skipBlankLine || _buffer.length > 2) {
156                                                                 dispatchEvent(new ProgressEvent( ProgressEvent.PROGRESS, false, false, e.bytesLoaded-dataInput.bytesAvailable, e.bytesTotal));
157                                                         }
158                                                 } else {
159                                                         if (!_skipBlankLine || _buffer.length > 1) {
160                                                                 dispatchEvent(new ProgressEvent( ProgressEvent.PROGRESS, false, false, e.bytesLoaded-dataInput.bytesAvailable, e.bytesTotal));
161                                                         }
162                                                 }
163                                                 _buffer = new ByteArray();
164                                                 continue;
165                                         } else {
166                                                 if (!_skipBlankLine || _buffer.length > 1) {
167                                                         dispatchEvent(new ProgressEvent( ProgressEvent.PROGRESS, false, false, e.bytesLoaded-dataInput.bytesAvailable-1, e.bytesTotal));
168                                                 }
169                                                 _buffer = new ByteArray();
170                                         }
171                                 } else if (byte == LINE_FEED) {
172                                         if (!_trimLineFeed) {
173                                                 _buffer.writeByte(byte);
174                                         }
175                                         if (!_skipBlankLine || _buffer.length > 1) {
176                                                 dispatchEvent(new ProgressEvent( ProgressEvent.PROGRESS, false, false, e.bytesLoaded-dataInput.bytesAvailable, e.bytesTotal));
177                                         }
178                                         _buffer = new ByteArray();
179                                         continue;
180                                 } else if (byte == CARRIAGE_RETURN) {
181                                         if (!_trimLineFeed) {
182                                                 _buffer.writeByte(byte);
183                                         }
184                                         _skipNextLineFeed = true;
185                                         continue;
186                                 }
187                                 _buffer.writeByte(byte);
188                                
189                         }
190                 }
191         }
192 }
Note: リポジトリブラウザについてのヘルプは TracBrowser を参照してください。