...ing logging 4.0

はてなブログに移行しました。D言語の話とかいろいろ。

stdex.encodedstream 習作

module stdex.encodedstream;

import std.stream;
import std.cstream;
import std.windows.charset;
import std.c.string;

class EncodedOutputStreamFilter(CoreEncode, OtherEncode) {
	private OutputStream stream;
	this(OutputStream stream) {
		this.stream = stream;
	}
	void writeLine(CoreEncode c) {
		write(c);
		stream.printf("\n".dup);
	}
	void write(CoreEncode c) {
		OtherEncode o;
		encode(c, o);
		stream.printf("%.*s".dup, o);
	}
}
class EncodedInputStreamFilter(CoreEncode, OtherEncode) {
	private InputStream stream;
	this(InputStream stream) {
		this.stream = stream;;
	}
	CoreEncode readLine() {
		OtherEncode o = cast(OtherEncode)stream.readLine();
		CoreEncode c;
		encode(o, c);
		return c;
	}
}

// 新しい文字エンコードごとに2つtypedef
typedef ubyte CP932Char;
typedef immutable(CP932Char)[] CP932String;

// CoreEncodeがstring(UTF8)である体系として相互変換関数を定義
void encode(string input, ref CP932String output) {
	const(char)* s = toMBSz(input);
	output = cast(CP932String)(s[0..strlen(s)]);
}

void encode(CP932String input, ref string output) {
	if (input.length != 0) {
		output = fromMBSz(cast(immutable(char*))input);
	}
}

// 定義しておくと便利
alias EncodedOutputStreamFilter!(string, CP932String) CP932OutputStream;
alias EncodedInputStreamFilter!(string, CP932String) CP932InputStream;

version(unittest) void main() {
	try {
		auto eout = new CP932OutputStream(dout);
		auto ein = new CP932InputStream(din);
		
		dout.writeLine("hogeほげ");
		eout.writeLine("hogeほげ");
		
		string hoge = ein.readLine();
		dout.writeLine(hoge);
		eout.writeLine(hoge);
	} catch (Object e) {
		dout.writeLine(e.toString());
	}
}

ほげほげStreamFilterと言いながらFilterStreamはおろかStreamさえ継承してなかったりするけど習作ということで.

実行結果を追記

hoge縺サ縺・
hogeほげ
ふがふが
縺オ縺後・縺・
ふがふが

これくらいシンプルだと拡張性が高くてするのも簡単でいいんじゃないかなあ.しらんけど.