浏览代码

Invent a serialisation text format that works well with multiline values.

Beoran 9 年之前
父节点
当前提交
6180893f06
共有 6 个文件被更改,包括 270 次插入48 次删除
  1. 23 0
      data/script/account.rb
  2. 0 0
      data/script/character.rb
  3. 16 1
      data/script/main.rb
  4. 81 0
      data/script/serdes.rb
  5. 122 0
      data/script/sitef.rb
  6. 28 47
      woe.geany

+ 23 - 0
data/script/account.rb

@@ -0,0 +1,23 @@
+script "serdes.rb"
+
+
+class Account
+  include Serdes
+  
+  serdes_reader :id
+  serdes_reader :pass
+  serdes_reader :algo
+  
+  def initialize(nam, pas, alg = 'plain') 
+    @id   = nam
+    @algo = alg
+    @pass = pas
+  end
+
+end
+
+
+
+
+
+

+ 0 - 0
data/script/character.rb


+ 16 - 1
data/script/main.rb

@@ -4,8 +4,10 @@ script "log.rb"
 log "Main mruby script loaded OK."
 p Signal.constants
 
+script "sitef.rb"
 script "client.rb"
 script "timer.rb"
+script "account.rb"
 
 # Return an array of symbols of constants of klass that match value
 def const_syms(klass, value)
@@ -161,7 +163,7 @@ end
 
 start_timers
 
-
+=begin
 f = File.open("/account/B/Beoran/Beoran.account", "r");
 if f
   while (!f.eof?)
@@ -192,4 +194,17 @@ if f
   end
   f.close
 end
+=end
+
+rec = { :name => 'Dyon', :algo => 'plain', :pass => 'noyd8pass',
+:desc => "A buff, tanned man\n with blonde hair."
+} 
+recs = [ rec ]
+Sitef.save_filename('Dyon.test', recs);
+
+rrecs, rerrs = Sitef.load_filename('Dyon.test');
+p rrecs, rerrs
 
+a = Account.new('Dyon', 'noyd8pass')
+p a.id
+a.save

+ 81 - 0
data/script/serdes.rb

@@ -0,0 +1,81 @@
+
+class Dir
+  def self.mkdir_p(name)
+    sub   = ""
+    parts = name.split('/').reject { |e| e.empty? }
+    parts.each do | part |
+      sub <<  "/#{part}"
+      mkdir sub
+    end
+  end
+end
+
+
+
+# Module to help with serialization and deserialization of any type of data
+module Serdes
+  
+  module ClassMethods
+    def serdes_add_to_register(name)
+      @serder_register ||= []
+      @serder_register << name
+    end
+    
+    def serdes_reader(name)
+      serdes_add_to_register(name)
+      attr_reader(name)
+    end
+    
+    def serdes_writer(name)
+      serdes_add_to_register(name)
+      attr_writer(name)
+    end
+    
+    def serdes_accessor(name)
+      serdes_add_to_register(name)
+      attr_accessor(name)
+    end
+    
+    def serdes_register()
+      @serder_register ||= []
+      return @serder_register
+    end  
+  end
+  
+  # include callback, be sure to extend the class with the ClassMethods
+  def self.included(klass)
+    klass.extend(ClassMethods)
+  end
+  
+  def serdes_dir_name
+    top = self.class.to_s.gsub('::', '/').downcase
+    top << '/' 
+    top << self.id.to_s[0]
+    top << '/' 
+    top << self.id.to_s    
+    return top
+  end
+  
+  def serdes_file_name
+    top = self.id.to_s.dup    
+    top << '.'
+    top << self.class.to_s.gsub('::', '.').downcase
+    return top 
+  end
+
+  
+  def save
+    Dir.mkdir_p serdes_dir_name
+    data = {}
+    self.class.serdes_register.each do |name|
+      key = "#{name}" 
+      value = "#{self.send(name.to_sym)}"
+      data[key] = value
+    end
+    full_name = serdes_dir_name + '/' + serdes_file_name
+    Sitef.save_filename(full_name, [ data ] )
+  end
+  
+
+
+end

+ 122 - 0
data/script/sitef.rb

