| 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 |
} |