comparison tango/tango/net/cluster/NetworkCall.d @ 132:1700239cab2e trunk

[svn r136] MAJOR UNSTABLE UPDATE!!! Initial commit after moving to Tango instead of Phobos. Lots of bugfixes... This build is not suitable for most things.
author lindquist
date Fri, 11 Jan 2008 17:57:40 +0100
parents
children
comparison
equal deleted inserted replaced
131:5825d48b27d1 132:1700239cab2e
1 /*******************************************************************************
2
3 copyright: Copyright (c) 2007 Tango. All rights reserved
4
5 license: BSD style: $(LICENSE)
6
7 version: April 2007: Initial release
8
9 author: h3r3tic, Kris
10
11 *******************************************************************************/
12
13 module tango.net.cluster.NetworkCall;
14
15 private import tango.core.Traits;
16 private import tango.core.Thread;
17
18 private import tango.net.cluster.NetworkMessage;
19
20 protected import tango.io.protocol.model.IReader,
21 tango.io.protocol.model.IWriter;
22
23 protected import tango.net.cluster.model.IChannel;
24
25
26 /*******************************************************************************
27
28 task harness, for initiating the send
29
30 *******************************************************************************/
31
32 class NetworkCall : NetworkMessage
33 {
34 /***********************************************************************
35
36 ***********************************************************************/
37
38 void send (IChannel channel = null)
39 {
40 if (channel)
41 channel.execute (this);
42 else
43 {
44 auto x = cast(IChannel) Thread.getLocal(0);
45 if (x)
46 x.execute (this);
47 else
48 execute;
49 }
50 }
51 }
52
53
54 /*******************************************************************************
55
56 Template for RPC glue
57
58 *******************************************************************************/
59
60 class NetCall(alias realFunc) : NetworkCall
61 {
62 alias ParameterTupleOf!(realFunc) Params;
63 alias ReturnTypeOf!(realFunc) RetType;
64
65 static if (!is(RetType == void)) {
66 RetType result;
67 }
68 Params params;
69
70
71 override char[] toString() {
72 return signatureOfFunc!(realFunc);
73 }
74
75 RetType opCall(Params params, IChannel channel = null) {
76 foreach (i, _dummy; this.params) {
77 this.params[i] = params[i];
78 }
79 send (channel);
80
81 static if (!is(RetType == void)) {
82 return result;
83 }
84 }
85
86 override void execute() {
87 static if (!is(RetType == void)) {
88 result = realFunc(params);
89 } else {
90 realFunc(params);
91 }
92 }
93
94 override void read(IReader input) {
95 static if (!is(RetType == void)) {
96 input(result);
97 }
98 foreach (i, _dummy; params) input(params[i]);
99 }
100
101 override void write(IWriter output) {
102 static if (!is(RetType == void)) {
103 output(result);
104 }
105 foreach (i, _dummy; params) output(params[i]);
106 }
107 }
108
109
110 /*******************************************************************************
111
112 Magic to get a clean function signature
113
114 *******************************************************************************/
115
116 private {
117 struct Wrapper(alias fn) {}
118 const char[] WrapperPrefix = `__T7Wrapper`;
119
120
121 uint parseUint(char[] str) {
122 int res = 0;
123 foreach (c; str) {
124 res *= 10;
125 res += c - '0';
126 }
127 return res;
128 }
129
130
131 char[] sliceOffSegment(inout char[] str) {
132 assert (str.length > 0 && str[0] >= '0' && str[0] <= '9');
133
134 int lenEnd = 0;
135 for (; str[lenEnd] >= '0' && str[lenEnd] <= '9'; ++lenEnd) {}
136
137 char[] lenStr = str[0..lenEnd];
138 uint segLen = parseUint(lenStr);
139 str = str[lenEnd .. $];
140
141 char[] res = str[0..segLen];
142 str = str[segLen .. $];
143 return res;
144 }
145
146
147 char[] digOutWrapper(char[] wrapped) {
148 wrapped = wrapped[1..$]; // skip the 'S'
149 char[] seg;
150
151 do {
152 seg = sliceOffSegment(wrapped);
153 } while (seg.length < WrapperPrefix.length || seg[0..WrapperPrefix.length] != WrapperPrefix);
154
155 return seg[WrapperPrefix.length .. $];
156 }
157
158
159 char[] demangleDFunc(char[] mangled) {
160 char[] res = sliceOffSegment(mangled);
161
162 while (mangled.length > 0 && mangled[0] >= '0' && mangled[0] <= '9') {
163 res ~= '.' ~ sliceOffSegment(mangled);
164 }
165 return res;
166 }
167
168
169 char[] nameOf_impl(char[] wrapped) {
170 char[] wrapper = digOutWrapper(wrapped)[1..$]; // skip the 'S'
171 char[] mangled = sliceOffSegment(wrapper);
172
173 if (mangled.length > 2 && mangled[0..2] == `_D`) {
174 // D func
175 return demangleDFunc(mangled[2..$]);
176 } else {
177 return mangled; // C func
178 }
179 }
180
181
182 int match_param_(char[] str) {
183 if (str.length < `_param_0`.length) return 0;
184
185 int numDigits = 0;
186 while (str[$-1-numDigits] >= '0' && str[$-1-numDigits] <= '9') {
187 ++numDigits;
188 }
189
190 if (0 == numDigits) return 0;
191
192 if (str.length >= `_param_`.length + numDigits && str[$-`_param_`.length-numDigits .. $-numDigits] == `_param_`) {
193 return `_param_`.length + numDigits;
194 } else {
195 return 0;
196 }
197 }
198
199
200 // sometimes the param lists have ugly _param_[0-9]+ names in them...
201 char[] tidyTupleStringof(char[] str) {
202 char[] res;
203 for (int i = 0; i < str.length; ++i) {
204 char c = str[i];
205
206 if (c == ')' || c == ',') {
207 if (auto len = match_param_(str[0..i])) {
208 // len is the length of the _param_[0-9]+ thing
209 int start = i-1-len;
210 str = str[0..start] ~ str[i..$];
211 i -= len;
212 }
213 }
214 }
215
216 return str;
217 }
218
219
220 template nameOfFunc(alias fn) {
221 static assert (is(typeof(fn) == function));
222 const char[] nameOfFunc = nameOf_impl((Wrapper!(fn)).mangleof);
223 }
224
225
226 template signatureOfFunc(alias fn) {
227 static assert (is(typeof(fn) == function));
228 const char[] signatureOfFunc = ReturnTypeOf!(fn).stringof ~ ' ' ~ nameOfFunc!(fn) ~ tidyTupleStringof(ParameterTupleOf!(fn).stringof);
229 }
230 }