@@ -0,0 +1,122 @@
+
+# Sitef is a simple text format for serializing data to
+# It's intent is to be human readable and easy to 
+# use for multi line text.
+
+module Sitef
+  # All Sitef data is stored in files with one or more records.
+  # Records are separated by separated by at least 2 dashes on a line.
+  # Records contain key/value fields. The key starts in the first column
+  # with a : and is followed by a : the value starts after the second :
+  # A multiline key / value needs a key that starts with . and ends with .
+  # the end of the value is a  pair of dots .. by itself 
+  # Keys may not be nested, however, une could use spaces or dots, 
+  # or array indexes to emulate nexted keys. 
+  # A # at the start optionally after whitespace is a comment
+  # 
+  def self.parse_file(file)
+    lineno   = 0
+    results  = []
+    errors   = []
+    
+    record   = {}
+    key      = nil
+    value    = nil
+    until file.eof?
+      lineno     += 1 
+      line        = file.gets(256)
+      # XXX does eof? even work???
+      break if line.nil?
+      next if line.empty? 
+      # new record
+      if line[0,2] == '--' 
+        # Store last key used if any.
+        if key
+          record[key.downcase] = value.chomp
+          key = nil
+        end  
+        results << record
+        record = {}
+      elsif line[0] == '#'
+      # Comments start with #
+      elsif line[0] == ':'
+      # a key/value pair
+      key, value = line[1,line.size].split(':', 2)
+      record[key.downcase] = value.chomp
+      key = value = nil
+      elsif line[0, 2] == '..'
+      # end of multiline value 
+      record[key.downcase] = value.chomp
+      key = value = nil
+      elsif (line[0] == '.') && key.nil?
+      # Multiline key/value starts here (but is ignored 
+      # until .. is encountered)
+      key   = line[1, line.size]
+      value = ""
+      elsif key
+          # continue the value
+          value << line
+      else
+          # Not in a key, sntax error.
+          errors << "#{lineno}: Don't know how to process line"
+      end      
+    end
+    # Store last key used if any.
+    if key
+      record[key.downcase] = value.chomp
+    end  
+    # store last record 
+    results << record unless record.empty?
+    return results, errors
+  end  
+  
+  def self.load_filename(filename)
+    results , errors, warnings = nil, nil, nil;
+    file = File.open(filename, 'rt')
+    return nil, ["Could not open #{filename}"] unless file
+    begin 
+      results, errors = parse_file(file)
+    ensure
+      file.close
+    end
+    return results, errors
+  end
+  
+  def self.save_field(file, key, value)
+    sval = value.to_s
+    if sval["\n"]
+      file.puts(".#{key}\n")
+      file.puts(sval)
+      file.puts("\n..\n")
+    else
+      file.puts(":#{key}:#{sval}\n")
+    end
+  end
+  
+  def self.save_record(file, record)
+    record.each do | key, value |
+      save_field(file, key, value)
+    end
+  end
+
+  def self.save_file(file, records)
+    records.each do | record |
+      save_record(file, record)
+      file.puts("--\n")
+    end
+  end
+  
+  def self.save_filename(filename, records)
+    results , errors = nil, nil
+    file = File.open(filename, 'wt')
+    return nil, ["Could not open #{filename}"] unless file
+    begin 
+      results, errors = save_file(file, records)
+    ensure
+      file.close
+    end
+    return results, errors
+  end
+  
+end
+

+ 28 - 47
woe.geany

@@ -23,56 +23,37 @@ long_line_behaviour=1
 long_line_column=80
 
 [files]
-current_page=2
+current_page=16
 FILE_NAME_0=32;C;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fwoe%2Fsrc%2Fmain.c;0;2
 FILE_NAME_1=1652;C;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fwoe%2Fsrc%2Fcallrb.c;0;2
 FILE_NAME_2=9463;C;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fwoe%2Fsrc%2Ftoruby.c;0;2
