Source Code Cross Referenced for RubyArray.java in  » Scripting » jruby » org » jruby » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Scripting » jruby » org.jruby 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /***** BEGIN LICENSE BLOCK *****
0002:         * Version: CPL 1.0/GPL 2.0/LGPL 2.1
0003:         *
0004:         * The contents of this file are subject to the Common Public
0005:         * License Version 1.0 (the "License"); you may not use this file
0006:         * except in compliance with the License. You may obtain a copy of
0007:         * the License at http://www.eclipse.org/legal/cpl-v10.html
0008:         *
0009:         * Software distributed under the License is distributed on an "AS
0010:         * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
0011:         * implied. See the License for the specific language governing
0012:         * rights and limitations under the License.
0013:         *
0014:         * Copyright (C) 2001 Alan Moore <alan_moore@gmx.net>
0015:         * Copyright (C) 2001 Chad Fowler <chadfowler@chadfowler.com>
0016:         * Copyright (C) 2001-2002 Benoit Cerrina <b.cerrina@wanadoo.fr>
0017:         * Copyright (C) 2001-2004 Jan Arne Petersen <jpetersen@uni-bonn.de>
0018:         * Copyright (C) 2002-2004 Anders Bengtsson <ndrsbngtssn@yahoo.se>
0019:         * Copyright (C) 2002-2005 Thomas E Enebo <enebo@acm.org>
0020:         * Copyright (C) 2004-2005 Charles O Nutter <headius@headius.com>
0021:         * Copyright (C) 2004 Stefan Matthias Aust <sma@3plus4.de>
0022:         * Copyright (C) 2006 Ola Bini <Ola.Bini@ki.se>
0023:         * Copyright (C) 2006 Daniel Steer <damian.steer@hp.com>
0024:         * 
0025:         * Alternatively, the contents of this file may be used under the terms of
0026:         * either of the GNU General Public License Version 2 or later (the "GPL"),
0027:         * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
0028:         * in which case the provisions of the GPL or the LGPL are applicable instead
0029:         * of those above. If you wish to allow use of your version of this file only
0030:         * under the terms of either the GPL or the LGPL, and not to allow others to
0031:         * use your version of this file under the terms of the CPL, indicate your
0032:         * decision by deleting the provisions above and replace them with the notice
0033:         * and other provisions required by the GPL or the LGPL. If you do not delete
0034:         * the provisions above, a recipient may use your version of this file under
0035:         * the terms of any one of the CPL, the GPL or the LGPL.
0036:         ***** END LICENSE BLOCK *****/package org.jruby;
0037:
0038:        import java.lang.reflect.Array;
0039:        import java.io.IOException;
0040:        import java.util.Arrays;
0041:        import java.util.Collection;
0042:        import java.util.Comparator;
0043:        import java.util.HashSet;
0044:        import java.util.Iterator;
0045:        import java.util.List;
0046:        import java.util.ListIterator;
0047:        import java.util.Set;
0048:        import org.jruby.javasupport.JavaUtil;
0049:        import org.jruby.runtime.Arity;
0050:        import org.jruby.runtime.Block;
0051:        import org.jruby.runtime.CallType;
0052:        import org.jruby.runtime.CallbackFactory;
0053:        import org.jruby.runtime.ClassIndex;
0054:        import org.jruby.runtime.MethodIndex;
0055:        import org.jruby.runtime.ObjectAllocator;
0056:        import org.jruby.runtime.ThreadContext;
0057:        import org.jruby.runtime.builtin.IRubyObject;
0058:        import org.jruby.runtime.marshal.MarshalStream;
0059:        import org.jruby.runtime.marshal.UnmarshalStream;
0060:        import org.jruby.util.ByteList;
0061:        import org.jruby.util.Pack;
0062:
0063:        /**
0064:         * The implementation of the built-in class Array in Ruby.
0065:         */
0066:        public class RubyArray extends RubyObject implements  List {
0067:
0068:            public static RubyClass createArrayClass(Ruby runtime) {
0069:                RubyClass arrayc = runtime.defineClass("Array", runtime
0070:                        .getObject(), ARRAY_ALLOCATOR);
0071:                arrayc.index = ClassIndex.ARRAY;
0072:                CallbackFactory callbackFactory = runtime
0073:                        .callbackFactory(RubyArray.class);
0074:
0075:                arrayc.includeModule(runtime.getModule("Enumerable"));
0076:                arrayc.getMetaClass().defineMethod("[]",
0077:                        callbackFactory.getOptSingletonMethod("create"));
0078:
0079:                arrayc.defineMethod("initialize", callbackFactory
0080:                        .getOptMethod("initialize"));
0081:                arrayc.defineFastMethod("initialize_copy", callbackFactory
0082:                        .getFastMethod("replace", RubyKernel.IRUBY_OBJECT));
0083:                arrayc.defineFastMethod("to_s", callbackFactory
0084:                        .getFastMethod("to_s"));
0085:                arrayc.defineFastMethod("inspect", callbackFactory
0086:                        .getFastMethod("inspect"));
0087:                arrayc.defineFastMethod("to_a", callbackFactory
0088:                        .getFastMethod("to_a"));
0089:                arrayc.defineFastMethod("to_ary", callbackFactory
0090:                        .getFastMethod("to_ary"));
0091:                arrayc.defineFastMethod("frozen?", callbackFactory
0092:                        .getFastMethod("frozen"));
0093:
0094:                arrayc.defineFastMethod("==", callbackFactory.getFastMethod(
0095:                        "op_equal", RubyKernel.IRUBY_OBJECT));
0096:                arrayc.defineFastMethod("eql?", callbackFactory.getFastMethod(
0097:                        "eql_p", RubyKernel.IRUBY_OBJECT));
0098:                arrayc.defineFastMethod("hash", callbackFactory
0099:                        .getFastMethod("hash"));
0100:
0101:                arrayc.defineFastMethod("[]", callbackFactory
0102:                        .getFastOptMethod("aref"));
0103:                arrayc.defineFastMethod("[]=", callbackFactory
0104:                        .getFastOptMethod("aset"));
0105:                arrayc.defineFastMethod("at", callbackFactory.getFastMethod(
0106:                        "at", RubyKernel.IRUBY_OBJECT));
0107:                arrayc.defineMethod("fetch", callbackFactory
0108:                        .getOptMethod("fetch"));
0109:                arrayc.defineFastMethod("first", callbackFactory
0110:                        .getFastOptMethod("first"));
0111:                arrayc.defineFastMethod("last", callbackFactory
0112:                        .getFastOptMethod("last"));
0113:                arrayc.defineFastMethod("concat", callbackFactory
0114:                        .getFastMethod("concat", RubyKernel.IRUBY_OBJECT));
0115:                arrayc.defineFastMethod("<<", callbackFactory.getFastMethod(
0116:                        "append", RubyKernel.IRUBY_OBJECT));
0117:                arrayc.defineFastMethod("push", callbackFactory
0118:                        .getFastOptMethod("push_m"));
0119:                arrayc.defineFastMethod("pop", callbackFactory
0120:                        .getFastMethod("pop"));
0121:                arrayc.defineFastMethod("shift", callbackFactory
0122:                        .getFastMethod("shift"));
0123:                arrayc.defineFastMethod("unshift", callbackFactory
0124:                        .getFastOptMethod("unshift_m"));
0125:                arrayc.defineFastMethod("insert", callbackFactory
0126:                        .getFastOptMethod("insert"));
0127:                arrayc.defineMethod("each", callbackFactory.getMethod("each"));
0128:                arrayc.defineMethod("each_index", callbackFactory
0129:                        .getMethod("each_index"));
0130:                arrayc.defineMethod("reverse_each", callbackFactory
0131:                        .getMethod("reverse_each"));
0132:                arrayc.defineFastMethod("length", callbackFactory
0133:                        .getFastMethod("length"));
0134:                arrayc.defineAlias("size", "length");
0135:                arrayc.defineFastMethod("empty?", callbackFactory
0136:                        .getFastMethod("empty_p"));
0137:                arrayc.defineFastMethod("index", callbackFactory.getFastMethod(
0138:                        "index", RubyKernel.IRUBY_OBJECT));
0139:                arrayc.defineFastMethod("rindex", callbackFactory
0140:                        .getFastMethod("rindex", RubyKernel.IRUBY_OBJECT));
0141:                arrayc.defineFastMethod("indexes", callbackFactory
0142:                        .getFastOptMethod("indexes"));
0143:                arrayc.defineFastMethod("indices", callbackFactory
0144:                        .getFastOptMethod("indexes"));
0145:                arrayc.defineFastMethod("join", callbackFactory
0146:                        .getFastOptMethod("join_m"));
0147:                arrayc.defineFastMethod("reverse", callbackFactory
0148:                        .getFastMethod("reverse"));
0149:                arrayc.defineFastMethod("reverse!", callbackFactory
0150:                        .getFastMethod("reverse_bang"));
0151:                arrayc.defineMethod("sort", callbackFactory.getMethod("sort"));
0152:                arrayc.defineMethod("sort!", callbackFactory
0153:                        .getMethod("sort_bang"));
0154:                arrayc.defineMethod("collect", callbackFactory
0155:                        .getMethod("collect"));
0156:                arrayc.defineMethod("collect!", callbackFactory
0157:                        .getMethod("collect_bang"));
0158:                arrayc
0159:                        .defineMethod("map", callbackFactory
0160:                                .getMethod("collect"));
0161:                arrayc.defineMethod("map!", callbackFactory
0162:                        .getMethod("collect_bang"));
0163:                arrayc.defineMethod("select", callbackFactory
0164:                        .getMethod("select"));
0165:                arrayc.defineFastMethod("values_at", callbackFactory
0166:                        .getFastOptMethod("values_at"));
0167:                arrayc.defineMethod("delete", callbackFactory.getMethod(
0168:                        "delete", RubyKernel.IRUBY_OBJECT));
0169:                arrayc.defineFastMethod("delete_at", callbackFactory
0170:                        .getFastMethod("delete_at", RubyKernel.IRUBY_OBJECT));
0171:                arrayc.defineMethod("delete_if", callbackFactory
0172:                        .getMethod("delete_if"));
0173:                arrayc.defineMethod("reject", callbackFactory
0174:                        .getMethod("reject"));
0175:                arrayc.defineMethod("reject!", callbackFactory
0176:                        .getMethod("reject_bang"));
0177:                arrayc.defineMethod("zip", callbackFactory.getOptMethod("zip"));
0178:                arrayc.defineFastMethod("transpose", callbackFactory
0179:                        .getFastMethod("transpose"));
0180:                arrayc.defineFastMethod("replace", callbackFactory
0181:                        .getFastMethod("replace", RubyKernel.IRUBY_OBJECT));
0182:                arrayc.defineFastMethod("clear", callbackFactory
0183:                        .getFastMethod("rb_clear"));
0184:                arrayc.defineMethod("fill", callbackFactory
0185:                        .getOptMethod("fill"));
0186:                arrayc.defineFastMethod("include?", callbackFactory
0187:                        .getFastMethod("include_p", RubyKernel.IRUBY_OBJECT));
0188:                arrayc.defineFastMethod("<=>", callbackFactory.getFastMethod(
0189:                        "op_cmp", RubyKernel.IRUBY_OBJECT));
0190:
0191:                arrayc.defineFastMethod("slice", callbackFactory
0192:                        .getFastOptMethod("aref"));
0193:                arrayc.defineFastMethod("slice!", callbackFactory
0194:                        .getFastOptMethod("slice_bang"));
0195:
0196:                arrayc.defineFastMethod("assoc", callbackFactory.getFastMethod(
0197:                        "assoc", RubyKernel.IRUBY_OBJECT));
0198:                arrayc.defineFastMethod("rassoc", callbackFactory
0199:                        .getFastMethod("rassoc", RubyKernel.IRUBY_OBJECT));
0200:
0201:                arrayc.defineFastMethod("+", callbackFactory.getFastMethod(
0202:                        "op_plus", RubyKernel.IRUBY_OBJECT));
0203:                arrayc.defineFastMethod("*", callbackFactory.getFastMethod(
0204:                        "op_times", RubyKernel.IRUBY_OBJECT));
0205:
0206:                arrayc.defineFastMethod("-", callbackFactory.getFastMethod(
0207:                        "op_diff", RubyKernel.IRUBY_OBJECT));
0208:                arrayc.defineFastMethod("&", callbackFactory.getFastMethod(
0209:                        "op_and", RubyKernel.IRUBY_OBJECT));
0210:                arrayc.defineFastMethod("|", callbackFactory.getFastMethod(
0211:                        "op_or", RubyKernel.IRUBY_OBJECT));
0212:
0213:                arrayc.defineFastMethod("uniq", callbackFactory
0214:                        .getFastMethod("uniq"));
0215:                arrayc.defineFastMethod("uniq!", callbackFactory
0216:                        .getFastMethod("uniq_bang"));
0217:                arrayc.defineFastMethod("compact", callbackFactory
0218:                        .getFastMethod("compact"));
0219:                arrayc.defineFastMethod("compact!", callbackFactory
0220:                        .getFastMethod("compact_bang"));
0221:
0222:                arrayc.defineFastMethod("flatten", callbackFactory
0223:                        .getFastMethod("flatten"));
0224:                arrayc.defineFastMethod("flatten!", callbackFactory
0225:                        .getFastMethod("flatten_bang"));
0226:
0227:                arrayc.defineFastMethod("nitems", callbackFactory
0228:                        .getFastMethod("nitems"));
0229:
0230:                arrayc.defineFastMethod("pack", callbackFactory.getFastMethod(
0231:                        "pack", RubyKernel.IRUBY_OBJECT));
0232:
0233:                return arrayc;
0234:            }
0235:
0236:            private static ObjectAllocator ARRAY_ALLOCATOR = new ObjectAllocator() {
0237:                public IRubyObject allocate(Ruby runtime, RubyClass klass) {
0238:                    return new RubyArray(runtime, klass);
0239:                }
0240:            };
0241:
0242:            public static final byte OP_PLUS_SWITCHVALUE = 1;
0243:            public static final byte AREF_SWITCHVALUE = 2;
0244:            public static final byte ASET_SWITCHVALUE = 3;
0245:            public static final byte POP_SWITCHVALUE = 4;
0246:            public static final byte PUSH_SWITCHVALUE = 5;
0247:            public static final byte NIL_P_SWITCHVALUE = 6;
0248:            public static final byte EQUALEQUAL_SWITCHVALUE = 7;
0249:            public static final byte UNSHIFT_SWITCHVALUE = 8;
0250:            public static final byte OP_LSHIFT_SWITCHVALUE = 9;
0251:            public static final byte EMPTY_P_SWITCHVALUE = 10;
0252:            public static final byte TO_S_SWITCHVALUE = 11;
0253:            public static final byte AT_SWITCHVALUE = 12;
0254:            public static final byte TO_ARY_SWITCHVALUE = 13;
0255:            public static final byte TO_A_SWITCHVALUE = 14;
0256:            public static final byte HASH_SWITCHVALUE = 15;
0257:            public static final byte OP_TIMES_SWITCHVALUE = 16;
0258:            public static final byte OP_SPACESHIP_SWITCHVALUE = 17;
0259:            public static final byte LENGTH_SWITCHVALUE = 18;
0260:            public static final byte LAST_SWITCHVALUE = 19;
0261:            public static final byte SHIFT_SWITCHVALUE = 20;
0262:            public static final byte INSPECT_SWITCHVALUE = 21;
0263:
0264:            public IRubyObject callMethod(ThreadContext context,
0265:                    RubyModule rubyclass, int methodIndex, String name,
0266:                    IRubyObject[] args, CallType callType, Block block) {
0267:                // If tracing is on, don't do STI dispatch
0268:                if (context.getRuntime().hasEventHooks())
0269:                    return super .callMethod(context, rubyclass, name, args,
0270:                            callType, block);
0271:
0272:                switch (getRuntime().getSelectorTable().table[rubyclass.index][methodIndex]) {
0273:                case OP_PLUS_SWITCHVALUE:
0274:                    if (args.length != 1)
0275:                        throw context.getRuntime().newArgumentError(
0276:                                "wrong number of arguments(" + args.length
0277:                                        + " for " + 1 + ")");
0278:                    return op_plus(args[0]);
0279:                case AREF_SWITCHVALUE:
0280:                    return aref(args);
0281:                case ASET_SWITCHVALUE:
0282:                    return aset(args);
0283:                case POP_SWITCHVALUE:
0284:                    if (args.length != 0)
0285:                        throw context.getRuntime().newArgumentError(
0286:                                "wrong number of arguments(" + args.length
0287:                                        + " for " + 0 + ")");
0288:                    return pop();
0289:                case PUSH_SWITCHVALUE:
0290:                    return push_m(args);
0291:                case NIL_P_SWITCHVALUE:
0292:                    if (args.length != 0)
0293:                        throw context.getRuntime().newArgumentError(
0294:                                "wrong number of arguments(" + args.length
0295:                                        + " for " + 0 + ")");
0296:                    return nil_p();
0297:                case EQUALEQUAL_SWITCHVALUE:
0298:                    if (args.length != 1)
0299:                        throw context.getRuntime().newArgumentError(
0300:                                "wrong number of arguments(" + args.length
0301:                                        + " for " + 1 + ")");
0302:                    return op_equal(args[0]);
0303:                case UNSHIFT_SWITCHVALUE:
0304:                    return unshift_m(args);
0305:                case OP_LSHIFT_SWITCHVALUE:
0306:                    if (args.length != 1)
0307:                        throw context.getRuntime().newArgumentError(
0308:                                "wrong number of arguments(" + args.length
0309:                                        + " for " + 1 + ")");
0310:                    return append(args[0]);
0311:                case EMPTY_P_SWITCHVALUE:
0312:                    if (args.length != 0)
0313:                        throw context.getRuntime().newArgumentError(
0314:                                "wrong number of arguments(" + args.length
0315:                                        + " for " + 0 + ")");
0316:                    return empty_p();
0317:                case TO_S_SWITCHVALUE:
0318:                    if (args.length != 0)
0319:                        throw context.getRuntime().newArgumentError(
0320:                                "wrong number of arguments(" + args.length
0321:                                        + " for " + 0 + ")");
0322:                    return to_s();
0323:                case AT_SWITCHVALUE:
0324:                    if (args.length != 1)
0325:                        throw context.getRuntime().newArgumentError(
0326:                                "wrong number of arguments(" + args.length
0327:                                        + " for " + 1 + ")");
0328:                    return at(args[0]);
0329:                case TO_ARY_SWITCHVALUE:
0330:                    if (args.length != 0)
0331:                        throw context.getRuntime().newArgumentError(
0332:                                "wrong number of arguments(" + args.length
0333:                                        + " for " + 0 + ")");
0334:                    return to_ary();
0335:                case TO_A_SWITCHVALUE:
0336:                    if (args.length != 0)
0337:                        throw context.getRuntime().newArgumentError(
0338:                                "wrong number of arguments(" + args.length
0339:                                        + " for " + 0 + ")");
0340:                    return to_a();
0341:                case HASH_SWITCHVALUE:
0342:                    if (args.length != 0)
0343:                        throw context.getRuntime().newArgumentError(
0344:                                "wrong number of arguments(" + args.length
0345:                                        + " for " + 0 + ")");
0346:                    return hash();
0347:                case OP_TIMES_SWITCHVALUE:
0348:                    if (args.length != 1)
0349:                        throw context.getRuntime().newArgumentError(
0350:                                "wrong number of arguments(" + args.length
0351:                                        + " for " + 1 + ")");
0352:                    return op_times(args[0]);
0353:                case OP_SPACESHIP_SWITCHVALUE:
0354:                    if (args.length != 1)
0355:                        throw context.getRuntime().newArgumentError(
0356:                                "wrong number of arguments(" + args.length
0357:                                        + " for " + 1 + ")");
0358:                    return op_cmp(args[0]);
0359:                case LENGTH_SWITCHVALUE:
0360:                    if (args.length != 0)
0361:                        throw context.getRuntime().newArgumentError(
0362:                                "wrong number of arguments(" + args.length
0363:                                        + " for " + 0 + ")");
0364:                    return length();
0365:                case LAST_SWITCHVALUE:
0366:                    return last(args);
0367:                case SHIFT_SWITCHVALUE:
0368:                    if (args.length != 0)
0369:                        throw context.getRuntime().newArgumentError(
0370:                                "wrong number of arguments(" + args.length
0371:                                        + " for " + 0 + ")");
0372:                    return shift();
0373:                case INSPECT_SWITCHVALUE:
0374:                    if (args.length != 0)
0375:                        throw context.getRuntime().newArgumentError(
0376:                                "wrong number of arguments(" + args.length
0377:                                        + " for " + 0 + ")");
0378:                    return inspect();
0379:                case 0:
0380:                default:
0381:                    return super .callMethod(context, rubyclass, name, args,
0382:                            callType, block);
0383:                }
0384:            }
0385:
0386:            public int getNativeTypeIndex() {
0387:                return ClassIndex.ARRAY;
0388:            }
0389:
0390:            /** rb_ary_s_create
0391:             * 
0392:             */
0393:            public static IRubyObject create(IRubyObject klass,
0394:                    IRubyObject[] args, Block block) {
0395:                RubyArray arr = (RubyArray) ((RubyClass) klass).allocate();
0396:                arr.callInit(IRubyObject.NULL_ARRAY, block);
0397:
0398:                if (args.length > 0) {
0399:                    arr.alloc(args.length);
0400:                    System.arraycopy(args, 0, arr.values, 0, args.length);
0401:                    arr.realLength = args.length;
0402:                }
0403:                return arr;
0404:            }
0405:
0406:            /** rb_ary_new2
0407:             *
0408:             */
0409:            public static final RubyArray newArray(final Ruby runtime,
0410:                    final long len) {
0411:                return new RubyArray(runtime, len);
0412:            }
0413:
0414:            public static final RubyArray newArrayLight(final Ruby runtime,
0415:                    final long len) {
0416:                return new RubyArray(runtime, len, false);
0417:            }
0418:
0419:            /** rb_ary_new
0420:             *
0421:             */
0422:            public static final RubyArray newArray(final Ruby runtime) {
0423:                return new RubyArray(runtime, ARRAY_DEFAULT_SIZE);
0424:            }
0425:
0426:            /** rb_ary_new
0427:             *
0428:             */
0429:            public static final RubyArray newArrayLight(final Ruby runtime) {
0430:                /* Ruby arrays default to holding 16 elements, so we create an
0431:                 * ArrayList of the same size if we're not told otherwise
0432:                 */
0433:                RubyArray arr = new RubyArray(runtime, false);
0434:                arr.alloc(ARRAY_DEFAULT_SIZE);
0435:                return arr;
0436:            }
0437:
0438:            public static RubyArray newArray(Ruby runtime, IRubyObject obj) {
0439:                return new RubyArray(runtime, new IRubyObject[] { obj });
0440:            }
0441:
0442:            /** rb_assoc_new
0443:             *
0444:             */
0445:            public static RubyArray newArray(Ruby runtime, IRubyObject car,
0446:                    IRubyObject cdr) {
0447:                return new RubyArray(runtime, new IRubyObject[] { car, cdr });
0448:            }
0449:
0450:            /** rb_ary_new4, rb_ary_new3
0451:             *   
0452:             */
0453:            public static RubyArray newArray(Ruby runtime, IRubyObject[] args) {
0454:                RubyArray arr = new RubyArray(runtime, args.length);
0455:                System.arraycopy(args, 0, arr.values, 0, args.length);
0456:                arr.realLength = args.length;
0457:                return arr;
0458:            }
0459:
0460:            public static RubyArray newArrayNoCopy(Ruby runtime,
0461:                    IRubyObject[] args) {
0462:                return new RubyArray(runtime, args);
0463:            }
0464:
0465:            public static RubyArray newArrayNoCopyLight(Ruby runtime,
0466:                    IRubyObject[] args) {
0467:                RubyArray arr = new RubyArray(runtime, false);
0468:                arr.values = args;
0469:                arr.realLength = args.length;
0470:                return arr;
0471:            }
0472:
0473:            public static RubyArray newArray(Ruby runtime, Collection collection) {
0474:                RubyArray arr = new RubyArray(runtime, collection.size());
0475:                collection.toArray(arr.values);
0476:                arr.realLength = arr.values.length;
0477:                return arr;
0478:            }
0479:
0480:            public static final int ARRAY_DEFAULT_SIZE = 16;
0481:
0482:            private IRubyObject[] values;
0483:            private boolean tmpLock = false;
0484:            private boolean shared = false;
0485:
0486:            private int begin = 0;
0487:            private int realLength = 0;
0488:
0489:            /* 
0490:             * plain internal array assignment
0491:             */
0492:            private RubyArray(Ruby runtime, IRubyObject[] vals) {
0493:                super (runtime, runtime.getArray());
0494:                values = vals;
0495:                realLength = vals.length;
0496:            }
0497:
0498:            /* rb_ary_new2
0499:             * just allocates the internal array
0500:             */
0501:            private RubyArray(Ruby runtime, long length) {
0502:                super (runtime, runtime.getArray());
0503:                checkLength(length);
0504:                alloc((int) length);
0505:            }
0506:
0507:            private RubyArray(Ruby runtime, long length, boolean objectspace) {
0508:                super (runtime, runtime.getArray(), objectspace);
0509:                checkLength(length);
0510:                alloc((int) length);
0511:            }
0512:
0513:            /* rb_ary_new3, rb_ary_new4
0514:             * allocates the internal array of size length and copies the 'length' elements
0515:             */
0516:            public RubyArray(Ruby runtime, long length, IRubyObject[] vals) {
0517:                super (runtime, runtime.getArray());
0518:                checkLength(length);
0519:                int ilength = (int) length;
0520:                alloc(ilength);
0521:                if (ilength > 0 && vals.length > 0)
0522:                    System.arraycopy(vals, 0, values, 0, ilength);
0523:
0524:                realLength = ilength;
0525:            }
0526:
0527:            /* NEWOBJ and OBJSETUP equivalent
0528:             * fastest one, for shared arrays, optional objectspace
0529:             */
0530:            private RubyArray(Ruby runtime, boolean objectSpace) {
0531:                super (runtime, runtime.getArray(), objectSpace);
0532:            }
0533:
0534:            private RubyArray(Ruby runtime) {
0535:                super (runtime, runtime.getArray());
0536:                alloc(ARRAY_DEFAULT_SIZE);
0537:            }
0538:
0539:            public RubyArray(Ruby runtime, RubyClass klass) {
0540:                super (runtime, klass);
0541:                alloc(ARRAY_DEFAULT_SIZE);
0542:            }
0543:
0544:            /* Array constructors taking the MetaClass to fulfil MRI Array subclass behaviour
0545:             * 
0546:             */
0547:            private RubyArray(Ruby runtime, RubyClass klass, int length) {
0548:                super (runtime, klass);
0549:                alloc(length);
0550:            }
0551:
0552:            private RubyArray(Ruby runtime, RubyClass klass, long length) {
0553:                super (runtime, klass);
0554:                checkLength(length);
0555:                alloc((int) length);
0556:            }
0557:
0558:            private RubyArray(Ruby runtime, RubyClass klass, long length,
0559:                    boolean objectspace) {
0560:                super (runtime, klass, objectspace);
0561:                checkLength(length);
0562:                alloc((int) length);
0563:            }
0564:
0565:            private RubyArray(Ruby runtime, RubyClass klass, boolean objectSpace) {
0566:                super (runtime, klass, objectSpace);
0567:            }
0568:
0569:            private RubyArray(Ruby runtime, RubyClass klass, RubyArray original) {
0570:                super (runtime, klass);
0571:                realLength = original.realLength;
0572:                alloc(realLength);
0573:                System.arraycopy(original.values, original.begin, values, 0,
0574:                        realLength);
0575:            }
0576:
0577:            private final IRubyObject[] reserve(int length) {
0578:                return new IRubyObject[length];
0579:            }
0580:
0581:            private final void alloc(int length) {
0582:                values = new IRubyObject[length];
0583:            }
0584:
0585:            private final void realloc(int newLength) {
0586:                IRubyObject[] reallocated = new IRubyObject[newLength];
0587:                System.arraycopy(values, 0, reallocated, 0,
0588:                        newLength > realLength ? realLength : newLength);
0589:                values = reallocated;
0590:            }
0591:
0592:            private final void checkLength(long length) {
0593:                if (length < 0) {
0594:                    throw getRuntime().newArgumentError(
0595:                            "negative array size (or size too big)");
0596:                }
0597:
0598:                if (length >= Integer.MAX_VALUE) {
0599:                    throw getRuntime().newArgumentError("array size too big");
0600:                }
0601:            }
0602:
0603:            /** Getter for property list.
0604:             * @return Value of property list.
0605:             */
0606:            public List getList() {
0607:                return Arrays.asList(toJavaArray());
0608:            }
0609:
0610:            public int getLength() {
0611:                return realLength;
0612:            }
0613:
0614:            public IRubyObject[] toJavaArray() {
0615:                IRubyObject[] copy = reserve(realLength);
0616:                System.arraycopy(values, begin, copy, 0, realLength);
0617:                return copy;
0618:            }
0619:
0620:            public IRubyObject[] toJavaArrayUnsafe() {
0621:                return !shared ? values : toJavaArray();
0622:            }
0623:
0624:            public IRubyObject[] toJavaArrayMaybeUnsafe() {
0625:                return (!shared && begin == 0 && values.length == realLength) ? values
0626:                        : toJavaArray();
0627:            }
0628:
0629:            /** rb_ary_make_shared
0630:             *
0631:             */
0632:            private final RubyArray makeShared(int beg, int len,
0633:                    RubyClass klass, boolean objectSpace) {
0634:                RubyArray sharedArray = new RubyArray(getRuntime(), klass,
0635:                        objectSpace);
0636:                shared = true;
0637:                sharedArray.values = values;
0638:                sharedArray.shared = true;
0639:                sharedArray.begin = beg;
0640:                sharedArray.realLength = len;
0641:                return sharedArray;
0642:            }
0643:
0644:            /** rb_ary_modify_check
0645:             *
0646:             */
0647:            private final void modifyCheck() {
0648:                testFrozen("array");
0649:
0650:                if (tmpLock) {
0651:                    throw getRuntime().newTypeError(
0652:                            "can't modify array during iteration");
0653:                }
0654:                if (!isTaint() && getRuntime().getSafeLevel() >= 4) {
0655:                    throw getRuntime().newSecurityError(
0656:                            "Insecure: can't modify array");
0657:                }
0658:            }
0659:
0660:            /** rb_ary_modify
0661:             *
0662:             */
0663:            private final void modify() {
0664:                modifyCheck();
0665:                if (shared) {
0666:                    IRubyObject[] vals = reserve(realLength);
0667:                    shared = false;
0668:                    System.arraycopy(values, begin, vals, 0, realLength);
0669:                    begin = 0;
0670:                    values = vals;
0671:                }
0672:            }
0673:
0674:            /*  ================
0675:             *  Instance Methods
0676:             *  ================ 
0677:             */
0678:
0679:            /** rb_ary_initialize
0680:             * 
0681:             */
0682:            public IRubyObject initialize(IRubyObject[] args, Block block) {
0683:                int argc = Arity.checkArgumentCount(getRuntime(), args, 0, 2);
0684:                Ruby runtime = getRuntime();
0685:
0686:                if (argc == 0) {
0687:                    realLength = 0;
0688:                    if (block.isGiven())
0689:                        runtime.getWarnings().warn("given block not used");
0690:
0691:                    return this ;
0692:                }
0693:
0694:                if (argc == 1 && !(args[0] instanceof  RubyFixnum)) {
0695:                    IRubyObject val = args[0].checkArrayType();
0696:                    if (!val.isNil()) {
0697:                        replace(val);
0698:                        return this ;
0699:                    }
0700:                }
0701:
0702:                long len = RubyNumeric.num2long(args[0]);
0703:
0704:                if (len < 0)
0705:                    throw runtime.newArgumentError("negative array size");
0706:
0707:                if (len >= Integer.MAX_VALUE)
0708:                    throw runtime.newArgumentError("array size too big");
0709:
0710:                int ilen = (int) len;
0711:
0712:                modify();
0713:
0714:                if (ilen > values.length)
0715:                    values = reserve(ilen);
0716:
0717:                if (block.isGiven()) {
0718:                    if (argc == 2) {
0719:                        runtime.getWarnings().warn(
0720:                                "block supersedes default value argument");
0721:                    }
0722:
0723:                    ThreadContext context = runtime.getCurrentContext();
0724:                    for (int i = 0; i < ilen; i++) {
0725:                        store(i, block.yield(context,
0726:                                new RubyFixnum(runtime, i)));
0727:                        realLength = i + 1;
0728:                    }
0729:                } else {
0730:                    Arrays.fill(values, 0, ilen, (argc == 2) ? args[1]
0731:                            : runtime.getNil());
0732:                    realLength = ilen;
0733:                }
0734:                return this ;
0735:            }
0736:
0737:            /** rb_ary_replace
0738:             *
0739:             */
0740:            public IRubyObject replace(IRubyObject orig) {
0741:                modifyCheck();
0742:
0743:                RubyArray origArr = orig.convertToArray();
0744:
0745:                if (this  == orig)
0746:                    return this ;
0747:
0748:                origArr.shared = true;
0749:                values = origArr.values;
0750:                realLength = origArr.realLength;
0751:                begin = origArr.begin;
0752:                shared = true;
0753:
0754:                return this ;
0755:            }
0756:
0757:            /** rb_ary_to_s
0758:             *
0759:             */
0760:            public IRubyObject to_s() {
0761:                if (realLength == 0)
0762:                    return getRuntime().newString("");
0763:
0764:                return join(getRuntime().getGlobalVariables().get("$,"));
0765:            }
0766:
0767:            public boolean includes(IRubyObject item) {
0768:                final ThreadContext context = getRuntime().getCurrentContext();
0769:                int begin = this .begin;
0770:
0771:                for (int i = begin; i < begin + realLength; i++) {
0772:                    if (values[i].equalInternal(context, item).isTrue())
0773:                        return true;
0774:                }
0775:
0776:                return false;
0777:            }
0778:
0779:            /** rb_ary_hash
0780:             * 
0781:             */
0782:            public RubyFixnum hash() {
0783:                int h = realLength;
0784:
0785:                Ruby runtime = getRuntime();
0786:                ThreadContext context = runtime.getCurrentContext();
0787:                int begin = this .begin;
0788:                for (int i = begin; i < begin + realLength; i++) {
0789:                    h = (h << 1) | (h < 0 ? 1 : 0);
0790:                    h ^= RubyNumeric.num2long(values[i].callMethod(context,
0791:                            MethodIndex.HASH, "hash"));
0792:                }
0793:
0794:                return runtime.newFixnum(h);
0795:            }
0796:
0797:            /** rb_ary_store
0798:             *
0799:             */
0800:            public final IRubyObject store(long index, IRubyObject value) {
0801:                if (index < 0) {
0802:                    index += realLength;
0803:                    if (index < 0) {
0804:                        throw getRuntime().newIndexError(
0805:                                "index " + (index - realLength)
0806:                                        + " out of array");
0807:                    }
0808:                }
0809:
0810:                modify();
0811:
0812:                if (index >= realLength) {
0813:                    if (index >= values.length) {
0814:                        long newLength = values.length >> 1;
0815:
0816:                        if (newLength < ARRAY_DEFAULT_SIZE)
0817:                            newLength = ARRAY_DEFAULT_SIZE;
0818:
0819:                        newLength += index;
0820:                        if (newLength >= Integer.MAX_VALUE) {
0821:                            throw getRuntime()
0822:                                    .newArgumentError("index too big");
0823:                        }
0824:                        realloc((int) newLength);
0825:                    }
0826:                    if (index != realLength)
0827:                        Arrays.fill(values, realLength, (int) index + 1,
0828:                                getRuntime().getNil());
0829:
0830:                    realLength = (int) index + 1;
0831:                }
0832:
0833:                values[(int) index] = value;
0834:                return value;
0835:            }
0836:
0837:            /** rb_ary_elt - faster
0838:             *
0839:             */
0840:            private final IRubyObject elt(long offset) {
0841:                if (realLength == 0 || offset < 0 || offset >= realLength)
0842:                    return getRuntime().getNil();
0843:
0844:                return values[begin + (int) offset];
0845:            }
0846:
0847:            /** rb_ary_elt - faster
0848:             *
0849:             */
0850:            private final IRubyObject elt(int offset) {
0851:                if (realLength == 0 || offset < 0 || offset >= realLength)
0852:                    return getRuntime().getNil();
0853:
0854:                return values[begin + offset];
0855:            }
0856:
0857:            /** rb_ary_elt - faster
0858:             *
0859:             */
0860:            private final IRubyObject elt_f(long offset) {
0861:                if (realLength == 0 || offset >= realLength)
0862:                    return getRuntime().getNil();
0863:
0864:                return values[begin + (int) offset];
0865:            }
0866:
0867:            /** rb_ary_elt - faster
0868:             *
0869:             */
0870:            private final IRubyObject elt_f(int offset) {
0871:                if (realLength == 0 || offset >= realLength)
0872:                    return getRuntime().getNil();
0873:
0874:                return values[begin + offset];
0875:            }
0876:
0877:            /** rb_ary_entry
0878:             *
0879:             */
0880:            public final IRubyObject entry(long offset) {
0881:                return (offset < 0) ? elt(offset + realLength) : elt_f(offset);
0882:            }
0883:
0884:            /** rb_ary_entry
0885:             *
0886:             */
0887:            public final IRubyObject entry(int offset) {
0888:                return (offset < 0) ? elt(offset + realLength) : elt_f(offset);
0889:            }
0890:
0891:            public final IRubyObject eltInternal(int offset) {
0892:                return values[begin + offset];
0893:            }
0894:
0895:            public final IRubyObject eltInternalSet(int offset, IRubyObject item) {
0896:                return values[begin + offset] = item;
0897:            }
0898:
0899:            /** rb_ary_fetch
0900:             *
0901:             */
0902:            public IRubyObject fetch(IRubyObject[] args, Block block) {
0903:                if (Arity.checkArgumentCount(getRuntime(), args, 1, 2) == 2
0904:                        && block.isGiven()) {
0905:                    getRuntime().getWarnings().warn(
0906:                            "block supersedes default value argument");
0907:                }
0908:
0909:                long index = RubyNumeric.num2long(args[0]);
0910:
0911:                if (index < 0)
0912:                    index += realLength;
0913:
0914:                if (index < 0 || index >= realLength) {
0915:                    if (block.isGiven())
0916:                        return block.yield(getRuntime().getCurrentContext(),
0917:                                args[0]);
0918:
0919:                    if (args.length == 1) {
0920:                        throw getRuntime().newIndexError(
0921:                                "index " + index + " out of array");
0922:                    }
0923:
0924:                    return args[1];
0925:                }
0926:
0927:                return values[begin + (int) index];
0928:            }
0929:
0930:            /** rb_ary_to_ary
0931:             * 
0932:             */
0933:            private static RubyArray aryToAry(IRubyObject obj) {
0934:                if (obj instanceof  RubyArray)
0935:                    return (RubyArray) obj;
0936:
0937:                if (obj.respondsTo("to_ary"))
0938:                    return obj.convertToArray();
0939:
0940:                RubyArray arr = new RubyArray(obj.getRuntime(), false); // possibly should not in object space
0941:                arr.alloc(1);
0942:                arr.values[0] = obj;
0943:                arr.realLength = 1;
0944:                return arr;
0945:            }
0946:
0947:            /** rb_ary_splice
0948:             * 
0949:             */
0950:            private final void splice(long beg, long len, IRubyObject rpl) {
0951:                int rlen;
0952:
0953:                if (len < 0)
0954:                    throw getRuntime().newIndexError(
0955:                            "negative length (" + len + ")");
0956:
0957:                if (beg < 0) {
0958:                    beg += realLength;
0959:                    if (beg < 0) {
0960:                        beg -= realLength;
0961:                        throw getRuntime().newIndexError(
0962:                                "index " + beg + " out of array");
0963:                    }
0964:                }
0965:
0966:                if (beg + len > realLength)
0967:                    len = realLength - beg;
0968:
0969:                RubyArray rplArr;
0970:                if (rpl == null || rpl.isNil()) {
0971:                    rplArr = null;
0972:                    rlen = 0;
0973:                } else {
0974:                    rplArr = aryToAry(rpl);
0975:                    rlen = rplArr.realLength;
0976:                }
0977:
0978:                modify();
0979:
0980:                if (beg >= realLength) {
0981:                    len = beg + rlen;
0982:
0983:                    if (len >= values.length) {
0984:                        int tryNewLength = values.length + (values.length >> 1);
0985:
0986:                        realloc(len > tryNewLength ? (int) len : tryNewLength);
0987:                    }
0988:
0989:                    Arrays.fill(values, realLength, (int) beg, getRuntime()
0990:                            .getNil());
0991:                    if (rlen > 0) {
0992:                        System.arraycopy(rplArr.values, rplArr.begin, values,
0993:                                (int) beg, rlen);
0994:                    }
0995:                    realLength = (int) len;
0996:                } else {
0997:                    long alen;
0998:
0999:                    if (beg + len > realLength)
1000:                        len = realLength - beg;
1001:
1002:                    alen = realLength + rlen - len;
1003:                    if (alen >= values.length) {
1004:                        int tryNewLength = values.length + (values.length >> 1);
1005:
1006:                        realloc(alen > tryNewLength ? (int) alen : tryNewLength);
1007:                    }
1008:
1009:                    if (len != rlen) {
1010:                        System.arraycopy(values, (int) (beg + len), values,
1011:                                (int) beg + rlen, realLength
1012:                                        - (int) (beg + len));
1013:                        realLength = (int) alen;
1014:                    }
1015:
1016:                    if (rlen > 0) {
1017:                        System.arraycopy(rplArr.values, rplArr.begin, values,
1018:                                (int) beg, rlen);
1019:                    }
1020:                }
1021:            }
1022:
1023:            /** rb_ary_insert
1024:             * 
1025:             */
1026:            public IRubyObject insert(IRubyObject[] args) {
1027:                if (args.length == 1)
1028:                    return this ;
1029:
1030:                if (args.length < 1) {
1031:                    throw getRuntime().newArgumentError(
1032:                            "wrong number of arguments (at least 1)");
1033:                }
1034:
1035:                long pos = RubyNumeric.num2long(args[0]);
1036:
1037:                if (pos == -1)
1038:                    pos = realLength;
1039:                if (pos < 0)
1040:                    pos++;
1041:
1042:                RubyArray inserted = new RubyArray(getRuntime(), false);
1043:                inserted.values = args;
1044:                inserted.begin = 1;
1045:                inserted.realLength = args.length - 1;
1046:
1047:                splice(pos, 0, inserted); // rb_ary_new4
1048:
1049:                return this ;
1050:            }
1051:
1052:            /** rb_ary_dup
1053:             * 
1054:             */
1055:            private final RubyArray aryDup() {
1056:                RubyArray dup = new RubyArray(getRuntime(), getMetaClass(),
1057:                        this );
1058:                dup.setTaint(isTaint()); // from DUP_SETUP
1059:                // rb_copy_generic_ivar from DUP_SETUP here ...unlikely..
1060:                return dup;
1061:            }
1062:
1063:            /** rb_ary_transpose
1064:             * 
1065:             */
1066:            public RubyArray transpose() {
1067:                RubyArray tmp, result = null;
1068:
1069:                int alen = realLength;
1070:                if (alen == 0)
1071:                    return aryDup();
1072:
1073:                Ruby runtime = getRuntime();
1074:                int elen = -1;
1075:                int end = begin + alen;
1076:                for (int i = begin; i < end; i++) {
1077:                    tmp = elt(i).convertToArray();
1078:                    if (elen < 0) {
1079:                        elen = tmp.realLength;
1080:                        result = new RubyArray(runtime, elen);
1081:                        for (int j = 0; j < elen; j++) {
1082:                            result.store(j, new RubyArray(runtime, alen));
1083:                        }
1084:                    } else if (elen != tmp.realLength) {
1085:                        throw runtime.newIndexError("element size differs ("
1086:                                + tmp.realLength + " should be " + elen + ")");
1087:                    }
1088:                    for (int j = 0; j < elen; j++) {
1089:                        ((RubyArray) result.elt(j))
1090:                                .store(i - begin, tmp.elt(j));
1091:                    }
1092:                }
1093:                return result;
1094:            }
1095:
1096:            /** rb_values_at (internal)
1097:             * 
1098:             */
1099:            private final IRubyObject values_at(long olen, IRubyObject[] args) {
1100:                RubyArray result = new RubyArray(getRuntime(), args.length);
1101:
1102:                for (int i = 0; i < args.length; i++) {
1103:                    if (args[i] instanceof  RubyFixnum) {
1104:                        result.append(entry(((RubyFixnum) args[i])
1105:                                .getLongValue()));
1106:                        continue;
1107:                    }
1108:
1109:                    long beglen[];
1110:                    if (!(args[i] instanceof  RubyRange)) {
1111:                    } else if ((beglen = ((RubyRange) args[i]).begLen(olen, 0)) == null) {
1112:                        continue;
1113:                    } else {
1114:                        int beg = (int) beglen[0];
1115:                        int len = (int) beglen[1];
1116:                        int end = begin + len;
1117:                        for (int j = begin; j < end; j++) {
1118:                            result.append(entry(j + beg));
1119:                        }
1120:                        continue;
1121:                    }
1122:                    result.append(entry(RubyNumeric.num2long(args[i])));
1123:                }
1124:
1125:                return result;
1126:            }
1127:
1128:            /** rb_values_at
1129:             * 
1130:             */
1131:            public IRubyObject values_at(IRubyObject[] args) {
1132:                return values_at(realLength, args);
1133:            }
1134:
1135:            /** rb_ary_subseq
1136:             *
1137:             */
1138:            public IRubyObject subseq(long beg, long len) {
1139:                if (beg > realLength || beg < 0 || len < 0)
1140:                    return getRuntime().getNil();
1141:
1142:                if (beg + len > realLength) {
1143:                    len = realLength - beg;
1144:
1145:                    if (len < 0)
1146:                        len = 0;
1147:                }
1148:
1149:                if (len == 0)
1150:                    return new RubyArray(getRuntime(), getMetaClass(), 0);
1151:
1152:                return makeShared(begin + (int) beg, (int) len, getMetaClass(),
1153:                        true);
1154:            }
1155:
1156:            /** rb_ary_subseq
1157:             *
1158:             */
1159:            public IRubyObject subseqLight(long beg, long len) {
1160:                if (beg > realLength || beg < 0 || len < 0)
1161:                    return getRuntime().getNil();
1162:
1163:                if (beg + len > realLength) {
1164:                    len = realLength - beg;
1165:
1166:                    if (len < 0)
1167:                        len = 0;
1168:                }
1169:
1170:                if (len == 0)
1171:                    return new RubyArray(getRuntime(), getMetaClass(), 0, false);
1172:
1173:                return makeShared(begin + (int) beg, (int) len, getMetaClass(),
1174:                        false);
1175:            }
1176:
1177:            /** rb_ary_length
1178:             *
1179:             */
1180:            public RubyFixnum length() {
1181:                return getRuntime().newFixnum(realLength);
1182:            }
1183:
1184:            /** rb_ary_push - specialized rb_ary_store 
1185:             *
1186:             */
1187:            public RubyArray append(IRubyObject item) {
1188:                modify();
1189:
1190:                if (realLength == values.length) {
1191:                    if (realLength == Integer.MAX_VALUE)
1192:                        throw getRuntime().newArgumentError("index too big");
1193:
1194:                    long newLength = values.length + (values.length >> 1);
1195:                    if (newLength > Integer.MAX_VALUE) {
1196:                        newLength = Integer.MAX_VALUE;
1197:                    } else if (newLength < ARRAY_DEFAULT_SIZE) {
1198:                        newLength = ARRAY_DEFAULT_SIZE;
1199:                    }
1200:
1201:                    realloc((int) newLength);
1202:                }
1203:
1204:                values[realLength++] = item;
1205:                return this ;
1206:            }
1207:
1208:            /** rb_ary_push_m
1209:             *
1210:             */
1211:            public RubyArray push_m(IRubyObject[] items) {
1212:                for (int i = 0; i < items.length; i++) {
1213:                    append(items[i]);
1214:                }
1215:
1216:                return this ;
1217:            }
1218:
1219:            /** rb_ary_pop
1220:             *
1221:             */
1222:            public IRubyObject pop() {
1223:                modifyCheck();
1224:
1225:                if (realLength == 0)
1226:                    return getRuntime().getNil();
1227:
1228:                if (!shared) {
1229:                    int index = begin + --realLength;
1230:                    IRubyObject obj = values[index];
1231:                    values[index] = null;
1232:                    return obj;
1233:                }
1234:
1235:                return values[begin + --realLength];
1236:            }
1237:
1238:            /** rb_ary_shift
1239:             *
1240:             */
1241:            public IRubyObject shift() {
1242:                modifyCheck();
1243:
1244:                if (realLength == 0)
1245:                    return getRuntime().getNil();
1246:
1247:                IRubyObject obj = values[begin];
1248:
1249:                if (!shared)
1250:                    shared = true;
1251:
1252:                begin++;
1253:                realLength--;
1254:
1255:                return obj;
1256:            }
1257:
1258:            /** rb_ary_unshift
1259:             *
1260:             */
1261:            public RubyArray unshift(IRubyObject item) {
1262:                modify();
1263:
1264:                if (realLength == values.length) {
1265:                    int newLength = values.length >> 1;
1266:                    if (newLength < ARRAY_DEFAULT_SIZE)
1267:                        newLength = ARRAY_DEFAULT_SIZE;
1268:
1269:                    newLength += values.length;
1270:                    realloc(newLength);
1271:                }
1272:                System.arraycopy(values, 0, values, 1, realLength);
1273:
1274:                realLength++;
1275:                values[0] = item;
1276:
1277:                return this ;
1278:            }
1279:
1280:            /** rb_ary_unshift_m
1281:             *
1282:             */
1283:            public RubyArray unshift_m(IRubyObject[] items) {
1284:                long len = realLength;
1285:
1286:                if (items.length == 0)
1287:                    return this ;
1288:
1289:                store(len + items.length - 1, getRuntime().getNil());
1290:
1291:                // it's safe to use zeroes here since modified by store()
1292:                System.arraycopy(values, 0, values, items.length, (int) len);
1293:                System.arraycopy(items, 0, values, 0, items.length);
1294:
1295:                return this ;
1296:            }
1297:
1298:            /** rb_ary_includes
1299:             * 
1300:             */
1301:            public RubyBoolean include_p(IRubyObject item) {
1302:                return getRuntime().newBoolean(includes(item));
1303:            }
1304:
1305:            /** rb_ary_frozen_p
1306:             *
1307:             */
1308:            public RubyBoolean frozen() {
1309:                return getRuntime().newBoolean(isFrozen() || tmpLock);
1310:            }
1311:
1312:            /** rb_ary_aref
1313:             */
1314:            public IRubyObject aref(IRubyObject[] args) {
1315:                long beg, len;
1316:
1317:                if (args.length == 1) {
1318:                    if (args[0] instanceof  RubyFixnum)
1319:                        return entry(((RubyFixnum) args[0]).getLongValue());
1320:                    if (args[0] instanceof  RubySymbol)
1321:                        throw getRuntime()
1322:                                .newTypeError("Symbol as array index");
1323:
1324:                    long[] beglen;
1325:                    if (!(args[0] instanceof  RubyRange)) {
1326:                    } else if ((beglen = ((RubyRange) args[0]).begLen(
1327:                            realLength, 0)) == null) {
1328:                        return getRuntime().getNil();
1329:                    } else {
1330:                        beg = beglen[0];
1331:                        len = beglen[1];
1332:                        return subseq(beg, len);
1333:                    }
1334:
1335:                    return entry(RubyNumeric.num2long(args[0]));
1336:                }
1337:
1338:                if (args.length == 2) {
1339:                    if (args[0] instanceof  RubySymbol) {
1340:                        throw getRuntime()
1341:                                .newTypeError("Symbol as array index");
1342:                    }
1343:                    beg = RubyNumeric.num2long(args[0]);
1344:                    len = RubyNumeric.num2long(args[1]);
1345:
1346:                    if (beg < 0)
1347:                        beg += realLength;
1348:
1349:                    return subseq(beg, len);
1350:                }
1351:
1352:                Arity.checkArgumentCount(getRuntime(), args, 1, 2);
1353:                return null;
1354:            }
1355:
1356:            /** rb_ary_aset
1357:             *
1358:             */
1359:            public IRubyObject aset(IRubyObject[] args) {
1360:                if (args.length == 2) {
1361:                    if (args[0] instanceof  RubyFixnum) {
1362:                        store(((RubyFixnum) args[0]).getLongValue(), args[1]);
1363:                        return args[1];
1364:                    }
1365:                    if (args[0] instanceof  RubyRange) {
1366:                        long[] beglen = ((RubyRange) args[0]).begLen(
1367:                                realLength, 1);
1368:                        splice(beglen[0], beglen[1], args[1]);
1369:                        return args[1];
1370:                    }
1371:                    if (args[0] instanceof  RubySymbol)
1372:                        throw getRuntime()
1373:                                .newTypeError("Symbol as array index");
1374:
1375:                    store(RubyNumeric.num2long(args[0]), args[1]);
1376:                    return args[1];
1377:                }
1378:
1379:                if (args.length == 3) {
1380:                    if (args[0] instanceof  RubySymbol)
1381:                        throw getRuntime()
1382:                                .newTypeError("Symbol as array index");
1383:                    if (args[1] instanceof  RubySymbol)
1384:                        throw getRuntime().newTypeError(
1385:                                "Symbol as subarray length");
1386:
1387:                    splice(RubyNumeric.num2long(args[0]), RubyNumeric
1388:                            .num2long(args[1]), args[2]);
1389:                    return args[2];
1390:                }
1391:
1392:                throw getRuntime()
1393:                        .newArgumentError(
1394:                                "wrong number of arguments (" + args.length
1395:                                        + " for 2)");
1396:            }
1397:
1398:            /** rb_ary_at
1399:             *
1400:             */
1401:            public IRubyObject at(IRubyObject pos) {
1402:                return entry(RubyNumeric.num2long(pos));
1403:            }
1404:
1405:            /** rb_ary_concat
1406:             *
1407:             */
1408:            public RubyArray concat(IRubyObject obj) {
1409:                RubyArray ary = obj.convertToArray();
1410:
1411:                if (ary.realLength > 0)
1412:                    splice(realLength, 0, ary);
1413:
1414:                return this ;
1415:            }
1416:
1417:            /** rb_ary_inspect
1418:             *
1419:             */
1420:            public IRubyObject inspect() {
1421:                if (realLength == 0)
1422:                    return getRuntime().newString("[]");
1423:
1424:                if (!getRuntime().registerInspecting(this ))
1425:                    return getRuntime().newString("[...]");
1426:
1427:                RubyString s;
1428:                try {
1429:                    StringBuffer buffer = new StringBuffer("[");
1430:                    Ruby runtime = getRuntime();
1431:                    ThreadContext context = runtime.getCurrentContext();
1432:                    boolean tainted = isTaint();
1433:                    for (int i = 0; i < realLength; i++) {
1434:                        s = RubyString.objAsString(values[begin + i]
1435:                                .callMethod(context, "inspect"));
1436:
1437:                        if (s.isTaint())
1438:                            tainted = true;
1439:
1440:                        if (i > 0)
1441:                            buffer.append(", ");
1442:
1443:                        buffer.append(s.toString());
1444:                    }
1445:                    buffer.append("]");
1446:                    if (tainted)
1447:                        setTaint(true);
1448:
1449:                    return runtime.newString(buffer.toString());
1450:                } finally {
1451:                    getRuntime().unregisterInspecting(this );
1452:                }
1453:            }
1454:
1455:            /** rb_ary_first
1456:             *
1457:             */
1458:            public IRubyObject first(IRubyObject[] args) {
1459:                if (args.length == 0) {
1460:                    if (realLength == 0)
1461:                        return getRuntime().getNil();
1462:
1463:                    return values[begin];
1464:                }
1465:
1466:                Arity.checkArgumentCount(getRuntime(), args, 0, 1);
1467:                long n = RubyNumeric.num2long(args[0]);
1468:                if (n > realLength) {
1469:                    n = realLength;
1470:                } else if (n < 0) {
1471:                    throw getRuntime().newArgumentError(
1472:                            "negative array size (or size too big)");
1473:                }
1474:
1475:                return makeShared(begin, (int) n, getRuntime().getArray(), true);
1476:            }
1477:
1478:            /** rb_ary_last
1479:             *
1480:             */
1481:            public IRubyObject last(IRubyObject[] args) {
1482:                if (args.length == 0) {
1483:                    if (realLength == 0)
1484:                        return getRuntime().getNil();
1485:
1486:                    return values[begin + realLength - 1];
1487:                }
1488:
1489:                Arity.checkArgumentCount(getRuntime(), args, 0, 1);
1490:                long n = RubyNumeric.num2long(args[0]);
1491:                if (n > realLength) {
1492:                    n = realLength;
1493:                } else if (n < 0) {
1494:                    throw getRuntime().newArgumentError(
1495:                            "negative array size (or size too big)");
1496:                }
1497:
1498:                return makeShared(begin + realLength - (int) n, (int) n,
1499:                        getRuntime().getArray(), true);
1500:            }
1501:
1502:            /** rb_ary_each
1503:             *
1504:             */
1505:            public IRubyObject each(Block block) {
1506:                ThreadContext context = getRuntime().getCurrentContext();
1507:                if (shared) {
1508:                    for (int i = begin; i < begin + realLength; i++) {
1509:                        block.yield(context, values[i]);
1510:                    }
1511:                } else {
1512:                    for (int i = 0; i < realLength; i++) {
1513:                        block.yield(context, values[i]);
1514:                    }
1515:                }
1516:                return this ;
1517:            }
1518:
1519:            /** rb_ary_each_index
1520:             *
1521:             */
1522:            public IRubyObject each_index(Block block) {
1523:                Ruby runtime = getRuntime();
1524:                ThreadContext context = runtime.getCurrentContext();
1525:                for (int i = 0; i < realLength; i++) {
1526:                    block.yield(context, runtime.newFixnum(i));
1527:                }
1528:                return this ;
1529:            }
1530:
1531:            /** rb_ary_reverse_each
1532:             *
1533:             */
1534:            public IRubyObject reverse_each(Block block) {
1535:                ThreadContext context = getRuntime().getCurrentContext();
1536:
1537:                int len = realLength;
1538:
1539:                while (len-- > 0) {
1540:                    block.yield(context, values[begin + len]);
1541:
1542:                    if (realLength < len)
1543:                        len = realLength;
1544:                }
1545:
1546:                return this ;
1547:            }
1548:
1549:            private final IRubyObject inspectJoin(IRubyObject sep) {
1550:                IRubyObject result = join(sep);
1551:                getRuntime().unregisterInspecting(this );
1552:                return result;
1553:            }
1554:
1555:            /** rb_ary_join
1556:             *
1557:             */
1558:            public RubyString join(IRubyObject sep) {
1559:                if (realLength == 0)
1560:                    return getRuntime().newString("");
1561:
1562:                boolean taint = isTaint() || sep.isTaint();
1563:
1564:                long len = 1;
1565:                for (int i = begin; i < begin + realLength; i++) {
1566:                    IRubyObject tmp = values[i].checkStringType();
1567:                    len += tmp.isNil() ? 10 : ((RubyString) tmp).getByteList()
1568:                            .length();
1569:                }
1570:
1571:                RubyString strSep = null;
1572:                if (!sep.isNil()) {
1573:                    sep = strSep = sep.convertToString();
1574:                    len += strSep.getByteList().length() * (realLength - 1);
1575:                }
1576:
1577:                ByteList buf = new ByteList((int) len);
1578:                Ruby runtime = getRuntime();
1579:                for (int i = begin; i < begin + realLength; i++) {
1580:                    IRubyObject tmp = values[i];
1581:                    if (tmp instanceof  RubyString) {
1582:                        // do nothing
1583:                    } else if (tmp instanceof  RubyArray) {
1584:                        if (!runtime.registerInspecting(tmp)) {
1585:                            tmp = runtime.newString("[...]");
1586:                        } else {
1587:                            tmp = ((RubyArray) tmp).inspectJoin(sep);
1588:                        }
1589:                    } else {
1590:                        tmp = RubyString.objAsString(tmp);
1591:                    }
1592:
1593:                    if (i > begin && !sep.isNil())
1594:                        buf.append(strSep.getByteList());
1595:
1596:                    buf.append(tmp.asString().getByteList());
1597:                    taint |= tmp.isTaint();
1598:                }
1599:
1600:                RubyString result = runtime.newString(buf);
1601:
1602:                if (taint)
1603:                    result.setTaint(true);
1604:
1605:                return result;
1606:            }
1607:
1608:            /** rb_ary_join_m
1609:             *
1610:             */
1611:            public RubyString join_m(IRubyObject[] args) {
1612:                int argc = Arity.checkArgumentCount(getRuntime(), args, 0, 1);
1613:                IRubyObject sep = (argc == 1) ? args[0] : getRuntime()
1614:                        .getGlobalVariables().get("$,");
1615:
1616:                return join(sep);
1617:            }
1618:
1619:            /** rb_ary_to_a
1620:             *
1621:             */
1622:            public RubyArray to_a() {
1623:                if (getMetaClass() != getRuntime().getArray()) {
1624:                    RubyArray dup = new RubyArray(getRuntime(), true);
1625:
1626:                    shared = true;
1627:                    dup.values = values;
1628:                    dup.realLength = realLength;
1629:                    dup.begin = begin;
1630:                    dup.shared = true;
1631:                    return dup;
1632:                }
1633:                return this ;
1634:            }
1635:
1636:            public IRubyObject to_ary() {
1637:                return this ;
1638:            }
1639:
1640:            public RubyArray convertToArray() {
1641:                return this ;
1642:            }
1643:
1644:            public IRubyObject checkArrayType() {
1645:                return this ;
1646:            }
1647:
1648:            /** rb_ary_equal
1649:             *
1650:             */
1651:            public IRubyObject op_equal(IRubyObject obj) {
1652:                if (this  == obj)
1653:                    return getRuntime().getTrue();
1654:
1655:                if (!(obj instanceof  RubyArray)) {
1656:                    if (!obj.respondsTo("to_ary")) {
1657:                        return getRuntime().getFalse();
1658:                    } else {
1659:                        return obj.equalInternal(getRuntime()
1660:                                .getCurrentContext(), this );
1661:                    }
1662:                }
1663:
1664:                RubyArray ary = (RubyArray) obj;
1665:                if (realLength != ary.realLength)
1666:                    return getRuntime().getFalse();
1667:
1668:                Ruby runtime = getRuntime();
1669:                final ThreadContext context = runtime.getCurrentContext();
1670:                for (long i = 0; i < realLength; i++) {
1671:                    if (!elt(i).equalInternal(context, ary.elt(i)).isTrue())
1672:                        return runtime.getFalse();
1673:                }
1674:                return runtime.getTrue();
1675:            }
1676:
1677:            /** rb_ary_eql
1678:             *
1679:             */
1680:            public RubyBoolean eql_p(IRubyObject obj) {
1681:                if (this  == obj)
1682:                    return getRuntime().getTrue();
1683:                if (!(obj instanceof  RubyArray))
1684:                    return getRuntime().getFalse();
1685:
1686:                RubyArray ary = (RubyArray) obj;
1687:
1688:                if (realLength != ary.realLength)
1689:                    return getRuntime().getFalse();
1690:
1691:                Ruby runtime = getRuntime();
1692:                final ThreadContext context = runtime.getCurrentContext();
1693:                for (int i = 0; i < realLength; i++) {
1694:                    if (!elt(i).eqlInternal(context, ary.elt(i)))
1695:                        return runtime.getFalse();
1696:                }
1697:                return runtime.getTrue();
1698:            }
1699:
1700:            /** rb_ary_compact_bang
1701:             *
1702:             */
1703:            public IRubyObject compact_bang() {
1704:                modify();
1705:
1706:                int p = 0;
1707:                int t = 0;
1708:                int end = p + realLength;
1709:
1710:                while (t < end) {
1711:                    if (values[t].isNil()) {
1712:                        t++;
1713:                    } else {
1714:                        values[p++] = values[t++];
1715:                    }
1716:                }
1717:
1718:                if (realLength == p)
1719:                    return getRuntime().getNil();
1720:
1721:                realloc(p);
1722:                realLength = p;
1723:                return this ;
1724:            }
1725:
1726:            /** rb_ary_compact
1727:             *
1728:             */
1729:            public IRubyObject compact() {
1730:                RubyArray ary = aryDup();
1731:                ary.compact_bang();
1732:                return ary;
1733:            }
1734:
1735:            /** rb_ary_empty_p
1736:             *
1737:             */
1738:            public IRubyObject empty_p() {
1739:                return realLength == 0 ? getRuntime().getTrue() : getRuntime()
1740:                        .getFalse();
1741:            }
1742:
1743:            /** rb_ary_clear
1744:             *
1745:             */
1746:            public IRubyObject rb_clear() {
1747:                modifyCheck();
1748:
1749:                if (shared) {
1750:                    alloc(ARRAY_DEFAULT_SIZE);
1751:                    shared = false;
1752:                } else if (values.length > ARRAY_DEFAULT_SIZE << 1) {
1753:                    alloc(ARRAY_DEFAULT_SIZE << 1);
1754:                }
1755:
1756:                begin = 0;
1757:                realLength = 0;
1758:                return this ;
1759:            }
1760:
1761:            /** rb_ary_fill
1762:             *
1763:             */
1764:            public IRubyObject fill(IRubyObject[] args, Block block) {
1765:                IRubyObject item = null;
1766:                IRubyObject begObj = null;
1767:                IRubyObject lenObj = null;
1768:                int argc = args.length;
1769:
1770:                if (block.isGiven()) {
1771:                    Arity.checkArgumentCount(getRuntime(), args, 0, 2);
1772:                    item = null;
1773:                    begObj = argc > 0 ? args[0] : null;
1774:                    lenObj = argc > 1 ? args[1] : null;
1775:                    argc++;
1776:                } else {
1777:                    Arity.checkArgumentCount(getRuntime(), args, 1, 3);
1778:                    item = args[0];
1779:                    begObj = argc > 1 ? args[1] : null;
1780:                    lenObj = argc > 2 ? args[2] : null;
1781:                }
1782:
1783:                long beg = 0, end = 0, len = 0;
1784:                switch (argc) {
1785:                case 1:
1786:                    beg = 0;
1787:                    len = realLength;
1788:                    break;
1789:                case 2:
1790:                    if (begObj instanceof  RubyRange) {
1791:                        long[] beglen = ((RubyRange) begObj).begLen(realLength,
1792:                                1);
1793:                        beg = (int) beglen[0];
1794:                        len = (int) beglen[1];
1795:                        break;
1796:                    }
1797:                    /* fall through */
1798:                case 3:
1799:                    beg = begObj.isNil() ? 0 : RubyNumeric.num2long(begObj);
1800:                    if (beg < 0) {
1801:                        beg = realLength + beg;
1802:                        if (beg < 0)
1803:                            beg = 0;
1804:                    }
1805:                    len = (lenObj == null || lenObj.isNil()) ? realLength - beg
1806:                            : RubyNumeric.num2long(lenObj);
1807:                    break;
1808:                }
1809:
1810:                modify();
1811:
1812:                end = beg + len;
1813:                if (end > realLength) {
1814:                    if (end >= values.length)
1815:                        realloc((int) end);
1816:
1817:                    Arrays.fill(values, realLength, (int) end, getRuntime()
1818:                            .getNil());
1819:                    realLength = (int) end;
1820:                }
1821:
1822:                if (block.isGiven()) {
1823:                    Ruby runtime = getRuntime();
1824:                    ThreadContext context = runtime.getCurrentContext();
1825:                    for (int i = (int) beg; i < (int) end; i++) {
1826:                        IRubyObject v = block.yield(context, runtime
1827:                                .newFixnum(i));
1828:                        if (i >= realLength)
1829:                            break;
1830:
1831:                        values[i] = v;
1832:                    }
1833:                } else {
1834:                    if (len > 0)
1835:                        Arrays.fill(values, (int) beg, (int) (beg + len), item);
1836:                }
1837:
1838:                return this ;
1839:            }
1840:
1841:            /** rb_ary_index
1842:             *
1843:             */
1844:            public IRubyObject index(IRubyObject obj) {
1845:                Ruby runtime = getRuntime();
1846:                final ThreadContext context = runtime.getCurrentContext();
1847:                for (int i = begin; i < begin + realLength; i++) {
1848:                    if (values[i].equalInternal(context, obj).isTrue())
1849:                        return runtime.newFixnum(i - begin);
1850:                }
1851:
1852:                return runtime.getNil();
1853:            }
1854:
1855:            /** rb_ary_rindex
1856:             *
1857:             */
1858:            public IRubyObject rindex(IRubyObject obj) {
1859:                Ruby runtime = getRuntime();
1860:                final ThreadContext context = runtime.getCurrentContext();
1861:
1862:                int i = realLength;
1863:
1864:                while (i-- > 0) {
1865:                    if (i > realLength) {
1866:                        i = realLength;
1867:                        continue;
1868:                    }
1869:                    if (values[begin + i].equalInternal(context, obj).isTrue()) {
1870:                        return getRuntime().newFixnum(i);
1871:                    }
1872:                }
1873:
1874:                return runtime.getNil();
1875:            }
1876:
1877:            /** rb_ary_indexes
1878:             * 
1879:             */
1880:            public IRubyObject indexes(IRubyObject[] args) {
1881:                getRuntime().getWarnings().warn(
1882:                        "Array#indexes is deprecated; use Array#values_at");
1883:
1884:                RubyArray ary = new RubyArray(getRuntime(), args.length);
1885:
1886:                IRubyObject[] arefArgs = new IRubyObject[1];
1887:                for (int i = 0; i < args.length; i++) {
1888:                    arefArgs[0] = args[i];
1889:                    ary.append(aref(arefArgs));
1890:                }
1891:
1892:                return ary;
1893:            }
1894:
1895:            /** rb_ary_reverse_bang
1896:             *
1897:             */
1898:            public IRubyObject reverse_bang() {
1899:                modify();
1900:
1901:                IRubyObject tmp;
1902:                if (realLength > 1) {
1903:                    int p1 = 0;
1904:                    int p2 = p1 + realLength - 1;
1905:
1906:                    while (p1 < p2) {
1907:                        tmp = values[p1];
1908:                        values[p1++] = values[p2];
1909:                        values[p2--] = tmp;
1910:                    }
1911:                }
1912:                return this ;
1913:            }
1914:
1915:            /** rb_ary_reverse_m
1916:             *
1917:             */
1918:            public IRubyObject reverse() {
1919:                return aryDup().reverse_bang();
1920:            }
1921:
1922:            /** rb_ary_collect
1923:             *
1924:             */
1925:            public RubyArray collect(Block block) {
1926:                Ruby runtime = getRuntime();
1927:
1928:                if (!block.isGiven())
1929:                    return new RubyArray(getRuntime(), runtime.getArray(), this );
1930:
1931:                ThreadContext context = runtime.getCurrentContext();
1932:                RubyArray collect = new RubyArray(runtime, realLength);
1933:
1934:                for (int i = begin; i < begin + realLength; i++) {
1935:                    collect.append(block.yield(context, values[i]));
1936:                }
1937:
1938:                return collect;
1939:            }
1940:
1941:            /** rb_ary_collect_bang
1942:             *
1943:             */
1944:            public RubyArray collect_bang(Block block) {
1945:                modify();
1946:                ThreadContext context = getRuntime().getCurrentContext();
1947:                for (int i = 0, len = realLength; i < len; i++) {
1948:                    store(i, block.yield(context, values[begin + i]));
1949:                }
1950:                return this ;
1951:            }
1952:
1953:            /** rb_ary_select
1954:             *
1955:             */
1956:            public RubyArray select(Block block) {
1957:                Ruby runtime = getRuntime();
1958:                RubyArray result = new RubyArray(runtime, realLength);
1959:
1960:                ThreadContext context = runtime.getCurrentContext();
1961:                if (shared) {
1962:                    for (int i = begin; i < begin + realLength; i++) {
1963:                        if (block.yield(context, values[i]).isTrue())
1964:                            result.append(elt(i - begin));
1965:                    }
1966:                } else {
1967:                    for (int i = 0; i < realLength; i++) {
1968:                        if (block.yield(context, values[i]).isTrue())
1969:                            result.append(elt(i));
1970:                    }
1971:                }
1972:                return result;
1973:            }
1974:
1975:            /** rb_ary_delete
1976:             *
1977:             */
1978:            public IRubyObject delete(IRubyObject item, Block block) {
1979:                int i2 = 0;
1980:
1981:                Ruby runtime = getRuntime();
1982:                final ThreadContext context = runtime.getCurrentContext();
1983:                for (int i1 = 0; i1 < realLength; i1++) {
1984:                    IRubyObject e = values[begin + i1];
1985:                    if (e.equalInternal(context, item).isTrue())
1986:                        continue;
1987:                    if (i1 != i2)
1988:                        store(i2, e);
1989:                    i2++;
1990:                }
1991:
1992:                if (realLength == i2) {
1993:                    if (block.isGiven())
1994:                        return block.yield(context, item);
1995:
1996:                    return runtime.getNil();
1997:                }
1998:
1999:                modify();
2000:
2001:                if (realLength > i2) {
2002:                    realLength = i2;
2003:                    if (i2 << 1 < values.length
2004:                            && values.length > ARRAY_DEFAULT_SIZE)
2005:                        realloc(i2 << 1);
2006:                }
2007:                return item;
2008:            }
2009:
2010:            /** rb_ary_delete_at
2011:             *
2012:             */
2013:            private final IRubyObject delete_at(int pos) {
2014:                int len = realLength;
2015:
2016:                if (pos >= len)
2017:                    return getRuntime().getNil();
2018:
2019:                if (pos < 0)
2020:                    pos += len;
2021:
2022:                if (pos < 0)
2023:                    return getRuntime().getNil();
2024:
2025:                modify();
2026:
2027:                IRubyObject obj = values[pos];
2028:                System.arraycopy(values, pos + 1, values, pos, len - (pos + 1));
2029:
2030:                realLength--;
2031:
2032:                return obj;
2033:            }
2034:
2035:            /** rb_ary_delete_at_m
2036:             * 
2037:             */
2038:            public IRubyObject delete_at(IRubyObject obj) {
2039:                return delete_at((int) RubyNumeric.num2long(obj));
2040:            }
2041:
2042:            /** rb_ary_reject_bang
2043:             * 
2044:             */
2045:            public IRubyObject reject(Block block) {
2046:                RubyArray ary = aryDup();
2047:                ary.reject_bang(block);
2048:                return ary;
2049:            }
2050:
2051:            /** rb_ary_reject_bang
2052:             *
2053:             */
2054:            public IRubyObject reject_bang(Block block) {
2055:                int i2 = 0;
2056:                modify();
2057:
2058:                ThreadContext context = getRuntime().getCurrentContext();
2059:                for (int i1 = 0; i1 < realLength; i1++) {
2060:                    IRubyObject v = values[i1];
2061:                    if (block.yield(context, v).isTrue())
2062:                        continue;
2063:
2064:                    if (i1 != i2)
2065:                        store(i2, v);
2066:                    i2++;
2067:                }
2068:                if (realLength == i2)
2069:                    return getRuntime().getNil();
2070:
2071:                if (i2 < realLength)
2072:                    realLength = i2;
2073:
2074:                return this ;
2075:            }
2076:
2077:            /** rb_ary_delete_if
2078:             *
2079:             */
2080:            public IRubyObject delete_if(Block block) {
2081:                reject_bang(block);
2082:                return this ;
2083:            }
2084:
2085:            /** rb_ary_zip
2086:             * 
2087:             */
2088:            public IRubyObject zip(IRubyObject[] args, Block block) {
2089:                for (int i = 0; i < args.length; i++) {
2090:                    args[i] = args[i].convertToArray();
2091:                }
2092:
2093:                Ruby runtime = getRuntime();
2094:                ThreadContext context = runtime.getCurrentContext();
2095:                if (block.isGiven()) {
2096:                    for (int i = 0; i < realLength; i++) {
2097:                        RubyArray tmp = new RubyArray(runtime, args.length + 1);
2098:                        tmp.append(elt(i));
2099:                        for (int j = 0; j < args.length; j++) {
2100:                            tmp.append(((RubyArray) args[j]).elt(i));
2101:                        }
2102:                        block.yield(context, tmp);
2103:                    }
2104:                    return runtime.getNil();
2105:                }
2106:
2107:                int len = realLength;
2108:                RubyArray result = new RubyArray(runtime, len);
2109:                for (int i = 0; i < len; i++) {
2110:                    RubyArray tmp = new RubyArray(runtime, args.length + 1);
2111:                    tmp.append(elt(i));
2112:                    for (int j = 0; j < args.length; j++) {
2113:                        tmp.append(((RubyArray) args[j]).elt(i));
2114:                    }
2115:                    result.append(tmp);
2116:                }
2117:                return result;
2118:            }
2119:
2120:            /** rb_ary_cmp
2121:             *
2122:             */
2123:            public IRubyObject op_cmp(IRubyObject obj) {
2124:                RubyArray ary2 = obj.convertToArray();
2125:
2126:                int len = realLength;
2127:
2128:                if (len > ary2.realLength)
2129:                    len = ary2.realLength;
2130:
2131:                Ruby runtime = getRuntime();
2132:                ThreadContext context = runtime.getCurrentContext();
2133:                for (int i = 0; i < len; i++) {
2134:                    IRubyObject v = elt(i).callMethod(context,
2135:                            MethodIndex.OP_SPACESHIP, "<=>", ary2.elt(i));
2136:                    if (!(v instanceof  RubyFixnum)
2137:                            || ((RubyFixnum) v).getLongValue() != 0)
2138:                        return v;
2139:                }
2140:                len = realLength - ary2.realLength;
2141:
2142:                if (len == 0)
2143:                    return RubyFixnum.zero(runtime);
2144:                if (len > 0)
2145:                    return RubyFixnum.one(runtime);
2146:
2147:                return RubyFixnum.minus_one(runtime);
2148:            }
2149:
2150:            /** rb_ary_slice_bang
2151:             *
2152:             */
2153:            public IRubyObject slice_bang(IRubyObject[] args) {
2154:                if (Arity.checkArgumentCount(getRuntime(), args, 1, 2) == 2) {
2155:                    long pos = RubyNumeric.num2long(args[0]);
2156:                    long len = RubyNumeric.num2long(args[1]);
2157:
2158:                    if (pos < 0)
2159:                        pos = realLength + pos;
2160:
2161:                    args[1] = subseq(pos, len);
2162:                    splice(pos, len, null);
2163:
2164:                    return args[1];
2165:                }
2166:
2167:                IRubyObject arg = args[0];
2168:                if (arg instanceof  RubyRange) {
2169:                    long[] beglen = ((RubyRange) arg).begLen(realLength, 1);
2170:                    long pos = beglen[0];
2171:                    long len = beglen[1];
2172:
2173:                    if (pos < 0) {
2174:                        pos = realLength + pos;
2175:                    }
2176:                    arg = subseq(pos, len);
2177:                    splice(pos, len, null);
2178:                    return arg;
2179:                }
2180:
2181:                return delete_at((int) RubyNumeric.num2long(args[0]));
2182:            }
2183:
2184:            /** rb_ary_assoc
2185:             *
2186:             */
2187:            public IRubyObject assoc(IRubyObject key) {
2188:                Ruby runtime = getRuntime();
2189:                final ThreadContext context = runtime.getCurrentContext();
2190:
2191:                for (int i = begin; i < begin + realLength; i++) {
2192:                    IRubyObject v = values[i];
2193:                    if (v instanceof  RubyArray
2194:                            && ((RubyArray) v).realLength > 0
2195:                            && ((RubyArray) v).values[0].equalInternal(context,
2196:                                    key).isTrue()) {
2197:                        return v;
2198:                    }
2199:                }
2200:                return runtime.getNil();
2201:            }
2202:
2203:            /** rb_ary_rassoc
2204:             *
2205:             */
2206:            public IRubyObject rassoc(IRubyObject value) {
2207:                Ruby runtime = getRuntime();
2208:                final ThreadContext context = runtime.getCurrentContext();
2209:
2210:                for (int i = begin; i < begin + realLength; i++) {
2211:                    IRubyObject v = values[i];
2212:                    if (v instanceof  RubyArray
2213:                            && ((RubyArray) v).realLength > 1
2214:                            && ((RubyArray) v).values[1].equalInternal(context,
2215:                                    value).isTrue()) {
2216:                        return v;
2217:                    }
2218:                }
2219:
2220:                return runtime.getNil();
2221:            }
2222:
2223:            /** flatten
2224:             * 
2225:             */
2226:            private final int flatten(int index, RubyArray ary2, RubyArray memo) {
2227:                int i = index;
2228:                int n;
2229:                int lim = index + ary2.realLength;
2230:
2231:                IRubyObject id = ary2.id();
2232:
2233:                if (memo.includes(id))
2234:                    throw getRuntime().newArgumentError(
2235:                            "tried to flatten recursive array");
2236:
2237:                memo.append(id);
2238:                splice(index, 1, ary2);
2239:                while (i < lim) {
2240:                    IRubyObject tmp = elt(i).checkArrayType();
2241:                    if (!tmp.isNil()) {
2242:                        n = flatten(i, (RubyArray) tmp, memo);
2243:                        i += n;
2244:                        lim += n;
2245:                    }
2246:                    i++;
2247:                }
2248:                memo.pop();
2249:                return lim - index - 1; /* returns number of increased items */
2250:            }
2251:
2252:            /** rb_ary_flatten_bang
2253:             *
2254:             */
2255:            public IRubyObject flatten_bang() {
2256:                int i = 0;
2257:                RubyArray memo = null;
2258:
2259:                while (i < realLength) {
2260:                    IRubyObject ary2 = values[begin + i];
2261:                    IRubyObject tmp = ary2.checkArrayType();
2262:                    if (!tmp.isNil()) {
2263:                        if (memo == null) {
2264:                            memo = new RubyArray(getRuntime(), false);
2265:                            memo.values = reserve(ARRAY_DEFAULT_SIZE);
2266:                        }
2267:
2268:                        i += flatten(i, (RubyArray) tmp, memo);
2269:                    }
2270:                    i++;
2271:                }
2272:                if (memo == null)
2273:                    return getRuntime().getNil();
2274:
2275:                return this ;
2276:            }
2277:
2278:            /** rb_ary_flatten
2279:             *
2280:             */
2281:            public IRubyObject flatten() {
2282:                RubyArray ary = aryDup();
2283:                ary.flatten_bang();
2284:                return ary;
2285:            }
2286:
2287:            /** rb_ary_nitems
2288:             *
2289:             */
2290:            public IRubyObject nitems() {
2291:                int n = 0;
2292:
2293:                for (int i = begin; i < begin + realLength; i++) {
2294:                    if (!values[i].isNil())
2295:                        n++;
2296:                }
2297:
2298:                return getRuntime().newFixnum(n);
2299:            }
2300:
2301:            /** rb_ary_plus
2302:             *
2303:             */
2304:            public IRubyObject op_plus(IRubyObject obj) {
2305:                RubyArray y = obj.convertToArray();
2306:                int len = realLength + y.realLength;
2307:                RubyArray z = new RubyArray(getRuntime(), len);
2308:                System.arraycopy(values, begin, z.values, 0, realLength);
2309:                System.arraycopy(y.values, y.begin, z.values, realLength,
2310:                        y.realLength);
2311:                z.realLength = len;
2312:                return z;
2313:            }
2314:
2315:            /** rb_ary_times
2316:             *
2317:             */
2318:            public IRubyObject op_times(IRubyObject times) {
2319:                IRubyObject tmp = times.checkStringType();
2320:
2321:                if (!tmp.isNil())
2322:                    return join(tmp);
2323:
2324:                long len = RubyNumeric.num2long(times);
2325:                if (len == 0)
2326:                    return new RubyArray(getRuntime(), getMetaClass(), 0);
2327:                if (len < 0)
2328:                    throw getRuntime().newArgumentError("negative argument");
2329:
2330:                if (Long.MAX_VALUE / len < realLength) {
2331:                    throw getRuntime().newArgumentError("argument too big");
2332:                }
2333:
2334:                len *= realLength;
2335:
2336:                RubyArray ary2 = new RubyArray(getRuntime(), getMetaClass(),
2337:                        len);
2338:                ary2.realLength = (int) len;
2339:
2340:                for (int i = 0; i < len; i += realLength) {
2341:                    System.arraycopy(values, begin, ary2.values, i, realLength);
2342:                }
2343:
2344:                ary2.infectBy(this );
2345:
2346:                return ary2;
2347:            }
2348:
2349:            /** ary_make_hash
2350:             * 
2351:             */
2352:            private final Set makeSet(RubyArray ary2) {
2353:                final Set set = new HashSet();
2354:                int begin = this .begin;
2355:                for (int i = begin; i < begin + realLength; i++) {
2356:                    set.add(values[i]);
2357:                }
2358:
2359:                if (ary2 != null) {
2360:                    begin = ary2.begin;
2361:                    for (int i = begin; i < begin + ary2.realLength; i++) {
2362:                        set.add(ary2.values[i]);
2363:                    }
2364:                }
2365:                return set;
2366:            }
2367:
2368:            /** rb_ary_uniq_bang
2369:             *
2370:             */
2371:            public IRubyObject uniq_bang() {
2372:                Set set = makeSet(null);
2373:
2374:                if (realLength == set.size())
2375:                    return getRuntime().getNil();
2376:
2377:                int j = 0;
2378:                for (int i = 0; i < realLength; i++) {
2379:                    IRubyObject v = elt(i);
2380:                    if (set.remove(v))
2381:                        store(j++, v);
2382:                }
2383:                realLength = j;
2384:                return this ;
2385:            }
2386:
2387:            /** rb_ary_uniq
2388:             *
2389:             */
2390:            public IRubyObject uniq() {
2391:                RubyArray ary = aryDup();
2392:                ary.uniq_bang();
2393:                return ary;
2394:            }
2395:
2396:            /** rb_ary_diff
2397:             *
2398:             */
2399:            public IRubyObject op_diff(IRubyObject other) {
2400:                Set set = other.convertToArray().makeSet(null);
2401:                RubyArray ary3 = new RubyArray(getRuntime());
2402:
2403:                int begin = this .begin;
2404:                for (int i = begin; i < begin + realLength; i++) {
2405:                    if (set.contains(values[i]))
2406:                        continue;
2407:
2408:                    ary3.append(elt(i - begin));
2409:                }
2410:
2411:                return ary3;
2412:            }
2413:
2414:            /** rb_ary_and
2415:             *
2416:             */
2417:            public IRubyObject op_and(IRubyObject other) {
2418:                RubyArray ary2 = other.convertToArray();
2419:                Set set = ary2.makeSet(null);
2420:                RubyArray ary3 = new RubyArray(getRuntime(),
2421:                        realLength < ary2.realLength ? realLength
2422:                                : ary2.realLength);
2423:
2424:                for (int i = 0; i < realLength; i++) {
2425:                    IRubyObject v = elt(i);
2426:                    if (set.remove(v))
2427:                        ary3.append(v);
2428:                }
2429:
2430:                return ary3;
2431:            }
2432:
2433:            /** rb_ary_or
2434:             *
2435:             */
2436:            public IRubyObject op_or(IRubyObject other) {
2437:                RubyArray ary2 = other.convertToArray();
2438:                Set set = makeSet(ary2);
2439:
2440:                RubyArray ary3 = new RubyArray(getRuntime(), realLength
2441:                        + ary2.realLength);
2442:
2443:                for (int i = 0; i < realLength; i++) {
2444:                    IRubyObject v = elt(i);
2445:                    if (set.remove(v))
2446:                        ary3.append(v);
2447:                }
2448:                for (int i = 0; i < ary2.realLength; i++) {
2449:                    IRubyObject v = ary2.elt(i);
2450:                    if (set.remove(v))
2451:                        ary3.append(v);
2452:                }
2453:                return ary3;
2454:            }
2455:
2456:            /** rb_ary_sort
2457:             *
2458:             */
2459:            public RubyArray sort(Block block) {
2460:                RubyArray ary = aryDup();
2461:                ary.sort_bang(block);
2462:                return ary;
2463:            }
2464:
2465:            /** rb_ary_sort_bang
2466:             *
2467:             */
2468:            public RubyArray sort_bang(Block block) {
2469:                modify();
2470:                if (realLength > 1) {
2471:                    tmpLock = true;
2472:                    try {
2473:                        if (block.isGiven()) {
2474:                            Arrays.sort(values, 0, realLength,
2475:                                    new BlockComparator(block));
2476:                        } else {
2477:                            Arrays.sort(values, 0, realLength,
2478:                                    new DefaultComparator());
2479:                        }
2480:                    } finally {
2481:                        tmpLock = false;
2482:                    }
2483:                }
2484:                return this ;
2485:            }
2486:
2487:            final class BlockComparator implements  Comparator {
2488:                private Block block;
2489:
2490:                public BlockComparator(Block block) {
2491:                    this .block = block;
2492:                }
2493:
2494:                public int compare(Object o1, Object o2) {
2495:                    ThreadContext context = getRuntime().getCurrentContext();
2496:                    IRubyObject obj1 = (IRubyObject) o1;
2497:                    IRubyObject obj2 = (IRubyObject) o2;
2498:                    IRubyObject ret = block.yield(context, getRuntime()
2499:                            .newArray(obj1, obj2), null, null, true);
2500:                    int n = RubyComparable.cmpint(ret, obj1, obj2);
2501:                    //TODO: ary_sort_check should be done here
2502:                    return n;
2503:                }
2504:            }
2505:
2506:            final class DefaultComparator implements  Comparator {
2507:                public int compare(Object o1, Object o2) {
2508:                    if (o1 instanceof  RubyFixnum && o2 instanceof  RubyFixnum) {
2509:                        long a = ((RubyFixnum) o1).getLongValue();
2510:                        long b = ((RubyFixnum) o2).getLongValue();
2511:                        if (a > b)
2512:                            return 1;
2513:                        if (a < b)
2514:                            return -1;
2515:                        return 0;
2516:                    }
2517:                    if (o1 instanceof  RubyString && o2 instanceof  RubyString) {
2518:                        return ((RubyString) o1).cmp((RubyString) o2);
2519:                    }
2520:
2521:                    IRubyObject obj1 = (IRubyObject) o1;
2522:                    IRubyObject obj2 = (IRubyObject) o2;
2523:
2524:                    IRubyObject ret = obj1.callMethod(obj1.getRuntime()
2525:                            .getCurrentContext(), MethodIndex.OP_SPACESHIP,
2526:                            "<=>", obj2);
2527:                    int n = RubyComparable.cmpint(ret, obj1, obj2);
2528:                    //TODO: ary_sort_check should be done here
2529:                    return n;
2530:                }
2531:            }
2532:
2533:            public static void marshalTo(RubyArray array, MarshalStream output)
2534:                    throws IOException {
2535:                output.writeInt(array.getList().size());
2536:                for (Iterator iter = array.getList().iterator(); iter.hasNext();) {
2537:                    output.dumpObject((IRubyObject) iter.next());
2538:                }
2539:            }
2540:
2541:            public static RubyArray unmarshalFrom(UnmarshalStream input)
2542:                    throws IOException {
2543:                RubyArray result = input.getRuntime().newArray();
2544:                input.registerLinkTarget(result);
2545:                int size = input.unmarshalInt();
2546:                for (int i = 0; i < size; i++) {
2547:                    result.append(input.unmarshalObject());
2548:                }
2549:                return result;
2550:            }
2551:
2552:            /**
2553:             * @see org.jruby.util.Pack#pack
2554:             */
2555:            public RubyString pack(IRubyObject obj) {
2556:                RubyString iFmt = RubyString.objAsString(obj);
2557:                return Pack.pack(getRuntime(), this , iFmt.getByteList());
2558:            }
2559:
2560:            public Class getJavaClass() {
2561:                return List.class;
2562:            }
2563:
2564:            // Satisfy java.util.List interface (for Java integration)
2565:
2566:            public int size() {
2567:                return realLength;
2568:            }
2569:
2570:            public boolean isEmpty() {
2571:                return realLength == 0;
2572:            }
2573:
2574:            public boolean contains(Object element) {
2575:                return indexOf(element) != -1;
2576:            }
2577:
2578:            public Object[] toArray() {
2579:                Object[] array = new Object[realLength];
2580:                for (int i = begin; i < realLength; i++) {
2581:                    array[i - begin] = JavaUtil.convertRubyToJava(values[i]);
2582:                }
2583:                return array;
2584:            }
2585:
2586:            public Object[] toArray(final Object[] arg) {
2587:                Object[] array = arg;
2588:                if (array.length < realLength) {
2589:                    Class type = array.getClass().getComponentType();
2590:                    array = (Object[]) Array.newInstance(type, realLength);
2591:                }
2592:                int length = realLength - begin;
2593:
2594:                for (int i = 0; i < length; i++) {
2595:                    array[i] = JavaUtil.convertRubyToJava(values[i + begin]);
2596:                }
2597:                return array;
2598:            }
2599:
2600:            public boolean add(Object element) {
2601:                append(JavaUtil.convertJavaToRuby(getRuntime(), element));
2602:                return true;
2603:            }
2604:
2605:            public boolean remove(Object element) {
2606:                IRubyObject deleted = delete(JavaUtil.convertJavaToRuby(
2607:                        getRuntime(), element), Block.NULL_BLOCK);
2608:                return deleted.isNil() ? false : true; // TODO: is this correct ?
2609:            }
2610:
2611:            public boolean containsAll(Collection c) {
2612:                for (Iterator iter = c.iterator(); iter.hasNext();) {
2613:                    if (indexOf(iter.next()) == -1)
2614:                        return false;
2615:                }
2616:
2617:                return true;
2618:            }
2619:
2620:            public boolean addAll(Collection c) {
2621:                for (Iterator iter = c.iterator(); iter.hasNext();) {
2622:                    add(iter.next());
2623:                }
2624:                return !c.isEmpty();
2625:            }
2626:
2627:            public boolean addAll(int index, Collection c) {
2628:                Iterator iter = c.iterator();
2629:                for (int i = index; iter.hasNext(); i++) {
2630:                    add(i, iter.next());
2631:                }
2632:                return !c.isEmpty();
2633:            }
2634:
2635:            public boolean removeAll(Collection c) {
2636:                boolean listChanged = false;
2637:                for (Iterator iter = c.iterator(); iter.hasNext();) {
2638:                    if (remove(iter.next())) {
2639:                        listChanged = true;
2640:                    }
2641:                }
2642:                return listChanged;
2643:            }
2644:
2645:            public boolean retainAll(Collection c) {
2646:                boolean listChanged = false;
2647:
2648:                for (Iterator iter = iterator(); iter.hasNext();) {
2649:                    Object element = iter.next();
2650:                    if (!c.contains(element)) {
2651:                        remove(element);
2652:                        listChanged = true;
2653:                    }
2654:                }
2655:                return listChanged;
2656:            }
2657:
2658:            public Object get(int index) {
2659:                return JavaUtil.convertRubyToJava((IRubyObject) elt(index),
2660:                        Object.class);
2661:            }
2662:
2663:            public Object set(int index, Object element) {
2664:                return store(index, JavaUtil.convertJavaToRuby(getRuntime(),
2665:                        element));
2666:            }
2667:
2668:            // TODO: make more efficient by not creating IRubyArray[]
2669:            public void add(int index, Object element) {
2670:                insert(new IRubyObject[] {
2671:                        RubyFixnum.newFixnum(getRuntime(), index),
2672:                        JavaUtil.convertJavaToRuby(getRuntime(), element) });
2673:            }
2674:
2675:            public Object remove(int index) {
2676:                return JavaUtil.convertRubyToJava(delete_at(index),
2677:                        Object.class);
2678:            }
2679:
2680:            public int indexOf(Object element) {
2681:                int begin = this .begin;
2682:
2683:                if (element == null) {
2684:                    for (int i = begin; i < begin + realLength; i++) {
2685:                        if (values[i] == null)
2686:                            return i;
2687:                    }
2688:                } else {
2689:                    IRubyObject convertedElement = JavaUtil.convertJavaToRuby(
2690:                            getRuntime(), element);
2691:
2692:                    for (int i = begin; i < begin + realLength; i++) {
2693:                        if (convertedElement.equals(values[i]))
2694:                            return i;
2695:                    }
2696:                }
2697:                return -1;
2698:            }
2699:
2700:            public int lastIndexOf(Object element) {
2701:                int begin = this .begin;
2702:
2703:                if (element == null) {
2704:                    for (int i = begin + realLength - 1; i >= begin; i--) {
2705:                        if (values[i] == null)
2706:                            return i;
2707:                    }
2708:                } else {
2709:                    IRubyObject convertedElement = JavaUtil.convertJavaToRuby(
2710:                            getRuntime(), element);
2711:
2712:                    for (int i = begin + realLength - 1; i >= begin; i--) {
2713:                        if (convertedElement.equals(values[i]))
2714:                            return i;
2715:                    }
2716:                }
2717:
2718:                return -1;
2719:            }
2720:
2721:            public class RubyArrayConversionIterator implements  Iterator {
2722:                protected int index = 0;
2723:                protected int last = -1;
2724:
2725:                public boolean hasNext() {
2726:                    return index < realLength;
2727:                }
2728:
2729:                public Object next() {
2730:                    IRubyObject element = elt(index);
2731:                    last = index++;
2732:                    return JavaUtil.convertRubyToJava(element, Object.class);
2733:                }
2734:
2735:                public void remove() {
2736:                    if (last == -1)
2737:                        throw new IllegalStateException();
2738:
2739:                    delete_at(last);
2740:                    if (last < index)
2741:                        index--;
2742:
2743:                    last = -1;
2744:
2745:                }
2746:            }
2747:
2748:            public Iterator iterator() {
2749:                return new RubyArrayConversionIterator();
2750:            }
2751:
2752:            final class RubyArrayConversionListIterator extends
2753:                    RubyArrayConversionIterator implements  ListIterator {
2754:                public RubyArrayConversionListIterator() {
2755:                }
2756:
2757:                public RubyArrayConversionListIterator(int index) {
2758:                    this .index = index;
2759:                }
2760:
2761:                public boolean hasPrevious() {
2762:                    return index >= 0;
2763:                }
2764:
2765:                public Object previous() {
2766:                    return JavaUtil.convertRubyToJava(
2767:                            (IRubyObject) elt(last = --index), Object.class);
2768:                }
2769:
2770:                public int nextIndex() {
2771:                    return index;
2772:                }
2773:
2774:                public int previousIndex() {
2775:                    return index - 1;
2776:                }
2777:
2778:                public void set(Object obj) {
2779:                    if (last == -1)
2780:                        throw new IllegalStateException();
2781:
2782:                    store(last, JavaUtil.convertJavaToRuby(getRuntime(), obj));
2783:                }
2784:
2785:                public void add(Object obj) {
2786:                    insert(new IRubyObject[] {
2787:                            RubyFixnum.newFixnum(getRuntime(), index++),
2788:                            JavaUtil.convertJavaToRuby(getRuntime(), obj) });
2789:                    last = -1;
2790:                }
2791:            }
2792:
2793:            public ListIterator listIterator() {
2794:                return new RubyArrayConversionListIterator();
2795:            }
2796:
2797:            public ListIterator listIterator(int index) {
2798:                return new RubyArrayConversionListIterator(index);
2799:            }
2800:
2801:            // TODO: list.subList(from, to).clear() is supposed to clear the sublist from the list.
2802:            // How can we support this operation?
2803:            public List subList(int fromIndex, int toIndex) {
2804:                if (fromIndex < 0 || toIndex > size() || fromIndex > toIndex) {
2805:                    throw new IndexOutOfBoundsException();
2806:                }
2807:
2808:                IRubyObject subList = subseq(fromIndex, toIndex - fromIndex + 1);
2809:
2810:                return subList.isNil() ? null : (List) subList;
2811:            }
2812:
2813:            public void clear() {
2814:                rb_clear();
2815:            }
2816:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.