1 # Copyright (C) 2002-2004 Kouichirou Eto, All rights reserved.
2 # libchise extension compatible library.
11 module ChiseValue; end
12 module TableAccessModule; end
18 def initialize(type=Berkeley_DB, loc=nil, subtype=0, modemask=0755)
20 loc = Config.instance.db_dir if loc.nil?
27 attr_reader :type, :location, :subtype, :modemask
30 @fdb[f] = FeatureTable.new(self, f) if @fdb[f].nil?
35 @cdb[ccs] = CCSTable.new(self, ccs) if @cdb[ccs].nil?
40 each_entry("character/feature") {|f| yield(f) }
44 each_entry("character/by_feature") {|f| yield(f) }
47 def load_feature(name, cid)
48 ft = get_feature(name)
53 def decode_char(ccs, code_point)
60 def each_entry(subdir)
61 dir = @location + subdir
63 next if f.to_s == "." || f.to_s == ".."
64 next if f.to_s =~ /\.txt\Z/
65 yield(f.unescape_win_filename.unescape.to_s)
71 def initialize(dir, cat, keytype, name, amask, mmask)
74 dbdir = dir + cat + keytype
76 #FileUtils.mkdir_p(dbdir.to_s) unless dbdir.directory?
78 path = dbdir + name.path.escape.escape_win_filename
79 #qp path.basename.to_s, amask, mmask
80 # if /test/ =~ path.to_s
84 if amask == BDB::RDONLY
85 #raise unless path.exist?
86 #raise unless FileTest.exist?(path.to_s)
87 v = FileTest.exist?(path.to_s)
91 # @db = BDB::Hash.open(path.to_s, nil, amask, mmask)
92 @db = BDB::Hash.open(path.to_s, nil, amask)
103 #p ["AttributeTable: close", @name]
109 def get(k) @db.get(k); end
110 def put(k, v) @db.put(k, v); end
112 def each() @db.each {|k, v| yield(k, v) } end
115 module TableAccessModule
129 def setup_db(writable=nil)
131 sync if @access & BDB::CREATE == 0
132 @access = BDB::CREATE
134 @access = BDB::RDONLY
140 @db = AttributeTable.new(@ds.location, @category, @keyvalue,
141 @name, @access, @ds.modemask)
152 include TableAccessModule
154 def initialize(ds, name)
155 @ds, @name = ds, name
156 @category, @keyvalue = "character", "feature"
162 return nil if @db.nil?
163 parse_value(@db.get(format_char_id(cid)))
166 def set_value(cid, value)
168 raise "@db is nil." if @db.nil?
169 @db.put(format_char_id(cid), value)
174 raise "@db is nil." if @db.nil?
176 yield(parse_c_string(k), v)
183 include TableAccessModule
185 def initialize(ds, name)
186 @ds, @name = ds, name
187 @category, @keyvalue = "character", "by_feature"
191 def decode(code_point)
193 return nil if @db.nil?
194 parse_c_string(@db.get(code_point.to_s))
197 def set_decoded_char(code_point, cid)
199 raise "@db is nil." if @db.nil?
200 @db.put(code_point.to_s, format_char_id(cid))
205 raise "@db is nil." if @db.nil?
207 yield(parse_value(k), parse_c_string(v))
215 #return v if v.kind_of?(Integer)
216 return v.to_i if /\A\d+\Z/ =~ v # number?
217 return $1 if /\A"(.+)"\Z/ =~ v # remove surrounding "
218 #return v.sub(/\A\?/, "") if v =~ /\A\?/ # remove ? in the head
219 #return parse_sexp(v) if v =~ /\A\(.+\)\Z/ # parse sexp # not yet
223 def parse_c_string(str)
224 return nil if str.nil?
231 raise unless 2 <= len && c == ?\?
247 return c & (0x80 | 0x1F)
273 if (counter + 2 <= len)
274 (0...counter).each {|j|
275 cid = (cid << 6) | (str[j + i] & 0x3F)
283 def format_char_id(cid)
285 when ?\t then return "?\t"
286 when ?\n then return "?\n"
287 when ?\r then return "?\r"
288 when 0x1C then return "?\^\\"
292 return "?\\^"+(?@+cid).chr
293 elsif (cid == ?\s) || (cid == ?\") ||
294 (cid == ?\#) || (cid == ?\') ||
295 (cid == ?\() || (cid == ?\)) ||
296 (cid == ?\,) || (cid == ?\.) ||
297 (cid == ?\;) || (cid == ?\?) ||
298 (cid == ?\[) || (cid == ?\\) ||
299 (cid == ?\]) || (cid == ?\`)
307 dest += (((cid + ?@) >> 6) | 0xC0).chr
308 dest += (((cid + ?@) & 0x3F) | 0x80).chr
312 dest[1] = (cid >> 6) | 0xC0
313 dest[2] = (cid & 0x3F) | 0x80
315 elsif (cid <= 0xFFFF)
317 dest[1] = (cid >> 12) | 0xE0
318 dest[2] = ((cid >> 6) & 0x3F) | 0x80
319 dest[3] = (cid & 0x3F) | 0x80
321 elsif (cid <= 0x1FFFFF)
323 dest[1] = (cid >> 18) | 0xF0
324 dest[2] = ((cid >> 12) & 0x3F) | 0x80
325 dest[3] = ((cid >> 6) & 0x3F) | 0x80
326 dest[4] = (cid & 0x3F) | 0x80
328 elsif (cid <= 0x3FFFFFF)
330 dest[1] = (cid >> 24) | 0xF8
331 dest[2] = ((cid >> 18) & 0x3F) | 0x80
332 dest[3] = ((cid >> 12) & 0x3F) | 0x80
333 dest[4] = ((cid >> 6) & 0x3F) | 0x80
334 dest[5] = (cid & 0x3F) | 0x80
338 dest[1] = (cid >> 30) | 0xFC
339 dest[2] = ((cid >> 24) & 0x3F) | 0x80
340 dest[3] = ((cid >> 18) & 0x3F) | 0x80
341 dest[4] = ((cid >> 12) & 0x3F) | 0x80
342 dest[5] = ((cid >> 6) & 0x3F) | 0x80
343 dest[6] = (cid & 0x3F) | 0x80