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: }