001    /*
002      Copyright (C) 2002-2003 Laurent Martelli <laurent@aopsys.com>
003    
004      This program is free software; you can redistribute it and/or modify
005      it under the terms of the GNU Lesser General Public License as
006      published by the Free Software Foundation; either version 2 of the
007      License, or (at your option) any later version.
008    
009      This program is distributed in the hope that it will be useful,
010      but WITHOUT ANY WARRANTY; without even the implied warranty of
011      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
012      GNU Lesser General Public License for more details.
013    
014      You should have received a copy of the GNU Lesser General Public License
015      along with this program; if not, write to the Free Software
016      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
017    
018    package org.objectweb.jac.util;
019    
020    import java.util.Arrays;
021    import java.util.List;
022    import org.aopalliance.intercept.Interceptor;
023    import java.lang.reflect.Array;
024    
025    
026    
027    /**
028     * Various often used array functions
029     */
030    public class ExtArrays
031    {
032        public static final Object[] emptyObjectArray = new Object[0];
033        public static final String[] emptyStringArray = new String[0];
034        public static final Class[] emptyClassArray = new Class[0];
035        public static final Interceptor[] emptyInterceptorArray = new Interceptor[0];
036    
037        /**
038         * Insert an object into an array
039         *
040         * @param position of the object to insert (>=0 and <=array.length)
041         * @param toInsert the object to insert
042         * @param array the array
043         * @return a new array of size array.length+1, where item at
044         * position "position" is toInsert. The actual type of the
045         * returned array is the same as the parameter <code>array</code>,
046         * or the type of <code>toInsert</code>, or Object[].
047         *
048         * @see #add(int,Object,Object[],Class)
049         * @see #add(Object,Object[]) 
050         */
051        public static Object[] add(int position, Object toInsert, Object[] array) {
052            Class type = array.getClass().getComponentType();
053            if (!type.isInstance(toInsert)) {
054                if (toInsert.getClass().isAssignableFrom(type))
055                    type = toInsert.getClass();
056                else 
057                    type = Object.class;
058            }
059            return add(position,toInsert,array,type);
060        }
061    
062        /**
063         * Insert an object into an array
064         *
065         * @param position of the object to insert (>=0 and <=array.length)
066         * @param toInsert the object to insert
067         * @param array the array
068         * @param type component type of the array to return
069         * @return a new array of size array.length+1, where item at
070         * position "position" is toInsert.
071         *
072         * @see #add(int,Object,Object[])
073         */
074        public static Object[] add(int position, Object toInsert, Object[] array, Class type) {
075            Object[] newArray = (Object[])
076                Array.newInstance(type,array.length+1);
077            if (position>0)
078                System.arraycopy(array,0,newArray,0,position);
079            newArray[position] = toInsert;
080            if (position<array.length) {
081                System.arraycopy(array,position,
082                                 newArray,position+1,
083                                 array.length-position);
084            }
085            return newArray;
086        }
087    
088        /**
089         * Append an object at the end of an array
090         * @param toAppend the object to add
091         * @param array the array
092         * @return a new array, of length array.length+1 and whose last item 
093         * is toAppend
094         *
095         * @see #add(int,Object,Object[],Class)
096         * @see #add(Object,Object[],Class)
097         */
098        public static Object[] add(Object toAppend, Object[] array) {
099            return add(array.length,toAppend,array);
100        }
101    
102        /**
103         * Append an object at the end of an array
104         * @param toAppend the object to add
105         * @param array the array
106         * @param type component type of the array to return
107         * @return a new array, of length array.length+1 and whose last item 
108         * is toAppend
109         *
110         * @see #add(Object,Object[])
111         * @see #add(int,Object,Object[])
112         */
113        public static Object[] add(Object toAppend, Object[] array, Class type) {
114            return add(array.length,toAppend,array,type);
115        }
116    
117        /**
118         * Returns the index of a value in an array of Object.
119         *
120         * @param array the array
121         * @param value the searched value
122         * @return Returns the lowest integer value i such that 
123         * array[i]==value, or -1.
124         */
125        public static int indexOf(Object[] array, Object value) {
126            for (int i=0; i<array.length; i++) {
127                if (value==array[i]) {
128                    return i;
129                }
130            }
131            return -1;
132        }
133    
134        /**
135         * Tells wether an array of objects contains a given value
136         * @param array the array to search the value in
137         * @param value the object to search for
138         * @return true if array contains value
139         */
140        public static boolean contains(Object[] array, Object value) {
141            return indexOf(array,value)!=-1;
142        }
143    
144        /**
145         * Tests equality of some elements of two arrays of bytes.
146         * @param a first array of bytes
147         * @param offseta start comparison in first array with this offset
148         * @param b second array
149         * @param offsetb start comparison in second array with this offset
150         * @param length number of bytes to compare
151         */
152        public static boolean equals(byte[] a, int offseta,
153                                     byte[] b, int offsetb,
154                                     int length) {
155            for (int i=0; i<length; i++) {
156                if (a[offseta+i]!=b[offsetb+i])
157                    return false;
158            }
159            return true;
160        }
161    
162        /**
163         * Builds a List out of an array of bytes
164         * @return a List whose elements are Byte objects
165         */
166        public static List asList(byte[] array) {
167            Object[] objects = new Object[array.length];
168            for (int i=0; i<array.length; i++) {
169                objects[i] = new Byte(array[i]);
170            }
171            return Arrays.asList(objects);
172        }
173    
174        /**
175         *
176         */
177        public static Object subArray(Object[] array, int start) {
178            Object result = 
179                Array.newInstance(
180                    array.getClass().getComponentType(), 
181                    array.length-start);
182            System.arraycopy(array, start, result, 0, array.length-start);
183            return result;
184        }
185    }