/*=============================================================================# # Copyright (c) 2009-2016 Stephan Wahlbrink (WalWare.de) and others. # All rights reserved. This program and the accompanying materials # are made available under the terms of either (per the licensee's choosing) # - the Eclipse Public License v1.0 # which accompanies this distribution, and is available at # http://www.eclipse.org/legal/epl-v10.html, or # - the GNU Lesser General Public License v2.1 or newer # which accompanies this distribution, and is available at # http://www.gnu.org/licenses/lgpl.html # # Contributors: # Stephan Wahlbrink - initial API and implementation #=============================================================================*/ package de.walware.rj.data.defaultImpl; import java.io.IOException; import de.walware.rj.data.RList; import de.walware.rj.data.RObject; import de.walware.rj.data.RStore; public abstract class AbstractRObject implements RObject { protected static final RObject[] EMPTY_ROBJECT_ARRAY = new RObject[0]; protected static final RObject[][] EMPTY_ROBJECT_2dARRAY = new RObject[0][]; protected static final long check2dArrayLength(final RObject[][] array, final int segmentLength) { long length = 0; if (array.length > 0) { final int last = array.length - 1; for (int i = 0; i < last; i++) { if (array[i].length != segmentLength) { throw new IllegalArgumentException("Unexpected list segment length (" + array[i].length + ", but " + segmentLength + " expected)"); } } length = last * (long) segmentLength; if (array[last].length > segmentLength) { throw new IllegalArgumentException("Unexpected list segment length (" + array[last].length + ", but max " + segmentLength + " expected)"); } length += array[last].length; } return length; } protected static final RObject[][] new2dRObjectArray(final long length, final int segmentLength) { if (length == 0) { return EMPTY_ROBJECT_2dARRAY; } final RObject[][] array = new RObject[1 + (int) ((length - 1) / segmentLength)][]; final int last = array.length - 1; for (int i = 0; i < last; i++) { array[i] = new RObject[segmentLength]; } { final int restLength = (int) (length % segmentLength); array[last] = new RObject[(restLength == 0) ? segmentLength : restLength]; } return array; } protected static final int checkShortLength(final long length) throws IOException { if (length >= Integer.MAX_VALUE) { throw new IOException("Long length (" + length + ") not supported by this implementation."); } return (int) length; } protected static final int getNewArraySize(final int length) { if (length >= 0xfffffff) { return Integer.MAX_VALUE; } return ((length+0x7) | 0xf) + 1; } protected static final RObject[] ensureCapacity(final RObject[] currentValues, final int length) { if (currentValues.length >= length) { return currentValues; } return new RObject[getNewArraySize(length)]; } protected static final RStore<?>[] ensureCapacity(final RStore<?>[] currentValues, final int length) { if (currentValues.length >= length) { return currentValues; } return new RStore[getNewArraySize(length)]; } protected static final RObject[] prepareInsert(final RObject[] currentValues, final int currentLength, final int[] idxs) { final RObject[] newValues = ensureCapacity(currentValues, currentLength+idxs.length); int i = idxs.length-1; System.arraycopy(currentValues, idxs[i], newValues, idxs[i]+i+1, currentLength-idxs[i]); for (i--; i >= 0; i--) { System.arraycopy(currentValues, idxs[i], newValues, idxs[i]+i+1, idxs[i+1]-idxs[i]); } if (currentValues != newValues) { System.arraycopy(currentValues, 0, newValues, 0, idxs[0]); } return newValues; } protected static final RStore<?>[] prepareInsert(final RStore<?>[] currentValues, final int currentLength, final int[] idxs) { final RStore<?>[] newValues = ensureCapacity(currentValues, currentLength+idxs.length); int i = idxs.length-1; System.arraycopy(currentValues, idxs[i], newValues, idxs[i]+i+1, currentLength-idxs[i]); for (i--; i >= 0; i--) { System.arraycopy(currentValues, idxs[i], newValues, idxs[i]+i+1, idxs[i+1]-idxs[i]); } if (currentValues != newValues) { System.arraycopy(currentValues, 0, newValues, 0, idxs[0]); } return newValues; } protected static final RObject[] remove(final RObject[] currentValues, final int currentLength, final int[] idxs) { final RObject[] newValues = ensureCapacity(currentValues, currentLength-idxs.length); if (currentValues != newValues) { System.arraycopy(currentValues, 0, newValues, 0, idxs[0]); } int i = 0; for (; i < idxs.length-1; i++) { System.arraycopy(currentValues, idxs[i]+1, newValues, idxs[i]-i, idxs[i+1]-idxs[i]); } System.arraycopy(currentValues, idxs[i]+1, newValues, idxs[i]-i, currentLength-idxs[i]-1); return newValues; } protected static final RStore<?>[] remove(final RStore<?>[] currentValues, final int currentLength, final int[] idxs) { final RStore<?>[] newValues = ensureCapacity(currentValues, currentLength-idxs.length); if (currentValues != newValues) { System.arraycopy(currentValues, 0, newValues, 0, idxs[0]); } int i = 0; for (; i < idxs.length-1; i++) { System.arraycopy(currentValues, idxs[i]+1, newValues, idxs[i]-i, idxs[i+1]-idxs[i]); } System.arraycopy(currentValues, idxs[i]+1, newValues, idxs[i]-i, currentLength-idxs[i]-1); return newValues; } private RList attributes; protected void setAttributes(final RList attributes) { this.attributes = attributes; } @Override public final RList getAttributes() { return this.attributes; } }