update.
[chise/ruby.git] / chise / libchise_r.rb
index 42954c5..525d6c2 100755 (executable)
@@ -11,13 +11,27 @@ module CHISE
   module ChiseValue; end
   module TableAccessModule; end
 
-  class DataSource
+  module EachEntryModule
+    def each_entry(subdir)
+      #dir = @location + subdir
+      dir = DataSource::DB_DIR.path + subdir
+      dir.each_entry {|f|
+       next if f.to_s == "." || f.to_s == ".."
+       next if f.to_s =~ /\.txt\Z/
+       yield(f.unescape_win_filename.unescape.to_s)
+      }
+    end
+  end
+
+  class DataSource_R
     NONE = 0
     Berkeley_DB = 1
+    #DB_DIR = "/cygdrive/c/chise/chise-db"
+    DB_DIR = CHISE::DB_DIR
 
-    def initialize(type=Berkeley_DB, loc=nil, subtype=0, modemask=0755)
+    def initialize(type=Berkeley_DB, loc=DB_DIR, subtype=0, modemask=0755)
       @type = type
-      loc = Config.instance.db_dir if loc.nil?
+      #loc = Config.instance.db_dir if loc.nil?
       @location = loc.path
       @subtype = subtype
       @modemask = modemask
@@ -26,66 +40,43 @@ module CHISE
     end
     attr_reader :type, :location, :subtype, :modemask
 
+    def close() end
+
     def get_feature(f)
-      @fdb[f] = FeatureTable.new(self, f) if @fdb[f].nil?
+      @fdb[f] = Feature.new(self, f) if @fdb[f].nil?
       @fdb[f]
     end
 
     def get_ccs(ccs)
-      @cdb[ccs] = CCSTable.new(self, ccs) if @cdb[ccs].nil?
+      @cdb[ccs] = CCS.new(self, ccs) if @cdb[ccs].nil?
       @cdb[ccs]
     end
 
-    def each_feature
-      each_entry("character/feature") {|f| yield(f) }
-    end
-
-    def each_ccs
-      each_entry("character/by_feature") {|f| yield(f) }
+    def each_feature_name
+      each_entry("character/feature") {|f| yield f }
     end
 
-    def load_feature(name, cid)
-      ft = get_feature(name)
-      return nil if ft.nil?
-      ft.get_value(cid)
+    def load_feature(cid, name)
+      feature = get_feature(name)
+      return nil if feature.nil?
+      feature.get_value(cid)
     end
 
     def decode_char(ccs, code_point)
-      ct = get_ccs(ccs)
-      return nil if ct.nil?
-      ct.decode(code_point)
+      ccst = get_ccs(ccs)
+      return nil if ccst.nil?
+      ccst.decode(code_point)
     end
 
     private
-    def each_entry(subdir)
-      dir = @location + subdir
-      dir.each_entry {|f|
-       next if f.to_s == "." || f.to_s == ".."
-       next if f.to_s =~ /\.txt\Z/
-       yield(f.unescape_win_filename.unescape.to_s)
-      }
-    end
+    include EachEntryModule
   end
 
   class AttributeTable
     def initialize(dir, cat, keytype, name, amask, mmask)
-      @name = name
-
-      dbdir  = dir + cat + keytype
-      #qp dbdir.to_s
-      #FileUtils.mkdir_p(dbdir.to_s) unless dbdir.directory?
-      #qp dbdir.to_s, "2"
-      path = dbdir + name.path.escape.escape_win_filename
-      #qp path.basename.to_s, amask, mmask
-#      if /test/ =~ path.to_s
-#      qp path.to_s, amask
-#      end
-
-      if amask == BDB::RDONLY
-       raise unless path.exist?
-      end
-#     @db = BDB::Hash.open(path.to_s, nil, amask, mmask)
-      @db = BDB::Hash.open(path.to_s, nil, amask)
+      @dir, @cat, @keytype, @name, @amask, @mmask = dir, cat, keytype, name, amask, mmask
+      @db = nil
+      setup_db
       at_exit {
        close
       }
@@ -96,16 +87,29 @@ module CHISE
       begin
        @db.sync
        @db.close
-       #p ["AttributeTable: close", @name]
+       # @db = nil
       rescue => e
-       #p e
+       p e
       end
     end
 
