+++ /dev/null
-/*
- * abstract exporter
- *
- * License : The MIT License
- * Copyright(c) 2010 MikuToga Partners
- */
-
-package jp.sourceforge.mikutoga.pmd.model.binio;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.nio.BufferOverflowException;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.nio.CharBuffer;
-import java.nio.charset.Charset;
-import java.nio.charset.CharsetEncoder;
-import java.nio.charset.CoderResult;
-import java.nio.charset.CodingErrorAction;
-
-/**
- * 抽象化されたエクスポーター共通部。
- */
-public abstract class AbstractExporter {
-
- private static final Charset CS_WIN31J = Charset.forName("windows-31j");
-
- private static final String ERRMSG_TOOLONGTEXT = "too long text";
- private static final String ERRMSG_INVUCSSEQ = "invalid unicode sequence";
- private static final String ERRMSG_NONWIN31J = "no character in win31j";
-
- private static final int BYTES_SHORT = Short .SIZE / Byte.SIZE;
- private static final int BYTES_INT = Integer.SIZE / Byte.SIZE;
- private static final int BYTES_FLOAT = Float .SIZE / Byte.SIZE;
-
- private static final int BUFSZ_BYTE = 512;
- private static final int BUFSZ_CHAR = 512;
-
- private final OutputStream ostream;
-
- private final byte[] barray;
- private final ByteBuffer bbuf;
-
- private final CharBuffer cbuf;
- private final CharsetEncoder encoder;
-
-
- /**
- * コンストラクタ。
- * @param stream 出力ストリーム
- * @throws NullPointerException 引数がnull
- */
- protected AbstractExporter(OutputStream stream)
- throws NullPointerException{
- super();
-
- if(stream == null) throw new NullPointerException();
- this.ostream = stream;
-
- this.barray = new byte[BUFSZ_BYTE];
- this.bbuf = ByteBuffer.wrap(this.barray);
- this.bbuf.order(ByteOrder.LITTLE_ENDIAN);
-
- this.cbuf = CharBuffer.allocate(BUFSZ_CHAR);
- this.encoder = CS_WIN31J.newEncoder();
- this.encoder.onMalformedInput(CodingErrorAction.REPORT);
- this.encoder.onUnmappableCharacter(CodingErrorAction.REPORT);
- this.encoder.reset();
-
- return;
- }
-
- /**
- * 出力をフラッシュする。
- * I/O効率とデバッグ効率のバランスを考え、ご利用は計画的に。
- * @throws IOException 出力エラー
- */
- protected void flush() throws IOException{
- this.ostream.flush();
- return;
- }
-
- /**
- * byte値を出力する。
- * @param bVal byte値
- * @throws IOException 出力エラー
- */
- protected void dumpByte(byte bVal) throws IOException{
- this.ostream.write((int)bVal);
- return;
- }
-
- /**
- * int値をbyte値で出力する。
- * byte値に収まらない上位ビットはそのまま捨てられる。
- * @param iVal int値
- * @throws IOException 出力エラー
- */
- protected void dumpByte(int iVal) throws IOException{
- dumpByte((byte)iVal);
- return;
- }
-
- /**
- * short値を出力する。
- * @param sVal short値
- * @throws IOException 出力エラー
- */
- protected void dumpShort(short sVal) throws IOException{
- this.bbuf.clear();
- this.bbuf.putShort(sVal);
- this.ostream.write(this.barray, 0, BYTES_SHORT);
- return;
- }
-
- /**
- * int値をshort値で出力する。
- * short値に収まらない上位ビットはそのまま捨てられる。
- * @param iVal int値
- * @throws IOException 出力エラー
- */
- protected void dumpShort(int iVal) throws IOException{
- dumpShort((short)iVal);
- return;
- }
-
- /**
- * int値を出力する。
- * @param iVal int値
- * @throws IOException 出力エラー
- */
- protected void dumpInt(int iVal) throws IOException{
- this.bbuf.clear();
- this.bbuf.putInt(iVal);
- this.ostream.write(this.barray, 0, BYTES_INT);
- return;
- }
-
- /**
- * float値を出力する。
- * @param fVal float値
- * @throws IOException 出力エラー
- */
- protected void dumpFloat(float fVal) throws IOException{
- this.bbuf.clear();
- this.bbuf.putFloat(fVal);
- this.ostream.write(this.barray, 0, BYTES_FLOAT);
- return;
- }
-
- /**
- * 文字列をwindows-31jエンコーディングで出力する。
- * @param seq 文字列
- * @return 出力されたbyte総数。
- * @throws IOException 出力エラー
- * @throws IllegalPmdTextException 文字エンコーディングに関するエラー
- */
- protected int dumpCharSequence(CharSequence seq)
- throws IOException, IllegalPmdTextException{
- encodeToByteBuffer(seq);
- this.bbuf.flip();
- int length = dumpByteBuffer();
- return length;
- }
-
- /**
- * windows-31jにエンコーディングした文字列を内部バッファに蓄積する。
- * @param seq 文字列
- * @throws IllegalPmdTextException 文字エンコーディングに関するエラー。
- * 考えられる状況としては、
- * <ul>
- * <li>入力文字列がUnicodeとしてすでにおかしい。
- * (サロゲートペアがペアになってないなど)
- * <li>windows-31jにない文字をエンコーディングしようとした
- * <li>エンコーディング結果が内部バッファに収まらなかった。
- * </ul>
- * など。
- */
- private void encodeToByteBuffer(CharSequence seq)
- throws IllegalPmdTextException{
- this.cbuf.clear();
- try{
- this.cbuf.append(seq);
- }catch(BufferOverflowException e){
- throw new IllegalPmdTextException(ERRMSG_TOOLONGTEXT);
- }
- this.cbuf.flip();
-
- this.bbuf.clear();
-
- CoderResult result = this.encoder.encode(this.cbuf, this.bbuf, true);
- if( ! result.isUnderflow()){
- if(result.isOverflow()){
- throw new IllegalPmdTextException(ERRMSG_TOOLONGTEXT);
- }else if(result.isMalformed()){
- throw new IllegalPmdTextException(ERRMSG_INVUCSSEQ);
- }else if(result.isUnmappable()){
- throw new IllegalPmdTextException(ERRMSG_NONWIN31J);
- }else{
- assert false;
- throw new AssertionError();
- }
- }
-
- return;
- }
-
- /**
- * 内部バッファに蓄積されたbyte値並びを出力する。
- * @return 出力されたbyte数
- * @throws IOException 出力エラー
- */
- private int dumpByteBuffer() throws IOException{
- int offset = this.bbuf.position();
- int limit = this.bbuf.limit();
- int length = limit - offset;
- this.ostream.write(this.barray, offset, length);
-
- this.bbuf.position(limit);
-
- return length;
- }
-
-}
return;
}
+ /**
+ * コンストラクタ。
+ * @param cause 原因
+ */
+ public IllegalPmdException(Throwable cause){
+ super(cause);
+ return;
+ }
+
}
import java.util.List;
import java.util.Map;
import java.util.Set;
+import jp.sourceforge.mikutoga.binio.BinaryExporter;
+import jp.sourceforge.mikutoga.binio.IllegalTextExportException;
import jp.sourceforge.mikutoga.math.MkPos2D;
import jp.sourceforge.mikutoga.math.MkPos3D;
import jp.sourceforge.mikutoga.math.MkVec3D;
* 英名対応以降のPMDファイルフォーマットを
* 使いたくない場合はこのエクスポーターを用いて出力せよ。
*/
-public class PmdExporterBase extends AbstractExporter{
+public class PmdExporterBase extends BinaryExporter{
/** 前(親)ボーンが無い場合の便宜的なボーンID。 */
public static final int NOPREVBONE_ID = 0xffff;
* 指定バイト長をはみ出した。
*/
protected void dumpText(String text, int maxByteLength)
- throws IOException, IllegalPmdTextException{
- dumpText(text, maxByteLength, FDFILLER);
- return;
- }
-
- /**
- * 文字列を指定されたバイト長で出力する。
- * 文字列の改行記号はLF(0x0a)に正規化される。
- * エンコード結果がバイト長に満たない場合は
- * fillerがパディングされる。
- * @param text 文字列
- * @param maxByteLength バイト超指定
- * @param filler 出力結果が足りない場合の詰め物。
- * それでも足りない場合は最後のbyte要素が繰り返し出力される。
- * @throws IOException 出力エラー
- * @throws IllegalPmdTextException エンコード結果が
- * 指定バイト長をはみ出した
- */
- protected void dumpText(String text, int maxByteLength, byte[] filler)
- throws IOException, IllegalPmdTextException{
- String normalized = normalizeBreak(text);
- int blen = dumpCharSequence(normalized);
- int remain = maxByteLength - blen;
-
- if(remain < 0) throw new IllegalPmdTextException("too long text");
-
- int fillerIdx = 0;
- while(remain > 0){
- if(fillerIdx >= filler.length){
- fillerIdx = filler.length - 1;
- }
- dumpByte(filler[fillerIdx]);
- fillerIdx++;
- remain--;
- }
-
+ throws IOException, IllegalTextExportException{
+ dumpFixedW31j(text, maxByteLength, FDFILLER);
return;
}
*/
public void dumpPmdModel(PmdModel model)
throws IOException, IllegalPmdException{
- dumpBasic(model);
- dumpVertexList(model);
- dumpSurfaceList(model);
- dumpMaterialList(model);
- dumpBoneList(model);
- dumpIKChainList(model);
- dumpMorphList(model);
- dumpMorphGroup(model);
- dumpBoneGroupList(model);
+ try{
+ dumpBasic(model);
+ dumpVertexList(model);
+ dumpSurfaceList(model);
+ dumpMaterialList(model);
+ dumpBoneList(model);
+ dumpIKChainList(model);
+ dumpMorphList(model);
+ dumpMorphGroup(model);
+ dumpBoneGroupList(model);
+ }catch(IllegalTextExportException e){
+ throw new IllegalPmdException(e);
+ }
return;
}
* @throws IllegalPmdTextException モデル名もしくは説明が長すぎる
*/
private void dumpBasic(PmdModel model)
- throws IOException, IllegalPmdTextException{
+ throws IOException, IllegalTextExportException{
for(int idx=0; idx < MAGIC_BYTES.length; idx++){
dumpByte(MAGIC_BYTES[idx]);
}
* @throws IllegalPmdTextException シェーディングファイル情報が長すぎる
*/
private void dumpMaterialList(PmdModel model)
- throws IOException, IllegalPmdTextException{
+ throws IOException, IllegalTextExportException{
List<Material> materialList = model.getMaterialList();
int materialNum = materialList.size();
* シェーディングファイル情報を出力する。
* @param shade シェーディング情報
* @throws IOException 出力エラー
- * @throws IllegalPmdTextException ファイル名が長すぎる
+ * @throws IllegalTextExportException ファイル名が長すぎる
*/
private void dumpShadeFileInfo(ShadeInfo shade)
- throws IOException, IllegalPmdTextException{
+ throws IOException, IllegalTextExportException{
String textureFile = shade.getTextureFileName();
String spheremapFile = shade.getSpheremapFileName();
if(text.length() <= 0) filler = NULLFILLER;
else filler = FDFILLER;
- dumpText(text.toString(),
- PmdLimits.MAXBYTES_TEXTUREFILENAME,
- filler );
+ dumpFixedW31j(text.toString(),
+ PmdLimits.MAXBYTES_TEXTUREFILENAME,
+ filler );
return;
}
* @throws IllegalPmdTextException ボーン名が長すぎる
*/
private void dumpBoneList(PmdModel model)
- throws IOException, IllegalPmdTextException{
+ throws IOException, IllegalTextExportException{
List<BoneInfo> boneList = model.getBoneList();
int boneNum = boneList.size();
* @throws IllegalPmdTextException ボーン名が長すぎる
*/
private void dumpBone(BoneInfo bone)
- throws IOException, IllegalPmdTextException{
+ throws IOException, IllegalTextExportException{
String boneName = bone.getBoneName().getPrimaryText();
dumpText(boneName, PmdLimits.MAXBYTES_BONENAME);
* @throws IllegalPmdTextException モーフ名が長すぎる
*/
private void dumpMorphList(PmdModel model)
- throws IOException, IllegalPmdTextException{
+ throws IOException, IllegalTextExportException{
Map<MorphType, List<MorphPart>> morphMap = model.getMorphMap();
Set<MorphType> typeSet = morphMap.keySet();
List<MorphVertex> mergedMorphVertexList = model.mergeMorphVertex();
* デフォルトボーングループ内訳は出力されない。
* @param model モデルデータ
* @throws IOException 出力エラー
- * @throws IllegalPmdTextException ボーングループ名が長すぎる
+ * @throws IllegalTextExportException ボーングループ名が長すぎる
*/
private void dumpBoneGroupList(PmdModel model)
- throws IOException, IllegalPmdTextException{
+ throws IOException, IllegalTextExportException{
List<BoneGroup> groupList = model.getBoneGroupList();
int groupNum = groupList.size();
dumpByte(groupNum - 1);
int dispBoneNum = 0;
for(BoneGroup group : groupList){
if(group.isDefaultBoneGroup()) continue;
- dumpText(group.getGroupName().getPrimaryText(),
- PmdLimits.MAXBYTES_BONEGROUPNAME, LFFILLER );
+ dumpFixedW31j(group.getGroupName().getPrimaryText(),
+ PmdLimits.MAXBYTES_BONEGROUPNAME, LFFILLER );
dispBoneNum += group.getBoneList().size();
}
dumpInt(dispBoneNum);
import java.io.OutputStream;
import java.util.List;
import java.util.Map;
+import jp.sourceforge.mikutoga.binio.IllegalTextExportException;
import jp.sourceforge.mikutoga.pmd.MorphType;
import jp.sourceforge.mikutoga.pmd.model.BoneGroup;
import jp.sourceforge.mikutoga.pmd.model.BoneInfo;
* @throws IllegalPmdTextException 文字列が長すぎる。
*/
private void dumpGlobalInfo(PmdModel model)
- throws IOException, IllegalPmdTextException{
+ throws IOException, IllegalPmdException{
boolean hasGlobal = model.hasGlobalText();
byte globalFlag;
if(hasGlobal) globalFlag = 0x01;
dumpByte(globalFlag);
if(hasGlobal){
- dumpBasicGlobal(model);
- dumpBoneGlobal(model);
- dumpMorphGlobal(model);
- dumpBoneGroupGlobal(model);
+ try{
+ dumpBasicGlobal(model);
+ dumpBoneGlobal(model);
+ dumpMorphGlobal(model);
+ dumpBoneGroupGlobal(model);
+ }catch(IllegalTextExportException e){
+ throw new IllegalPmdException(e);
+ }
}
flush();
* @throws IllegalPmdTextException 文字列が長すぎる。
*/
private void dumpBasicGlobal(PmdModel model)
- throws IOException, IllegalPmdTextException{
+ throws IOException, IllegalTextExportException{
String modelName = model.getModelName().getGlobalText();
if(modelName == null) modelName = "";
dumpText(modelName, PmdLimits.MAXBYTES_MODELNAME);
* @throws IllegalPmdTextException 文字列が長すぎる。
*/
private void dumpBoneGlobal(PmdModel model)
- throws IOException, IllegalPmdTextException{
+ throws IOException, IllegalTextExportException{
for(BoneInfo bone : model.getBoneList()){
String boneName = bone.getBoneName().getGlobalText();
if(boneName == null) boneName = "";
* @throws IllegalPmdTextException 文字列が長すぎる。
*/
private void dumpMorphGlobal(PmdModel model)
- throws IOException, IllegalPmdTextException{
+ throws IOException, IllegalTextExportException{
Map<MorphType, List<MorphPart>> morphMap = model.getMorphMap();
for(MorphType type : MorphType.values()){
* @throws IllegalPmdTextException 文字列が長すぎる
*/
private void dumpBoneGroupGlobal(PmdModel model)
- throws IOException, IllegalPmdTextException{
+ throws IOException, IllegalTextExportException{
for(BoneGroup group : model.getBoneGroupList()){
if(group.isDefaultBoneGroup()) continue;
String groupName = group.getGroupName().getGlobalText();
import java.io.IOException;
import java.io.OutputStream;
+import jp.sourceforge.mikutoga.binio.IllegalTextExportException;
import jp.sourceforge.mikutoga.pmd.model.PmdModel;
import jp.sourceforge.mikutoga.pmd.model.ToonMap;
import jp.sourceforge.mikutoga.pmd.parser.PmdLimits;
throws IOException, IllegalPmdException{
super.dumpPmdModel(model);
- dumpToonMap(model);
+ try{
+ dumpToonMap(model);
+ }catch(IllegalTextExportException e){
+ throw new IllegalPmdException(e);
+ }
return;
}
* @throws IllegalPmdTextException トゥーンファイル名が長すぎる
*/
private void dumpToonMap(PmdModel model)
- throws IOException, IllegalPmdTextException{
+ throws IOException, IllegalTextExportException{
ToonMap map = model.getToonMap();
for(int idx = 0; idx < PmdLimits.TOON_FIXEDNUM; idx++){
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
+import jp.sourceforge.mikutoga.binio.IllegalTextExportException;
import jp.sourceforge.mikutoga.pmd.Deg3d;
import jp.sourceforge.mikutoga.pmd.Rad3d;
import jp.sourceforge.mikutoga.pmd.RigidShapeType;
throws IOException, IllegalPmdException{
super.dumpPmdModel(model);
- dumpRigidList(model);
- dumpJointList(model);
+ try{
+ dumpRigidList(model);
+ dumpJointList(model);
+ }catch(IllegalTextExportException e){
+ throw new IllegalPmdException(e);
+ }
return;
}
* @throws IllegalPmdTextException 長すぎる剛体名
*/
private void dumpRigidList(PmdModel model)
- throws IOException, IllegalPmdTextException{
+ throws IOException, IllegalTextExportException{
List<RigidInfo> rigidList = model.getRigidList();
int rigidNum = rigidList.size();
dumpInt(rigidNum);
* @throws IllegalPmdTextException 長すぎる剛体名
*/
private void dumpRigid(RigidInfo rigid)
- throws IOException, IllegalPmdTextException{
+ throws IOException, IllegalTextExportException{
String rigidName = rigid.getRigidName().getPrimaryText();
dumpText(rigidName, PmdLimits.MAXBYTES_RIGIDNAME);
* @throws IllegalPmdTextException 長すぎるジョイント名
*/
private void dumpJointList(PmdModel model)
- throws IOException, IllegalPmdTextException{
+ throws IOException, IllegalTextExportException{
List<JointInfo> jointList = model.getJointList();
int jointNum = jointList.size();
dumpInt(jointNum);
* @throws IllegalPmdTextException 長すぎるジョイント名
*/
private void dumpJoint(JointInfo joint)
- throws IOException, IllegalPmdTextException{
+ throws IOException, IllegalTextExportException{
String jointName = joint.getJointName().getPrimaryText();
dumpText(jointName, PmdLimits.MAXBYTES_JOINTNAME);