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