2 * MMD file input stream
4 * License : The MIT License
5 * Copyright(c) 2012 MikuToga Partners
8 package jp.sourceforge.mikutoga.parser;
10 import java.io.IOException;
11 import java.io.InputStream;
12 import java.nio.ByteBuffer;
13 import java.nio.ByteOrder;
16 * MMD各種バイナリデータ用の入力ストリーム。
17 * リトルエンディアンデータおよびEOFの扱い方で
18 * java.io.DataInputStreamと差別化される。
20 public class MmdInputStream extends SpottedInputStream {
22 private static final int BYTES_SHORT = Short .SIZE / Byte.SIZE;
23 private static final int BYTES_INT = Integer.SIZE / Byte.SIZE;
24 private static final int BYTES_FLOAT = Float .SIZE / Byte.SIZE;
25 private static final int BUF_SZ = 4;
28 private final byte[] readArray;
29 private final ByteBuffer beBuf;
30 private final ByteBuffer leBuf;
37 public MmdInputStream(InputStream is){
40 this.readArray = new byte[BUF_SZ];
42 this.beBuf = ByteBuffer.wrap(this.readArray);
43 this.leBuf = ByteBuffer.wrap(this.readArray);
45 this.beBuf.order(ByteOrder.BIG_ENDIAN);
46 this.leBuf.order(ByteOrder.LITTLE_ENDIAN);
54 * なるべく指定したバイト数全てが読み飛ばされるよう、
56 * @param skipLength 読み飛ばすバイト数。
57 * @return 実際に読み飛ばしたバイト数。
58 * @throws IOException IOエラー
59 * @see java.io.InputStream#skip(long)
61 public long skipRepeat(long skipLength)
63 if(skipLength <= 0L) return 0L;
65 long remain = skipLength;
66 while(remain > 0L){ // BufferedInputStream対策
67 long result = skip(remain);
68 if(result <= 0L) break;
72 return skipLength - remain;
76 * 指定したバイト数だけ内部バッファに読み込む。
77 * @param fillSize 読み込むバイト数
78 * @throws IOException IOエラー
79 * @throws IndexOutOfBoundsException 引数がバッファサイズと矛盾。
80 * @throws MmdEofException 読み込む途中でストリーム終端に達した。
82 private void fillBuffer(int fillSize)
83 throws IOException, IndexOutOfBoundsException, MmdEofException{
84 int result = read(this.readArray, 0, fillSize);
86 if(result != fillSize){
87 long pos = getPosition();
88 throw new MmdEofException(pos);
97 * @throws IOException IOエラー
98 * @throws MmdEofException 読み込む途中でストリーム終端に達した。
100 public byte parseByte() throws IOException, MmdEofException{
103 long pos = getPosition();
104 throw new MmdEofException(pos);
107 byte result = (byte) bData;
112 * byte値を読み込み、boolean型に変換して返す。
113 * 0x00は偽、それ以外は真と解釈される。
114 * @return 読み込まれた値のboolean値
115 * @throws IOException IOエラー
116 * @throws MmdEofException 読み込む途中でストリーム終端に達した。
118 public boolean parseBoolean() throws IOException, MmdEofException{
119 byte result = parseByte();
120 if(result == 0x00) return false;
126 * @param buf オーダー指定されたバッファ
128 * @throws IOException 入力エラー
129 * @throws MmdEofException 途中でストリーム終端に達した。
131 private short parseShort(ByteBuffer buf)
132 throws IOException, MmdEofException{
133 fillBuffer(BYTES_SHORT);
134 short result = buf.getShort(0);
140 * ビッグエンディアンでshort値を読み込む。
142 * @throws IOException 入力エラー
143 * @throws MmdEofException 途中でストリーム終端に達した。
145 public short parseBeShort() throws IOException, MmdEofException{
146 short result = parseShort(this.beBuf);
151 * リトルエンディアンでshort値を読み込む。
153 * @throws IOException 入力エラー
154 * @throws MmdEofException 途中でストリーム終端に達した。
156 public short parseLeShort() throws IOException, MmdEofException{
157 short result = parseShort(this.leBuf);
163 * @param buf オーダー指定されたバッファ
165 * @throws IOException 入力エラー
166 * @throws MmdEofException 途中でストリーム終端に達した。
168 private int parseInt(ByteBuffer buf)
169 throws IOException, MmdEofException{
170 fillBuffer(BYTES_INT);
171 int result = buf.getInt(0);
177 * ビッグエンディアンでint値を読み込む。
179 * @throws IOException 入力エラー
180 * @throws MmdEofException 途中でストリーム終端に達した。
182 public int parseBeInt() throws IOException, MmdEofException{
183 int result = parseInt(this.beBuf);
188 * リトルエンディアンでint値を読み込む。
190 * @throws IOException 入力エラー
191 * @throws MmdEofException 途中でストリーム終端に達した。
193 public int parseLeInt() throws IOException, MmdEofException{
194 int result = parseInt(this.leBuf);
200 * @param buf オーダー指定されたバッファ
202 * @throws IOException 入力エラー
203 * @throws MmdEofException 途中でストリーム終端に達した。
205 private float parseFloat(ByteBuffer buf)
206 throws IOException, MmdEofException{
207 fillBuffer(BYTES_FLOAT);
208 float result = buf.getFloat(0);
213 * ビッグエンディアンでfloat値を読み込む。
215 * @throws IOException 入力エラー
216 * @throws MmdEofException 途中でストリーム終端に達した。
218 public float parseBeFloat() throws IOException, MmdEofException{
219 float result = parseFloat(this.beBuf);
224 * リトルエンディアンでfloat値を読み込む。
226 * @throws IOException 入力エラー
227 * @throws MmdEofException 途中でストリーム終端に達した。
229 public float parseLeFloat() throws IOException, MmdEofException{
230 float result = parseFloat(this.leBuf);