import java.util.RandomAccess;
/**
- * ã\83\87ã\82³ã\83¼ã\83\89ã\82¨ã\83©ã\83¼æ\83\85å ±ã\82\92å\90«ã\82\80å\86\8då\88©ç\94¨å\8f¯è\83½ã\81ª文字列。
+ * ã\83\87ã\82³ã\83¼ã\83\89ã\82¨ã\83©ã\83¼æ\83\85å ±ã\81¨å\85±ã\81«è¿½è¨\98å\8f¯è\83½ã\81ªå\8f¯å¤\89文字列。
*
* <p>デコードエラーを起こした箇所は代替文字{@link #ALTCHAR}で置き換えられる。
*
*/
public static final char ALTCHAR = '?';
- private static final String NULLTEXT = "null";
-
private static final List<DecodeErrorInfo> EMPTY_LIST;
+ private static final String NULLTEXT = "null";
static{
List<DecodeErrorInfo> emptyList;
emptyList = Collections.emptyList();
emptyList = Collections.unmodifiableList(emptyList);
EMPTY_LIST = emptyList;
+
+ assert createErrorList() instanceof RandomAccess;
}
private final StringBuilder rawContent = new StringBuilder();
-
- private List<DecodeErrorInfo> decodeError;
+ private List<DecodeErrorInfo> errList;
/**
* 戻り値となる場合がありうる。
*
* @param srcErrList 追加元エラーリスト
- * @param startCharPos 範囲開始位置
- * @param endCharPos 範囲終了位置
+ * @param startCharPt 範囲開始位置
+ * @param endCharPt 範囲終了位置
* @param dstErrList 追加先エラーリスト。nullでもよい。
* 追加元と異なるリストでなければならない。
* @param gap ギャップ量
* @throws IllegalArgumentException 追加元リストと追加先リストが
* 同一インスタンス
*/
- protected static List<DecodeErrorInfo>
- appendGappedErrorInfo(List<DecodeErrorInfo> srcErrList,
- int startCharPos, int endCharPos,
- List<DecodeErrorInfo> dstErrList,
- int gap){
+ static List<DecodeErrorInfo> appendGappedErrorInfo(
+ List<DecodeErrorInfo> srcErrList,
+ int startCharPt, int endCharPt,
+ List<DecodeErrorInfo> dstErrList,
+ int gap
+ ){
if(srcErrList == dstErrList) throw new IllegalArgumentException();
+ if(startCharPt >= endCharPt) return dstErrList;
- if(startCharPos >= endCharPos) return dstErrList;
-
+ int startErrorIdx =
+ DecodeErrorInfo.searchErrorIndex(srcErrList, startCharPt);
int errSize = srcErrList.size();
-
- int startErrorIdx;
- int endErrorIdx;
-
- startErrorIdx =
- DecodeErrorInfo.searchErrorIndex(srcErrList, startCharPos);
if(startErrorIdx >= errSize){
return null;
}
- int lastCharPos = endCharPos - 1;
- endErrorIdx =
- DecodeErrorInfo.searchErrorIndex(srcErrList, lastCharPos);
- if(endErrorIdx >= errSize){
- endErrorIdx = errSize - 1;
- }else{
- DecodeErrorInfo lastErrorInfo = srcErrList.get(endErrorIdx);
- boolean isLastErrorInfoOnLastPos =
- lastErrorInfo.getCharPosition() == lastCharPos;
- if( ! isLastErrorInfoOnLastPos){
- endErrorIdx--;
- }
- }
+ int endErrorIdx = calcEndIdx(srcErrList, endCharPt);
boolean hasLoop =
(0 <= startErrorIdx) && (startErrorIdx <= endErrorIdx);
}
/**
+ * 文字列終了点からエラーリスト範囲の最終インデックスを求める。
+ *
+ * @param srcErrList エラーリスト
+ * @param endCharPt 文字列終了点
+ * @return リスト範囲の最終インデックス
+ */
+ private static int calcEndIdx(List<DecodeErrorInfo> srcErrList,
+ int endCharPt){
+ int lastCharPos = endCharPt - 1;
+
+ int endErrorIdx =
+ DecodeErrorInfo.searchErrorIndex(srcErrList, lastCharPos);
+
+ int errSize = srcErrList.size();
+ if(endErrorIdx >= errSize){
+ endErrorIdx = errSize - 1;
+ }else{
+ DecodeErrorInfo lastErrorInfo = srcErrList.get(endErrorIdx);
+
+ boolean isLastErrorInfoOnLastPos =
+ lastErrorInfo.getCharPosition() == lastCharPos;
+ if( ! isLastErrorInfoOnLastPos){
+ endErrorIdx--;
+ }
+ }
+
+ return endErrorIdx;
+ }
+
+ /**
* エラーリストの一部の範囲を、gapを加味して別リストに追加コピーする。
*
* @param srcErrList コピー元リスト
* @param dstErrList コピー先リスト
* @param gap 代替文字出現位置ギャップ量
*/
- private static void
- copyGappedErrorInfo(List<DecodeErrorInfo> srcErrList,
- int startErrorIdx, int endErrorIdx,
- List<DecodeErrorInfo> dstErrList,
- int 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);
return result;
}
- static{
- assert createErrorList() instanceof RandomAccess;
- }
-
/**
* 初期化。
private void initImpl(){
this.rawContent.setLength(0);
- if(this.decodeError != null){
- this.decodeError.clear();
+ if(this.errList != null){
+ this.errList.clear();
}
return;
* @return デコードエラーを含むならtrue
*/
public boolean hasDecodeError(){
- if(this.decodeError == null) return false;
- if(this.decodeError.isEmpty()) return false;
+ if(this.errList == null) return false;
+ if(this.errList.isEmpty()) return false;
return true;
}
if( ! hasDecodeError() ){
return EMPTY_LIST;
}
- return Collections.unmodifiableList(this.decodeError);
+ return Collections.unmodifiableList(this.errList);
}
/**
* 生の文字列を得る。
*
+ * <p>戻り値からエラー情報は消される。
+ *
* <p>高速なCharSequenceアクセス用途。
*
* @return 生の文字列。
/**
* {@inheritDoc}
*
- * @param start {@inheritDoc}
- * @param end {@inheritDoc}
+ * @param startCharPt {@inheritDoc}
+ * @param endCharPt {@inheritDoc}
* @return {@inheritDoc}
*/
@Override
- public CharSequence subSequence(int start, int end){
- return this.rawContent.subSequence(start, end);
+ public CharSequence subSequence(int startCharPt, int endCharPt){
+ return this.rawContent.subSequence(startCharPt, endCharPt);
}
/**
*
* <p>サブコンテントにはデコードエラー情報が引き継がれる。
*
- * @param start 開始位置
- * @param end 終了位置
+ * @param startCharPt 開始位置
+ * @param endCharPt 終了位置
* @return サブコンテント
* @throws IndexOutOfBoundsException start または end が負の値の場合、
* end が length() より大きい場合、
* あるいは start が end より大きい場合
*/
- public DecodedContent subContent(int start, int end)
+ public DecodedContent subContent(int startCharPt, int endCharPt)
throws IndexOutOfBoundsException{
- int length = end - start;
+ int length = endCharPt - startCharPt;
if(length < 0) throw new IndexOutOfBoundsException();
DecodedContent result = new DecodedContent(length);
- result.append(this, start, end);
+ result.append(this, startCharPt, endCharPt);
return result;
}
* <p>nullが渡されると文字列"null"として解釈される。
*
* @param seq 追加する文字列
- * @param startPos 開始位置
- * @param endPos 終了位置
+ * @param startCharPt 開始位置
+ * @param endCharPt 終了位置
* @return thisオブジェクト
* @throws IndexOutOfBoundsException 範囲指定が変。
*/
@Override
public DecodedContent append(CharSequence seq,
- int startPos, int endPos)
+ int startCharPt, int endCharPt)
throws IndexOutOfBoundsException{
DecodedContent result;
if(seq == null){
- result = append(NULLTEXT, startPos, endPos);
+ result = append(NULLTEXT, startCharPt, endCharPt);
}else if(seq instanceof DecodedContent){
- result = append((DecodedContent) seq, startPos, endPos);
- }else if( startPos < 0
- || startPos > endPos
- || endPos > seq.length()){
+ result = append((DecodedContent) seq, startCharPt, endCharPt);
+ }else if( startCharPt < 0
+ || startCharPt > endCharPt
+ || endCharPt > seq.length()){
throw new IndexOutOfBoundsException();
- }else if(startPos == endPos){
+ }else if(startCharPt == endCharPt){
result = this;
}else{
- this.rawContent.append(seq, startPos, endPos);
+ this.rawContent.append(seq, startCharPt, endCharPt);
result = this;
}
* <p>nullが渡されると文字列"null"として解釈される。
*
* @param source 追加する文字列
- * @param startPos 開始位置
- * @param endPos 終了位置
+ * @param startCharPt 開始位置
+ * @param endCharPt 終了位置
* @return thisオブジェクト
* @throws IndexOutOfBoundsException 範囲指定が変。
* @see Appendable#append(CharSequence, int, int)
*/
public DecodedContent append(DecodedContent source,
- int startPos, int endPos)
+ int startCharPt, int endCharPt)
throws IndexOutOfBoundsException{
if(source == null){
- return append(NULLTEXT, startPos, endPos);
+ return append(NULLTEXT, startCharPt, endCharPt);
}
- if( startPos < 0
- || startPos > endPos
- || endPos > source.length()){
+ if( startCharPt < 0
+ || startCharPt > endCharPt
+ || endCharPt > source.length()){
throw new IndexOutOfBoundsException();
- }else if(startPos == endPos){
+ }else if(startCharPt == endCharPt){
return this;
}
int oldLength = this.rawContent.length();
- this.rawContent.append(source.rawContent, startPos, endPos);
+ this.rawContent.append(source.rawContent, startCharPt, endCharPt);
List<DecodeErrorInfo> srcErrList;
if(source.hasDecodeError()){
- srcErrList = source.decodeError;
+ srcErrList = source.errList;
}else{
return this;
}
List<DecodeErrorInfo> dstErrList;
if(source == this) dstErrList = null;
- else dstErrList = this.decodeError;
+ else dstErrList = this.errList;
- int gap = startPos - oldLength;
+ int gap = startCharPt - oldLength;
dstErrList = appendGappedErrorInfo(srcErrList,
- startPos, endPos,
+ startCharPt, endCharPt,
dstErrList,
gap);
- if(dstErrList == null) return this;
- if(dstErrList == this.decodeError) return this;
+ if(dstErrList == null) return this;
+ if(dstErrList == this.errList) return this;
- if(this.decodeError == null){
- this.decodeError = dstErrList;
+ if(this.errList == null){
+ this.errList = dstErrList;
}else{
- this.decodeError.addAll(dstErrList);
+ this.errList.addAll(dstErrList);
}
return this;
*
* @param errorInfo デコードエラー
*/
- private void addDecodeError(DecodeErrorInfo errorInfo){
- if(this.decodeError == null){
- this.decodeError = createErrorList();
+ void addDecodeError(DecodeErrorInfo errorInfo){
+ if(this.errList == null){
+ this.errList = createErrorList();
}
- this.decodeError.add(errorInfo);
+ this.errList.add(errorInfo);
this.rawContent.append(ALTCHAR);
return;
}