File Annotation

Not logged in
dcdd144598 2011-02-23        kinaba: #include "stdafx.h"
dcdd144598 2011-02-23        kinaba: #include "app.h"
dcdd144598 2011-02-23        kinaba: #include "textfile.h"
dcdd144598 2011-02-23        kinaba: #include "ktlarray.h"
dcdd144598 2011-02-23        kinaba: using namespace ki;
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: //=========================================================================
dcdd144598 2011-02-23        kinaba: // テキストファイル読み出し共通インターフェイス
dcdd144598 2011-02-23        kinaba: //=========================================================================
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: struct ki::TextFileRPimpl : public Object
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	inline TextFileRPimpl()
dcdd144598 2011-02-23        kinaba: 		: state(EOL) {}
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	virtual size_t ReadLine( unicode* buf, ulong siz )
dcdd144598 2011-02-23        kinaba: 		= 0;
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	enum { EOF=0, EOL=1, EOB=2 } state;
dcdd144598 2011-02-23        kinaba: };
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: //-------------------------------------------------------------------------
dcdd144598 2011-02-23        kinaba: // Unicode系用のベースクラス
dcdd144598 2011-02-23        kinaba: //	UTF-8以外はそんなに出会わないだろうから遅くてもよしとする。
dcdd144598 2011-02-23        kinaba: //-------------------------------------------------------------------------
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: struct rBasicUTF : public ki::TextFileRPimpl
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	virtual unicode PeekC() = 0;
dcdd144598 2011-02-23        kinaba: 	virtual unicode GetC() {unicode ch=PeekC(); Skip(); return ch;}
dcdd144598 2011-02-23        kinaba: 	virtual void Skip() = 0;
dcdd144598 2011-02-23        kinaba: 	virtual bool Eof() = 0;
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	size_t ReadLine( unicode* buf, ulong siz )
dcdd144598 2011-02-23        kinaba: 	{
dcdd144598 2011-02-23        kinaba: 		state = EOF;
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 		// 改行が出るまで読む
dcdd144598 2011-02-23        kinaba: 		unicode *w=buf, *e=buf+siz;
dcdd144598 2011-02-23        kinaba: 		while( !Eof() )
dcdd144598 2011-02-23        kinaba: 		{
dcdd144598 2011-02-23        kinaba: 			*w = GetC();
dcdd144598 2011-02-23        kinaba: 			if( *w==L'\r' || *w==L'\n' )
dcdd144598 2011-02-23        kinaba: 			{
dcdd144598 2011-02-23        kinaba: 				state = EOL;
dcdd144598 2011-02-23        kinaba: 				break;
dcdd144598 2011-02-23        kinaba: 			}
dcdd144598 2011-02-23        kinaba: 			else if( *w!=0xfeff && ++w==e )
dcdd144598 2011-02-23        kinaba: 			{
dcdd144598 2011-02-23        kinaba: 				state = EOB;
dcdd144598 2011-02-23        kinaba: 				break;
dcdd144598 2011-02-23        kinaba: 			}
dcdd144598 2011-02-23        kinaba: 		}
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 		// 改行コードスキップ処理
dcdd144598 2011-02-23        kinaba: 		if( state == EOL )
dcdd144598 2011-02-23        kinaba: 			if( *w==L'\r' && !Eof() && PeekC()==L'\n' )
dcdd144598 2011-02-23        kinaba: 				Skip();
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 		// 読んだ文字数
dcdd144598 2011-02-23        kinaba: 		return w-buf;
dcdd144598 2011-02-23        kinaba: 	}
dcdd144598 2011-02-23        kinaba: };
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: //-------------------------------------------------------------------------
dcdd144598 2011-02-23        kinaba: // UCS2ベタ/UCS4ベタ。それぞれUTF16, UTF32の代わりとして使う。
dcdd144598 2011-02-23        kinaba: // ついでに同じtemplateで、ISO-8859-1も処理してしまう。^^;
dcdd144598 2011-02-23        kinaba: //-------------------------------------------------------------------------
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: template<typename T>
dcdd144598 2011-02-23        kinaba: struct rUCS : public rBasicUTF
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	rUCS( const uchar* b, ulong s, bool bigendian )
dcdd144598 2011-02-23        kinaba: 		: fb( reinterpret_cast<const T*>(b) )
dcdd144598 2011-02-23        kinaba: 		, fe( reinterpret_cast<const T*>(b+(s/sizeof(T))*sizeof(T)) )
dcdd144598 2011-02-23        kinaba: 		, be( bigendian ) {}
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	const T *fb, *fe;
dcdd144598 2011-02-23        kinaba: 	const bool be;
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	// エンディアン変換
dcdd144598 2011-02-23        kinaba: 	inline  byte swap(  byte val ) { return val; }
dcdd144598 2011-02-23        kinaba: 	inline dbyte swap( dbyte val ) { return (val<<8) |(val>>8); }
dcdd144598 2011-02-23        kinaba: 	inline qbyte swap( qbyte val ) { return ((val>>24)&0xff |
dcdd144598 2011-02-23        kinaba: 	                                         (val>>8)&0xff00 |
dcdd144598 2011-02-23        kinaba: 											 (val<<8)&0xff0000|
dcdd144598 2011-02-23        kinaba: 											 (val<<24)); }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	virtual void Skip() { ++fb; }
dcdd144598 2011-02-23        kinaba: 	virtual bool Eof() { return fb==fe; }
dcdd144598 2011-02-23        kinaba: 	virtual unicode PeekC() { return (unicode)(be ? swap(*fb) : *fb); }
dcdd144598 2011-02-23        kinaba: };
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: typedef rUCS< byte> rWest;
dcdd144598 2011-02-23        kinaba: typedef rUCS<dbyte> rUtf16;
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: // UTF-32読み込み
dcdd144598 2011-02-23        kinaba: struct rUtf32 : public rUCS<qbyte>
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	rUtf32( const uchar* b, ulong s, bool bigendian )
dcdd144598 2011-02-23        kinaba: 		: rUCS<qbyte>(b,s,bigendian)
dcdd144598 2011-02-23        kinaba: 		, state(0) {}
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	int state;
dcdd144598 2011-02-23        kinaba: 	qbyte curChar() { return be ? swap(*fb) : *fb; }
dcdd144598 2011-02-23        kinaba: 	bool inBMP(qbyte c) { return c<0x10000; }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	virtual unicode PeekC()
dcdd144598 2011-02-23        kinaba: 	{
dcdd144598 2011-02-23        kinaba: 		qbyte c = curChar();
dcdd144598 2011-02-23        kinaba: 		if( inBMP(c) )
dcdd144598 2011-02-23        kinaba: 			return (unicode)c;
dcdd144598 2011-02-23        kinaba: 		return (unicode)(state==0 ? 0xD800 + (((c-0x10000) >> 10)&0x3ff)
dcdd144598 2011-02-23        kinaba: 			                      : 0xDC00 + ( (c-0x10000)       &0x3ff));
dcdd144598 2011-02-23        kinaba: 	}
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	virtual void Skip()
dcdd144598 2011-02-23        kinaba: 	{
dcdd144598 2011-02-23        kinaba: 		if( inBMP(curChar()) )
dcdd144598 2011-02-23        kinaba: 			++fb;
dcdd144598 2011-02-23        kinaba: 		else if( state==0 )
dcdd144598 2011-02-23        kinaba: 			state=1;
dcdd144598 2011-02-23        kinaba: 		else
dcdd144598 2011-02-23        kinaba: 			++fb, state=0;
dcdd144598 2011-02-23        kinaba: 	}
dcdd144598 2011-02-23        kinaba: };
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: //-------------------------------------------------------------------------
dcdd144598 2011-02-23        kinaba: // UTF-5
dcdd144598 2011-02-23        kinaba: //     0-  F : 1bbbb
dcdd144598 2011-02-23        kinaba: //    10- FF : 1bbbb 0bbbb
dcdd144598 2011-02-23        kinaba: //   100-FFF : 1bbbb 0bbbb 0bbbb
dcdd144598 2011-02-23        kinaba: // というように、16進での一桁を一文字で表していくフォーマット。
dcdd144598 2011-02-23        kinaba: // 各 0bbbb は '0', '1', ... '9', 'A', ... 'F'
dcdd144598 2011-02-23        kinaba: // 各 1bbbb は 'G', 'H', ... 'P', 'Q', ... 'V' の字で表現。
dcdd144598 2011-02-23        kinaba: //-------------------------------------------------------------------------
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: struct rUtf5 : public rBasicUTF
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	rUtf5( const uchar* b, ulong s )
dcdd144598 2011-02-23        kinaba: 		: fb( b )
dcdd144598 2011-02-23        kinaba: 		, fe( b+s ) {}
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	const uchar *fb, *fe;
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	// 16進文字から整数値へ変換
dcdd144598 2011-02-23        kinaba: 	inline byte conv( uchar x )
dcdd144598 2011-02-23        kinaba: 	{
dcdd144598 2011-02-23        kinaba: 		if( '0'<=x && x<='9' ) return x-'0';
dcdd144598 2011-02-23        kinaba: 		else                   return x-'A'+0x0A;
dcdd144598 2011-02-23        kinaba: 	}
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	void Skip() { do ++fb; while( fb<fe && *fb<'G' ); }
dcdd144598 2011-02-23        kinaba: 	bool Eof() { return fb==fe; }
dcdd144598 2011-02-23        kinaba: 	unicode PeekC()
dcdd144598 2011-02-23        kinaba: 	{
dcdd144598 2011-02-23        kinaba: 		unicode ch = (*fb-'G');
dcdd144598 2011-02-23        kinaba: 		for( const uchar* p=fb+1; p<fe && *p<'G'; ++p )
dcdd144598 2011-02-23        kinaba: 			ch = (ch<<4)|conv(*p);
dcdd144598 2011-02-23        kinaba: 		return ch;
dcdd144598 2011-02-23        kinaba: 	}
dcdd144598 2011-02-23        kinaba: };
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: //-------------------------------------------------------------------------
dcdd144598 2011-02-23        kinaba: // UTF-7
dcdd144598 2011-02-23        kinaba: //   ASCII範囲の字はそのまま。それ以外はUTF-16の値をbase64エンコード
dcdd144598 2011-02-23        kinaba: //   して出力。エンコードされた部分は + と - で挟まれる。また '+' と
dcdd144598 2011-02-23        kinaba: //   いう字自体を表現するために "+-" という形式を用いる。
dcdd144598 2011-02-23        kinaba: //-------------------------------------------------------------------------
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: namespace
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	static const uchar u7c[128]={
dcdd144598 2011-02-23        kinaba: 	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
dcdd144598 2011-02-23        kinaba: 	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
dcdd144598 2011-02-23        kinaba: 	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3e,0xff,0xff,0xff,0x3f,
dcdd144598 2011-02-23        kinaba: 	0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0xff,0xff,0xff,0xff,0xff,0xff,
dcdd144598 2011-02-23        kinaba: 	0xff,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,
dcdd144598 2011-02-23        kinaba: 	0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0xff,0xff,0xff,0xff,0xff,
dcdd144598 2011-02-23        kinaba: 	0xff,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,
dcdd144598 2011-02-23        kinaba: 	0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0xff,0xff,0xff,0xff,0xff };
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: struct rUtf7 : public rBasicUTF
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	rUtf7( const uchar* b, ulong s )
dcdd144598 2011-02-23        kinaba: 		: fb( b )
dcdd144598 2011-02-23        kinaba: 		, fe( b+s )
dcdd144598 2011-02-23        kinaba: 		, rest( -1 ) { fillbuf(); }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	const uchar *fb, *fe;
dcdd144598 2011-02-23        kinaba: 	unicode buf[3]; // b64を8文字毎に読んでバッファに溜めておく
dcdd144598 2011-02-23        kinaba: 	int rest;       // バッファの空き
dcdd144598 2011-02-23        kinaba: 	bool inB64;     // base64エリア内ならtrue
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	void Skip() { if(--rest==0) fillbuf(); }
dcdd144598 2011-02-23        kinaba: 	bool Eof() { return fb==fe && rest==0; }
dcdd144598 2011-02-23        kinaba: 	unicode PeekC() { return buf[rest-1]; }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	void fillbuf()
dcdd144598 2011-02-23        kinaba: 	{
dcdd144598 2011-02-23        kinaba: 		if( fb<fe )
dcdd144598 2011-02-23        kinaba: 			if( !inB64 )
dcdd144598 2011-02-23        kinaba: 				if( *fb=='+' )
dcdd144598 2011-02-23        kinaba: 					if( fb+1<fe && fb[1]=='-' )
dcdd144598 2011-02-23        kinaba: 						rest=1, buf[0]=L'+', fb+=2;  // +-
dcdd144598 2011-02-23        kinaba: 					else
dcdd144598 2011-02-23        kinaba: 						++fb, inB64=true, fillbuf(); // 単独 +
dcdd144598 2011-02-23        kinaba: 				else
dcdd144598 2011-02-23        kinaba: 					rest=1, buf[0]=*fb++;            // 普通の字
dcdd144598 2011-02-23        kinaba: 			else
dcdd144598 2011-02-23        kinaba: 			{
dcdd144598 2011-02-23        kinaba: 				// 何文字デコードできるか数える
dcdd144598 2011-02-23        kinaba: 				int N=0, E=Max(int(fb-fe),8);
dcdd144598 2011-02-23        kinaba: 				while( N<E && fb[N]<0x80 && u7c[fb[N]]!=0xff )
dcdd144598 2011-02-23        kinaba: 					++N;
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 				// デコード
dcdd144598 2011-02-23        kinaba: 				buf[0]=buf[1]=buf[2]=0;
dcdd144598 2011-02-23        kinaba: 				switch( N )
dcdd144598 2011-02-23        kinaba: 				{
dcdd144598 2011-02-23        kinaba: 				case 8: buf[2]|= u7c[fb[7]];
dcdd144598 2011-02-23        kinaba: 				case 7: buf[2]|=(u7c[fb[6]]<< 6);
dcdd144598 2011-02-23        kinaba: 				case 6: buf[2]|=(u7c[fb[5]]<<12), buf[1]|=(u7c[fb[5]]>>4);
dcdd144598 2011-02-23        kinaba: 				case 5: buf[1]|=(u7c[fb[4]]<< 2);
dcdd144598 2011-02-23        kinaba: 				case 4: buf[1]|=(u7c[fb[3]]<< 8);
dcdd144598 2011-02-23        kinaba: 				case 3: buf[1]|=(u7c[fb[2]]<<14), buf[0]|=(u7c[fb[2]]>>2);
dcdd144598 2011-02-23        kinaba: 				case 2: buf[0]|=(u7c[fb[1]]<< 4);
dcdd144598 2011-02-23        kinaba: 				case 1: buf[0]|=(u7c[fb[0]]<<10);
dcdd144598 2011-02-23        kinaba: 					unicode t;
dcdd144598 2011-02-23        kinaba: 					rest = 1;
dcdd144598 2011-02-23        kinaba: 					if( N==8 )
dcdd144598 2011-02-23        kinaba: 						rest=3, t=buf[0], buf[0]=buf[2], buf[2]=t;
dcdd144598 2011-02-23        kinaba: 					else if( N>=6 )
dcdd144598 2011-02-23        kinaba: 						rest=2, t=buf[0], buf[0]=buf[1], buf[1]=t;
dcdd144598 2011-02-23        kinaba: 				}
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 				// 使った分進む
dcdd144598 2011-02-23        kinaba: 				if( N<E )
dcdd144598 2011-02-23        kinaba: 				{
dcdd144598 2011-02-23        kinaba: 					inB64=false;
dcdd144598 2011-02-23        kinaba: 					if( fb[N]=='-' )
dcdd144598 2011-02-23        kinaba: 						++fb;
dcdd144598 2011-02-23        kinaba: 				}
dcdd144598 2011-02-23        kinaba: 				fb += N;
dcdd144598 2011-02-23        kinaba: 				if( N==0 )
dcdd144598 2011-02-23        kinaba: 					fillbuf();
dcdd144598 2011-02-23        kinaba: 			}
dcdd144598 2011-02-23        kinaba: 	}
dcdd144598 2011-02-23        kinaba: };
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: //-------------------------------------------------------------------------
dcdd144598 2011-02-23        kinaba: // UTF8/MBCS
dcdd144598 2011-02-23        kinaba: //  CR,LFが1バイト文字としてきちんと出てくるので、
dcdd144598 2011-02-23        kinaba: //  切り分けが簡単な形式をここでまとめて扱う。UTF8以外の変換は
dcdd144598 2011-02-23        kinaba: //  Windowsに全て任せている。
dcdd144598 2011-02-23        kinaba: //-------------------------------------------------------------------------
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: namespace
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	typedef char* (WINAPI * uNextFunc)(WORD,const char*,DWORD);
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	static const byte mask[] = { 0, 0xff, 0x1f, 0x0f, 0x07, 0x03, 0x01 };
dcdd144598 2011-02-23        kinaba: 	static inline int GetMaskIndex(uchar n)
dcdd144598 2011-02-23        kinaba: 	{
dcdd144598 2011-02-23        kinaba: 		if( uchar(n+2) < 0xc2 ) return 1; // 00〜10111111, fe, ff
dcdd144598 2011-02-23        kinaba: 		if( n          < 0xe0 ) return 2; // 110xxxxx
dcdd144598 2011-02-23        kinaba: 		if( n          < 0xf0 ) return 3; // 1110xxxx
dcdd144598 2011-02-23        kinaba: 		if( n          < 0xf8 ) return 4; // 11110xxx
dcdd144598 2011-02-23        kinaba: 		if( n          < 0xfc ) return 5; // 111110xx
dcdd144598 2011-02-23        kinaba: 		                        return 6; // 1111110x
dcdd144598 2011-02-23        kinaba: 	}
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	static char* WINAPI CharNextUtf8( WORD, const char* p, DWORD )
dcdd144598 2011-02-23        kinaba: 	{
dcdd144598 2011-02-23        kinaba: 		return const_cast<char*>( p+GetMaskIndex(uchar(*p)) );
dcdd144598 2011-02-23        kinaba: 	}
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	// Win95対策。
dcdd144598 2011-02-23        kinaba: 	//   http://support.microsoft.com/default.aspx?scid=%2Fisapi%2Fgomscom%2Easp%3Ftarget%3D%2Fjapan%2Fsupport%2Fkb%2Farticles%2Fjp175%2F3%2F92%2Easp&LN=JA
dcdd144598 2011-02-23        kinaba: 	// MSDNにはWin95以降でサポートと書いてあるのにCP_UTF8は
dcdd144598 2011-02-23        kinaba: 	// 使えないらしいので、自前の変換関数で。
dcdd144598 2011-02-23        kinaba: 	typedef int (WINAPI * uConvFunc)(UINT,DWORD,const char*,int,wchar_t*,int);
dcdd144598 2011-02-23        kinaba: 	static int WINAPI Utf8ToWideChar( UINT, DWORD, const char* sb, int ss, wchar_t* wb, int ws )
dcdd144598 2011-02-23        kinaba: 	{
dcdd144598 2011-02-23        kinaba: 		const uchar *p = reinterpret_cast<const uchar*>(sb);
dcdd144598 2011-02-23        kinaba: 		const uchar *e = reinterpret_cast<const uchar*>(sb+ss);
dcdd144598 2011-02-23        kinaba: 		wchar_t     *w = wb; // バッファサイズチェック無し(仕様)
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 		for( int t; p<e; ++w )
dcdd144598 2011-02-23        kinaba: 		{
dcdd144598 2011-02-23        kinaba: 			t  = GetMaskIndex(*p);
dcdd144598 2011-02-23        kinaba: 			qbyte qch = (*p++ & mask[t]);
dcdd144598 2011-02-23        kinaba: 			while( p<e && --t )
dcdd144598 2011-02-23        kinaba: 				qch<<=6, qch|=(*p++)&0x3f;
dcdd144598 2011-02-23        kinaba: 			if(qch<0x10000)
dcdd144598 2011-02-23        kinaba: 				*w = (wchar_t)qch;
dcdd144598 2011-02-23        kinaba: 			else
dcdd144598 2011-02-23        kinaba: 				*w++ = (wchar_t)(0xD800 + (((qch-0x10000)>>10)&0x3ff)),
dcdd144598 2011-02-23        kinaba: 				*w   = (wchar_t)(0xDC00 + (((qch-0x10000)    )&0x3ff));
dcdd144598 2011-02-23        kinaba: 		}
dcdd144598 2011-02-23        kinaba: 		return int(w-wb);
dcdd144598 2011-02-23        kinaba: 	}
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: struct rMBCS : public TextFileRPimpl
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	// ファイルポインタ&コードページ
dcdd144598 2011-02-23        kinaba: 	const char* fb;
dcdd144598 2011-02-23        kinaba: 	const char* fe;
dcdd144598 2011-02-23        kinaba: 	const int   cp;
dcdd144598 2011-02-23        kinaba: 	uNextFunc next;
dcdd144598 2011-02-23        kinaba: 	uConvFunc conv;
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	// 初期設定
dcdd144598 2011-02-23        kinaba: 	rMBCS( const uchar* b, ulong s, int c )
dcdd144598 2011-02-23        kinaba: 		: fb( reinterpret_cast<const char*>(b) )
dcdd144598 2011-02-23        kinaba: 		, fe( reinterpret_cast<const char*>(b+s) )
dcdd144598 2011-02-23        kinaba: 		, cp( c==UTF8 ? UTF8N : c )
dcdd144598 2011-02-23        kinaba: 		, next( cp==UTF8N ?   CharNextUtf8 : CharNextExA )
dcdd144598 2011-02-23        kinaba: 		, conv( cp==UTF8N && app().isWin95()
dcdd144598 2011-02-23        kinaba: 		                  ? Utf8ToWideChar : MultiByteToWideChar )
dcdd144598 2011-02-23        kinaba: 	{
dcdd144598 2011-02-23        kinaba: 		if( cp==UTF8N && fe-fb>=3
dcdd144598 2011-02-23        kinaba: 		 && b[0]==0xef && b[1]==0xbb && b[2]==0xbf )
dcdd144598 2011-02-23        kinaba: 			fb += 3; // BOMスキップ
dcdd144598 2011-02-23        kinaba: 	}
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	size_t ReadLine( unicode* buf, ulong siz )
dcdd144598 2011-02-23        kinaba: 	{
dcdd144598 2011-02-23        kinaba: 		// バッファの終端か、ファイルの終端の近い方まで読み込む
dcdd144598 2011-02-23        kinaba: 		const char *p, *end = Min( fb+siz/2, fe );
dcdd144598 2011-02-23        kinaba: 		state = (end==fe ? EOF : EOB);
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 		// 改行が出るまで進む
dcdd144598 2011-02-23        kinaba: 		for( p=fb; p<end; )
dcdd144598 2011-02-23        kinaba: 			if( *p=='\r' || *p=='\n' )
dcdd144598 2011-02-23        kinaba: 			{
dcdd144598 2011-02-23        kinaba: 				state = EOL;
dcdd144598 2011-02-23        kinaba: 				break;
dcdd144598 2011-02-23        kinaba: 			}
dcdd144598 2011-02-23        kinaba: 			else if( (*p) & 0x80 )
dcdd144598 2011-02-23        kinaba: 			{
dcdd144598 2011-02-23        kinaba: 				p = next(cp,p,0);
dcdd144598 2011-02-23        kinaba: 			}
dcdd144598 2011-02-23        kinaba: 			else
dcdd144598 2011-02-23        kinaba: 			{
dcdd144598 2011-02-23        kinaba: 				++p;
dcdd144598 2011-02-23        kinaba: 			}
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 		// Unicodeへ変換
dcdd144598 2011-02-23        kinaba: #ifndef _UNICODE
dcdd144598 2011-02-23        kinaba: 		ulong len = conv( cp, 0, fb, p-fb, buf, siz );
dcdd144598 2011-02-23        kinaba: #else
dcdd144598 2011-02-23        kinaba: 		ulong len = ::MultiByteToWideChar( cp, 0, fb, int(p-fb), buf, siz );
dcdd144598 2011-02-23        kinaba: #endif
dcdd144598 2011-02-23        kinaba: 		// 改行コードスキップ処理
dcdd144598 2011-02-23        kinaba: 		if( state == EOL )
dcdd144598 2011-02-23        kinaba: 			if( *(p++)=='\r' && p<fe && *p=='\n' )
dcdd144598 2011-02-23        kinaba: 				++p;
dcdd144598 2011-02-23        kinaba: 		fb = p;
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 		// 終了
dcdd144598 2011-02-23        kinaba: 		return len;
dcdd144598 2011-02-23        kinaba: 	}
dcdd144598 2011-02-23        kinaba: };
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: //-------------------------------------------------------------------------
dcdd144598 2011-02-23        kinaba: // ISO-2022 の適当な実装
dcdd144598 2011-02-23        kinaba: //
dcdd144598 2011-02-23        kinaba: //	コードページとして、G0, G1, G2, G3 の四面を持つ。
dcdd144598 2011-02-23        kinaba: //	それぞれ決まったエスケープシーケンスによって、
dcdd144598 2011-02-23        kinaba: //	さまざまな文字集合を各面に呼び出すことが出来る。
dcdd144598 2011-02-23        kinaba: //	とりあえず現在のバージョンで対応しているふりなのは
dcdd144598 2011-02-23        kinaba: //	次の通り。()内に、そのいい加減っぷりを示す。
dcdd144598 2011-02-23        kinaba: //
dcdd144598 2011-02-23        kinaba: //		<<いつでも>>
dcdd144598 2011-02-23        kinaba: //		1B 28 42    : G0へ ASCII
dcdd144598 2011-02-23        kinaba: //		1B 28 4A    : G0へ JIS X 0201 ローマ字 (のかわりにASCII)
dcdd144598 2011-02-23        kinaba: //		1B 29 4A    : G1へ JIS X 0201 ローマ字 (のかわりにASCII)
dcdd144598 2011-02-23        kinaba: //		1B 2A 4A    : G2へ JIS X 0201 ローマ字 (のかわりにASCII)
dcdd144598 2011-02-23        kinaba: //		1B 3B 4A    : G3へ JIS X 0201 ローマ字 (のかわりにASCII)
dcdd144598 2011-02-23        kinaba: //		1B 2E 41    : G2へ ISO-8859-1
dcdd144598 2011-02-23        kinaba: //		<<CP932が有効な場合>>
dcdd144598 2011-02-23        kinaba: //		1B 28 49    : G0へ JIS X 0201 カナ
dcdd144598 2011-02-23        kinaba: //		1B 29 49    : G1へ JIS X 0201 カナ
dcdd144598 2011-02-23        kinaba: //		1B 2A 49    : G2へ JIS X 0201 カナ
dcdd144598 2011-02-23        kinaba: //		1B 2B 49    : G3へ JIS X 0201 カナ
dcdd144598 2011-02-23        kinaba: //		1B 24 40    : G0へ JIS X 0208(1978)
dcdd144598 2011-02-23        kinaba: //		1B 24 42    : G0へ JIS X 0208(1983)    (年度は区別しない)
dcdd144598 2011-02-23        kinaba: //		<<CP936が有効な場合>>
dcdd144598 2011-02-23        kinaba: //		1B 24 41    : G0へ GB 2312
dcdd144598 2011-02-23        kinaba: //		1B 24 29 41 : G1へ GB 2312
dcdd144598 2011-02-23        kinaba: //		1B 24 2A 41 : G2へ GB 2312
dcdd144598 2011-02-23        kinaba: //		1B 24 2B 41 : G3へ GB 2312
dcdd144598 2011-02-23        kinaba: //		<<CP949が有効な場合>>
dcdd144598 2011-02-23        kinaba: //		1B 24 28 43 : G0へ KS X 1001
dcdd144598 2011-02-23        kinaba: //		1B 24 29 43 : G1へ KS X 1001
dcdd144598 2011-02-23        kinaba: //		1B 24 2A 43 : G2へ KS X 1001
dcdd144598 2011-02-23        kinaba: //		1B 24 2B 43 : G3へ KS X 1001
dcdd144598 2011-02-23        kinaba: //
dcdd144598 2011-02-23        kinaba: //	各面に呼び出した文字集合は、
dcdd144598 2011-02-23        kinaba: //		GL (0x21〜0xfe) GR (0xa0〜0xff)
dcdd144598 2011-02-23        kinaba: //	のどちらかへマップすることで、実際のバイト値となる。
dcdd144598 2011-02-23        kinaba: //	マップ命令となるバイト列は、次の通り
dcdd144598 2011-02-23        kinaba: //
dcdd144598 2011-02-23        kinaba: //		0F    : GL        へG0を呼び出し
dcdd144598 2011-02-23        kinaba: //		0E    : GL        へG1を呼び出し
dcdd144598 2011-02-23        kinaba: //		1B 7E : GR        へG1を呼び出し
dcdd144598 2011-02-23        kinaba: //		8E    : GL/GR両方 へG2を一瞬だけ呼び出し。1B 4E も同義
dcdd144598 2011-02-23        kinaba: //		8F    : GL/GR両方 へG3を一瞬だけ呼び出し。1B 4F も同義
dcdd144598 2011-02-23        kinaba: //
dcdd144598 2011-02-23        kinaba: //-------------------------------------------------------------------------
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: enum CodeSet { ASCII, LATIN, KANA, JIS, KSX, GB };
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: struct rIso2022 : public TextFileRPimpl
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	// Helper: JIS X 0208 => SJIS
dcdd144598 2011-02-23        kinaba: 	void jis2sjis( uchar k, uchar t, char* s )
dcdd144598 2011-02-23        kinaba: 	{
dcdd144598 2011-02-23        kinaba: 		if(k>=0x3f)	s[0] = (char)(((k+1)>>1)+0xc0);
dcdd144598 2011-02-23        kinaba: 		else		s[0] = (char)(((k+1)>>1)+0x80);
dcdd144598 2011-02-23        kinaba: 		if( k&1 )	s[1] = (char)((t>>6) ? t+0x40 : t+0x3f);
dcdd144598 2011-02-23        kinaba: 		else		s[1] = (char)(t+0x9e);
dcdd144598 2011-02-23        kinaba: 	}
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	// ファイルポインタ
dcdd144598 2011-02-23        kinaba: 	const uchar* fb;
dcdd144598 2011-02-23        kinaba: 	const uchar* fe;
dcdd144598 2011-02-23        kinaba: 	bool      fixed; // ESCによる切り替えを行わないならtrue
dcdd144598 2011-02-23        kinaba: 	bool    mode_hz; // HZの場合。
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	// 作業変数
dcdd144598 2011-02-23        kinaba: 	CodeSet *GL, *GR, G[4];
dcdd144598 2011-02-23        kinaba: 	int gWhat; // 次の字は 1:GL/GR 2:G2 3:G3 で出力
dcdd144598 2011-02-23        kinaba: 	ulong len;
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	// 初期化
dcdd144598 2011-02-23        kinaba: 	rIso2022( const uchar* b, ulong s, bool f, bool hz,
dcdd144598 2011-02-23        kinaba: 		CodeSet g0, CodeSet g1, CodeSet g2=ASCII, CodeSet g3=ASCII )
dcdd144598 2011-02-23        kinaba: 		: fb( b )
dcdd144598 2011-02-23        kinaba: 		, fe( b+s )
dcdd144598 2011-02-23        kinaba: 		, fixed( f )
dcdd144598 2011-02-23        kinaba: 		, mode_hz( hz )
dcdd144598 2011-02-23        kinaba: 		, GL( &G[0] )
dcdd144598 2011-02-23        kinaba: 		, GR( &G[1] )
dcdd144598 2011-02-23        kinaba: 		, gWhat( 1 )
dcdd144598 2011-02-23        kinaba: 	{
dcdd144598 2011-02-23        kinaba: 		G[0]=g0, G[1]=g1, G[2]=g2, G[3]=g3;
dcdd144598 2011-02-23        kinaba: 	}
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	void DoSwitching( const uchar*& p )
dcdd144598 2011-02-23        kinaba: 	{
dcdd144598 2011-02-23        kinaba: 		if( fixed )
dcdd144598 2011-02-23        kinaba: 		{
dcdd144598 2011-02-23        kinaba: 			if( p[0]==0x24 && p[1]!=0x40 && p[1]!=0x41 && p[1]!=0x42
dcdd144598 2011-02-23        kinaba: 			 && p+2 < fe && (p[2]==0x41 || p[2]==0x43) )
dcdd144598 2011-02-23        kinaba: 				++p;
dcdd144598 2011-02-23        kinaba: 		}
dcdd144598 2011-02-23        kinaba: 		else
dcdd144598 2011-02-23        kinaba: 		{
dcdd144598 2011-02-23        kinaba: 			if( p[1]==0x4A )
dcdd144598 2011-02-23        kinaba: 				G[ (p[0]-0x28)%4 ] = ASCII;         // 1B [28-2B] 4A
dcdd144598 2011-02-23        kinaba: 			else if( p[1]==0x49 )
dcdd144598 2011-02-23        kinaba: 				G[ (p[0]-0x28)%4 ] = KANA;          // 1B [28-2B] 49
dcdd144598 2011-02-23        kinaba: 			else if( *reinterpret_cast<const dbyte*>(p)==0x4228 )
dcdd144598 2011-02-23        kinaba: 				G[ 0 ] = ASCII;                     // 1B 28 42
dcdd144598 2011-02-23        kinaba: 			else if( *reinterpret_cast<const dbyte*>(p)==0x412E )
dcdd144598 2011-02-23        kinaba: 				G[ 2 ] = LATIN;                     // 1B 2E 41
dcdd144598 2011-02-23        kinaba: 			else if( p[0]==0x24 )
dcdd144598 2011-02-23        kinaba: 				if( p[1]==0x40 || p[1]==0x42 )
dcdd144598 2011-02-23        kinaba: 					G[ 0 ] = JIS;                   // 1B 24 [40|42]
dcdd144598 2011-02-23        kinaba: 				else if( p[1]==0x41 )
dcdd144598 2011-02-23        kinaba: 					G[ 0 ] = GB;                    // 1B 24 41
dcdd144598 2011-02-23        kinaba: 				else if( p+2 < fe )
dcdd144598 2011-02-23        kinaba: 					if( p[2]==0x41 )
dcdd144598 2011-02-23        kinaba: 						G[ ((*++p)-0x28)%4 ] = GB;  // 1B 24 [28-2B] 41
dcdd144598 2011-02-23        kinaba: 					else if( p[2]==0x43 )
dcdd144598 2011-02-23        kinaba: 						G[ ((*++p)-0x28)%4 ] = KSX; // 1B 24 [28-2B] 43
dcdd144598 2011-02-23        kinaba: 		}
dcdd144598 2011-02-23        kinaba: 		++p;
dcdd144598 2011-02-23        kinaba: 	}
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	void DoOutput( unicode*& buf, const uchar*& p )
dcdd144598 2011-02-23        kinaba: 	{
dcdd144598 2011-02-23        kinaba: 		// 文字集合取り出し
dcdd144598 2011-02-23        kinaba: 		CodeSet cs =
dcdd144598 2011-02-23        kinaba: 			(gWhat==2 ? G[2] :
dcdd144598 2011-02-23        kinaba: 			(gWhat==3 ? G[3] :
dcdd144598 2011-02-23        kinaba: 			(*p&0x80  ? *GR  : *GL)));
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 		char c[2];
dcdd144598 2011-02-23        kinaba: 		ulong wt=1;
dcdd144598 2011-02-23        kinaba: 		switch( cs )
dcdd144598 2011-02-23        kinaba: 		{
dcdd144598 2011-02-23        kinaba: 		case ASCII:
dcdd144598 2011-02-23        kinaba: 			*buf = (*p)&0x7f;
dcdd144598 2011-02-23        kinaba: 			break;
dcdd144598 2011-02-23        kinaba: 		case LATIN:
dcdd144598 2011-02-23        kinaba: 			*buf = (*p)|0x80;
dcdd144598 2011-02-23        kinaba: 			break;
dcdd144598 2011-02-23        kinaba: 		case KANA:
dcdd144598 2011-02-23        kinaba: 			c[0] = (*p)|0x80;
dcdd144598 2011-02-23        kinaba: 			wt = ::MultiByteToWideChar(
dcdd144598 2011-02-23        kinaba: 				932, MB_PRECOMPOSED, c, 1, buf, 2 );
dcdd144598 2011-02-23        kinaba: 			break;
dcdd144598 2011-02-23        kinaba: 		case GB:
dcdd144598 2011-02-23        kinaba: 		case KSX:
dcdd144598 2011-02-23        kinaba: 			c[0] = (*  p)|0x80;
dcdd144598 2011-02-23        kinaba: 			c[1] = (*++p)|0x80;
dcdd144598 2011-02-23        kinaba: 			wt = ::MultiByteToWideChar(
dcdd144598 2011-02-23        kinaba: 				(cs==GB?936:949), MB_PRECOMPOSED, c, 2, buf, 2 );
dcdd144598 2011-02-23        kinaba: 			break;
dcdd144598 2011-02-23        kinaba: 		case JIS:
dcdd144598 2011-02-23        kinaba: 			jis2sjis( (p[0]&0x7f)-0x20, (p[1]&0x7f)-0x20, c );
dcdd144598 2011-02-23        kinaba: 			++p;
dcdd144598 2011-02-23        kinaba: 			wt = ::MultiByteToWideChar(
dcdd144598 2011-02-23        kinaba: 				932, MB_PRECOMPOSED, c, 2, buf, 2 );
dcdd144598 2011-02-23        kinaba: 			break;
dcdd144598 2011-02-23        kinaba: 		}
dcdd144598 2011-02-23        kinaba: 		buf+=wt;
dcdd144598 2011-02-23        kinaba: 		len+=wt;
dcdd144598 2011-02-23        kinaba: 	}
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	size_t ReadLine( unicode* buf, ulong siz )
dcdd144598 2011-02-23        kinaba: 	{
dcdd144598 2011-02-23        kinaba: 		len=0;
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 		// バッファの終端か、ファイルの終端の近い方まで読み込む
dcdd144598 2011-02-23        kinaba: 		const uchar *p, *end = Min( fb+siz/2, fe );
dcdd144598 2011-02-23        kinaba: 		state = (end==fe ? EOF : EOB);
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 		// 改行が出るまで進む
dcdd144598 2011-02-23        kinaba: 		for( p=fb; p<end; ++p )
dcdd144598 2011-02-23        kinaba: 			switch( *p )
dcdd144598 2011-02-23        kinaba: 			{
dcdd144598 2011-02-23        kinaba: 			case '\r':
dcdd144598 2011-02-23        kinaba: 			case '\n': state =   EOL; goto outofloop;
dcdd144598 2011-02-23        kinaba: 			case 0x0F:    GL = &G[0]; break;
dcdd144598 2011-02-23        kinaba: 			case 0x0E:    GL = &G[1]; break;
dcdd144598 2011-02-23        kinaba: 			case 0x8E: gWhat =     2; break;
dcdd144598 2011-02-23        kinaba: 			case 0x8F: gWhat =     3; break;
dcdd144598 2011-02-23        kinaba: 			case 0x1B:
dcdd144598 2011-02-23        kinaba: 				if( p+1<fe ) {
dcdd144598 2011-02-23        kinaba: 					++p; if( *p==0x7E )    GR = &G[1];
dcdd144598 2011-02-23        kinaba: 					else if( *p==0x4E ) gWhat =  2;
dcdd144598 2011-02-23        kinaba: 					else if( *p==0x4F ) gWhat =  3;
dcdd144598 2011-02-23        kinaba: 					else if( p+1<fe )   DoSwitching(p);
dcdd144598 2011-02-23        kinaba: 				}break;
dcdd144598 2011-02-23        kinaba: 			case 0x7E: if( mode_hz && p+1<fe ) {
dcdd144598 2011-02-23        kinaba: 					++p; if( *p==0x7D ){ GL = &G[0]; break; }
dcdd144598 2011-02-23        kinaba: 					else if( *p==0x7B ){ GL = &G[1]; break; }
dcdd144598 2011-02-23        kinaba: 				} // fall through...
dcdd144598 2011-02-23        kinaba: 			default:   DoOutput( buf, p ); gWhat=1; break;
dcdd144598 2011-02-23        kinaba: 			}
dcdd144598 2011-02-23        kinaba: 		outofloop:
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 		// 改行コードスキップ処理
dcdd144598 2011-02-23        kinaba: 		if( state == EOL )
dcdd144598 2011-02-23        kinaba: 			if( *(p++)=='\r' && p<fe && *p=='\n' )
dcdd144598 2011-02-23        kinaba: 				++p;
dcdd144598 2011-02-23        kinaba: 		fb = p;
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 		// 終了
dcdd144598 2011-02-23        kinaba: 		return len;
dcdd144598 2011-02-23        kinaba: 	}
dcdd144598 2011-02-23        kinaba: };
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: //-------------------------------------------------------------------------
dcdd144598 2011-02-23        kinaba: // 自動判定などなど
dcdd144598 2011-02-23        kinaba: //-------------------------------------------------------------------------
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: TextFileR::TextFileR( int charset )
dcdd144598 2011-02-23        kinaba: 	: cs_( charset )
dcdd144598 2011-02-23        kinaba: 	, nolbFound_(true)
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: TextFileR::~TextFileR()
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	Close();
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: size_t TextFileR::ReadLine( unicode* buf, ulong siz )
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	return impl_->ReadLine( buf, siz );
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: int TextFileR::state() const
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	return impl_->state;
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: void TextFileR::Close()
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	fp_.Close();
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: bool TextFileR::Open( const TCHAR* fname )
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	// ファイルを開く
dcdd144598 2011-02-23        kinaba: 	if( !fp_.Open(fname) )
dcdd144598 2011-02-23        kinaba: 		return false;
dcdd144598 2011-02-23        kinaba: 	const uchar* buf = fp_.base();
dcdd144598 2011-02-23        kinaba: 	const ulong  siz = fp_.size();
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	// 必要なら自動判定
dcdd144598 2011-02-23        kinaba: 	cs_ = AutoDetection( cs_, buf, Min<ulong>(siz,16<<10) ); // 先頭16KB
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	// 対応するデコーダを作成
dcdd144598 2011-02-23        kinaba: 	switch( cs_ )
dcdd144598 2011-02-23        kinaba: 	{
dcdd144598 2011-02-23        kinaba: 	case Western: impl_ = new rWest(buf,siz,true); break;
dcdd144598 2011-02-23        kinaba: 	case UTF16b:
dcdd144598 2011-02-23        kinaba: 	case UTF16BE: impl_ = new rUtf16(buf,siz,true); break;
dcdd144598 2011-02-23        kinaba: 	case UTF16l:
dcdd144598 2011-02-23        kinaba: 	case UTF16LE: impl_ = new rUtf16(buf,siz,false); break;
dcdd144598 2011-02-23        kinaba: 	case UTF32b:
dcdd144598 2011-02-23        kinaba: 	case UTF32BE: impl_ = new rUtf32(buf,siz,true); break;
dcdd144598 2011-02-23        kinaba: 	case UTF32l:
dcdd144598 2011-02-23        kinaba: 	case UTF32LE: impl_ = new rUtf32(buf,siz,false); break;
dcdd144598 2011-02-23        kinaba: 	case UTF5:    impl_ = new rUtf5(buf,siz); break;
dcdd144598 2011-02-23        kinaba: 	case UTF7:    impl_ = new rUtf7(buf,siz); break;
dcdd144598 2011-02-23        kinaba: 	case EucJP:   impl_ = new rIso2022(buf,siz,true,false,ASCII,JIS,KANA); break;
dcdd144598 2011-02-23        kinaba: 	case IsoJP:   impl_ = new rIso2022(buf,siz,false,false,ASCII,KANA); break;
dcdd144598 2011-02-23        kinaba: 	case IsoKR:   impl_ = new rIso2022(buf,siz,true,false,ASCII,KSX); break;
dcdd144598 2011-02-23        kinaba: 	case IsoCN:   impl_ = new rIso2022(buf,siz,true,false,ASCII,GB); break;
dcdd144598 2011-02-23        kinaba: 	case HZ:      impl_ = new rIso2022(buf,siz,true,true, ASCII,GB); break;
dcdd144598 2011-02-23        kinaba: 	default:      impl_ = new rMBCS(buf,siz,cs_); break;
dcdd144598 2011-02-23        kinaba: 	}
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	return true;
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: int TextFileR::AutoDetection( int cs, const uchar* ptr, ulong siz )
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: //-- まず、文字の出現回数の統計を取る
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	int  freq[256];
dcdd144598 2011-02-23        kinaba: 	bool bit8 = false;
dcdd144598 2011-02-23        kinaba: 	mem00( freq, sizeof(freq) );
dcdd144598 2011-02-23        kinaba: 	for( ulong i=0; i<siz; ++i )
dcdd144598 2011-02-23        kinaba: 	{
dcdd144598 2011-02-23        kinaba: 		if( ptr[i] >= 0x80 )
dcdd144598 2011-02-23        kinaba: 			bit8 = true;
dcdd144598 2011-02-23        kinaba: 		++freq[ ptr[i] ];
dcdd144598 2011-02-23        kinaba: 	}
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: //-- 改行コード決定 (UTF16/32/7のとき問題あり。UTF5に至っては判定不可…)
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	     if( freq['\r'] > freq['\n']*2 ) lb_ = CR;
dcdd144598 2011-02-23        kinaba: 	else if( freq['\n'] > freq['\r']*2 ) lb_ = LF;
dcdd144598 2011-02-23        kinaba: 	else                                 lb_ = CRLF;
dcdd144598 2011-02-23        kinaba: 	nolbFound_ = freq['\r']==0 && freq['\n']==0;
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: //-- デフォルトコード
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	int defCs = ::GetACP();
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: //-- 小さすぎる場合はここで終了
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	if( siz <= 4 )
dcdd144598 2011-02-23        kinaba: 		return cs==AutoDetect ? defCs : cs;
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: //-- 明示指定がある場合はここで終了
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	ulong bom4 = (ptr[0]<<24) + (ptr[1]<<16) + (ptr[2]<<8) + (ptr[3]);
dcdd144598 2011-02-23        kinaba: 	ulong bom2 = (ptr[0]<<8)  + (ptr[1]);
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	if( cs==UTF8 || cs==UTF8N )
dcdd144598 2011-02-23        kinaba: 		cs = (bom4>>8==0xefbbbf ? UTF8 : UTF8N);
dcdd144598 2011-02-23        kinaba: 	else if( cs==UTF32b || cs==UTF32BE )
dcdd144598 2011-02-23        kinaba: 		cs = (bom4==0x0000feff ? UTF32b : UTF32BE);
dcdd144598 2011-02-23        kinaba: 	else if( cs==UTF32l || cs==UTF32LE )
dcdd144598 2011-02-23        kinaba: 		cs = (bom4==0xfffe0000 ? UTF32l : UTF32LE);
dcdd144598 2011-02-23        kinaba: 	else if( cs==UTF16b || cs==UTF16BE )
dcdd144598 2011-02-23        kinaba: 		cs = (bom2==0xfeff ? UTF16b : UTF16BE);
dcdd144598 2011-02-23        kinaba: 	else if( cs==UTF16l || cs==UTF16LE )
dcdd144598 2011-02-23        kinaba: 		cs = (bom2==0xfffe ? UTF16l : UTF16LE);
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	if( cs != AutoDetect )
dcdd144598 2011-02-23        kinaba: 		return cs;
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: //-- BOMチェック・7bitチェック
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	bool Jp = ::IsValidCodePage(932)!=FALSE;
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	if( (bom4>>8) == 0xefbbbf )   cs = UTF8;
dcdd144598 2011-02-23        kinaba: 	else if( bom4 == 0x0000feff ) cs = UTF32b;
dcdd144598 2011-02-23        kinaba: 	else if( bom4 == 0xfffe0000 ) cs = UTF32l;
dcdd144598 2011-02-23        kinaba: 	else if( bom2 == 0xfeff )     cs = UTF16b;
dcdd144598 2011-02-23        kinaba: 	else if( bom2 == 0xfffe )     cs = UTF16l;
dcdd144598 2011-02-23        kinaba: 	else if( bom4 == 0x1b242943 && ::IsValidCodePage(949) ) cs = IsoKR;
dcdd144598 2011-02-23        kinaba: 	else if( bom4 == 0x1b242941 && ::IsValidCodePage(936) ) cs = IsoCN;
dcdd144598 2011-02-23        kinaba: 	else if( Jp && !bit8 && freq[0x1b]>0 )                  cs = IsoJP;
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	if( cs != AutoDetect )
dcdd144598 2011-02-23        kinaba: 		return cs;
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: //-- UTF-5 チェック
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	ulong u5sum = 0;
dcdd144598 2011-02-23        kinaba: 	for( uchar c='0'; c<='9'; ++c ) u5sum += freq[c];
dcdd144598 2011-02-23        kinaba: 	for( uchar c='A'; c<='V'; ++c ) u5sum += freq[c];
dcdd144598 2011-02-23        kinaba: 	if( siz == u5sum )
dcdd144598 2011-02-23        kinaba: 		return UTF5;
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: //-- 暫定版 UTF-8 / 日本語EUC チェック
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	cs = defCs;
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	// 改行コードがLFか、ある程度の大きさか、でないと
dcdd144598 2011-02-23        kinaba: 	// 無条件で ANSI-CP と見なしてしまう。
dcdd144598 2011-02-23        kinaba: 	if( bit8 && (siz>4096 || lb_==1
dcdd144598 2011-02-23        kinaba: 	 || freq[0xfd]>0 || freq[0xfe]>0 || freq[0xff]>0 || freq[0x80]>0) )
dcdd144598 2011-02-23        kinaba: 	{
dcdd144598 2011-02-23        kinaba: 		// UHCやGBKはEUC-JPと非常に混同しやすいので、そっちがデフォルトの場合は
dcdd144598 2011-02-23        kinaba: 		// EUC-JP自動判定を切る
dcdd144598 2011-02-23        kinaba: 		if( Jp && ::GetACP()!=UHC && ::GetACP()!=GBK && ::GetACP()!=Big5 )
dcdd144598 2011-02-23        kinaba: 		{
dcdd144598 2011-02-23        kinaba: 			// EUCとしておかしい値が無いかチェック
dcdd144598 2011-02-23        kinaba: 			bool be=true;
dcdd144598 2011-02-23        kinaba: 			for( int k=0x90; k<=0xa0; ++k )if( freq[k]>0 ){be=false;break;}
dcdd144598 2011-02-23        kinaba: 			for( int k=0x7f; k<=0x8d; ++k )if( freq[k]>0 ){be=false;break;}
dcdd144598 2011-02-23        kinaba: 			if( be )
dcdd144598 2011-02-23        kinaba: 				return EucJP;
dcdd144598 2011-02-23        kinaba: 		}
dcdd144598 2011-02-23        kinaba: 		{
dcdd144598 2011-02-23        kinaba: 			// UTF8として読めるかどうかチェック
dcdd144598 2011-02-23        kinaba: 			bool b8=true;
dcdd144598 2011-02-23        kinaba: 			int mi=1;
dcdd144598 2011-02-23        kinaba: 			for( ulong i=0; i<siz && b8; ++i )
dcdd144598 2011-02-23        kinaba: 				if( --mi )
dcdd144598 2011-02-23        kinaba: 				{
dcdd144598 2011-02-23        kinaba: 					if( ptr[i]<0x80 || ptr[i]>=0xc0 )
dcdd144598 2011-02-23        kinaba: 						b8 = false;
dcdd144598 2011-02-23        kinaba: 				}
dcdd144598 2011-02-23        kinaba: 				else
dcdd144598 2011-02-23        kinaba: 				{
dcdd144598 2011-02-23        kinaba: 					mi = 1;
dcdd144598 2011-02-23        kinaba: 					if( ptr[i] > 0x7f )
dcdd144598 2011-02-23        kinaba: 					{
dcdd144598 2011-02-23        kinaba: 						mi = GetMaskIndex( ptr[i] );
dcdd144598 2011-02-23        kinaba: 						if( mi == 1 )//ptr[i] >= 0xfe )
dcdd144598 2011-02-23        kinaba: 							b8 = false;
dcdd144598 2011-02-23        kinaba: 					}
dcdd144598 2011-02-23        kinaba: 				}
dcdd144598 2011-02-23        kinaba: 			if( b8 )
dcdd144598 2011-02-23        kinaba: 				return UTF8N;
dcdd144598 2011-02-23        kinaba: 		}
dcdd144598 2011-02-23        kinaba: 	}
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: //-- 判定結果
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	return cs;
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: //=========================================================================
dcdd144598 2011-02-23        kinaba: // テキストファイル出力共通インターフェイス
dcdd144598 2011-02-23        kinaba: //=========================================================================
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: struct ki::TextFileWPimpl : public Object
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	virtual void WriteLine( const unicode* buf, ulong siz )
dcdd144598 2011-02-23        kinaba: 		{ while( siz-- ) WriteChar( *buf++ ); }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	virtual void WriteLB( const unicode* buf, ulong siz )
dcdd144598 2011-02-23        kinaba: 		{ WriteLine( buf, siz ); }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	virtual void WriteChar( unicode ch )
dcdd144598 2011-02-23        kinaba: 		{}
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	~TextFileWPimpl()
dcdd144598 2011-02-23        kinaba: 		{ delete [] buf_; }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: protected:
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	TextFileWPimpl( FileW& w )
dcdd144598 2011-02-23        kinaba: 		: fp_   (w)
dcdd144598 2011-02-23        kinaba: 		, bsiz_ (65536)
dcdd144598 2011-02-23        kinaba: 		, buf_  (new char[bsiz_]) {}
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	void ReserveMoreBuffer()
dcdd144598 2011-02-23        kinaba: 		{
dcdd144598 2011-02-23        kinaba: 			char* nBuf = new char[bsiz_<<=1];
dcdd144598 2011-02-23        kinaba: 			delete [] buf_;
dcdd144598 2011-02-23        kinaba: 			buf_ = nBuf;
dcdd144598 2011-02-23        kinaba: 		}
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	FileW& fp_;
dcdd144598 2011-02-23        kinaba: 	ulong  bsiz_;
dcdd144598 2011-02-23        kinaba: 	char*  buf_;
dcdd144598 2011-02-23        kinaba: };
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: //-------------------------------------------------------------------------
dcdd144598 2011-02-23        kinaba: // Unicodeテキスト
dcdd144598 2011-02-23        kinaba: //-------------------------------------------------------------------------
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: struct wUtf16LE : public TextFileWPimpl
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	wUtf16LE( FileW& w, bool bom ) : TextFileWPimpl(w)
dcdd144598 2011-02-23        kinaba: 		{ if(bom){ unicode ch=0xfeff; fp_.Write(&ch,2); } }
dcdd144598 2011-02-23        kinaba: 	void WriteLine( const unicode* buf, ulong siz ) {fp_.Write(buf,siz*2);}
dcdd144598 2011-02-23        kinaba: };
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: struct wUtf16BE : public TextFileWPimpl
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	wUtf16BE( FileW& w, bool bom ) : TextFileWPimpl(w)
dcdd144598 2011-02-23        kinaba: 		{ if(bom) WriteChar(0xfeff); }
dcdd144598 2011-02-23        kinaba: 	void WriteChar( unicode ch ) { fp_.WriteC(ch>>8), fp_.WriteC(ch&0xff); }
dcdd144598 2011-02-23        kinaba: };
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: struct wUtf32LE : public TextFileWPimpl
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	wUtf32LE( FileW& w, bool bom ) : TextFileWPimpl(w)
dcdd144598 2011-02-23        kinaba: 		{ if(bom) {unicode c=0xfeff; WriteLine(&c,1);} }
dcdd144598 2011-02-23        kinaba: //	void WriteChar( unicode ch )
dcdd144598 2011-02-23        kinaba: //		{ fp_.WriteC(ch&0xff), fp_.WriteC(ch>>8), fp_.WriteC(0), fp_.WriteC(0); }
dcdd144598 2011-02-23        kinaba: 	virtual void WriteLine( const unicode* buf, ulong siz )
dcdd144598 2011-02-23        kinaba: 	{
dcdd144598 2011-02-23        kinaba: 		while( siz-- )
dcdd144598 2011-02-23        kinaba: 		{
dcdd144598 2011-02-23        kinaba: 			unicode c = *buf++;
dcdd144598 2011-02-23        kinaba: 			qbyte  cc = c;
dcdd144598 2011-02-23        kinaba: 			if( (0xD800<=c && c<=0xDBFF) && siz>0 ) // trail char が正しいかどうかはチェックする気がない
dcdd144598 2011-02-23        kinaba: 			{
dcdd144598 2011-02-23        kinaba: 				unicode c2 = *buf++; siz--;
dcdd144598 2011-02-23        kinaba: 				cc = 0x10000 + (((c-0xD800)&0x3ff)<<10) + ((c2-0xDC00)&0x3ff);
dcdd144598 2011-02-23        kinaba: 			}
dcdd144598 2011-02-23        kinaba: 			for(int i=0; i<=3; ++i)
dcdd144598 2011-02-23        kinaba: 				fp_.WriteC( (uchar)(cc>>(8*i)) );
dcdd144598 2011-02-23        kinaba: 		}
dcdd144598 2011-02-23        kinaba: 	}
dcdd144598 2011-02-23        kinaba: };
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: struct wUtf32BE : public TextFileWPimpl
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	wUtf32BE( FileW& w, bool bom ) : TextFileWPimpl(w)
dcdd144598 2011-02-23        kinaba: 		{ if(bom) {unicode c=0xfeff; WriteLine(&c,1);} }
dcdd144598 2011-02-23        kinaba: //	void WriteChar( unicode ch )
dcdd144598 2011-02-23        kinaba: //		{ fp_.WriteC(0), fp_.WriteC(0), fp_.WriteC(ch>>8), fp_.WriteC(ch&0xff); }
dcdd144598 2011-02-23        kinaba: 	virtual void WriteLine( const unicode* buf, ulong siz )
dcdd144598 2011-02-23        kinaba: 	{
dcdd144598 2011-02-23        kinaba: 		while( siz-- )
dcdd144598 2011-02-23        kinaba: 		{
dcdd144598 2011-02-23        kinaba: 			unicode c = *buf++;
dcdd144598 2011-02-23        kinaba: 			qbyte  cc = c;
dcdd144598 2011-02-23        kinaba: 			if( (0xD800<=c && c<=0xDBFF) && siz>0 ) // trail char が正しいかどうかはチェックする気がない
dcdd144598 2011-02-23        kinaba: 			{
dcdd144598 2011-02-23        kinaba: 				unicode c2 = *buf++; siz--;
dcdd144598 2011-02-23        kinaba: 				cc = 0x10000 + (((c-0xD800)&0x3ff)<<10) + ((c2-0xDC00)&0x3ff);
dcdd144598 2011-02-23        kinaba: 			}
dcdd144598 2011-02-23        kinaba: 			for(int i=3; i>=0; --i)
dcdd144598 2011-02-23        kinaba: 				fp_.WriteC( (uchar)(cc>>(8*i)) );
dcdd144598 2011-02-23        kinaba: 		}
dcdd144598 2011-02-23        kinaba: 	}
dcdd144598 2011-02-23        kinaba: };
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: struct wWest : public TextFileWPimpl
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	wWest( FileW& w ) : TextFileWPimpl(w) {}
dcdd144598 2011-02-23        kinaba: 	void WriteChar( unicode ch ) { fp_.WriteC(ch>0xff ? '?' : (uchar)ch); }
dcdd144598 2011-02-23        kinaba: };
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: struct wUtf5 : public TextFileWPimpl
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	wUtf5( FileW& w ) : TextFileWPimpl(w) {}
dcdd144598 2011-02-23        kinaba: 	void WriteChar( unicode ch )
dcdd144598 2011-02-23        kinaba: 	{
dcdd144598 2011-02-23        kinaba: 		static const char conv[] = {
dcdd144598 2011-02-23        kinaba: 			'0','1','2','3','4','5','6','7',
dcdd144598 2011-02-23        kinaba: 				'8','9','A','B','C','D','E','F' };
dcdd144598 2011-02-23        kinaba: 		if(ch<0x10)
dcdd144598 2011-02-23        kinaba: 		{
dcdd144598 2011-02-23        kinaba: 			fp_.WriteC(ch+'G');
dcdd144598 2011-02-23        kinaba: 		}
dcdd144598 2011-02-23        kinaba: 		else if(ch<0x100)
dcdd144598 2011-02-23        kinaba: 		{
dcdd144598 2011-02-23        kinaba: 			fp_.WriteC((ch>>4)+'G');
dcdd144598 2011-02-23        kinaba: 			fp_.WriteC(conv[ch&0xf]);
dcdd144598 2011-02-23        kinaba: 		}
dcdd144598 2011-02-23        kinaba: 		else if(ch<0x1000)
dcdd144598 2011-02-23        kinaba: 		{
dcdd144598 2011-02-23        kinaba: 			fp_.WriteC((ch>>8)+'G');
dcdd144598 2011-02-23        kinaba: 			fp_.WriteC(conv[(ch>>4)&0xf]);
dcdd144598 2011-02-23        kinaba: 			fp_.WriteC(conv[ch&0xf]);
dcdd144598 2011-02-23        kinaba: 		}
dcdd144598 2011-02-23        kinaba: 		else
dcdd144598 2011-02-23        kinaba: 		{
dcdd144598 2011-02-23        kinaba: 			fp_.WriteC((ch>>12)+'G');
dcdd144598 2011-02-23        kinaba: 			fp_.WriteC(conv[(ch>>8)&0xf]);
dcdd144598 2011-02-23        kinaba: 			fp_.WriteC(conv[(ch>>4)&0xf]);
dcdd144598 2011-02-23        kinaba: 			fp_.WriteC(conv[ch&0xf]);
dcdd144598 2011-02-23        kinaba: 		}
dcdd144598 2011-02-23        kinaba: 	}
dcdd144598 2011-02-23        kinaba: };
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: //-------------------------------------------------------------------------
dcdd144598 2011-02-23        kinaba: // Win95対策の自前UTF8/UTF7処理
dcdd144598 2011-02-23        kinaba: //-------------------------------------------------------------------------
dcdd144598 2011-02-23        kinaba: #ifndef _UNICODE
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: struct wUTF8 : public TextFileWPimpl
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	wUTF8( FileW& w, int cp )
dcdd144598 2011-02-23        kinaba: 		: TextFileWPimpl(w)
dcdd144598 2011-02-23        kinaba: 	{
dcdd144598 2011-02-23        kinaba: 		if( cp == UTF8 ) // BOM書き込み
dcdd144598 2011-02-23        kinaba: 			fp_.Write( "\xEF\xBB\xBF", 3 );
dcdd144598 2011-02-23        kinaba: 	}
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	void WriteLine( const unicode* str, ulong len )
dcdd144598 2011-02-23        kinaba: 	{
dcdd144598 2011-02-23        kinaba: 		//        0000-0000-0xxx-xxxx | 0xxxxxxx
dcdd144598 2011-02-23        kinaba: 		//        0000-0xxx-xxyy-yyyy | 110xxxxx 10yyyyyy
dcdd144598 2011-02-23        kinaba: 		//        xxxx-yyyy-yyzz-zzzz | 1110xxxx 10yyyyyy 10zzzzzz
dcdd144598 2011-02-23        kinaba: 		// x-xxyy-yyyy-zzzz-zzww-wwww | 11110xxx 10yyyyyy 10zzzzzz 10wwwwww
dcdd144598 2011-02-23        kinaba: 		// ...
dcdd144598 2011-02-23        kinaba: 		while( len-- )
dcdd144598 2011-02-23        kinaba: 		{
dcdd144598 2011-02-23        kinaba: 			qbyte ch = *str;
dcdd144598 2011-02-23        kinaba: 			if( (0xD800<=ch&&ch<=0xDBFF) && len )
dcdd144598 2011-02-23        kinaba: 				ch = 0x10000 + (((ch-0xD800)&0x3ff)<<10) + ((*++str-0xDC00)&0x3ff), len--;
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 			if( ch <= 0x7f )
dcdd144598 2011-02-23        kinaba: 				fp_.WriteC( static_cast<uchar>(ch) );
dcdd144598 2011-02-23        kinaba: 			else if( ch <= 0x7ff )
dcdd144598 2011-02-23        kinaba: 				fp_.WriteC( 0xc0 | static_cast<uchar>(ch>>6) ),
dcdd144598 2011-02-23        kinaba: 				fp_.WriteC( 0x80 | static_cast<uchar>(ch&0x3f) );
dcdd144598 2011-02-23        kinaba: 			else if( ch<= 0xffff )
dcdd144598 2011-02-23        kinaba: 				fp_.WriteC( 0xe0 | static_cast<uchar>(ch>>12) ),
dcdd144598 2011-02-23        kinaba: 				fp_.WriteC( 0x80 | static_cast<uchar>((ch>>6)&0x3f) ),
dcdd144598 2011-02-23        kinaba: 				fp_.WriteC( 0x80 | static_cast<uchar>(ch&0x3f) );
dcdd144598 2011-02-23        kinaba: 			else if( ch<= 0x1fffff )
dcdd144598 2011-02-23        kinaba: 				fp_.WriteC( 0xf0 | static_cast<uchar>(ch>>18) ),
dcdd144598 2011-02-23        kinaba: 				fp_.WriteC( 0x80 | static_cast<uchar>((ch>>12)&0x3f) ),
dcdd144598 2011-02-23        kinaba: 				fp_.WriteC( 0x80 | static_cast<uchar>((ch>>6)&0x3f) ),
dcdd144598 2011-02-23        kinaba: 				fp_.WriteC( 0x80 | static_cast<uchar>(ch&0x3f) );
dcdd144598 2011-02-23        kinaba: 			else if( ch<= 0x3ffffff )
dcdd144598 2011-02-23        kinaba: 				fp_.WriteC( 0xf8 | static_cast<uchar>(ch>>24) ),
dcdd144598 2011-02-23        kinaba: 				fp_.WriteC( 0x80 | static_cast<uchar>((ch>>18)&0x3f) ),
dcdd144598 2011-02-23        kinaba: 				fp_.WriteC( 0x80 | static_cast<uchar>((ch>>12)&0x3f) ),
dcdd144598 2011-02-23        kinaba: 				fp_.WriteC( 0x80 | static_cast<uchar>((ch>>6)&0x3f) ),
dcdd144598 2011-02-23        kinaba: 				fp_.WriteC( 0x80 | static_cast<uchar>(ch&0x3f) );
dcdd144598 2011-02-23        kinaba: 			else
dcdd144598 2011-02-23        kinaba: 				fp_.WriteC( 0xfc | static_cast<uchar>(ch>>30) ),
dcdd144598 2011-02-23        kinaba: 				fp_.WriteC( 0x80 | static_cast<uchar>((ch>>24)&0x3f) ),
dcdd144598 2011-02-23        kinaba: 				fp_.WriteC( 0x80 | static_cast<uchar>((ch>>18)&0x3f) ),
dcdd144598 2011-02-23        kinaba: 				fp_.WriteC( 0x80 | static_cast<uchar>((ch>>12)&0x3f) ),
dcdd144598 2011-02-23        kinaba: 				fp_.WriteC( 0x80 | static_cast<uchar>((ch>>6)&0x3f) ),
dcdd144598 2011-02-23        kinaba: 				fp_.WriteC( 0x80 | static_cast<uchar>(ch&0x3f) );
dcdd144598 2011-02-23        kinaba: 			++str;
dcdd144598 2011-02-23        kinaba: 		}
dcdd144598 2011-02-23        kinaba: 	}
dcdd144598 2011-02-23        kinaba: };
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: struct wUTF7 : public TextFileWPimpl
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	wUTF7( FileW& w ) : TextFileWPimpl(w) {}
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	void WriteLine( const unicode* str, ulong len )
dcdd144598 2011-02-23        kinaba: 	{
dcdd144598 2011-02-23        kinaba: 		static const uchar mime[64] = {
dcdd144598 2011-02-23        kinaba: 		'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P',
dcdd144598 2011-02-23        kinaba: 		'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f',
dcdd144598 2011-02-23        kinaba: 		'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v',
dcdd144598 2011-02-23        kinaba: 		'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/'};
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 		// XxxxxxYyyyyyZzzz | zzWwwwwwUuuuuuVv | vvvvTtttttSsssss
dcdd144598 2011-02-23        kinaba: 		bool mode_m = false;
dcdd144598 2011-02-23        kinaba: 		while( len )
dcdd144598 2011-02-23        kinaba: 		{
dcdd144598 2011-02-23        kinaba: 			if( *str <= 0x7f )
dcdd144598 2011-02-23        kinaba: 			{
dcdd144598 2011-02-23        kinaba: 				fp_.WriteC( static_cast<uchar>(*str) );
dcdd144598 2011-02-23        kinaba: 				if( *str == L'+' )
dcdd144598 2011-02-23        kinaba: 					fp_.WriteC( '-' );
dcdd144598 2011-02-23        kinaba: 				++str, --len;
dcdd144598 2011-02-23        kinaba: 			}
dcdd144598 2011-02-23        kinaba: 			else
dcdd144598 2011-02-23        kinaba: 			{
dcdd144598 2011-02-23        kinaba: 				if(!mode_m) fp_.WriteC( '+' ), mode_m=true;
dcdd144598 2011-02-23        kinaba: 				unicode tx[3] = {0,0,0};
dcdd144598 2011-02-23        kinaba: 				int n=0;
dcdd144598 2011-02-23        kinaba: 				tx[0] = *str, ++str, --len, ++n;
dcdd144598 2011-02-23        kinaba: 				if( len && *str>0x7f )
dcdd144598 2011-02-23        kinaba: 				{
dcdd144598 2011-02-23        kinaba: 					tx[1] = *str, ++str, --len, ++n;
dcdd144598 2011-02-23        kinaba: 					if( len && *str>0x7f )
dcdd144598 2011-02-23        kinaba: 						tx[2] = *str, ++str, --len, ++n;
dcdd144598 2011-02-23        kinaba: 				}
dcdd144598 2011-02-23        kinaba: 				{
dcdd144598 2011-02-23        kinaba: 					fp_.WriteC( mime[ tx[0]>>10 ] );
dcdd144598 2011-02-23        kinaba: 					fp_.WriteC( mime[ (tx[0]>>4)&0x3f ] );
dcdd144598 2011-02-23        kinaba: 					fp_.WriteC( mime[ (tx[0]<<2|tx[1]>>14)&0x3f ] );
dcdd144598 2011-02-23        kinaba: 					if( n>=2 )
dcdd144598 2011-02-23        kinaba: 					{
dcdd144598 2011-02-23        kinaba: 						fp_.WriteC( mime[ (tx[1]>>8)&0x3f ] );
dcdd144598 2011-02-23        kinaba: 						fp_.WriteC( mime[ (tx[1]>>2)&0x3f ] );
dcdd144598 2011-02-23        kinaba: 						fp_.WriteC( mime[ (tx[1]<<4|tx[2]>>12)&0x3f ] );
dcdd144598 2011-02-23        kinaba: 						if( n>=3 )
dcdd144598 2011-02-23        kinaba: 						{
dcdd144598 2011-02-23        kinaba: 							fp_.WriteC( mime[ (tx[2]>>6)&0x3f ] );
dcdd144598 2011-02-23        kinaba: 							fp_.WriteC( mime[ tx[2]&0x3f ] );
dcdd144598 2011-02-23        kinaba: 						}
dcdd144598 2011-02-23        kinaba: 					}
dcdd144598 2011-02-23        kinaba: 				}
dcdd144598 2011-02-23        kinaba: 				if( len && *str<=0x7f )
dcdd144598 2011-02-23        kinaba: 					fp_.WriteC( '-' ), mode_m = false;
dcdd144598 2011-02-23        kinaba: 			}
dcdd144598 2011-02-23        kinaba: 		}
dcdd144598 2011-02-23        kinaba: 	}
dcdd144598 2011-02-23        kinaba: };
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: #endif
dcdd144598 2011-02-23        kinaba: //-------------------------------------------------------------------------
dcdd144598 2011-02-23        kinaba: // Windows頼りの変換
dcdd144598 2011-02-23        kinaba: //-------------------------------------------------------------------------
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: struct wMBCS : public TextFileWPimpl
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	wMBCS( FileW& w, int cp )
dcdd144598 2011-02-23        kinaba: 		: TextFileWPimpl(w), cp_(cp)
dcdd144598 2011-02-23        kinaba: 	{
dcdd144598 2011-02-23        kinaba: 		if( cp == UTF8 )
dcdd144598 2011-02-23        kinaba: 		{
dcdd144598 2011-02-23        kinaba: 			// BOM書き込み
dcdd144598 2011-02-23        kinaba: 			cp_ = UTF8N;
dcdd144598 2011-02-23        kinaba: 			fp_.Write( "\xEF\xBB\xBF", 3 );
dcdd144598 2011-02-23        kinaba: 		}
dcdd144598 2011-02-23        kinaba: 	}
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	void WriteLine( const unicode* str, ulong len )
dcdd144598 2011-02-23        kinaba: 	{
dcdd144598 2011-02-23        kinaba: 		// WideCharToMultiByte API を利用した変換
dcdd144598 2011-02-23        kinaba: 		int r;
dcdd144598 2011-02-23        kinaba: 		while(
dcdd144598 2011-02-23        kinaba: 			0==(r=::WideCharToMultiByte(cp_,0,str,len,buf_,bsiz_,NULL,NULL))
dcdd144598 2011-02-23        kinaba: 		 && ::GetLastError()==ERROR_INSUFFICIENT_BUFFER )
dcdd144598 2011-02-23        kinaba: 			ReserveMoreBuffer();
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 		// ファイルへ書き込み
dcdd144598 2011-02-23        kinaba: 		fp_.Write( buf_, r );
dcdd144598 2011-02-23        kinaba: 	}
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	int cp_;
dcdd144598 2011-02-23        kinaba: };
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: //-------------------------------------------------------------------------
dcdd144598 2011-02-23        kinaba: // ISO-2022 サブセットその1。
dcdd144598 2011-02-23        kinaba: // ASCIIともう一つしか文字集合を使わないもの
dcdd144598 2011-02-23        kinaba: //-------------------------------------------------------------------------
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: struct wIso2022 : public TextFileWPimpl
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	wIso2022( FileW& w, int cp )
dcdd144598 2011-02-23        kinaba: 		: TextFileWPimpl(w), hz_(cp==HZ)
dcdd144598 2011-02-23        kinaba: 	{
dcdd144598 2011-02-23        kinaba: 		switch( cp )
dcdd144598 2011-02-23        kinaba: 		{
dcdd144598 2011-02-23        kinaba: 		case IsoKR:
dcdd144598 2011-02-23        kinaba: 			fp_.Write( "\x1B\x24\x29\x43", 4 );
dcdd144598 2011-02-23        kinaba: 			cp_ = UHC;
dcdd144598 2011-02-23        kinaba: 			break;
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 		case IsoCN:
dcdd144598 2011-02-23        kinaba: 			fp_.Write( "\x1B\x24\x29\x41", 4 );
dcdd144598 2011-02-23        kinaba: 			// fall through...
dcdd144598 2011-02-23        kinaba: 		default:
dcdd144598 2011-02-23        kinaba: 			cp_ = GBK;
dcdd144598 2011-02-23        kinaba: 			break;
dcdd144598 2011-02-23        kinaba: 		}
dcdd144598 2011-02-23        kinaba: 	}
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	void WriteLine( const unicode* str, ulong len )
dcdd144598 2011-02-23        kinaba: 	{
dcdd144598 2011-02-23        kinaba: 		// まず WideCharToMultiByte API を利用して変換
dcdd144598 2011-02-23        kinaba: 		int r;
dcdd144598 2011-02-23        kinaba: 		while(
dcdd144598 2011-02-23        kinaba: 			0==(r=::WideCharToMultiByte(cp_,0,str,len,buf_,bsiz_,NULL,NULL))
dcdd144598 2011-02-23        kinaba: 		 && ::GetLastError()==ERROR_INSUFFICIENT_BUFFER )
dcdd144598 2011-02-23        kinaba: 			ReserveMoreBuffer();
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 		bool ascii = true;
dcdd144598 2011-02-23        kinaba: 		for( int i=0; i<r; ++i )
dcdd144598 2011-02-23        kinaba: 			if( buf_[i] & 0x80 )
dcdd144598 2011-02-23        kinaba: 			{
dcdd144598 2011-02-23        kinaba: 				// 非ASCII部分は最上位ビットを落としてから出力
dcdd144598 2011-02-23        kinaba: 				if( ascii )
dcdd144598 2011-02-23        kinaba: 				{
dcdd144598 2011-02-23        kinaba: 					if( hz_ )
dcdd144598 2011-02-23        kinaba: 						fp_.WriteC( 0x7E ), fp_.WriteC( 0x7B );
dcdd144598 2011-02-23        kinaba: 					else
dcdd144598 2011-02-23        kinaba: 						fp_.WriteC( 0x0E );
dcdd144598 2011-02-23        kinaba: 					ascii = false;
dcdd144598 2011-02-23        kinaba: 				}
dcdd144598 2011-02-23        kinaba: 				fp_.WriteC( buf_[i++] & 0x7F );
dcdd144598 2011-02-23        kinaba: 				fp_.WriteC( buf_[i]   & 0x7F );
dcdd144598 2011-02-23        kinaba: 			}
dcdd144598 2011-02-23        kinaba: 			else
dcdd144598 2011-02-23        kinaba: 			{
dcdd144598 2011-02-23        kinaba: 				// ASCII部分はそのまま出力
dcdd144598 2011-02-23        kinaba: 				if( !ascii )
dcdd144598 2011-02-23        kinaba: 				{
dcdd144598 2011-02-23        kinaba: 					if( hz_ )
dcdd144598 2011-02-23        kinaba: 						fp_.WriteC( 0x7E ), fp_.WriteC( 0x7D );
dcdd144598 2011-02-23        kinaba: 					else
dcdd144598 2011-02-23        kinaba: 						fp_.WriteC( 0x0F );
dcdd144598 2011-02-23        kinaba: 					ascii = true;
dcdd144598 2011-02-23        kinaba: 				}
dcdd144598 2011-02-23        kinaba: 				fp_.WriteC( buf_[i] );
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 				// ただしHZの場合、0x7E は 0x7E 0x7E と表す
dcdd144598 2011-02-23        kinaba: 				if( hz_ && buf_[i]==0x7E )
dcdd144598 2011-02-23        kinaba: 					fp_.WriteC( 0x7E );
dcdd144598 2011-02-23        kinaba: 			}
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 		// 最後は確実にASCIIに戻す
dcdd144598 2011-02-23        kinaba: 		if( !ascii )
dcdd144598 2011-02-23        kinaba: 			if( hz_ )
dcdd144598 2011-02-23        kinaba: 				fp_.WriteC( 0x7E ), fp_.WriteC( 0x7D );
dcdd144598 2011-02-23        kinaba: 			else
dcdd144598 2011-02-23        kinaba: 				fp_.WriteC( 0x0F );
dcdd144598 2011-02-23        kinaba: 	}
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	int  cp_;
dcdd144598 2011-02-23        kinaba: 	bool hz_;
dcdd144598 2011-02-23        kinaba: };
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: //-------------------------------------------------------------------------
dcdd144598 2011-02-23        kinaba: // ISO-2022 サブセットその2。日本語EUC
dcdd144598 2011-02-23        kinaba: //-------------------------------------------------------------------------
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: // Helper: SJIS ==> JIS X 0208
dcdd144598 2011-02-23        kinaba: static void sjis2jis( uchar s1, uchar s2, char* k )
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	if( ((s1==0xfa || s1==0xfb) && s2>=0x40) || (s1==0xfc && (s2&0xf0)==0x40) )
dcdd144598 2011-02-23        kinaba: 	{
dcdd144598 2011-02-23        kinaba: 		// IBM外字のマッピング
dcdd144598 2011-02-23        kinaba: static const WORD IBM_sjis2kuten[] = {
dcdd144598 2011-02-23        kinaba: /*fa40*/0x5c51,0x5c52,0x5c53,0x5c54,0x5c55,0x5c56,0x5c57,0x5c58,0x5c59,0x5c5a,0x0d15,0x0d16,0x0d17,0x0d18,0x0d19,0x0d1a,
dcdd144598 2011-02-23        kinaba: /*fa50*/0x0d1b,0x0d1c,0x0d1d,0x0d1e,0x022c,0x5c5c,0x5c5d,0x5c5e,0x0d4a,0x0d42,0x0d44,0x0248,0x5901,0x5902,0x5903,0x5904,
dcdd144598 2011-02-23        kinaba: /*fa60*/0x5905,0x5906,0x5907,0x5908,0x5909,0x590a,0x590b,0x590c,0x590d,0x590e,0x590f,0x5910,0x5911,0x5912,0x5913,0x5914,
dcdd144598 2011-02-23        kinaba: /*fa70*/0x5915,0x5916,0x5917,0x5918,0x5919,0x591a,0x591b,0x591c,0x591d,0x591e,0x591f,0x5920,0x5921,0x5922,0x5923,/**/0x0109,
dcdd144598 2011-02-23        kinaba: /*fa80*/0x5924,0x5925,0x5926,0x5927,0x5928,0x5929,0x592a,0x592b,0x592c,0x592d,0x592e,0x592f,0x5930,0x5931,0x5932,0x5933,
dcdd144598 2011-02-23        kinaba: /*fa90*/0x5934,0x5935,0x5936,0x5937,0x5938,0x5939,0x593a,0x593b,0x593c,0x593d,0x593e,0x593f,0x5940,0x5941,0x5942,0x5943,
dcdd144598 2011-02-23        kinaba: /*faa0*/0x5944,0x5945,0x5946,0x5947,0x5948,0x5949,0x594a,0x594b,0x594c,0x594d,0x594e,0x594f,0x5950,0x5951,0x5952,0x5953,
dcdd144598 2011-02-23        kinaba: /*fab0*/0x5954,0x5955,0x5956,0x5957,0x5958,0x5959,0x595a,0x595b,0x595c,0x595d,0x595e,0x5a01,0x5a02,0x5a03,0x5a04,0x5a05,
dcdd144598 2011-02-23        kinaba: /*fac0*/0x5a06,0x5a07,0x5a08,0x5a09,0x5a0a,0x5a0b,0x5a0c,0x5a0d,0x5a0e,0x5a0f,0x5a10,0x5a11,0x5a12,0x5a13,0x5a14,0x5a15,
dcdd144598 2011-02-23        kinaba: /*fad0*/0x5a16,0x5a17,0x5a18,0x5a19,0x5a1a,0x5a1b,0x5a1c,0x5a1d,0x5a1e,0x5a1f,0x5a20,0x5a21,0x5a22,0x5a23,0x5a24,0x5a25,
dcdd144598 2011-02-23        kinaba: /*fae0*/0x5a26,0x5a27,0x5a28,0x5a29,0x5a2a,0x5a2b,0x5a2c,0x5a2d,0x5a2e,0x5a2f,0x5a30,0x5a31,0x5a32,0x5a33,0x5a34,0x5a35,
dcdd144598 2011-02-23        kinaba: /*faf0*/0x5a36,0x5a37,0x5a38,0x5a39,0x5a3a,0x5a3b,0x5a3c,0x5a3d,0x5a3e,0x5a3f,0x5a40,0x5a41,0x5a42,/**/0x0109,0x0109,0x0109,
dcdd144598 2011-02-23        kinaba: /*fb40*/0x5a43,0x5a44,0x5a45,0x5a46,0x5a47,0x5a48,0x5a49,0x5a4a,0x5a4b,0x5a4c,0x5a4d,0x5a4e,0x5a4f,0x5a50,0x5a51,0x5a52,
dcdd144598 2011-02-23        kinaba: /*fb50*/0x5a53,0x5a54,0x5a55,0x5a56,0x5a57,0x5a58,0x5a59,0x5a5a,0x5a5b,0x5a5c,0x5a5d,0x5a5e,0x5b01,0x5b02,0x5b03,0x5b04,
dcdd144598 2011-02-23        kinaba: /*fb60*/0x5b05,0x5b06,0x5b07,0x5b08,0x5b09,0x5b0a,0x5b0b,0x5b0c,0x5b0d,0x5b0e,0x5b0f,0x5b10,0x5b11,0x5b12,0x5b13,0x5b14,
dcdd144598 2011-02-23        kinaba: /*fb70*/0x5b15,0x5b16,0x5b17,0x5b18,0x5b19,0x5b1a,0x5b1b,0x5b1c,0x5b1d,0x5b1e,0x5b1f,0x5b20,0x5b21,0x5b22,0x5b23,/**/0x0109,
dcdd144598 2011-02-23        kinaba: /*fb80*/0x5b24,0x5b25,0x5b26,0x5b27,0x5b28,0x5b29,0x5b2a,0x5b2b,0x5b2c,0x5b2d,0x5b2e,0x5b2f,0x5b30,0x5b31,0x5b32,0x5b33,
dcdd144598 2011-02-23        kinaba: /*fb90*/0x5b34,0x5b35,0x5b36,0x5b37,0x5b38,0x5b39,0x5b3a,0x5b3b,0x5b3c,0x5b3d,0x5b3e,0x5b3f,0x5b40,0x5b41,0x5b42,0x5b43,
dcdd144598 2011-02-23        kinaba: /*fba0*/0x5b44,0x5b45,0x5b46,0x5b47,0x5b48,0x5b49,0x5b4a,0x5b4b,0x5b4c,0x5b4d,0x5b4e,0x5b4f,0x5b50,0x5b51,0x5b52,0x5b53,
dcdd144598 2011-02-23        kinaba: /*fbb0*/0x5b54,0x5b55,0x5b56,0x5b57,0x5b58,0x5b59,0x5b5a,0x5b5b,0x5b5c,0x5b5d,0x5b5e,0x5c01,0x5c02,0x5c03,0x5c04,0x5c05,
dcdd144598 2011-02-23        kinaba: /*fbc0*/0x5c06,0x5c07,0x5c08,0x5c09,0x5c0a,0x5c0b,0x5c0c,0x5c0d,0x5c0e,0x5c0f,0x5c10,0x5c11,0x5c12,0x5c13,0x5c14,0x5c15,
dcdd144598 2011-02-23        kinaba: /*fbd0*/0x5c16,0x5c17,0x5c18,0x5c19,0x5c1a,0x5c1b,0x5c1c,0x5c1d,0x5c1e,0x5c1f,0x5c20,0x5c21,0x5c22,0x5c23,0x5c24,0x5c25,
dcdd144598 2011-02-23        kinaba: /*fbe0*/0x5c26,0x5c27,0x5c28,0x5c29,0x5c2a,0x5c2b,0x5c2c,0x5c2d,0x5c2e,0x5c2f,0x5c30,0x5c31,0x5c32,0x5c33,0x5c34,0x5c35,
dcdd144598 2011-02-23        kinaba: /*fbf0*/0x5c36,0x5c37,0x5c38,0x5c39,0x5c3a,0x5c3b,0x5c3c,0x5c3d,0x5c3e,0x5c3f,0x5c40,0x5c41,0x5c42,/**/0x0109,0x0109,0x0109,
dcdd144598 2011-02-23        kinaba: /*fc40*/0x5c43,0x5c44,0x5c45,0x5c46,0x5c47,0x5c48,0x5c49,0x5c4a,0x5c4b,0x5c4c,0x5c4d,0x5c4e,/**/0x0109,0x0109,0x0109,0x0109,
dcdd144598 2011-02-23        kinaba: };
dcdd144598 2011-02-23        kinaba: 		k[0] = IBM_sjis2kuten[ (s1-0xfa)*12*16 + (s2-0x40) ]>>8;
dcdd144598 2011-02-23        kinaba: 		k[1] = IBM_sjis2kuten[ (s1-0xfa)*12*16 + (s2-0x40) ]&0xff;
dcdd144598 2011-02-23        kinaba: 	}
dcdd144598 2011-02-23        kinaba: 	else
dcdd144598 2011-02-23        kinaba: 	{
dcdd144598 2011-02-23        kinaba: 		// その他
dcdd144598 2011-02-23        kinaba: 		if( s2>=0x9f )
dcdd144598 2011-02-23        kinaba: 		{
dcdd144598 2011-02-23        kinaba: 			if( s1>=0xe0 ) k[0] = ((s1-0xc0)<<1);
dcdd144598 2011-02-23        kinaba: 			else           k[0] = ((s1-0x80)<<1);
dcdd144598 2011-02-23        kinaba: 			k[1] = s2-0x9e;
dcdd144598 2011-02-23        kinaba: 		}
dcdd144598 2011-02-23        kinaba: 		else
dcdd144598 2011-02-23        kinaba: 		{
dcdd144598 2011-02-23        kinaba: 			if( s1>=0xe0 ) k[0] = ((s1-0xc0)<<1)-1;
dcdd144598 2011-02-23        kinaba: 			else           k[0] = ((s1-0x80)<<1)-1;
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 			if( s2 & 0x80 )	k[1] = s2-0x40;
dcdd144598 2011-02-23        kinaba: 			else			k[1] = s2-0x3f;
dcdd144598 2011-02-23        kinaba: 		}
dcdd144598 2011-02-23        kinaba: 	}
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	k[0] += 0x20;
dcdd144598 2011-02-23        kinaba: 	k[1] += 0x20;
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: struct wEucJp : public TextFileWPimpl
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	wEucJp( FileW& w )
dcdd144598 2011-02-23        kinaba: 		: TextFileWPimpl(w) {}
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	void WriteLine( const unicode* str, ulong len )
dcdd144598 2011-02-23        kinaba: 	{
dcdd144598 2011-02-23        kinaba: 		// まず WideCharToMultiByte API を利用して変換
dcdd144598 2011-02-23        kinaba: 		int r;
dcdd144598 2011-02-23        kinaba: 		while(
dcdd144598 2011-02-23        kinaba: 			0==(r=::WideCharToMultiByte(932,0,str,len,buf_,bsiz_,NULL,NULL))
dcdd144598 2011-02-23        kinaba: 		 && ::GetLastError()==ERROR_INSUFFICIENT_BUFFER )
dcdd144598 2011-02-23        kinaba: 			ReserveMoreBuffer();
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 		for( int i=0; i<r; ++i )
dcdd144598 2011-02-23        kinaba: 			if( buf_[i] & 0x80 )
dcdd144598 2011-02-23        kinaba: 			{
dcdd144598 2011-02-23        kinaba: 				if( 0xA1<=(uchar)buf_[i] && (uchar)buf_[i]<=0xDF )
dcdd144598 2011-02-23        kinaba: 				{
dcdd144598 2011-02-23        kinaba: 					// カナ
dcdd144598 2011-02-23        kinaba: 					fp_.WriteC( 0x8E );
dcdd144598 2011-02-23        kinaba: 					fp_.WriteC( buf_[i] );
dcdd144598 2011-02-23        kinaba: 				}
dcdd144598 2011-02-23        kinaba: 				else
dcdd144598 2011-02-23        kinaba: 				{
dcdd144598 2011-02-23        kinaba: 					// JIS X 0208
dcdd144598 2011-02-23        kinaba: 					sjis2jis( buf_[i], buf_[i+1], buf_+i );
dcdd144598 2011-02-23        kinaba: 					fp_.WriteC( buf_[i++] | 0x80 );
dcdd144598 2011-02-23        kinaba: 					fp_.WriteC( buf_[i]   | 0x80 );
dcdd144598 2011-02-23        kinaba: 				}
dcdd144598 2011-02-23        kinaba: 			}
dcdd144598 2011-02-23        kinaba: 			else
dcdd144598 2011-02-23        kinaba: 			{
dcdd144598 2011-02-23        kinaba: 				// ASCII部分はそのまま出力
dcdd144598 2011-02-23        kinaba: 				fp_.WriteC( buf_[i] );
dcdd144598 2011-02-23        kinaba: 			}
dcdd144598 2011-02-23        kinaba: 	}
dcdd144598 2011-02-23        kinaba: };
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: //-------------------------------------------------------------------------
dcdd144598 2011-02-23        kinaba: // ISO-2022 サブセットその3。ISO-2022-JP
dcdd144598 2011-02-23        kinaba: //-------------------------------------------------------------------------
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: struct wIsoJp : public TextFileWPimpl
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	wIsoJp( FileW& w )
dcdd144598 2011-02-23        kinaba: 		: TextFileWPimpl(w)
dcdd144598 2011-02-23        kinaba: 	{
dcdd144598 2011-02-23        kinaba: 		fp_.Write( "\x1b\x28\x42", 3 );
dcdd144598 2011-02-23        kinaba: 	}
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	void WriteLine( const unicode* str, ulong len )
dcdd144598 2011-02-23        kinaba: 	{
dcdd144598 2011-02-23        kinaba: 		// まず WideCharToMultiByte API を利用して変換
dcdd144598 2011-02-23        kinaba: 		int r;
dcdd144598 2011-02-23        kinaba: 		while(
dcdd144598 2011-02-23        kinaba: 			0==(r=::WideCharToMultiByte(932,0,str,len,buf_,bsiz_,NULL,NULL))
dcdd144598 2011-02-23        kinaba: 		 && ::GetLastError()==ERROR_INSUFFICIENT_BUFFER )
dcdd144598 2011-02-23        kinaba: 			ReserveMoreBuffer();
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 		enum { ROMA, KANJI, KANA } state = ROMA;
dcdd144598 2011-02-23        kinaba: 		for( int i=0; i<r; ++i )
dcdd144598 2011-02-23        kinaba: 			if( buf_[i] & 0x80 )
dcdd144598 2011-02-23        kinaba: 			{
dcdd144598 2011-02-23        kinaba: 				if( 0xA1<=(uchar)buf_[i] && (uchar)buf_[i]<=0xDF )
dcdd144598 2011-02-23        kinaba: 				{
dcdd144598 2011-02-23        kinaba: 					// カナ
dcdd144598 2011-02-23        kinaba: 					if( state != KANA )
dcdd144598 2011-02-23        kinaba: 						fp_.Write( "\x1b\x28\x49", 3 ), state = KANA;
dcdd144598 2011-02-23        kinaba: 					fp_.WriteC( buf_[i] & 0x7f );
dcdd144598 2011-02-23        kinaba: 				}
dcdd144598 2011-02-23        kinaba: 				else
dcdd144598 2011-02-23        kinaba: 				{
dcdd144598 2011-02-23        kinaba: 					// JIS X 0208
dcdd144598 2011-02-23        kinaba: 					if( state != KANJI )
dcdd144598 2011-02-23        kinaba: 						fp_.Write( "\x1b\x24\x42", 3 ), state = KANJI;
dcdd144598 2011-02-23        kinaba: 					sjis2jis( buf_[i], buf_[i+1], buf_+i );
dcdd144598 2011-02-23        kinaba: 					fp_.WriteC( buf_[i++] );
dcdd144598 2011-02-23        kinaba: 					fp_.WriteC( buf_[i]   );
dcdd144598 2011-02-23        kinaba: 				}
dcdd144598 2011-02-23        kinaba: 			}
dcdd144598 2011-02-23        kinaba: 			else
dcdd144598 2011-02-23        kinaba: 			{
dcdd144598 2011-02-23        kinaba: 				// ASCII部分はそのまま出力
dcdd144598 2011-02-23        kinaba: 				if( state != ROMA )
dcdd144598 2011-02-23        kinaba: 					fp_.Write( "\x1b\x28\x42", 3 ), state = ROMA;
dcdd144598 2011-02-23        kinaba: 				fp_.WriteC( buf_[i] );
dcdd144598 2011-02-23        kinaba: 			}
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 		if( state != ROMA )
dcdd144598 2011-02-23        kinaba: 			fp_.Write( "\x1b\x28\x42", 3 ), state = ROMA;
dcdd144598 2011-02-23        kinaba: 	}
dcdd144598 2011-02-23        kinaba: };
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: //-------------------------------------------------------------------------
dcdd144598 2011-02-23        kinaba: // 書き込みルーチンの準備等々
dcdd144598 2011-02-23        kinaba: //-------------------------------------------------------------------------
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: TextFileW::TextFileW( int charset, int linebreak )
dcdd144598 2011-02-23        kinaba: 	: cs_( charset ), lb_(linebreak)
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: TextFileW::~TextFileW()
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	Close();
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: void TextFileW::Close()
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	impl_ = NULL;
dcdd144598 2011-02-23        kinaba: 	fp_.Close();
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: void TextFileW::WriteLine( const unicode* buf, ulong siz, bool lastline )
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	impl_->WriteLine( buf, siz );
dcdd144598 2011-02-23        kinaba: 	if( !lastline )
dcdd144598 2011-02-23        kinaba: 	{
dcdd144598 2011-02-23        kinaba: 		static const ulong lbLst[] = {0x0D, 0x0A, 0x000A000D};
dcdd144598 2011-02-23        kinaba: 		static const ulong lbLen[] = {   1,    1,          2};
dcdd144598 2011-02-23        kinaba: 		impl_->WriteLB(
dcdd144598 2011-02-23        kinaba: 			reinterpret_cast<const unicode*>(&lbLst[lb_]), lbLen[lb_] );
dcdd144598 2011-02-23        kinaba: 	}
dcdd144598 2011-02-23        kinaba: }
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: bool TextFileW::Open( const TCHAR* fname )
dcdd144598 2011-02-23        kinaba: {
dcdd144598 2011-02-23        kinaba: 	if( !fp_.Open( fname, true ) )
dcdd144598 2011-02-23        kinaba: 		return false;
dcdd144598 2011-02-23        kinaba: 
dcdd144598 2011-02-23        kinaba: 	switch( cs_ )
dcdd144598 2011-02-23        kinaba: 	{
dcdd144598 2011-02-23        kinaba: 	case Western: impl_ = new wWest( fp_ ); break;
dcdd144598 2011-02-23        kinaba: 	case UTF5:    impl_ = new wUtf5( fp_ ); break;
dcdd144598 2011-02-23        kinaba: 	case UTF16l:
dcdd144598 2011-02-23        kinaba: 	case UTF16LE: impl_ = new wUtf16LE( fp_, cs_==UTF16l ); break;
dcdd144598 2011-02-23        kinaba: 	case UTF16b:
dcdd144598 2011-02-23        kinaba: 	case UTF16BE: impl_ = new wUtf16BE( fp_, cs_==UTF16b ); break;
dcdd144598 2011-02-23        kinaba: 	case UTF32l:
dcdd144598 2011-02-23        kinaba: 	case UTF32LE: impl_ = new wUtf32LE( fp_, cs_==UTF32l ); break;
dcdd144598 2011-02-23        kinaba: 	case UTF32b:
dcdd144598 2011-02-23        kinaba: 	case UTF32BE: impl_ = new wUtf32BE( fp_, cs_==UTF32b ); break;
dcdd144598 2011-02-23        kinaba: 	case EucJP:   impl_ = new wEucJp( fp_ ); break;
dcdd144598 2011-02-23        kinaba: 	case IsoJP:   impl_ = new wIsoJp( fp_ ); break;
dcdd144598 2011-02-23        kinaba: 	case IsoKR:   impl_ = new wIso2022( fp_, cs_ ); break;
dcdd144598 2011-02-23        kinaba: 	case IsoCN:   impl_ = new wIso2022( fp_, cs_ ); break;
dcdd144598 2011-02-23        kinaba: 	case HZ:      impl_ = new wIso2022( fp_, cs_ ); break;
dcdd144598 2011-02-23        kinaba: 	case UTF8:
dcdd144598 2011-02-23        kinaba: 	case UTF8N:
dcdd144598 2011-02-23        kinaba: 	default:
dcdd144598 2011-02-23        kinaba: #ifndef _UNICODE
dcdd144598 2011-02-23        kinaba: 		if( app().isWin95() && (cs_==UTF8 || cs_==UTF8N) )
dcdd144598 2011-02-23        kinaba: 			impl_ = new wUTF8( fp_, cs_ );
dcdd144598 2011-02-23        kinaba: 		else if( app().isWin95() && cs_==UTF7 )
dcdd144598 2011-02-23        kinaba: 			impl_ = new wUTF7( fp_ );
dcdd144598 2011-02-23        kinaba: 		else
dcdd144598 2011-02-23        kinaba: #endif
dcdd144598 2011-02-23        kinaba: 		impl_ = new wMBCS( fp_, cs_ );
dcdd144598 2011-02-23        kinaba: 		break;
dcdd144598 2011-02-23        kinaba: 	}
dcdd144598 2011-02-23        kinaba: 	return true;
dcdd144598 2011-02-23        kinaba: }