From: Olyutorskii Date: Wed, 29 Jun 2016 10:02:35 +0000 (+0900) Subject: 出力変更 X-Git-Tag: fromMercurial~20 X-Git-Url: http://git.osdn.net/view?p=jindolf%2FJinArchiver.git;a=commitdiff_plain;h=edcb48b7df57fdb2ad4617442cb0730ebb74413f 出力変更 --- diff --git a/src/main/java/jp/sourceforge/jindolf/archiver/DumpXmlTask.java b/src/main/java/jp/sourceforge/jindolf/archiver/DumpXmlTask.java index a5c59d6..3859be0 100644 --- a/src/main/java/jp/sourceforge/jindolf/archiver/DumpXmlTask.java +++ b/src/main/java/jp/sourceforge/jindolf/archiver/DumpXmlTask.java @@ -8,7 +8,6 @@ package jp.sourceforge.jindolf.archiver; import java.io.IOException; -import java.io.Writer; import java.util.concurrent.Callable; /** @@ -29,10 +28,10 @@ public class DumpXmlTask implements Callable { * @param villageData 村情報 * @param writer 出力先 */ - public DumpXmlTask(VillageData villageData, Writer writer){ + public DumpXmlTask(VillageData villageData, XmlOut writer){ super(); this.villageData = villageData; - this.writer = new XmlOut(writer); + this.writer = writer; return; } diff --git a/src/main/java/jp/sourceforge/jindolf/archiver/JinArchiver.java b/src/main/java/jp/sourceforge/jindolf/archiver/JinArchiver.java index 09442dc..ddeaced 100644 --- a/src/main/java/jp/sourceforge/jindolf/archiver/JinArchiver.java +++ b/src/main/java/jp/sourceforge/jindolf/archiver/JinArchiver.java @@ -18,6 +18,7 @@ import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.Reader; import java.io.Writer; +import java.nio.charset.Charset; import java.text.MessageFormat; import java.util.List; import java.util.Properties; @@ -158,24 +159,10 @@ public final class JinArchiver{ * @param optInfo オプション情報 */ private static void dumpOut(OptInfo optInfo){ - String outdir = optInfo.getOutdir(); LandDef landDef = optInfo.getLandDef(); int vid = optInfo.getVid(); - Writer writer; - if(outdir != null){ - writer = getFileWriter(outdir, landDef, vid); - }else{ - writer = getStdOutWriter(); - } - - SnifWriter snifWriter = new SnifWriter(writer); - Reader reader = snifWriter.getSnifReader(); - - writer = new BufferedWriter(snifWriter); - reader = new BufferedReader(reader); - Validator validator; try{ validator = XmlUtils.createValidator(); @@ -184,6 +171,13 @@ public final class JinArchiver{ return; } + Writer writer; + if(outdir != null){ + writer = getFileWriter(outdir, landDef, vid); + }else{ + writer = getStdOutWriter(); + } + VillageData villageData; try{ villageData = load(landDef, vid); @@ -198,8 +192,18 @@ public final class JinArchiver{ return; } + SnifWriter snifWriter = new SnifWriter(writer); + Reader reader = snifWriter.getSnifReader(); + + writer = new BufferedWriter(snifWriter); + reader = new BufferedReader(reader); + + XmlOut xmlOut = new XmlOut(writer); + Charset cs = landDef.getEncoding(); + xmlOut.setSourceCharset(cs); + ValidateTask valTask = new ValidateTask(reader, validator); - DumpXmlTask dumpTask = new DumpXmlTask(villageData, writer); + DumpXmlTask dumpTask = new DumpXmlTask(villageData, xmlOut); ProdCons taskman = new ProdCons(dumpTask, valTask); try{ diff --git a/src/main/java/jp/sourceforge/jindolf/archiver/XmlOut.java b/src/main/java/jp/sourceforge/jindolf/archiver/XmlOut.java index dee7607..04d1e91 100644 --- a/src/main/java/jp/sourceforge/jindolf/archiver/XmlOut.java +++ b/src/main/java/jp/sourceforge/jindolf/archiver/XmlOut.java @@ -11,6 +11,7 @@ import java.io.Closeable; import java.io.Flushable; import java.io.IOException; import java.io.Writer; +import java.nio.charset.Charset; import java.text.MessageFormat; import java.util.Calendar; import java.util.GregorianCalendar; @@ -54,9 +55,19 @@ public class XmlOut implements Appendable, Flushable, Closeable{ private static final TimeZone TZ_TOKYO = TimeZone.getTimeZone("Asia/Tokyo"); + private static final Charset CS_DEF = Charset.forName("Shift_JIS"); + + private static final char[] HEX_TABLE = { + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + 'a', 'b', 'c', 'd', 'e', 'f', + }; + private final Writer writer; + private String charsetName; + private boolean isShiftJis; + /** * コンストラクタ。 @@ -64,7 +75,11 @@ public class XmlOut implements Appendable, Flushable, Closeable{ */ XmlOut(Writer writer){ super(); + this.writer = writer; + + setSourceCharsetImpl(CS_DEF); + return; } @@ -93,6 +108,8 @@ public class XmlOut implements Appendable, Flushable, Closeable{ * *

