Develop and Download Open Source Software

Browse CVS Repository

Contents of /netruby/netruby/array.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:06 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.Text;
11 using System.Globalization;
12 using System.Collections;
13 using System.Reflection;
14 using System.Security;
15
16 namespace arton.NETRuby
17 {
18 public class RArray : RBasic, ICloneable, IList, IEnumerable
19 {
20 public RArray(NetRuby rb, ArrayList a) :
21 base(rb, rb.cArray)
22 {
23 ptr = a;
24 }
25 public RArray(NetRuby rb, ArrayList a, bool clone) :
26 base(rb, rb.cArray)
27 {
28 if (clone)
29 {
30 // but it creates only a shallow copy.
31 ptr = (ArrayList)a.Clone();
32 }
33 else
34 {
35 ptr = a;
36 }
37 }
38 public RArray(NetRuby rb, ICollection col) :
39 base(rb, rb.cArray)
40 {
41 ptr = new ArrayList(col);
42 }
43 public RArray(NetRuby rb, bool newobj) :
44 base(rb, rb.cArray)
45 {
46 ptr = (newobj) ? new ArrayList() : null;
47 }
48 public RArray(NetRuby rb, bool newobj, RMetaObject spr) :
49 base(rb, spr)
50 {
51 ptr = (newobj) ? new ArrayList() : null;
52 }
53 public RArray(NetRuby rb, int capa) :
54 base(rb, rb.cArray)
55 {
56 ptr = new ArrayList(capa);
57 }
58
59 public ArrayList ArrayList
60 {
61 get { return ptr; }
62 }
63
64 public bool IsFixedSize
65 {
66 get { return false; }
67 }
68 public bool IsReadOnly
69 {
70 get { return IsFrozen; }
71 }
72
73 public override RArray ToArray()
74 {
75 return this;
76 }
77
78 public object[] Array
79 {
80 get { return ptr.ToArray(); }
81 }
82
83 public object Clone()
84 {
85 RArray ra = new RArray(ruby, (ArrayList)ptr.Clone());
86 if (Test(FL.TAINT)) ra.Set(FL.TAINT);
87 return ra;
88 }
89
90 public override string ToString()
91 {
92 if (ptr == null || ptr.Count <= 0) return String.Empty;
93 return Join(ruby.outputFS).ToString();
94 }
95
96 public override RString ToRString()
97 {
98 if (ptr.Count <= 0) return new RString(ruby, String.Empty, false);
99 return Join(ruby.outputFS);
100 }
101
102 public override object Inspect()
103 {
104 if (ptr.Count == 0) return "[]";
105 if (ruby.IsInspecting(this)) return "[...]";
106 return ruby.ProtectInspect(this,
107 new InspectMethod(inspect_ary),
108 new object[2] {this, 0});
109 }
110
111 public void Clear()
112 {
113 ptr.Clear();
114 }
115 public RArray Clear2()
116 {
117 ptr.Clear();
118 return this;
119 }
120
121 static public RArray AssocNew(NetRuby ruby, RBasic car, RBasic cdr)
122 {
123 ArrayList ar = new ArrayList();
124 ar.Add(car);
125 ar.Add(cdr);
126 return new RArray(ruby, ar);
127 }
128 static public RArray AssocNew(NetRuby ruby, object car, object cdr)
129 {
130 ArrayList ar = new ArrayList();
131 ar.Add(car);
132 ar.Add(cdr);
133 return new RArray(ruby, ar);
134 }
135
136 public RArray Fill(object[] argv)
137 {
138 object[] args = new object[3];
139 ruby.ScanArgs(argv, "12", args);
140 int beg = 0;
141 int len = ptr.Count;
142 switch (argv.Length)
143 {
144 case 1:
145 break;
146 case 2:
147 //range
148 goto case 3;
149 case 3:
150 beg = (args[1] == null) ? 0 : (int)args[1];
151 if (beg < 0)
152 {
153 beg = ptr.Count + beg;
154 if (beg < 0) beg = 0;
155 }
156 len = (args[2] == null) ? ptr.Count - beg : (int)args[2];
157 break;
158 }
159 CheckModify();
160 int end = beg + len;
161 if (end > ptr.Count)
162 {
163 ptr.AddRange(new object[end - ptr.Count]);
164 }
165 for (int i = beg; i < len; i++)
166 {
167 ptr[i] = args[0];
168 }
169 return this;
170 }
171
172 public bool Contains(object o)
173 {
174 return ptr.Contains(o);
175 }
176
177 public RArray ToRArrayWith(object x)
178 {
179 if (x is ArrayList)
180 return new RArray(ruby, (ArrayList)x);
181 return (RArray)ruby.ConvertType(x, typeof(RArray), "Array", "to_ary");
182 }
183
184 public RArray Concat(object o)
185 {
186 RArray ary = ToRArrayWith(o);
187 ptr.AddRange(ary.ptr);
188 return this;
189 }
190
191 public RString JoinMethod(object[] argv)
192 {
193 object[] args = new object[1];
194 ruby.ScanArgs(argv, "01", args);
195 return Join((args[0] == null) ? ruby.outputFS : args[0]);
196 }
197
198 public RString Join(object sep)
199 {
200 if (ptr.Count <= 0) return new RString(ruby, String.Empty, false);
201 bool taint = IsTainted;
202 if (sep is RBasic && ((RBasic)sep).IsTainted)
203 {
204 taint = true;
205 }
206 string ssep = String.Empty;
207 if (sep != null)
208 {
209 if (sep is string || sep is RString)
210 {
211 ssep = sep.ToString();
212 }
213 else
214 {
215 ssep = RString.StringToRString(ruby, sep).ToString();
216 }
217 }
218 string result = String.Empty;
219 string tmp;
220 for (int i = 0; i < ptr.Count; i++)
221 {
222 object o = ptr[i];
223 if (o is RBasic && ((RBasic)o).IsTainted) taint = true;
224
225 if (o is string || o is RString)
226 {
227 tmp = o.ToString();
228 }
229 else if (o is RArray)
230 {
231 if (ruby.IsInspecting(o))
232 {
233 tmp = "[...]";
234 }
235 else
236 {
237 tmp = ruby.ProtectInspect(this,
238 new InspectMethod(inspect_join),
239 new object[2] {o, sep}).ToString();
240 }
241 }
242 else
243 {
244 tmp = RString.AsString(ruby, o);
245 }
246 if (i > 0)
247 {
248 result += ssep;
249 }
250 result += tmp;
251 }
252 return new RString(ruby, result, taint);
253 }
254
255 public RArray Reverse()
256 {
257 RArray ary = (RArray)Clone();
258 return ary.ReverseAt();
259 }
260 public RArray ReverseAt()
261 {
262 CheckModify();
263 ptr.Reverse();
264 return this;
265 }
266 public RArray Sort()
267 {
268 RArray ary = (RArray)Clone();
269 return ary.SortAt();
270 }
271 public RArray SortAt()
272 {
273 CheckModify();
274 ptr.Sort();
275 return this;
276 }
277 public RArray Collect()
278 {
279 if (ruby.IsBlockGiven == false)
280 return (RArray)Clone();
281 RArray collect = new RArray(ruby, ptr.Count);
282 lock (ptr.SyncRoot)
283 {
284 foreach (object o in ptr)
285 {
286 collect.Add(ruby.Yield(o));
287 }
288 }
289 return collect;
290 }
291 public RArray CollectAt()
292 {
293 CheckModify();
294 lock (ptr.SyncRoot)
295 {
296 for (int i = 0; i < ptr.Count; i++)
297 {
298 ptr[i] = ruby.Yield(ptr[i]);
299 }
300 }
301 return this;
302 }
303
304 private object inspect_ary(RBasic ary, object[] args)
305 {
306 bool taint = false;
307 StringBuilder result = new StringBuilder("[");
308 for (int i = 0; i < ptr.Count; i++)
309 {
310 object o = ruby.Inspect(ptr[i]);
311 if (o is RBasic && ((RBasic)o).IsTainted) taint = true;
312 if (i > 0)
313 result.AppendFormat(", {0}", (o == null) ? "nil" : o.ToString());
314 else
315 result.Append(o.ToString());
316 }
317 result.Append("]");
318 if (IsTainted || taint)
319 return new RString(ruby, result.ToString(), true);
320 else
321 return result.ToString();
322 }
323 private object inspect_join(RBasic ary, object[] args)
324 {
325 RString rs = ((RArray)args[0]).Join(args[1]);
326 return rs;
327 }
328
329 public RArray Initialize(object[] argv)
330 {
331 object[] args = new object[2];
332 if (ruby.ScanArgs(argv, "02", args) == 0)
333 {
334 ptr = new ArrayList();
335 return this;
336 }
337 CheckModify();
338 int len = (int)args[0];
339 if (len < 0)
340 {
341 throw new ArgumentException("negative array size");
342 }
343 if (len > ptr.Capacity)
344 {
345 ptr = ArrayList.Repeat(args[1], len);
346 }
347 return this;
348 }
349
350 private void CheckModify()
351 {
352 if (IsFrozen) ruby.ErrorFrozen("array");
353 // Sort is done by .NET Framework
354 if (IsTainted == false && ruby.SafeLevel >= 4)
355 throw new SecurityException("Insecure: can't modify array");
356 }
357
358 internal static object s_new(RBasic r, params object[] args)
359 {
360 NetRuby rb = r.ruby;
361 RArray a = new RArray(rb, false, (RMetaObject)r);
362 rb.CallInit(a, args);
363 if (a.ptr == null) a.ptr = new ArrayList();
364 return a;
365 }
366
367 internal static RArray Create(NetRuby rb, object[] args)
368 {
369 RArray a = new RArray(rb, args);
370 return a;
371 }
372
373 public object this[int index]
374 {
375 get {
376 if (ptr.Count == 0) return null;
377 if (index < 0)
378 {
379 index += ptr.Count;
380 }
381 if (index < 0 || ptr.Count <= index)
382 {
383 return null;
384 }
385 return ptr[index];
386 }
387 set {
388 if (index >= ptr.Count)
389 {
390 ptr.Insert(index, value);
391 }
392 else
393 {
394 ptr[index] = value;
395 }
396 }
397 }
398 public object First
399 {
400 get { return (ptr.Count == 0) ? null : ptr[0]; }
401 }
402 public object Last
403 {
404 get { return (ptr.Count == 0) ? null : ptr[ptr.Count - 1]; }
405 }
406 internal object ARef(object[] argv)
407 {
408 int beg, len;
409 object[] args = new object[2];
410 if (ruby.ScanArgs(argv, "11", args) == 2)
411 {
412 beg = RInteger.ToInt(ruby, args[0]);
413 len = RInteger.ToInt(ruby, args[1]);
414 if (beg < 0)
415 beg += ptr.Count;
416 return Subseq(beg, len);
417 }
418 int offset;
419 if (args[0] is int)
420 offset = (int)args[0];
421 else if (args[0] is RBignum)
422 throw new eIndexError("index too big");
423 else
424 // Range object check
425 offset = RInteger.ToInt(ruby, args[0]);
426 if (offset < 0)
427 offset = ptr.Count + offset;
428 if (offset < 0 || ptr.Count <= offset)
429 return null;
430 return ptr[offset];
431 }
432 internal object Subseq(int beg, int len)
433 {
434 if (beg > ptr.Count) return null;
435 if (beg < 0 || len < 0) return null;
436 if (beg + len > ptr.Count)
437 {
438 len = ptr.Count - beg;
439 }
440 if (len < 0) len = 0;
441 if (len == 0) return new RArray(ruby, true);
442 RArray ary2 = new RArray(ruby, ptr.GetRange(beg, len));
443 ary2.klass = Class;
444 return ary2;
445 }
446 internal void Replace(int beg, int len, object rpl)
447 {
448 if (len < 0) throw new ArgumentOutOfRangeException("negative length " + len.ToString());
449 if (beg < 0)
450 beg += ptr.Count;
451 if (beg < 0)
452 {
453 beg -= ptr.Count;
454 throw new ArgumentOutOfRangeException("index " + beg.ToString() + " out of array");
455 }
456 if (beg + len > ptr.Count)
457 {
458 len = ptr.Count - beg;
459 }
460 ArrayList ary2;
461 if (rpl == null)
462 {
463 ary2 = new ArrayList();
464 }
465 else if (rpl is RArray == false)
466 {
467 ary2 = new ArrayList();
468 ary2.Add(rpl);
469 }
470 else
471 {
472 ary2 = ((RArray)rpl).ArrayList;
473 }
474 CheckModify();
475 if (beg >= ptr.Count)
476 {
477 if (beg > ptr.Count)
478 ptr.AddRange(new object[beg - ptr.Count]);
479 ptr.AddRange(ary2);
480 }
481 else
482 {
483 if (beg + len > ptr.Count)
484 {
485 len = ptr.Count - beg;
486 }
487 ptr.RemoveRange(beg, len);
488 ptr.InsertRange(beg, ary2);
489 }
490 #if ARRAY_DEBUG
491 System.Console.WriteLine("replace");
492 foreach (object x in ptr)
493 {
494 System.Console.WriteLine(" - " + ((x == null) ? "null" : x.ToString()));
495 }
496 System.Console.WriteLine("done");
497 #endif
498 }
499 internal object ASet(object[] argv)
500 {
501 if (argv.Length == 3)
502 {
503 Replace((int)argv[0], (int)argv[1], argv[2]);
504 return argv[2];
505 }
506 if (argv.Length != 2)
507 {
508 throw new ArgumentException("wrong # of argments(" + argv.Length.ToString() + " for 2)");
509 }
510 // Range object check
511 CheckModify();
512 int idx = RInteger.ToInt(ruby, argv[0]);
513 if (idx < 0)
514 {
515 idx += ptr.Count;
516 if (idx < 0)
517 throw new eIndexError(String.Format("index {0} out of array",
518 idx - ptr.Count));
519 }
520 if (idx >= ptr.Count)
521 {
522 ptr.Insert(idx, argv[1]);
523 }
524 else
525 {
526 ptr[idx] = argv[1];
527 }
528 return argv[1];
529 }
530 internal object At(int pos)
531 {
532 return this[pos];
533 }
534 internal object Push(params object[] argv)
535 {
536 if (argv.Length == 0)
537 {
538 throw new ArgumentException("wrong # of arguments(at least 1)");
539 }
540 CheckModify();
541 ptr.AddRange(argv);
542 return this;
543 }
544 public int Add(object o)
545 {
546 return ptr.Add(o);
547 }
548 internal object Pop()
549 {
550 CheckModify();
551 if (ptr.Count == 0) return null;
552 object result = ptr[ptr.Count - 1];
553 ptr.Remove(ptr.Count - 1);
554 return result;
555 }
556 internal object Shift()
557 {
558 CheckModify();
559 if (ptr.Count == 0) return null;
560 object result = ptr[0];
561 ptr.RemoveAt(0);
562 return result;
563 }
564 internal object Unshift(params object[] args)
565 {
566 if (args == null || args.Length == 0)
567 throw new eArgError("wrong # of arguments(at least 1)");
568
569 CheckModify();
570 ptr.InsertRange(0, args);
571 return this;
572 }
573 internal RArray Each()
574 {
575 foreach (object o in ptr)
576 {
577 ruby.Yield(o);
578 }
579 return this;
580 }
581 internal RArray EachIndex()
582 {
583 for (int i = 0; i < ptr.Count; i++)
584 {
585 ruby.Yield(i);
586 }
587 return this;
588 }
589 internal RArray ReverseEach()
590 {
591 for (int i = ptr.Count - 1; i >= 0; i--)
592 {
593 ruby.Yield(ptr[i]);
594 }
595 return this;
596 }
597 internal bool ArrayEqual(object o)
598 {
599 if (this == o) return true;
600 if (o is RArray == false) return false;
601 RArray a = (RArray)o;
602 if (ptr == a.ptr) return true;
603 if (ptr.Count != a.ptr.Count) return false;
604 for (int i = 0; i < ptr.Count; i++)
605 {
606 if (ruby.Equal(ptr[i], a.ptr[i]) == false) return false;
607 }
608 return true;
609 }
610 internal bool ArrayEql(object o)
611 {
612 if (o is RArray == false) return false;
613 RArray a = (RArray)o;
614 if (ptr.Count != a.ptr.Count) return false;
615 for (int i = 0; i < ptr.Count; i++)
616 {
617 if (ruby.Eql(ptr[i], a.ptr[i])== false) return false;
618 }
619 return true;
620 }
621 public IEnumerator GetEnumerator()
622 {
623 return ptr.GetEnumerator();
624 }
625 public int Count
626 {
627 get { return ptr.Count; }
628 }
629 public bool IsSynchronized
630 {
631 get { return ptr.IsSynchronized; }
632 }
633 public object SyncRoot
634 {
635 get { return ptr.SyncRoot; }
636 }
637 public void CopyTo(Array array, int index)
638 {
639 ptr.CopyTo(array, index);
640 }
641 public bool IsEmpty
642 {
643 get { return (ptr.Count == 0); }
644 }
645 public int IndexOf(object o)
646 {
647 for (int i = 0; i < ptr.Count; i++)
648 {
649 if (ruby.Equal(ptr[i], o)) return i;
650 }
651 return -1;
652 }
653 public void Insert(int index, object value)
654 {
655 ptr.Insert(index, value);
656 }
657 public void Remove(object o)
658 {
659 int i = IndexOf(o);
660 if (i >= 0) RemoveAt(i);
661 }
662 public void RemoveAt(int i)
663 {
664 if (i < 0 || i >= ptr.Count) throw new ArgumentOutOfRangeException();
665 try
666 {
667 DeleteAt(i);
668 }
669 catch (SecurityException)
670 {
671 throw new NotSupportedException();
672 }
673 catch (eTypeError)
674 {
675 throw new NotSupportedException();
676 }
677 }
678 internal object Delete(object item)
679 {
680 int pos = ptr.Count;
681 Remove(item);
682 if (ptr.Count == pos)
683 {
684 if (ruby.IsBlockGiven)
685 {
686 ruby.Yield(item);
687 }
688 return null;
689 }
690 return item;
691 }
692 internal object DeleteAt(int pos)
693 {
694 CheckModify();
695 if (pos >= ptr.Count) return null;
696 if (pos < 0) pos += ptr.Count;
697 if (pos < 0) return null;
698 object del = ptr[pos];
699 ptr.RemoveAt(pos);
700 return del;
701 }
702 public object Index(object o)
703 {
704 int i = IndexOf(o);
705 if (i < 0)
706 return null;
707 return i;
708 }
709 public object RIndex(object o)
710 {
711 for (int i = ptr.Count - 1; i >= 0; i--)
712 {
713 if (ruby.Equal(ptr[i], o)) return i;
714 }
715 return null;
716 }
717 ArrayList ptr;
718
719 static internal void Init(NetRuby rb)
720 {
721 BindingFlags bf = BindingFlags.InvokeMethod
722 | BindingFlags.Static | BindingFlags.Public
723 | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy
724 | BindingFlags.Instance;
725 RClass ary = rb.DefineClass("Array", rb.cObject);
726 RMetaObject.IncludeModule(ary, rb.mEnumerable);
727 rb.cArray = ary;
728 Type obj = typeof(RArray);
729 ary.DefineSingletonMethod("new", new RMethod(s_new), -1);
730 ary.DefineSingletonMethod("[]", obj.GetMethod("Create", bf));
731
732 ary.DefineMethod("initialize", obj.GetMethod("Initialize", bf));
733
734 ary.DefineMethod("to_ary", obj.GetMethod("ToArray", bf));
735 ary.DefineMethod("==", obj.GetMethod("ArrayEqual", bf));
736 ary.DefineMethod("eql?", obj.GetMethod("ArrayEql", bf));
737
738 ary.DefineMethod("[]", obj.GetMethod("ARef", bf));
739 ary.DefineMethod("[]=", obj.GetMethod("ASet", bf));
740 ary.DefineMethod("at", obj.GetMethod("At", bf));
741 ary.DefineMethod("first", obj.GetMethod("get_First", bf));
742 ary.DefineMethod("last", obj.GetMethod("get_Last", bf));
743 ary.DefineMethod("concat", obj.GetMethod("Concat", bf));
744 ary.DefineMethod("<<", obj.GetMethod("Push", bf));
745 ary.DefineMethod("push", obj.GetMethod("Push", bf));
746 ary.DefineMethod("pop", obj.GetMethod("Pop", bf));
747 ary.DefineMethod("shift", obj.GetMethod("Shift", bf));
748 ary.DefineMethod("unshift", obj.GetMethod("Unshift", bf));
749 ary.DefineMethod("each", obj.GetMethod("Each", bf));
750 ary.DefineMethod("each_index", obj.GetMethod("EachIndex", bf));
751 ary.DefineMethod("reverse_each", obj.GetMethod("ReverseEach", bf));
752 ary.DefineMethod("length", obj.GetMethod("get_Count", bf));
753 ary.DefineAlias("size", "length");
754 ary.DefineMethod("empty?", obj.GetMethod("get_IsEmpty", bf));
755 ary.DefineMethod("index", obj.GetMethod("Index", bf));
756 ary.DefineMethod("rindex", obj.GetMethod("RIndex", bf));
757
758 ary.DefineMethod("clone", obj.GetMethod("Clone", bf));
759 ary.DefineMethod("join", obj.GetMethod("JoinMethod", bf));
760
761 ary.DefineMethod("reverse", obj.GetMethod("Reverse", bf));
762 ary.DefineMethod("reverse!", obj.GetMethod("ReverseAt", bf));
763 ary.DefineMethod("sort", obj.GetMethod("Sort", bf));
764 ary.DefineMethod("sort!", obj.GetMethod("SortAt", bf));
765 ary.DefineMethod("collect", obj.GetMethod("Collect", bf));
766 ary.DefineMethod("collect!", obj.GetMethod("CollectAt", bf));
767
768 ary.DefineMethod("delete", obj.GetMethod("Delete", bf));
769 ary.DefineMethod("delete_at", obj.GetMethod("DeleteAt", bf));
770
771 ary.DefineMethod("clear", obj.GetMethod("Clear2", bf));
772 ary.DefineMethod("fill", obj.GetMethod("Fill", bf));
773 ary.DefineMethod("include", obj.GetMethod("Contains", bf));
774 }
775 }
776 }

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