OSDN Git Service

入出力強化
authorOlyutorskii <olyutorskii@users.osdn.me>
Thu, 20 Dec 2012 14:03:11 +0000 (23:03 +0900)
committerOlyutorskii <olyutorskii@users.osdn.me>
Thu, 20 Dec 2012 14:03:11 +0000 (23:03 +0900)
28 files changed:
pom.xml
src/main/config/checks.xml
src/main/config/pmdrules.xml
src/main/java/jp/sourceforge/mikutoga/binio/BinaryExporter.java
src/main/java/jp/sourceforge/mikutoga/binio/FeedableOutputStream.java [deleted file]
src/main/java/jp/sourceforge/mikutoga/binio/IllegalTextExportException.java
src/main/java/jp/sourceforge/mikutoga/binio/TextExporter.java
src/main/java/jp/sourceforge/mikutoga/parser/CommonParser.java
src/main/java/jp/sourceforge/mikutoga/parser/MmdInputStream.java [new file with mode: 0644]
src/main/java/jp/sourceforge/mikutoga/parser/MmdSource.java [deleted file]
src/main/java/jp/sourceforge/mikutoga/parser/SpottedInputStream.java [new file with mode: 0644]
src/main/java/jp/sourceforge/mikutoga/parser/TextDecoder.java
src/main/java/jp/sourceforge/mikutoga/pmd/parser/PmdParser.java
src/main/java/jp/sourceforge/mikutoga/pmd/parser/PmdParserBase.java
src/main/java/jp/sourceforge/mikutoga/pmd/parser/PmdParserExt1.java
src/main/java/jp/sourceforge/mikutoga/pmd/parser/PmdParserExt2.java
src/main/java/jp/sourceforge/mikutoga/pmd/parser/PmdParserExt3.java
src/main/java/jp/sourceforge/mikutoga/vmd/parser/VmdBasicParser.java
src/main/java/jp/sourceforge/mikutoga/vmd/parser/VmdCameraParser.java
src/main/java/jp/sourceforge/mikutoga/vmd/parser/VmdLightingParser.java
src/main/java/jp/sourceforge/mikutoga/vmd/parser/VmdParser.java
src/test/java/jp/sourceforge/mikutoga/binio/BinaryExporterTest.java [new file with mode: 0644]
src/test/java/jp/sourceforge/mikutoga/binio/TextExporterTest.java [new file with mode: 0644]
src/test/java/jp/sourceforge/mikutoga/parser/MmdInputStreamTest.java [new file with mode: 0644]
src/test/java/jp/sourceforge/mikutoga/parser/SpottedInputStreamTest.java [new file with mode: 0644]
src/test/java/jp/sourceforge/mikutoga/parser/TextDecoderTest.java
src/test/java/sample/pmd/DummyMain.java
src/test/java/sample/vmd/DummyMain.java

diff --git a/pom.xml b/pom.xml
index 6fd6bf7..f4d468d 100644 (file)
--- a/pom.xml
+++ b/pom.xml
         <dependency>
             <groupId>junit</groupId>
             <artifactId>junit</artifactId>
-            <version>4.10</version>
+            <version>4.11</version>
             <scope>test</scope>
         </dependency>
 
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-enforcer-plugin</artifactId>
-                <version>1.0.1</version>
+                <version>1.1.1</version>
                 <configuration>
                     <rules>
                         <requireMavenVersion>
 
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-install-plugin</artifactId>
+                <version>2.4</version>
+            </plugin>
+
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-clean-plugin</artifactId>
-                <version>2.4.1</version>
+                <version>2.5</version>
                 <configuration>
                     <filesets>
                         <fileset>
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-compiler-plugin</artifactId>
-                <version>2.3.2</version>
+                <version>3.0</version>
                 <configuration>
                     <source>1.6</source>  <!-- for NetBeans IDE -->
                     <target>1.6</target>
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-jar-plugin</artifactId>
-                <version>2.3.2</version>
+                <version>2.4</version>
                 <configuration>
                     <archive>
                         <manifestEntries>
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-assembly-plugin</artifactId>
-                <version>2.2.1</version>
+                <version>2.4</version>
                 <configuration>
                     <descriptors>
                         <descriptor>src/main/assembly/descriptor.xml</descriptor>
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-source-plugin</artifactId>
-                <version>2.1.2</version>
+                <version>2.2.1</version>
                 <configuration>
                     <includePom>true</includePom>
                     <archive>
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-resources-plugin</artifactId>
-                <version>2.5</version>
+                <version>2.6</version>
             </plugin>
 
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-surefire-plugin</artifactId>
-                <version>2.10</version>
+                <version>2.12.4</version>
                 <configuration>
                     <skipTests>false</skipTests>
                     <enableAssertions>true</enableAssertions>
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-site-plugin</artifactId>
-                <version>3.0</version>
+                <version>3.2</version>
                 <configuration>
                     <generateReports>true</generateReports>
                     <locales>ja</locales>
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-checkstyle-plugin</artifactId>
-                <version>2.8</version>
+                <version>2.9.1</version>
                 <!-- config from property value -->
             </plugin>
 
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-pmd-plugin</artifactId>
-                <version>2.6</version>
+                <version>2.7.1</version>
                 <configuration>
                     <targetJdk>${maven.compiler.target}</targetJdk>
                     <rulesets>
             <plugin>
                 <groupId>org.codehaus.mojo</groupId>
                 <artifactId>findbugs-maven-plugin</artifactId>
-                <version>2.3.2</version>
+                <version>2.5.2</version>
                 <configuration>
                     <effort>Max</effort>
                     <threshold>Low</threshold>
+                    <!-- for Jenkins -->
+                    <findbugsXmlOutput>true</findbugsXmlOutput>
+                    <findbugsXmlWithMessages>true</findbugsXmlWithMessages>
+                    <xmlOutput>true</xmlOutput>
+                </configuration>
+            </plugin>
+
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>cobertura-maven-plugin</artifactId>
+                <version>2.5.2</version>
+                <configuration>
+                    <encoding>${project.build.sourceEncoding}</encoding>
+                    <formats>
+                        <format>html</format>
+                        <format>xml</format> <!-- for Jenkins -->
+                    </formats>
                 </configuration>
             </plugin>
 
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-project-info-reports-plugin</artifactId>
-                <version>2.4</version>
+                <version>2.6</version>
                 <configuration>
                     <linkOnly>true</linkOnly>
                     <offline>true</offline>
                             <report>project-team</report>
 <!--
                             <report>dependency-convergence</report>
+                            <report>dependency-info</report>
                             <report>dependency-management</report>
                             <report>distribution-management</report>
                             <report>issue-tracking</report>
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-javadoc-plugin</artifactId>
-                <version>2.8</version>
+                <version>2.9</version>
                 <configuration>
                     <skip>false</skip>
                     <notimestamp>true</notimestamp>
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-surefire-report-plugin</artifactId>
-                <version>2.10</version>
+                <version>2.12.4</version>
                 <configuration>
                     <showSuccess>false</showSuccess>
                 </configuration>
             <plugin>
                 <groupId>org.codehaus.mojo</groupId>
                 <artifactId>cobertura-maven-plugin</artifactId>
-                <version>2.5.1</version>
+                <version>2.5.2</version>
                 <configuration>
                     <encoding>${project.build.sourceEncoding}</encoding>
+                    <formats>
+                        <format>html</format>
+                        <format>xml</format> <!-- for Jenkins -->
+                    </formats>
                 </configuration>
             </plugin>
 
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-checkstyle-plugin</artifactId>
-                <version>2.8</version>
+                <version>2.9.1</version>
                 <configuration>
                     <skip>false</skip>
                     <!-- config from property value -->
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-pmd-plugin</artifactId>
-                <version>2.6</version>
+                <version>2.7.1</version>
                 <configuration>
                     <skip>false</skip>
                     <targetJdk>${maven.compiler.target}</targetJdk>
             <plugin>
                 <groupId>org.codehaus.mojo</groupId>
                 <artifactId>findbugs-maven-plugin</artifactId>
-                <version>2.3.2</version>
+                <version>2.5.2</version>
                 <configuration>
-                    <skip>true</skip>  <!-- UTF-8 Bugs? -->
+                    <skip>false</skip>
                     <effort>Max</effort>
                     <threshold>Low</threshold>
+                    <!-- for Jenkins -->
+                    <findbugsXmlOutput>true</findbugsXmlOutput>
+                    <findbugsXmlWithMessages>true</findbugsXmlWithMessages>
+                    <xmlOutput>true</xmlOutput>
                     <!-- excludeFilterFile/ -->
                 </configuration>
             </plugin>
index d5e3ff9..cf55cf6 100644 (file)
@@ -7,7 +7,7 @@
 <!--
     Checkstyle用チェック項目定義。
 
