arrayvalueimpl.java

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

JAVA
981
字号
/* * 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.util.RandomUtil;import java.io.IOException;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.io.Serializable;import java.util.IdentityHashMap;import java.util.Map;import java.util.logging.Logger;/** * Represents a PHP array value. */public class ArrayValueImpl extends ArrayValue  implements Serializable{  private static final Logger log    = Logger.getLogger(ArrayValueImpl.class.getName());  private static final StringValue KEY = new StringBuilderValue("key");  private static final StringValue VALUE = new StringBuilderValue("value");    private static final int DEFAULT_SIZE = 16;    private static final int SORT_REGULAR = 0;  private static final int SORT_NUMERIC = 1;  private static final int SORT_STRING = 2;  private static final int SORT_LOCALE_STRING = 5;    private Entry []_entries;  private int _hashMask;  private int _size;  private long _nextAvailableIndex;  private boolean _isDirty;  private Entry _head;  private Entry _tail;  public ArrayValueImpl()  {    _entries = new Entry[DEFAULT_SIZE];    _hashMask = _entries.length - 1;  }  public ArrayValueImpl(int size)  {    int capacity = DEFAULT_SIZE;    while (capacity < 4 * size)      capacity *= 2;        _entries = new Entry[capacity];    _hashMask = _entries.length - 1;  }  public ArrayValueImpl(ArrayValue copy)  {    this(copy.getSize());    for (Entry ptr = copy.getHead(); ptr != null; ptr = ptr._next) {      // php/0662 for copy      put(ptr._key, ptr._value.copyArrayItem());    }  }  public ArrayValueImpl(ArrayValueImpl copy)  {    copy._isDirty = true;    _isDirty = true;        _size = copy._size;    _entries = copy._entries;    _hashMask = copy._hashMask;    _head = copy._head;    _current = copy._current;    _tail = copy._tail;    _nextAvailableIndex = copy._nextAvailableIndex;  }  public ArrayValueImpl(Env env,			IdentityHashMap<Value,Value> map,			ArrayValue copy)  {    this();        map.put(copy, this);    for (Entry ptr = copy.getHead(); ptr != null; ptr = ptr._next) {      put(ptr._key, ptr._value.toValue().copy(env, map));    }  }  /**   * Copy for unserialization.   *   * XXX: need to update for references   */  protected ArrayValueImpl(Env env, ArrayValue copy, CopyRoot root)  {    this();        for (Entry ptr = copy.getHead(); ptr != null; ptr = ptr._next) {      put(ptr._key, ptr._value.toValue().copyTree(env, root));    }  }  public ArrayValueImpl(Value []keys, Value []values)  {    this();    for (int i = 0; i < keys.length; i++) {      if (keys[i] != null)	put(keys[i], values[i]);      else	put(values[i]);    }  }  public ArrayValueImpl(Value []values)  {    this();    for (int i = 0; i < values.length; i++) {      put(values[i]);    }  }  private void copyOnWrite()  {    if (! _isDirty)      return;    _isDirty = false;        Entry []entries = new Entry[_entries.length];        Entry prev = null;    for (Entry ptr = _head; ptr != null; ptr = ptr._next) {      Entry ptrCopy = new Entry(ptr._key, ptr._value.copyArrayItem());      Entry head = entries[ptr._index];      if (head != null) {        ptrCopy._nextHash = head;        head._prevHash = ptrCopy;      }      entries[ptr._index] = ptrCopy;            ptrCopy._index = ptr._index;      if (prev == null)	_head = _current = ptrCopy;      else {	prev._next = ptrCopy;	ptrCopy._prev = prev;      }      prev = ptrCopy;    }    _tail = prev;    _entries = entries;  }    /**   * Returns the type.   */  public String getType()  {    return "array";  }  /**   * Converts to a boolean.   */  public boolean toBoolean()  {    return _size != 0;  }    /**   * Converts to a string.   * @param env   */  public StringValue toString(Env env)  {    return env.createString("Array");  }    /**   * Converts to an object.   */  public Object toObject()  {    return null;  }    /**   * Copy for assignment.   */  public Value copy()  {    _isDirty = true;        return new ArrayValueImpl(this);  }    /**   * Copy for assignment.   */  public Value copyReturn()  {    _isDirty = true;        return new ArrayValueImpl(this);  }    /**   * Copy for serialization   */  public Value copy(Env env, IdentityHashMap<Value,Value> map)  {    Value oldValue = map.get(this);    if (oldValue != null)      return oldValue;    return new ArrayValueImpl(env, map, this);  }    /**   * Copy for serialization   */  @Override  public Value copyTree(Env env, CopyRoot root)  {    return new ArrayCopyValueImpl(env, this, root);  }    /**   * Convert to an argument value.   */  @Override  public Value toArgValue()  {    return copy();  }    /**   * Convert to an argument declared as a reference   */  @Override  public Value toRefValue()  {    return this;  }  /**   * Returns the size.   */  public int size()  {    return _size;  }  /**   * Returns the size.   */  public int getSize()  {    return size();  }  /**   * Clears the array   */  public void clear()  {    if (_isDirty) {      _entries = new Entry[_entries.length];      _isDirty = false;    }        _size = 0;    _head = _tail = _current = null;    _nextAvailableIndex = 0;    for (int j = _entries.length - 1; j >= 0; j--) {      _entries[j] = null;    }  }  /**   * Returns true for an array.   */  public boolean isArray()  {    return true;  }    /**   * Adds a new value.   */  public Value put(Value key, Value value)  {    if (_isDirty)      copyOnWrite();    if (key instanceof UnsetValue) // php/4a4h      key = createTailKey();    Entry entry = createEntry(key);    // php/0434    Value oldValue = entry._value;    if (value instanceof Var) {      // php/0a59      Var var = (Var) value;      var.setReference();      entry._value = var;    }    else if (oldValue instanceof Var) {      oldValue.set(value);    }    else {      entry._value = value;    }    return value;  }  /**   * Add to the beginning   */  public ArrayValue unshift(Value value)  {    if (_isDirty)      copyOnWrite();        _size++;        if (_entries.length <= 2 * _size)      expand();    Value key = createTailKey();    Entry entry = new Entry(key, value.toArgValue());    addEntry(entry);    if (_head != null) {      _head._prev = entry;      entry._next = _head;      _head = entry;    }    else {      _head = _tail = entry;    }    return this;  }  /**   * Replace a section of the array.   */  public ArrayValue splice(int start, int end, ArrayValue replace)  {    if (_isDirty)      copyOnWrite();    int index = 0;    ArrayValueImpl result = new ArrayValueImpl();    Entry ptr = _head;    Entry next = null;    for (; ptr != null; ptr = next) {      next = ptr._next;            Value key = ptr.getKey();            if (index < start) {      }      else if (index < end) {	_size--;		if (ptr._prev != null)	  ptr._prev._next = ptr._next;	else	  _head = ptr._next;		if (ptr._next != null)	  ptr._next._prev = ptr._prev;	else	  _tail = ptr._prev;	if (ptr.getKey() instanceof StringValue)	  result.put(ptr.getKey(), ptr.getValue());	else	  result.put(ptr.getValue());      }      else if (replace == null) {	return result;      }      else {	for (Entry replaceEntry = replace.getHead();	     replaceEntry != null;	     replaceEntry = replaceEntry._next) {	  _size++;	  	  if (_entries.length <= 2 * _size)	    expand();	  Entry entry = new Entry(createTailKey(), replaceEntry.getValue());	  addEntry(entry);	  entry._next = ptr;	  entry._prev = ptr._prev;	  if (ptr._prev != null)	    ptr._prev._next = entry;	  else	    _head = entry;	  ptr._prev = entry;	}	return result;      }      index++;    }    if (replace != null) {      for (Entry replaceEntry = replace.getHead();	   replaceEntry != null;	   replaceEntry = replaceEntry._next) {	put(replaceEntry.getValue());      }    }    return result;  }  /**   * Returns the value as an argument which may be a reference.   */  public Value getArg(Value index)  {    if (_isDirty) // XXX: needed?      copyOnWrite();    

⌨️ 快捷键说明

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