OSDN Git Service

modify DecodedContent
authorOlyutorskii <olyutorskii@users.osdn.me>
Wed, 21 Mar 2018 15:10:38 +0000 (00:10 +0900)
committerOlyutorskii <olyutorskii@users.osdn.me>
Wed, 21 Mar 2018 15:10:38 +0000 (00:10 +0900)
src/main/java/jp/osdn/jindolf/parser/content/DecodeErrorInfo.java
src/main/java/jp/osdn/jindolf/parser/content/DecodedContent.java
src/test/java/jp/osdn/jindolf/parser/content/ContentBuilderTest.java
src/test/java/jp/osdn/jindolf/parser/content/DecodeErrorInfoTest.java
src/test/java/jp/osdn/jindolf/parser/content/DecodedContentTest.java

index 6142665..e4e67b9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * invalid Shift_JIS decoding information
+ * invalid character decoding information
  *
  * License : The MIT License
  * Copyright(c) 2009 olyutorskii
@@ -8,12 +8,18 @@
 package jp.osdn.jindolf.parser.content;
 
 import java.util.Comparator;
+import java.util.List;
 
 /**
- * 不正な Shift_JIS デコードの情報。
+ * 文字デコード異常系の発生により
+ * {@link DecodedContent}に代替文字とエラーバイトが埋め込まれた事実を
+ * 記録する。
+ *
+ * <p>エラーの原因となったバイト値に関する情報は、
  * 1バイトもしくは2バイトで構成される。
- * 1バイトの場合はおそらくエンコーディングに関するエラー。
- * 2バイトの場合はおそらく文字集合に関するエラー。
+ * 2バイトの場合はおそらくシフトJISの文字集合に関するエラー。
+ *
+ * <p>{@link DecodedContent}内での代替文字出現位置をchar単位で保持する。
  */
 public class DecodeErrorInfo{
 
@@ -21,23 +27,28 @@ public class DecodeErrorInfo{
     public static final Comparator<DecodeErrorInfo> POS_COMPARATOR =
             new PosComparator();
 
+    private static final int BSEARCH_THRESHOLD = 16;
+
+
     private final int charPos;
     private final boolean has2ndFlag;
     private final byte rawByte1st;
     private final byte rawByte2nd;
 
+
     /**
      * 下請けコンストラクタ。
-     * @param charPos デコードエラーで置き換えられた文字列の開始位置
+     *
+     * @param charPos デコードエラーで置き換えられた代替文字の出現位置
      * @param has2ndFlag 2バイト目が有効ならtrueを渡す。
-     * @param rawByte1st デコードエラーを引き起こした最初のバイト値
+     * @param rawByte1st デコードエラーを引き起こした1番目のバイト値
      * @param rawByte2nd デコードエラーを引き起こした2番目のバイト値
      * @throws IndexOutOfBoundsException charPosが負
      */
     private DecodeErrorInfo(int charPos,
-                              boolean has2ndFlag,
-                              byte rawByte1st,
-                              byte rawByte2nd)
+                            boolean has2ndFlag,
+                            byte rawByte1st,
+                            byte rawByte2nd)
             throws IndexOutOfBoundsException{
         if(charPos < 0) throw new IndexOutOfBoundsException();
 
@@ -51,14 +62,15 @@ public class DecodeErrorInfo{
 
     /**
      * コンストラクタ。
-     * @param charPos デコードエラーで置き換えられた文字列の開始位置
-     * @param rawByte1st デコードエラーを引き起こした最初のバイト値
+     *
+     * @param charPos デコードエラーで置き換えられた代替文字の出現位置
+     * @param rawByte1st デコードエラーを引き起こした1番目のバイト値
      * @param rawByte2nd デコードエラーを引き起こした2番目のバイト値
      * @throws IndexOutOfBoundsException charPosが負
      */
     public DecodeErrorInfo(int charPos,
-                             byte rawByte1st,
-                             byte rawByte2nd)
+                           byte rawByte1st,
+                           byte rawByte2nd)
             throws IndexOutOfBoundsException{
         this(charPos, true, rawByte1st, rawByte2nd);
         return;
@@ -66,27 +78,117 @@ public class DecodeErrorInfo{
 
     /**
      * コンストラクタ。
-     * @param charPos デコードエラーで置き換えられた文字列の開始位置
+     *
+     * @param charPos デコードエラーで置き換えられた代替文字の出現位置
      * @param rawByte1st デコードエラーを引き起こしたバイト値
      * @throws IndexOutOfBoundsException charPosが負
      */
     public DecodeErrorInfo(int charPos,
-                             byte rawByte1st)
+                           byte rawByte1st)
             throws IndexOutOfBoundsException{
         this(charPos, false, rawByte1st, (byte) 0x00);
         return;
     }
 
+
+    /**
+     * 与えられた文字位置を含むか、またはそれ以降で最も小さな位置情報を持つ
+     * デコードエラーのインデックス位置を返す。※リニアサーチ版。
+     *
+     * @param errList デコードエラーのリスト
+     * @param startPos 文字位置
+     * @return 0から始まるリスト内の位置。
+     *     文字位置の一致するデコードエラーがなければ
+     *     リストへの挿入ポイントが返る。
+     */
+    public static int lsearchErrorIndex(List<DecodeErrorInfo> errList,
+                                        int startPos){
+        // assert errList instanceof RandomAccess;
+
+        int listSize = errList.size();
+
+        int idx;
+        for(idx = 0; idx < listSize; idx++){
+            DecodeErrorInfo einfo = errList.get(idx);
+            int errPos = einfo.getCharPosition();
+            if(startPos <= errPos) break;
+        }
+
+        return idx;
+    }
+
+    /**
+     * 与えられた文字位置を含むか、またはそれ以降で最も小さな位置情報を持つ
+     * デコードエラーのインデックス位置を返す。※バイナリサーチ版。
+     *
+     * @param errList デコードエラーのリスト
+     * @param startPos 文字位置
+     * @return 0から始まるリスト内の位置。
+     *     文字位置の一致するデコードエラーがなければ
+     *     リストへの挿入ポイントが返る。
+     */
+    public static int bsearchErrorIndex(List<DecodeErrorInfo> errList,
+                                        int startPos){
+        // assert errList instanceof RandomAccess;
+
+        int floor = 0;
+        int roof  = errList.size() - 1;
+
+        while(floor <= roof){
+            int gapHalf = (roof - floor) / 2;  // 切り捨て
+            int midpoint = floor + gapHalf;
+            DecodeErrorInfo einfo = errList.get(midpoint);
+            int errPos = einfo.getCharPosition();
+
+            if     (errPos < startPos) floor = midpoint + 1;
+            else if(errPos > startPos) roof  = midpoint - 1;
+            else return midpoint;
+        }
+
+        return floor;
+    }
+
     /**
-     * デコードエラーで置き換えられた文字列の開始位置を返す。
-     * @return デコードエラーで置き換えられた文字列の開始位置
+     * 与えられた文字位置を含むか、またはそれ以降で最も小さな位置情報を持つ
+     * デコードエラーのインデックス位置を返す。
+     *
+     * <p>要素数の増減に応じてリニアサーチとバイナリサーチを使い分ける。
+     *
+     * @param errList デコードエラーのリスト
+     * @param startPos 文字位置
+     * @return 0から始まるリスト内の位置。
+     *     文字位置の一致するデコードエラーがなければ
+     *     リストへの挿入ポイントが返る。
+     */
+    public static int searchErrorIndex(List<DecodeErrorInfo> errList,
+                                       int startPos){
+        int result;
+
+        int listSize = errList.size();
+        if(listSize < BSEARCH_THRESHOLD){
+            // linear-search
+            result = lsearchErrorIndex(errList, startPos);
+        }else{
+            // binary-search
+            result = bsearchErrorIndex(errList, startPos);
+        }
+
+        return result;
+    }
+
+
+    /**
+     * エラー代替文字の出現位置を返す。
+     *
+     * @return 代替文字の開始位置
      */
     public int getCharPosition(){
         return this.charPos;
     }
 
     /**
-     * 2バイト目の情報を持つか判定する。
+     * 2バイト目のエラー情報を持つか判定する。
+     *
      * @return 2バイト目の情報を持つならtrue
      */
     public boolean has2nd(){
@@ -94,7 +196,8 @@ public class DecodeErrorInfo{
     }
 
     /**
-     * 1バイト目の値を返す。
+     * 1バイト目のエラーバイト値を返す。
+     *
      * @return 1バイト目の値
      */
     public byte getRawByte1st(){
@@ -102,7 +205,8 @@ public class DecodeErrorInfo{
     }
 
     /**
-     * 2バイト目の値を返す。
+     * 2バイト目のエラーバイト値を返す。
+     *
      * @return 2バイト目の値
      * @throws IllegalStateException 2バイト目の情報を把持していないとき
      */
@@ -113,27 +217,26 @@ public class DecodeErrorInfo{
 
     /**
      * 出現位置のみが違う複製オブジェクトを生成する。
+     *
      * @param gap 出現位置から引きたい値。正の値なら文字開始位置に向かう。
      * @return 複製オブジェクト
      * @throws IndexOutOfBoundsException 再計算された出現位置が負
      */
     public DecodeErrorInfo createGappedClone(int gap)
             throws IndexOutOfBoundsException{
-        DecodeErrorInfo result;
-
         int newPos = this.charPos - gap;
-        if(this.has2ndFlag){
-            result = new DecodeErrorInfo(newPos,
-                                         this.rawByte1st, this.rawByte2nd);
-        }else{
-            result = new DecodeErrorInfo(newPos, this.rawByte1st);
-        }
+
+        DecodeErrorInfo result;
+        result = new DecodeErrorInfo(newPos,
+                                     this.has2ndFlag,
+                                     this.rawByte1st, this.rawByte2nd);
 
         return result;
     }
 
     /**
      * {@inheritDoc}
+     *
      * @return {@inheritDoc}
      */
     @Override
@@ -148,8 +251,8 @@ public class DecodeErrorInfo{
         result.append(hex);
 
         if(this.has2ndFlag){
-            hex = Integer.toHexString(this.rawByte2nd & 0xff);
             result.append(':');
+            hex = Integer.toHexString(this.rawByte2nd & 0xff);
             if(hex.length() <= 1) result.append('0');
             result.append(hex);
         }
@@ -160,6 +263,7 @@ public class DecodeErrorInfo{
     /**
      * 出現位置で順序づける比較子。
      */
+    @SuppressWarnings("serial")
     private static final class PosComparator
             implements Comparator<DecodeErrorInfo> {
 
@@ -173,22 +277,26 @@ public class DecodeErrorInfo{
 
         /**
          * {@inheritDoc}
+         *
          * @param info1 {@inheritDoc}
          * @param info2 {@inheritDoc}
          * @return {@inheritDoc}
          */
         @Override
         public int compare(DecodeErrorInfo info1, DecodeErrorInfo info2){
-            int pos1;
-            int pos2;
+            if     (info1 == info2) return 0;
+            else if(info1 == null)  return -1;
+            else if(info2 == null)  return 1;
 
-            if(info1 == null) pos1 = -1;
-            else              pos1 = info1.charPos;
+            int pos1 = info1.charPos;
+            int pos2 = info2.charPos;
 
-            if(info2 == null) pos2 = -1;
-            else              pos2 = info2.charPos;
+            int result;
+            if     (pos1 < pos2) result = -1;
+            else if(pos1 > pos2) result = 1;
+            else                 result = 0;
 
-            return pos1 - pos2;
+            return result;
         }
 
     }
index c5567c2..17e092f 100644 (file)
@@ -24,16 +24,14 @@ public class DecodedContent
 
     /**
      * 代替文字。
-     * {@literal HTMLで使うなら < や > や & や " や ' はやめて!}
+     *
+     * <p>{@literal HTMLで使うなら < や > や & や " や ' はやめて!}
      */
     public static final char ALTCHAR = '?';
 
     private static final String NULLTEXT = "null";
 
-    private static final List<DecodeErrorInfo> EMPTY_LIST =
-            Collections.emptyList();
-
-    private static final int BSEARCH_THRESHOLD = 16;
+    private static final List<DecodeErrorInfo> EMPTY_LIST;
 
     static{
         assert ALTCHAR != '<';
@@ -42,6 +40,11 @@ public class DecodedContent
         assert ALTCHAR != '"';
         assert ALTCHAR != '\'';
         assert ALTCHAR != '\\';
+
+        List<DecodeErrorInfo> emptyList;
+        emptyList = Collections.emptyList();
+        emptyList = Collections.unmodifiableList(emptyList);
+        EMPTY_LIST = emptyList;
     }
 
 
@@ -60,6 +63,7 @@ public class DecodedContent
 
     /**
      * コンストラクタ。
+     *
      * @param seq 初期化文字列
      * @throws NullPointerException 引数がnull
      */
@@ -73,6 +77,7 @@ public class DecodedContent
 
     /**
      * コンストラクタ。
+     *
      * @param capacity 文字数の初期容量
      * @throws NegativeArraySizeException 容量が負の値
      */
@@ -86,88 +91,13 @@ public class DecodedContent
 
 
     /**
-     * 与えられた文字位置を含むか、またはそれ以降で最も小さな位置情報を持つ
-     * デコードエラーのインデックス位置を返す。※リニアサーチ版。
-     * @param errList デコードエラーのリスト
-     * @param startPos 文字位置
-     * @return 0から始まるリスト内の位置。
-     *     一致する文字位置がなければ挿入ポイント。
-     */
-    protected static int lsearchErrorIndex(List<DecodeErrorInfo> errList,
-                                             int startPos){
-        // assert errList instanceof RandomAccess;
-
-        int errSize = errList.size();
-
-        int idx;
-        for(idx = 0; idx < errSize; idx++){
-            DecodeErrorInfo einfo = errList.get(idx);
-            int errPos = einfo.getCharPosition();
-            if(startPos <= errPos) break;
-        }
-
-        return idx;
-    }
-
-    /**
-     * 与えられた文字位置を含むか、またはそれ以降で最も小さな位置情報を持つ
-     * デコードエラーのインデックス位置を返す。※バイナリサーチ版。
-     * @param errList デコードエラーのリスト
-     * @param startPos 文字位置
-     * @return 0から始まるリスト内の位置。
-     *     一致する文字位置がなければ挿入ポイント。
-     */
-    protected static int bsearchErrorIndex(List<DecodeErrorInfo> errList,
-                                             int startPos){
-        // assert errList instanceof RandomAccess;
-
-        int floor = 0;
-        int roof  = errList.size() - 1;
-
-        while(floor <= roof){
-            int gapHalf = (roof - floor) / 2;  // 切り捨て
-            int midpoint = floor + gapHalf;
-            DecodeErrorInfo einfo = errList.get(midpoint);
-            int cmp = einfo.getCharPosition() - startPos;
-
-            if     (cmp < 0) floor = midpoint + 1;
-            else if(cmp > 0) roof  = midpoint - 1;
-            else return midpoint;
-        }
-
-        return floor;
-    }
-
-    /**
-     * 与えられた文字位置を含むか、またはそれ以降で最も小さな位置情報を持つ
-     * デコードエラーのインデックス位置を返す。
-     * 要素数の増減に応じてリニアサーチとバイナリサーチを使い分ける。
-     * @param errList デコードエラーのリスト
-     * @param startPos 文字位置
-     * @return 0から始まるリスト内の位置。
-     *     一致する文字位置がなければ挿入ポイント。
-     */
-    protected static int searchErrorIndex(List<DecodeErrorInfo> errList,
-                                            int startPos){
-        int result;
-
-        int errSize = errList.size();
-        if(errSize < BSEARCH_THRESHOLD){
-            // linear-search
-            result = lsearchErrorIndex(errList, startPos);
-        }else{
-            // binary-search
-            result = bsearchErrorIndex(errList, startPos);
-        }
-
-        return result;
-    }
-
-    /**
      * ギャップ情報が加味されたデコードエラー情報を、
-     * 範囲指定込みで指定エラーリストに追加転記する。
-     * 追加先エラーリストがnullだった場合、必要に応じてエラーリストが生成され
+     * 範囲指定込みで指定エラーリストに追加コピーする。
+     *
+     * <p>追加先エラーリストがnullだった場合、
+     * 必要に応じてエラーリストが生成され
      * 戻り値となる場合がありうる。
+     *
      * @param sourceContent 元の文字列
      * @param startPos 範囲開始位置
      * @param endPos 範囲終了位置
@@ -177,33 +107,75 @@ public class DecodedContent
      */
     protected static List<DecodeErrorInfo>
             appendGappedErrorInfo(DecodedContent sourceContent,
-                                     int startPos, int endPos,
-                                     List<DecodeErrorInfo> targetError,
-                                     int gap){
-        List<DecodeErrorInfo> sourceError = sourceContent.decodeError;
-        List<DecodeErrorInfo> result = targetError;
+                                  int startPos, int endPos,
+                                  List<DecodeErrorInfo> targetError,
+                                  int gap){
+        List<DecodeErrorInfo> errList = sourceContent.decodeError;
+        int errSize = errList.size();
+        assert errSize > 0;
 
-        int startErrorIdx = searchErrorIndex(sourceError, startPos);
-        int endErrorIdx = sourceError.size() - 1;
-        assert endErrorIdx >= 0;
+        int startErrorIdx;
+        int endErrorIdx;
 
-        for(int index = startErrorIdx; index <= endErrorIdx; index++){
-            DecodeErrorInfo einfo = sourceError.get(index);
-            int pos = einfo.getCharPosition();
-            if(pos < startPos) continue;
-            if(pos >= endPos) break;
-            DecodeErrorInfo newInfo = einfo.createGappedClone(gap);
-            if(result == null){
-                result = createErrorList();
+        startErrorIdx = DecodeErrorInfo.searchErrorIndex(errList, startPos);
+        if(startErrorIdx >= errSize){
+            return null;
+        }
+
+        int lastCharPos = endPos - 1;
+        endErrorIdx = DecodeErrorInfo.searchErrorIndex(errList, lastCharPos);
+        if(endErrorIdx >= errSize){
+            endErrorIdx = errSize - 1;
+        }else{
+            DecodeErrorInfo lastErrorInfo = errList.get(endErrorIdx);
+            boolean isLastErrorInfoOnLastPos =
+                    lastErrorInfo.getCharPosition() == lastCharPos;
+            if( ! isLastErrorInfoOnLastPos){
+                endErrorIdx--;
             }
-            result.add(newInfo);
         }
 
+        boolean hasLoop =
+                (0 <= startErrorIdx) && (startErrorIdx <= endErrorIdx);
+        if( ! hasLoop){
+            return null;
+        }
+
+        List<DecodeErrorInfo> result;
+        if(targetError == null) result = createErrorList();
+        else                    result = targetError;
+
+        copyGappedErrorInfo(errList,
+                            startErrorIdx, endErrorIdx,
+                            result, gap);
         return result;
     }
 
     /**
+     * エラーリストの一部の範囲を、gapを加味して別リストに追加コピーする。
+     *
+     * @param srcErrList コピー元リスト
+     * @param startErrorIdx コピー元の範囲開始インデックス
+     * @param endErrorIdx コピー元の範囲終了インデックス
+     * @param dstErrList コピー先リスト
+     * @param gap 代替文字出現位置ギャップ量
+     */
+    private static void
+            copyGappedErrorInfo(List<DecodeErrorInfo> srcErrList,
+                                int startErrorIdx, int endErrorIdx,
+                                List<DecodeErrorInfo> dstErrList,
+                                int gap){
+        for(int index = startErrorIdx; index <= endErrorIdx; index++){
+            DecodeErrorInfo srcErrInfo = srcErrList.get(index);
+            DecodeErrorInfo gappedInfo = srcErrInfo.createGappedClone(gap);
+            dstErrList.add(gappedInfo);
+        }
+        return;
+    }
+
+    /**
      * エラー格納用リストを生成する。
+     *
      * @return リスト
      */
     private static List<DecodeErrorInfo> createErrorList(){
@@ -215,9 +187,11 @@ public class DecodedContent
         assert createErrorList() instanceof RandomAccess;
     }
 
+
     /**
      * 初期化下請け。
-     * 長さ0の文字列&デコードエラー無しの状態になる。
+     *
+     * <p>長さ0の文字列&デコードエラー無しの状態になる。
      */
     private void initImpl(){
         this.rawContent.setLength(0);
@@ -231,7 +205,9 @@ public class DecodedContent
 
     /**
      * 事前にキャパシティを確保する。
-     * 指定されたキャパシティの範囲内で再割り当てが起きないことを保証する。
+     *
+     * <p>指定されたキャパシティの範囲内で再割り当てが起きないことを保証する。
+     *
      * @param minimumCapacity キャラクタ単位のキャパシティ長。
      */
     public void ensureCapacity(int minimumCapacity){
@@ -241,7 +217,8 @@ public class DecodedContent
 
     /**
      * 初期化。
-     * 長さ0の文字列&デコードエラー無しの状態になる。
+     *
+     * <p>長さ0の文字列&デコードエラー無しの状態になる。
      * コンストラクタで新インスタンスを作るより低コスト。
      */
     public void init(){
@@ -251,6 +228,7 @@ public class DecodedContent
 
     /**
      * デコードエラーを含むか判定する。
+     *
      * @return デコードエラーを含むならtrue
      */
     public boolean hasDecodeError(){
@@ -261,6 +239,7 @@ public class DecodedContent
 
     /**
      * デコードエラーの一覧を取得する。
+     *
      * @return デコードエラーの一覧
      */
     public List<DecodeErrorInfo> getDecodeErrorList(){
@@ -272,7 +251,9 @@ public class DecodedContent
 
     /**
      * 生の文字列を得る。
-     * 高速なCharSequenceアクセス用途。
+     *
+     * <p>高速なCharSequenceアクセス用途。
+     *
      * @return 生の文字列。
      */
     public CharSequence getRawContent(){
@@ -281,6 +262,7 @@ public class DecodedContent
 
     /**
      * 指定された位置の文字を変更する。
+     *
      * @param index 文字位置
      * @param ch 文字
      * @throws IndexOutOfBoundsException 不正な位置指定
@@ -293,6 +275,7 @@ public class DecodedContent
 
     /**
      * {@inheritDoc}
+     *
      * @param index {@inheritDoc}
      * @return {@inheritDoc}
      */
@@ -303,6 +286,7 @@ public class DecodedContent
 
     /**
      * {@inheritDoc}
+     *
      * @return {@inheritDoc}
      */
     @Override
@@ -312,6 +296,7 @@ public class DecodedContent
 
     /**
      * {@inheritDoc}
+     *
      * @param start {@inheritDoc}
      * @param end {@inheritDoc}
      * @return {@inheritDoc}
@@ -323,7 +308,9 @@ public class DecodedContent
 
     /**
      * 範囲指定されたサブコンテントを切り出す。
-     * サブコンテントにはデコードエラー情報が引き継がれる。
+     *
+     * <p>サブコンテントにはデコードエラー情報が引き継がれる。
+     *
      * @param start 開始位置
      * @param end 終了位置
      * @return サブコンテント
@@ -342,6 +329,7 @@ public class DecodedContent
 
     /**
      * 文字を追加する。
+     *
      * @param letter 追加する文字
      * @return thisオブジェクト
      */
@@ -353,6 +341,7 @@ public class DecodedContent
 
     /**
      * 文字列を追加する。
+     *
      * @param seq 追加する文字列
      * @return thisオブジェクト
      */
@@ -370,6 +359,7 @@ public class DecodedContent
 
     /**
      * 文字列を追加する。
+     *
      * @param seq 追加する文字列
      * @param startPos 開始位置
      * @param endPos 終了位置
@@ -413,6 +403,7 @@ public class DecodedContent
 
     /**
      * 文字列を追加する。
+     *
      * @param source 追加する文字列
      * @param startPos 開始位置
      * @param endPos 終了位置
@@ -420,7 +411,7 @@ public class DecodedContent
      * @throws IndexOutOfBoundsException 範囲指定が変。
      */
     public DecodedContent append(DecodedContent source,
-                                  int startPos, int endPos)
+                                 int startPos, int endPos)
             throws IndexOutOfBoundsException{
         if(source == null){
             return append(NULLTEXT);
@@ -429,7 +420,6 @@ public class DecodedContent
         int gap = startPos - this.rawContent.length();
 
         this.rawContent.append(source.rawContent, startPos, endPos);
-
         if( ! source.hasDecodeError() ) return this;
 
         List<DecodeErrorInfo> targetErrorList;
@@ -455,8 +445,10 @@ public class DecodedContent
 
     /**
      * 代替文字とともにデコードエラーを追加する。
-     * ※呼び出し側は、追加されるデコードエラーの位置情報が
+     *
+     * <p>※呼び出し側は、追加されるデコードエラーの位置情報が
      * 既存のデコードエラーよりも大きいことを保証しなければならない。
+     *
      * @param errorInfo デコードエラー
      */
     private void addDecodeError(DecodeErrorInfo errorInfo){
@@ -470,6 +462,7 @@ public class DecodedContent
 
     /**
      * 代替文字とともにデコードエラーを追加する。
+     *
      * @param b1st 1バイト目の値
      */
     public void addDecodeError(byte b1st){
@@ -496,6 +489,7 @@ public class DecodedContent
 
     /**
      * {@inheritDoc}
+     *
      * @return {@inheritDoc}
      */
     @Override
index 41404ba..9739c9c 100644 (file)
@@ -259,36 +259,6 @@ public class ContentBuilderTest {
         return;
     }
 
-    /**
-     * Test of UTF16 mapping error
-     * @throws Exception
-     */
-    @Test
-    public void testUTF16_nomap() throws Exception {
-        Charset cs = Charset.forName("UTF-16");
-
-        CharsetDecoder cd;
-        ContentBuilder cb;
-        DecodeNotifier decoder;
-        byte[] bdata;
-        InputStream is;
-        DecodedContent content;
-
-        cd = cs.newDecoder();
-        decoder = new DecodeNotifier(cd);
-        cb = new ContentBuilder();
-        decoder.setCharDecodeListener(cb);
-        bdata = Bseq.byteArray("0041:d83d:dc11:0042");
-        is = new ByteArrayInputStream(bdata);
-        decoder.decode(is);
-        content = cb.getContent();
-
-        assertEquals(4, content.length());
-        assertEquals("A\ud83d\udc11B", content.toString());
-
-        return;
-    }
-
     @Test
     public void testSheep() throws IOException, DecodeBreakException {
         System.out.println("sheep");
index ab2db1b..9ac6754 100644 (file)
@@ -5,6 +5,8 @@
 
 package jp.osdn.jindolf.parser.content;
 
+import java.util.ArrayList;
+import java.util.List;
 import org.junit.After;
 import org.junit.AfterClass;
 import org.junit.Before;
@@ -43,26 +45,34 @@ public class DecodeErrorInfoTest {
     public void testConstructor(){
         System.out.println("Constructor");
 
-        new DecodeErrorInfo(99, (byte)0xfe);
-        new DecodeErrorInfo(999, (byte)0x87, (byte)0x40);
+        DecodeErrorInfo info;
+
+        info = new DecodeErrorInfo(99, (byte)0xfe);
+        assertNotNull(info);
+
+        info = new DecodeErrorInfo(999, (byte)0x87, (byte)0x40);
+        assertNotNull(info);
 
-        new DecodeErrorInfo(0, (byte)0xfe);
-        new DecodeErrorInfo(0, (byte)0x87, (byte)0x40);
+        info = new DecodeErrorInfo(0, (byte)0xfe);
+        assertNotNull(info);
+
+        info = new DecodeErrorInfo(0, (byte)0x87, (byte)0x40);
+        assertNotNull(info);
 
         try{
-            new DecodeErrorInfo(-1, (byte)0xfe);
+            info = new DecodeErrorInfo(-1, (byte)0xfe);
             fail();
+            info.hashCode();
         }catch(IndexOutOfBoundsException e){
-        }catch(Throwable e){
-            fail();
+            // GOOD
         }
 
         try{
-            new DecodeErrorInfo(-1, (byte)0x87, (byte)0x40);
+            info = new DecodeErrorInfo(-1, (byte)0x87, (byte)0x40);
             fail();
+            info.hashCode();
         }catch(IndexOutOfBoundsException e){
-        }catch(Throwable e){
-            fail();
+            // GOOD
         }
 
         return;
@@ -77,6 +87,9 @@ public class DecodeErrorInfoTest {
 
         DecodeErrorInfo info;
 
+        info = new DecodeErrorInfo(0, (byte)0xfe);
+        assertEquals(0, info.getCharPosition());
+
         info = new DecodeErrorInfo(99, (byte)0xfe);
         assertEquals(99, info.getCharPosition());
 
@@ -136,8 +149,7 @@ public class DecodeErrorInfoTest {
             info.getRawByte2nd();
             fail();
         }catch(IllegalStateException e){
-        }catch(Throwable e){
-            fail();
+            // GOOD
         }
 
         info = new DecodeErrorInfo(999, (byte)0x87, (byte)0x40);
@@ -183,18 +195,18 @@ public class DecodeErrorInfoTest {
         try{
             info = info.createGappedClone(100);
             fail();
+            info.hashCode();
         }catch(IndexOutOfBoundsException e){
-        }catch(Throwable e){
-            fail();
+            // GOOD
         }
 
         info = new DecodeErrorInfo(999, (byte)0x87, (byte)0x40);
         try{
             info = info.createGappedClone(1000);
             fail();
+            info.hashCode();
         }catch(IndexOutOfBoundsException e){
-        }catch(Throwable e){
-            fail();
+            // GOOD
         }
 
         return;
@@ -225,6 +237,137 @@ public class DecodeErrorInfoTest {
     }
 
     /**
+     * Test of lsearchErrorIndex method, of class DecodedContent.
+     */
+    @Test
+    public void testLsearchErrorIndex(){
+        System.out.println("lsearchErrorIndex");
+
+        List<DecodeErrorInfo> errList;
+        int result;
+
+        errList = new ArrayList<>();
+        result = DecodeErrorInfo.lsearchErrorIndex(errList, 10);
+        assertEquals(0, result);
+
+        errList.clear();
+        errList.add(new DecodeErrorInfo(5, (byte)0x00));
+        result = DecodeErrorInfo.lsearchErrorIndex(errList, 10);
+        assertEquals(1, result);
+
+        errList.clear();
+        errList.add(new DecodeErrorInfo(10, (byte)0x00));
+        result = DecodeErrorInfo.lsearchErrorIndex(errList, 10);
+        assertEquals(0, result);
+
+        errList.clear();
+        errList.add(new DecodeErrorInfo(15, (byte)0x00));
+        result = DecodeErrorInfo.lsearchErrorIndex(errList, 10);
+        assertEquals(0, result);
+
+        errList.clear();
+        errList.add(new DecodeErrorInfo(4, (byte)0x00));
+        errList.add(new DecodeErrorInfo(5, (byte)0x00));
+        errList.add(new DecodeErrorInfo(14, (byte)0x00));
+        errList.add(new DecodeErrorInfo(15, (byte)0x00));
+        result = DecodeErrorInfo.lsearchErrorIndex(errList, 10);
+        assertEquals(2, result);
+
+        errList.clear();
+        errList.add(new DecodeErrorInfo(4, (byte)0x00));
+        errList.add(new DecodeErrorInfo(5, (byte)0x00));
+        errList.add(new DecodeErrorInfo(10, (byte)0x00));
+        errList.add(new DecodeErrorInfo(14, (byte)0x00));
+        errList.add(new DecodeErrorInfo(15, (byte)0x00));
+        result = DecodeErrorInfo.lsearchErrorIndex(errList, 10);
+        assertEquals(2, result);
+
+        return;
+     }
+
+    /**
+     * Test of bsearchErrorIndex method, of class DecodedContent.
+     */
+    @Test
+    public void testBsearchErrorIndex(){
+        System.out.println("bsearchErrorIndex");
+
+        List<DecodeErrorInfo> errList;
+        int result;
+
+        errList = new ArrayList<>();
+        result = DecodeErrorInfo.bsearchErrorIndex(errList, 10);
+        assertEquals(0, result);
+
+        errList.clear();
+        errList.add(new DecodeErrorInfo(5, (byte)0x00));
+        result = DecodeErrorInfo.bsearchErrorIndex(errList, 10);
+        assertEquals(1, result);
+
+        errList.clear();
+        errList.add(new DecodeErrorInfo(10, (byte)0x00));
+        result = DecodeErrorInfo.bsearchErrorIndex(errList, 10);
+        assertEquals(0, result);
+
+        errList.clear();
+        errList.add(new DecodeErrorInfo(15, (byte)0x00));
+        result = DecodeErrorInfo.bsearchErrorIndex(errList, 10);
+        assertEquals(0, result);
+
+        errList.clear();
+        errList.add(new DecodeErrorInfo(4, (byte)0x00));
+        errList.add(new DecodeErrorInfo(5, (byte)0x00));
+        errList.add(new DecodeErrorInfo(14, (byte)0x00));
+        errList.add(new DecodeErrorInfo(15, (byte)0x00));
+        result = DecodeErrorInfo.bsearchErrorIndex(errList, 10);
+        assertEquals(2, result);
+
+        errList.clear();
+        errList.add(new DecodeErrorInfo(4, (byte)0x00));
+        errList.add(new DecodeErrorInfo(5, (byte)0x00));
+        errList.add(new DecodeErrorInfo(10, (byte)0x00));
+        errList.add(new DecodeErrorInfo(14, (byte)0x00));
+        errList.add(new DecodeErrorInfo(15, (byte)0x00));
+        result = DecodeErrorInfo.bsearchErrorIndex(errList, 10);
+        assertEquals(2, result);
+        result = DecodeErrorInfo.bsearchErrorIndex(errList, 9);
+        assertEquals(2, result);
+        result = DecodeErrorInfo.bsearchErrorIndex(errList, 11);
+        assertEquals(3, result);
+
+        return;
+    }
+
+    /**
+     * Test of searchErrorIndex method, of class DecodedContent.
+     */
+    @Test
+    public void testSearchErrorIndex(){
+        System.out.println("searchErrorIndex");
+
+        List<DecodeErrorInfo> errList;
+        int result;
+
+        errList = new ArrayList<>();
+
+        errList.clear();
+        for(int pos = 0; pos <= 1000; pos += 10){
+            errList.add(new DecodeErrorInfo(pos, (byte)0x00));
+        }
+        result = DecodeErrorInfo.searchErrorIndex(errList, 503);
+        assertEquals(51, result);
+
+        errList.clear();
+        for(int pos = 0; pos <= 50; pos += 10){
+            errList.add(new DecodeErrorInfo(pos, (byte)0x00));
+        }
+        result = DecodeErrorInfo.searchErrorIndex(errList, 23);
+        assertEquals(3, result);
+
+        return;
+    }
+
+    /**
      * Test of POS_COMPARATOR.
      */
     @Test
@@ -234,16 +377,16 @@ public class DecodeErrorInfoTest {
         DecodeErrorInfo info;
         DecodeErrorInfo other;
 
-        info  = new DecodeErrorInfo(99, (byte)0xfe);
-        other = new DecodeErrorInfo(98, (byte)0xfe);
+        info  = new DecodeErrorInfo(99, (byte)0xf1);
+        other = new DecodeErrorInfo(98, (byte)0xf2);
         assertTrue(DecodeErrorInfo.POS_COMPARATOR.compare(info, other) > 0);
 
-        info  = new DecodeErrorInfo(99, (byte)0xfe);
-        other = new DecodeErrorInfo(100, (byte)0xfe);
+        info  = new DecodeErrorInfo(99, (byte)0xf3);
+        other = new DecodeErrorInfo(100, (byte)0xf4);
         assertTrue(DecodeErrorInfo.POS_COMPARATOR.compare(info, other) < 0);
 
-        info  = new DecodeErrorInfo(99, (byte)0xfe);
-        other = new DecodeErrorInfo(99, (byte)0xfe);
+        info  = new DecodeErrorInfo(99, (byte)0xf5);
+        other = new DecodeErrorInfo(99, (byte)0xf6);
         assertTrue(DecodeErrorInfo.POS_COMPARATOR.compare(info, other) == 0);
 
         assertTrue(DecodeErrorInfo.POS_COMPARATOR.compare(null, other) < 0);
index 48a85dd..4894a3a 100644 (file)
@@ -5,7 +5,6 @@
 
 package jp.osdn.jindolf.parser.content;
 
-import java.util.ArrayList;
 import java.util.List;
 import org.junit.After;
 import org.junit.AfterClass;
@@ -372,6 +371,8 @@ public class DecodedContentTest {
         CharSequence seq = "abc";
         content.append(seq);
         assertEquals("abc", content.toString());
+        content.append(null);
+        assertEquals("abcnull", content.toString());
 
         return;
     }
@@ -392,6 +393,8 @@ public class DecodedContentTest {
         CharSequence seq = "12345";
         content.append(seq, 1, 4);
         assertEquals("abc234", content.toString());
+        content.append((CharSequence)null, 1, 2);
+        assertEquals("abc234null", content.toString());
 
         return;
     }
@@ -462,6 +465,8 @@ public class DecodedContentTest {
         char[] seq = {'1','2','3','4','5',};
         content.append(seq, 1, 3);
         assertEquals("abc234", content.toString());
+        content.append((char[])null, 1, 2);
+        assertEquals("abc234null", content.toString());
 
         return;
     }
@@ -558,137 +563,6 @@ public class DecodedContentTest {
     }
 
     /**
-     * Test of lsearchErrorIndex method, of class DecodedContent.
-     */
-    @Test
-    public void testLsearchErrorIndex(){
-        System.out.println("lsearchErrorIndex");
-
-        List<DecodeErrorInfo> errList;
-        int result;
-
-        errList = new ArrayList<>();
-        result = DecodedContent.lsearchErrorIndex(errList, 10);
-        assertEquals(0, result);
-
-        errList.clear();
-        errList.add(new DecodeErrorInfo(5, (byte)0x00));
-        result = DecodedContent.lsearchErrorIndex(errList, 10);
-        assertEquals(1, result);
-
-        errList.clear();
-        errList.add(new DecodeErrorInfo(10, (byte)0x00));
-        result = DecodedContent.lsearchErrorIndex(errList, 10);
-        assertEquals(0, result);
-
-        errList.clear();
-        errList.add(new DecodeErrorInfo(15, (byte)0x00));
-        result = DecodedContent.lsearchErrorIndex(errList, 10);
-        assertEquals(0, result);
-
-        errList.clear();
-        errList.add(new DecodeErrorInfo(4, (byte)0x00));
-        errList.add(new DecodeErrorInfo(5, (byte)0x00));
-        errList.add(new DecodeErrorInfo(14, (byte)0x00));
-        errList.add(new DecodeErrorInfo(15, (byte)0x00));
-        result = DecodedContent.lsearchErrorIndex(errList, 10);
-        assertEquals(2, result);
-
-        errList.clear();
-        errList.add(new DecodeErrorInfo(4, (byte)0x00));
-        errList.add(new DecodeErrorInfo(5, (byte)0x00));
-        errList.add(new DecodeErrorInfo(10, (byte)0x00));
-        errList.add(new DecodeErrorInfo(14, (byte)0x00));
-        errList.add(new DecodeErrorInfo(15, (byte)0x00));
-        result = DecodedContent.lsearchErrorIndex(errList, 10);
-        assertEquals(2, result);
-
-        return;
-     }
-
-    /**
-     * Test of bsearchErrorIndex method, of class DecodedContent.
-     */
-    @Test
-    public void testBsearchErrorIndex(){
-        System.out.println("bsearchErrorIndex");
-
-        List<DecodeErrorInfo> errList;
-        int result;
-
-        errList = new ArrayList<>();
-        result = DecodedContent.bsearchErrorIndex(errList, 10);
-        assertEquals(0, result);
-
-        errList.clear();
-        errList.add(new DecodeErrorInfo(5, (byte)0x00));
-        result = DecodedContent.bsearchErrorIndex(errList, 10);
-        assertEquals(1, result);
-
-        errList.clear();
-        errList.add(new DecodeErrorInfo(10, (byte)0x00));
-        result = DecodedContent.bsearchErrorIndex(errList, 10);
-        assertEquals(0, result);
-
-        errList.clear();
-        errList.add(new DecodeErrorInfo(15, (byte)0x00));
-        result = DecodedContent.bsearchErrorIndex(errList, 10);
-        assertEquals(0, result);
-
-        errList.clear();
-        errList.add(new DecodeErrorInfo(4, (byte)0x00));
-        errList.add(new DecodeErrorInfo(5, (byte)0x00));
-        errList.add(new DecodeErrorInfo(14, (byte)0x00));
-        errList.add(new DecodeErrorInfo(15, (byte)0x00));
-        result = DecodedContent.bsearchErrorIndex(errList, 10);
-        assertEquals(2, result);
-
-        errList.clear();
-        errList.add(new DecodeErrorInfo(4, (byte)0x00));
-        errList.add(new DecodeErrorInfo(5, (byte)0x00));
-        errList.add(new DecodeErrorInfo(10, (byte)0x00));
-        errList.add(new DecodeErrorInfo(14, (byte)0x00));
-        errList.add(new DecodeErrorInfo(15, (byte)0x00));
-        result = DecodedContent.bsearchErrorIndex(errList, 10);
-        assertEquals(2, result);
-        result = DecodedContent.bsearchErrorIndex(errList, 9);
-        assertEquals(2, result);
-        result = DecodedContent.bsearchErrorIndex(errList, 11);
-        assertEquals(3, result);
-
-        return;
-    }
-
-    /**
-     * Test of searchErrorIndex method, of class DecodedContent.
-     */
-    @Test
-    public void testSearchErrorIndex(){
-        System.out.println("searchErrorIndex");
-
-        List<DecodeErrorInfo> errList;
-        int result;
-
-        errList = new ArrayList<>();
-
-        errList.clear();
-        for(int pos = 0; pos <= 1000; pos += 10){
-            errList.add(new DecodeErrorInfo(pos, (byte)0x00));
-        }
-        result = DecodedContent.searchErrorIndex(errList, 503);
-        assertEquals(51, result);
-
-        errList.clear();
-        for(int pos = 0; pos <= 50; pos += 10){
-            errList.add(new DecodeErrorInfo(pos, (byte)0x00));
-        }
-        result = DecodedContent.searchErrorIndex(errList, 23);
-        assertEquals(3, result);
-
-        return;
-    }
-
-    /**
      * Test of appendGappedErrorInfo method, of class DecodedContent.
      */
     @Test