package jp.sourceforge.jindolf.archiver;
import java.io.IOException;
-import java.io.Writer;
import java.util.concurrent.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;
}
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;
* @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();
return;
}
+ Writer writer;
+ if(outdir != null){
+ writer = getFileWriter(outdir, landDef, vid);
+ }else{
+ writer = getStdOutWriter();
+ }
+
VillageData villageData;
try{
villageData = load(landDef, vid);
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{
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;
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;
+
/**
* コンストラクタ。
*/
XmlOut(Writer writer){
super();
+
this.writer = writer;
+
+ setSourceCharsetImpl(CS_DEF);
+
return;
}
*
* <p>サロゲートペアのシーケンスまでは調べない。
*
+ * <p>XML規格2.2 Char 定義を参照せよ。
+ *
* @param chVal 文字
* @return 出現可能ならtrue
*/
*
* <p>ControlPicturesが利用できない場合はU+FFFDを用いる。
*
- * <p>UnicodeのControl Picturesブロックを参照せよ。
+ * <p>Unicode規格のControl Picturesブロックを参照せよ。
*
* @param chVal 対象文字
* @return 代替キャラクタ
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進文字列表記に変換する。
+ *
+ * <p>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}
*/
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);
*/
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 出力エラー
private void rawDataOut(String hex, char replace) throws IOException{
append("<rawdata");
+ String encName = this.charsetName;
sp();
- attrOut("encoding", "Shift_JIS");
+ attrOut("encoding", encName);
sp();
attrOut("hexBin", hex);
*/
public void dumpRawData(char chVal)
throws IOException{
- int hexVal;
- hexVal = chVal & 0xff;
- String hexBin = Integer.toHexString(hexVal);
- if(hexBin.length() % 2 != 0) hexBin = "0" + hexBin;
-
+ String hexBin = toHex(chVal);
char replaceChar = replaceChar(chVal);
-
rawDataOut(hexBin, replaceChar);
-
return;
}
xmlOut = new XmlOut(writer);
xmlOut.dumpRawData('\u0100');
xmlOut.close();
- assertEquals("<rawdata encoding=\"Shift_JIS\" hexBin=\"00\" >\ufffd</rawdata>", writer.toString());
+ assertEquals("<rawdata encoding=\"Shift_JIS\" hexBin=\"0100\" >\ufffd</rawdata>", writer.toString());
return;
}
}
/**
- * 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;
errorInfo = new DecodeErrorInfo(0, (byte) 0x00);
xmlOut.dumpErrorInfo(errorInfo);
xmlOut.close();
- assertEquals("<rawdata encoding=\"Shift_JIS\" hexBin=\"00\" >\ufffd</rawdata>", writer.toString());
+ assertEquals("<rawdata encoding=\"Shift_JIS\" hexBin=\"00\" >\u2400</rawdata>", writer.toString());
writer = new StringWriter();
xmlOut = new XmlOut(writer);
errorInfo = new DecodeErrorInfo(0, (byte) 0x0f);
xmlOut.dumpErrorInfo(errorInfo);
xmlOut.close();
- assertEquals("<rawdata encoding=\"Shift_JIS\" hexBin=\"0f\" >\ufffd</rawdata>", writer.toString());
+ assertEquals("<rawdata encoding=\"Shift_JIS\" hexBin=\"0f\" >\u240f</rawdata>", writer.toString());
writer = new StringWriter();
xmlOut = new XmlOut(writer);
errorInfo = new DecodeErrorInfo(0, (byte) 0x10);
xmlOut.dumpErrorInfo(errorInfo);
xmlOut.close();
- assertEquals("<rawdata encoding=\"Shift_JIS\" hexBin=\"10\" >\ufffd</rawdata>", writer.toString());
+ assertEquals("<rawdata encoding=\"Shift_JIS\" hexBin=\"10\" >\u2410</rawdata>", writer.toString());
writer = new StringWriter();
xmlOut = new XmlOut(writer);
content.append("CD");
xmlOut.dumpDecodedContent(content);
xmlOut.close();
- assertEquals("AB<rawdata encoding=\"Shift_JIS\" hexBin=\"08\" >\ufffd</rawdata>CD", writer.toString());
+ assertEquals("AB<rawdata encoding=\"Shift_JIS\" hexBin=\"08\" >\u2408</rawdata>CD", writer.toString());
writer = new StringWriter();
xmlOut = new XmlOut(writer);
content.addDecodeError((byte)0x08);
xmlOut.dumpDecodedContent(content);
xmlOut.close();
- assertEquals("AB<rawdata encoding=\"Shift_JIS\" hexBin=\"08\" >\ufffd</rawdata>", writer.toString());
+ assertEquals("AB<rawdata encoding=\"Shift_JIS\" hexBin=\"08\" >\u2408</rawdata>", writer.toString());
writer = new StringWriter();
xmlOut = new XmlOut(writer);
content.append("CD");
xmlOut.dumpDecodedContent(content);
xmlOut.close();
- assertEquals("<rawdata encoding=\"Shift_JIS\" hexBin=\"08\" >\ufffd</rawdata>CD", writer.toString());
+ assertEquals("<rawdata encoding=\"Shift_JIS\" hexBin=\"08\" >\u2408</rawdata>CD", 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;
}