-    def get(k)    @db.get(k);    end
-    def put(k, v) @db.put(k, v); end
+    def get(k)    setup_db; @db.get(k);    end
+    def put(k, v) setup_db; @db.put(k, v); end
 
-    def each() @db.each {|k, v| yield(k, v) } end
+    def each() setup_db; @db.each {|k, v| yield(k, v) } end
+
+    private
+    def setup_db
+      return if @db
+      dbdir  = @dir + @cat + @keytype
+      path = dbdir + @name.path.escape.escape_win_filename
+      #TODO: should make dir.
+      if @amask == BDB::RDONLY
+       raise unless FileTest.exist?(path.to_s)
+      end
+      #qp path.to_s
+      @db = BDB::Hash.open(path.to_s, nil, @amask)
+    end
   end
 
   module TableAccessModule
@@ -117,32 +121,44 @@ module CHISE
     def sync
       @db.close if @db
       reset
+      true
     end
     alias close sync
 
-    private
     def setup_db(writable=nil)
       if writable
        sync if @access & BDB::CREATE == 0
-       @access = BDB::CREATE
+       access = BDB::CREATE
       else
-       @access = BDB::RDONLY
+       access = BDB::RDONLY
       end
 
-      return if @db
+      return true if @db
 
       begin
-       @db = AttributeTable.new(@ds.location, @category, @keyvalue,
-                                @name, @access, @ds.modemask)
+       db_dir = @ds.location
+       modemask = @ds.modemask
+      rescue
+       db_dir = CHISE::DataSource::DB_DIR.path
+       modemask = 0755
+      end
+
+      #qp db_dir, @category, @keyvalue, @name, @access, modemask
+      begin
+       @db = AttributeTable.new(db_dir, @category, @keyvalue,
+                                @name, access, modemask)
+       return false if @db.nil?
+       @access = access
       rescue => e
-       #qp e
+       #puts $!, $@
        @db = nil
+       return false
       end
-      #raise if @db.nil?
+      true
     end
   end
 
-  class FeatureTable
+  class Feature_R
     include ChiseValue
     include TableAccessModule
 
@@ -155,16 +171,17 @@ module CHISE
     def get_value(cid)
       setup_db
       return nil if @db.nil?
-      parse_value(@db.get(format_char_id(cid)))
+      @db.get(format_char_id(cid))
     end
 
     def set_value(cid, value)
       setup_db(true)
       raise "@db is nil." if @db.nil?
       @db.put(format_char_id(cid), value)
+      true
     end
 
-    def each
+    def each_char
       setup_db
       raise "@db is nil." if @db.nil?
       @db.each {|k, v|
@@ -173,7 +190,7 @@ module CHISE
     end
   end
 
-  class CCSTable
+  class CCS_R
     include ChiseValue
     include TableAccessModule
 
@@ -183,6 +200,14 @@ module CHISE
       reset
     end
 
+    def set(code_point, cid)
+      setup_db(true)
+      raise "@db is nil." if @db.nil?
+      parse_c_string(@db.get(code_point.to_s))
+      @db.put(code_point.to_s, format_char_id(cid))
+      true
+    end
+
     def decode(code_point)
       setup_db
       return nil if @db.nil?
@@ -195,26 +220,20 @@ module CHISE
       @db.put(code_point.to_s, format_char_id(cid))
     end
 
-    def each
+    def each_char
       setup_db
-      raise "@db is nil." if @db.nil?
-      @db.each {|k, v|
-       yield(parse_value(k), parse_c_string(v))
+      if @db.nil?
+       #raise "@db is nil."+@name
+       p "@db is nil."+@name
+       return nil
+      end
+      @db.each {|code_point, cid|
+       yield(code_point, parse_c_string(cid))
       }
     end
   end
 
   module ChiseValue
-    def parse_value(v)
-      return v if v.nil?
-      #return v if v.kind_of?(Integer)
-      return v.to_i if /\A\d+\Z/ =~ v # number?
-      return $1 if /\A"(.+)"\Z/ =~ v # remove surrounding "
-      #return v.sub(/\A\?/, "") if v =~ /\A\?/ # remove ? in the head
-      #return parse_sexp(v) if v =~ /\A\(.+\)\Z/ # parse sexp # not yet
-      v
-    end
-
     def parse_c_string(str)
       return nil if str.nil?