All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.gwt.emul.javaemul.internal.ArrayHelper Maven / Gradle / Ivy

There is a newer version: 2.12.1
Show newest version
/*
 * Copyright 2015 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package javaemul.internal;

import javaemul.internal.annotations.DoNotAutobox;
import jsinterop.annotations.JsFunction;
import jsinterop.annotations.JsMethod;
import jsinterop.annotations.JsProperty;
import jsinterop.annotations.JsType;

/** Provides utilities to perform operations on Arrays. */
public final class ArrayHelper {

  public static final int ARRAY_PROCESS_BATCH_SIZE = 10000;

  public static  T[] clone(T[] array) {
    Object result = asNativeArray(array).slice();
    return ArrayStamper.stampJavaTypeInfo(result, array);
  }

  public static  T[] clone(T[] array, int fromIndex, int toIndex) {
    Object result = unsafeClone(array, fromIndex, toIndex);
    // array.slice doesn't expand if toIndex > array.length
    setLength(result, toIndex - fromIndex);
    return ArrayStamper.stampJavaTypeInfo(result, array);
  }

  /**
   * Unlike clone, this method returns a copy of the array that is not type marked, nor size
   * guaranteed. This is only safe for temp arrays as returned array will not do any type checks.
   */
  public static Object[] unsafeClone(Object array, int fromIndex, int toIndex) {
    return asNativeArray(array).slice(fromIndex, toIndex);
  }

  public static  T[] createFrom(T[] array, int length) {
    return ArrayStamper.stampJavaTypeInfo(new NativeArray(length), array);
  }

  @JsMethod(name = "Array.isArray", namespace = "")
  public static native boolean isArray(Object o);

  public static int getLength(Object array) {
    return asNativeArray(array).length;
  }

  public static void setLength(Object array, int length) {
    asNativeArray(array).length = length;
  }

  public static void push(Object[] array, Object o) {
    asNativeArray(array).push(o);
  }

  public static void push(byte[] array, byte o) {
    asNativeArray(array).push(o);
  }

  /**
   * Sets an element of an array.
   *
   * 

In GWT, the naive approach of checking or setting an element which may be out of bounds is * optimal. This method always returns the original value, or null for out of bounds. */ public static T setAt(T[] array, int index, T value) { T originalValue = array[index]; array[index] = value; return originalValue; } public static void removeFrom(Object[] array, int index, int deleteCount) { asNativeArray(array).splice(index, deleteCount); } public static void insertTo(Object[] array, int index, Object value) { asNativeArray(array).splice(index, 0, value); } public static void insertTo(Object[] array, int index, Object[] values) { copy(values, 0, array, index, values.length, false); } public static void copy(Object array, int srcOfs, Object dest, int destOfs, int len) { copy(array, srcOfs, dest, destOfs, len, true); } private static void copy( Object src, int srcOfs, Object dest, int destOfs, int len, boolean overwrite) { if (len == 0) { return; } /* * Array.prototype.splice is not used directly to overcome the limits imposed to the number of * function parameters by browsers. */ if (src == dest) { // copying to the same array, make a copy first src = unsafeClone(src, srcOfs, srcOfs + len); srcOfs = 0; } NativeArray destArray = asNativeArray(dest); for (int batchStart = srcOfs, end = srcOfs + len; batchStart < end;) { // increment in block int batchEnd = Math.min(batchStart + ARRAY_PROCESS_BATCH_SIZE, end); len = batchEnd - batchStart; Object[] spliceArgs = unsafeClone(src, batchStart, batchEnd); asNativeArray(spliceArgs).splice(0, 0, (double) destOfs, (double) (overwrite ? len : 0)); getSpliceFunction().apply(destArray, spliceArgs); batchStart = batchEnd; destOfs += len; } } @JsType(isNative = true, name = "Function", namespace = "") private static class NativeFunction { public native String apply(Object thisContext, Object[] argsArray); } @JsProperty(name = "Array.prototype.splice", namespace = "") private static native NativeFunction getSpliceFunction(); /** Compare function for sort. */ @JsFunction public interface CompareFunction { double compare(Object d1, Object d2); } public static void sort(Object array, CompareFunction fn) { asNativeArray(array).sort(fn); } private static NativeArray asNativeArray(Object array) { return JsUtils.uncheckedCast(array); } @JsType(isNative = true, name = "Array", namespace = "") private static class NativeArray { int length; NativeArray(int length) {} native void push(@DoNotAutobox Object item); native Object[] slice(); native Object[] slice(int fromIndex, int toIndex); native void splice(int index, int deleteCount, Object... value); native void sort(CompareFunction compareFunction); } private ArrayHelper() {} }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy