1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
|
#!/usr/bin/env ruby
$: << ".." # Include .. in load path
require 'cppgen'
class ProxyGen < CppGen
def initialize(chassis, outdir, amqp)
super(outdir, amqp)
@chassis=chassis
@classname="AMQP_#{@chassis.caps}Proxy"
end
def include(m) gen "#include \"#{m.body_name}.h\"\n"; end
def proxy_member(c) c.name.lcaps+"Proxy"; end
def inner_class_decl(c)
cname=c.name.caps
gen <<EOS
// ==================== class #{cname} ====================
class #{cname}
{
private:
ChannelAdapter& channel;
public:
// Constructors and destructors
#{cname}(ChannelAdapter& ch) :
channel(ch) {}
virtual ~#{cname}() {}
static #{cname}& get(#{@classname}& proxy) { return proxy.get#{cname}();}
// Protocol methods
EOS
indent(2) { c.methods_on(@chassis).each { |m| inner_method_decl(m) } }
gen "\n }; // class #{cname}\n\n"
end
def inner_method_decl(m)
gen "virtual void #{m.cppname}(#{m.signature.join(",\n ")})\n\n";
end
def inner_class_defn(c)
cname=c.cppname
gen "// ==================== class #{cname} ====================\n"
c.methods_on(@chassis).each { |m| inner_method_defn(m, cname) }
end
def inner_method_defn(m,cname)
if m.response?
rettype="void"
ret=""
sigadd=["RequestId responseTo"]
paramadd=["channel.getVersion(), responseTo"]
else
rettype="RequestId"
ret="return "
sigadd=[]
paramadd=["channel.getVersion()"]
end
sig=(m.signature+sigadd).join(", ")
params=(paramadd+m.param_names).join(",\n ")
gen <<EOS
#{rettype} #{@classname}::#{cname}::#{m.cppname}(#{sig}) {
#{ret}channel.send(new #{m.body_name}(#{params}));
}
EOS
end
def get_decl(c)
cname=c.name.caps
gen " #{cname}& #{@classname}::get#{cname}();\n"
end
def get_defn(c)
cname=c.name.caps
gen <<EOS
#{@classname}::#{c.name.caps}& #{@classname}::get#{c.name.caps}()
{
return #{proxy_member(c)};
}
EOS
end
def generate
# .h file
h_file(@classname+".h") {
gen <<EOS
#include "qpid/framing/Proxy.h"
namespace qpid {
namespace framing {
class #{@classname} : public Proxy
{
public:
#{@classname}(ChannelAdapter& ch);
// Inner class definitions
EOS
@amqp.classes.each{ |c| inner_class_decl(c) }
gen " // Inner class instance get methods\n"
@amqp.classes.each{ |c| get_decl(c) }
gen <<EOS
private:
// Inner class instances
EOS
indent { @amqp.classes.each{ |c| gen c.cppname+" "+proxy_member(c)+";\n" } }
gen <<EOS
}; /* class #{@classname} */
} /* namespace framing */
} /* namespace qpid */
EOS
}
# .cpp file
cpp_file(@classname+".cpp") {
gen <<EOS
#include <sstream>
#include "#{@classname}.h"
#include "qpid/framing/ChannelAdapter.h"
#include "qpid/framing/amqp_types_full.h"
EOS
@amqp.methods_on(@chassis).each { |m| include(m) }
gen <<EOS
namespace qpid {
namespace framing {
#{@classname}::#{@classname}(ChannelAdapter& ch) :
EOS
gen " Proxy(ch)"
@amqp.classes.each { |c| gen ",\n "+proxy_member(c)+"(channel)" }
gen <<EOS
{}
// Inner class instance get methods
EOS
@amqp.classes.each { |c| get_defn(c) }
gen " // Inner class implementation\n\n"
@amqp.classes.each { |c| inner_class_defn(c) }
gen "}} // namespae qpid::framing"
}
end
end
ProxyGen.new("client", ARGV[0], amqp).generate;
ProxyGen.new("server", ARGV[0], amqp).generate;
|