1# 2# tk/encodedstr.rb : Tk::EncodedString class 3# 4require 'tk' 5 6########################################### 7# string with Tcl's encoding 8########################################### 9module 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 187end 188