[#30455] a[] += 1 で SEGV — "Hiroki Motoyoshi" <himotoyoshi.ml@...>
本吉と申します。
6 messages
2007/03/01
[#30477] ThreadError on shell.rb — "Akira ODA" <oda.org@...>
はじめまして、尾田といいます。
8 messages
2007/03/04
[#30478] Re: ThreadError on shell.rb
— keiju@... (石塚圭樹)
2007/03/04
けいじゅ@いしつかです.
[#30482] Ruby 1.8.6 preview3 has been released — "Akinori MUSHA" <knu@...>
Ruby 1.8.6 preview3 をリリースしました。
10 messages
2007/03/04
[#30489] Re: Ruby 1.8.6 preview3 has been released
— nekomaho <nekomaho@...>
2007/03/05
ねこまほです.
[#30486] str.lines[1..-1] — Minero Aoki <aamine@...>
青木です。
7 messages
2007/03/05
[#30487] Time#to_s format — OHARA Shigeki <os@...>
大原です。
6 messages
2007/03/05
[#30504] num_tとthread_initという名前について — "Yutaka Kanemoto" <kinpoco@...>
金本ともうします。
1 message
2007/03/07
[#30505] [BUG?] SIGTERM の取り扱い — Hidetoshi NAGAI <nagai@...>
永井@知能.九工大です.
10 messages
2007/03/08
[#30509] Re: [BUG?] SIGTERM の取り扱い
— Nobuyoshi Nakada <nobu@...>
2007/03/08
なかだです。
[#30510] Re: [BUG?] SIGTERM の取り扱い
— Yukihiro Matsumoto <matz@...>
2007/03/08
まつもと ゆきひろです
[#30531] DL::PtrData#to_a dumps core — sheepman <sheepman@...>
こんばんは、sheepman です。
4 messages
2007/03/11
[#30532] DL::PtrData#inspect — sheepman <sheepman@...>
こんばんは、sheepman です。
6 messages
2007/03/11
[#30537] Microsoft-IIS 上で cgi.rb がレスポンス行を2重に出力する — MIYASAKA Masaru <alkaid@...>
初めての投稿です。みやさか と申します。よろしくお願いいたします。
5 messages
2007/03/12
[#30549] [ANN] Ruby 1.8.6 has been released — "Akinori MUSHA" <knu@...>
Ruby 1.8.6 をリリースしました。
14 messages
2007/03/12
[#30555] Re: [ANN] Ruby 1.8.6 has been released
— "U.Nakamura" <usa@...>
2007/03/13
こんにちは、なかむら(う)です。
[#30558] Re: [ANN] Ruby 1.8.6 has been released
— moonwolf@...
2007/03/13
おひさしぶり、MoonWolfです。
[#30559] Re: [ANN] Ruby 1.8.6 has been released
— nekomaho <nekomaho@...>
2007/03/13
ねこまほです.
[#30553] help: lib/shell for ruby 1.9 — keiju@... (Keiju ISHITSUKA)
けいじゅ@いしつかです.
13 messages
2007/03/13
[#30585] Re: help: lib/shell for ruby 1.9
— Yukihiro Matsumoto <matz@...>
2007/03/15
まつもと ゆきひろです
[#30587] Re: help: lib/shell for ruby 1.9
— keiju@... (石塚圭樹)
2007/03/15
けいじゅ@いしつかです.
[#30588] Re: help: lib/shell for ruby 1.9
— Yukihiro Matsumoto <matz@...>
2007/03/15
まつもと ゆきひろです
[#30590] [BUG?] Mutex or ConditionVariable for ruby 1.8[Re: Re: help: lib/shell for ruby 1.9]
— keiju@... (石塚圭樹)
2007/03/15
けいじゅ@いしつかです.
[#30592] Re: [BUG?] Mutex or ConditionVariable for ruby 1.8[Re: Re: help: lib/shell for ruby 1.9]
— "Akinori MUSHA" <knu@...>
2007/03/15
At Thu, 15 Mar 2007 18:53:46 +0900,
[#30600] Re: [BUG?] Mutex or ConditionVariable for ruby 1.8[Re: Re: help: lib/shell for ruby 1.9]
— "Akinori MUSHA" <knu@...>
2007/03/16
At Thu, 15 Mar 2007 19:18:42 +0900,
[#30601] Re: [BUG?] Mutex or ConditionVariable for ruby 1.8[Re: Re: help: lib/shell for ruby 1.9]
— keiju@... (keiju ISHITSUKA)
2007/03/16
けいじゅ@いしつかです.
[#30564] release code and revision number — Nobuyoshi Nakada <nobu@...>
なかだです。
11 messages
2007/03/13
[#30566] Re: release code and revision number
— Urabe Shyouhei <shyouhei@...>
2007/03/14
卜部です
[#30581] [ruby-core:10580] Thread後のexecでENOTSUPPエラー対応 — "H.Holon" <holon@...>
相馬 - H.Holonです。
8 messages
2007/03/14
[#30646] Re: [ruby-core:10580] Thread後のexecでENOTSUPPエラー対応
— Nobuyoshi Nakada <nobu@...>
2007/03/19
なかだです。
[#30586] Etc.getgrgid が getgid の値に固定されています — 植田裕之 <ueda@...>
植田と申します。
5 messages
2007/03/15
[#30593] [BUG] waitpid for ruby-trunk — keiju@... (Keiju ISHITSUKA)
けいじゅ@いしつかです.
5 messages
2007/03/15
[#30612] stdout flush in fork — keiju@... (Keiju ISHITSUKA)
けいじゅ@いしつかです.
9 messages
2007/03/17
[#30614] Re: stdout flush in fork
— Yukihiro Matsumoto <matz@...>
2007/03/17
まつもと ゆきひろです
[#30616] Re: stdout flush in fork
— keiju@... (石塚圭樹)
2007/03/17
けいじゅ@いしつかです.
[#30620] DL.callback as free function causes errors — sheepman <sheepman@...>
こんにちは、sheepman です。
4 messages
2007/03/18
[#30627] [ ruby-Bugs-9360 ] Matrix inverse problem — Yukihiro Matsumoto <matz@...>
まつもと ゆきひろです
4 messages
2007/03/19
[#30648] YARVでのalias名の取得方法 — Yukihiro Matsumoto <matz@...>
まつもと ゆきひろです
5 messages
2007/03/20
[#30653] [BUG] queue 0x424010 freed with live thread(s) waiting — Masatoshi SEKI <m_seki@...>
咳といいます。
4 messages
2007/03/20
[#30655] win32/registry wtime — moonwolf@...
MoonWolfです。
11 messages
2007/03/20
[#30658] Unicode対応と文字化け(Re: win32/registry wtime)
— Yukihiro Matsumoto <matz@...>
2007/03/21
まつもと ゆきひろです
[#30659] Re: Unicode対応と文字化け(Re: win32/registry wtime)
— Tietew <tietew+ruby-dev@...>
2007/03/21
win32/registry.rb を書いた Tietew です。
[ruby-dev:30670] Re: Unicode対応と文字化け(win32/registry)
From:
moonwolf@...
Date:
2007-03-22 10:37:01 UTC
List:
ruby-dev #30670
MoonWolfです。 Yukihiro Matsumoto <matz@ruby-lang.org>: > |# 別件になりますがユニコード対応してないから文字化けがたまに起きますね。 > |# レジストリをダンプするプログラムを組もうとして嵌りました^^; > > ま、Unicode対応しているとうたってる言語でも文字化けは発生し > てるみたいですしね。で、今回はどのような経緯で文字化けしまし > たか。同じような問題が今後発生しないような仕組みを考えるヒン > トにしたいので、ぜひ教えてください。 Windowsのレジストリ内部は全てユニコードで記録されています。 現状のwin32/registryで呼び出しているANSI版のAPIでは ANSI(CP932)書き込み→内部(UCS2)→ANSI(CP932)読み込みという風になります。 CP932しか使わないのであれば全く問題はありません。 今回発生した文字化けはレジストリのバックアップ/リストア処理で起きました。 レジストリを読み出す段階でCP932に無い文字は'?'に置き換えられてしまいます。 そのため、読み込んだ値をそのまま書き戻すということができませんでした。 とりあえず明示的にユニコードで読み書きするメソッドを追加してみました。 readのUTF-8版としてread_utf8、writeにはwrite_utf8というのを追加しています。
Attachments (1)
reg.patch
(5.35 KB, text/x-diff)
Index: registry.rb
===================================================================
--- registry.rb (revision 12112)
+++ registry.rb (working copy)
@@ -330,6 +330,48 @@
include Constants
include Enumerable
+ # UTF-16 to UTF-8
+ def self::u16tou8(u16str)
+ u8 = ''
+ sur = nil
+ u16str.unpack("S*").each {|x|
+ if sur
+ if (0xdc00..0xdfff).include?(x)
+ sur = (x - 0xdc00) + 0x10000
+ u8 << [x].pack("U")
+ sur = nil
+ else
+ raise "Invalid UTF-16"
+ end
+ else
+ if (0xd800..0xdbff).include?(x)
+ sur = (x - 0xd800) << 10
+ else
+ u8 << [x].pack("U")
+ end
+ end
+ }
+ u8.chop
+ end
+
+ # UTF-8 to UTF-16
+ def self::u8tou16(u8str)
+ ary = u8str.unpack("U*")
+ u16 =""
+ ary.each {|ucs|
+ case ucs
+ when 0..0xffff
+ u16 << [ucs].pack("S")
+ when 0x10000..0x10ffff
+ ucs -= 0x10000
+ h = (ucs >> 10) & 0x3ff + 0xd800
+ l = ucs & 0x3ff + 0xdc00
+ u16 << [h,l].pack("SS")
+ end
+ }
+ u16
+ end
+
#
# Error
#
@@ -382,6 +424,8 @@
%w/RegEnumKeyExA LLPPLLLP L/,
%w/RegQueryValueExA LPLPPP L/,
%w/RegSetValueExA LPLLPL L/,
+ %w/RegQueryValueExW LPLPPP L/,
+ %w/RegSetValueExW LPLLPL L/,
%w/RegDeleteValue LP L/,
%w/RegDeleteKey LP L/,
%w/RegFlushKey L L/,
@@ -453,10 +497,26 @@
[ unpackdw(type), data[0, unpackdw(size)] ]
end
+ def QueryValueW(hkey, name)
+ type = packdw(0)
+ size = packdw(0)
+ name = Win32::Registry::u8tou16(name)
+ check RegQueryValueExW.call(hkey, name, 0, type, 0, size)
+ data = '\x00\x00' * unpackdw(size)
+ check RegQueryValueExW.call(hkey, name, 0, type, data, size)
+ [ unpackdw(type), Win32::Registry::u16tou8(data[0, unpackdw(size)]) ]
+ end
+
def SetValue(hkey, name, type, data, size)
check RegSetValueExA.call(hkey, name, 0, type, data, size)
end
+ def SetValueW(hkey, name, type, data, size)
+ name = Win32::Registry::u8tou16(name)
+ data = Win32::Registry::u8tou16(data)
+ check RegSetValueExW.call(hkey, name, 0, type, data, data.size)
+ end
+
def DeleteValue(hkey, name)
check RegDeleteValue.call(hkey, name)
end
@@ -511,11 +571,11 @@
end
def self.wtime2time(wtime)
- Time.at((wtime - 116444736000000000) / 10000000)
+ Time.at((wtime - 116444736000000000).quo(10000000))
end
def self.time2wtime(time)
- time.to_i * 10000000 + 116444736000000000
+ time.to_i * 10000000 + time.usec * 10 + 116444736000000000
end
#
@@ -687,6 +747,21 @@
end
end
+ def read_utf8(name, *rtype)
+ type, data = API.QueryValueW(@hkey, name)
+ unless rtype.empty? or rtype.include?(type)
+ raise TypeError, "Type mismatch (expect #{rtype.inspect} but #{type} present)"
+ end
+ case type
+ when REG_SZ, REG_EXPAND_SZ
+ [ type, data ]
+ when REG_MULTI_SZ
+ [ type, data.split(/\0/) ]
+ else
+ read(name, *rtype)
+ end
+ end
+
def [](name, *rtype)
type, data = read(name, *rtype)
case type
@@ -702,6 +777,14 @@
def read_s(name)
read(name, REG_SZ)[1]
end
+
+ def read_s_utf8(name)
+ type, data = API.QueryValueW(@hkey, name)
+ if type != REG_SZ
+ raise TypeError, "Type mismatch (#{type} present)"
+ end
+ data
+ end
def read_s_expand(name)
type, data = read(name, REG_SZ, REG_EXPAND_SZ)
@@ -712,6 +795,15 @@
end
end
+ def read_s_expand_utf8(name)
+ type, data = API.QueryValueW(@hkey, name)
+ if type == REG_EXPAND_SZ
+ Registry.expand_environ(data)
+ else
+ data
+ end
+ end
+
def read_i(name)
read(name, REG_DWORD, REG_DWORD_BIG_ENDIAN, REG_QWORD)[1]
end
@@ -742,7 +834,30 @@
end
API.SetValue(@hkey, name, type, data, data.length)
end
-
+
+ def write_utf8(name, type, data)
+ case type
+ when REG_SZ, REG_EXPAND_SZ
+ API.SetValueW(@hkey, name, type, data, data.length)
+ when REG_MULTI_SZ
+ API.SetValueW(@hkey, name, type, data, data.length)
+ when REG_BINARY
+ data = data.to_s
+ API.SetValue(@hkey, name, type, data, data.length)
+ when REG_DWORD
+ data = API.packdw(data.to_i)
+ API.SetValue(@hkey, name, type, data, data.length)
+ when REG_DWORD_BIG_ENDIAN
+ data = [data.to_i].pack('N')
+ API.SetValue(@hkey, name, type, data, data.length)
+ when REG_QWORD
+ data = API.packqw(data.to_i)
+ API.SetValue(@hkey, name, type, data, data.length)
+ else
+ raise TypeError, "Unsupported type #{type}"
+ end
+ end
+
def []=(name, rtype, value = nil)
if value
write name, rtype, value
@@ -765,6 +880,10 @@
write name, REG_SZ, value.to_s
end
+ def write_s_utf8(name, value)
+ write_utf8 name, REG_SZ, value.to_s
+ end
+
def write_i(name, value)
write name, REG_DWORD, value.to_i
end