X-Git-Url: http://git.osdn.net/view?p=jindolf%2FJinParser.git;a=blobdiff_plain;f=src%2Fmain%2Fjava%2Fjp%2Fosdn%2Fjindolf%2Fparser%2Fcontent%2FDecodeErrorInfo.java;fp=src%2Fmain%2Fjava%2Fjp%2Fosdn%2Fjindolf%2Fparser%2Fcontent%2FDecodeErrorInfo.java;h=ee66182926f45ecfbe288c7616c8b0fb2d45acf1;hp=0000000000000000000000000000000000000000;hb=ffb5cc4bf0ebcbc9a2e7ffb51ab5d8d2ba940129;hpb=3ab4018d742ecdb3ddb40961f9f74c2c97537d4e
diff --git a/src/main/java/jp/osdn/jindolf/parser/content/DecodeErrorInfo.java b/src/main/java/jp/osdn/jindolf/parser/content/DecodeErrorInfo.java
new file mode 100644
index 0000000..ee66182
--- /dev/null
+++ b/src/main/java/jp/osdn/jindolf/parser/content/DecodeErrorInfo.java
@@ -0,0 +1,310 @@
+/*
+ * invalid character decoding information
+ *
+ * License : The MIT License
+ * Copyright(c) 2009 olyutorskii
+ */
+
+package jp.osdn.jindolf.parser.content;
+
+import java.util.Comparator;
+import java.util.List;
+import java.util.RandomAccess;
+
+/**
+ * æåãã³ã¼ãç°å¸¸ç³»ã®çºçã«ãã
+ * {@link DecodedContent}ã«ä»£æ¿æåã¨ã¨ã©ã¼ãã¤ããåãè¾¼ã¾ããäºå®ã
+ * è¨é²ããã
+ *
+ *
ã¨ã©ã¼ã®åå ã¨ãªã£ããã¤ãå¤ã«é¢ããæ
å ±ã¯ã
+ * 1ãã¤ããããã¯2ãã¤ãã§æ§æãããã
+ * 2ãã¤ãã®å ´åã¯ããããã·ããJISã®æåéåã«é¢ããã¨ã©ã¼ã
+ *
+ *
{@link DecodedContent}å
ã§ã®ä»£æ¿æååºç¾ä½ç½®ãcharåä½ã§ä¿æããã
+ */
+public class DecodeErrorInfo{
+
+ /** åºç¾ä½ç½®é Comparatorã */
+ public static final Comparator POS_COMPARATOR =
+ new PosComparator();
+
+ 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 has2ndFlag 2ãã¤ãç®ãæå¹ãªãtrueã渡ãã
+ * @param rawByte1st ãã³ã¼ãã¨ã©ã¼ãå¼ãèµ·ããã1çªç®ã®ãã¤ãå¤
+ * @param rawByte2nd ãã³ã¼ãã¨ã©ã¼ãå¼ãèµ·ããã2çªç®ã®ãã¤ãå¤
+ * @throws IndexOutOfBoundsException charPosãè²
+ */
+ private DecodeErrorInfo(int charPos,
+ boolean has2ndFlag,
+ byte rawByte1st,
+ byte rawByte2nd)
+ throws IndexOutOfBoundsException{
+ if(charPos < 0) throw new IndexOutOfBoundsException();
+
+ this.charPos = charPos;
+ this.has2ndFlag = has2ndFlag;
+ this.rawByte1st = rawByte1st;
+ this.rawByte2nd = rawByte2nd;
+
+ return;
+ }
+
+ /**
+ * ã³ã³ã¹ãã©ã¯ã¿ã
+ *
+ * @param charPos ãã³ã¼ãã¨ã©ã¼ã§ç½®ãæãããã代æ¿æåã®åºç¾ä½ç½®
+ * @param rawByte1st ãã³ã¼ãã¨ã©ã¼ãå¼ãèµ·ããã1çªç®ã®ãã¤ãå¤
+ * @param rawByte2nd ãã³ã¼ãã¨ã©ã¼ãå¼ãèµ·ããã2çªç®ã®ãã¤ãå¤
+ * @throws IndexOutOfBoundsException charPosãè²
+ */
+ public DecodeErrorInfo(int charPos,
+ byte rawByte1st,
+ byte rawByte2nd)
+ throws IndexOutOfBoundsException{
+ this(charPos, true, rawByte1st, rawByte2nd);
+ return;
+ }
+
+ /**
+ * ã³ã³ã¹ãã©ã¯ã¿ã
+ *
+ * @param charPos ãã³ã¼ãã¨ã©ã¼ã§ç½®ãæãããã代æ¿æåã®åºç¾ä½ç½®
+ * @param rawByte1st ãã³ã¼ãã¨ã©ã¼ãå¼ãèµ·ããããã¤ãå¤
+ * @throws IndexOutOfBoundsException charPosãè²
+ */
+ public DecodeErrorInfo(int charPos,
+ byte rawByte1st)
+ throws IndexOutOfBoundsException{
+ this(charPos, false, rawByte1st, (byte) 0x00);
+ return;
+ }
+
+
+ /**
+ * ä¸ããããæåä½ç½®ãå«ãããã¾ãã¯ãã以éã§æãå°ããªä½ç½®æ
å ±ãæã¤
+ * ãã³ã¼ãã¨ã©ã¼ã®ã¤ã³ããã¯ã¹ä½ç½®ãè¿ããâ»ãªãã¢ãµã¼ãçã
+ *
+ * @param errList ãã³ã¼ãã¨ã©ã¼ã®ãªã¹ã
+ * @param charPos 代æ¿æåä½ç½®
+ * @return 0ããå§ã¾ããªã¹ãå
ã®ä½ç½®ã
+ * æåä½ç½®ã®ä¸è´ãããã³ã¼ãã¨ã©ã¼ããªããã°
+ * ãªã¹ãã¸ã®æ¿å
¥ãã¤ã³ããè¿ãã
+ */
+ public static int lsearchErrorIndex(List errList,
+ int charPos){
+ int idx = 0;
+ for(DecodeErrorInfo einfo : errList){
+ int errCharPos = einfo.getCharPosition();
+ if(charPos <= errCharPos) break;
+ idx++;
+ }
+
+ return idx;
+ }
+
+ /**
+ * ä¸ããããæåä½ç½®ãå«ãããã¾ãã¯ãã以éã§æãå°ããªä½ç½®æ
å ±ãæã¤
+ * ãã³ã¼ãã¨ã©ã¼ã®ã¤ã³ããã¯ã¹ä½ç½®ãè¿ããâ»ãã¤ããªãµã¼ãçã
+ *
+ * @param errList ãã³ã¼ãã¨ã©ã¼ã®ãªã¹ã
+ * @param charPos 代æ¿æåä½ç½®
+ * @return 0ããå§ã¾ããªã¹ãå
ã®ä½ç½®ã
+ * æåä½ç½®ã®ä¸è´ãããã³ã¼ãã¨ã©ã¼ããªããã°
+ * ãªã¹ãã¸ã®æ¿å
¥ãã¤ã³ããè¿ãã
+ */
+ public static int bsearchErrorIndex(List errList,
+ int charPos){
+ int floorIdx = 0;
+ int roofIdx = errList.size() - 1;
+
+ while(floorIdx <= roofIdx){
+ int gapHalf = (roofIdx - floorIdx) / 2; // åãæ¨ã¦
+ int midIdx = floorIdx + gapHalf;
+ DecodeErrorInfo einfo = errList.get(midIdx);
+ int errCharPos = einfo.getCharPosition();
+
+ if (errCharPos < charPos) floorIdx = midIdx + 1;
+ else if(errCharPos > charPos) roofIdx = midIdx - 1;
+ else return midIdx;
+ }
+
+ return floorIdx;
+ }
+
+ /**
+ * ä¸ããããæåä½ç½®ãå«ãããã¾ãã¯ãã以éã§æãå°ããªä½ç½®æ
å ±ãæã¤
+ * ãã³ã¼ãã¨ã©ã¼ã®ã¤ã³ããã¯ã¹ä½ç½®ãè¿ãã
+ *
+ * ã©ã³ãã ã¢ã¯ã»ã¹ã®å¯å¦ãããã³è¦ç´ æ°ã®å¢æ¸ã«å¿ãã¦
+ * ãªãã¢ãµã¼ãã¨ãã¤ããªãµã¼ãã使ãåããã
+ *
+ * @param errList ãã³ã¼ãã¨ã©ã¼ã®ãªã¹ã
+ * @param charPos 代æ¿æåä½ç½®
+ * @return 0ããå§ã¾ããªã¹ãå
ã®ä½ç½®ã
+ * æåä½ç½®ã®ä¸è´ãããã³ã¼ãã¨ã©ã¼ããªããã°
+ * ãªã¹ãã¸ã®æ¿å
¥ãã¤ã³ããè¿ãã
+ */
+ public static int searchErrorIndex(List errList,
+ int charPos){
+ int result;
+
+ boolean useLinear;
+ if(errList instanceof RandomAccess){
+ if(errList.size() < BSEARCH_THRESHOLD){
+ useLinear = true;
+ }else{
+ useLinear = false;
+ }
+ }else{
+ useLinear = true;
+ }
+
+ if(useLinear){
+ // linear-search
+ result = lsearchErrorIndex(errList, charPos);
+ }else{
+ // binary-search
+ result = bsearchErrorIndex(errList, charPos);
+ }
+
+ return result;
+ }
+
+
+ /**
+ * ã¨ã©ã¼ä»£æ¿æåã®åºç¾ä½ç½®ãè¿ãã
+ *
+ * @return 代æ¿æåã®éå§ä½ç½®
+ */
+ public int getCharPosition(){
+ return this.charPos;
+ }
+
+ /**
+ * 2ãã¤ãç®ã®ã¨ã©ã¼æ
å ±ãæã¤ãå¤å®ããã
+ *
+ * @return 2ãã¤ãç®ã®æ
å ±ãæã¤ãªãtrue
+ */
+ public boolean has2nd(){
+ return this.has2ndFlag;
+ }
+
+ /**
+ * 1ãã¤ãç®ã®ã¨ã©ã¼ãã¤ãå¤ãè¿ãã
+ *
+ * @return 1ãã¤ãç®ã®å¤
+ */
+ public byte getRawByte1st(){
+ return this.rawByte1st;
+ }
+
+ /**
+ * 2ãã¤ãç®ã®ã¨ã©ã¼ãã¤ãå¤ãè¿ãã
+ *
+ * @return 2ãã¤ãç®ã®å¤
+ * @throws IllegalStateException 2ãã¤ãç®ã®æ
å ±ãææãã¦ããªãã¨ã
+ */
+ public byte getRawByte2nd() throws IllegalStateException{
+ if( ! this.has2ndFlag ) throw new IllegalStateException();
+ return this.rawByte2nd;
+ }
+
+ /**
+ * åºç¾ä½ç½®ã®ã¿ãéãè¤è£½ãªãã¸ã§ã¯ããçæããã
+ *
+ * @param gap åºç¾ä½ç½®ããå¼ãããå¤ãæ£ã®å¤ãªãæåéå§ä½ç½®ã«åããã
+ * @return è¤è£½ãªãã¸ã§ã¯ã
+ * @throws IndexOutOfBoundsException åè¨ç®ãããåºç¾ä½ç½®ãè²
+ */
+ public DecodeErrorInfo createGappedClone(int gap)
+ throws IndexOutOfBoundsException{
+ int newPos = this.charPos - gap;
+
+ DecodeErrorInfo result;
+ result = new DecodeErrorInfo(newPos,
+ this.has2ndFlag,
+ this.rawByte1st, this.rawByte2nd);
+
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @return {@inheritDoc}
+ */
+ @Override
+ public String toString(){
+ StringBuilder result = new StringBuilder();
+
+ result.append("start:").append(this.charPos).append(' ');
+
+ String hex;
+ hex = Integer.toHexString(this.rawByte1st & 0xff);
+ if(hex.length() <= 1) result.append('0');
+ result.append(hex);
+
+ if(this.has2ndFlag){
+ result.append(':');
+ hex = Integer.toHexString(this.rawByte2nd & 0xff);
+ if(hex.length() <= 1) result.append('0');
+ result.append(hex);
+ }
+
+ return result.toString();
+ }
+
+ /**
+ * åºç¾ä½ç½®ã§é åºã¥ããæ¯è¼åã
+ */
+ @SuppressWarnings("serial")
+ private static final class PosComparator
+ implements Comparator {
+
+ /**
+ * ã³ã³ã¹ãã©ã¯ã¿ã
+ */
+ PosComparator(){
+ super();
+ return;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @param info1 {@inheritDoc}
+ * @param info2 {@inheritDoc}
+ * @return {@inheritDoc}
+ */
+ @Override
+ public int compare(DecodeErrorInfo info1, DecodeErrorInfo info2){
+ if (info1 == info2) return 0;
+ else if(info1 == null) return -1;
+ else if(info2 == null) return 1;
+
+ int pos1 = info1.getCharPosition();
+ int pos2 = info2.getCharPosition();
+
+ int result;
+ if (pos1 < pos2) result = -1;
+ else if(pos1 > pos2) result = 1;
+ else result = 0;
+
+ return result;
+ }
+
+ }
+
+}