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 + -
显示快捷键?