-    Checkstyle 5.3 以降向けに記述。
+    Checkstyle 5.5 以降向けに記述。
 
     [ http://checkstyle.sourceforge.net/ ]
 
 <!--    <module name="DesignForExtension" />  -->
         <module name="MutableException" />
         <module name="ThrowsCount">
-            <property name="max" value="3" />
+            <property name="max" value="4" />
         </module>
         <module name="InnerTypeLast" />
 
         <module name="DefaultComesLast" />
         <module name="MissingCtor" />
         <module name="FallThrough" />
-        <module name="MultipleStringLiterals">
-            <property
-                name="ignoreStringsRegexp"
-                value="^&quot;&quot;$|^&quot;.&quot;$"
-            />
-        </module>
+        <module name="MultipleStringLiterals" />
         <module name="MultipleVariableDeclarations" />
+        <module name="RequireThis">
+            <property name="checkMethods" value="false" />
+        </module>
         <module name="UnnecessaryParentheses" />
         <module name="OneStatementPerLine" />
 
         <module name="ParameterName">
             <property name="format" value="^[a-z][_a-zA-Z0-9]*$" />
         </module>
-        <module name="StaticVariableName" />
+        <module name="StaticVariableName">
+            <property name="format" value="^[a-z][_a-zA-Z0-9]*$" />
+        </module>
         <module name="TypeName" />
 
 
         <module name="RegexpSinglelineJava" />
 -->
 
-<!-- バグ?
-        <module name="RequireThis" />
--->
-
 <!-- Obsolated
         <module name="TabCharacter" />
 -->
index 65d196b..a77bfcc 100644 (file)
@@ -3,7 +3,7 @@
 <!--
     PMD用ルールセット定義
 
-    PMD [ http://pmd.sourceforge.net/ ] 4.2.5 以降用に記述されています。
+    PMD [ http://pmd.sourceforge.net/ ] 4.3 以降用に記述されています。
 
     Copyright(c) 2010 olyutorskii
 -->
@@ -47,6 +47,7 @@
         <exclude name="DefaultPackage" />
         <exclude name="DataflowAnomalyAnalysis" />
         <exclude name="AvoidUsingShortType" />
+        <exclude name="AvoidLiteralsInIfCondition" />
     </rule>
 
     <rule ref="rulesets/coupling.xml" />
index e3226b9..c1dba28 100644 (file)
@@ -7,10 +7,11 @@
 
 package jp.sourceforge.mikutoga.binio;
 
+import java.io.ByteArrayOutputStream;
+import java.io.Closeable;
+import java.io.Flushable;
 import java.io.IOException;
 import java.io.OutputStream;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
 import java.nio.charset.CharacterCodingException;
 import java.nio.charset.Charset;
 import java.text.MessageFormat;
@@ -19,7 +20,7 @@ import java.text.MessageFormat;
  * バイナリデータの出力を行う汎用エクスポーター。
  * <p>デフォルトではリトルエンディアン形式で出力される。
  */
-public class BinaryExporter {
+public class BinaryExporter implements Closeable, Flushable{
 
     private static final Charset CS_UTF16LE = Charset.forName("UTF-16LE");
     private static final Charset CS_WIN31J  = Charset.forName("windows-31j");
@@ -30,6 +31,7 @@ public class BinaryExporter {
             + "text \"{0}\" needs {1}bytes encoded but limit={2}bytes";
 
     private static final int MASK_16 = 0xffff;
+    private static final int MASK_8  =   0xff;
 
     private static final int BYTES_SHORT  = Short   .SIZE / Byte.SIZE;
     private static final int BYTES_INT    = Integer .SIZE / Byte.SIZE;
@@ -43,11 +45,10 @@ public class BinaryExporter {
     private final OutputStream ostream;
 
     private final byte[] barray;
-    private final ByteBuffer primbuf;
 
     private final TextExporter texporter_w31j;
     private final TextExporter texporter_u16le;
-    private final FeedableOutputStream xos;
+    private final ByteArrayOutputStream xos;
 
 
     /**
@@ -62,40 +63,20 @@ public class BinaryExporter {
         this.ostream = ostream;
 
         this.barray = new byte[BUFSZ_PRIM];
-        this.primbuf = ByteBuffer.wrap(this.barray);
-        this.primbuf.order(ByteOrder.LITTLE_ENDIAN);
-
-        this.primbuf.clear();
 
         this.texporter_w31j  = new TextExporter(CS_WIN31J);
         this.texporter_u16le = new TextExporter(CS_UTF16LE);
-        this.xos = new FeedableOutputStream();
-
-        return;
-    }
+        this.xos = new ByteArrayOutputStream();
 
-
-    /**
-     * バイトオーダーを設定する。
-     * @param order バイトオーダー
-     */
-    public void setOrder(ByteOrder order){
-        this.primbuf.order(order);
         return;
     }
 
-    /**
-     * 設定されたバイトオーダーを返す。
-     * @return 設定されたバイトオーダー
-     */
-    public ByteOrder getOrder(){
-        return this.primbuf.order();
-    }
 
     /**
      * 出力ストリームを閉じる。
      * @throws IOException 出力エラー
      */
+    @Override
     public void close() throws IOException{
         this.ostream.close();
         return;
@@ -104,12 +85,12 @@ public class BinaryExporter {
     /**
      * 出力をフラッシュする。
      * I/O効率とデバッグ効率のバランスを考え、ご利用は計画的に。
-     * @return this
      * @throws IOException 出力エラー
      */
-    public BinaryExporter flush() throws IOException{
+    @Override
+    public void flush() throws IOException{
         this.ostream.flush();
-        return this;
+        return;
     }
 
     /**
@@ -161,86 +142,111 @@ public class BinaryExporter {
     }
 
     /**
-     * 内部バッファの先頭を出力する。
-     * @param length 出力バイト数
-     * @throws IOException 出力エラー
-     */
-    private void dumpBuffer(int length) throws IOException{
-        this.ostream.write(this.barray, 0, length);
-        return;
-    }
-
-    /**
-     * short値を出力する。
+     * short値をリトルエンディアンで出力する。
      * @param sVal short値
      * @return this自身
      * @throws IOException 出力エラー
      */
     @SuppressWarnings("PMD.AvoidUsingShortType")
-    public BinaryExporter dumpShort(short sVal) throws IOException{
-        this.primbuf.putShort(0, sVal);
-        dumpBuffer(BYTES_SHORT);
+    public BinaryExporter dumpLeShort(short sVal) throws IOException{
+        this.barray[0] = (byte)( (sVal >>  0) & MASK_8 );
+        this.barray[1] = (byte)( (sVal >>  8) & MASK_8 );
+
+        this.ostream.write(this.barray, 0, BYTES_SHORT);
+
         return this;
     }
 
     /**
-     * short値を出力する。
+     * short値をリトルエンディアンで出力する。
      * @param iVal int値。上位16bitは捨てられる。
      * @return this自身
      * @throws IOException 出力エラー
      */
     @SuppressWarnings("PMD.AvoidUsingShortType")
-    public BinaryExporter dumpShort(int iVal) throws IOException{
+    public BinaryExporter dumpLeShort(int iVal) throws IOException{
         short sVal = (short)(iVal & MASK_16);
-        dumpShort(sVal);
+        dumpLeShort(sVal);
         return this;
     }
 
     /**
-     * int値を出力する。
+     * int値をリトルエンディアンで出力する。
      * @param iVal int値
      * @return this自身
      * @throws IOException 出力エラー
      */
-    public BinaryExporter dumpInt(int iVal) throws IOException{
-        this.primbuf.putInt(0, iVal);
-        dumpBuffer(BYTES_INT);
+    public BinaryExporter dumpLeInt(int iVal) throws IOException{
+        this.barray[0] = (byte)( (iVal >>  0) & MASK_8 );
+        this.barray[1] = (byte)( (iVal >>  8) & MASK_8 );
+        this.barray[2] = (byte)( (iVal >> 16) & MASK_8 );
+        this.barray[3] = (byte)( (iVal >> 24) & MASK_8 );
+
+        this.ostream.write(this.barray, 0, BYTES_INT);
+
         return this;
     }
 
     /**
-     * long値を出力する。
+     * long値をリトルエンディアンで出力する。
      * @param lVal long値
      * @return this自身
      * @throws IOException 出力エラー
      */
-    public BinaryExporter dumpLong(long lVal) throws IOException{
-        this.primbuf.putLong(0, lVal);
-        dumpBuffer(BYTES_LONG);
+    public BinaryExporter dumpLeLong(long lVal) throws IOException{
+        this.barray[0] = (byte)( (lVal >>  0) & 0xffL );
+        this.barray[1] = (byte)( (lVal >>  8) & 0xffL );
+        this.barray[2] = (byte)( (lVal >> 16) & 0xffL );
+        this.barray[3] = (byte)( (lVal >> 24) & 0xffL );
+        this.barray[4] = (byte)( (lVal >> 32) & 0xffL );
+        this.barray[5] = (byte)( (lVal >> 40) & 0xffL );
+        this.barray[6] = (byte)( (lVal >> 48) & 0xffL );
+        this.barray[7] = (byte)( (lVal >> 56) & 0xffL );
+
+        this.ostream.write(this.barray, 0, BYTES_LONG);
+
         return this;
     }
 
     /**
-     * float値を出力する。
+     * float値をリトルエンディアンで出力する。
      * @param fVal float値
      * @return this自身
      * @throws IOException 出力エラー
      */
-    public BinaryExporter dumpFloat(float fVal) throws IOException{
-        this.primbuf.putFloat(0, fVal);
-        dumpBuffer(BYTES_FLOAT);
+    public BinaryExporter dumpLeFloat(float fVal) throws IOException{
+        int rawiVal = Float.floatToRawIntBits(fVal);
+
+        this.barray[0] = (byte)( (rawiVal >>  0) & MASK_8 );
+        this.barray[1] = (byte)( (rawiVal >>  8) & MASK_8 );
+        this.barray[2] = (byte)( (rawiVal >> 16) & MASK_8 );
+        this.barray[3] = (byte)( (rawiVal >> 24) & MASK_8 );
+
+        this.ostream.write(this.barray, 0, BYTES_FLOAT);
+
         return this;
     }
 
     /**
-     * double値を出力する。
+     * double値をリトルエンディアンで出力する。
      * @param dVal double値
      * @return this自身
      * @throws IOException 出力エラー
      */
-    public BinaryExporter dumpDouble(double dVal) throws IOException{
-        this.primbuf.putDouble(0, dVal);
-        dumpBuffer(BYTES_DOUBLE);
+    public BinaryExporter dumpLeDouble(double dVal) throws IOException{
+        long rawlVal = Double.doubleToRawLongBits(dVal);
+
+        this.barray[0] = (byte)( (rawlVal >>  0) & MASK_8 );
+        this.barray[1] = (byte)( (rawlVal >>  8) & MASK_8 );
+        this.barray[2] = (byte)( (rawlVal >> 16) & MASK_8 );
+        this.barray[3] = (byte)( (rawlVal >> 24) & MASK_8 );
+        this.barray[4] = (byte)( (rawlVal >> 32) & MASK_8 );
+        this.barray[5] = (byte)( (rawlVal >> 40) & MASK_8 );
+        this.barray[6] = (byte)( (rawlVal >> 48) & MASK_8 );
+        this.barray[7] = (byte)( (rawlVal >> 56) & MASK_8 );
+
+        this.ostream.write(this.barray, 0, BYTES_DOUBLE);
+
         return this;
     }
 
@@ -307,7 +313,8 @@ public class BinaryExporter {
             throw new IllegalTextExportException(message);
         }
 
-        int xferred = this.xos.feedStored(this.ostream);
+        this.xos.writeTo(this.ostream);
+        int xferred = this.xos.size();
 
         int remain = fixedLength - xferred;
         if(remain > 0){
@@ -341,9 +348,10 @@ public class BinaryExporter {
             throw new IllegalTextExportException(ERRMSG_ILLENC, e);
         }
 
-        dumpInt(encodedSize);
+        dumpLeInt(encodedSize);
 
-        int xferred = this.xos.feedStored(this.ostream);
+        this.xos.writeTo(this.ostream);
+        int xferred = this.xos.size();
         assert xferred == encodedSize;
 
         return xferred;
diff --git a/src/main/java/jp/sourceforge/mikutoga/binio/FeedableOutputStream.java b/src/main/java/jp/sourceforge/mikutoga/binio/FeedableOutputStream.java
deleted file mode 100644 (file)
index 22bcc38..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * output stream with feedable byte array
- *
- * License : The MIT License
- * Copyright(c) 2011 MikuToga Partners
- */
-
-package jp.sourceforge.mikutoga.binio;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-
-/**
- * 蓄積された出力結果の他ストリームへの転送を可能とする
- * {@link java.io.ByteArrayOutputStream}。
- */
-public class FeedableOutputStream extends ByteArrayOutputStream {
-
-    /**
-     * コンストラクタ。
-     * @see java.io.ByteArrayOutputStream#ByteArrayOutputStream()
-     */
-    public FeedableOutputStream(){
-        super();
-        return;
-    }
-
-    /**
-     * コンストラクタ。
-     * @param size 初期バッファ長(byte単位)。
-     * @see java.io.ByteArrayOutputStream#ByteArrayOutputStream(int)
-     */
-    public FeedableOutputStream(int size){
-        super(size);
-        return;
-    }
-
-    /**
-     * 蓄積されたストリームデータを別ストリームへ転送する。
-     * <p>何も蓄積されていなければ何も転送されない。
-     * <p>蓄積されたストリームデータに変更は生じない。
-     * @param os 別ストリーム
-     * @return 転送量。
-     * @throws IOException 転送先の出力エラー
-     */
-    public int feedStored(OutputStream os) throws IOException {
-        if(this.count <= 0) return 0;
-        os.write(this.buf, 0, this.count);
-        return this.count;
-    }
-
-}
index e657dae..0e6ced2 100644 (file)
@@ -62,14 +62,4 @@ public class IllegalTextExportException extends Exception {
         return;
     }
 
-    /**
-     * 原因となったエンコーディング例外を返す。
-     * @return 原因となったエンコーディング例外。なければnull。
-     */
-    @Override
-    public CharacterCodingException getCause(){
-        Throwable superCause = super.getCause();
-        return (CharacterCodingException) superCause;
-    }
-
 }
index 7d54c7f..dc5a08e 100644 (file)
@@ -32,7 +32,7 @@ public class TextExporter {
     private final CharsetEncoder encoder;
     private CharBuffer cbuf = CharBuffer.allocate(DEFBUFSZ_CHAR);
     private byte[] barray = new byte[DEFBUFSZ_BYTE];
-    private ByteBuffer bbuf = ByteBuffer.wrap(barray);
+    private ByteBuffer bbuf = ByteBuffer.wrap(this.barray);
 
     private CharSequence textData;
     private int textLength;
@@ -87,27 +87,30 @@ public class TextExporter {
 
     /**
      * 出力内部バッファサイズを設定する。
+     * 最低限必要な出力バッファサイズはエンコード設定により異なる。
      * @param newSize バッファサイズ。(単位:byte)
-     * @throws IllegalArgumentException サイズ指定が正で無かった
+     * @throws IllegalArgumentException サイズ指定が小さすぎる
      */
     public void setByteBufSize(int newSize)
             throws IllegalArgumentException {
-        if(newSize <= 0) throw new IllegalArgumentException();
+        float ratio = this.encoder.maxBytesPerChar();
+        int minSz = (int)( StrictMath.floor(ratio) );
+        if(newSize < minSz) throw new IllegalArgumentException();
         this.barray = new byte[newSize];
-        this.bbuf = ByteBuffer.wrap(barray);
+        this.bbuf = ByteBuffer.wrap(this.barray);
         this.bbuf.clear();
         return;
     }
 
     /**
      * 与えられた文字列をエンコードしてストリームに出力する。
-     * @param os 出力ストリーム
      * @param text 文字列
+     * @param os 出力ストリーム
      * @return 出力バイト長
      * @throws IOException 出力エラー
      * @throws CharacterCodingException エンコードエラー
      */
-    public int dumpText(OutputStream os, CharSequence text)
+    public int dumpText(CharSequence text, OutputStream os)
             throws IOException, CharacterCodingException {
         this.textData = text;
 
@@ -139,15 +142,13 @@ public class TextExporter {
             CoderResult result = encode();
             if(result.isUnderflow()){
                 this.cbuf.clear();
-                if(hasMoreInput()){
-                    continue;
+                if( ! hasMoreInput() ){
+                    total += sweepByteBuffer(os);
+                    break;
                 }
-                total += sweepByteBuffer(os);
-                break;
             }else if(result.isOverflow()){
                 total += sweepByteBuffer(os);
                 this.cbuf.compact();
-                continue;
             }else if(result.isError()){
                 result.throwException();
             }
@@ -237,14 +238,14 @@ public class TextExporter {
             throws IOException, CharacterCodingException {
         int total = 0;
 
-        for(;;){
-            CoderResult result = this.encoder.flush(this.bbuf);
+        CoderResult result;
+        do{
+            result = this.encoder.flush(this.bbuf);
             if(result.isError()) result.throwException();
 
             total += sweepByteBuffer(os);
 
-            if(result.isUnderflow()) break;
-        }
+        }while( ! result.isUnderflow() );
 
         return total;
     }
@@ -263,7 +264,7 @@ public class TextExporter {
             throws CharacterCodingException {
         int result = 0;
         try{
-            result = dumpText(bos, text);
+            result = dumpText(text, bos);
         }catch(CharacterCodingException e){
             throw e;
         }catch(IOException e){
index 819a986..0c9dcce 100644 (file)
@@ -29,7 +29,11 @@ public class CommonParser {
     /** PMXで用いられる文字エンコーディング(UTF-16のリトルエンディアン)。 */
     public static final Charset CS_UTF16LE = Charset.forName("UTF-16LE");
 
-    private final MmdSource source;
+    private static final int MASK_8BIT  =   0xff;
+    private static final int MASK_16BIT = 0xffff;
+
+
+    private final MmdInputStream is;
 
     private final TextDecoder decoderWin31j  = new TextDecoder(CS_WIN31J);
     private final TextDecoder decoderUTF8    = new TextDecoder(CS_UTF8);
@@ -39,10 +43,10 @@ public class CommonParser {
      * コンストラクタ。
      * @param source 入力ソース
      */
-    public CommonParser(MmdSource source){
+    public CommonParser(MmdInputStream source){
         super();
 
-        this.source = source;
+        this.is = source;
 
         this.decoderWin31j .setZeroChopMode(true);
         this.decoderUTF8   .setZeroChopMode(false);
@@ -55,8 +59,8 @@ public class CommonParser {
      * 入力ソースを返す。
      * @return 入力ソース
      */
-    protected MmdSource getSource(){
-        return this.source;
+    protected MmdInputStream getSource(){
+        return this.is;
     }
 
     /**
@@ -64,7 +68,7 @@ public class CommonParser {
      * @return 入力ソースの読み込み位置。単位はbyte。
      */
     protected long getPosition(){
-        long result = this.source.getPosition();
+        long result = this.is.getPosition();
         return result;
     }
 
@@ -72,10 +76,10 @@ public class CommonParser {
      * 入力ソースにまだデータが残っているか判定する。
      * @return まだ読み込んでいないデータが残っていればtrue
      * @throws IOException IOエラー
-     * @see MmdSource#hasMore()
+     * @see MmdInputStream#hasMore()
      */
     protected boolean hasMore() throws IOException{
-        boolean result = this.source.hasMore();
+        boolean result = this.is.hasMore();
         return result;
     }
 
@@ -84,13 +88,13 @@ public class CommonParser {
      * @param skipLength 読み飛ばすバイト数。
      * @throws IOException IOエラー
      * @throws MmdEofException 読み飛ばす途中でストリーム終端に達した。
-     * @see MmdSource#skip(long)
+     * @see MmdInputStream#skip(long)
      */
     protected void skip(long skipLength)
             throws IOException, MmdEofException {
-        long result = this.source.skip(skipLength);
+        long result = this.is.skipRepeat(skipLength);
         if(result != skipLength){
-            throw new MmdEofException(this.source.getPosition());
+            throw new MmdEofException(this.is.getPosition());
         }
 
         return;
@@ -101,7 +105,7 @@ public class CommonParser {
      * @param skipLength 読み飛ばすバイト数。
      * @throws IOException IOエラー
      * @throws MmdEofException 読み飛ばす途中でストリーム終端に達した。
-     * @see MmdSource#skip(long)
+     * @see MmdInputStream#skip(long)
      */
     protected void skip(int skipLength)
             throws IOException, MmdEofException {
@@ -113,11 +117,11 @@ public class CommonParser {
      * @return 読み込んだbyte値
      * @throws IOException IOエラー
      * @throws MmdEofException 読み込む途中でストリーム終端に達した。
-     * @see MmdSource#parseByte()
+     * @see MmdInputStream#parseByte()
      */
     protected byte parseByte()
             throws IOException, MmdEofException{
-        return this.source.parseByte();
+        return this.is.parseByte();
     }
 
     /**
@@ -126,11 +130,11 @@ public class CommonParser {
      * @return 読み込まれた値のint値
      * @throws IOException IOエラー
      * @throws MmdEofException 読み込む途中でストリーム終端に達した。
-     * @see MmdSource#parseUByteAsInteger()
+     * @see MmdInputStream#parseUByteAsInt()
      */
-    protected int parseUByteAsInteger()
+    protected int parseUByteAsInt()
             throws IOException, MmdEofException{
-        return this.source.parseUByteAsInteger();
+        return ((int) parseByte()) & MASK_8BIT;
     }
 
     /**
@@ -139,11 +143,11 @@ public class CommonParser {
      * @return 読み込まれた値のboolean値
      * @throws IOException IOエラー
      * @throws MmdEofException 読み込む途中でストリーム終端に達した。
-     * @see MmdSource#parseBoolean()
+     * @see MmdInputStream#parseBoolean()
      */
     protected boolean parseBoolean()
             throws IOException, MmdEofException{
-        return this.source.parseBoolean();
+        return this.is.parseBoolean();
     }
 
     /**
@@ -152,11 +156,11 @@ public class CommonParser {
      * @return 読み込んだshort値
      * @throws IOException IOエラー
      * @throws MmdEofException 読み込む途中でストリーム終端に達した。
-     * @see MmdSource#parseShort()
+     * @see MmdInputStream#parseShort()
      */
-    protected short parseShort()
+    protected short parseLeShort()
             throws IOException, MmdEofException{
-        return this.source.parseShort();
+        return this.is.parseLeShort();
     }
 
     /**
@@ -166,11 +170,11 @@ public class CommonParser {
      * @return 読み込まれた値のint値
      * @throws IOException IOエラー
      * @throws MmdEofException 読み込む途中でストリーム終端に達した。
-     * @see MmdSource#parseUShortAsInteger()
+     * @see MmdInputStream#parseUShortAsInteger()
      */
-    protected int parseUShortAsInteger()
+    protected int parseLeUShortAsInt()
             throws IOException, MmdEofException{
-        return this.source.parseUShortAsInteger();
+        return ((int) parseLeShort()) & MASK_16BIT;
     }
 
     /**
@@ -179,11 +183,11 @@ public class CommonParser {
      * @return 読み込んだint値
      * @throws IOException IOエラー
      * @throws MmdEofException 読み込む途中でストリーム終端に達した。
-     * @see MmdSource#parseInteger()
+     * @see MmdInputStream#parseInteger()
      */
-    protected int parseInteger()
+    protected int parseLeInt()
             throws IOException, MmdEofException{
-        return this.source.parseInteger();
+        return this.is.parseLeInt();
     }
 
     /**
@@ -192,11 +196,11 @@ public class CommonParser {
      * @return 読み込んだfloat値
      * @throws IOException IOエラー
      * @throws MmdEofException 読み込む途中でストリーム終端に達した。
-     * @see MmdSource#parseFloat()
+     * @see MmdInputStream#parseFloat()
      */
-    protected float parseFloat()
+    protected float parseLeFloat()
             throws IOException, MmdEofException{
-        return this.source.parseFloat();
+        return this.is.parseLeFloat();
     }
 
     /**
@@ -208,14 +212,18 @@ public class CommonParser {
      * @throws NullPointerException 配列がnull
      * @throws IndexOutOfBoundsException 引数が配列属性と矛盾
      * @throws MmdEofException 読み込む途中でストリーム終端に達した。
-     * @see MmdSource#parseByteArray(byte[], int, int)
+     * @see MmdInputStream#parseByteArray(byte[], int, int)
      */
     protected void parseByteArray(byte[] dst, int offset, int length)
             throws IOException,
                    NullPointerException,
                    IndexOutOfBoundsException,
                    MmdEofException {
-        this.source.parseByteArray(dst, offset, length);
+        int readSize = this.is.read(dst, offset, length);
+        if(readSize != length){
+            throw new MmdEofException(this.is.getPosition());
+        }
+
         return;
     }
 
@@ -226,46 +234,11 @@ public class CommonParser {
      * @throws IOException IOエラー
      * @throws NullPointerException 配列がnull
      * @throws MmdEofException 読み込む途中でストリーム終端に達した。
-     * @see MmdSource#parseByteArray(byte[])
+     * @see MmdInputStream#parseByteArray(byte[])
      */
     protected void parseByteArray(byte[] dst)
             throws IOException, NullPointerException, MmdEofException{
-        this.source.parseByteArray(dst);
-        return;
-    }
-
-    /**
-     * float配列を読み込む。
-     * @param dst 格納先配列
-     * @param offset 読み込み開始オフセット
-     * @param length 読み込みfloat要素数
-     * @throws IOException IOエラー
-     * @throws NullPointerException 配列がnull
-     * @throws IndexOutOfBoundsException 引数が配列属性と矛盾
-     * @throws MmdEofException 読み込む途中でストリーム終端に達した。
-     * @see MmdSource#parseFloatArray(float[], int, int)
-     */
-    protected void parseFloatArray(float[] dst, int offset, int length)
-            throws IOException,
-                   NullPointerException,
-                   IndexOutOfBoundsException,
-                   MmdEofException {
-        this.source.parseFloatArray(dst, offset, length);
-        return;
-    }
-
-    /**
-     * float配列を読み込む。
-     * 配列要素全ての読み込みが試みられる。
-     * @param dst 格納先配列
-     * @throws IOException IOエラー
-     * @throws NullPointerException 配列がnull
-     * @throws MmdEofException 読み込む途中でストリーム終端に達した。
-     * @see MmdSource#parseFloatArray(float[])
-     */
-    protected void parseFloatArray(float[] dst)
-            throws IOException, NullPointerException, MmdEofException{
-        this.source.parseFloatArray(dst);
+        parseByteArray(dst, 0, dst.length);
         return;
     }
 
@@ -287,7 +260,7 @@ public class CommonParser {
                    MmdEofException,
                    MmdFormatException {
         CharBuffer encoded =
-                this.decoderWin31j.parseString(this.source, maxlen);
+                this.decoderWin31j.parseString(this.is, maxlen);
 
         String result = encoded.toString();
 
@@ -306,10 +279,10 @@ public class CommonParser {
             throws IOException,
                    MmdEofException,
                    MmdFormatException {
-        int byteLen = this.source.parseInteger();
+        int byteLen = this.is.parseLeInt();
 
         CharBuffer encoded =
-                this.decoderUTF8.parseString(this.source, byteLen);
+                this.decoderUTF8.parseString(this.is, byteLen);
 
         String result = encoded.toString();
 
@@ -328,10 +301,10 @@ public class CommonParser {
             throws IOException,
                    MmdEofException,
                    MmdFormatException {
-        int byteLen = this.source.parseInteger();
+        int byteLen = this.is.parseLeInt();
 
         CharBuffer encoded =
-                this.decoderUTF16LE.parseString(this.source, byteLen);
+                this.decoderUTF16LE.parseString(this.is, byteLen);
 
         String result = encoded.toString();
 
diff --git a/src/main/java/jp/sourceforge/mikutoga/parser/MmdInputStream.java b/src/main/java/jp/sourceforge/mikutoga/parser/MmdInputStream.java
new file mode 100644 (file)
index 0000000..0082516
--- /dev/null
@@ -0,0 +1,234 @@
+/*
+ * MMD file input stream
+ *
+ * License : The MIT License
+ * Copyright(c) 2012 MikuToga Partners
+ */
+
+package jp.sourceforge.mikutoga.parser;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+/**
+ * MMD各種バイナリデータ用の入力ストリーム。
+ * リトルエンディアンデータおよびEOFの扱い方で
+ * java.io.DataInputStreamと差別化される。
+ */
+public class MmdInputStream extends SpottedInputStream {
+
+    private static final int BYTES_SHORT = Short  .SIZE / Byte.SIZE;
+    private static final int BYTES_INT   = Integer.SIZE / Byte.SIZE;
+    private static final int BYTES_FLOAT = Float  .SIZE / Byte.SIZE;
+    private static final int BUF_SZ = 4;
+
+
+    private final byte[] readArray;
+    private final ByteBuffer beBuf;
+    private final ByteBuffer leBuf;
+
+
+    /**
+     * コンストラクタ。
+     * @param is 入力ストリーム
+     */
+    public MmdInputStream(InputStream is){
+        super(is);
+
+        this.readArray = new byte[BUF_SZ];
+
+        this.beBuf = ByteBuffer.wrap(this.readArray);
+        this.leBuf = ByteBuffer.wrap(this.readArray);
+
+        this.beBuf.order(ByteOrder.BIG_ENDIAN);
+        this.leBuf.order(ByteOrder.LITTLE_ENDIAN);
+
+        return;
+    }
+
+
+    /**
+     * 入力ストリームを読み飛ばす。
+     * なるべく指定したバイト数全てが読み飛ばされるよう、
+     * 読み飛ばし処理が繰り返される。
+     * @param skipLength 読み飛ばすバイト数。
+     * @return 実際に読み飛ばしたバイト数。
+     * @throws IOException IOエラー
+     * @see java.io.InputStream#skip(long)
+     */
+    public long skipRepeat(long skipLength)
+            throws IOException{
+        if(skipLength <= 0L) return 0L;
+
+        long remain = skipLength;
+        while(remain > 0L){      // BufferedInputStream対策
+            long result = skip(remain);
+            if(result <= 0L) break;
+            remain -= result;
+        }
+
+        return skipLength - remain;
+    }
+
+    /**
+     * 指定したバイト数だけ内部バッファに読み込む。
+     * @param fillSize 読み込むバイト数
+     * @throws IOException IOエラー
+     * @throws IndexOutOfBoundsException 引数がバッファサイズと矛盾。
+     * @throws MmdEofException 読み込む途中でストリーム終端に達した。
+     */
+    private void fillBuffer(int fillSize)
+            throws IOException, IndexOutOfBoundsException, MmdEofException{
+        int result = read(this.readArray, 0, fillSize);
+
+        if(result != fillSize){
+            long pos = getPosition();
+            throw new MmdEofException(pos);
+        }
+
+        return;
+    }
+
+    /**
+     * byte値を読み込む。
+     * @return 読み込んだbyte値
+     * @throws IOException IOエラー
+     * @throws MmdEofException 読み込む途中でストリーム終端に達した。
+     */
+    public byte parseByte() throws IOException, MmdEofException{
+        int bData = read();
+        if(bData < 0){
+            long pos = getPosition();
+            throw new MmdEofException(pos);
+        }
+
+        byte result = (byte) bData;
+        return result;
+    }
+
+    /**
+     * byte値を読み込み、boolean型に変換して返す。
+     * 0x00は偽、それ以外は真と解釈される。
+     * @return 読み込まれた値のboolean値
+     * @throws IOException IOエラー
+     * @throws MmdEofException 読み込む途中でストリーム終端に達した。
+     */
+    public boolean parseBoolean() throws IOException, MmdEofException{
+        byte result = parseByte();
+        if(result == 0x00) return false;
+        return true;
+    }
+
+    /**
+     * short値を読み込む。
+     * @param buf オーダー指定されたバッファ
+     * @return short値
+     * @throws IOException 入力エラー
+     * @throws MmdEofException 途中でストリーム終端に達した。
+     */
+    private short parseShort(ByteBuffer buf)
+            throws IOException, MmdEofException{
+        fillBuffer(BYTES_SHORT);
+        short result = buf.getShort(0);
+
+        return result;
+    }
+
+    /**
+     * ビッグエンディアンでshort値を読み込む。
+     * @return short値
+     * @throws IOException 入力エラー
+     * @throws MmdEofException 途中でストリーム終端に達した。
+     */
+    public short parseBeShort() throws IOException, MmdEofException{
+        short result = parseShort(this.beBuf);
+        return result;
+    }
+
+    /**
+     * リトルエンディアンでshort値を読み込む。
+     * @return short値
+     * @throws IOException 入力エラー
+     * @throws MmdEofException 途中でストリーム終端に達した。
+     */
+    public short parseLeShort() throws IOException, MmdEofException{
+        short result = parseShort(this.leBuf);
+        return result;
+    }
+
+    /**
+     * int値を読み込む。
+     * @param buf オーダー指定されたバッファ
+     * @return int値
+     * @throws IOException 入力エラー
+     * @throws MmdEofException 途中でストリーム終端に達した。
+     */
+    private int parseInt(ByteBuffer buf)
+            throws IOException, MmdEofException{
+        fillBuffer(BYTES_INT);
+        int result = buf.getInt(0);
+
+        return result;
+    }
+
+    /**
+     * ビッグエンディアンでint値を読み込む。
+     * @return int値
+     * @throws IOException 入力エラー
+     * @throws MmdEofException 途中でストリーム終端に達した。
+     */
+    public int parseBeInt() throws IOException, MmdEofException{
+        int result = parseInt(this.beBuf);
+        return result;
+    }
+
+    /**
+     * リトルエンディアンでint値を読み込む。
+     * @return int値
+     * @throws IOException 入力エラー
+     * @throws MmdEofException 途中でストリーム終端に達した。
+     */
+    public int parseLeInt() throws IOException, MmdEofException{
+        int result = parseInt(this.leBuf);
+        return result;
+    }
+
+    /**
+     * float値を読み込む。
+     * @param buf オーダー指定されたバッファ
+     * @return float値
+     * @throws IOException 入力エラー
+     * @throws MmdEofException 途中でストリーム終端に達した。
+     */
+    private float parseFloat(ByteBuffer buf)
+            throws IOException, MmdEofException{
+        fillBuffer(BYTES_FLOAT);
+        float result = buf.getFloat(0);
+        return result;
+    }
+
+    /**
+     * ビッグエンディアンでfloat値を読み込む。
+     * @return float値
+     * @throws IOException 入力エラー
+     * @throws MmdEofException 途中でストリーム終端に達した。
+     */
+    public float parseBeFloat() throws IOException, MmdEofException{
+        float result = parseFloat(this.beBuf);
+        return result;
+    }
+
+    /**
+     * リトルエンディアンでfloat値を読み込む。
+     * @return float値
+     * @throws IOException 入力エラー
+     * @throws MmdEofException 途中でストリーム終端に達した。
+     */
+    public float parseLeFloat() throws IOException, MmdEofException{
+        float result = parseFloat(this.leBuf);
+        return result;
+    }
+
+}
diff --git a/src/main/java/jp/sourceforge/mikutoga/parser/MmdSource.java b/src/main/java/jp/sourceforge/mikutoga/parser/MmdSource.java
deleted file mode 100644 (file)
index cb44f4d..0000000
+++ /dev/null
@@ -1,329 +0,0 @@
-/*
- * MMD file input source
- *
- * License : The MIT License
- * Copyright(c) 2010 MikuToga Partners
- */
-
-package jp.sourceforge.mikutoga.parser;
-
-import java.io.Closeable;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.PushbackInputStream;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-
-/**
- * MMD各種ファイルの入力ソース。
- * 入力ソース終端の判定が可能。
- * パースエラー発生位置(バイト単位)の取得が可能。
- * リトルエンディアン形式で格納された各種プリミティブ型値の解決を行う。
- */
-public class MmdSource implements Closeable {
-
-    private static final int BYTES_SHORT = Short  .SIZE / Byte.SIZE;
-    private static final int BYTES_INT   = Integer.SIZE / Byte.SIZE;
-    private static final int BYTES_FLOAT = Float  .SIZE / Byte.SIZE;
-    private static final int BUF_SZ = 4;
-
-    private static final int MASK_8BIT = 0xff;
-    private static final int MASK_16BIT = 0xffff;
-
-    static{
-        assert BUF_SZ >= BYTES_SHORT;
-        assert BUF_SZ >= BYTES_INT;
-        assert BUF_SZ >= BYTES_FLOAT;
-    }
-
-    private final PushbackInputStream istream;
-    private final byte[] readArray;       // 読み込みバッファ
-    private final ByteBuffer readBuffer;  // 読み込みバッファの別ビュー
-    private long position;                // 読み込み位置
-
-    /**
-     * コンストラクタ。
-     * @param is 入力ストリーム。
-     * I/O効率が考慮されたバッファリングを行うストリームを渡すのが望ましい。
-     * @throws NullPointerException ストリーム引数がnull。
-     */
-    public MmdSource(InputStream is)
-            throws NullPointerException {
-        super();
-
-        if(is == null) throw new NullPointerException();
-
-        // 読み戻しバッファは1byte確保
-        this.istream = new PushbackInputStream(is);
-
-        this.readArray = new byte[BUF_SZ];
-        this.readBuffer = ByteBuffer.wrap(this.readArray);
-        this.readBuffer.order(ByteOrder.LITTLE_ENDIAN);
-        this.readBuffer.clear();
-
-        this.position = 0L;
-
-        return;
-    }
-
-    /**
-     * 今までに読み込みに成功したバイト数を返す。
-     * @return 読み込みに成功したバイト数。
-     */
-    public long getPosition(){
-        return this.position;
-    }
-
-    /**
-     * 入力ソースを読み飛ばす。
-     * 入力ソースがディスクファイルに由来する場合、
-     * 空読みするより早くなるかも。
-     * @param skipLength 読み飛ばすバイト数。
-     * @return 実際に読み飛ばしたバイト数。
-     * @throws IOException IOエラー
-     * @see java.io.InputStream#skip(long)
-     */
-    public long skip(long skipLength)
-            throws IOException{
-        if(skipLength <= 0L) return 0L;
-
-        long remain = skipLength;
-        while(remain > 0L){      // BufferedInputStream対策
-            long result = this.istream.skip(remain);
-            if(result <= 0L) break;
-            this.position += result;
-            remain -= result;
-        }
-
-        return skipLength - remain;
-    }
-
-    /**
-     * 入力ソースにまだデータが残っているか判定する。
-     * @return まだ読み込んでいないデータが残っていればtrue
-     * @throws IOException IOエラー
-     */
-    public boolean hasMore() throws IOException{
-        int bData = this.istream.read();
-        if(bData < 0){
-            return false;
-        }
-
-        this.istream.unread(bData);
-
-        return true;
-    }
-
-    /**
-     * 入力ソースを閉じる。
-     * 読み込み済みバイト数の情報は保持される。
-     * @throws IOException IOエラー
-     * @see java.io.InputStream#close()
-     */
-    @Override
-    public void close() throws IOException{
-        this.istream.close();
-        this.readBuffer.clear();
-        return;
-    }
-
-    /**
-     * 指定したバイト数だけ内部バッファに読み込む。
-     * @param fillSize 読み込むバイト数
-     * @throws IOException IOエラー
-     * @throws IndexOutOfBoundsException 引数がバッファサイズと矛盾。
-     * @throws MmdEofException 読み込む途中でストリーム終端に達した。
-     */
-    protected void fillBuffer(int fillSize)
-            throws IOException, IndexOutOfBoundsException, MmdEofException{
-        int result = this.istream.read(this.readArray, 0, fillSize);
-        if(result >= 0){
-            this.position += result;
-        }
-
-        if(result != fillSize){
-            throw new MmdEofException(this.position);
-        }
-
-        this.readBuffer.rewind();
-
-        return;
-    }
-
-    /**
-     * byte値を読み込む。
-     * @return 読み込んだbyte値
-     * @throws IOException IOエラー
-     * @throws MmdEofException 読み込む途中でストリーム終端に達した。
-     */
-    public byte parseByte() throws IOException, MmdEofException{
-        int bData = this.istream.read();
-        if(bData < 0){
-            throw new MmdEofException(this.position);
-        }else{
-            this.position++;
-        }
-
-        byte result = (byte) bData;
-        return result;
-    }
-
-    /**
-     * 符号無し値としてbyte値を読み込み、int型に変換して返す。
-     * 符号は拡張されない。(0xffは0x000000ffとなる)
-     * @return 読み込まれた値のint値
-     * @throws IOException IOエラー
-     * @throws MmdEofException 読み込む途中でストリーム終端に達した。
-     */
-    public int parseUByteAsInteger()
-            throws IOException, MmdEofException{
-        return ((int) parseByte()) & MASK_8BIT;
-    }
-
-    /**
-     * byte値を読み込み、boolean型に変換して返す。
-     * 0x00は偽、それ以外は真と解釈される。
-     * @return 読み込まれた値のboolean値
-     * @throws IOException IOエラー
-     * @throws MmdEofException 読み込む途中でストリーム終端に達した。
-     */
-    public boolean parseBoolean() throws IOException, MmdEofException{
-        byte result = parseByte();
-        if(result == 0x00) return false;
-        return true;
-    }
-
-    /**
-     * short値を読み込む。
-     * short値はリトルエンディアンで格納されていると仮定される。
-     * @return 読み込んだshort値
-     * @throws IOException IOエラー
-     * @throws MmdEofException 読み込む途中でストリーム終端に達した。
-     */
-    public short parseShort() throws IOException, MmdEofException{
-        fillBuffer(BYTES_SHORT);
-        short result = this.readBuffer.getShort();
-        return result;
-    }
-
-    /**
-     * 符号無し値としてshort値を読み込み、int型に変換して返す。
-     * 符号は拡張されない。(0xffffは0x0000ffffとなる)
-     * short値はリトルエンディアンで格納されていると仮定される。
-     * @return 読み込まれた値のint値
-     * @throws IOException IOエラー
-     * @throws MmdEofException 読み込む途中でストリーム終端に達した。
-     */
-    public int parseUShortAsInteger()
-            throws IOException, MmdEofException{
-        return ((int) parseShort()) & MASK_16BIT;
-    }
-
-    /**
-     * int値を読み込む。
-     * int値はリトルエンディアンで格納されていると仮定される。
-     * @return 読み込んだint値
-     * @throws IOException IOエラー
-     * @throws MmdEofException 読み込む途中でストリーム終端に達した。
-     */
-    public int parseInteger() throws IOException, MmdEofException{
-        fillBuffer(BYTES_INT);
-        int result = this.readBuffer.getInt();
-        return result;
-    }
-
-    /**
-     * float値を読み込む。
-     * float値はリトルエンディアンで格納されていると仮定される。
-     * @return 読み込んだfloat値
-     * @throws IOException IOエラー
-     * @throws MmdEofException 読み込む途中でストリーム終端に達した。
-     */
-    public float parseFloat() throws IOException, MmdEofException{
-        fillBuffer(BYTES_FLOAT);
-        float result = this.readBuffer.getFloat();
-        return result;
-    }
-
-    /**
-     * byte配列を読み込む。
-     * @param dst 格納先配列
-     * @param offset 読み込み開始オフセット
-     * @param length 読み込みバイト数
-     * @throws IOException IOエラー
-     * @throws NullPointerException 配列がnull
-     * @throws IndexOutOfBoundsException 引数が配列属性と矛盾
-     * @throws MmdEofException 読み込む途中でストリーム終端に達した。
-     * @see java.io.InputStream#read(byte[], int, int)
-     */
-    public void parseByteArray(byte[] dst, int offset, int length)
-            throws IOException,
-                   NullPointerException,
-                   IndexOutOfBoundsException,
-                   MmdEofException {
-        int result = this.istream.read(dst, offset, length);
-        if(result >= 0){
-            this.position += result;
-        }
-
-        if(result != length){
-            throw new MmdEofException(this.position);
-        }
-
-        return;
-    }
-
-    /**
-     * byte配列を読み込む。
-     * @param dst 格納先配列
-     * @throws IOException IOエラー
-     * @throws NullPointerException 配列がnull
-     * @throws MmdEofException 読み込む途中でストリーム終端に達した。
-     */
-    public void parseByteArray(byte[] dst)
-            throws IOException, NullPointerException, MmdEofException{
-        parseByteArray(dst, 0, dst.length);
-        return;
-    }
-
-    /**
-     * float配列を読み込む。
-     * @param dst 格納先配列
-     * @param offset 読み込み開始オフセット
-     * @param length 読み込みfloat要素数
-     * @throws IOException IOエラー
-     * @throws NullPointerException 配列がnull
-     * @throws IndexOutOfBoundsException 引数が配列属性と矛盾
-     * @throws MmdEofException 読み込む途中でストリーム終端に達した。
-     */
-    public void parseFloatArray(float[] dst, int offset, int length)
-            throws IOException,
-                   NullPointerException,
-                   IndexOutOfBoundsException,
-                   MmdEofException {
-        if(offset < 0 || length < 0 || dst.length - offset < length){
-            throw new IndexOutOfBoundsException();
-        }
-
-        for(int idx = 0; idx < length; idx++){
-            dst[offset+idx] = parseFloat();
-        }
-
-        return;
-    }
-
-    /**
-     * float配列を読み込む。
-     * @param dst 格納先配列
-     * @throws IOException IOエラー
-     * @throws NullPointerException 配列がnull
-     * @throws MmdEofException 読み込む途中でストリーム終端に達した。
-     */
-    public void parseFloatArray(float[] dst)
-            throws IOException, NullPointerException, MmdEofException{
-        parseFloatArray(dst, 0, dst.length);
-        return;
-    }
-
-    // TODO ビッグエンディアン対応が今後必要になる状況はありうるか?
-}
diff --git a/src/main/java/jp/sourceforge/mikutoga/parser/SpottedInputStream.java b/src/main/java/jp/sourceforge/mikutoga/parser/SpottedInputStream.java
new file mode 100644 (file)
index 0000000..8933584
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ * position spotted input stream
+ *
+ * License : The MIT License
+ * Copyright(c) 2012 MikuToga Partners
+ */
+
+package jp.sourceforge.mikutoga.parser;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PushbackInputStream;
+
+/**
+ * エラー報告用のバイト位置管理、
+ * およびストリーム末端の判定
+ * のための機能を含む入力ストリーム。
+ */
+class SpottedInputStream extends InputStream {
+
+    private final PushbackInputStream pin;
+    private long position = 0L;
+
+
+    /**
+     * コンストラクタ。
+     * @param is 入力ストリーム
+     */
+    SpottedInputStream(InputStream is){
+        super();
+        this.pin = new PushbackInputStream(is, 1);
+        return;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     * @return {@inheritDoc}
+     * @throws IOException {@inheritDoc}
+     */
+    @Override
+    public int read() throws IOException{
+        int result = this.pin.read();
+        if(result >= 0) this.position++;
+        return result;
+    }
+
+    /**
+     * {@inheritDoc}
+     * @param b {@inheritDoc}
+     * @return {@inheritDoc}
+     * @throws IOException {@inheritDoc}
+     */
+    @Override
+    public int read(byte[] b) throws IOException{
+        int result = this.pin.read(b);
+        if(result >= 0) this.position += result;
+        return result;
+    }
+
+    /**
+     * {@inheritDoc}
+     * @param b {@inheritDoc}
+     * @param off {@inheritDoc}
+     * @param len {@inheritDoc}
+     * @return {@inheritDoc}
+     * @throws IOException {@inheritDoc}
+     */
+    @Override
+    public int read(byte[] b, int off, int len) throws IOException{
+        int result = this.pin.read(b, off, len);
+        if(result >= 0) this.position += result;
+        return result;
+    }
+
+    /**
+     * {@inheritDoc}
+     * @param skipLength {@inheritDoc}
+     * @return {@inheritDoc}
+     * @throws IOException {@inheritDoc}
+     */
+    @Override
+    public long skip(long skipLength) throws IOException{
+        long result = this.pin.skip(skipLength);
+        if(result >= 0L) this.position += result;
+        return result;
+    }
+
+    /**
+     * {@inheritDoc}
+     * @throws IOException {@inheritDoc}
+     */
+    @Override
+    public void close() throws IOException{
+        this.pin.close();
+        return;
+    }
+
+    /**
+     * 読み込み済みバイト数を返す。
+     * @return 読み込み済みバイト数
+     */
+    public long getPosition(){
+        return this.position;
+    }
+
+    /**
+     * まだ入力が残っているか判定する。
+     * @return 残っていればtrue
+     * @throws IOException 入力エラー。java.io.EOFException ではないはず。
+     */
+    public boolean hasMore() throws IOException{
+        int bVal;
+
+        try{
+            bVal = this.pin.read();
+        }catch(EOFException e){ // ありえない?
+            return false;
+        }
+
+        if(bVal < 0){
+            return false;
+        }
+
+        this.pin.unread(bVal);
+
+        return true;
+    }
+
+}
index 879cb93..1a8044a 100644 (file)
@@ -133,7 +133,7 @@ public class TextDecoder {
 
     /**
      * バイト列を読み込み文字列へデコーディングする。
-     * @param source 入力ソース
+     * @param is 入力ストリーム
      * @param byteSize 読み込みバイトサイズ
      * @return 内部に保持されるデコード結果。
      * 次回呼び出しまでに結果の適切なコピーがなされなければならない。
@@ -142,11 +142,15 @@ public class TextDecoder {
      * もしくは未定義文字
      * @throws IOException 入力エラー
      */
-    public CharBuffer parseString(MmdSource source, int byteSize)
+    public CharBuffer parseString(MmdInputStream is, int byteSize)
             throws MmdEofException, MmdFormatException, IOException{
         prepareBuffer(byteSize);
 
-        source.parseByteArray(this.byteArray, 0, byteSize);
+        int readSize = is.read(this.byteArray, 0, byteSize);
+        if(readSize != byteSize){
+            throw new MmdEofException(is.getPosition());
+        }
+
         this.byteBuffer.rewind().limit(byteSize);
         chopZeroTermed();
 
@@ -158,10 +162,10 @@ public class TextDecoder {
         if(decResult.isError()){
             if(decResult.isUnmappable()){
                 throw new MmdFormatException("unmapped character",
-                                             source.getPosition() );
+                                             is.getPosition() );
             }else{
                 throw new MmdFormatException("illegal character encoding",
-                                             source.getPosition() );
+                                             is.getPosition() );
             }
         }else if(decResult.isOverflow()){
             assert false;
index 423f4f6..d67fa99 100644 (file)
@@ -7,7 +7,7 @@
 
 package jp.sourceforge.mikutoga.pmd.parser;
 
-import jp.sourceforge.mikutoga.parser.MmdSource;
+import jp.sourceforge.mikutoga.parser.MmdInputStream;
 
 /**
  * PMDモデルファイルのパーサ最新版。
@@ -21,7 +21,7 @@ public class PmdParser extends PmdParserExt3{
      * コンストラクタ。
      * @param source 入力ソース
      */
-    public PmdParser(MmdSource source){
+    public PmdParser(MmdInputStream source){
         super(source);
         return;
     }
index e545ffe..54f69ac 100644 (file)
@@ -10,7 +10,7 @@ package jp.sourceforge.mikutoga.pmd.parser;
 import java.io.IOException;
 import jp.sourceforge.mikutoga.parser.CommonParser;
 import jp.sourceforge.mikutoga.parser.MmdFormatException;
-import jp.sourceforge.mikutoga.parser.MmdSource;
+import jp.sourceforge.mikutoga.parser.MmdInputStream;
 
 /**
  * PMDモデルファイルのパーサ基本部。
@@ -61,7 +61,7 @@ public class PmdParserBase extends CommonParser {
      * コンストラクタ。
      * @param source 入力ソース
      */
-    public PmdParserBase(MmdSource source){
+    public PmdParserBase(MmdInputStream source){
         super(source);
         return;
     }
@@ -260,7 +260,7 @@ public class PmdParserBase extends CommonParser {
      * @throws MmdFormatException フォーマットエラー
      */
     private void parseVertexList() throws IOException, MmdFormatException{
-        int vertexNum = parseInteger();
+        int vertexNum = parseLeInt();
 
         if(this.shapeHandler == null){
             skip(VERTEX_DATA_SZ * vertexNum);
@@ -270,23 +270,23 @@ public class PmdParserBase extends CommonParser {
         this.shapeHandler.loopStart(PmdShapeHandler.VERTEX_LIST, vertexNum);
 
         for(int ct = 0; ct < vertexNum; ct++){
-            float xPos = parseFloat();
-            float yPos = parseFloat();
-            float zPos = parseFloat();
+            float xPos = parseLeFloat();
+            float yPos = parseLeFloat();
+            float zPos = parseLeFloat();
             this.shapeHandler.pmdVertexPosition(xPos, yPos, zPos);
 
-            float xVec = parseFloat();
-            float yVec = parseFloat();
-            float zVec = parseFloat();
+            float xVec = parseLeFloat();
+            float yVec = parseLeFloat();
+            float zVec = parseLeFloat();
             this.shapeHandler.pmdVertexNormal(xVec, yVec, zVec);
 
-            float uVal = parseFloat();
-            float vVal = parseFloat();
+            float uVal = parseLeFloat();
+            float vVal = parseLeFloat();
             this.shapeHandler.pmdVertexUV(uVal, vVal);
 
-            int boneId1 = parseUShortAsInteger();
-            int boneId2 = parseUShortAsInteger();
-            int weightForB1 = parseUByteAsInteger();
+            int boneId1 = parseLeUShortAsInt();
+            int boneId2 = parseLeUShortAsInt();
+            int weightForB1 = parseUByteAsInt();
             this.shapeHandler.pmdVertexWeight(boneId1, boneId2, weightForB1);
 
             boolean hideEdge = parseBoolean();
@@ -306,7 +306,7 @@ public class PmdParserBase extends CommonParser {
      * @throws MmdFormatException フォーマットエラー
      */
     private void parseSurfaceList() throws IOException, MmdFormatException{
-        int vertexNum = parseInteger();
+        int vertexNum = parseLeInt();
         if(vertexNum % 3 != 0) throw new MmdFormatException();
         int surfaceNum = vertexNum / 3;
 
@@ -318,9 +318,9 @@ public class PmdParserBase extends CommonParser {
         this.shapeHandler.loopStart(PmdShapeHandler.SURFACE_LIST, surfaceNum);
 
         for(int ct = 0; ct < surfaceNum; ct++){
-            int vertexId1 = parseUShortAsInteger();
-            int vertexId2 = parseUShortAsInteger();
-            int vertexId3 = parseUShortAsInteger();
+            int vertexId1 = parseLeUShortAsInt();
+            int vertexId2 = parseLeUShortAsInt();
+            int vertexId3 = parseLeUShortAsInt();
             this.shapeHandler.pmdSurfaceTriangle(vertexId1,
                                                  vertexId2,
                                                  vertexId3 );
@@ -338,7 +338,7 @@ public class PmdParserBase extends CommonParser {
      * @throws MmdFormatException フォーマットエラー
      */
     private void parseMaterialList() throws IOException, MmdFormatException{
-        int materialNum = parseInteger();
+        int materialNum = parseLeInt();
 
         if(this.materialHandler == null){
             skip(MATERIAL_DATA_SZ * materialNum);
@@ -353,27 +353,27 @@ public class PmdParserBase extends CommonParser {
             float green;
             float blue;
 
-            red   = parseFloat();
-            green = parseFloat();
-            blue  = parseFloat();
-            float alpha = parseFloat();
+            red   = parseLeFloat();
+            green = parseLeFloat();
+            blue  = parseLeFloat();
+            float alpha = parseLeFloat();
             this.materialHandler.pmdMaterialDiffuse(red, green, blue, alpha);
 
-            float shininess = parseFloat();
-            red   = parseFloat();
-            green = parseFloat();
-            blue  = parseFloat();
+            float shininess = parseLeFloat();
+            red   = parseLeFloat();
+            green = parseLeFloat();
+            blue  = parseLeFloat();
             this.materialHandler.pmdMaterialSpecular(red, green, blue,
                                                      shininess);
 
-            red   = parseFloat();
-            green = parseFloat();
-            blue  = parseFloat();
+            red   = parseLeFloat();
+            green = parseLeFloat();
+            blue  = parseLeFloat();
             this.materialHandler.pmdMaterialAmbient(red, green, blue);
 
-            int toonidx = parseUByteAsInteger();
+            int toonidx = parseUByteAsInt();
             boolean hasEdge = parseBoolean();
-            int surfaceCount = parseInteger();
+            int surfaceCount = parseLeInt();
             String shadingFile =
                     parseZeroTermWin31J(PmdLimits.MAXBYTES_TEXTUREFILENAME);
             String[] splitted = splitShadingFileInfo(shadingFile);
@@ -398,7 +398,7 @@ public class PmdParserBase extends CommonParser {
      * @throws MmdFormatException フォーマットエラー
      */
     private void parseBoneList() throws IOException, MmdFormatException{
-        this.boneCount = parseUShortAsInteger();
+        this.boneCount = parseLeUShortAsInt();
 
         if(this.boneHandler == null){
             skip(BONE_DATA_SZ * this.boneCount);
@@ -410,17 +410,17 @@ public class PmdParserBase extends CommonParser {
         for(int ct = 0; ct < this.boneCount; ct++){
             String boneName =
                     parseZeroTermWin31J(PmdLimits.MAXBYTES_BONENAME);
-            int parentId = parseUShortAsInteger();
-            int tailId = parseUShortAsInteger();
+            int parentId = parseLeUShortAsInt();
+            int tailId = parseLeUShortAsInt();
             byte boneKind = parseByte();
-            int ikId = parseUShortAsInteger();
+            int ikId = parseLeUShortAsInt();
 
             this.boneHandler.pmdBoneInfo(boneName, boneKind);
             this.boneHandler.pmdBoneLink(parentId, tailId, ikId);
 
-            float xPos = parseFloat();
-            float yPos = parseFloat();
-            float zPos = parseFloat();
+            float xPos = parseLeFloat();
+            float yPos = parseLeFloat();
+            float zPos = parseLeFloat();
 
             this.boneHandler.pmdBonePosition(xPos, yPos, zPos);
 
@@ -438,18 +438,18 @@ public class PmdParserBase extends CommonParser {
      * @throws MmdFormatException フォーマットエラー
      */
     private void parseIKList() throws IOException, MmdFormatException{
-        int ikCount = parseUShortAsInteger();
+        int ikCount = parseLeUShortAsInt();
 
         if(this.boneHandler != null){
             this.boneHandler.loopStart(PmdBoneHandler.IK_LIST, ikCount);
         }
 
         for(int ct = 0; ct < ikCount; ct++){
-            int boneId = parseUShortAsInteger();
-            int targetId = parseUShortAsInteger();
-            int chainLength = parseUByteAsInteger();
-            int depth = parseUShortAsInteger();
-            float weight = parseFloat();
+            int boneId = parseLeUShortAsInt();
+            int targetId = parseLeUShortAsInt();
+            int chainLength = parseUByteAsInt();
+            int depth = parseLeUShortAsInt();
+            float weight = parseLeFloat();
 
             parseIKChainList(chainLength);
 
@@ -480,7 +480,7 @@ public class PmdParserBase extends CommonParser {
         }
 
         for(int ct = 0; ct < chainLength; ct++){
-            int childId = parseUShortAsInteger();
+            int childId = parseLeUShortAsInt();
             if(this.boneHandler != null){
                 this.boneHandler.pmdIKChainInfo(childId);
                 this.boneHandler.loopNext(PmdBoneHandler.IKCHAIN_LIST);
@@ -500,7 +500,7 @@ public class PmdParserBase extends CommonParser {
      * @throws MmdFormatException フォーマットエラー
      */
     private void parseMorphList() throws IOException, MmdFormatException{
-        this.morphCount = parseUShortAsInteger();
+        this.morphCount = parseLeUShortAsInt();
 
         if(this.morphHandler != null){
             this.morphHandler.loopStart(PmdMorphHandler.MORPH_LIST,
@@ -510,7 +510,7 @@ public class PmdParserBase extends CommonParser {
         for(int ct = 0; ct < this.morphCount; ct++){
             String morphName =
                     parseZeroTermWin31J(PmdLimits.MAXBYTES_MORPHNAME);
-            int vertexCount = parseInteger();
+            int vertexCount = parseLeInt();
             byte morphType = parseByte();
 
             if(this.morphHandler != null){
@@ -548,10 +548,10 @@ public class PmdParserBase extends CommonParser {
                                     vertexCount );
 
         for(int ct = 0; ct < vertexCount; ct++){
-            int vertexId = parseInteger();
-            float xPos = parseFloat();
-            float yPos = parseFloat();
-            float zPos = parseFloat();
+            int vertexId = parseLeInt();
+            float xPos = parseLeFloat();
+            float yPos = parseLeFloat();
+            float zPos = parseLeFloat();
             this.morphHandler.pmdMorphVertexInfo(vertexId, xPos, yPos, zPos);
             this.morphHandler.loopNext(PmdMorphHandler.MORPHVERTEX_LIST);
         }
@@ -568,7 +568,7 @@ public class PmdParserBase extends CommonParser {
      */
     private void parseMorphOrderList()
             throws IOException, MmdFormatException{
-        int morphOrderCount = parseUByteAsInteger();
+        int morphOrderCount = parseUByteAsInt();
 
         if(this.morphHandler == null){
             skip(MORPHORDER_DATA_SZ * morphOrderCount);
@@ -579,7 +579,7 @@ public class PmdParserBase extends CommonParser {
                                     morphOrderCount );
 
         for(int ct = 0; ct < morphOrderCount; ct++){
-            int morphId = parseUShortAsInteger();
+            int morphId = parseLeUShortAsInt();
             this.morphHandler.pmdMorphOrderInfo(morphId);
 
             this.morphHandler.loopNext(PmdMorphHandler.MORPHORDER_LIST);
@@ -597,7 +597,7 @@ public class PmdParserBase extends CommonParser {
      */
     private void parseBoneGroupList()
             throws IOException, MmdFormatException{
-        this.boneGroupCount = parseUByteAsInteger();
+        this.boneGroupCount = parseUByteAsInt();
 
         if(this.boneHandler == null){
             skip(BONEGROUP_DATA_SZ * this.boneGroupCount);
@@ -628,7 +628,7 @@ public class PmdParserBase extends CommonParser {
      */
     private void parseGroupedBoneList()
             throws IOException, MmdFormatException{
-        int groupedBoneCount = parseInteger();
+        int groupedBoneCount = parseLeInt();
 
         if(this.boneHandler == null){
             skip(GROUPEDBONE_DATA_SZ * groupedBoneCount);
@@ -639,8 +639,8 @@ public class PmdParserBase extends CommonParser {
                                    groupedBoneCount);
 
         for(int ct = 0; ct < groupedBoneCount; ct++){
-            int boneId = parseUShortAsInteger();
-            int groupId = parseUByteAsInteger();
+            int boneId = parseLeUShortAsInt();
+            int groupId = parseUByteAsInt();
             this.boneHandler.pmdGroupedBoneInfo(boneId, groupId);
 
             this.boneHandler.loopNext(PmdBoneHandler.GROUPEDBONE_LIST);
index c1b8172..ce329ec 100644 (file)
@@ -9,7 +9,7 @@ package jp.sourceforge.mikutoga.pmd.parser;
 
 import java.io.IOException;
 import jp.sourceforge.mikutoga.parser.MmdFormatException;
-import jp.sourceforge.mikutoga.parser.MmdSource;
+import jp.sourceforge.mikutoga.parser.MmdInputStream;
 
 /**
  * PMDモデルファイルのパーサ拡張その1。
@@ -24,7 +24,7 @@ public class PmdParserExt1 extends PmdParserBase {
      * コンストラクタ。
      * @param source 入力ソース
      */
-    public PmdParserExt1(MmdSource source){
+    public PmdParserExt1(MmdInputStream source){
         super(source);
         return;
     }
index 9ac7d4c..be15890 100644 (file)
@@ -9,7 +9,7 @@ package jp.sourceforge.mikutoga.pmd.parser;
 
 import java.io.IOException;
 import jp.sourceforge.mikutoga.parser.MmdFormatException;
-import jp.sourceforge.mikutoga.parser.MmdSource;
+import jp.sourceforge.mikutoga.parser.MmdInputStream;
 
 /**
  * PMDモデルファイルのパーサ拡張その2。
@@ -23,7 +23,7 @@ public class PmdParserExt2 extends PmdParserExt1 {
      * コンストラクタ。
      * @param source 入力ソース
      */
-    public PmdParserExt2(MmdSource source){
+    public PmdParserExt2(MmdInputStream source){
         super(source);
         return;
     }
index 0a420ae..2fa93c0 100644 (file)
@@ -9,7 +9,7 @@ package jp.sourceforge.mikutoga.pmd.parser;
 
 import java.io.IOException;
 import jp.sourceforge.mikutoga.parser.MmdFormatException;
-import jp.sourceforge.mikutoga.parser.MmdSource;
+import jp.sourceforge.mikutoga.parser.MmdInputStream;
 
 /**
  * PMDモデルファイルのパーサ拡張その3。
@@ -27,7 +27,7 @@ public class PmdParserExt3 extends PmdParserExt2 {
      * コンストラクタ。
      * @param source 入力ソース
      */
-    public PmdParserExt3(MmdSource source){
+    public PmdParserExt3(MmdInputStream source){
         super(source);
         return;
     }
@@ -74,7 +74,7 @@ public class PmdParserExt3 extends PmdParserExt2 {
      * @throws MmdFormatException フォーマットエラー
      */
     private void parseRigidList() throws IOException, MmdFormatException{
-        int rigidNum = parseInteger();
+        int rigidNum = parseLeInt();
 
         if(this.rigidHandler == null){
             skip(RIGID_DATA_SZ * rigidNum);
@@ -88,32 +88,32 @@ public class PmdParserExt3 extends PmdParserExt2 {
                     parseZeroTermWin31J(PmdLimits.MAXBYTES_RIGIDNAME);
             this.rigidHandler.pmdRigidName(rigidName);
 
-            int linkedBoneId = parseUShortAsInteger();
-            int rigidGroupId = parseUByteAsInteger();
-            short collisionMap = parseShort();
+            int linkedBoneId = parseLeUShortAsInt();
+            int rigidGroupId = parseUByteAsInt();
+            short collisionMap = parseLeShort();
             this.rigidHandler.pmdRigidInfo(rigidGroupId, linkedBoneId);
 
             byte shapeType = parseByte();
-            float width = parseFloat();
-            float height = parseFloat();
-            float depth = parseFloat();
+            float width = parseLeFloat();
+            float height = parseLeFloat();
+            float depth = parseLeFloat();
             this.rigidHandler.pmdRigidShape(shapeType, width, height, depth);
 
-            float posX = parseFloat();
-            float posY = parseFloat();
-            float posZ = parseFloat();
+            float posX = parseLeFloat();
+            float posY = parseLeFloat();
+            float posZ = parseLeFloat();
             this.rigidHandler.pmdRigidPosition(posX, posY, posZ);
 
-            float rotX = parseFloat();
-            float rotY = parseFloat();
-            float rotZ = parseFloat();
+            float rotX = parseLeFloat();
+            float rotY = parseLeFloat();
+            float rotZ = parseLeFloat();
             this.rigidHandler.pmdRigidRotation(rotX, rotY, rotZ);
 
-            float mass = parseFloat();
-            float dampingPos = parseFloat();
-            float dampingRot = parseFloat();
-            float restitution = parseFloat();
-            float friction = parseFloat();
+            float mass = parseLeFloat();
+            float dampingPos = parseLeFloat();
+            float dampingRot = parseLeFloat();
+            float restitution = parseLeFloat();
+            float friction = parseLeFloat();
             this.rigidHandler.pmdRigidPhysics(mass,
                                               dampingPos, dampingRot,
                                               restitution, friction );
@@ -135,7 +135,7 @@ public class PmdParserExt3 extends PmdParserExt2 {
      * @throws MmdFormatException フォーマットエラー
      */
     private void parseJointList() throws IOException, MmdFormatException{
-        int jointNum = parseInteger();
+        int jointNum = parseLeInt();
 
         if(this.jointHandler == null){
             skip(JOINT_DATA_SZ * jointNum);
@@ -149,50 +149,50 @@ public class PmdParserExt3 extends PmdParserExt2 {
                     parseZeroTermWin31J(PmdLimits.MAXBYTES_JOINTNAME);
             this.jointHandler.pmdJointName(jointName);
 
-            int rigidIdA = parseInteger();
-            int rigidIdB = parseInteger();
+            int rigidIdA = parseLeInt();
+            int rigidIdB = parseLeInt();
             this.jointHandler.pmdJointLink(rigidIdA, rigidIdB);
 
-            float posX = parseFloat();
-            float posY = parseFloat();
-            float posZ = parseFloat();
+            float posX = parseLeFloat();
+            float posY = parseLeFloat();
+            float posZ = parseLeFloat();
             this.jointHandler.pmdJointPosition(posX, posY, posZ);
 
-            float rotX = parseFloat();
-            float rotY = parseFloat();
-            float rotZ = parseFloat();
+            float rotX = parseLeFloat();
+            float rotY = parseLeFloat();
+            float rotZ = parseLeFloat();
             this.jointHandler.pmdJointRotation(rotX, rotY, rotZ);
 
-            float posXlim1 = parseFloat();
-            float posYlim1 = parseFloat();
-            float posZlim1 = parseFloat();
-            float posXlim2 = parseFloat();
-            float posYlim2 = parseFloat();
-            float posZlim2 = parseFloat();
+            float posXlim1 = parseLeFloat();
+            float posYlim1 = parseLeFloat();
+            float posZlim1 = parseLeFloat();
+            float posXlim2 = parseLeFloat();
+            float posYlim2 = parseLeFloat();
+            float posZlim2 = parseLeFloat();
             this.jointHandler.pmdPositionLimit(posXlim1, posXlim2,
                                                posYlim1, posYlim2,
                                                posZlim1, posZlim2 );
 
-            float rotXlim1 = parseFloat();
-            float rotYlim1 = parseFloat();
-            float rotZlim1 = parseFloat();
-            float rotXlim2 = parseFloat();
-            float rotYlim2 = parseFloat();
-            float rotZlim2 = parseFloat();
+            float rotXlim1 = parseLeFloat();
+            float rotYlim1 = parseLeFloat();
+            float rotZlim1 = parseLeFloat();
+            float rotXlim2 = parseLeFloat();
+            float rotYlim2 = parseLeFloat();
+            float rotZlim2 = parseLeFloat();
             this.jointHandler.pmdRotationLimit(rotXlim1, rotXlim2,
                                                rotYlim1, rotYlim2,
                                                rotZlim1, rotZlim2 );
 
-            float elasticPosX = parseFloat();
-            float elasticPosY = parseFloat();
-            float elasticPosZ = parseFloat();
+            float elasticPosX = parseLeFloat();
+            float elasticPosY = parseLeFloat();
+            float elasticPosZ = parseLeFloat();
             this.jointHandler.pmdElasticPosition(elasticPosX,
                                                  elasticPosY,
                                                  elasticPosZ );
 
-            float elasticRotX = parseFloat();
-            float elasticRotY = parseFloat();
-            float elasticRotZ = parseFloat();
+            float elasticRotX = parseLeFloat();
+            float elasticRotY = parseLeFloat();
+            float elasticRotZ = parseLeFloat();
             this.jointHandler.pmdElasticRotation(elasticRotX,
                                                  elasticRotY,
                                                  elasticRotZ );
index 4c15a5a..b15f211 100644 (file)
@@ -10,7 +10,7 @@ package jp.sourceforge.mikutoga.vmd.parser;
 import java.io.IOException;
 import jp.sourceforge.mikutoga.parser.CommonParser;
 import jp.sourceforge.mikutoga.parser.MmdFormatException;
-import jp.sourceforge.mikutoga.parser.MmdSource;
+import jp.sourceforge.mikutoga.parser.MmdInputStream;
 import jp.sourceforge.mikutoga.vmd.VmdConst;
 
 /**
@@ -41,7 +41,7 @@ class VmdBasicParser extends CommonParser{
      * コンストラクタ。
      * @param source 入力ソース
      */
-    VmdBasicParser(MmdSource source){
+    VmdBasicParser(MmdInputStream source){
         super(source);
         return;
     }
@@ -138,7 +138,7 @@ class VmdBasicParser extends CommonParser{
      */
     private void parseVmdBoneMotion()
             throws IOException, MmdFormatException{
-        int boneMotionNo = parseInteger();
+        int boneMotionNo = parseLeInt();
 
         if(this.handler == null){
             skip(VmdConst.BONEMOTION_DATA_SZ * boneMotionNo);
@@ -150,18 +150,18 @@ class VmdBasicParser extends CommonParser{
 
         for(int ct = 0; ct < boneMotionNo; ct++){
             String boneName = parseZeroTermWin31J(VmdConst.BONENAME_MAX);
-            int keyFrameNo = parseInteger();
+            int keyFrameNo = parseLeInt();
             this.handler.vmdBoneMotion(boneName, keyFrameNo);
 
-            float xPos = parseFloat();
-            float yPos = parseFloat();
-            float zPos = parseFloat();
+            float xPos = parseLeFloat();
+            float yPos = parseLeFloat();
+            float zPos = parseLeFloat();
             this.handler.vmdBonePosition(xPos, yPos, zPos);
 
-            float qx = parseFloat();
-            float qy = parseFloat();
-            float qz = parseFloat();
-            float qw = parseFloat();
+            float qx = parseLeFloat();
+            float qy = parseLeFloat();
+            float qz = parseLeFloat();
+            float qw = parseLeFloat();
             this.handler.vmdBoneRotationQt(qx, qy, qz, qw);
 
             parseVmdMotionInterpolation();
@@ -270,7 +270,7 @@ class VmdBasicParser extends CommonParser{
      * @throws MmdFormatException フォーマットエラー
      */
     private void parseVmdMorph() throws IOException, MmdFormatException{
-        int morphMotionNo = parseInteger();
+        int morphMotionNo = parseLeInt();
 
         if(this.handler == null){
             skip(VmdConst.MORPH_DATA_SZ * morphMotionNo);
@@ -282,8 +282,8 @@ class VmdBasicParser extends CommonParser{
 
         for(int ct = 0; ct < morphMotionNo; ct++){
             String morphName = parseZeroTermWin31J(VmdConst.MORPHNAME_MAX);
-            int keyFrameNo = parseInteger();
-            float flex = parseFloat();
+            int keyFrameNo = parseLeInt();
+            float flex = parseLeFloat();
             this.handler.vmdMorphMotion(morphName, keyFrameNo, flex);
 
             this.handler.loopNext(VmdBasicHandler.MORPH_LIST);
index 7065c7c..8e1634a 100644 (file)
@@ -10,7 +10,7 @@ package jp.sourceforge.mikutoga.vmd.parser;
 import java.io.IOException;
 import jp.sourceforge.mikutoga.parser.CommonParser;
 import jp.sourceforge.mikutoga.parser.MmdFormatException;
-import jp.sourceforge.mikutoga.parser.MmdSource;
+import jp.sourceforge.mikutoga.parser.MmdInputStream;
 import jp.sourceforge.mikutoga.vmd.VmdConst;
 
 /**
@@ -33,7 +33,7 @@ class VmdCameraParser extends CommonParser{
      * コンストラクタ。
      * @param source 入力ソース
      */
-    VmdCameraParser(MmdSource source){
+    VmdCameraParser(MmdInputStream source){
         super(source);
         return;
     }
@@ -54,7 +54,7 @@ class VmdCameraParser extends CommonParser{
      * @throws MmdFormatException フォーマットエラー
      */
     void parse() throws IOException, MmdFormatException {
-        int cameraMotionNo = parseInteger();
+        int cameraMotionNo = parseLeInt();
 
         if(this.handler == null){
             skip(VmdConst.CAMERA_DATA_SZ * cameraMotionNo);
@@ -64,26 +64,26 @@ class VmdCameraParser extends CommonParser{
         this.handler.loopStart(VmdCameraHandler.CAMERA_LIST, cameraMotionNo);
 
         for(int ct = 0; ct < cameraMotionNo; ct++){
-            int keyFrameNo = parseInteger();
+            int keyFrameNo = parseLeInt();
             this.handler.vmdCameraMotion(keyFrameNo);
 
-            float range = parseFloat();
+            float range = parseLeFloat();
             this.handler.vmdCameraRange(range);
 
-            float xPos = parseFloat();
-            float yPos = parseFloat();
-            float zPos = parseFloat();
+            float xPos = parseLeFloat();
+            float yPos = parseLeFloat();
+            float zPos = parseLeFloat();
             this.handler.vmdCameraPosition(xPos, yPos, zPos);
 
-            float latitude  = parseFloat();
-            float longitude = parseFloat();
-            float roll      = parseFloat();
+            float latitude  = parseLeFloat();
+            float longitude = parseLeFloat();
+            float roll      = parseLeFloat();
             this.handler.vmdCameraRotation(latitude, longitude, roll);
 
             parseCameraXyzInterpolation();
             parseCameraEtcInterpolation();
 
-            int angle = parseInteger();
+            int angle = parseLeInt();
             boolean hasPerspective = ! parseBoolean();
             this.handler.vmdCameraProjection(angle, hasPerspective);
 
index 3786c71..9115c87 100644 (file)
@@ -10,7 +10,7 @@ package jp.sourceforge.mikutoga.vmd.parser;
 import java.io.IOException;
 import jp.sourceforge.mikutoga.parser.CommonParser;
 import jp.sourceforge.mikutoga.parser.MmdFormatException;
-import jp.sourceforge.mikutoga.parser.MmdSource;
+import jp.sourceforge.mikutoga.parser.MmdInputStream;
 import jp.sourceforge.mikutoga.vmd.VmdConst;
 
 /**
@@ -27,7 +27,7 @@ class VmdLightingParser extends CommonParser {
      * コンストラクタ。
      * @param source 入力ソース
      */
-    VmdLightingParser(MmdSource source){
+    VmdLightingParser(MmdInputStream source){
         super(source);
         return;
     }
@@ -62,7 +62,7 @@ class VmdLightingParser extends CommonParser {
      * @throws MmdFormatException フォーマットエラー
      */
     private void parseVmdLighting() throws IOException, MmdFormatException{
-        int lightMotionNo = parseInteger();
+        int lightMotionNo = parseLeInt();
 
         if(this.handler == null){
             skip(VmdConst.LUMINOUS_DATA_SZ * lightMotionNo);
@@ -73,17 +73,17 @@ class VmdLightingParser extends CommonParser {
                 lightMotionNo);
 
         for(int ct = 0; ct < lightMotionNo; ct++){
-            int keyFrameNo = parseInteger();
+            int keyFrameNo = parseLeInt();
             this.handler.vmdLuminousMotion(keyFrameNo);
 
-            float rVal = parseFloat();
-            float gVal = parseFloat();
-            float bVal = parseFloat();
+            float rVal = parseLeFloat();
+            float gVal = parseLeFloat();
+            float bVal = parseLeFloat();
             this.handler.vmdLuminousColor(rVal, gVal, bVal);
 
-            float xVec = parseFloat();
-            float yVec = parseFloat();
-            float zVec = parseFloat();
+            float xVec = parseLeFloat();
+            float yVec = parseLeFloat();
+            float zVec = parseLeFloat();
             this.handler.vmdLuminousDirection(xVec, yVec, zVec);
 
             this.handler.loopNext(VmdLightingHandler.LUMINOUS_LIST);
@@ -100,7 +100,7 @@ class VmdLightingParser extends CommonParser {
      * @throws MmdFormatException フォーマットエラー
      */
     private void parseVmdShadow() throws IOException, MmdFormatException{
-        int shadowMotionNo = parseInteger();
+        int shadowMotionNo = parseLeInt();
 
         if(this.handler == null){
             skip(VmdConst.SHADOW_DATA_SZ * shadowMotionNo);
@@ -111,13 +111,13 @@ class VmdLightingParser extends CommonParser {
                 shadowMotionNo);
 
         for(int ct = 0; ct < shadowMotionNo; ct++){
-            int keyFrameNo = parseInteger();
+            int keyFrameNo = parseLeInt();
             this.handler.vmdShadowMotion(keyFrameNo);
 
             byte shadowMode = parseByte();
             this.handler.vmdShadowMode(shadowMode);
 
-            float shadowScope = parseFloat();
+            float shadowScope = parseLeFloat();
             this.handler.vmdShadowScopeRaw(shadowScope);
 
             this.handler.loopNext(VmdLightingHandler.SHADOW_LIST);
index 95fb1df..f19e141 100644 (file)
@@ -9,14 +9,14 @@ package jp.sourceforge.mikutoga.vmd.parser;
 
 import java.io.IOException;
 import jp.sourceforge.mikutoga.parser.MmdFormatException;
-import jp.sourceforge.mikutoga.parser.MmdSource;
+import jp.sourceforge.mikutoga.parser.MmdInputStream;
 
 /**
  * VMDモーションファイルのパーサ。
  */
 public class VmdParser {
 
-    private final MmdSource source;
+    private final MmdInputStream source;
 
     private final VmdBasicParser    basicParser;
     private final VmdCameraParser   cameraParser;
@@ -31,7 +31,7 @@ public class VmdParser {
      * @param source 入力ソース
      * @throws NullPointerException 引数がnull
      */
-    public VmdParser(MmdSource source) throws NullPointerException{
+    public VmdParser(MmdInputStream source) throws NullPointerException{
         super();
 
         if(source == null) throw new NullPointerException();
@@ -49,7 +49,7 @@ public class VmdParser {
      * 入力ソースを返す。
      * @return 入力ソース
      */
-    public MmdSource getSource(){
+    public MmdInputStream getSource(){
         return this.source;
     }
 
diff --git a/src/test/java/jp/sourceforge/mikutoga/binio/BinaryExporterTest.java b/src/test/java/jp/sourceforge/mikutoga/binio/BinaryExporterTest.java
new file mode 100644 (file)
index 0000000..7babd07
--- /dev/null
@@ -0,0 +1,581 @@
+/*
+ */
+
+package jp.sourceforge.mikutoga.binio;
+
+import java.io.ByteArrayOutputStream;
+import java.io.FilterOutputStream;
+import java.io.IOException;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+/**
+ *
+ */
+public class BinaryExporterTest {
+
+    public BinaryExporterTest() {
+    }
+
+    @BeforeClass
+    public static void setUpClass() {
+    }
+
+    @AfterClass
+    public static void tearDownClass() {
+    }
+
+    @Before
+    public void setUp() {
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    /**
+     * Test of close method, of class BinaryExporter.
+     */
+    @Test
+    public void testClose() throws Exception {
+        System.out.println("close");
+
+        TestOutputStream os = new TestOutputStream();
+        BinaryExporter bex;
+        bex = new BinaryExporter(os);
+
+        assertFalse(os.closed);
+        bex.close();
+        assertTrue(os.closed);
+
+        return;
+    }
+
+    /**
+     * Test of flush method, of class BinaryExporter.
+     */
+    @Test
+    public void testFlush() throws Exception {
+        System.out.println("flush");
+
+        TestOutputStream os = new TestOutputStream();
+        BinaryExporter bex;
+        bex = new BinaryExporter(os);
+
+        assertFalse(os.flushed);
+        bex.flush();
+        assertTrue(os.flushed);
+
+        return;
+    }
+
+    /**
+     * Test of dumpByte method, of class BinaryExporter.
+     */
+    @Test
+    public void testDumpByte_byte() throws Exception {
+        System.out.println("dumpByte");
+
+        ByteArrayOutputStream bos;
+        BinaryExporter bex;
+        byte[] barr;
+
+        bos = new ByteArrayOutputStream();
+        bex = new BinaryExporter(bos);
+
+        bex.dumpByte((byte)10);
+        bex.flush();
+
+        barr = bos.toByteArray();
+        assertEquals(1, barr.length);
+        assertEquals((byte)10, barr[0]);
+
+        return;
+    }
+
+    /**
+     * Test of dumpByte method, of class BinaryExporter.
+     */
+    @Test
+    public void testDumpByte_int() throws Exception {
+        System.out.println("dumpByte");
+
+        ByteArrayOutputStream bos;
+        BinaryExporter bex;
+        byte[] barr;
+
+        bos = new ByteArrayOutputStream();
+        bex = new BinaryExporter(bos);
+
+        bex.dumpByte(10);
+        bex.flush();
+        barr = bos.toByteArray();
+        assertEquals(1, barr.length);
+        assertEquals((byte)10, barr[0]);
+
+        bos.reset();
+        bex.dumpByte(257);
+        bex.flush();
+        barr = bos.toByteArray();
+        assertEquals(1, barr.length);
+        assertEquals((byte)1, barr[0]);
+
+
+        return;
+    }
+
+    /**
+     * Test of dumpByteArray method, of class BinaryExporter.
+     */
+    @Test
+    public void testDumpByteArray_byteArr() throws Exception {
+        System.out.println("dumpByteArray");
+
+        ByteArrayOutputStream bos;
+        BinaryExporter bex;
+        byte[] barr;
+
+        bos = new ByteArrayOutputStream();
+        bex = new BinaryExporter(bos);
+
+        bex.dumpByteArray(new byte[]{0x01, 0x02, 0x03});
+        bex.flush();
+
+        barr = bos.toByteArray();
+        assertEquals(3, barr.length);
+        assertEquals((byte)0x01, barr[0]);
+        assertEquals((byte)0x02, barr[1]);
+        assertEquals((byte)0x03, barr[2]);
+
+        return;
+    }
+
+    /**
+     * Test of dumpByteArray method, of class BinaryExporter.
+     */
+    @Test
+    public void testDumpByteArray_3args() throws Exception {
+        System.out.println("dumpByteArray");
+
+        ByteArrayOutputStream bos;
+        BinaryExporter bex;
+        byte[] barr;
+
+        bos = new ByteArrayOutputStream();
+        bex = new BinaryExporter(bos);
+
+        bex.dumpByteArray(new byte[]{0x01, 0x02, 0x03, 0x04, 0x05},
+                          1, 3);
+        bex.flush();
+
+        barr = bos.toByteArray();
+        assertEquals(3, barr.length);
+        assertEquals((byte)0x02, barr[0]);
+        assertEquals((byte)0x03, barr[1]);
+        assertEquals((byte)0x04, barr[2]);
+
+        return;
+    }
+
+    /**
+     * Test of dumpLeShort method, of class BinaryExporter.
+     */
+    @Test
+    public void testDumpLeShort_short() throws Exception {
+        System.out.println("dumpLeShort");
+
+        ByteArrayOutputStream bos;
+        BinaryExporter bex;
+        byte[] barr;
+
+        bos = new ByteArrayOutputStream();
+        bex = new BinaryExporter(bos);
+
+        bos.reset();
+        bex.dumpLeShort((short)( 256 * 2 + 1));
+        bex.flush();
+        barr = bos.toByteArray();
+        assertEquals(2, barr.length);
+        assertEquals((byte)1, barr[0]);
+        assertEquals((byte)2, barr[1]);
+
+        bos.reset();
+        bex.dumpLeShort((short)-2);
+        bex.flush();
+        barr = bos.toByteArray();
+        assertEquals(2, barr.length);
+        assertEquals((byte)0xfe, barr[0]);
+        assertEquals((byte)0xff, barr[1]);
+
+        return;
+    }
+
+    /**
+     * Test of dumpLeShort method, of class BinaryExporter.
+     */
+    @Test
+    public void testDumpLeShort_int() throws Exception {
+        System.out.println("dumpLeShort");
+
+        ByteArrayOutputStream bos;
+        BinaryExporter bex;
+        byte[] barr;
+
+        bos = new ByteArrayOutputStream();
+        bex = new BinaryExporter(bos);
+
+        bos.reset();
+        bex.dumpLeShort(256 * 2 + 1);
+        bex.flush();
+        barr = bos.toByteArray();
+        assertEquals(2, barr.length);
+        assertEquals((byte)1, barr[0]);
+        assertEquals((byte)2, barr[1]);
+
+        bos.reset();
+        bex.dumpLeShort(0xff1234);
+        bex.flush();
+        barr = bos.toByteArray();
+        assertEquals(2, barr.length);
+        assertEquals((byte)0x34, barr[0]);
+        assertEquals((byte)0x12, barr[1]);
+
+        bos.reset();
+        bex.dumpLeShort(-2);
+        bex.flush();
+        barr = bos.toByteArray();
+        assertEquals(2, barr.length);
+        assertEquals((byte)0xfe, barr[0]);
+        assertEquals((byte)0xff, barr[1]);
+
+        return;
+    }
+
+    /**
+     * Test of dumpLeInt method, of class BinaryExporter.
+     */
+    @Test
+    public void testDumpLeInt() throws Exception {
+        System.out.println("dumpLeInt");
+
+        ByteArrayOutputStream bos;
+        BinaryExporter bex;
+        byte[] barr;
+
+        bos = new ByteArrayOutputStream();
+        bex = new BinaryExporter(bos);
+
+        bos.reset();
+        bex.dumpLeInt(0x12345678);
+        bex.flush();
+        barr = bos.toByteArray();
+        assertEquals(4, barr.length);
+        assertEquals((byte)0x78, barr[0]);
+        assertEquals((byte)0x56, barr[1]);
+        assertEquals((byte)0x34, barr[2]);
+        assertEquals((byte)0x12, barr[3]);
+
+        bos.reset();
+        bex.dumpLeInt(-2);
+        bex.flush();
+        barr = bos.toByteArray();
+        assertEquals(4, barr.length);
+        assertEquals((byte)0xfe, barr[0]);
+        assertEquals((byte)0xff, barr[1]);
+        assertEquals((byte)0xff, barr[2]);
+        assertEquals((byte)0xff, barr[3]);
+
+        return;
+    }
+
+    /**
+     * Test of dumpLeLong method, of class BinaryExporter.
+     */
+    @Test
+    public void testDumpLeLong() throws Exception {
+        System.out.println("dumpLeLong");
+
+        ByteArrayOutputStream bos;
+        BinaryExporter bex;
+        byte[] barr;
+
+        bos = new ByteArrayOutputStream();
+        bex = new BinaryExporter(bos);
+
+        bos.reset();
+        bex.dumpLeLong(0x12345678abcdef00L);
+        bex.flush();
+        barr = bos.toByteArray();
+        assertEquals(8, barr.length);
+        assertEquals((byte)0x00, barr[0]);
+        assertEquals((byte)0xef, barr[1]);
+        assertEquals((byte)0xcd, barr[2]);
+        assertEquals((byte)0xab, barr[3]);
+        assertEquals((byte)0x78, barr[4]);
+        assertEquals((byte)0x56, barr[5]);
+        assertEquals((byte)0x34, barr[6]);
+        assertEquals((byte)0x12, barr[7]);
+
+        bos.reset();
+        bex.dumpLeLong(-2L);
+        bex.flush();
+        barr = bos.toByteArray();
+        assertEquals(8, barr.length);
+        assertEquals((byte)0xfe, barr[0]);
+        assertEquals((byte)0xff, barr[1]);
+        assertEquals((byte)0xff, barr[2]);
+        assertEquals((byte)0xff, barr[3]);
+        assertEquals((byte)0xff, barr[4]);
+        assertEquals((byte)0xff, barr[5]);
+        assertEquals((byte)0xff, barr[6]);
+        assertEquals((byte)0xff, barr[7]);
+
+        return;
+    }
+
+    /**
+     * Test of dumpLeFloat method, of class BinaryExporter.
+     */
+    @Test
+    public void testDumpLeFloat() throws Exception {
+        System.out.println("dumpLeFloat");
+
+        ByteArrayOutputStream bos;
+        BinaryExporter bex;
+        byte[] barr;
+
+        bos = new ByteArrayOutputStream();
+        bex = new BinaryExporter(bos);
+
+        bos.reset();
+        bex.dumpLeFloat(Float.intBitsToFloat(0x12345678));
+        bex.flush();
+        barr = bos.toByteArray();
+        assertEquals(4, barr.length);
+        assertEquals((byte)0x78, barr[0]);
+        assertEquals((byte)0x56, barr[1]);
+        assertEquals((byte)0x34, barr[2]);
+        assertEquals((byte)0x12, barr[3]);
+
+        bos.reset();
+        bex.dumpLeFloat(-1.5f);
+        bex.flush();
+        barr = bos.toByteArray();
+        assertEquals(4, barr.length);
+        assertEquals((byte)0x00, barr[0]);
+        assertEquals((byte)0x00, barr[1]);
+        assertEquals((byte)0xc0, barr[2]);
+        assertEquals((byte)0xbf, barr[3]);
+
+        return;
+    }
+
+    /**
+     * Test of dumpLeDouble method, of class BinaryExporter.
+     */
+    @Test
+    public void testDumpLeDouble() throws Exception {
+        System.out.println("dumpLeDouble");
+
+        ByteArrayOutputStream bos;
+        BinaryExporter bex;
+        byte[] barr;
+
+        bos = new ByteArrayOutputStream();
+        bex = new BinaryExporter(bos);
+
+        bos.reset();
+        bex.dumpLeDouble(Double.longBitsToDouble(0x12345678abcdef00L));
+        bex.flush();
+        barr = bos.toByteArray();
+        assertEquals(8, barr.length);
+        assertEquals((byte)0x00, barr[0]);
+        assertEquals((byte)0xef, barr[1]);
+        assertEquals((byte)0xcd, barr[2]);
+        assertEquals((byte)0xab, barr[3]);
+        assertEquals((byte)0x78, barr[4]);
+        assertEquals((byte)0x56, barr[5]);
+        assertEquals((byte)0x34, barr[6]);
+        assertEquals((byte)0x12, barr[7]);
+
+        bos.reset();
+        bex.dumpLeDouble(-1.5);
+        bex.flush();
+        barr = bos.toByteArray();
+        assertEquals(8, barr.length);
+        assertEquals((byte)0x00, barr[0]);
+        assertEquals((byte)0x00, barr[1]);
+        assertEquals((byte)0x00, barr[2]);
+        assertEquals((byte)0x00, barr[3]);
+        assertEquals((byte)0x00, barr[4]);
+        assertEquals((byte)0x00, barr[5]);
+        assertEquals((byte)0xf8, barr[6]);
+        assertEquals((byte)0xbf, barr[7]);
+
+        return;
+    }
+
+    /**
+     * Test of dumpFiller method, of class BinaryExporter.
+     */
+    @Test
+    public void testDumpFiller() throws Exception {
+        System.out.println("dumpFiller");
+
+        ByteArrayOutputStream bos;
+        BinaryExporter bex;
+        byte[] barr;
+
+        bos = new ByteArrayOutputStream();
+        bex = new BinaryExporter(bos);
+
+        bex.dumpFiller(new byte[]{}, 1);
+        bex.flush();
+        barr = bos.toByteArray();
+        assertEquals(0, barr.length);
+
+        bos.reset();
+        bex.dumpFiller(new byte[]{0x01}, 3);
+        bex.flush();
+        barr = bos.toByteArray();
+        assertEquals(3, barr.length);
+        assertEquals((byte)0x01, barr[0]);
+        assertEquals((byte)0x01, barr[1]);
+        assertEquals((byte)0x01, barr[2]);
+
+        bos.reset();
+        bex.dumpFiller(new byte[]{0x01, 0x02}, 3);
+        bex.flush();
+        barr = bos.toByteArray();
+        assertEquals(3, barr.length);
+        assertEquals((byte)0x01, barr[0]);
+        assertEquals((byte)0x02, barr[1]);
+        assertEquals((byte)0x02, barr[2]);
+
+        bos.reset();
+        bex.dumpFiller(new byte[]{0x01, 0x02, 0x03}, 2);
+        bex.flush();
+        barr = bos.toByteArray();
+        assertEquals(2, barr.length);
+        assertEquals((byte)0x01, barr[0]);
+        assertEquals((byte)0x02, barr[1]);
+
+        return;
+    }
+
+    /**
+     * Test of dumpFixedW31j method, of class BinaryExporter.
+     */
+    @Test
+    public void testDumpFixedW31j() throws Exception {
+        System.out.println("dumpFixedW31j");
+
+        ByteArrayOutputStream bos;
+        BinaryExporter bex;
+        byte[] barr;
+
+        bos = new ByteArrayOutputStream();
+        bex = new BinaryExporter(bos);
+
+        bos.reset();
+        bex.dumpFixedW31j("あい", 7, new byte[]{0x01, 0x02});
+        bex.flush();
+        barr = bos.toByteArray();
+        assertEquals(7, barr.length);
+        assertEquals((byte)0x82, barr[0]);
+        assertEquals((byte)0xA0, barr[1]);
+        assertEquals((byte)0x82, barr[2]);
+        assertEquals((byte)0xA2, barr[3]);
+        assertEquals((byte)0x01, barr[4]);
+        assertEquals((byte)0x02, barr[5]);
+        assertEquals((byte)0x02, barr[6]);
+
+        bos.reset();
+        try{
+            bex.dumpFixedW31j("あい", 3, new byte[]{0x00});
+            fail();
+        }catch(IllegalTextExportException e){
+            // GOOD
+        }
+
+        bos.reset();
+        try{
+            bex.dumpFixedW31j("¤", 10, new byte[]{0x00});
+            fail();
+        }catch(IllegalTextExportException e){
+            // GOOD
+        }
+
+        return;
+    }
+
+    /**
+     * Test of dumpHollerithUtf16LE method, of class BinaryExporter.
+     */
+    @Test
+    public void testDumpHollerithUtf16LE() throws Exception {
+        System.out.println("dumpHollerithUtf16LE");
+
+        ByteArrayOutputStream bos;
+        BinaryExporter bex;
+        byte[] barr;
+
+        bos = new ByteArrayOutputStream();
+        bex = new BinaryExporter(bos);
+
+        bex.dumpHollerithUtf16LE("あい");
+        bex.flush();
+        barr = bos.toByteArray();
+        assertEquals(8, barr.length);
+        assertEquals((byte)0x04, barr[0]);
+        assertEquals((byte)0x00, barr[1]);
+        assertEquals((byte)0x00, barr[2]);
+        assertEquals((byte)0x00, barr[3]);
+        assertEquals((byte)0x42, barr[4]);
+        assertEquals((byte)0x30, barr[5]);
+        assertEquals((byte)0x44, barr[6]);
+        assertEquals((byte)0x30, barr[7]);
+
+        bos.reset();
+        bex.dumpHollerithUtf16LE("");
+        bex.flush();
+        barr = bos.toByteArray();
+        assertEquals(4, barr.length);
+        assertEquals((byte)0x00, barr[0]);
+        assertEquals((byte)0x00, barr[1]);
+        assertEquals((byte)0x00, barr[2]);
+        assertEquals((byte)0x00, barr[3]);
+
+        return;
+    }
+
+    private static class TestOutputStream extends FilterOutputStream{
+        public boolean closed = false;
+        public boolean flushed = false;
+
+        TestOutputStream(){
+            super(new ByteArrayOutputStream());
+            return;
+        }
+
+        @Override
+        public void flush() throws IOException {
+            super.flush();
+            this.flushed = true;
+            return;
+        }
+
+        @Override
+        public void close() throws IOException {
+            super.close();
+            this.closed = true;
+            return;
+        }
+
+    }
+
+}
diff --git a/src/test/java/jp/sourceforge/mikutoga/binio/TextExporterTest.java b/src/test/java/jp/sourceforge/mikutoga/binio/TextExporterTest.java
new file mode 100644 (file)
index 0000000..e8af350
--- /dev/null
@@ -0,0 +1,183 @@
+/*
+ */
+
+package jp.sourceforge.mikutoga.binio;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.PipedOutputStream;
+import java.nio.charset.CharacterCodingException;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetEncoder;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+/**
+ *
+ */
+public class TextExporterTest {
+
+    private static Charset CS_ASCII = Charset.forName("US-ASCII");
+    private static Charset CS_UTF8  = Charset.forName("UTF-8");
+
+    public TextExporterTest() {
+    }
+
+    @BeforeClass
+    public static void setUpClass() {
+    }
+
+    @AfterClass
+    public static void tearDownClass() {
+    }
+
+    @Before
+    public void setUp() {
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    /**
+     * Test of getEncoder method, of class TextExporter.
+     */
+    @Test
+    public void testGetEncoder() {
+        System.out.println("getEncoder");
+
+        Charset cs;
+        cs = Charset.forName("US-ASCII");
+        CharsetEncoder usenc = cs.newEncoder();
+
+        TextExporter exporter;
+        CharsetEncoder enc;
+
+        exporter = new TextExporter(cs);
+        enc = exporter.getEncoder();
+        assertEquals(usenc.charset(), enc.charset());
+
+        exporter = new TextExporter(usenc);
+        enc = exporter.getEncoder();
+        assertEquals(usenc.charset(), enc.charset());
+
+        return;
+    }
+
+    /**
+     * Test of setCharBufSize method, of class TextExporter.
+     */
+    @Test
+    public void testSetBufSize() {
+        System.out.println("setCharBufSize");
+
+        TextExporter exporter;
+        ByteArrayOutputStream bout = new ByteArrayOutputStream();
+
+        exporter = new TextExporter(CS_UTF8);
+        exporter.setCharBufSize(1);
+        exporter.setByteBufSize(4);
+        bout.reset();
+        try{
+            exporter.encodeToByteStream("あいう", bout);
+        }catch(CharacterCodingException e){
+            fail();
+        }
+        assertEquals(9, bout.size());
+
+        try{
+            exporter.setByteBufSize(3);
+            fail();
+        }catch(IllegalArgumentException e){
+            // GOOD
+        }
+
+        return;
+    }
+
+    /**
+     * Test of dumpText method, of class TextExporter.
+     */
+    @Test
+    public void testDumpText() throws Exception {
+        System.out.println("dumpText");
+
+        TextExporter exporter;
+        ByteArrayOutputStream bout;
+        byte[] barr;
+
+        exporter = new TextExporter(CS_ASCII);
+
+        bout = new ByteArrayOutputStream();
+        exporter.dumpText("ABC", bout);
+        assertEquals(3, bout.size());
+        barr = bout.toByteArray();
+        assertEquals(3, barr.length);
+        assertEquals((byte)0x41, barr[0]);
+        assertEquals((byte)0x42, barr[1]);
+        assertEquals((byte)0x43, barr[2]);
+
+        PipedOutputStream pout;
+        pout = new PipedOutputStream();
+        try{
+            exporter.dumpText("ABC", pout);
+            fail();
+        }catch(IOException e){
+            // GOOD
+        }
+
+        return;
+    }
+
+    /**
+     * Test of encodeToByteStream method, of class TextExporter.
+     */
+    @Test
+    public void testEncodeToByteStream() throws Exception {
+        System.out.println("encodeToByteStream");
+
+        TextExporter exporter;
+        ByteArrayOutputStream bout = new ByteArrayOutputStream();
+        byte[] barr;
+
+        exporter = new TextExporter(CS_ASCII);
+
+        bout.reset();
+        exporter.encodeToByteStream("ABC", bout);
+        assertEquals(3, bout.size());
+        barr = bout.toByteArray();
+        assertEquals(3, barr.length);
+        assertEquals((byte)0x41, barr[0]);
+        assertEquals((byte)0x42, barr[1]);
+        assertEquals((byte)0x43, barr[2]);
+
+        bout.reset();
+        exporter.encodeToByteStream("", bout);
+        assertEquals(0, bout.size());
+
+        bout.reset();
+        try{
+            exporter.encodeToByteStream("あ", bout);
+            fail();
+        }catch(CharacterCodingException e){
+            // GOOD
+        }
+
+        exporter = new TextExporter(CS_UTF8);
+        bout.reset();
+        exporter.encodeToByteStream("あ", bout);
+        assertEquals(3, bout.size());
+        barr = bout.toByteArray();
+        assertEquals(3, barr.length);
+        assertEquals((byte)0xe3, barr[0]);
+        assertEquals((byte)0x81, barr[1]);
+        assertEquals((byte)0x82, barr[2]);
+
+        return;
+    }
+
+}
diff --git a/src/test/java/jp/sourceforge/mikutoga/parser/MmdInputStreamTest.java b/src/test/java/jp/sourceforge/mikutoga/parser/MmdInputStreamTest.java
new file mode 100644 (file)
index 0000000..11435c9
--- /dev/null
@@ -0,0 +1,324 @@
+/*
+ */
+
+package jp.sourceforge.mikutoga.parser;
+
+import java.io.ByteArrayInputStream;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+/**
+ *
+ */
+public class MmdInputStreamTest {
+
+    public MmdInputStreamTest() {
+    }
+
+    @BeforeClass
+    public static void setUpClass() {
+    }
+
+    @AfterClass
+    public static void tearDownClass() {
+    }
+
+    @Before
+    public void setUp() {
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    /**
+     * Test of parseByte method, of class MmdInputStream.
+     */
+    @Test
+    public void testParseByte() throws Exception {
+        System.out.println("parseByte");
+
+        MmdInputStream mis;
+        ByteArrayInputStream bis;
+
+        bis = new ByteArrayInputStream(new byte[]{0x01, 0x02});
+        mis = new MmdInputStream(bis);
+
+        byte result;
+
+        result = mis.parseByte();
+        assertEquals(result, (byte)0x01);
+
+        result = mis.parseByte();
+        assertEquals(result, (byte)0x02);
+
+        try{
+            mis.parseByte();
+            fail();
+        }catch(MmdEofException e){
+            // GOOD
+        }
+
+        assertEquals(-1, mis.read());
+
+        return;
+    }
+
+    /**
+     * Test of parseBoolean method, of class MmdInputStream.
+     */
+    @Test
+    public void testParseBoolean() throws Exception {
+        System.out.println("parseBoolean");
+
+        MmdInputStream mis;
+        ByteArrayInputStream bis;
+
+        bis = new ByteArrayInputStream(new byte[]{0x00, 0x01, 0x02});
+        mis = new MmdInputStream(bis);
+
+        boolean result;
+
+        result = mis.parseBoolean();
+        assertFalse(result);
+
+        result = mis.parseBoolean();
+        assertTrue(result);
+
+        result = mis.parseBoolean();
+        assertTrue(result);
+
+        try{
+            mis.parseBoolean();
+            fail();
+        }catch(MmdEofException e){
+            // GOOD
+        }
+
+        assertEquals(-1, mis.read());
+
+        return;
+    }
+
+    /**
+     * Test of parseBeShort method, of class MmdInputStream.
+     */
+    @Test
+    public void testParseBeShort() throws Exception {
+        System.out.println("parseBeShort");
+
+        MmdInputStream mis;
+        ByteArrayInputStream bis;
+
+        bis = new ByteArrayInputStream(new byte[]{0x01, 0x02, 0x03});
+        mis = new MmdInputStream(bis);
+
+        short result;
+
+        result = mis.parseBeShort();
+        assertEquals((short)0x0102, result);
+
+        try{
+            mis.parseBeShort();
+            fail();
+        }catch(MmdEofException e){
+            // GOOD
+        }
+
+        assertEquals(-1, mis.read());
+
+        return;
+    }
+
+    /**
+     * Test of parseLeShort method, of class MmdInputStream.
+     */
+    @Test
+    public void testParseLeShort() throws Exception {
+        System.out.println("parseLeShort");
+
+        MmdInputStream mis;
+        ByteArrayInputStream bis;
+
+        bis = new ByteArrayInputStream(new byte[]{0x01, 0x02, 0x03});
+        mis = new MmdInputStream(bis);
+
+        short result;
+
+        result = mis.parseLeShort();
+        assertEquals((short)0x0201, result);
+
+        try{
+            mis.parseLeShort();
+            fail();
+        }catch(MmdEofException e){
+            // GOOD
+        }
+
+        assertEquals(-1, mis.read());
+
+        return;
+    }
+
+    /**
+     * Test of parseBeInt method, of class MmdInputStream.
+     */
+    @Test
+    public void testParseBeInt() throws Exception {
+        System.out.println("parseBeInt");
+
+        MmdInputStream mis;
+        ByteArrayInputStream bis;
+
+        bis = new ByteArrayInputStream(
+                new byte[]{0x01, 0x02, 0x03, 0x04, 0x05});
+        mis = new MmdInputStream(bis);
+
+        int result;
+
+        result = mis.parseBeInt();
+        assertEquals(0x01020304, result);
+
+        try{
+            mis.parseBeInt();
+            fail();
+        }catch(MmdEofException e){
+            // GOOD
+        }
+
+        assertEquals(-1, mis.read());
+
+        return;
+    }
+
+    /**
+     * Test of parseLeInt method, of class MmdInputStream.
+     */
+    @Test
+    public void testParseLeInt() throws Exception {
+        System.out.println("parseLeInt");
+
+        MmdInputStream mis;
+        ByteArrayInputStream bis;
+
+        bis = new ByteArrayInputStream(
+                new byte[]{0x01, 0x02, 0x03, 0x04, 0x05});
+        mis = new MmdInputStream(bis);
+
+        int result;
+
+        result = mis.parseLeInt();
+        assertEquals(0x04030201, result);
+
+        try{
+            mis.parseLeInt();
+            fail();
+        }catch(MmdEofException e){
+            // GOOD
+        }
+
+        assertEquals(-1, mis.read());
+
+        return;
+    }
+
+    /**
+     * Test of parseBeFloat method, of class MmdInputStream.
+     */
+    @Test
+    public void testParseBeFloat() throws Exception {
+        System.out.println("parseBeFloat");
+
+        MmdInputStream mis;
+        ByteArrayInputStream bis;
+
+        bis = new ByteArrayInputStream(
+                new byte[]{0x01, 0x02, 0x03, 0x04, 0x05});
+        mis = new MmdInputStream(bis);
+
+        float result;
+
+        result = mis.parseBeFloat();
+        assertEquals(Float.intBitsToFloat(0x01020304), result, 0.0f);
+
+        try{
+            mis.parseBeFloat();
+            fail();
+        }catch(MmdEofException e){
+            // GOOD
+        }
+
+        assertEquals(-1, mis.read());
+
+        return;
+    }
+
+    /**
+     * Test of parseLeFloat method, of class MmdInputStream.
+     */
+    @Test
+    public void testParseLeFloat() throws Exception {
+        System.out.println("parseLeFloat");
+
+        MmdInputStream mis;
+        ByteArrayInputStream bis;
+
+        bis = new ByteArrayInputStream(
+                new byte[]{0x01, 0x02, 0x03, 0x04, 0x05});
+        mis = new MmdInputStream(bis);
+
+        float result;
+
+        result = mis.parseLeFloat();
+        assertEquals(Float.intBitsToFloat(0x04030201), result, 0.0f);
+
+        try{
+            mis.parseLeFloat();
+            fail();
+        }catch(MmdEofException e){
+            // GOOD
+        }
+
+        assertEquals(-1, mis.read());
+
+        return;
+    }
+
+    /**
+     * Test of skipRepeat method, of class MmdInputStream.
+     */
+    @Test
+    public void testSkipRepeat() throws Exception {
+        System.out.println("skipRepeat");
+
+        MmdInputStream mis;
+        ByteArrayInputStream bis;
+
+        bis = new ByteArrayInputStream(new byte[]{0x11, 0x12, 0x13});
+        mis = new MmdInputStream(bis);
+
+        int result;
+        long skipped;
+
+        result = mis.read();
+        assertEquals(0x11, result);
+
+        skipped = mis.skip(1L);
+        assertEquals(1L, skipped);
+
+        result = mis.read();
+        assertEquals(0x13, result);
+
+        skipped = mis.skip(1L);
+        assertEquals(0L, skipped);
+
+        // TODO: BufferedInputStreamと組み合わせた時の不思議なskip動作
+
+        return;
+    }
+
+}
diff --git a/src/test/java/jp/sourceforge/mikutoga/parser/SpottedInputStreamTest.java b/src/test/java/jp/sourceforge/mikutoga/parser/SpottedInputStreamTest.java
new file mode 100644 (file)
index 0000000..1c551b6
--- /dev/null
@@ -0,0 +1,253 @@
+/*
+ */
+package jp.sourceforge.mikutoga.parser;
+
+import java.io.ByteArrayInputStream;
+import java.io.FilterInputStream;
+import java.io.IOException;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+/**
+ *
+ */
+public class SpottedInputStreamTest {
+
+    public SpottedInputStreamTest() {
+    }
+
+    @BeforeClass
+    public static void setUpClass() {
+    }
+
+    @AfterClass
+    public static void tearDownClass() {
+    }
+
+    @Before
+    public void setUp() {
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    /**
+     * Test of read method, of class SpottedInputStream.
+     */
+    @Test
+    public void testRead_0args() throws Exception {
+        System.out.println("read");
+
+        SpottedInputStream sis;
+        ByteArrayInputStream bis;
+
+        bis = new ByteArrayInputStream(new byte[]{0x01, 0x02});
+        sis = new SpottedInputStream(bis);
+
+        int result;
+
+        result = sis.read();
+        assertEquals(0x01, result);
+
+        result = sis.read();
+        assertEquals(0x02, result);
+
+        result = sis.read();
+        assertEquals(-1, result);
+
+        return;
+    }
+
+    /**
+     * Test of read method, of class SpottedInputStream.
+     */
+    @Test
+    public void testRead_byteArr() throws Exception {
+        System.out.println("read");
+
+        SpottedInputStream sis;
+        ByteArrayInputStream bis;
+
+        bis = new ByteArrayInputStream(new byte[]{0x01, 0x02, 0x03});
+        sis = new SpottedInputStream(bis);
+
+        byte[] buf = new byte[2];
+        int result;
+
+        result = sis.read(buf);
+        assertEquals(2, result);
+        assertEquals((byte)0x01, buf[0]);
+        assertEquals((byte)0x02, buf[1]);
+
+        result = sis.read(buf);
+        assertEquals(1, result);
+        assertEquals((byte)0x03, buf[0]);
+
+        result = sis.read(buf);
+        assertEquals(-1, result);
+
+        return;
+    }
+
+    /**
+     * Test of read method, of class SpottedInputStream.
+     */
+    @Test
+    public void testRead_3args() throws Exception {
+        System.out.println("read");
+
+
+        SpottedInputStream sis;
+        ByteArrayInputStream bis;
+
+        bis = new ByteArrayInputStream(new byte[]{0x01, 0x02, 0x03});
+        sis = new SpottedInputStream(bis);
+
+        byte[] buf = new byte[3];
+        buf[0] = (byte)0xf1;
+        buf[1] = (byte)0xf2;
+        buf[2] = (byte)0xf3;
+        int result;
+
+        result = sis.read(buf, 1, 2);
+        assertEquals(2, result);
+        assertEquals((byte)0xf1, buf[0]);
+        assertEquals((byte)0x01, buf[1]);
+        assertEquals((byte)0x02, buf[2]);
+
+        result = sis.read(buf, 0, 1);
+        assertEquals(1, result);
+        assertEquals((byte)0x03, buf[0]);
+        assertEquals((byte)0x01, buf[1]);
+        assertEquals((byte)0x02, buf[2]);
+
+        result = sis.read(buf, 0, 1);
+        assertEquals(-1, result);
+
+        return;
+    }
+
+    /**
+     * Test of skip method, of class SpottedInputStream.
+     */
+    @Test
+    public void testSkip() throws Exception {
+        System.out.println("skip");
+
+        SpottedInputStream sis;
+        ByteArrayInputStream bis;
+
+        bis = new ByteArrayInputStream(new byte[]{0x11, 0x12, 0x13});
+        sis = new SpottedInputStream(bis);
+
+        int result;
+        long skipped;
+
+        result = sis.read();
+        assertEquals(0x11, result);
+
+        skipped = sis.skip(1L);
+        assertEquals(1L, skipped);
+
+        result = sis.read();
+        assertEquals(0x13, result);
+
+        skipped = sis.skip(1L);
+        assertEquals(0L, skipped);
+
+        return;
+    }
+
+    /**
+     * Test of close method, of class SpottedInputStream.
+     */
+    @Test
+    public void testClose() throws Exception {
+        System.out.println("close");
+
+        SpottedInputStream sis;
+        TestInputStream tis;
+
+        tis = new TestInputStream();
+        sis = new SpottedInputStream(tis);
+
+        assertFalse(tis.closed);
+        sis.close();
+        assertTrue(tis.closed);
+
+        return;
+    }
+
+    /**
+     * Test of getPosition method, of class SpottedInputStream.
+     */
+    @Test
+    public void testGetPosition() throws Exception{
+        System.out.println("getPosition");
+
+        SpottedInputStream sis;
+        ByteArrayInputStream bis;
+
+        bis = new ByteArrayInputStream(new byte[]{0x01,0x02});
+        sis = new SpottedInputStream(bis);
+
+        assertEquals(0L, sis.getPosition());
+
+        sis.read();
+        assertEquals(1L, sis.getPosition());
+
+        sis.read();
+        assertEquals(2L, sis.getPosition());
+
+        sis.read();
+        assertEquals(2L, sis.getPosition());
+
+        return;
+    }
+
+    /**
+     * Test of hasMore method, of class SpottedInputStream.
+     */
+    @Test
+    public void testHasMore() throws Exception {
+        System.out.println("hasMore");
+
+        SpottedInputStream sis;
+        ByteArrayInputStream bis;
+
+        bis = new ByteArrayInputStream(new byte[]{0x01,0x02});
+        sis = new SpottedInputStream(bis);
+
+        assertTrue(sis.hasMore());
+        sis.read();
+        assertTrue(sis.hasMore());
+        sis.read();
+        assertFalse(sis.hasMore());
+
+        return;
+    }
+
+    private static class TestInputStream extends FilterInputStream{
+        public boolean closed = false;
+        public boolean flushed = false;
+
+        TestInputStream(){
+            super(new ByteArrayInputStream(new byte[]{}));
+            return;
+        }
+
+        @Override
+        public void close() throws IOException {
+            super.close();
+            this.closed = true;
+            return;
+        }
+
+    }
+
+}
index da4709a..d09b5fd 100644 (file)
@@ -133,7 +133,7 @@ public class TextDecoderTest {
         TextDecoder decoder;
         byte[] bdata;
         InputStream istream;
-        MmdSource source;
+        MmdInputStream source;
         CharBuffer cb;
 
         decoder = new TextDecoder(CS_WIN31J);
@@ -146,7 +146,7 @@ public class TextDecoderTest {
 
         bdata = byteArray("41:00:42:43");
         istream = new ByteArrayInputStream(bdata);
-        source = new MmdSource(istream);
+        source = new MmdInputStream(istream);
         cb =decoder.parseString(source, 3);
         assertEquals("A", cb.toString());
         cb =decoder.parseString(source, 1);
@@ -178,12 +178,12 @@ public class TextDecoderTest {
 
         byte[] bdata;
         InputStream istream;
-        MmdSource source;
+        MmdInputStream source;
         CharBuffer cb;
 
         bdata = byteArray("88:9F:88:A0");
         istream = new ByteArrayInputStream(bdata);
-        source = new MmdSource(istream);
+        source = new MmdInputStream(istream);
         try{
             cb =decoder.parseString(source, 5);
             fail();
@@ -218,12 +218,12 @@ public class TextDecoderTest {
 
         byte[] bdata;
         InputStream istream;
-        MmdSource source;
+        MmdInputStream source;
         CharBuffer cb;
 
         bdata = byteArray("E4:BA:9C:E5:94:96");
         istream = new ByteArrayInputStream(bdata);
-        source = new MmdSource(istream);
+        source = new MmdInputStream(istream);
         try{
             cb =decoder.parseString(source, 7);
             fail();
@@ -263,11 +263,11 @@ public class TextDecoderTest {
 
         byte[] bdata;
         InputStream istream;
-        MmdSource source;
+        MmdInputStream source;
         CharBuffer cb;
         bdata = byteArray("9C:4E:16:55");
         istream = new ByteArrayInputStream(bdata);
-        source = new MmdSource(istream);
+        source = new MmdInputStream(istream);
         try{
             cb =decoder.parseString(source, 5);
             fail();
@@ -339,19 +339,19 @@ public class TextDecoderTest {
             throws Exception{
         byte[] bdata;
         InputStream istream;
-        MmdSource source;
+        MmdInputStream source;
         CharBuffer cb;
 
         bdata = byteArray(bin);
         istream = new ByteArrayInputStream(bdata);
-        source = new MmdSource(istream);
+        source = new MmdInputStream(istream);
 
         assertDecoded(source, desired, decoder, len);
 
         return;
     }
 
-    public void assertDecoded(MmdSource source, String desired,
+    public void assertDecoded(MmdInputStream source, String desired,
                                 TextDecoder decoder, int len)
             throws Exception{
         CharBuffer cb;
@@ -365,11 +365,11 @@ public class TextDecoderTest {
             throws Exception{
         byte[] bdata;
         InputStream istream;
-        MmdSource source;
+        MmdInputStream source;
 
         bdata = byteArray(bin);
         istream = new ByteArrayInputStream(bdata);
-        source = new MmdSource(istream);
+        source = new MmdInputStream(istream);
 
         try{
             decoder.parseString(source, len);
index 2f5762d..b0f0d1f 100644 (file)
@@ -14,7 +14,7 @@ import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
 import jp.sourceforge.mikutoga.parser.MmdFormatException;
-import jp.sourceforge.mikutoga.parser.MmdSource;
+import jp.sourceforge.mikutoga.parser.MmdInputStream;
 import jp.sourceforge.mikutoga.pmd.parser.PmdParser;
 
 /**
@@ -57,7 +57,7 @@ public class DummyMain {
      * @param fname ファイル名
      * @return 入力ソース
      */
-    private static MmdSource buildSource(String fname){
+    private static MmdInputStream buildSource(String fname){
         File file = new File(fname);
 
         InputStream is;
@@ -70,7 +70,7 @@ public class DummyMain {
         }
         is = new BufferedInputStream(is, BUF_SZ);
 
-        MmdSource source = new MmdSource(is);
+        MmdInputStream source = new MmdInputStream(is);
 
         return source;
     }
@@ -102,7 +102,7 @@ public class DummyMain {
         if(args.length == 1) fname = args[0];
         else                 fname = PMDFILE;
 
-        MmdSource source = buildSource(fname);
+        MmdInputStream source = buildSource(fname);
 
         PmdParser parser = new PmdParser(source);
 
index 5d25cf4..28015cc 100644 (file)
@@ -14,7 +14,7 @@ import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
 import jp.sourceforge.mikutoga.parser.MmdFormatException;
-import jp.sourceforge.mikutoga.parser.MmdSource;
+import jp.sourceforge.mikutoga.parser.MmdInputStream;
 import jp.sourceforge.mikutoga.vmd.parser.VmdParser;
 
 /**
@@ -32,7 +32,7 @@ public class DummyMain {
         VMDFILE = "D:\\Test\\camera.vmd";
     }
 
-    private static MmdSource buildSource(String fname){
+    private static MmdInputStream buildSource(String fname){
         File file = new File(fname);
 
         InputStream is;
@@ -45,7 +45,7 @@ public class DummyMain {
         }
         is = new BufferedInputStream(is, BUF_SZ);
 
-        MmdSource source = new MmdSource(is);
+        MmdInputStream source = new MmdInputStream(is);
 
         return source;
     }
@@ -63,7 +63,7 @@ public class DummyMain {
         if(args.length == 1) fname = args[0];
         else                 fname = VMDFILE;
 
-        MmdSource source = buildSource(fname);
+        MmdInputStream source = buildSource(fname);
 
         VmdParser parser = new VmdParser(source);