arraymodule.java

来自「RESIN 3.2 最新源码」· Java 代码 · 共 2,383 行 · 第 1/5 页

JAVA
2,383
字号
      break;    default:      array.sort(CNO_KEY_REVERSE, NO_KEY_RESET, NOT_STRICT);      break;    }    return true;  }  /**   * Sorts the array based on string values using natural order, preserving   * keys, case sensitive   *   * @param array the array to sort   * @return true if the sort works, false otherwise   * @throws ClassCastException if the elements are not mutually comparable   */  static public Value natsort(ArrayValue array)  {    if (array == null)      return NullValue.NULL;    trimArrayStrings(array);    array.sort(CNA_VALUE_NORMAL_SENSITIVE, NO_KEY_RESET, NOT_STRICT);    return BooleanValue.TRUE;  }  /**   * Sorts the array based on string values using natural order, preserving   * keys, case insensitive   *   * @param array the array to sort   * @return true if the sort works, false otherwise   * @throws ClassCastException if the elements are not mutually comparable   */  static public Value natcasesort(ArrayValue array)  {    if (array == null)      return NullValue.NULL;    trimArrayStrings(array);    array.sort(CNA_VALUE_NORMAL_INSENSITIVE, NO_KEY_RESET, NOT_STRICT);    return BooleanValue.TRUE;  }  /**   * Helper function for natsort and natcasesort to trim the string in the   * array   *   * @param array the array to trim strings from   */  static private void trimArrayStrings(ArrayValue array)  {    if (array != null) {      for (Map.Entry<Value, Value> entry : array.entrySet()) {        Value entryValue = entry.getValue();        if (entryValue instanceof StringValue)          array.put(entry.getKey(),                    StringValue.create(entryValue.toString().trim()));      }    }  }  // XXX: compact  /**   * Determines if the key is in the array   *   * @param needle the array to sort   * @return true if the sort works, false otherwise   * @throws ClassCastException if the elements are not mutually comparable   */  public boolean in_array(@ReadOnly Value needle,                          @ReadOnly ArrayValue stack,                          @Optional("false") boolean strict)  {    if (stack == null)      return false;    Value result;        if (strict)      result = stack.containsStrict(needle);    else      result = stack.contains(needle);        return ! result.isNull();  }  /**   * Sorts the array based on values in ascending order   *   * @param array the array to sort   * @param sortFlag provides optional methods to process the sort   * @return true if the sort works, false otherwise   * @throws ClassCastException if the elements are not mutually comparable   */  public boolean sort(Env env, ArrayValue array, @Optional long sortFlag)  {    if (array == null)      return false;    switch ((int) sortFlag) {    case SORT_STRING:      array.sort(CS_VALUE_NORMAL, KEY_RESET, STRICT);      break;    case SORT_NUMERIC:      array.sort(CN_VALUE_NORMAL, KEY_RESET, STRICT);      break;    case SORT_LOCALE_STRING:      Locale locale = env.getLocaleInfo().getCollate().getLocale();      array.sort(new CompareLocale(ArrayValue.GET_VALUE, SORT_NORMAL,                                   Collator.getInstance(locale)),                 KEY_RESET, STRICT);      break;    default:      array.sort(CNO_VALUE_NORMAL, KEY_RESET, STRICT);      break;    }    return true;  }  /**   * Sorts the array based on values in reverse order   *   * @param array the array to sort   * @param sortFlag provides optional methods to process the sort   * @return true if the sort works, false otherwise   * @throws ClassCastException if the elements are not mutually comparable   */  public boolean rsort(Env env, ArrayValue array, @Optional long sortFlag)  {    if (array == null)      return false;    switch ((int) sortFlag) {    case SORT_STRING:      array.sort(CS_VALUE_REVERSE, KEY_RESET, STRICT);      break;    case SORT_NUMERIC:      array.sort(CN_VALUE_REVERSE, KEY_RESET, STRICT);      break;    case SORT_LOCALE_STRING:      Locale locale = env.getLocaleInfo().getCollate().getLocale();      array.sort(new CompareLocale(ArrayValue.GET_VALUE, SORT_REVERSE,                                   Collator.getInstance(locale)),                 KEY_RESET, STRICT);      break;    default:      array.sort(CNO_VALUE_REVERSE, KEY_RESET, STRICT);      break;    }    return true;  }  /**   * Sorts the array based on values in ascending order using a callback   * function   *   * @param array the array to sort   * @param func the name of the callback function   * @param sortFlag provides optional methods to process the sort   * @return true if the sort works, false otherwise   * @throws ClassCastException if the elements are not mutually comparable   */  public boolean usort(Env env,                       ArrayValue array,                       Callback func,                       @Optional long sortFlag)  {    if (array == null)      return false;    if (! func.isValid()) {      env.warning(L.l("Invalid comparison function"));      return false;    }    CompareCallBack cmp;    // XXX: callback needs to be able to modify array?    cmp = new CompareCallBack(ArrayValue.GET_VALUE, SORT_NORMAL, func, env);    array.sort(cmp, KEY_RESET, STRICT);    return true;  }  /**   * Sorts the array based on values in ascending order using a callback   * function   *   * @param array the array to sort   * @param func the name of the callback function   * @param sortFlag provides optional methods to process the sort   * @return true if the sort works, false otherwise   * @throws ClassCastException if the elements are not mutually comparable   */  static public boolean uasort(Env env,                               ArrayValue array,                               Callback func,                               @Optional long sortFlag)  {    if (array == null)      return false;    if (!func.isValid()) {      env.warning(L.l("Invalid comparison function"));      return false;    }    // XXX: callback needs to be able to modify array?    array.sort(new CompareCallBack(ArrayValue.GET_VALUE, SORT_NORMAL, func,                                   env), NO_KEY_RESET, NOT_STRICT);    return true;  }  /**   * Sorts the array based on values in ascending order using a callback   * function   *   * @param array the array to sort   * @param func the name of the callback function   * @param sortFlag provides optional methods to process the sort   * @return true if the sort works, false otherwise   * @throws ClassCastException if the elements are not mutually comparable   */  static public boolean uksort(Env env,                               ArrayValue array,                               Callback func,                               @Optional long sortFlag)  {    if (array == null)      return false;    if (!func.isValid()) {      env.warning(L.l("Invalid comparison function"));      return false;    }    CompareCallBack cmp;    // XXX: callback needs to be able to modify array?    cmp = new CompareCallBack(ArrayValue.GET_KEY, SORT_NORMAL, func, env);    array.sort(cmp, NO_KEY_RESET, NOT_STRICT);    return true;  }  /**   * Creates an array using the start and end values provided   *   * @param start the 0 index element   * @param end the length - 1 index element   * @param step the new value is increased by this to determine the value for   * the next element   * @return the new array   */  public Value range(Env env,                     @ReadOnly Value start,                     @ReadOnly Value end,                     @Optional("1") long step)  {    if (step < 1)      step = 1;    if (!start.getType().equals(end.getType())) {      start = LongValue.create(start.toLong());      end = LongValue.create(end.toLong());    }    else if (Character.isDigit(start.toChar())) {      start = LongValue.create(start.toLong());      end = LongValue.create(end.toLong());    }    else {      start = rangeIncrement(start, 0);      end = rangeIncrement(end, 0);    }    if (start.eq(end)) {    }    else if (start instanceof StringValue &&             (Math.abs(end.toChar() - start.toChar()) < step)) {      env.warning("steps exceeds the specified range");      return BooleanValue.FALSE;    }    else if (start instanceof LongValue &&             (Math.abs(end.toLong() - start.toLong()) < step)) {      env.warning("steps exceeds the specified range");      return BooleanValue.FALSE;    }    boolean increment = true;    if (! end.geq(start)) {      step *= -1;      increment = false;    }    ArrayValue array = new ArrayValueImpl();    do {      array.put(start);      start = rangeIncrement(start, step);    } while ((increment && start.leq(end)) ||             (!increment && start.geq(end)));    return array;  }  private Value rangeIncrement(Value value, long step)  {    if (value instanceof StringValue)      return StringValue.create((char) (value.toChar() + step));    return LongValue.create(value.toLong() + step);  }  // XXX:You'll need to mark the function as XXX:, because I need to add an  // attribute like @ModifiedSymbolTable and change some analysis of the  // compilation based on that attribute.  //  // Basically, the compiled mode uses Java variables to store PHP  // variables.  The extract() call messes that up, or at least forces the  // compiler to synchronize its view of the variables.  // (email Re:extract: symbol table)  /**   * Inputs new variables into the symbol table from the passed array   *   * @param array the array contained the new variables   * @return the number of new variables added from the array to the symbol   *         table   */  @UsesSymbolTable(replace=false)  public static Value extract(Env env,                              ArrayValue array)  {    if (array == null)      return NullValue.NULL;    int completedSymbols = 0;    for (Value entryKey : array.keySet()) {      Value entryValue;      entryValue = array.get(entryKey);      String symbolName = entryKey.toString();      if (validVariableName(symbolName)) {        env.setValue(symbolName, entryValue);        completedSymbols++;      }    }    return LongValue.create(completedSymbols);  }  /**   * Inputs new variables into the symbol table from the passed array   *   * @param array the array contained the new variables   * @param rawType flag to determine how to handle collisions   * @param valuePrefix used along with the flag   * @return the number of new variables added from the array to the symbol   *         table   */  @UsesSymbolTable  public static Value extract(Env env,                              ArrayValue array,                              long rawType,                              @Optional("NULL") Value valuePrefix)  {    if (array == null)      return NullValue.NULL;    long extractType = rawType & ~EXTR_REFS;    boolean extrRefs = (rawType & EXTR_REFS) != 0;    if (extractType < EXTR_OVERWRITE        || extractType > EXTR_IF_EXISTS && extractType != EXTR_REFS) {      env.warning("Unknown extract type");      return NullValue.NULL;    }    if (extractType >= EXTR_PREFIX_SAME        && extractType <= EXTR_PREFIX_IF_EXISTS        && (valuePrefix == null || ! (valuePrefix.isString()))) {      env.warning("Prefix expected to be specified");      return NullValue.NULL;    }    String prefix = "";    if (valuePrefix instanceof StringValue)      prefix = valuePrefix.toString() + "_";    int completedSymbols = 0;    for (Value entryKey : array.keySet()) {      Value entryValue;      if (extrRefs)        entryValue = array.getRef(entryKey);      else        entryValue = array.get(entryKey);      String symbolName = entryKey.toString();      Value tableValue = env.getValue(symbolName);      switch ((int) extractType) {      case EXTR_SKIP:        if (! tableValue.isNull())          symbolName = "";        break;      case EXTR_PREFIX_SAME:        if (! tableValue.isNull())          symbolName = prefix + symbolName;        break;      case EXTR_PREFIX_ALL:        symbolName = prefix + symbolName;        break;      case EXTR_PREFIX_INVALID:        if (! validVariableName(symbolName))          symbolName = prefix + symbolName;        break;      case EXTR_IF_EXISTS:        if (tableValue.isNull())          symbolName = "";//entryValue = tableValue;        break;      case EXTR_PREFIX_IF_EXISTS:        if (! tableValue.isNull())          symbolName = prefix + symbolName;        else          symbolName = "";        break;      default:        break;      }      if (validVariableName(symbolName)) {        env.setValue(symbolName, entryValue);        completedSymbols++;      }    }    return LongValue.create(completedSymbols);  }  /**

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?