OSDN Git Service

d9ea5c9d7dde264749e8a4eeb0a5c851af81fedf
[jindolf/JinParser.git] / src / main / java / jp / sourceforge / jindolf / parser / DecodeErrorInfo.java
1 /*
2  * invalid Shift_JIS decoding information
3  *
4  * License : The MIT License
5  * Copyright(c) 2009 olyutorskii
6  */
7
8 package jp.sourceforge.jindolf.parser;
9
10 import java.util.Comparator;
11
12 /**
13  * 不正な Shift_JIS デコードの情報。
14  * 1バイトもしくは2バイトで構成される。
15  * 1バイトの場合はおそらくエンコーディングに関するエラー。
16  * 2バイトの場合はおそらく文字集合に関するエラー。
17  */
18 public class DecodeErrorInfo{
19
20     /** 出現位置順Comparator。 */
21     public static final Comparator<DecodeErrorInfo> POS_COMPARATOR =
22             new PosComparator();
23
24     private final int charPos;
25     private final boolean has2ndFlag;
26     private final byte rawByte1st;
27     private final byte rawByte2nd;
28
29     /**
30      * 下請けコンストラクタ。
31      * @param charPos デコードエラーで置き換えられた文字列の開始位置
32      * @param has2ndFlag 2バイト目が有効ならtrueを渡す。
33      * @param rawByte1st デコードエラーを引き起こした最初のバイト値
34      * @param rawByte2nd デコードエラーを引き起こした2番目のバイト値
35      * @throws IndexOutOfBoundsException charPosが負
36      */
37     private DecodeErrorInfo(int charPos,
38                               boolean has2ndFlag,
39                               byte rawByte1st,
40                               byte rawByte2nd)
41             throws IndexOutOfBoundsException{
42         if(charPos < 0) throw new IndexOutOfBoundsException();
43
44         this.charPos = charPos;
45         this.has2ndFlag = has2ndFlag;
46         this.rawByte1st = rawByte1st;
47         this.rawByte2nd = rawByte2nd;
48
49         return;
50     }
51
52     /**
53      * コンストラクタ。
54      * @param charPos デコードエラーで置き換えられた文字列の開始位置
55      * @param rawByte1st デコードエラーを引き起こした最初のバイト値
56      * @param rawByte2nd デコードエラーを引き起こした2番目のバイト値
57      * @throws IndexOutOfBoundsException charPosが負
58      */
59     public DecodeErrorInfo(int charPos,
60                              byte rawByte1st,
61                              byte rawByte2nd)
62             throws IndexOutOfBoundsException{
63         this(charPos, true, rawByte1st, rawByte2nd);
64         return;
65     }
66
67     /**
68      * コンストラクタ。
69      * @param charPos デコードエラーで置き換えられた文字列の開始位置
70      * @param rawByte1st デコードエラーを引き起こしたバイト値
71      * @throws IndexOutOfBoundsException charPosが負
72      */
73     public DecodeErrorInfo(int charPos,
74                              byte rawByte1st)
75             throws IndexOutOfBoundsException{
76         this(charPos, false, rawByte1st, (byte) 0x00);
77         return;
78     }
79
80     /**
81      * デコードエラーで置き換えられた文字列の開始位置を返す。
82      * @return デコードエラーで置き換えられた文字列の開始位置
83      */
84     public int getCharPosition(){
85         return this.charPos;
86     }
87
88     /**
89      * 2バイト目の情報を持つか判定する。
90      * @return 2バイト目の情報を持つならtrue
91      */
92     public boolean has2nd(){
93         return this.has2ndFlag;
94     }
95
96     /**
97      * 1バイト目の値を返す。
98      * @return 1バイト目の値
99      */
100     public byte getRawByte1st(){
101         return this.rawByte1st;
102     }
103
104     /**
105      * 2バイト目の値を返す。
106      * @return 2バイト目の値
107      * @throws IllegalStateException 2バイト目の情報を把持していないとき
108      */
109     public byte getRawByte2nd() throws IllegalStateException{
110         if( ! this.has2ndFlag ) throw new IllegalStateException();
111         return this.rawByte2nd;
112     }
113
114     /**
115      * 出現位置のみが違う複製オブジェクトを生成する。
116      * @param gap 出現位置から引きたい値。正の値なら文字開始位置に向かう。
117      * @return 複製オブジェクト
118      * @throws IndexOutOfBoundsException 再計算された出現位置が負
119      */
120     public DecodeErrorInfo createGappedClone(int gap)
121             throws IndexOutOfBoundsException{
122         DecodeErrorInfo result;
123
124         int newPos = this.charPos - gap;
125         if(this.has2ndFlag){
126             result = new DecodeErrorInfo(newPos,
127                                          this.rawByte1st, this.rawByte2nd);
128         }else{
129             result = new DecodeErrorInfo(newPos, this.rawByte1st);
130         }
131
132         return result;
133     }
134
135     /**
136      * {@inheritDoc}
137      * @return {@inheritDoc}
138      */
139     @Override
140     public String toString(){
141         StringBuilder result = new StringBuilder();
142
143         result.append("start:").append(this.charPos).append(' ');
144
145         String hex;
146         hex = Integer.toHexString(this.rawByte1st & 0xff);
147         if(hex.length() <= 1) result.append('0');
148         result.append(hex);
149
150         if(this.has2ndFlag){
151             hex = Integer.toHexString(this.rawByte2nd & 0xff);
152             result.append(':');
153             if(hex.length() <= 1) result.append('0');
154             result.append(hex);
155         }
156
157         return result.toString();
158     }
159
160     /**
161      * 出現位置で順序づける比較子。
162      */
163     private static final class PosComparator
164             implements Comparator<DecodeErrorInfo> {
165
166         /**
167          * コンストラクタ。
168          */
169         PosComparator(){
170             super();
171             return;
172         }
173
174         /**
175          * {@inheritDoc}
176          * @param info1 {@inheritDoc}
177          * @param info2 {@inheritDoc}
178          * @return {@inheritDoc}
179          */
180         @Override
181         public int compare(DecodeErrorInfo info1, DecodeErrorInfo info2){
182             int pos1;
183             int pos2;
184
185             if(info1 == null) pos1 = -1;
186             else              pos1 = info1.charPos;
187
188             if(info2 == null) pos2 = -1;
189             else              pos2 = info2.charPos;
190
191             return pos1 - pos2;
192         }
193
194     }
195
196 }