aboutsummaryrefslogtreecommitdiffstats
path: root/lib/xsd
diff options
context:
space:
mode:
authornahi <nahi@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2004-07-03 13:33:20 +0000
committernahi <nahi@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2004-07-03 13:33:20 +0000
commitdf731e37a1953755edfedd1462995fa824ca22bf (patch)
tree38a98e1b29b3784843ad079fa003790c8f352f58 /lib/xsd
parent0d6fa996d9e842fe435308cef68df06bc3596a76 (diff)
downloadruby-df731e37a1953755edfedd1462995fa824ca22bf.tar.gz
* added files:
* lib/soap/header/* * lib/soap/rpc/httpserver.rb * lib/wsdl/soap/cgiStubCreator.rb * lib/wsdl/soap/classDefCreator.rb * lib/wsdl/soap/classDefCreatorSupport.rb * lib/wsdl/soap/clientSkeltonCreator.rb * lib/wsdl/soap/driverCreator.rb * lib/wsdl/soap/mappingRegistryCreator.rb * lib/wsdl/soap/methodDefCreator.rb * lib/wsdl/soap/servantSkeltonCreator.rb * lib/wsdl/soap/standaloneServerStubCreator.rb * lib/wsdl/xmlSchema/enumeration.rb * lib/wsdl/xmlSchema/simpleRestriction.rb * lib/wsdl/xmlSchema/simpleType.rb * lib/xsd/codegen/* * lib/xsd/codegen.rb * sample/soap/authheader/* * sample/soap/raa2.4/* * sample/soap/ssl/* * sample/soap/swa/* * sample/soap/whois.rb * sample/wsdl/raa2.4/* * test/soap/header/* * test/soap/ssl/* * test/soap/struct/* * test/soap/swa/* * test/soap/wsdlDriver/* * test/wsdl/multiplefault.wsdl * test/wsdl/simpletype/* * test/wsdl/test_multiplefault.rb * modified files: * lib/soap/baseData.rb * lib/soap/element.rb * lib/soap/generator.rb * lib/soap/netHttpClient.rb * lib/soap/parser.rb * lib/soap/property.rb * lib/soap/soap.rb * lib/soap/streamHandler.rb * lib/soap/wsdlDriver.rb * lib/soap/wsdlDriver.rb * lib/soap/encodingstyle/handler.rb * lib/soap/encodingstyle/literalHandler.rb * lib/soap/encodingstyle/soapHandler.rb * lib/soap/mapping/factory.rb * lib/soap/mapping/mapping.rb * lib/soap/mapping/registry.rb * lib/soap/mapping/rubytypeFactory.rb * lib/soap/mapping/wsdlRegistry.rb * lib/soap/rpc/cgistub.rb * lib/soap/rpc/driver.rb * lib/soap/rpc/proxy.rb * lib/soap/rpc/router.rb * lib/soap/rpc/soaplet.rb * lib/soap/rpc/standaloneServer.rb * lib/wsdl/data.rb * lib/wsdl/definitions.rb * lib/wsdl/operation.rb * lib/wsdl/parser.rb * lib/wsdl/soap/definitions.rb * lib/wsdl/xmlSchema/complexContent.rb * lib/wsdl/xmlSchema/complexType.rb * lib/wsdl/xmlSchema/data.rb * lib/wsdl/xmlSchema/parser.rb * lib/wsdl/xmlSchema/schema.rb * lib/xsd/datatypes.rb * lib/xsd/qname.rb * sample/soap/sampleStruct/server.rb * sample/wsdl/amazon/AmazonSearch.rb * sample/wsdl/amazon/AmazonSearchDriver.rb * test/soap/test_property.rb * test/soap/calc/test_calc_cgi.rb * test/wsdl/test_emptycomplextype.rb * summary * add SOAP Header mustUnderstand support. * add HTTP client SSL configuration and Cookies support (works completely with http-access2). * add header handler for handling sending/receiving SOAP Header. * map Ruby's anonymous Struct to common SOAP Struct in SOAP Object Model. it caused error. * add WSDL simpleType support to restrict lexical value space. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@6565 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'lib/xsd')
-rw-r--r--lib/xsd/codegen.rb12
-rw-r--r--lib/xsd/codegen/classdef.rb203
-rw-r--r--lib/xsd/codegen/commentdef.rb34
-rw-r--r--lib/xsd/codegen/gensupport.rb112
-rw-r--r--lib/xsd/codegen/methoddef.rb63
-rw-r--r--lib/xsd/codegen/moduledef.rb191
-rw-r--r--lib/xsd/datatypes.rb296
-rw-r--r--lib/xsd/qname.rb9
8 files changed, 764 insertions, 156 deletions
diff --git a/lib/xsd/codegen.rb b/lib/xsd/codegen.rb
new file mode 100644
index 0000000000..d820ebf1f2
--- /dev/null
+++ b/lib/xsd/codegen.rb
@@ -0,0 +1,12 @@
+# XSD4R - Generating code library
+# Copyright (C) 2004 NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
+
+# This program is copyrighted free software by NAKAMURA, Hiroshi. You can
+# redistribute it and/or modify it under the same terms of Ruby's license;
+# either the dual license version in 2003, or any later version.
+
+
+require 'xsd/codegen/gensupport'
+require 'xsd/codegen/moduledef'
+require 'xsd/codegen/classdef'
+require 'xsd/codegen/methoddef'
diff --git a/lib/xsd/codegen/classdef.rb b/lib/xsd/codegen/classdef.rb
new file mode 100644
index 0000000000..8f72e95efd
--- /dev/null
+++ b/lib/xsd/codegen/classdef.rb
@@ -0,0 +1,203 @@
+# XSD4R - Generating class definition code
+# Copyright (C) 2004 NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
+
+# This program is copyrighted free software by NAKAMURA, Hiroshi. You can
+# redistribute it and/or modify it under the same terms of Ruby's license;
+# either the dual license version in 2003, or any later version.
+
+
+require 'xsd/codegen/gensupport'
+require 'xsd/codegen/moduledef'
+require 'xsd/codegen/methoddef'
+
+
+module XSD
+module CodeGen
+
+
+class ClassDef < ModuleDef
+ include GenSupport
+
+ def initialize(name, baseclass = nil)
+ super(name)
+ @baseclass = baseclass
+ @classvar = []
+ @attrdef = []
+ end
+
+ def def_classvar(var, value)
+ var = var.sub(/\A@@/, "")
+ unless safevarname?(var)
+ raise ArgumentError.new("#{var} seems to be unsafe")
+ end
+ @classvar << [var, value]
+ end
+
+ def def_attr(attrname, writable = true, varname = nil)
+ unless safevarname?(varname || attrname)
+ raise ArgumentError.new("#{varname || attrname} seems to be unsafe")
+ end
+ @attrdef << [attrname, writable, varname]
+ end
+
+ def dump
+ buf = ""
+ unless @requirepath.empty?
+ buf << dump_requirepath
+ end
+ buf << dump_emptyline unless buf.empty?
+ package = @name.split(/::/)[0..-2]
+ buf << dump_package_def(package) unless package.empty?
+ buf << dump_comment if @comment
+ buf << dump_class_def
+ spacer = false
+ unless @classvar.empty?
+ spacer = true
+ buf << dump_classvar
+ end
+ unless @const.empty?
+ buf << dump_emptyline if spacer
+ spacer = true
+ buf << dump_const
+ end
+ unless @code.empty?
+ buf << dump_emptyline if spacer
+ spacer = true
+ buf << dump_code
+ end
+ unless @attrdef.empty?
+ buf << dump_emptyline if spacer
+ spacer = true
+ buf << dump_attributes
+ end
+ unless @methoddef.empty?
+ buf << dump_emptyline if spacer
+ spacer = true
+ buf << dump_methods
+ end
+ buf << dump_class_def_end
+ buf << dump_package_def_end(package) unless package.empty?
+ buf
+ end
+
+private
+
+ def dump_class_def
+ name = @name.to_s.split(/::/)
+ if @baseclass
+ format("class #{name.last} < #{@baseclass}")
+ else
+ format("class #{name.last}")
+ end
+ end
+
+ def dump_class_def_end
+ str = format("end")
+ end
+
+ def dump_classvar
+ dump_static(
+ @classvar.collect { |var, value|
+ %Q(@@#{var.sub(/^@@/, "")} = #{dump_value(value)})
+ }.join("\n")
+ )
+ end
+
+ def dump_attributes
+ str = ""
+ @attrdef.each do |attrname, writable, varname|
+ varname ||= attrname
+ if attrname == varname
+ str << format(dump_accessor(attrname, writable), 2)
+ end
+ end
+ @attrdef.each do |attrname, writable, varname|
+ varname ||= attrname
+ if attrname != varname
+ str << "\n" unless str.empty?
+ str << format(dump_attribute(attrname, writable, varname), 2)
+ end
+ end
+ str
+ end
+
+ def dump_accessor(attrname, writable)
+ if writable
+ "attr_accessor :#{attrname}"
+ else
+ "attr_reader :#{attrname}"
+ end
+ end
+
+ def dump_attribute(attrname, writable, varname)
+ str = nil
+ mr = MethodDef.new(attrname)
+ mr.definition = "@#{varname}"
+ str = mr.dump
+ if writable
+ mw = MethodDef.new(attrname + "=", 'value')
+ mw.definition = "@#{varname} = value"
+ str << "\n" + mw.dump
+ end
+ str
+ end
+end
+
+
+end
+end
+
+
+if __FILE__ == $0
+ require 'xsd/codegen/classdef'
+ include XSD::CodeGen
+ c = ClassDef.new("Foo::Bar::HobbitName", String)
+ c.def_require("foo/bar")
+ c.comment = <<-EOD
+ foo
+ bar
+ baz
+ EOD
+ c.def_const("FOO", 1)
+ c.def_classvar("@@foo", "var".dump)
+ c.def_classvar("baz", "1".dump)
+ c.def_attr("Foo", true, "foo")
+ c.def_attr("bar")
+ c.def_attr("baz", true)
+ c.def_attr("Foo2", true, "foo2")
+ c.def_attr("foo3", false, "foo3")
+ c.def_method("foo") do
+ <<-EOD
+ foo.bar = 1
+\tbaz.each do |ele|
+\t ele
+ end
+ EOD
+ end
+ c.def_method("baz", "qux") do
+ <<-EOD
+ [1, 2, 3].each do |i|
+ p i
+ end
+ EOD
+ end
+
+ m = MethodDef.new("qux", "quxx", "quxxx") do
+ <<-EOD
+ p quxx + quxxx
+ EOD
+ end
+ m.comment = "hello world\n123"
+ c.add_method(m)
+ c.def_code <<-EOD
+ Foo.new
+ Bar.z
+ EOD
+ c.def_code <<-EOD
+ Foo.new
+ Bar.z
+ EOD
+ c.def_privatemethod("foo", "baz", "*arg", "&block")
+
+ puts c.dump
+end
diff --git a/lib/xsd/codegen/commentdef.rb b/lib/xsd/codegen/commentdef.rb
new file mode 100644
index 0000000000..f98fade57d
--- /dev/null
+++ b/lib/xsd/codegen/commentdef.rb
@@ -0,0 +1,34 @@
+# XSD4R - Generating comment definition code
+# Copyright (C) 2004 NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
+
+# This program is copyrighted free software by NAKAMURA, Hiroshi. You can
+# redistribute it and/or modify it under the same terms of Ruby's license;
+# either the dual license version in 2003, or any later version.
+
+
+require 'xsd/codegen/gensupport'
+
+
+module XSD
+module CodeGen
+
+
+module CommentDef
+ include GenSupport
+
+ attr_accessor :comment
+
+private
+
+ def dump_comment
+ if /^#/ =~ @comment
+ format(@comment)
+ else
+ format(@comment).gsub(/^/, "# ")
+ end
+ end
+end
+
+
+end
+end
diff --git a/lib/xsd/codegen/gensupport.rb b/lib/xsd/codegen/gensupport.rb
new file mode 100644
index 0000000000..df90550fa0
--- /dev/null
+++ b/lib/xsd/codegen/gensupport.rb
@@ -0,0 +1,112 @@
+# XSD4R - Code generation support
+# Copyright (C) 2004 NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
+
+# This program is copyrighted free software by NAKAMURA, Hiroshi. You can
+# redistribute it and/or modify it under the same terms of Ruby's license;
+# either the dual license version in 2003, or any later version.
+
+
+module XSD
+module CodeGen
+
+
+module GenSupport
+ def capitalize(target)
+ target.sub(/^([a-z])/) { $1.tr!('[a-z]', '[A-Z]') }
+ end
+ module_function :capitalize
+
+ def uncapitalize(target)
+ target.sub(/^([A-Z])/) { $1.tr!('[A-Z]', '[a-z]') }
+ end
+ module_function :uncapitalize
+
+ def safeconstname(name)
+ safename = name.scan(/[a-zA-Z0-9_]+/).collect { |ele|
+ GenSupport.capitalize(ele)
+ }.join
+ unless /^[A-Z]/ =~ safename
+ safename = "C_#{safename}"
+ end
+ safename
+ end
+ module_function :safeconstname
+
+ def safeconstname?(name)
+ /\A[A-Z][a-zA-Z0-9_]*\z/ =~ name
+ end
+ module_function :safeconstname?
+
+ def safemethodname(name)
+ safevarname(name)
+ end
+ module_function :safemethodname
+
+ def safemethodname?(name)
+ /\A[a-zA-Z_][a-zA-Z0-9_]*[=!?]?\z/ =~ name
+ end
+ module_function :safemethodname?
+
+ def safevarname(name)
+ safename = name.scan(/[a-zA-Z0-9_]+/).join('_')
+ safename = uncapitalize(safename)
+ unless /^[a-z]/ =~ safename
+ safename = "m_#{safename}"
+ end
+ safename
+ end
+ module_function :safevarname
+
+ def safevarname?(name)
+ /\A[a-z_][a-zA-Z0-9_]*\z/ =~ name
+ end
+ module_function :safevarname?
+
+ def format(str, indent = nil)
+ str = trim_eol(str)
+ str = trim_indent(str)
+ if indent
+ str.gsub(/^/, " " * indent)
+ else
+ str
+ end
+ end
+
+private
+
+ def trim_eol(str)
+ str.collect { |line|
+ line.sub(/\r?\n$/, "") + "\n"
+ }.join
+ end
+
+ def trim_indent(str)
+ indent = nil
+ str = str.collect { |line| untab(line) }.join
+ str.each do |line|
+ head = line.index(/\S/)
+ if !head.nil? and (indent.nil? or head < indent)
+ indent = head
+ end
+ end
+ return str unless indent
+ str.collect { |line|
+ line.sub(/^ {0,#{indent}}/, "")
+ }.join
+ end
+
+ def untab(line, ts = 8)
+ while pos = line.index(/\t/)
+ line = line.sub(/\t/, " " * (ts - (pos % ts)))
+ end
+ line
+ end
+
+ def dump_emptyline
+ "\n"
+ end
+end
+
+
+end
+end
diff --git a/lib/xsd/codegen/methoddef.rb b/lib/xsd/codegen/methoddef.rb
new file mode 100644
index 0000000000..797a4f024e
--- /dev/null
+++ b/lib/xsd/codegen/methoddef.rb
@@ -0,0 +1,63 @@
+# XSD4R - Generating method definition code
+# Copyright (C) 2004 NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
+
+# This program is copyrighted free software by NAKAMURA, Hiroshi. You can
+# redistribute it and/or modify it under the same terms of Ruby's license;
+# either the dual license version in 2003, or any later version.
+
+
+require 'xsd/codegen/gensupport'
+require 'xsd/codegen/commentdef'
+
+
+module XSD
+module CodeGen
+
+
+class MethodDef
+ include GenSupport
+ include CommentDef
+
+ attr_accessor :definition
+
+ def initialize(name, *params)
+ unless safemethodname?(name)
+ raise ArgumentError.new("#{name} seems to be unsafe")
+ end
+ @name = name
+ @params = params
+ @comment = nil
+ @definition = yield if block_given?
+ end
+
+ def dump
+ buf = ""
+ buf << dump_comment if @comment
+ buf << dump_method_def
+ buf << dump_definition if @definition
+ buf << dump_method_def_end
+ buf
+ end
+
+private
+
+ def dump_method_def
+ if @params.empty?
+ format("def #{@name}")
+ else
+ format("def #{@name}(#{@params.join(", ")})")
+ end
+ end
+
+ def dump_method_def_end
+ format("end")
+ end
+
+ def dump_definition
+ format(@definition, 2)
+ end
+end
+
+
+end
+end
diff --git a/lib/xsd/codegen/moduledef.rb b/lib/xsd/codegen/moduledef.rb
new file mode 100644
index 0000000000..dc2746b2ee
--- /dev/null
+++ b/lib/xsd/codegen/moduledef.rb
@@ -0,0 +1,191 @@
+# XSD4R - Generating module definition code
+# Copyright (C) 2004 NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
+
+# This program is copyrighted free software by NAKAMURA, Hiroshi. You can
+# redistribute it and/or modify it under the same terms of Ruby's license;
+# either the dual license version in 2003, or any later version.
+
+
+require 'xsd/codegen/gensupport'
+require 'xsd/codegen/methoddef'
+require 'xsd/codegen/commentdef'
+
+
+module XSD
+module CodeGen
+
+
+class ModuleDef
+ include GenSupport
+ include CommentDef
+
+ def initialize(name)
+ @name = name
+ @comment = nil
+ @const = []
+ @code = []
+ @requirepath = []
+ @methoddef = []
+ end
+
+ def def_require(path)
+ @requirepath << path
+ end
+
+ def def_const(const, value)
+ unless safeconstname?(const)
+ raise ArgumentError.new("#{const} seems to be unsafe")
+ end
+ @const << [const, value]
+ end
+
+ def def_code(code)
+ @code << code
+ end
+
+ def def_method(name, *params)
+ add_method(MethodDef.new(name, *params) { yield if block_given? }, :public)
+ end
+ alias def_publicmethod def_method
+
+ def def_protectedmethod(name, *params)
+ add_method(MethodDef.new(name, *params) { yield if block_given? },
+ :protected)
+ end
+
+ def def_privatemethod(name, *params)
+ add_method(MethodDef.new(name, *params) { yield if block_given? }, :private)
+ end
+
+ def add_method(m, visibility = :public)
+ @methoddef << [visibility, m]
+ end
+
+ def dump
+ buf = ""
+ unless @requirepath.empty?
+ buf << dump_requirepath
+ end
+ buf << dump_emptyline unless buf.empty?
+ package = @name.split(/::/)[0..-2]
+ buf << dump_package_def(package) unless package.empty?
+ buf << dump_comment if @comment
+ buf << dump_module_def
+ spacer = false
+ unless @const.empty?
+ buf << dump_emptyline if spacer
+ spacer = true
+ buf << dump_const
+ end
+ unless @code.empty?
+ buf << dump_emptyline if spacer
+ spacer = true
+ buf << dump_code
+ end
+ unless @methoddef.empty?
+ buf << dump_emptyline if spacer
+ spacer = true
+ buf << dump_methods
+ end
+ buf << dump_module_def_end
+ buf << dump_package_def_end(package) unless package.empty?
+ buf
+ end
+
+private
+
+ def dump_requirepath
+ format(
+ @requirepath.collect { |path|
+ %Q(require '#{path}')
+ }.join("\n")
+ )
+ end
+
+ def dump_const
+ dump_static(
+ @const.sort.collect { |var, value|
+ %Q(#{var} = #{dump_value(value)})
+ }.join("\n")
+ )
+ end
+
+ def dump_code
+ dump_static(@code.join("\n"))
+ end
+
+ def dump_static(str)
+ format(str, 2)
+ end
+
+ def dump_methods
+ methods = {}
+ @methoddef.each do |visibility, method|
+ (methods[visibility] ||= []) << method
+ end
+ str = ""
+ [:public, :protected, :private].each do |visibility|
+ if methods[visibility]
+ str << "\n" unless str.empty?
+ str << visibility.to_s << "\n\n" unless visibility == :public
+ str << methods[visibility].collect { |m| format(m.dump, 2) }.join("\n")
+ end
+ end
+ str
+ end
+
+ def dump_value(value)
+ if value.respond_to?(:to_src)
+ value.to_src
+ else
+ value
+ end
+ end
+
+ def dump_package_def(package)
+ format(package.collect { |ele| "module #{ele}" }.join("; ")) + "\n\n"
+ end
+
+ def dump_package_def_end(package)
+ "\n\n" + format(package.collect { |ele| "end" }.join("; "))
+ end
+
+ def dump_module_def
+ name = @name.to_s.split(/::/)
+ format("module #{name.last}")
+ end
+
+ def dump_module_def_end
+ format("end")
+ end
+end
+
+
+end
+end
+
+
+if __FILE__ == $0
+ require 'xsd/codegen/moduledef'
+ include XSD::CodeGen
+ m = ModuleDef.new("Foo::Bar::HobbitName")
+ m.def_require("foo/bar")
+ m.def_require("baz")
+ m.comment = <<-EOD
+ foo
+ bar
+ baz
+ EOD
+ m.def_method("foo") do
+ <<-EOD
+ foo.bar = 1
+ baz.each do |ele|
+ ele + 1
+ end
+ EOD
+ end
+ m.def_method("baz", "qux")
+ #m.def_protectedmethod("aaa")
+ m.def_privatemethod("bbb")
+ puts m.dump
+end
diff --git a/lib/xsd/datatypes.rb b/lib/xsd/datatypes.rb
index 7223632b04..7173f52d65 100644
--- a/lib/xsd/datatypes.rb
+++ b/lib/xsd/datatypes.rb
@@ -103,6 +103,12 @@ class XSDAnySimpleType < NSDBase
set(value) if value
end
+ # true or raise
+ def check_lexical_format(value)
+ screen_data(value)
+ true
+ end
+
# set accepts a string which follows lexical space (ex. String: "+123"), or
# an object which follows canonical space (ex. Integer: 123).
def set(value)
@@ -111,7 +117,7 @@ class XSDAnySimpleType < NSDBase
@data = nil
else
@is_nil = false
- _set(value)
+ _set(screen_data(value))
end
end
@@ -126,6 +132,11 @@ class XSDAnySimpleType < NSDBase
private
+ # raises ValueSpaceError if check failed
+ def screen_data(value)
+ value
+ end
+
def _set(value)
@data = value
end
@@ -144,12 +155,6 @@ class XSDNil < XSDAnySimpleType
@type = Type
set(value)
end
-
-private
-
- def _set(value)
- @data = value
- end
end
@@ -167,11 +172,11 @@ class XSDString < XSDAnySimpleType
private
- def _set(value)
+ def screen_data(value)
unless XSD::Charset.is_ces(value, XSD::Charset.encoding)
raise ValueSpaceError.new("#{ type }: cannot accept '#{ value }'.")
end
- @data = value
+ value
end
end
@@ -186,18 +191,18 @@ class XSDBoolean < XSDAnySimpleType
private
- def _set(value)
+ def screen_data(value)
if value.is_a?(String)
str = value.strip
if str == 'true' || str == '1'
- @data = true
+ true
elsif str == 'false' || str == '0'
- @data = false
+ false
else
raise ValueSpaceError.new("#{ type }: cannot accept '#{ str }'.")
end
else
- @data = value ? true : false
+ value ? true : false
end
end
end
@@ -220,38 +225,39 @@ class XSDDecimal < XSDAnySimpleType
private
- def _set(d)
+ def screen_data(d)
if d.is_a?(String)
# Integer("00012") => 10 in Ruby.
d.sub!(/^([+\-]?)0*(?=\d)/, "\\1")
end
- set_str(d)
+ screen_data_str(d)
end
- def set_str(str)
+ def screen_data_str(str)
/^([+\-]?)(\d*)(?:\.(\d*)?)?$/ =~ str.to_s.strip
unless Regexp.last_match
raise ValueSpaceError.new("#{ type }: cannot accept '#{ str }'.")
end
-
- @sign = $1 || '+'
+ sign = $1 || '+'
int_part = $2
frac_part = $3
-
int_part = '0' if int_part.empty?
frac_part = frac_part ? frac_part.sub(/0+$/, '') : ''
- @point = - frac_part.size
- @number = int_part + frac_part
-
+ point = - frac_part.size
+ number = int_part + frac_part
# normalize
- if @sign == '+'
- @sign = ''
- elsif @sign == '-'
- if @number == '0'
- @sign = ''
+ if sign == '+'
+ sign = ''
+ elsif sign == '-'
+ if number == '0'
+ sign = ''
end
end
+ [sign, point, number]
+ end
+ def _set(pair)
+ @sign, @point, @number = pair
@data = _to_s
@data.freeze
end
@@ -272,7 +278,7 @@ module FloatConstants
NEGATIVE_INF = -1.0/0.0
POSITIVE_ZERO = +1.0/POSITIVE_INF
NEGATIVE_ZERO = -1.0/POSITIVE_INF
- MIN_POSITIVE_SINGLE = 2 ** -149
+ MIN_POSITIVE_SINGLE = 2.0 ** -149
end
class XSDFloat < XSDAnySimpleType
@@ -287,20 +293,18 @@ class XSDFloat < XSDAnySimpleType
private
- def _set(value)
+ def screen_data(value)
# "NaN".to_f => 0 in some environment. libc?
if value.is_a?(Float)
- @data = narrow32bit(value)
- return
+ return narrow32bit(value)
end
-
str = value.to_s.strip
if str == 'NaN'
- @data = NaN
+ NaN
elsif str == 'INF'
- @data = POSITIVE_INF
+ POSITIVE_INF
elsif str == '-INF'
- @data = NEGATIVE_INF
+ NEGATIVE_INF
else
if /^[+\-\.\deE]+$/ !~ str
raise ValueSpaceError.new("#{ type }: cannot accept '#{ str }'.")
@@ -308,7 +312,7 @@ private
# Float("-1.4E") might fail on some system.
str << '0' if /e$/i =~ str
begin
- @data = narrow32bit(Float(str))
+ return narrow32bit(Float(str))
rescue ArgumentError
raise ValueSpaceError.new("#{ type }: cannot accept '#{ str }'.")
end
@@ -357,28 +361,26 @@ class XSDDouble < XSDAnySimpleType
private
- def _set(value)
+ def screen_data(value)
# "NaN".to_f => 0 in some environment. libc?
if value.is_a?(Float)
- @data = value
- return
+ return value
end
-
str = value.to_s.strip
if str == 'NaN'
- @data = NaN
+ NaN
elsif str == 'INF'
- @data = POSITIVE_INF
+ POSITIVE_INF
elsif str == '-INF'
- @data = NEGATIVE_INF
+ NEGATIVE_INF
else
begin
- @data = Float(str)
+ return Float(str)
rescue ArgumentError
# '1.4e' cannot be parsed on some architecture.
if /e\z/i =~ str
begin
- @data = Float(str + '0')
+ return Float(str + '0')
rescue ArgumentError
raise ValueSpaceError.new("#{ type }: cannot accept '#{ str }'.")
end
@@ -429,24 +431,27 @@ class XSDDuration < XSDAnySimpleType
private
- def _set(value)
+ def screen_data(value)
/^([+\-]?)P(?:(\d+)Y)?(?:(\d+)M)?(?:(\d+)D)?(T(?:(\d+)H)?(?:(\d+)M)?(?:(\d+(?:\.\d+)?)S)?)?$/ =~ value.to_s.strip
unless Regexp.last_match
raise ValueSpaceError.new("#{ type }: cannot accept '#{ value }'.")
end
-
if ($5 and ((!$2 and !$3 and !$4) or (!$6 and !$7 and !$8)))
# Should we allow 'PT5S' here?
raise ValueSpaceError.new("#{ type }: cannot accept '#{ value }'.")
end
+ sign = $1
+ year = $2.to_i
+ month = $3.to_i
+ day = $4.to_i
+ hour = $6.to_i
+ min = $7.to_i
+ sec = $8 ? XSDDecimal.new($8) : 0
+ [sign, year, month, day, hour, min, sec]
+ end
- @sign = $1
- @year = $2.to_i
- @month = $3.to_i
- @day = $4.to_i
- @hour = $6.to_i
- @min = $7.to_i
- @sec = $8 ? XSDDecimal.new($8) : 0
+ def _set(ary)
+ @sign, @year, @month, @day, @hour, @min, @sec = ary
@data = _to_s
@data.freeze
end
@@ -524,18 +529,18 @@ module XSDDateTimeImpl
end
end
- def _set(t)
- set_datetime_init(t)
+ def screen_data(t)
if (t.is_a?(Date))
- @data = t
+ t
elsif (t.is_a?(Time))
sec, min, hour, mday, month, year = t.to_a[0..5]
diffday = t.usec.to_r / 1000000 / SecInDay
of = t.utc_offset.to_r / SecInDay
- @data = DateTime.civil(year, month, mday, hour, min, sec, of)
- @data += diffday
+ data = DateTime.civil(year, month, mday, hour, min, sec, of)
+ data += diffday
+ data
else
- set_str(t)
+ screen_data_str(t)
end
end
@@ -557,11 +562,7 @@ class XSDDateTime < XSDAnySimpleType
private
- def set_datetime_init(t)
- @secfrac = nil
- end
-
- def set_str(t)
+ def screen_data_str(t)
/^([+\-]?\d{4,})-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d(?:\.(\d*))?)(Z|(?:[+\-]\d\d:\d\d)?)?$/ =~ t.to_s.strip
unless Regexp.last_match
raise ValueSpaceError.new("#{ type }: cannot accept '#{ t }'.")
@@ -569,7 +570,6 @@ private
if $1 == '0000'
raise ValueSpaceError.new("#{ type }: cannot accept '#{ t }'.")
end
-
year = $1.to_i
if year < 0
year += 1
@@ -581,22 +581,18 @@ private
sec = $6.to_i
secfrac = $7
zonestr = $8
-
- @data = DateTime.civil(year, mon, mday, hour, min, sec, tz2of(zonestr))
- @secfrac = secfrac
-
+ data = DateTime.civil(year, mon, mday, hour, min, sec, tz2of(zonestr))
if secfrac
diffday = secfrac.to_i.to_r / (10 ** secfrac.size) / SecInDay
- # jd = @data.jd
- # day_fraction = @data.day_fraction + diffday
- # @data = DateTime.new0(DateTime.jd_to_rjd(jd, day_fraction,
- # @data.offset), @data.offset)
- #
- # Thanks to Funaba-san, above code can be simply written as below.
- @data += diffday
+ data += diffday
# FYI: new0 and jd_to_rjd are not necessary to use if you don't have
# exceptional reason.
end
+ [data, secfrac]
+ end
+
+ def _set(pair)
+ @data, @secfrac = pair
end
def _to_s
@@ -607,7 +603,8 @@ private
if @secfrac
s << ".#{ @secfrac }"
else
- s << sprintf("%.16f", (@data.sec_fraction * SecInDay).to_f).sub(/^0/, '').sub(/0*$/, '')
+ s << sprintf("%.16f",
+ (@data.sec_fraction * SecInDay).to_f).sub(/^0/, '').sub(/0*$/, '')
end
end
add_tz(s)
@@ -627,29 +624,26 @@ class XSDTime < XSDAnySimpleType
private
- def set_datetime_init(t)
- @secfrac = nil
- end
-
- def set_str(t)
+ def screen_data_str(t)
/^(\d\d):(\d\d):(\d\d(?:\.(\d*))?)(Z|(?:([+\-])(\d\d):(\d\d))?)?$/ =~ t.to_s.strip
unless Regexp.last_match
raise ValueSpaceError.new("#{ type }: cannot accept '#{ t }'.")
end
-
hour = $1.to_i
min = $2.to_i
sec = $3.to_i
secfrac = $4
zonestr = $5
-
- @data = DateTime.civil(1, 1, 1, hour, min, sec, tz2of(zonestr))
- @secfrac = secfrac
-
+ data = DateTime.civil(1, 1, 1, hour, min, sec, tz2of(zonestr))
if secfrac
diffday = secfrac.to_i.to_r / (10 ** secfrac.size) / SecInDay
- @data += diffday
+ data += diffday
end
+ [data, secfrac]
+ end
+
+ def _set(pair)
+ @data, @secfrac = pair
end
def _to_s
@@ -658,7 +652,8 @@ private
if @secfrac
s << ".#{ @secfrac }"
else
- s << sprintf("%.16f", (@data.sec_fraction * SecInDay).to_f).sub(/^0/, '').sub(/0*$/, '')
+ s << sprintf("%.16f",
+ (@data.sec_fraction * SecInDay).to_f).sub(/^0/, '').sub(/0*$/, '')
end
end
add_tz(s)
@@ -677,15 +672,11 @@ class XSDDate < XSDAnySimpleType
private
- def set_datetime_init(t)
- end
-
- def set_str(t)
+ def screen_data_str(t)
/^([+\-]?\d{4,})-(\d\d)-(\d\d)(Z|(?:([+\-])(\d\d):(\d\d))?)?$/ =~ t.to_s.strip
unless Regexp.last_match
raise ValueSpaceError.new("#{ type }: cannot accept '#{ t }'.")
end
-
year = $1.to_i
if year < 0
year += 1
@@ -693,8 +684,7 @@ private
mon = $2.to_i
mday = $3.to_i
zonestr = $4
-
- @data = DateTime.civil(year, mon, mday, 0, 0, 0, tz2of(zonestr))
+ DateTime.civil(year, mon, mday, 0, 0, 0, tz2of(zonestr))
end
def _to_s
@@ -716,23 +706,18 @@ class XSDGYearMonth < XSDAnySimpleType
private
- def set_datetime_init(t)
- end
-
- def set_str(t)
+ def screen_data_str(t)
/^([+\-]?\d{4,})-(\d\d)(Z|(?:([+\-])(\d\d):(\d\d))?)?$/ =~ t.to_s.strip
unless Regexp.last_match
raise ValueSpaceError.new("#{ type }: cannot accept '#{ t }'.")
end
-
year = $1.to_i
if year < 0
year += 1
end
mon = $2.to_i
zonestr = $3
-
- @data = DateTime.civil(year, mon, 1, 0, 0, 0, tz2of(zonestr))
+ DateTime.civil(year, mon, 1, 0, 0, 0, tz2of(zonestr))
end
def _to_s
@@ -754,22 +739,17 @@ class XSDGYear < XSDAnySimpleType
private
- def set_datetime_init(t)
- end
-
- def set_str(t)
+ def screen_data_str(t)
/^([+\-]?\d{4,})(Z|(?:([+\-])(\d\d):(\d\d))?)?$/ =~ t.to_s.strip
unless Regexp.last_match
raise ValueSpaceError.new("#{ type }: cannot accept '#{ t }'.")
end
-
year = $1.to_i
if year < 0
year += 1
end
zonestr = $2
-
- @data = DateTime.civil(year, 1, 1, 0, 0, 0, tz2of(zonestr))
+ DateTime.civil(year, 1, 1, 0, 0, 0, tz2of(zonestr))
end
def _to_s
@@ -791,20 +771,15 @@ class XSDGMonthDay < XSDAnySimpleType
private
- def set_datetime_init(t)
- end
-
- def set_str(t)
+ def screen_data_str(t)
/^(\d\d)-(\d\d)(Z|(?:[+\-]\d\d:\d\d)?)?$/ =~ t.to_s.strip
unless Regexp.last_match
raise ValueSpaceError.new("#{ type }: cannot accept '#{ t }'.")
end
-
mon = $1.to_i
mday = $2.to_i
zonestr = $3
-
- @data = DateTime.civil(1, mon, mday, 0, 0, 0, tz2of(zonestr))
+ DateTime.civil(1, mon, mday, 0, 0, 0, tz2of(zonestr))
end
def _to_s
@@ -825,19 +800,14 @@ class XSDGDay < XSDAnySimpleType
private
- def set_datetime_init(t)
- end
-
- def set_str(t)
+ def screen_data_str(t)
/^(\d\d)(Z|(?:[+\-]\d\d:\d\d)?)?$/ =~ t.to_s.strip
unless Regexp.last_match
raise ValueSpaceError.new("#{ type }: cannot accept '#{ t }'.")
end
-
mday = $1.to_i
zonestr = $2
-
- @data = DateTime.civil(1, 1, mday, 0, 0, 0, tz2of(zonestr))
+ DateTime.civil(1, 1, mday, 0, 0, 0, tz2of(zonestr))
end
def _to_s
@@ -858,19 +828,14 @@ class XSDGMonth < XSDAnySimpleType
private
- def set_datetime_init(t)
- end
-
- def set_str(t)
+ def screen_data_str(t)
/^(\d\d)(Z|(?:[+\-]\d\d:\d\d)?)?$/ =~ t.to_s.strip
unless Regexp.last_match
raise ValueSpaceError.new("#{ type }: cannot accept '#{ t }'.")
end
-
mon = $1.to_i
zonestr = $2
-
- @data = DateTime.civil(1, mon, 1, 0, 0, 0, tz2of(zonestr))
+ DateTime.civil(1, mon, 1, 0, 0, 0, tz2of(zonestr))
end
def _to_s
@@ -903,9 +868,8 @@ class XSDHexBinary < XSDAnySimpleType
private
- def _set(value)
- @data = value.unpack("H*")[0]
- @data.tr!('a-f', 'A-F')
+ def screen_data(value)
+ value.unpack("H*")[0].tr('a-f', 'A-F')
end
end
@@ -933,8 +897,8 @@ class XSDBase64Binary < XSDAnySimpleType
private
- def _set(value)
- @data = [value].pack("m").strip
+ def screen_data(value)
+ [value].pack("m").strip
end
end
@@ -949,9 +913,9 @@ class XSDAnyURI < XSDAnySimpleType
private
- def _set(value)
+ def screen_data(value)
begin
- @data = URI.parse(value.to_s.strip)
+ URI.parse(value.to_s.strip)
rescue URI::InvalidURIError
raise ValueSpaceError.new("#{ type }: cannot accept '#{ value }'.")
end
@@ -969,14 +933,18 @@ class XSDQName < XSDAnySimpleType
private
- def _set(value)
+ def screen_data(value)
/^(?:([^:]+):)?([^:]+)$/ =~ value.to_s.strip
unless Regexp.last_match
raise ValueSpaceError.new("#{ type }: cannot accept '#{ value }'.")
end
+ prefix = $1
+ localpart = $2
+ [prefix, localpart]
+ end
- @prefix = $1
- @localpart = $2
+ def _set(pair)
+ @prefix, @localpart = pair
@data = _to_s
@data.freeze
end
@@ -1005,7 +973,7 @@ class XSDNormalizedString < XSDString
private
- def _set(value)
+ def screen_data(value)
if /[\t\r\n]/ =~ value
raise ValueSpaceError.new("#{ type }: cannot accept '#{ value }'.")
end
@@ -1024,12 +992,17 @@ class XSDInteger < XSDDecimal
private
- def set_str(str)
+ def screen_data_str(str)
begin
- @data = Integer(str)
+ data = Integer(str)
rescue ArgumentError
raise ValueSpaceError.new("#{ type }: cannot accept '#{ str }'.")
end
+ data
+ end
+
+ def _set(value)
+ @data = value
end
def _to_s()
@@ -1048,15 +1021,20 @@ class XSDLong < XSDInteger
private
- def set_str(str)
+ def screen_data_str(str)
begin
- @data = Integer(str)
+ data = Integer(str)
rescue ArgumentError
raise ValueSpaceError.new("#{ type }: cannot accept '#{ str }'.")
end
- unless validate(@data)
+ unless validate(data)
raise ValueSpaceError.new("#{ type }: cannot accept '#{ str }'.")
end
+ data
+ end
+
+ def _set(value)
+ @data = value
end
MaxInclusive = +9223372036854775807
@@ -1077,15 +1055,20 @@ class XSDInt < XSDLong
private
- def set_str(str)
+ def screen_data_str(str)
begin
- @data = Integer(str)
+ data = Integer(str)
rescue ArgumentError
raise ValueSpaceError.new("#{ type }: cannot accept '#{ str }'.")
end
- unless validate(@data)
+ unless validate(data)
raise ValueSpaceError.new("#{ type }: cannot accept '#{ str }'.")
end
+ data
+ end
+
+ def _set(value)
+ @data = value
end
MaxInclusive = +2147483647
@@ -1106,15 +1089,20 @@ class XSDShort < XSDInt
private
- def set_str(str)
+ def screen_data_str(str)
begin
- @data = Integer(str)
+ data = Integer(str)
rescue ArgumentError
raise ValueSpaceError.new("#{ type }: cannot accept '#{ str }'.")
end
- unless validate(@data)
+ unless validate(data)
raise ValueSpaceError.new("#{ type }: cannot accept '#{ str }'.")
end
+ data
+ end
+
+ def _set(value)
+ @data = value
end
MaxInclusive = +32767
diff --git a/lib/xsd/qname.rb b/lib/xsd/qname.rb
index 9dce1340f8..7185fedf2d 100644
--- a/lib/xsd/qname.rb
+++ b/lib/xsd/qname.rb
@@ -1,5 +1,5 @@
# XSD4R - XML QName definition.
-# Copyright (C) 2002, 2003 NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
+# Copyright (C) 2002, 2003, 2004 NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
# This program is copyrighted free software by NAKAMURA, Hiroshi. You can
# redistribute it and/or modify it under the same terms of Ruby's license;
@@ -19,7 +19,7 @@ class QName
end
def dup_name(name)
- self.class.new(@namespace, name)
+ ::XSD::QName.new(@namespace, name)
end
def match(rhs)
@@ -55,6 +55,11 @@ class QName
"{#{ namespace }}#{ name }"
end
+ def inspect
+ sprintf("#<%s:0x%x %s>", self.class.name, __id__,
+ "{#{ namespace }}#{ name }")
+ end
+
NormalizedNameRegexp = /^\{([^}]*)\}(.*)$/
def parse(str)
NormalizedNameRegexp =~ str