2013年4月22日月曜日

java でファイルダンプ(クラス風味+)

今回は、16進数の出力の前後に文字列を指定できるクラス(dhex)とキャラクタの前後に文字列を指定できるクラス(dchr)に分けて、ダンプのフォーマットを知っているクラス(dump)でdhexとdchrを使ってダンプするプログラムにしてみた。こうしたことで dump2 の新しいレイアウトダンプフォーマットを書く気力が沸いたので、そう言う意味の再利用性の向上があったと思える。クラスにするのであれば再利用性のあるクラスか、組み立て方をしっているクラスにわけるべきなのだろう。dhex、chex は、最近気になってる clisp の影響で再帰処理にしてみた。さらに、結城先生のデザインパターンのアダプタなどを模してみるとよいのかもしれないが、この内容のプログラムではその有りがたさがまだわからない。
import java.io.*;
import java.util.*;

class dhex {
    String fpad = "";
    String lpad = "";

    public dhex(String f, String l) {
        fpad = f;  
        lpad = l;  
    }

    public String hex(byte buf[],int no,int size) {
        no--;
        if (no>=0) {
            return(this.hex(buf,no,size) 
                 + (no > size-1 ? String.format("%s%2s%s",fpad,"",lpad) 
                       : String.format("%s%02x%s",fpad,buf[no],lpad)));
        }
        return("");
    }
}

class dchr {
    String fpad = "";
    String lpad = "";

    public dchr(String f, String l) {
        fpad = f;  
        lpad = l;  
    }

    public byte trpchr(byte c) {
        if ((0x00<=c && c<=0x1f) || 0x7f<=(c&0xff)) {
            return('.');
        }
        return(c);
    }

    public String chr(byte buf[],int no,int size) {
        no--;
        if (no>=0) {
            return(this.chr(buf,no,size) 
                 + (no > size-1 ? String.format("%s%s%s",fpad," ",lpad) 
                       : String.format("%s%c%s",fpad,trpchr(buf[no]),lpad)));
        }
        return("");
    }
}

class Dump {
    String fname;
    int    max;

    public Dump(String name) {
        fname = name;
        max   = 16;
    }

    public String fhalf(String line) {
        return(line.substring(0,3*(max/2)));
    }

    public String lhalf(String line) {
        return(line.substring(3*(max/2),3*max));
    }

    public void normalp() throws FileNotFoundException,IOException {
        byte   buf[] = new byte[16];
        int    size,cnt = 0;
        FileInputStream ifs = null;

        try {
            ifs = new FileInputStream(fname);
            dhex h = new dhex(""," ");
            dchr c = new dchr("","");

            while(ifs.available()>0) {
                size = ifs.read(buf);

                System.out.print(String.format("%08x : ",cnt*16));
                String line = h.hex(buf,16,size);

                System.out.print(fhalf(line));
                System.out.print("- ");
                System.out.print(lhalf(line));
                System.out.print("|");
                System.out.print(c.chr(buf,16,size));
                System.out.printf("|\n");
                cnt++;
            }
        }
        finally {
            if (ifs != null) {
                ifs.close(); 
            }
        }
    }
}

class Dump2 extends Dump {
    public Dump2(String name) {
        super(name);
    }

    public void normalp() throws FileNotFoundException,IOException {
        byte   buf[] = new byte[16];
        int    size,cnt = 0;
        FileInputStream ifs = null;

        try {
            ifs = new FileInputStream(fname);
            dhex h = new dhex(""," ");
            dchr c = new dchr(" "," ");

            while(ifs.available()>0) {
                size = ifs.read(buf);

                System.out.print(String.format("%08x : ",cnt*16));
                System.out.print(h.hex(buf,16,size));
                System.out.printf("\n");
                System.out.print(String.format("         : "));
                System.out.print(c.chr(buf,16,size));
                System.out.printf("\n");
                cnt++;
            }
        }
        finally {
            if (ifs != null) {
                ifs.close(); 
            }
        }
    }
}

class test05 {
    public static void main(String args[]) {
        Dump d = new Dump(args[0]);
        try {
            d.normalp();
        }
        catch(FileNotFoundException e) {
            System.out.println("ファイルオープンエラー");
        }
        catch(Exception e) {
            System.out.println("異常終了");
            e.printStackTrace();
        }
    }
}

0 件のコメント:

コメントを投稿