arrayvalue.java

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

JAVA
1,663
字号
/* * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved * * This file is part of Resin(R) Open Source * * Each copy or derived work must preserve the copyright notice and this * notice unmodified. * * Resin Open Source is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Resin Open Source is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty * of NON-INFRINGEMENT.  See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License * along with Resin Open Source; if not, write to the * *   Free Software Foundation, Inc. *   59 Temple Place, Suite 330 *   Boston, MA 02111-1307  USA * * @author Scott Ferguson */package com.caucho.quercus.env;import com.caucho.quercus.Location;import com.caucho.quercus.function.Marshal;import com.caucho.quercus.function.MarshalFactory;import com.caucho.vfs.WriteStream;import java.io.IOException;import java.io.Serializable;import java.lang.reflect.Array;import java.util.*;import java.util.logging.Level;import java.util.logging.Logger;/** * Represents a PHP array value. */abstract public class ArrayValue extends Value {  private static final Logger log    = Logger.getLogger(ArrayValue.class.getName());  protected static final StringValue KEY = new StringBuilderValue("key");  protected static final StringValue VALUE = new StringBuilderValue("value");  public static final GetKey GET_KEY = new GetKey();  public static final GetValue GET_VALUE = new GetValue();  protected Entry _current;  protected ArrayValue()  {  }  /**   * Returns the type.   */  @Override  public String getType()  {    return "array";  }  /**   * Returns the ValueType.   */  @Override  public ValueType getValueType()  {    return ValueType.ARRAY;  }  /**   * Converts to a boolean.   */  @Override  public boolean toBoolean()  {    return getSize() != 0;  }  /**   * Converts to a string.   */  @Override  public String toString()  {    return "Array";  }  /**   * Converts to an object.   */  public Object toObject()  {    return null;  }  /**   * Converts to a java object.   */  @Override  public Object toJavaObject()  {    return this;  }  //  // Conversions  //    /**   * Converts to an object.   */  @Override  public Value toArray()  {    return this;  }    /**   * Converts to an array value   */  @Override  public ArrayValue toArrayValue(Env env)  {    return this;  }  /**   * Converts to an object.   */  @Override  public Value toObject(Env env)  {    Value obj = env.createObject();    for (Entry entry = getHead(); entry != null; entry = entry._next) {      Value key = entry.getKey();      if (key instanceof StringValue) {        // XXX: intern?        obj.putField(env, key.toString(), entry.getValue());      }    }    return obj;  }  /**   * Converts to a java List object.   */  @Override  public Collection toJavaCollection(Env env, Class type)  {    Collection coll = null;        if (type.isAssignableFrom(HashSet.class)) {      coll = new HashSet();    }    else if (type.isAssignableFrom(TreeSet.class)) {      coll = new TreeSet();    }    else {      try {        coll = (Collection) type.newInstance();      }      catch (Throwable e) {        log.log(Level.FINE, e.toString(), e);        env.warning(L.l("Can't assign array to {0}", type.getName()));        return null;      }    }        for (Entry entry = getHead(); entry != null; entry = entry._next) {      coll.add(entry.getValue().toJavaObject());    }    return coll;  }    /**   * Converts to a java List object.   */  @Override  public List toJavaList(Env env, Class type)  {    List list = null;        if (type.isAssignableFrom(ArrayList.class)) {      list = new ArrayList();    }    else if (type.isAssignableFrom(LinkedList.class)) {      list = new LinkedList();    }    else if (type.isAssignableFrom(Vector.class)) {      list = new Vector();    }    else {      try {        list = (List) type.newInstance();      }      catch (Throwable e) {        log.log(Level.FINE, e.toString(), e);        env.warning(L.l("Can't assign array to {0}", type.getName()));        return null;      }    }    for (Entry entry = getHead(); entry != null; entry = entry._next) {      list.add(entry.getValue().toJavaObject());    }    return list;  }    /**   * Converts to a java object.   */  @Override  public Map toJavaMap(Env env, Class type)  {    Map map = null;        if (type.isAssignableFrom(TreeMap.class)) {      map = new TreeMap();    }    else if (type.isAssignableFrom(LinkedHashMap.class)) {      map = new LinkedHashMap();    }    else {      try {        map = (Map) type.newInstance();      }      catch (Throwable e) {        log.log(Level.FINE, e.toString(), e);	        env.warning(L.l("Can't assign array to {0}",			            type.getName()));	return null;      }    }    for (Entry entry = getHead(); entry != null; entry = entry._next) {      map.put(entry.getKey().toJavaObject(),	          entry.getValue().toJavaObject());    }    return map;  }  /**   * Returns true for an array.   */  @Override  public boolean isArray()  {    return true;  }  /**   * Copy as a return value   */  @Override  public Value copyReturn()  {    return copy(); // php/3a5e  }  /**   * Copy for assignment.   */  @Override  abstract public Value copy();  /**   * Copy for serialization   */  @Override  abstract public Value copy(Env env, IdentityHashMap<Value,Value> map);  /**   * Returns the size.   */  @Override  abstract public int getSize();  /**   * Returns the count().   */  @Override  public int getCount(Env env)  {    return getSize();  }  /**   * Returns the count().   */  @Override  public int getCountRecursive(Env env)  {    env.stub("recursive count of array unimplemented");    return getSize();  }  /**   * Returns true if the value is empty   */  @Override  public boolean isEmpty()  {    return getSize() == 0;  }  /**   * Clears the array   */  abstract public void clear();  @Override  public int cmp(Value rValue)  {    return cmpImpl(rValue, 1);  }  private int cmpImpl(Value rValue, int resultIfKeyMissing)  {    // "if key from operand 1 is not found in operand 2 then    // arrays are uncomparable, otherwise - compare value by value"    // php/335h    if (!rValue.isArray())      return 1;    int lSize =  getSize();    int rSize = rValue.toArray().getSize();        if (lSize != rSize)      return lSize < rSize ? -1 : 1;    for (Map.Entry<Value,Value> entry : entrySet()) {      Value lElementValue = entry.getValue();      Value rElementValue = rValue.get(entry.getKey());      if (!rElementValue.isset())        return resultIfKeyMissing;      int cmp = lElementValue.cmp(rElementValue);      if (cmp != 0)        return cmp;    }    return 0;  }  /**   * Returns true for less than   */  @Override  public boolean lt(Value rValue)  {    // php/335h    return cmpImpl(rValue, 1) < 0;  }  /**   * Returns true for less than or equal to   */  @Override  public boolean leq(Value rValue)  {    // php/335h    return cmpImpl(rValue, 1) <= 0;  }  /**   * Returns true for greater than   */  @Override  public boolean gt(Value rValue)  {    // php/335h    return cmpImpl(rValue, -1) > 0;  }  /**   * Returns true for greater than or equal to   */  @Override  public boolean geq(Value rValue)  {    // php/335h    return cmpImpl(rValue, -1) >= 0;  }  /**   * Adds a new value.   */  @Override  abstract public Value put(Value key, Value value);  /**   * Add   */  @Override  abstract public Value put(Value value);  /**   * Add to front.   */  abstract public ArrayValue unshift(Value value);  /**   * Splices.   */  abstract public ArrayValue splice(int begin, int end, ArrayValue replace);  /**   * Returns the value as an array.   */  @Override  public Value getArray(Value index)  {    Value value = get(index);    Value array = value.toAutoArray();        if (value != array) {      value = array;      put(index, value);    }    return value;  }  /**   * Returns the value as an argument which may be a reference.   */  @Override  abstract public Value getArg(Value index);  /**   * Returns the field value, creating an object if it's unset.   */  @Override  public Value getObject(Env env, Value fieldName)  {    Value value = get(fieldName);    Value object = value.toAutoObject(env);    if (value != object) {      value = object;      put(fieldName, value);    }    return value;  }  /**   * Sets the array ref.   */  @Override  abstract public Value putRef();  /**   * Creatse a tail index.   */  abstract public Value createTailKey();  /**   * Returns a union of this array and the rValue as array.   * If the rValue is not an array, the returned union contains the elements   * of this array only.   *   * To append a value to this ArrayValue use the {@link #put(Value)} method.   */  @Override  public Value add(Value rValue)  {    rValue = rValue.toValue();    if (! (rValue instanceof ArrayValue))      return copy();    ArrayValue rArray = (ArrayValue) rValue;    ArrayValue result = new ArrayValueImpl(rArray);    for (Entry entry = getHead(); entry != null; entry = entry._next) {      result.put(entry.getKey(), entry.getValue());    }    return result;  }  @Override  public Iterator<Map.Entry<Value, Value>> getIterator(Env env)  {    return new EntryIterator(getHead());  }  @Override  public Iterator<Value> getKeyIterator(Env env)  {    return new KeyIterator(getHead());  }  @Override  public Iterator<Value> getValueIterator(Env env)  {    return new ValueIterator(getHead());  }  /**   * Gets a new value.   */  @Override  abstract public Value get(Value key);  /**   * Returns the value in the array as-is.   * (i.e. without calling toValue() on it).   */  public Value getRaw(Value key)  {    return get(key);  }    /**   * Removes a value.   */  @Override  abstract public Value remove(Value key);  /**   * Returns the array ref.   */  @Override

⌨️ 快捷键说明

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