* transcode.c (transcode_restartable): my_transcoder argument removed.
[ruby-svn.git] / lib / xmlrpc / utils.rb
blobf0966fee4008ad5e2d610e345145275e8085dc16
2 # Defines ParserWriterChooseMixin, which makes it possible to choose a
3 # different XML writer and/or XML parser then the default one.
4 # The Mixin is used in client.rb (class Client) and server.rb (class 
5 # BasicServer)
6
7 # Copyright (C) 2001, 2002, 2003 by Michael Neumann (mneumann@ntecs.de)
9 # $Id$ 
12 module XMLRPC
14   #
15   # This module enables a user-class to be marshalled
16   # by XML-RPC for Ruby into a Hash, with one additional
17   # key/value pair "___class___" => ClassName
18   # 
19   module Marshallable
20   end
23   module ParserWriterChooseMixin
25     def set_writer(writer)
26       @create = Create.new(writer)
27       self
28     end
30     def set_parser(parser)
31       @parser = parser
32       self
33     end
35     private
37     def create
38       # if set_writer was not already called then call it now
39       if @create.nil? then
40         set_writer(Config::DEFAULT_WRITER.new)
41       end
42       @create
43     end
45     def parser
46       # if set_parser was not already called then call it now
47       if @parser.nil? then
48         set_parser(Config::DEFAULT_PARSER.new)
49       end
50       @parser
51     end
53   end # module ParserWriterChooseMixin
56   module Service
58   #
59   # base class for Service Interface definitions, used
60   # by BasicServer#add_handler
61   #
63   class BasicInterface
64     attr_reader :prefix, :methods
66     def initialize(prefix)
67       @prefix = prefix
68       @methods = []
69     end
71     def add_method(sig, help=nil, meth_name=nil)
72       mname = nil
73       sig = [sig] if sig.kind_of? String
75       sig = sig.collect do |s| 
76         name, si = parse_sig(s)
77         raise "Wrong signatures!" if mname != nil and name != mname 
78         mname = name
79         si
80       end
82       @methods << [mname, meth_name || mname, sig, help]
83     end
85     private # ---------------------------------
86   
87     def parse_sig(sig)
88       # sig is a String
89       if sig =~ /^\s*(\w+)\s+([^(]+)(\(([^)]*)\))?\s*$/
90         params = [$1]
91         name   = $2.strip 
92         $4.split(",").each {|i| params << i.strip} if $4 != nil
93         return name, params
94       else
95         raise "Syntax error in signature"
96       end
97     end
99   end # class BasicInterface
101   #
102   # class which wraps a Service Interface definition, used
103   # by BasicServer#add_handler
104   #
105   class Interface < BasicInterface
106     def initialize(prefix, &p)
107       raise "No interface specified" if p.nil?
108       super(prefix)
109       instance_eval(&p)
110     end
112     def get_methods(obj, delim=".") 
113       prefix = @prefix + delim
114       @methods.collect { |name, meth, sig, help| 
115         [prefix + name, obj.method(meth).to_proc, sig, help] 
116       }
117     end
119     private # ---------------------------------
121     def meth(*a)
122       add_method(*a)
123     end
125   end # class Interface
127   class PublicInstanceMethodsInterface < BasicInterface
128     def initialize(prefix)
129       super(prefix)
130     end
132     def get_methods(obj, delim=".")
133       prefix = @prefix + delim
134       obj.class.public_instance_methods(false).collect { |name|
135         [prefix + name, obj.method(name).to_proc, nil, nil] 
136       }
137     end
138   end
141   end # module Service
144   # 
145   # short-form to create a Service::Interface
146   #
147   def self.interface(prefix, &p)
148     Service::Interface.new(prefix, &p)  
149   end
151   # short-cut for creating a PublicInstanceMethodsInterface
152   def self.iPIMethods(prefix)
153     Service::PublicInstanceMethodsInterface.new(prefix) 
154   end
157   module ParseContentType
158     def parse_content_type(str)
159       a, *b = str.split(";")
160       return a.strip.downcase, *b
161     end
162   end
164 end # module XMLRPC