-FILE_NAME_3=94;C;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fekq%2Ftest%2Ftest_monolog.c;0;2
-FILE_NAME_4=0;C;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fwork%2Fsrc%2Fsplix%2Fsrc%2Fbarg.c;0;2
-FILE_NAME_5=16838;C;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fwork%2Fsrc%2Fsplix%2Fsrc%2Fsplix.c;0;2
-FILE_NAME_6=12135;C;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fwoe%2Fsrc%2Fserver.c;0;2
-FILE_NAME_7=4816;C;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fwoe%2Fsrc%2Flibtelnet.c;0;2
-FILE_NAME_8=2640;C;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fwoe%2Fsrc%2Fclient.c;0;2
-FILE_NAME_9=158;C;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fwoe%2Fsrc%2Fconfig.c;0;2
-FILE_NAME_10=1302;C;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fwoe%2Finclude%2Fclient.h;0;2
-FILE_NAME_11=240;C;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fwoe%2Finclude%2Fconfig.h;0;2
-FILE_NAME_12=3599;C;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fwoe%2Finclude%2Fesh.h;0;2
-FILE_NAME_13=3217;C;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fwoe%2Fsrc%2Fesh.c;0;2
-FILE_NAME_14=264;None;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fwoe%2FTupfile;0;2
-FILE_NAME_15=1810;C;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fwoe%2Finclude%2Frh.h;0;2
-FILE_NAME_16=7445;C;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fwoe%2Finclude%2Ftr_macro.h;0;2
-FILE_NAME_17=1250;C;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fwoe%2Fsrc%2Frh.c;0;2
-FILE_NAME_18=2107;Ruby;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fwoe%2Fdata%2Fscript%2Fmain.rb;0;2
-FILE_NAME_19=137;Ruby;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fwoe%2Fdata%2Fscript%2Flog.rb;0;2
-FILE_NAME_20=578;Ruby;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fwoe%2Fdata%2Fscript%2Fclient.rb;0;2
-FILE_NAME_21=867;C;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fwoe%2Finclude%2Ftimer.h;0;2
-FILE_NAME_22=2864;C;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fwoe%2Fsrc%2Ftimer.c;0;2
-FILE_NAME_23=11192;C;0;EUTF-8;0;1;0;%2Fusr%2Finclude%2Ftime.h;0;2
-FILE_NAME_24=17639;C;0;EUTF-8;0;1;0;%2Fusr%2Flocal%2Finclude%2Fmruby.h;0;2
-FILE_NAME_25=4107;C;0;EUTF-8;0;1;0;%2Fusr%2Flocal%2Finclude%2Fmruby%2Fvalue.h;0;2
-FILE_NAME_26=0;C;0;EUTF-8;0;1;0;%2Fusr%2Flocal%2Finclude%2Fmruby%2Firep.h;0;2
-FILE_NAME_27=4903;C;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fekq%2Fsrc%2Frh.c;0;2
-FILE_NAME_28=1167;C;0;EUTF-8;0;1;0;%2Fusr%2Flocal%2Finclude%2Fmruby%2Fobject.h;0;2
-FILE_NAME_29=0;C;0;EUTF-8;0;1;0;%2Fusr%2Flocal%2Finclude%2Fmruby%2Fvariable.h;0;2
-FILE_NAME_30=2341;C;0;EUTF-8;0;1;0;%2Fusr%2Flocal%2Finclude%2Fmruby%2Fclass.h;0;2
-FILE_NAME_31=60;C;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fwoe%2Finclude%2Fmem.h;0;2
-FILE_NAME_32=426;C;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fwoe%2Finclude%2Fstate.h;0;2
-FILE_NAME_33=9297;C;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fmruby-matz%2Fsrc%2Fvariable.c;0;2
-FILE_NAME_34=17613;C;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fmruby-matz%2Fsrc%2Fclass.c;0;2
-FILE_NAME_35=4785;C;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fmruby-matz%2Fmrbgems%2Fmruby-sprintf%2Fsrc%2Fsprintf.c;0;2
-FILE_NAME_36=49330;C;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fmruby-matz%2Fsrc%2Fstring.c;0;2
-FILE_NAME_37=4154;C;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fmruby-matz%2Fmrbgems%2Fmruby-time%2Fsrc%2Ftime.c;0;2
-FILE_NAME_38=0;Markdown;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fmruby-matz%2Ftest%2FREADME.md;0;2
-FILE_NAME_39=0;Ruby;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fmruby-matz%2Ftest%2Ft%2Fobject.rb;0;2
-FILE_NAME_40=0;Ruby;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fmruby-matz%2Ftest%2Ft%2Fbasicobject.rb;0;2
-FILE_NAME_41=2520;Ruby;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fmruby-matz%2Ftest%2Ft%2Fsyntax.rb;0;2
-FILE_NAME_42=61;C;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fwoe%2Fsrc%2Fmonolog.c;0;2
-FILE_NAME_43=2307;C;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fwoe%2Finclude%2Flibtelnet.h;0;2
-FILE_NAME_44=1774;C;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fwoe%2Finclude%2Fmonolog.h;0;2
-FILE_NAME_45=235;C;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fwoe%2Finclude%2Fdynar.h;0;2
-FILE_NAME_46=103;C;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fwoe%2Fsrc%2Fmem.c;0;2
-FILE_NAME_47=5343;C;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fwoe%2Fsrc%2Fdynar.c;0;2
-FILE_NAME_48=2919;C;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fwoe%2Finclude%2Fserver.h;0;2
+FILE_NAME_3=12135;C;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fwoe%2Fsrc%2Fserver.c;0;2
+FILE_NAME_4=4816;C;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fwoe%2Fsrc%2Flibtelnet.c;0;2
+FILE_NAME_5=2640;C;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fwoe%2Fsrc%2Fclient.c;0;2
+FILE_NAME_6=158;C;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fwoe%2Fsrc%2Fconfig.c;0;2
+FILE_NAME_7=1302;C;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fwoe%2Finclude%2Fclient.h;0;2
+FILE_NAME_8=240;C;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fwoe%2Finclude%2Fconfig.h;0;2
+FILE_NAME_9=3599;C;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fwoe%2Finclude%2Fesh.h;0;2
+FILE_NAME_10=3217;C;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fwoe%2Fsrc%2Fesh.c;0;2
+FILE_NAME_11=264;None;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fwoe%2FTupfile;0;2
+FILE_NAME_12=1810;C;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fwoe%2Finclude%2Frh.h;0;2
+FILE_NAME_13=7445;C;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fwoe%2Finclude%2Ftr_macro.h;0;2
+FILE_NAME_14=1250;C;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fwoe%2Fsrc%2Frh.c;0;2
+FILE_NAME_15=2107;Ruby;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fwoe%2Fdata%2Fscript%2Fmain.rb;0;2
+FILE_NAME_16=842;Ruby;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fwoe%2Fdata%2Fscript%2Fserdes.rb;0;2
+FILE_NAME_17=137;Ruby;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fwoe%2Fdata%2Fscript%2Flog.rb;0;2
+FILE_NAME_18=578;Ruby;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fwoe%2Fdata%2Fscript%2Fclient.rb;0;2
+FILE_NAME_19=867;C;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fwoe%2Finclude%2Ftimer.h;0;2
+FILE_NAME_20=2864;C;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fwoe%2Fsrc%2Ftimer.c;0;2
+FILE_NAME_21=60;C;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fwoe%2Finclude%2Fmem.h;0;2
+FILE_NAME_22=426;C;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fwoe%2Finclude%2Fstate.h;0;2
+FILE_NAME_23=61;C;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fwoe%2Fsrc%2Fmonolog.c;0;2
+FILE_NAME_24=2307;C;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fwoe%2Finclude%2Flibtelnet.h;0;2
+FILE_NAME_25=1774;C;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fwoe%2Finclude%2Fmonolog.h;0;2
+FILE_NAME_26=235;C;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fwoe%2Finclude%2Fdynar.h;0;2
+FILE_NAME_27=103;C;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fwoe%2Fsrc%2Fmem.c;0;2
+FILE_NAME_28=5343;C;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fwoe%2Fsrc%2Fdynar.c;0;2
+FILE_NAME_29=2919;C;0;EUTF-8;0;1;0;%2Fhome%2Fbjorn%2Fsrc%2Fwoe%2Finclude%2Fserver.h;0;2
 
 [VTE]
 last_dir=/home/bjorn/src/woe