サロゲートペアのシーケンスまでは調べない。 * + *

XML規格2.2 Char 定義を参照せよ。 + * * @param chVal 文字 * @return 出現可能ならtrue */ @@ -112,7 +129,7 @@ public class XmlOut implements Appendable, Flushable, Closeable{ * *

ControlPicturesが利用できない場合はU+FFFDを用いる。 * - *

UnicodeのControl Picturesブロックを参照せよ。 + *

Unicode規格のControl Picturesブロックを参照せよ。 * * @param chVal 対象文字 * @return 代替キャラクタ @@ -131,6 +148,99 @@ public class XmlOut implements Appendable, Flushable, Closeable{ return result; } + /** + * byte値を2桁の16進文字列表記に変換する。 + * @param bVal byte値 + * @return 16進文字列 + */ + public static String toHex(byte bVal){ + int hexVal = bVal & 0xff; + + char ch1 = HEX_TABLE[hexVal & 0x0f]; + hexVal >>= 4; + char ch0 = HEX_TABLE[hexVal & 0x0f]; + + StringBuilder txt = new StringBuilder(); + txt.append(ch0); + txt.append(ch1); + + return txt.toString(); + } + + /** + * char値を2桁または4桁の16進文字列表記に変換する。 + * + *

U+00FFより大きな値は4桁出力となる。 + * + * @param cVal char値 + * @return 16進文字列 + */ + public static String toHex(char cVal){ + int hexVal = cVal & 0xffff; + + char ch3 = HEX_TABLE[hexVal & 0x0f]; + hexVal >>= 4; + char ch2 = HEX_TABLE[hexVal & 0x0f]; + hexVal >>= 4; + char ch1 = HEX_TABLE[hexVal & 0x0f]; + hexVal >>= 4; + char ch0 = HEX_TABLE[hexVal & 0x0f]; + + StringBuilder txt = new StringBuilder(); + if(cVal > '\u00ff'){ + txt.append(ch0); + txt.append(ch1); + } + txt.append(ch2); + txt.append(ch3); + + return txt.toString(); + } + + /** + * short値を4桁の16進文字列表記に変換する。 + * @param sVal short値 + * @return 16進文字列 + */ + public static String toHex(short sVal){ + int hexVal = sVal & 0xffff; + + char ch3 = HEX_TABLE[hexVal & 0x0f]; + hexVal >>= 4; + char ch2 = HEX_TABLE[hexVal & 0x0f]; + hexVal >>= 4; + char ch1 = HEX_TABLE[hexVal & 0x0f]; + hexVal >>= 4; + char ch0 = HEX_TABLE[hexVal & 0x0f]; + + StringBuilder txt = new StringBuilder(); + txt.append(ch0); + txt.append(ch1); + txt.append(ch2); + txt.append(ch3); + + return txt.toString(); + } + + + /** + * パース元の文字コードを設定する。 + * @param cs Charset + */ + public void setSourceCharset(Charset cs){ + setSourceCharsetImpl(cs); + return; + } + + /** + * パース元の文字コードを設定する。 + * @param cs Charset + */ + private void setSourceCharsetImpl(Charset cs){ + this.charsetName = cs.name(); + this.isShiftJis = "Shift_JIS".equals(this.charsetName); + return; + } /** * {@inheritDoc} @@ -229,9 +339,7 @@ public class XmlOut implements Appendable, Flushable, Closeable{ */ public void charRefOut(char chVal) throws IOException{ - int ival = 0xffff & ((int) chVal); - String hex = Integer.toHexString(ival); - if(hex.length() % 2 != 0) hex = "0" + hex; + String hex = toHex(chVal); append("&#x"); append(hex); @@ -436,25 +544,57 @@ public class XmlOut implements Appendable, Flushable, Closeable{ */ public void dumpErrorInfo(DecodeErrorInfo errorInfo) throws IOException{ - int hexVal; - hexVal = errorInfo.getRawByte1st() & 0xff; - if(errorInfo.has2nd()){ - hexVal <<= 8; - hexVal |= errorInfo.getRawByte2nd() & 0xff; + if(this.isShiftJis && errorInfo.has2nd()){ + byte bVal1 = errorInfo.getRawByte1st(); + byte bVal2 = errorInfo.getRawByte2nd(); + dumpSjisMapError(bVal1, bVal2); + }else{ + byte bVal1 = errorInfo.getRawByte1st(); + dumpDecodeError(bVal1); + if(errorInfo.has2nd()){ + byte bVal2 = errorInfo.getRawByte2nd(); + dumpDecodeError(bVal2); + } } - String hexBin = Integer.toHexString(hexVal); - if(hexBin.length() % 2 != 0) hexBin = "0" + hexBin; - char replaceChar = Win31j.getWin31jChar(errorInfo); + return; + } + + /** + * シフトJISマッピングに関するエラー情報をrawdataタグで出力する。 + * @param bVal1 エラーデータ1 + * @param bVal2 エラーデータ2 + * @throws IOException 出力エラー + */ + public void dumpSjisMapError(byte bVal1, byte bVal2) throws IOException{ + short hexVal; + hexVal = (short) (bVal1 & 0xff); + hexVal <<= 8; + hexVal |= (short) (bVal2 & 0xff); + + String hexBin = toHex(hexVal); + char replaceChar = Win31j.getWin31jChar(bVal1, bVal2); rawDataOut(hexBin, replaceChar); return; } /** - * 生データ出力 + * デコードエラー情報をrawdataタグで出力する。 + * @param bVal エラーデータ + * @throws IOException 出力エラー + */ + public void dumpDecodeError(byte bVal) throws IOException{ + String hexBin = toHex(bVal); + char replaceChar = replaceChar((char) (bVal & 0xff)); + rawDataOut(hexBin, replaceChar); + return; + } + + /** + * 生データ出力。 * @param hex 16進文字列 * @param replace 代替キャラクタ * @throws IOException 出力エラー @@ -462,8 +602,9 @@ public class XmlOut implements Appendable, Flushable, Closeable{ private void rawDataOut(String hex, char replace) throws IOException{ append("\ufffd", writer.toString()); + assertEquals("\ufffd", writer.toString()); return; } @@ -515,11 +515,11 @@ public class XmlOutTest { } /** - * Test of dumpErrorInfo method, of class XmlUtils. + * Test of dumpSjisMapError method, of class XmlUtils. * @throws java.lang.Exception */ @Test - public void testDumpErrorInfo() throws Exception { + public void testDumpDecodeError() throws Exception { System.out.println("dumpErrorInfo"); Writer writer; @@ -531,21 +531,21 @@ public class XmlOutTest { errorInfo = new DecodeErrorInfo(0, (byte) 0x00); xmlOut.dumpErrorInfo(errorInfo); xmlOut.close(); - assertEquals("\ufffd", writer.toString()); + assertEquals("\u2400", writer.toString()); writer = new StringWriter(); xmlOut = new XmlOut(writer); errorInfo = new DecodeErrorInfo(0, (byte) 0x0f); xmlOut.dumpErrorInfo(errorInfo); xmlOut.close(); - assertEquals("\ufffd", writer.toString()); + assertEquals("\u240f", writer.toString()); writer = new StringWriter(); xmlOut = new XmlOut(writer); errorInfo = new DecodeErrorInfo(0, (byte) 0x10); xmlOut.dumpErrorInfo(errorInfo); xmlOut.close(); - assertEquals("\ufffd", writer.toString()); + assertEquals("\u2410", writer.toString()); writer = new StringWriter(); xmlOut = new XmlOut(writer); @@ -591,7 +591,7 @@ public class XmlOutTest { content.append("CD"); xmlOut.dumpDecodedContent(content); xmlOut.close(); - assertEquals("AB\ufffdCD", writer.toString()); + assertEquals("AB\u2408CD", writer.toString()); writer = new StringWriter(); xmlOut = new XmlOut(writer); @@ -600,7 +600,7 @@ public class XmlOutTest { content.addDecodeError((byte)0x08); xmlOut.dumpDecodedContent(content); xmlOut.close(); - assertEquals("AB\ufffd", writer.toString()); + assertEquals("AB\u2408", writer.toString()); writer = new StringWriter(); xmlOut = new XmlOut(writer); @@ -609,7 +609,171 @@ public class XmlOutTest { content.append("CD"); xmlOut.dumpDecodedContent(content); xmlOut.close(); - assertEquals("\ufffdCD", writer.toString()); + assertEquals("\u2408CD", writer.toString()); + + return; + } + + /** + * Test of isXmlChar method, of class XmlOut. + */ + @Test + public void testIsXmlChar() { + System.out.println("isXmlChar"); + + assertFalse(XmlOut.isXmlChar('\u0000')); + assertFalse(XmlOut.isXmlChar('\u001f')); + + assertTrue(XmlOut.isXmlChar('\n')); + assertTrue(XmlOut.isXmlChar('\r')); + assertTrue(XmlOut.isXmlChar('\t')); + + assertTrue(XmlOut.isXmlChar('\u0020')); + assertTrue(XmlOut.isXmlChar('A')); + assertTrue(XmlOut.isXmlChar('\ud7ff')); + + assertTrue(XmlOut.isXmlChar('\ud800')); + assertTrue(XmlOut.isXmlChar('\udbff')); + + assertTrue(XmlOut.isXmlChar('\udc00')); + assertTrue(XmlOut.isXmlChar('\udfff')); + + assertTrue(XmlOut.isXmlChar('\ue000')); + assertTrue(XmlOut.isXmlChar('\ufffd')); + + assertFalse(XmlOut.isXmlChar('\ufffe')); + assertFalse(XmlOut.isXmlChar('\uffff')); + + return; + } + + /** + * Test of replaceChar method, of class XmlOut. + */ + @Test + public void testReplaceChar() { + System.out.println("replaceChar"); + + char result; + + result = XmlOut.replaceChar('\u0000'); + assertEquals('\u2400', result); + + result = XmlOut.replaceChar('\u001f'); + assertEquals('\u241f', result); + + result = XmlOut.replaceChar('\u007f'); + assertEquals('\u2421', result); + + result = XmlOut.replaceChar('A'); + assertEquals('\ufffd', result); + + return; + } + + /** + * Test of toHex method, of class XmlOut. + */ + @Test + public void testToHex_byte() { + System.out.println("toHex"); + + byte bVal; + String result; + + bVal = 0x00; + result = XmlOut.toHex(bVal); + assertEquals("00", result); + + bVal = 0x0a; + result = XmlOut.toHex(bVal); + assertEquals("0a", result); + + bVal = 0x7f; + result = XmlOut.toHex(bVal); + assertEquals("7f", result); + + bVal = (byte) 0x80; + result = XmlOut.toHex(bVal); + assertEquals("80", result); + + bVal = (byte) 0xff; + result = XmlOut.toHex(bVal); + assertEquals("ff", result); + + return; + } + + /** + * Test of toHex method, of class XmlOut. + */ + @Test + public void testToHex_char() { + System.out.println("toHex"); + + char cVal; + String result; + + cVal = '\u0000'; + result = XmlOut.toHex(cVal); + assertEquals("00", result); + + cVal = '\u000b'; + result = XmlOut.toHex(cVal); + assertEquals("0b", result); + + cVal = '\u00ff'; + result = XmlOut.toHex(cVal); + assertEquals("ff", result); + + cVal = '\u0100'; + result = XmlOut.toHex(cVal); + assertEquals("0100", result); + + cVal = '\u7fff'; + result = XmlOut.toHex(cVal); + assertEquals("7fff", result); + + cVal = '\u8000'; + result = XmlOut.toHex(cVal); + assertEquals("8000", result); + + cVal = '\uffff'; + result = XmlOut.toHex(cVal); + assertEquals("ffff", result); + + return; + } + + /** + * Test of toHex method, of class XmlOut. + */ + @Test + public void testToHex_short() { + System.out.println("toHex"); + + short sVal; + String result; + + sVal = 0x0000; + result = XmlOut.toHex(sVal); + assertEquals("0000", result); + + sVal = 0x00ff; + result = XmlOut.toHex(sVal); + assertEquals("00ff", result); + + sVal = 0x7fff; + result = XmlOut.toHex(sVal); + assertEquals("7fff", result); + + sVal = (short) 0x8000; + result = XmlOut.toHex(sVal); + assertEquals("8000", result); + + sVal = (short) 0xffff; + result = XmlOut.toHex(sVal); + assertEquals("ffff", result); return; }