objectextvalue.java

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

JAVA
1,740
字号
/* * 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.expr.Expr;import com.caucho.quercus.expr.StringLiteralExpr;import com.caucho.quercus.program.AbstractFunction;import com.caucho.vfs.WriteStream;import java.io.IOException;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.io.Serializable;import java.util.AbstractSet;import java.util.HashMap;import java.util.IdentityHashMap;import java.util.Iterator;import java.util.Map;import java.util.Set;import java.util.TreeSet;/** * Represents a PHP object value. */public class ObjectExtValue extends ObjectValue  implements Serializable{  private static final StringValue TO_STRING    = new StringBuilderValue("__toString");  private static final int DEFAULT_SIZE = 16;  private MethodMap<AbstractFunction> _methodMap;  private Entry []_entries;  private int _hashMask;  private int _size;  private boolean _isFieldInit;  public ObjectExtValue(QuercusClass cl)  {    super(cl);    _methodMap = cl.getMethodMap();    _entries = new Entry[DEFAULT_SIZE];    _hashMask = _entries.length - 1;  }  public ObjectExtValue(Env env, ObjectExtValue copy, CopyRoot root)  {    super(copy.getQuercusClass());    _methodMap = copy._methodMap;    _size = copy._size;    _isFieldInit = copy._isFieldInit;        Entry []copyEntries = copy._entries;        _entries = new Entry[copyEntries.length];    _hashMask = copy._hashMask;    int len = copyEntries.length;    for (int i = 0; i < len; i++) {      Entry entry = copyEntries[i];      for (; entry != null; entry = entry._next) {	Entry entryCopy = entry.copyTree(env, root);	entryCopy._next = _entries[i];	if (_entries[i] != null)	  _entries[i]._prev = entryCopy;	_entries[i] = entryCopy;      }    }  }  private void init()  {    _entries = new Entry[DEFAULT_SIZE];    _hashMask = _entries.length - 1;  }    @Override  protected void setQuercusClass(QuercusClass cl)  {    super.setQuercusClass(cl);        _methodMap = cl.getMethodMap();  }  /**   * Returns the number of entries.   */  @Override  public int getSize()  {    return _size;  }  /**   * Gets a field value.   */  @Override  public final Value getField(Env env, StringValue name)  {    int hash = name.hashCode() & _hashMask;    for (Entry entry = _entries[hash];	 entry != null;	 entry = entry._next) {      if (name.equals(entry._key))        return entry._value.toValue();    }    Value value = getFieldExt(env, name);    if (value != null)      return value;    else      return _quercusClass.getField(env, this, name);  }  /**   * Gets a field value.   */  @Override  public Value getThisField(Env env, StringValue name)  {    int hash = name.hashCode() & _hashMask;    for (Entry entry = _entries[hash];	 entry != null;	 entry = entry._next) {      if (name.equals(entry._key))        return entry._value.toValue();    }    Value value = getFieldExt(env, name);    if (value != null)      return value;    else      return UnsetValue.UNSET;  }  /**   * Returns fields not specified by the value.   */  protected Value getFieldExt(Env env, StringValue name)  {    return null;  }  /**   * Returns the array ref.   */  @Override  public Var getFieldRef(Env env, StringValue name)  {    Entry entry = createEntry(name);    Value value = entry._value;    if (value instanceof Var)      return (Var) value;    Var var = new Var(value);    entry.setValue(var);    return var;  }  /**   * Returns the array ref.   */  @Override  public Var getThisFieldRef(Env env, StringValue name)  {    Entry entry = createEntry(name);    Value value = entry._value;    if (value instanceof Var)      return (Var) value;    Var var = new Var(value);    entry.setValue(var);    return var;  }  /**   * Returns the value as an argument which may be a reference.   */  @Override  public Value getFieldArg(Env env, StringValue name)  {    Entry entry = getEntry(name);    if (entry != null)      return entry.toArg();    else      return new ArgGetFieldValue(env, this, name);  }  /**   * Returns the value as an argument which may be a reference.   */  @Override  public Value getThisFieldArg(Env env, StringValue name)  {    Entry entry = getEntry(name);    if (entry != null)      return entry.toArg();    else      return new ArgGetFieldValue(env, this, name);  }  /**   * Returns the value as an argument which may be a reference.   */  @Override  public Value getFieldArgRef(Env env, StringValue name)  {    Entry entry = getEntry(name);    if (entry != null)      return entry.toArg();    else      return new ArgGetFieldValue(env, this, name);  }  /**   * Returns the value as an argument which may be a reference.   */  @Override  public Value getThisFieldArgRef(Env env, StringValue name)  {    Entry entry = getEntry(name);    if (entry != null)      return entry.toArg();    else      return new ArgGetFieldValue(env, this, name);  }  /**   * Adds a new value.   */  @Override  public Value putField(Env env, StringValue name, Value value)  {    Entry entry = getEntry(name);    if (entry == null) {      Value oldValue = putFieldExt(env, name, value);      if (oldValue != null)        return oldValue;            if (! _isFieldInit) {        AbstractFunction fieldSet = _quercusClass.getFieldSet();        if (fieldSet != null) {          _isFieldInit = true;          Value retVal = fieldSet.callMethod(env, this, name, value);          _isFieldInit = false;                    return retVal;        }      }    }        entry = createEntry(name);    Value oldValue = entry._value;    if (value instanceof Var) {      Var var = (Var) value;      // for function return optimization      var.setReference();      entry._value = var;    }    else if (oldValue instanceof Var) {      oldValue.set(value);    }    else {      entry._value = value;    }    return value;  }  /**   * Sets/adds field to this object.   */  @Override  public Value putThisField(Env env, StringValue name, Value value)  {    Entry entry = getEntry(name);    if (entry == null) {      Value oldValue = putFieldExt(env, name, value);      if (oldValue != null)        return oldValue;            if (! _isFieldInit) {        AbstractFunction fieldSet = _quercusClass.getFieldSet();            if (fieldSet != null) {          //php/09k7          _isFieldInit = true;                    Value retVal = fieldSet.callMethod(env, this, name, value);                    _isFieldInit = false;          return retVal;        }      }    }        entry = createEntry(name);    Value oldValue = entry._value;    if (value instanceof Var) {      Var var = (Var) value;      // for function return optimization      var.setReference();      entry._value = var;    }    else if (oldValue instanceof Var) {      oldValue.set(value);    }    else {      entry._value = value;    }    return value;  }    protected Value putFieldExt(Env env, StringValue name, Value value)  {    return null;  }  /**   * Adds a new value to the object.   */  @Override  public void initField(StringValue key, Value value)  {    Entry entry = createEntry(key);    entry._value = value;  }  /**   * Removes a value.   */  @Override  public void unsetField(StringValue name)  {    int hash = name.hashCode() & _hashMask;    for (Entry entry = _entries[hash];	 entry != null;	 entry = entry._next) {      if (name.equals(entry.getKey())) {	Entry prev = entry._prev;	Entry next = entry._next;	if (prev != null)	  prev._next = next;	else	  _entries[hash] = next;	if (next != null)	  next._prev = prev;	_size--;        return;      }    }  }  /**   * Gets a new value.   */  private Entry getEntry(StringValue name)  {    int hash = name.hashCode() & _hashMask;    for (Entry entry = _entries[hash];	 entry != null;	 entry = entry._next) {      if (name.equals(entry._key))	return entry;    }    return null;  }  /**   * Creates the entry for a key.   */  private Entry createEntry(StringValue name)  {    int hash = name.hashCode() & _hashMask;    for (Entry entry = _entries[hash];	 entry != null;	 entry = entry._next) {      if (name.equals(entry._key))        return entry;    }        _size++;    Entry newEntry = new Entry(name);    Entry next = _entries[hash];        if (next != null) {      newEntry._next = next;      next._prev = newEntry;    }    _entries[hash] = newEntry;    // XXX: possibly resize    return newEntry;  }  //  // array methods  //  /**   * Returns the array value with the given key.   */  @Override  public Value get(Value key)  {    ArrayDelegate delegate = _quercusClass.getArrayDelegate();    // php/066q vs. php/0906    //return getField(null, key.toString());    if (delegate != null)      return delegate.get(this, key);    else      return super.get(key);  }  /**   * Sets the array value with the given key.   */  @Override  public Value put(Value key, Value value)  {    // php/0d94    ArrayDelegate delegate = _quercusClass.getArrayDelegate();    if (delegate != null)      return delegate.put(this, key, value);    else      return super.put(key, value);  }  /**   * Appends a new array value   */  @Override  public Value put(Value value)  {    // php/0d94    ArrayDelegate delegate = _quercusClass.getArrayDelegate();    if (delegate != null)      return delegate.put(this, value);    else      return super.put(value);  }  /**   * Unsets the array value   */  @Override  public Value remove(Value key)  {    ArrayDelegate delegate = _quercusClass.getArrayDelegate();    if (delegate != null)      return delegate.unset(this, key);    else      return super.remove(key);  }  //  // Foreach/Traversable functions  //  /**   * Returns an iterator for the key => value pairs.   */  @Override  public Iterator<Map.Entry<Value, Value>> getIterator(Env env)  {    TraversableDelegate delegate = _quercusClass.getTraversableDelegate();    if (delegate != null)      return delegate.getIterator(env, this);    return new EntryIterator(_entries);  }  /**   * Returns an iterator for the keys.   */  @Override  public Iterator<Value> getKeyIterator(Env env)  {    TraversableDelegate delegate = _quercusClass.getTraversableDelegate();    if (delegate != null)      return delegate.getKeyIterator(env, this);    return new KeyIterator(_entries);  }  /**   * Returns an iterator for the values.   */  @Override  public Iterator<Value> getValueIterator(Env env)  {    TraversableDelegate delegate = _quercusClass.getTraversableDelegate();

⌨️ 快捷键说明

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