1 #
2 # tk/encodedstr.rb : Tk::EncodedString class
3 #
4 require 'tk'
5
6 ###########################################
7 # string with Tcl's encoding
8 ###########################################
9 module Tk
10 class EncodedString < String
11 Encoding = nil
12
13 def self.subst_utf_backslash(str)
14 # str.gsub(/\\u([0-9A-Fa-f]{1,4})/){[$1.hex].pack('U')}
15 TclTkLib._subst_UTF_backslash(str)
16 end
17 def self.utf_backslash(str)
18 self.subst_utf_backslash(str)
19 end
20
21 def self.subst_tk_backslash(str)
22 TclTkLib._subst_Tcl_backslash(str)
23 end
24
25 def self.utf_to_backslash_sequence(str)
26 str.unpack('U*').collect{|c|
27 if c <= 0xFF # ascii character
28 c.chr
29 else
30 format('\u%X', c)
31 end
32 }.join('')
33 end
34 def self.utf_to_backslash(str)
35 self.utf_to_backslash_sequence(str)
36 end
37
38 def self.to_backslash_sequence(str)
39 str.unpack('U*').collect{|c|
40 if c <= 0x1F # control character
41 case c
42 when 0x07; '\a'
43 when 0x08; '\b'
44 when 0x09; '\t'
45 when 0x0a; '\n'
46 when 0x0b; '\v'
47 when 0x0c; '\f'
48 when 0x0d; '\r'
49 else
50 format('\x%02X', c)
51 end
52 elsif c <= 0xFF # ascii character
53 c.chr
54 else
55 format('\u%X', c)
56 end
57 }.join('')
58 end
59
60 def self.new_with_utf_backslash(str, enc = nil)
61 self.new('', enc).replace(self.subst_utf_backslash(str))
62 end
63
64 def self.new_without_utf_backslash(str, enc = nil)
65 self.new('', enc).replace(str)
66 end
67
68 def initialize(str, enc = nil)
69 super(str)
70 # @encoding = ( enc ||
71 # ((self.class::Encoding)?
72 # self.class::Encoding : Tk.encoding_system) )
73 enc ||= (self.class::Encoding)?
74 self.class::Encoding :
75 ((Tk.encoding)? Tk.encoding : Tk.encoding_system)
76 if TkCore::WITH_ENCODING
77 unless encobj = Tk::Encoding::ENCODING_TABLE.get_obj(enc)
78 fail ArgumentError, "unsupported Tk encoding '#{enc}'"
79 end
80 self.force_encoding(encobj)
81 else
82 @encoding = enc
83 end
84 end
85
86 if TkCore::WITH_ENCODING
87 alias encoding_obj encoding
88 alias __encoding encoding
89 def encoding
90 Tk::Encoding::ENCODING_TABLE.get_name(super())
91 end
92 else
93 def encoding
94 @encoding
95 end
96 alias encoding_obj encoding
97 end
98
99 if TkCore::WITH_ENCODING
100 # wrapper methods for compatibility
101 alias __instance_variable_get instance_variable_get
102 alias __instance_variable_set instance_variable_set
103 alias __instance_eval instance_eval
104 alias __instance_variables instance_variables
105
106 def instance_variable_get(key)
107 if (key.to_s == '@encoding')
108 self.encoding
109 else
110 super(key)
111 end
112 end
113
114 def instance_variable_set(key, value)
115 if (key.to_s == '@encoding')
116 if value
117 self.force_encoding(value)
118 else
119 self.force_encoding(Tk::Encoding::UNKNOWN)
120 end
121 value
122 else
123 super(key, value)
124 end
125 end
126
127 def instance_eval(*args, &b)
128 old_enc = @encoding = self.encoding
129
130 ret = super(*args, &b)
131
132 if @encoding
133 if @encoding != old_enc
134 # modified by user
135 self.force_encoding(@encoding)
136 end
137 remove_instance_variable(:@encoding)
138 else
139 begin
140 remove_instance_variable(:@encoding)
141 # user sets to nil -> use current default
142 self.force_encoding(Tk.encoding)
143 rescue NameError
144 # removed by user -> ignore, because user don't use @encoding
145 end
146 end
147 ret
148 end
149 end
150
151 def instance_variables
152 ret = super()
153 ret << :@encoding # fake !!
154 ret
155 end
156 end
157 # def Tk.EncodedString(str, enc = nil)
158 # Tk::EncodedString.new(str, enc)
159 # end
160
161 ##################################
162
163 class BinaryString < EncodedString
164 Encoding = 'binary'.freeze
165 end
166 # def Tk.BinaryString(str)
167 # Tk::BinaryString.new(str)
168 # end
169
170 ##################################
171
172 class UTF8_String < EncodedString
173 Encoding = 'utf-8'.freeze
174 def self.new(str)
175 super(self.subst_utf_backslash(str))
176 end
177
178 def to_backslash_sequence
179 Tk::EncodedString.utf_to_backslash_sequence(self)
180 end
181 alias to_backslash to_backslash_sequence
182 end
183 # def Tk.UTF8_String(str)
184 # Tk::UTF8_String.new(str)
185 # end
186
187 end