OSDN Git Service

2.102.3-SNAPSHOT 開発開始
[mikutoga/TogaGem.git] / src / test / java / jp / sfjp / mikutoga / bin / parser / DummyInputStream.java
1 /*
2  */
3
4 package jp.sfjp.mikutoga.bin.parser;
5
6 import java.io.IOException;
7 import java.io.InputStream;
8 import java.util.LinkedList;
9 import java.util.Queue;
10
11 /**
12  * テスト用入力ストリーム。
13  * これはユニットテストではない。
14  */
15 public class DummyInputStream extends InputStream {
16
17     private static final int MASK_08BIT = 0xff;
18
19
20     private final Queue<Byte> queue = new LinkedList<Byte>();
21
22     private boolean closed = false;
23
24     private long errPos = -1L;
25     private IOException errEx = null;
26
27
28     public DummyInputStream(byte[] bArray, int offset, int len){
29         super();
30         queueByteArrayImpl(bArray, offset, len);
31         return;
32     }
33
34     public DummyInputStream(byte... bArray){
35         this(bArray, 0, bArray.length);
36         return;
37     }
38
39     public DummyInputStream(int... iArray) throws IllegalArgumentException{
40         this(toBarray(iArray));
41         return;
42     }
43
44
45     /**
46      * int配列からbyte配列への変換を行う。
47      * bitが欠損した場合は異常系を投げる。
48      * @param iArray int配列
49      * @return byte配列
50      * @throws IllegalArgumentException bit欠損が発生
51      */
52     protected static byte[] toBarray(int[] iArray)
53             throws IllegalArgumentException{
54         int length = iArray.length;
55         byte[] result = new byte[length];
56
57         for(int pos = 0; pos < length; pos++){
58             int iVal = iArray[pos];
59             if(iVal < 0x00 || 0xff < iVal){
60                 throw new IllegalArgumentException();
61             }
62             byte bVal = (byte) iVal;
63             result[pos] = bVal;
64         }
65
66         return result;
67     }
68
69
70     /**
71      * 指定バイト数読み込んだ後に入力例外を意図的に発生させるよう設定する。
72      * @param pos 正常に読める残りバイト数。負の値なら設定解除。
73      * @param ex 入力例外。解除時に限ってnullも可。
74      */
75     public void setErrorPosition(long pos, IOException ex){
76         this.errPos = pos;
77
78         if(this.errPos >= 0L){
79             if(ex == null) throw new NullPointerException();
80             this.errEx = ex;
81         }else{
82             this.errEx = null;
83         }
84
85         return;
86     }
87
88     /**
89      * 意図的な入力例外を起こすまで、
90      * あと何バイト正常に読めるか設定値を返す。
91      * @return 正常に読めるバイト数。
92      */
93     public long getErrorPosition(){
94         long result = this.errPos;
95         return result;
96     }
97
98     /**
99      * 意図した入力エラー報告を投げる状況かチェックする。
100      * @throws IOException 意図した入力エラー
101      */
102     protected void checkIOEx() throws IOException {
103         if(this.errPos < 0L) return;
104         if(this.errPos > 0L) return;
105
106         IOException ex = this.errEx;
107         this.errPos = -1L;
108         this.errEx = null;
109
110         throw ex;
111     }
112
113     /**
114      * {@inheritDoc}
115      * クローズの有無は外部からの観察が可能。
116      * @throws IOException {@inheritDoc}
117      * 設定状況によっては意図的な入力例外を投げる。
118      */
119     @Override
120     public void close() throws IOException {
121         checkIOEx();
122         this.closed = true;
123         return;
124     }
125
126     /**
127      * クローズされた状況か判定する。
128      * @return クローズ済みであればtrue
129      */
130     public boolean isClosed(){
131         boolean result = this.closed;
132         return result;
133     }
134
135     /**
136      * {@inheritDoc}
137      * @param bArray {@inheritDoc}
138      * @param offset {@inheritDoc}
139      * @param len {@inheritDoc}
140      * @return {@inheritDoc}
141      * @throws IOException {@inheritDoc}
142      */
143     @Override
144     public int read(byte[] bArray, int offset, int len) throws IOException {
145         int result = 0;
146
147         for(int pos = 0; pos < len; pos++){
148             int iVal = read();
149             if(iVal < 0){
150                 if(result == 0) result = -1;
151                 break;
152             }
153             bArray[offset + pos] = (byte)iVal;
154             result++;
155         }
156
157         return result;
158     }
159
160     /**
161      * {@inheritDoc}
162      * @param bArray {@inheritDoc}
163      * @return {@inheritDoc}
164      * @throws IOException {@inheritDoc}
165      */
166     @Override
167     public int read(byte[] bArray) throws IOException {
168         int result = read(bArray, 0, bArray.length);
169         return result;
170     }
171
172     /**
173      * {@inheritDoc}
174      * @return {@inheritDoc}
175      * @throws IOException {@inheritDoc}
176      */
177     @Override
178     public int read() throws IOException {
179         checkIOEx();
180
181         Byte val = this.queue.poll();
182         if(val == null) return  -1;
183
184         int iVal = (int)( val.byteValue() );
185         int result = iVal & MASK_08BIT;
186
187         if(this.errPos > 0){
188             this.errPos--;
189         }
190
191         return result;
192     }
193
194     /**
195      * 未出力のバイト列長を返す。
196      * @return バイト列長
197      */
198     public int getQueueLength(){
199         int result = this.queue.size();
200         return result;
201     }
202
203     /**
204      * 未出力バイト列を空にする。
205      */
206     public void clearQueue(){
207         this.queue.clear();
208         return;
209     }
210
211     /**
212      * 未出力バイト列にデータを追加する。
213      * @param bArray 配列
214      * @param offset 開始オフセット
215      * @param len バイト長
216      */
217     private void queueByteArrayImpl(byte[] bArray, int offset, int len){
218         for(int pos = 0; pos < len; pos++){
219             byte bVal = bArray[offset + pos];
220             this.queue.add(bVal);
221         }
222         return;
223     }
224
225     /**
226      * 未出力バイト列にデータを追加する。
227      * @param bArray 配列
228      * @param offset 開始オフセット
229      * @param len バイト長
230      */
231     public void queueByteArray(byte[] bArray, int offset, int len){
232         queueByteArrayImpl(bArray, offset, len);
233         return;
234     }
235
236     /**
237      * 未出力バイト列にデータを追加する。
238      * @param bArray 配列
239      */
240     public void queueByteArray(byte[] bArray){
241         for(byte bVal : bArray){
242             this.queue.add(bVal);
243         }
244         return;
245     }
246
247     /**
248      * 未出力バイト列にデータを追加する。
249      * @param bArray byte型可変引数
250      */
251     public void queueByte(byte... bArray){
252         queueByteArray(bArray);
253         return;
254     }
255
256     /**
257      * 未出力バイト列にデータを追加する。
258      * @param iArray int型可変引数。byte値に収まる要素値でなければならない。
259      * @throws IllegalArgumentException byte値に収まらない値が指定された。
260      */
261     public void queueByte(int... iArray) throws IllegalArgumentException{
262         for(int iVal : iArray){
263             if(iVal < 0x00 || 0xff < iVal){
264                 throw new IllegalArgumentException();
265             }
266             byte bVal = (byte) iVal;
267             this.queue.add(bVal);
268         }
269         return;
270     }
271
272 }