diff --git a/src/corelib/doc/snippets/code/src_corelib_io_qtextstream.cpp b/src/corelib/doc/snippets/code/src_corelib_io_qtextstream.cpp index c30f13df5a..4795650748 100644 --- a/src/corelib/doc/snippets/code/src_corelib_io_qtextstream.cpp +++ b/src/corelib/doc/snippets/code/src_corelib_io_qtextstream.cpp @@ -135,5 +135,5 @@ stream << '\n' << Qt::flush; //! [10] QTextStream out(&file); -out.setCodec("UTF-8"); +out.setEncoding(QStringConverter::Utf8); //! [10] diff --git a/src/corelib/io/qfile.cpp b/src/corelib/io/qfile.cpp index 2a9c24bbd5..2544496c32 100644 --- a/src/corelib/io/qfile.cpp +++ b/src/corelib/io/qfile.cpp @@ -173,9 +173,8 @@ QAbstractFileEngine *QFilePrivate::engine() const QTextStream takes care of converting the 8-bit data stored on disk into a 16-bit Unicode QString. By default, it assumes that - the user system's local 8-bit encoding is used (e.g., UTF-8 - on most unix based operating systems; see QTextCodec::codecForLocale() for - details). This can be changed using \l QTextStream::setCodec(). + the file is encoded in UTF-8. This can be changed using + \l QTextStream::setEncoding(). To write text, we can use operator<<(), which is overloaded to take a QTextStream on the left and various data types (including diff --git a/src/corelib/serialization/qtextstream.cpp b/src/corelib/serialization/qtextstream.cpp index a2af401a41..df683d74da 100644 --- a/src/corelib/serialization/qtextstream.cpp +++ b/src/corelib/serialization/qtextstream.cpp @@ -3157,6 +3157,45 @@ QTextStream &bom(QTextStream &stream) } // namespace Qt + +/*! + Sets the encoding for this stream to \a encoding. The encoding is used for + decoding any data that is read from the assigned device, and for + encoding any data that is written. By default, + QStringConverter::Utf8 is used, and automatic unicode + detection is enabled. + + If QTextStream operates on a string, this function does nothing. + + \warning If you call this function while the text stream is reading + from an open sequential socket, the internal buffer may still contain + text decoded using the old encoding. + + \sa encoding(), setAutoDetectUnicode(), setLocale() +*/ +void QTextStream::setEncoding(QStringConverter::Encoding encoding) +{ + Q_D(QTextStream); + d->encoding = encoding; +#if QT_CONFIG(textcodec) + // FIXME: This is temporary until QTextStream is converted to use QStringConverter + const char *name = QStringConverter::nameForEncoding(encoding); + auto codec = QTextCodec::codecForName(name); + setCodec(codec); +#endif +} + +/*! + Returns the encoding that is current assigned to the stream. + + \sa setEncoding(), setAutoDetectUnicode(), locale() +*/ +QStringConverter::Encoding QTextStream::encoding() const +{ + Q_D(const QTextStream); + return d->encoding; +} + /*! Sets the codec for this stream to \a codec. The codec is used for decoding any data that is read from the assigned device, and for diff --git a/src/corelib/serialization/qtextstream.h b/src/corelib/serialization/qtextstream.h index 97d596137e..9daa87947c 100644 --- a/src/corelib/serialization/qtextstream.h +++ b/src/corelib/serialization/qtextstream.h @@ -45,6 +45,7 @@ #include #include #include +#include #include @@ -98,6 +99,8 @@ public: explicit QTextStream(const QByteArray &array, QIODevice::OpenMode openMode = QIODevice::ReadOnly); virtual ~QTextStream(); + void setEncoding(QStringConverter::Encoding encoding); + QStringConverter::Encoding encoding() const; #if QT_CONFIG(textcodec) void setCodec(QTextCodec *codec); void setCodec(const char *codecName); diff --git a/src/corelib/serialization/qtextstream_p.h b/src/corelib/serialization/qtextstream_p.h index 172824d27d..2cf548bca6 100644 --- a/src/corelib/serialization/qtextstream_p.h +++ b/src/corelib/serialization/qtextstream_p.h @@ -118,6 +118,7 @@ public: int stringOffset; QIODevice::OpenMode stringOpenMode; + QStringConverter::Encoding encoding = QStringConverter::Utf8; #if QT_CONFIG(textcodec) // codec QTextCodec *codec; diff --git a/src/tools/uic/main.cpp b/src/tools/uic/main.cpp index 81492bbf45..8327dd5829 100644 --- a/src/tools/uic/main.cpp +++ b/src/tools/uic/main.cpp @@ -161,9 +161,7 @@ int runUic(int argc, char *argv[]) return 1; } out = new QTextStream(&f); -#if QT_CONFIG(textcodec) - out->setCodec(QTextCodec::codecForName("UTF-8")); -#endif + out->setEncoding(QStringConverter::Utf8); } bool rtn = driver.uic(inputFile, out); diff --git a/src/xml/dom/qdom.cpp b/src/xml/dom/qdom.cpp index 022de70090..5224c8b31c 100644 --- a/src/xml/dom/qdom.cpp +++ b/src/xml/dom/qdom.cpp @@ -5964,8 +5964,6 @@ void QDomDocumentPrivate::saveDocument(QTextStream& s, const int indent, QDomNod #if QT_CONFIG(textcodec) && QT_CONFIG(regularexpression) const QDomNodePrivate* n = first; - QTextCodec *codec = nullptr; - if (n && n->isProcessingInstruction() && n->nodeName() == QLatin1String("xml")) { // we have an XML declaration QString data = n->nodeValue(); @@ -5974,13 +5972,14 @@ void QDomDocumentPrivate::saveDocument(QTextStream& s, const int indent, QDomNod QString enc = match.captured(3); if (enc.isEmpty()) enc = match.captured(5); - if (!enc.isEmpty()) - codec = QTextCodec::codecForName(std::move(enc).toLatin1()); + if (!enc.isEmpty()) { + auto encoding = QStringConverter::encodingForName(enc.toUtf8().constData()); + if (!encoding) + qWarning() << "QDomDocument::save(): Unsupported encoding" << enc << "specified."; + else + s.setEncoding(encoding.value()); + } } - if (!codec) - codec = QTextCodec::codecForName("UTF-8"); - if (codec) - s.setCodec(codec); #endif bool doc = false; @@ -5998,11 +5997,9 @@ void QDomDocumentPrivate::saveDocument(QTextStream& s, const int indent, QDomNod // Write out the XML declaration. #if !QT_CONFIG(textcodec) - const QLatin1String codecName("iso-8859-1"); + const QLatin1String codecName("UTF-8"); #else - const QTextCodec *const codec = s.codec(); - Q_ASSERT_X(codec, "QDomNode::save()", "A codec must be specified in the text stream."); - const QByteArray codecName = codec->name(); + const QByteArray codecName = QStringConverter::nameForEncoding(s.encoding()); #endif s << ""; のような場合、\" による引用符のエスケープは、表 の第2バイトの\のため、\\ " という組み合わせになり、エスケープが打ち消されています。そのため、このリテラルは、perlから見ると、"\"対応表\" Unicode -> CP932 の順で変換されると、重複定義文字は、どれか一つに揃えられます。この優先順位は JIS X 0208, NEC特殊文字 (13区)、IBM拡張文字 (115〜119区)、NEC選定IBM拡張文字 (89〜92区) の順です。一例として、'∵' の場合、NEC特殊文字の "\x87\x9A" や IBM拡張文字の "\xFA\x5B" は、JIS X 0208 の "\x81\xE6" になります。 -しかし、CP-932 のテキスト中、重複定義文字がどれかに揃っていないことがあります。例えば "\x87\x9A" や "\xFA\x5B" が含まれていると、テキストを目で見ると違いがないのに、"\x81\xE6" で検索しても見つけられないことになります。 -重複定義文字を揃えるモジュールとして、ShiftJIS/CP932/Correct.pm があります。入手と使い方はPerlのページに戻れば見つかります。 -また、ShiftJIS/String.pm の strtr() または trclosure() を使う方法もあります。入手と使い方はPerlのページに戻れば見つかります。 -サンプルコード - -# (1) $necJIS -> $jisNEC (9対) - $necJIS = "\x87\x90\x87\x91\x87\x92\x87\x95\x87\x96\x87\x97\x87\x9A\x87\x9B\x87\x9C"; - # NEC特殊文字のうち、JIS文字に変換されるべき非漢字 - $jisNEC = "\x81\xE0\x81\xDF\x81\xE7\x81\xE3\x81\xDB\x81\xDA\x81\xE6\x81\xBF\x81\xBE"; - # JIS文字のうち、NEC特殊文字に重複定義されている非漢字 - -# (2) $necibmJIS -> $jisNECIBM (1対) - $necibmJIS = "\xEE\xF9"; - # NEC選定IBM拡張文字のうち、JIS文字に変換されるべき非漢字 - $jisNECIBM = "\x81\xCA"; - # JIS文字のうち、NEC選定IBM拡張文字に重複定義されている非漢字 - -# (3) $ibmJIS -> $jisIBM (2対) - $ibmJIS = "\xFA\x54\xFA\x5B"; - # IBM拡張文字のうち、JIS文字に変換されるべき非漢字 - $jisIBM = "\x81\xCA\x81\xE6"; - # JIS文字のうち、IBM拡張文字に重複定義されている非漢字 - -# (4) $ibmNEC -> $necIBM (13対) - $ibmNEC = "\xFA\x4A-\xFA\x53\xFA\x58\xFA\x59\xFA\x5A"; - # IBM拡張文字のうち、NEC特殊文字に変換されるべき非漢字 - $necIBM = "\x87\x54-\x87\x5D\x87\x8A\x87\x82\x87\x84"; - # NEC特殊文字のうち、IBM拡張文字に重複定義されている非漢字 - -# (5) $necibmIBM -> $ibmNECIBM (13対) - $necibmIBM = "\xEE\xEF-\xEE\xF8\xEE\xFA\xEE\xFB\xEE\xFC"; - # NEC選定IBM拡張文字のうち、IBM拡張文字に変換されるべき非漢字 - $ibmNECIBM = "\xFA\x40-\xFA\x49\xFA\x55\xFA\x56\xFA\x57"; - # IBM拡張文字のうち、NEC選定IBM拡張文字に重複定義されている非漢字 - -# (6) $necibmCJK -> $ibmCJK (360対) - $necibmCJK = "\xED\x40-\xEE\xEC"; - # NEC選定IBM拡張文字中の漢字 - $ibmCJK = "\xFA\x5C-\xFC\x4B"; - # IBM拡張文字中の漢字 - -use ShiftJIS::String qw(trclosure); - -# 変換用クロージャの生成 -$correctCP932 = trclosure( - $necJIS.$necibmJIS.$ibmJIS.$ibmNEC.$necibmIBM.$necibmCJK, # from - $jisNEC.$jisNECIBM.$jisIBM.$necIBM.$ibmNECIBM.$ibmCJK # to -); - -$result = $correctCP932->($source); # $source を変換して $result を得る - -文字数を数える -Shift-JIS文字列の文字数を数えるには、マッチ演算子を利用するならスカラーコンテキストで数えた方が若干速かったです。それより、置換演算子を利用したほうが速く書けるとわかりました。 -もっともXSで書いたほうがずっと速かったです。まあ、XSUBは無理に利用しなくてもよいでしょう。 -サンプルコード -use Benchmark; - -$char = '(?:[\x00-\x7F\xA1-\xDF]|[\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC])'; -$s = "漢字あ\0AアCテスト -"; - -timethese (100000, { - le => q{ - ($str = $s) =~ s/$char/0/go; - $le = length $str; - }, - sg => q{ - $sg = ($str = $s) =~ s/$char//go; - }, - ab => q{ - $ab = 0; - $ab++ while $s =~ /[^\x81-\x9F\xE0-\xFC]|../g; - }, - ar => q{ - $ar = @{[ $s =~ /$char/go ]}; - }, - gr => q{ - $gr = grep defined, $s =~ /$char/go; - }, - wh => q{ - $wh = 0; - $wh++ while $s =~ /$char/go; - }, - sj => q{ - $sj = sjslen($s); - }, - xs => q{ - $xs = sjlength($s); - }, -}); - -sub sjslen { - my($str,$len,$i,$c,$blen); - $str = shift; - $blen = length $str; - while ($i < $blen) { - $c = vec($str, $i, 8); - if (0x81 <= $c && $c <= 0x9F || 0xE0 <= $c && $c <= 0xFC){ $i++ } - $i++,$len++; - } - $len; -} - -結果 -Benchmark: timing 100000 iterations of ab, ar, gr, le, sg, sj, wh, xs... - ab: 4 wallclock secs ( 3.46 usr + 0.00 sys = 3.46 CPU) @ 28901.73/s - ar: 6 wallclock secs ( 5.98 usr + 0.00 sys = 5.98 CPU) @ 16722.41/s - gr: 6 wallclock secs ( 5.50 usr + 0.00 sys = 5.50 CPU) @ 18181.82/s - le: 3 wallclock secs ( 2.09 usr + 0.00 sys = 2.09 CPU) @ 47846.89/s - sg: 2 wallclock secs ( 1.92 usr + 0.00 sys = 1.92 CPU) @ 52083.33/s - sj: 9 wallclock secs ( 8.57 usr + 0.00 sys = 8.57 CPU) @ 11668.61/s - wh: 5 wallclock secs ( 4.78 usr + 0.00 sys = 4.78 CPU) @ 20920.50/s - xs: 1 wallclock secs ( 0.38 usr + 0.00 sys = 0.38 CPU) @ 263157.89/s - (warning: too few iterations for a reliable count) - -XSUB -int -sjlength(arg) - SV* arg - PROTOTYPE: $ - PREINIT: - unsigned char *str, *p, *e; - STRLEN byte, len = 0; - CODE: - p = str = (unsigned char *)SvPV(arg, byte); - e = str + byte; - while (p < e) { - if (0x81 <= *p && *p <= 0x9F || 0xE0 <= *p && *p <= 0xFC) - ++p; - ++p, ++len; - } - RETVAL = len; - OUTPUT: - RETVAL - -文字単位に分ける -Shift-JIS文字列を文字単位に分割しましょう。この場合は、XSを利用してもあまり速くなりませんでした。返り値のリストを用意するのに時間が取られるのか、やはりPerlの正規表現の処理はかなり速いものだということでしょう。 -サンプルコード -use Benchmark; - -$char = '(?:[\x00-\x7F\xA1-\xDF]|[\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC])'; -$s = "日本語ニホンゴ\0ABC" x 100; - -timethese (1000, { - re => q{ - @re = $s =~ /$char/go; - }, - xs => q{ - @xs = sjsplit($s); - }, -}); - -結果 -Benchmark: timing 1000 iterations of re, xs... - re: 7 wallclock secs ( 6.65 usr + 0.00 sys = 6.65 CPU) @ 150.38/s - xs: 6 wallclock secs ( 5.33 usr + 0.00 sys = 5.33 CPU) @ 187.62/s - -XSUB -void -sjsplit(arg) - SV* arg - PROTOTYPE: $ - PREINIT: - unsigned char *str, *p, *e; - STRLEN ch, byte, len = 0; - PPCODE: - str = (unsigned char *)SvPV(arg,byte); - e = str + byte; - for (p = str; p < e; p++) { - if (0x81 <= *p && *p <= 0x9F || 0xE0 <= *p && *p <= 0xFC) ++p; - ++len; - } - EXTEND(SP,len); - for (p = str; p < e; p += ch) { - ch = (0x81 <= *p && *p <= 0x9F || 0xE0 < *p && *p <= 0xFC) ? 2 : 1; - PUSHs(sv_2mortal(newSVpv(p,ch))); - } - -色々な分割 -文字で分割でみたように、文字列を分割するには、m//gが便利です。 -サンプルコード -$onebyte = '[\x00-\x7F\xA1-\xDF]'; -$twobyte = '(?:[\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC])'; -$char = '(?:[\x00-\x7F\xA1-\xDF]|[\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC])'; - -#1バイト文字の塊と2バイト文字の塊に分ける。 - while ($str =~ /\G($onebyte*)($twobyte*)/g) { - push @one, $1 if $1 ne ''; - push @two, $2 if $2 ne ''; - } - -#句点が最後の文字となるように分割する。 -# '。' ではいいが、文字によっては注意が必要。 - @sentences = $str =~ /\G$char*?(?:。|.|$)/g; - -特定の長さで切りそろえる -長い文字列を特定の長さ(バイト長)で切りそろえるなら、次のようにしてできます。 -サンプルコード -$char = '(?:[\x00-\x7F\xA1-\xDF]|[\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC])'; - -$str = 'わざわざEUC-JPに変換しないで、Shift-JISのまま処理'. - 'できたらいいんだけど、なかなか面倒だねえ。'; - -print join "\n", bytebreak($str,15); - -sub bytebreak{ - my($byte,$bmax,$ch,@lines); - my $str = shift; - $byte = $bmax = shift; - foreach $ch ($str =~ /$char/go) { - $byte += length $ch; # 次の文字を継ぎ足した長さ - if ($byte <= $bmax) { - $lines[-1] .= $ch; # 長すぎなければ継ぎ足す - } else { - $byte = length $ch; - push @lines, $ch; # さもなければ次の行へ - } - } - return @lines; - # 長さが足らない場合に、右をスペースで埋めたければ。 - # return map {$_ .= ' ' x ($bmax - length)} @lines; -} - -禁則処理は、例えば次のようにして行います。単純な考え方では、禁則処理は、(i) 行頭禁則文字の直前で改行しない;(ii) 行末禁則文字の直後で改行しない;ということになります。また、"(a)"のように、行末禁則文字と行頭禁則文字の間に1文字しかない連続した部分は、その部分の全体が無改行になる点にも配慮します。 -この例では文字列の長さをバイト長 length で規定していますが、文字幅とバイト数は必ずしも比例しませんので、場合によっては(ギリシア文字は半角幅にしたいとか、またはプロポーショナルの場合とか、UTF-8の場合とか)文字幅を返す width のような関数を定義する必要があるでしょう。 -また、この例のやり方では、禁則による無改行部分だけで一行より長くなる場合は、はみだしを防げません。それが困るなら、禁則の例外として行を分ける(例えば$nextの長さが$bmaxを超えないようにする)処置が必要でしょう。 -サンプルコード -$CharRE = '(?:[\x00-\x7F\xA1-\xDF]|[\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC])'; - -# 行頭禁則文字(一部分) -$NotAtBegin = q/)]}’”」』)]}!,.:;?、。々゛゜!,.:;?/; -# 行末禁則文字(一部分) -$NotAtEnd = q/([{‘“「『([{/; - -# ハッシュを作る -@NotAtBegin{$NotAtBegin =~ m/$CharRE/g} = (); -@NotAtEnd{ $NotAtEnd =~ m/$CharRE/g} = (); - -$Str = 'わざわざEUC-JPに変換しないで、Shift-JISのまま処理'. - 'できたらいいんだけど、なかなか面倒だねえ。'; - -print join "\n", linebreak($Str,16); - -sub linebreak{ - my($byte,$i,@chars,$next,@lines); - my($str, $bmax, $pad) = @_; - - # $byteは次の文字を継ぎ足したときの長さ - $byte = $bmax; # すぐ改行できるための初期値。 - - # 文字単位にばらす - @chars = $str =~ /$CharRE/go; - - for ($i=0; $i<@chars; $i++) { - $next .= $chars[$i]; # 次の文字 - $byte += length $chars[$i]; # 次の文字を継ぎ足した長さ - - # 次の文字が行末禁則のとき - next if $i+1 < @chars && exists $NotAtEnd{ $chars[$i] }; - # 次の文字の次が行頭禁則のとき - next if $i+1 < @chars && exists $NotAtBegin{ $chars[$i+1] }; - - # 行の振り分け - # 長すぎなければ継ぎ足す - if ($byte <= $bmax) { - $lines[-1] .= $next; - } - # さもなければ次の行へ - else { - push @lines, $next; - $byte = length $next;# 新しい行の長さ - } - $next = ''; - } - return defined $pad && 1 == length $pad # 詰め物 - ? map {$_ .= $pad x ($bmax - length)} @lines - : @lines; -} - -ぶら下がり禁則の場合($bmin から $bmaxの範囲を許す)。 - $bmin = $bmax - 2; # 例えば。 - - # 行の振り分け - # 長すぎなければ継ぎ足す - if ($byte <= $bmax && @lines && length $lines[-1] < $bmin){ - $lines[-1] .= $next; - } - # さもなければ次の行へ - else { - push @lines, $next; - $byte = length $next;# 新しい行の長さ - } - -日本語文字列を並び替える -仮名文字列を五十音順にソートするモジュールとして、ShiftJIS/Collate.pm があります。入手と使い方はPerlのページに戻れば見つかります。 -「読み・表記照合」は次のようにして行います。sortYomiメソッドの受け取るリストの各要素は、[ 表記列, 読み列 ]という配列リファレンスでなければなりません。 -サンプルコード -use ShiftJIS::Collate; - -my @data = ( - [qw/ 小山 こやま /], - [qw/ 長田 ながた /], - [qw/ 田中 たなか /], - [qw/ 鈴木 すずき /], - [qw/ 小嶋 こじま /], - [qw/ 児島 こじま /], - [qw/ 小山 おやま /], - [qw/ 小島 こじま /], - [qw/ 小島 こじま /], - [qw/ 山田 やまだ /], - [qw/ 永田 ながた /], -); - -@sort = ShiftJIS::Collate->new()->sortYomi(@data); - -「簡易代表読み照合」は次のようにして行います。sortDaihyoメソッドの受け取るリストの各要素は、[ 表記列, 読み列 ]という配列リファレンスでなければなりません。 -サンプルコード - -#!perl -use ShiftJIS::Collate; - -my @data = ( - [qw/ λ計算 らむだけいさん /], - [qw/ JIS番号 じすばんごう /], - [qw/ 安達 あだち /], - [qw/ 安藤 あんどう /], - [qw/ 河西 かさい /], - [qw/ 河内 かわち /], - [qw/ 角田 かくた /], - [qw/ 角田 かどた /], - [qw/ 如月 きさらぎ /], - [qw/ 河内 こうち /], - [qw/ 幸山 こうやま /], - [qw/ 幸山 さきやま /], - [qw/ 佐藤 さとう /], - [qw/ 佐和田 さわだ /], - [qw/ 沢島 さわしま /], - [qw/ 沢田 さわだ /], - [qw/ 澤田 さわだ /], - [qw/ 角田 つのだ /], - [qw/ 槌井 つちい /], - [qw/ 土井 つちい /], - [qw/ 土居 つちい /], - [qw/ 戸井 とい /], - [qw/ 戸田 とだ /], - [qw/ 土井 どい /], - [qw/ 土居 どい /], - [qw/ 土岐 とき /], - [qw/ 安田 やすだ /], -); - -@sort = ShiftJIS::Collate->new()->sortDaihyo(@data); - - -Shift-JISの漢字を含むファイル名/パス名 -本項目は、他の項目に増して、検討不充分のまま記述していますので、もし何か参考にしようと思った場合、十分に注意の上、納得できるまでご自分の作業環境でテストしてください。 -Windows (95/98/NT/2000など) で、ファイル名やパス名が漢字(ここでは二バイト文字の意味で使っていますので、平仮名や記号なども含みます。)を含む場合、Perlで扱う際に問題が生じる可能性があります。 -末尾バイトが "\x5C" の漢字をもつファイル名/パス名 -ディレクトリ操作関数(mkdir, rmdir, opendir, -d など)、ファイル操作関数(open, unlink, -f など)で、アクセスできないことがあります。 -ファイルの場合は、末尾に半角スペースを添えるとアクセスできる場合があります(例えば、-f '表 ' または -f "\x95\x5C\x20" など)。 -ディレクトリの場合は、末尾に / か \ を添えるとアクセスできる場合があります(例えば、-d '表/' または -d "\x95\x5C/" など)。末尾に添える文字を半角スペースとしても、うまくアクセスできる場合があります。添える文字の候補として、三種類の文字(スラッシュ、円記号、空白)を挙げましたが、どの文字がよいかは、関数によって異なる場合があるようです。使用する前に十分にテストしてください。 -なお、ディレクトリ名の末尾に / か \ を添える場合、もともと末尾に / か \ が付いている場合には、二重に付けるとうまく行かないおそれがありますので、文字列連結の前に検査したほうがよいでしょう。 -どうしても挙動が不明で信頼できない場合は、`` または qx// や system()関数などを通じてWindowsのコマンドを呼ぶのが良いと思います。 -おまけ - Shift-JIS で書かれた POD を Perl 5.8.1, 5.8.2 の Pod::Html で HTML に変換した場合、アンカーの名前は、 英数字と仮名文字 [0xA6..0xDF] を除き、 他の各バイトは下線('_')に変換されるようです。 具体的には、use locale; 下で、lc と s/\W/_/g を実行した結果 (cf. Pod::Html::anchorify) になります。 -[2003-11-18] -Perlのページ diff --git a/tests/auto/corelib/serialization/qtextstream/tst_qtextstream.cpp b/tests/auto/corelib/serialization/qtextstream/tst_qtextstream.cpp index 58f0d65f94..07960f1348 100644 --- a/tests/auto/corelib/serialization/qtextstream/tst_qtextstream.cpp +++ b/tests/auto/corelib/serialization/qtextstream/tst_qtextstream.cpp @@ -221,7 +221,7 @@ private slots: // Regression tests for old bugs void alignAccountingStyle(); - void setCodec(); + void setEncoding(); void textModeOnEmptyRead(); @@ -240,7 +240,6 @@ private: QSharedPointer m_dataDir; #endif const QString m_rfc3261FilePath; - const QString m_shiftJisFilePath; }; void runOnExit() @@ -253,7 +252,6 @@ Q_DESTRUCTOR_FUNCTION(runOnExit) tst_QTextStream::tst_QTextStream() : tempDir(QDir::tempPath() + "/tst_qtextstream.XXXXXX") , m_rfc3261FilePath(QFINDTESTDATA("rfc3261.txt")) - , m_shiftJisFilePath(QFINDTESTDATA("shift-jis.txt")) { } @@ -261,7 +259,6 @@ void tst_QTextStream::initTestCase() { QVERIFY2(tempDir.isValid(), qPrintable(tempDir.errorString())); QVERIFY(!m_rfc3261FilePath.isEmpty()); - QVERIFY(!m_shiftJisFilePath.isEmpty()); testFileName = tempDir.path() + "/testfile"; @@ -280,13 +277,12 @@ void tst_QTextStream::getSetCheck() { // Initialize codecs QTextStream obj1; - // QTextCodec * QTextStream::codec() - // void QTextStream::setCodec(QTextCodec *) - QTextCodec *var1 = QTextCodec::codecForName("en"); - obj1.setCodec(var1); - QCOMPARE(var1, obj1.codec()); - obj1.setCodec((QTextCodec *)0); - QCOMPARE((QTextCodec *)0, obj1.codec()); + // QTextCodec * QTextStream::encoding() + // void QTextStream::setEncoding() + obj1.setEncoding(QStringConverter::Utf32BE); + QCOMPARE(QStringConverter::Utf32BE, obj1.encoding()); + obj1.setEncoding(QStringConverter::Utf8); + QCOMPARE(QStringConverter::Utf8, obj1.encoding()); // bool QTextStream::autoDetectUnicode() // void QTextStream::setAutoDetectUnicode(bool) @@ -577,7 +573,7 @@ void tst_QTextStream::readLineMaxlen() file.write(input.toUtf8()); file.seek(0); stream.setDevice(&file); - stream.setCodec("utf-8"); + stream.setEncoding(QStringConverter::Utf8); } else { stream.setString(&input); } @@ -1378,46 +1374,6 @@ void tst_QTextStream::pos() QCOMPARE(stream.pos(), qint64(2607)); QCOMPARE(strtmp, QString("locations")); } - { - // Shift-JIS device - for (int i = 0; i < 2; ++i) { - QFile file(m_shiftJisFilePath); - if (i == 0) - QVERIFY(file.open(QIODevice::ReadOnly)); - else - QVERIFY(file.open(QIODevice::ReadOnly | QIODevice::Text)); - - QTextStream stream(&file); - stream.setCodec("Shift-JIS"); - QVERIFY(stream.codec()); - - QCOMPARE(stream.pos(), qint64(0)); - for (int i = 0; i <= file.size(); i += 7) { - QVERIFY(stream.seek(i)); - QCOMPARE(stream.pos(), qint64(i)); - } - for (int j = file.size(); j >= 0; j -= 7) { - QVERIFY(stream.seek(j)); - QCOMPARE(stream.pos(), qint64(j)); - } - - stream.seek(2089); - QString strtmp; - stream >> strtmp; - QCOMPARE(strtmp, QString("AUnicode")); - QCOMPARE(stream.pos(), qint64(2097)); - - stream.seek(43325); - stream >> strtmp; - QCOMPARE(strtmp, QString("Shift-JIS")); - stream >> strtmp; - QCOMPARE(strtmp, QString::fromUtf8("\343\201\247\346\233\270\343\201\213\343\202\214\343\201\237")); - QCOMPARE(stream.pos(), qint64(43345)); - stream >> strtmp; - QCOMPARE(strtmp, QString("POD")); - QCOMPARE(stream.pos(), qint64(43349)); - } - } } // ------------------------------------------------------------------------------ @@ -1534,7 +1490,7 @@ void tst_QTextStream::readAllFromStdin() stdinProcess.setReadChannel(QProcess::StandardError); QTextStream stream(&stdinProcess); - stream.setCodec("ISO-8859-1"); + stream.setEncoding(QStringConverter::Latin1); stream << "hello world" << Qt::flush; stdinProcess.closeWriteChannel(); @@ -1821,7 +1777,7 @@ void tst_QTextStream::utf8IncompleteAtBufferBoundary() data.open(QFile::WriteOnly | QFile::Truncate); { QTextStream out(&data); - out.setCodec(utf8Codec); + out.setEncoding(QStringConverter::Utf8); out.setFieldWidth(3); for (int i = 0; i < 1000; ++i) { @@ -1835,9 +1791,9 @@ void tst_QTextStream::utf8IncompleteAtBufferBoundary() QFETCH(bool, useLocale); if (!useLocale) - in.setCodec(utf8Codec); // QUtf8Codec + in.setEncoding(QStringConverter::Utf8); else - in.setCodec(QTextCodec::codecForLocale()); + in.setEncoding(QStringConverter::Locale); int i = 0; do { @@ -1887,7 +1843,7 @@ void tst_QTextStream::writeSeekWriteNoBOM() QBuffer out16; out16.open(QIODevice::WriteOnly); QTextStream stream16(&out16); - stream16.setCodec("UTF-16"); + stream16.setEncoding(QStringConverter::Utf16); stream16 << "one" << "two" << QLatin1String("three"); stream16.flush(); @@ -1941,7 +1897,7 @@ void tst_QTextStream::QChar_operators_FromDevice() QBuffer buf(&input); buf.open(QBuffer::ReadOnly); QTextStream stream(&buf); - stream.setCodec(QTextCodec::codecForName("ISO-8859-1")); + stream.setEncoding(QStringConverter::Latin1); QChar tmp; stream >> tmp; QCOMPARE(tmp, qchar_output); @@ -1950,7 +1906,7 @@ void tst_QTextStream::QChar_operators_FromDevice() writeBuf.open(QBuffer::WriteOnly); QTextStream writeStream(&writeBuf); - writeStream.setCodec(QTextCodec::codecForName("ISO-8859-1")); + writeStream.setEncoding(QStringConverter::Latin1); writeStream << qchar_output; writeStream.flush(); @@ -1974,7 +1930,7 @@ void tst_QTextStream::char_operators_FromDevice() QBuffer buf(&input); buf.open(QBuffer::ReadOnly); QTextStream stream(&buf); - stream.setCodec(QTextCodec::codecForName("ISO-8859-1")); + stream.setEncoding(QStringConverter::Latin1); char tmp; stream >> tmp; QCOMPARE(tmp, char_output); @@ -1983,7 +1939,7 @@ void tst_QTextStream::char_operators_FromDevice() writeBuf.open(QBuffer::WriteOnly); QTextStream writeStream(&writeBuf); - writeStream.setCodec(QTextCodec::codecForName("ISO-8859-1")); + writeStream.setEncoding(QStringConverter::Latin1); writeStream << char_output; writeStream.flush(); @@ -2191,7 +2147,7 @@ void tst_QTextStream::charPtr_read_operator_FromDevice() QBuffer buffer(&input); buffer.open(QBuffer::ReadOnly); QTextStream stream(&buffer); - stream.setCodec(QTextCodec::codecForName("ISO-8859-1")); + stream.setEncoding(QStringConverter::Latin1); stream.setAutoDetectUnicode(true); char buf[1024]; @@ -2215,7 +2171,7 @@ void tst_QTextStream::stringRef_read_operator_FromDevice() QBuffer buffer(&input); buffer.open(QBuffer::ReadOnly); QTextStream stream(&buffer); - stream.setCodec(QTextCodec::codecForName("ISO-8859-1")); + stream.setEncoding(QStringConverter::Latin1); stream.setAutoDetectUnicode(true); QString tmp; @@ -2239,7 +2195,7 @@ void tst_QTextStream::byteArray_read_operator_FromDevice() QBuffer buffer(&input); buffer.open(QBuffer::ReadOnly); QTextStream stream(&buffer); - stream.setCodec(QTextCodec::codecForName("ISO-8859-1")); + stream.setEncoding(QStringConverter::Latin1); stream.setAutoDetectUnicode(true); QByteArray array; @@ -2518,7 +2474,7 @@ void tst_QTextStream::string_write_operator_ToDevice() QBuffer buf; buf.open(QBuffer::WriteOnly); QTextStream stream(&buf); - stream.setCodec(QTextCodec::codecForName("ISO-8859-1")); + stream.setEncoding(QStringConverter::Latin1); stream.setAutoDetectUnicode(true); stream << bytedata.constData(); @@ -2530,7 +2486,7 @@ void tst_QTextStream::string_write_operator_ToDevice() QBuffer buf; buf.open(QBuffer::WriteOnly); QTextStream stream(&buf); - stream.setCodec(QTextCodec::codecForName("ISO-8859-1")); + stream.setEncoding(QStringConverter::Latin1); stream.setAutoDetectUnicode(true); stream << bytedata; @@ -2542,7 +2498,7 @@ void tst_QTextStream::string_write_operator_ToDevice() QBuffer buf; buf.open(QBuffer::WriteOnly); QTextStream stream(&buf); - stream.setCodec(QTextCodec::codecForName("ISO-8859-1")); + stream.setEncoding(QStringConverter::Latin1); stream.setAutoDetectUnicode(true); stream << stringdata; @@ -2556,7 +2512,7 @@ void tst_QTextStream::latin1String_write_operator_ToDevice() QBuffer buf; buf.open(QBuffer::WriteOnly); QTextStream stream(&buf); - stream.setCodec(QTextCodec::codecForName("ISO-8859-1")); + stream.setEncoding(QStringConverter::Latin1); stream.setAutoDetectUnicode(true); stream << QLatin1String("No explicit length"); @@ -2570,7 +2526,7 @@ void tst_QTextStream::stringref_write_operator_ToDevice() QBuffer buf; buf.open(QBuffer::WriteOnly); QTextStream stream(&buf); - stream.setCodec(QTextCodec::codecForName("ISO-8859-1")); + stream.setEncoding(QStringConverter::Latin1); stream.setAutoDetectUnicode(true); const QString expected = "No explicit lengthExplicit length"; @@ -2601,7 +2557,7 @@ void tst_QTextStream::useCase1() { QTextStream stream(&file); - stream.setCodec(QTextCodec::codecForName("ISO-8859-1")); + stream.setEncoding(QStringConverter::Latin1); stream.setAutoDetectUnicode(true); stream << 4.15 << ' ' << QByteArray("abc") << ' ' << QString("ole"); @@ -2616,7 +2572,7 @@ void tst_QTextStream::useCase1() QByteArray a; QString s; QTextStream stream(&file); - stream.setCodec(QTextCodec::codecForName("ISO-8859-1")); + stream.setEncoding(QStringConverter::Latin1); stream.setAutoDetectUnicode(true); stream >> d; @@ -2637,7 +2593,7 @@ void tst_QTextStream::useCase2() QVERIFY(file.open(QFile::ReadWrite)); QTextStream stream(&file); - stream.setCodec(QTextCodec::codecForName("ISO-8859-1")); + stream.setEncoding(QStringConverter::Latin1); stream.setAutoDetectUnicode(true); stream << 4.15 << ' ' << QByteArray("abc") << ' ' << QString("ole"); @@ -2654,7 +2610,7 @@ void tst_QTextStream::useCase2() QByteArray a; QString s; QTextStream stream2(&file); - stream2.setCodec(QTextCodec::codecForName("ISO-8859-1")); + stream2.setEncoding(QStringConverter::Latin1); stream2.setAutoDetectUnicode(true); stream2 >> d; @@ -2703,7 +2659,7 @@ void tst_QTextStream::manipulators() buffer.open(QBuffer::WriteOnly); QTextStream stream(&buffer); - stream.setCodec(QTextCodec::codecForName("ISO-8859-1")); + stream.setEncoding(QStringConverter::Latin1); stream.setAutoDetectUnicode(true); stream.setIntegerBase(base); @@ -2726,7 +2682,7 @@ void tst_QTextStream::generateBOM() QVERIFY(file.open(QFile::ReadWrite | QFile::Truncate)); QTextStream stream(&file); - stream.setCodec(QTextCodec::codecForName("UTF-16LE")); + stream.setEncoding(QStringConverter::Utf16LE); stream << "Hello" << Qt::endl; file.close(); @@ -2740,7 +2696,7 @@ void tst_QTextStream::generateBOM() QVERIFY(file.open(QFile::ReadWrite | QFile::Truncate)); QTextStream stream(&file); - stream.setCodec(QTextCodec::codecForName("UTF-16LE")); + stream.setEncoding(QStringConverter::Utf16LE); stream << Qt::bom << "Hello" << Qt::endl; file.close(); @@ -2759,7 +2715,7 @@ void tst_QTextStream::readBomSeekBackReadBomAgain() QCOMPARE(file.pos(), qint64(0)); QTextStream stream(&file); - stream.setCodec("UTF-8"); + stream.setEncoding(QStringConverter::Utf8); QString Andreas; stream >> Andreas; QCOMPARE(Andreas, QString("Andreas")); @@ -2853,7 +2809,7 @@ void tst_QTextStream::status_write_error() FakeBuffer fb(false); QVERIFY(fb.open(QBuffer::ReadWrite)); QTextStream fs(&fb); - fs.setCodec(QTextCodec::codecForName("latin1")); + fs.setEncoding(QStringConverter::Latin1); /* first write some initial content */ fs << "hello"; fs.flush(); @@ -2916,15 +2872,15 @@ void tst_QTextStream::alignAccountingStyle() } } -void tst_QTextStream::setCodec() +void tst_QTextStream::setEncoding() { QByteArray ba("\xe5 v\xe6r\n\xc3\xa5 v\xc3\xa6r\n"); QString res = QLatin1String("\xe5 v\xe6r"); QTextStream stream(ba); - stream.setCodec("ISO 8859-1"); + stream.setEncoding(QStringConverter::Latin1); QCOMPARE(stream.readLine(),res); - stream.setCodec("UTF-8"); + stream.setEncoding(QStringConverter::Utf8); QCOMPARE(stream.readLine(),res); } diff --git a/tests/auto/corelib/serialization/qxmlstream/tst_qxmlstream.cpp b/tests/auto/corelib/serialization/qxmlstream/tst_qxmlstream.cpp index 36689f773c..4c8d4bf2e7 100644 --- a/tests/auto/corelib/serialization/qxmlstream/tst_qxmlstream.cpp +++ b/tests/auto/corelib/serialization/qxmlstream/tst_qxmlstream.cpp @@ -698,7 +698,7 @@ QByteArray tst_QXmlStream::readFile(const QString &filename) QByteArray outarray; QTextStream writer(&outarray); // We always want UTF-8, and not what the system picks up. - writer.setCodec("UTF-8"); + writer.setEncoding(QStringConverter::Utf8); while (!reader.atEnd()) { reader.readNext();