4 * License : The MIT License
5 * Copyright(c) 2010 MikuToga Partners
8 package jp.sourceforge.mikutoga.parser;
10 import java.io.IOException;
11 import java.nio.CharBuffer;
12 import java.nio.charset.Charset;
17 public class CommonParser {
20 * PMDで用いられる文字エンコーディング(windows-31j)。
21 * ほぼShift_JISのスーパーセットと思ってよい。
22 * デコード結果はUCS-2集合に収まるはず。
24 public static final Charset CS_WIN31J = Charset.forName("windows-31j");
26 /** PMXで用いられる文字エンコーディング(UTF-8)。 */
27 public static final Charset CS_UTF8 = Charset.forName("UTF-8");
29 /** PMXで用いられる文字エンコーディング(UTF-16のリトルエンディアン)。 */
30 public static final Charset CS_UTF16LE = Charset.forName("UTF-16LE");
32 private final MmdSource source;
34 private final TextDecoder decoderWin31j = new TextDecoder(CS_WIN31J);
35 private final TextDecoder decoderUTF8 = new TextDecoder(CS_UTF8);
36 private final TextDecoder decoderUTF16LE = new TextDecoder(CS_UTF16LE);
42 public CommonParser(MmdSource source){
47 this.decoderWin31j .setZeroChopMode(true);
48 this.decoderUTF8 .setZeroChopMode(false);
49 this.decoderUTF16LE.setZeroChopMode(false);
55 * 入力ソースにまだデータが残っているか判定する。
56 * @return まだ読み込んでいないデータが残っていればtrue
57 * @throws IOException IOエラー
58 * @see MmdSource#hasMore()
60 protected boolean hasMore() throws IOException{
61 boolean result = this.source.hasMore();
67 * @param skipLength 読み飛ばすバイト数。
68 * @throws IOException IOエラー
69 * @throws MmdEofException 読み飛ばす途中でストリーム終端に達した。
70 * @see MmdSource#skip(long)
72 protected void skip(long skipLength)
73 throws IOException, MmdEofException {
74 long result = this.source.skip(skipLength);
75 if(result != skipLength){
76 throw new MmdEofException(this.source.getPosition());
84 * @param skipLength 読み飛ばすバイト数。
85 * @throws IOException IOエラー
86 * @throws MmdEofException 読み飛ばす途中でストリーム終端に達した。
87 * @see MmdSource#skip(long)
89 protected void skip(int skipLength)
90 throws IOException, MmdEofException {
91 skip((long) skipLength);
97 * @throws IOException IOエラー
98 * @throws MmdEofException 読み込む途中でストリーム終端に達した。
99 * @see MmdSource#parseByte()
101 protected byte parseByte()
102 throws IOException, MmdEofException{
103 return this.source.parseByte();
107 * 符号無し値としてbyte値を読み込み、int型に変換して返す。
108 * 符号は拡張されない。(0xffは0x000000ffとなる)
109 * @return 読み込まれた値のint値
110 * @throws IOException IOエラー
111 * @throws MmdEofException 読み込む途中でストリーム終端に達した。
112 * @see MmdSource#parseUByteAsInteger()
114 protected int parseUByteAsInteger()
115 throws IOException, MmdEofException{
116 return this.source.parseUByteAsInteger();
120 * byte値を読み込み、boolean型に変換して返す。
121 * 0x00は偽、それ以外は真と解釈される。
122 * @return 読み込まれた値のboolean値
123 * @throws IOException IOエラー
124 * @throws MmdEofException 読み込む途中でストリーム終端に達した。
125 * @see MmdSource#parseBoolean()
127 protected boolean parseBoolean()
128 throws IOException, MmdEofException{
129 return this.source.parseBoolean();
134 * short値はリトルエンディアンで格納されていると仮定される。
135 * @return 読み込んだshort値
136 * @throws IOException IOエラー
137 * @throws MmdEofException 読み込む途中でストリーム終端に達した。
138 * @see MmdSource#parseShort()
140 protected short parseShort()
141 throws IOException, MmdEofException{
142 return this.source.parseShort();
146 * 符号無し値としてshort値を読み込み、int型に変換して返す。
147 * 符号は拡張されない。(0xffffは0x0000ffffとなる)
148 * short値はリトルエンディアンで格納されていると仮定される。
149 * @return 読み込まれた値のint値
150 * @throws IOException IOエラー
151 * @throws MmdEofException 読み込む途中でストリーム終端に達した。
152 * @see MmdSource#parseUShortAsInteger()
154 protected int parseUShortAsInteger()
155 throws IOException, MmdEofException{
156 return this.source.parseUShortAsInteger();
161 * int値はリトルエンディアンで格納されていると仮定される。
163 * @throws IOException IOエラー
164 * @throws MmdEofException 読み込む途中でストリーム終端に達した。
165 * @see MmdSource#parseInteger()
167 protected int parseInteger()
168 throws IOException, MmdEofException{
169 return this.source.parseInteger();
174 * float値はリトルエンディアンで格納されていると仮定される。
175 * @return 読み込んだfloat値
176 * @throws IOException IOエラー
177 * @throws MmdEofException 読み込む途中でストリーム終端に達した。
178 * @see MmdSource#parseFloat()
180 protected float parseFloat()
181 throws IOException, MmdEofException{
182 return this.source.parseFloat();
188 * @param offset 読み込み開始オフセット
189 * @param length 読み込みバイト数
190 * @throws IOException IOエラー
191 * @throws NullPointerException 配列がnull
192 * @throws IndexOutOfBoundsException 引数が配列属性と矛盾
193 * @throws MmdEofException 読み込む途中でストリーム終端に達した。
194 * @see MmdSource#parseByteArray(byte[], int, int)
196 protected void parseByteArray(byte[] dst, int offset, int length)
198 NullPointerException,
199 IndexOutOfBoundsException,
201 this.source.parseByteArray(dst, offset, length);
209 * @throws IOException IOエラー
210 * @throws NullPointerException 配列がnull
211 * @throws MmdEofException 読み込む途中でストリーム終端に達した。
212 * @see MmdSource#parseByteArray(byte[])
214 protected void parseByteArray(byte[] dst)
215 throws IOException, NullPointerException, MmdEofException{
216 this.source.parseByteArray(dst);
223 * @param offset 読み込み開始オフセット
224 * @param length 読み込みfloat要素数
225 * @throws IOException IOエラー
226 * @throws NullPointerException 配列がnull
227 * @throws IndexOutOfBoundsException 引数が配列属性と矛盾
228 * @throws MmdEofException 読み込む途中でストリーム終端に達した。
229 * @see MmdSource#parseFloatArray(float[], int, int)
231 protected void parseFloatArray(float[] dst, int offset, int length)
233 NullPointerException,
234 IndexOutOfBoundsException,
236 this.source.parseFloatArray(dst, offset, length);
244 * @throws IOException IOエラー
245 * @throws NullPointerException 配列がnull
246 * @throws MmdEofException 読み込む途中でストリーム終端に達した。
247 * @see MmdSource#parseFloatArray(float[])
249 protected void parseFloatArray(float[] dst)
250 throws IOException, NullPointerException, MmdEofException{
251 this.source.parseFloatArray(dst);
256 * 指定された最大バイト長に収まるゼロ終端(0x00)文字列を読み込む。
257 * 入力バイト列はwindows-31jエンコーディングとして解釈される。
259 * IO入力は指定バイト数だけ読み進められる。
260 * ゼロ終端が見つからないまま指定バイト数が読み込み終わった場合、
261 * そこまでのデータから文字列を構成する。
263 * @param maxlen 読み込みバイト数
265 * @throws IOException IOエラー
266 * @throws MmdEofException 読み込む途中でストリーム終端に達した。
267 * @throws MmdFormatException 不正な文字エンコーディングが検出された。
269 protected String parseZeroTermWin31J(int maxlen)
274 this.decoderWin31j.parseString(this.source, maxlen);
276 String result = encoded.toString();