Develop and Download Open Source Software

Browse CVS Repository

Contents of /netruby/netruby/frmobj.cs

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.1.1.1 - (show annotations) (download) (vendor branch)
Mon Apr 8 13:27:20 2002 UTC (22 years ago) by arton
Branch: MAIN, vendor
CVS Tags: start, HEAD
Changes since 1.1: +0 -0 lines
initial version 0.8

1 /*
2 Copyright(C) 2001-2002 arton
3
4 Permission is granted for use, copying, modification, distribution,
5 and distribution of modified versions of this work as long as the
6 above copyright notice is included.
7 */
8
9 using System;
10 using System.Diagnostics;
11 using System.Collections;
12 using System.IO;
13 using System.Text;
14 using System.Reflection;
15 using System.Reflection.Emit;
16 using System.Security;
17
18 namespace arton.NETRuby
19 {
20 public class RFrmworkObject : RObject
21 {
22 internal RFrmworkObject(NetRuby rb, RMetaObject spr, object o) :
23 base(rb, spr)
24 {
25 obj = o;
26 }
27
28 public object GetOriginal()
29 {
30 return obj;
31 }
32
33 public override string ToString()
34 {
35 return obj.ToString();
36 }
37
38 public override object Missing(params object[] args)
39 {
40 ruby.CheckMissingParam(args);
41 uint id = Symbol.SYM2ID((uint)args[0]);
42 string func = ruby.id2name(id);
43 if (func == "each")
44 {
45 return Each(args);
46 }
47 string cname = func;
48 if (func == "[]")
49 {
50 cname = "get_Item";
51 }
52 else if (func == "[]=")
53 {
54 cname = "set_Item";
55 }
56 else if (func[func.Length - 1] == '=')
57 {
58 cname = "set_" + func.Substring(0, func.Length - 1);
59 }
60 Type[] param;
61 object[] argv = RFrmworkClass.adjustCLS(1, args, out param);
62 MethodInfo mtd = obj.GetType().GetMethod(cname, param);
63 if (mtd == null)
64 {
65 mtd = obj.GetType().GetMethod("get_" + func, param);
66 if (mtd == null)
67 {
68 throw new ArgumentException(
69 String.Format("undefined method `{0}' for {1}", func, klass.Name));
70 }
71 }
72 object o = mtd.Invoke(obj, argv);
73 return o;
74 }
75 object Each(object[] args)
76 {
77 try
78 {
79 IEnumerable e = (IEnumerable)obj;
80 foreach (object o in e)
81 {
82 ruby.Yield(o);
83 }
84 }
85 catch
86 {
87 throw new ArgumentException(
88 String.Format("undefined method `each' for {1}", klass.Name));
89 }
90 return this;
91 }
92
93 object obj;
94 }
95
96 public class RFrmworkClass : RClass
97 {
98 internal RFrmworkClass(NetRuby rb, string name, RMetaObject super, Type tp) :
99 base(rb, name, super)
100 {
101 metaClass = tp;
102 }
103 protected Type metaClass;
104
105 public override RBasic NewInstance(object[] args)
106 {
107 Type[] param;
108 object[] argv = adjustCLS(0, args, out param);
109 ConstructorInfo ctr = metaClass.GetConstructor(param);
110 if (ctr == null)
111 throw new ArgumentException(String.Format("Invalid Argument for {0}::new", Name));
112 object o = ctr.Invoke(argv);
113 return new RFrmworkObject(ruby, this, o);
114 }
115 public RBasic WrapObject(object o)
116 {
117 return new RFrmworkObject(ruby, this, o);
118 }
119
120 public override RArray SingletonMethods
121 {
122 get {
123 BindingFlags bf = BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.FlattenHierarchy;
124 return methodList(bf);
125 }
126 }
127 public override RArray ClassInstanceMethods(object[] argv)
128 {
129 BindingFlags bf = BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Instance;
130 if (argv.Length > 0 && RTest(argv[0]))
131 bf |= BindingFlags.FlattenHierarchy;
132 return methodList(bf);
133 }
134 public override RArray ClassProtectedInstanceMethods(object[] argv)
135 {
136 BindingFlags bf = BindingFlags.InvokeMethod | BindingFlags.Instance;
137 if (argv.Length > 0 && RTest(argv[0]))
138 bf |= BindingFlags.FlattenHierarchy;
139 return methodList(bf);
140 }
141 public override RArray ClassPrivateInstanceMethods(object[] argv)
142 {
143 BindingFlags bf = BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Instance;
144 if (argv.Length > 0 && RTest(argv[0]))
145 bf |= BindingFlags.FlattenHierarchy;
146 return methodList(bf);
147 }
148 RArray methodList(BindingFlags bf)
149 {
150 MethodInfo[] mis = metaClass.GetMethods(bf);
151 RArray ra = new RArray(ruby, true);
152 foreach (MethodInfo m in mis)
153 {
154 ra.Add(m.ToString());
155 }
156 return ra;
157 }
158
159 public override object Missing(params object[] args)
160 {
161 ruby.CheckMissingParam(args);
162 uint id = Symbol.SYM2ID((uint)args[0]);
163 string func = ruby.id2name(id);
164
165 Type[] param;
166 object[] argv = adjustCLS(1, args, out param);
167 MethodInfo mtd = metaClass.GetMethod(func, param);
168 if (mtd == null)
169 {
170 if (func[func.Length - 1] == '=')
171 mtd = metaClass.GetMethod("set_" + func.Substring(0, func.Length - 1), param);
172 else
173 mtd = metaClass.GetMethod("get_" + func, param);
174 if (mtd == null)
175 throw new ArgumentException(
176 String.Format("undefined method `{0}' for {1}", func, klass.Name));
177 }
178 object o = mtd.Invoke(null, argv); // static
179 return o;
180 }
181
182 internal static object[] adjustCLS(int idx, object[] args, out Type[] tps)
183 {
184 tps = null;
185 object[] argv = new object[args.Length - idx];
186 tps = new Type[args.Length - idx];
187 for (int ix = idx; ix < args.Length; ix++)
188 {
189 int i = ix - idx;
190 object o = args[ix];
191 if (o is string || o is RString)
192 {
193 argv[i] = o.ToString();
194 tps[i] = typeof(string);
195 }
196 else if (o is RFixnum)
197 {
198 argv[i] = ((RFixnum)o).ToInt();
199 tps[i] = typeof(int);
200 }
201 else if (o is RBignum)
202 {
203 RBignum b = (RBignum)o;
204 try
205 {
206 argv[i] = b.ToLong();
207 tps[i] = typeof(long);
208 }
209 catch
210 {
211 argv[i] = b.Big2Dbl();
212 tps[i] = typeof(double);
213 }
214 }
215 else if (o is RFloat)
216 {
217 argv[i] = ((RFloat)o).Double;
218 tps[i] = typeof(double);
219 }
220 else if (o is RBool)
221 {
222 argv[i] = ((RBool)o).ToBool();
223 tps[i] = typeof(bool);
224 }
225 else if (o is RChar)
226 {
227 argv[i] = ((RChar)o).Char;
228 tps[i] = typeof(char);
229 }
230 else if (o is RNil)
231 {
232 argv[i] = null;
233 tps[i] = typeof(object);
234 }
235 else if (o is RArray)
236 {
237 argv[i] = ((RArray)o).Array;
238 tps[i] = typeof(object[]);
239 }
240 else if (o is RFrmworkObject)
241 {
242 argv[i] = ((RFrmworkObject)o).GetOriginal();
243 tps[i] = argv[i].GetType();
244 }
245 else if (o is RBasic)
246 {
247 argv[i] = o;
248 tps[i] = typeof(object);
249 }
250 else
251 {
252 tps[i] = o.GetType();
253 argv[i] = Convert.ChangeType(o, tps[i]);
254 }
255 }
256 return argv;
257 }
258 internal object attach(RBasic r, params object[] args)
259 {
260 return ((RFrmworkClass)r).WrapObject(args[0]);
261 }
262 }
263
264 public class RDotNetClass : RClass
265 {
266 private RDotNetClass(NetRuby rb) :
267 base(rb, "DotNet", rb.cObject)
268 {
269 ulist = new ArrayList();
270 tlist = new Hashtable();
271 alist = new ArrayList();
272 ulist.Add("System");
273 }
274
275 ArrayList ulist;
276 Hashtable tlist;
277 ArrayList alist;
278 public bool Using(string nmspace)
279 {
280 ruby.GetCurrentContext().Secure(3);
281
282 bool load = false;
283 if (ulist.Contains(nmspace) == false)
284 {
285 lock (ulist.SyncRoot)
286 {
287 if (ulist.Contains(nmspace) == false)
288 {
289 ulist.Add(nmspace);
290 load = true;
291 }
292 }
293 if (load)
294 {
295 AssemblyName asm;
296 nmspace += ".dll";
297 if (CheckAssembly(nmspace + ".dll", out asm) == false)
298 {
299 string fname = typeof(Object).Assembly.CodeBase.Replace("mscorlib.dll", nmspace);
300 fname = fname.Replace("file:///", "");
301 CheckAssembly(fname, out asm);
302 }
303 if (asm != null)
304 {
305 Assembly a = Assembly.Load(asm);
306 Type[] ts = a.GetTypes();
307 foreach (Type t in ts)
308 {
309 lock (tlist.SyncRoot)
310 {
311 tlist[t.ToString()] = t;
312 }
313 }
314 alist.Add(a);
315 }
316 }
317 }
318 return load;
319 }
320 static bool CheckAssembly(string fname, out AssemblyName asm)
321 {
322 asm = null;
323 try
324 {
325 asm = AssemblyName.GetAssemblyName(fname);
326 }
327 catch
328 {
329 return false;
330 }
331 return true;
332 }
333
334 public string[] UsingList
335 {
336 get {
337 string[] list = (string[])ulist.ToArray(typeof(string));
338 return list;
339 }
340 }
341 public Type[] TypeList
342 {
343 get {
344 Type[] list = (Type[])ulist.ToArray(typeof(Type));
345 return list;
346 }
347 }
348 internal RFrmworkClass AddFrameworkClass(Type tp)
349 {
350 string cname = tp.ToString().Replace('.', '_');
351 uint cid = ruby.intern(cname);
352 if (IsConstDefined(cid))
353 {
354 return (RFrmworkClass)ConstGet(cid);
355 }
356 ruby.warning("Implicitly create DotNet class `{0}'", cname);
357 if (ruby.SafeLevel >= 3)
358 throw new SecurityException("Insecure: can't add DotNet Class");
359 return NewFrameworkClass(tp);
360 }
361 public RFrmworkClass NewFrameworkClass(object[] args)
362 {
363 if (args.Length < 1)
364 throw new ArgumentException("wrong # of arguments(at least 1)");
365 string typename = args[0].ToString();
366 Type tp = null;
367 StringBuilder sb = new StringBuilder(255);
368 if (typename.IndexOf('.') >= 0)
369 {
370 if (tlist.ContainsKey(typename))
371 tp = (Type)tlist[typename];
372 else
373 {
374 tp = Type.GetType(typename);
375 if (tp != null)
376 {
377 lock (tlist.SyncRoot)
378 {
379 tlist[typename] = tp;
380 }
381 }
382 }
383 sb.Append(typename);
384 }
385 else
386 {
387 lock (ulist.SyncRoot)
388 {
389 foreach (string s in ulist)
390 {
391 sb.Length = 0;
392 string sname = sb.AppendFormat("{0}.{1}", s, typename).ToString();
393 if (tlist.ContainsKey(sname))
394 {
395 tp = (Type)tlist[sname];
396 break;
397 }
398 tp = Type.GetType(sname);
399 if (tp != null)
400 {
401 lock (tlist.SyncRoot)
402 {
403 tlist[sname] = tp;
404 }
405 break;
406 }
407 }
408 }
409 }
410 if (tp == null)
411 {
412 sb.Length = 0;
413 throw new ArgumentException(sb.AppendFormat("type {0} not found", typename).ToString());
414 }
415 return NewFrameworkClass(tp);
416 }
417
418 public RFrmworkClass NewFrameworkClass(Type tp)
419 {
420 StringBuilder sb = new StringBuilder(tp.ToString());
421 sb[0] = Char.ToUpper(sb[0]);
422 string cname = sb.Replace('.', '_').ToString();
423 uint id = ruby.intern(cname);
424 if (IsConstDefinedAt(id))
425 {
426 return (RFrmworkClass)ConstGetAt(id);
427 }
428 RFrmworkClass frm = new RFrmworkClass(ruby, cname, ruby.cObject, tp);
429 frm.DefineClass(cname, ruby.cObject);
430 ConstSet(id, frm);
431 frm.DefineSingletonMethod("attach", new RMethod(frm.attach), 1);
432 foreach (FieldInfo finf in tp.GetFields())
433 {
434 if (finf.IsLiteral && finf.IsStatic)
435 {
436 frm.ConstSet(ruby.intern(finf.Name), finf.GetValue(null));
437 }
438 }
439 return frm;
440 }
441 internal static object dn_new(RBasic r, params object[] args)
442 {
443 RBasic o = ((RDotNetClass)r).NewFrameworkClass(args);
444 return o;
445 }
446 internal static object dn_ulist(RBasic r, params object[] args)
447 {
448 RDotNetClass rd = (RDotNetClass)r;
449 return new RArray(rd.ruby, rd.ulist, true);
450 }
451 internal static object dn_tlist(RBasic r, params object[] args)
452 {
453 RDotNetClass rd = (RDotNetClass)r;
454 ArrayList arry = new ArrayList(rd.tlist.Count);
455 lock (rd.tlist.SyncRoot)
456 {
457 foreach (DictionaryEntry ent in rd.tlist)
458 {
459 arry.Add(ent.Key);
460 }
461 }
462 return new RArray(rd.ruby, arry);
463 }
464 internal static object dn_using(RBasic r, params object[] args)
465 {
466 string s = args[0].ToString();
467 return r.ruby.cDotNet.Using(s);
468 }
469 internal static void Init(NetRuby rb)
470 {
471 RDotNetClass dn = new RDotNetClass(rb);
472 dn.DefineClass("DotNet", rb.cObject);
473 rb.cDotNet = dn;
474 dn.DefineSingletonMethod("new", new RMethod(dn_new), -1);
475 dn.DefineSingletonMethod("using_list", new RMethod(dn_ulist), 0);
476 dn.DefineSingletonMethod("type_list", new RMethod(dn_tlist), 0);
477 dn.DefineSingletonMethod("using", new RMethod(dn_using), 1);
478 rb.DefineGlobalFunction("using", new RMethod(dn_using), 1);
479 }
480 }
481 }

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26