1: <?php
2: /**
3: * PHPWord
4: *
5: * Copyright (c) 2013 PHPWord
6: *
7: * This library is free software; you can redistribute it and/or
8: * modify it under the terms of the GNU Lesser General Public
9: * License as published by the Free Software Foundation; either
10: * version 2.1 of the License, or (at your option) any later version.
11: *
12: * This library is distributed in the hope that it will be useful,
13: * but WITHOUT ANY WARRANTY; without even the implied warranty of
14: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15: * Lesser General Public License for more details.
16: *
17: * You should have received a copy of the GNU Lesser General Public
18: * License along with this library; if not, write to the Free Software
19: * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20: *
21: * @category PHPWord
22: * @package PHPWord
23: * @copyright Copyright (c) 2013 PHPWord
24: * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
25: * @version 0.7.0
26: */
27:
28: /**
29: * PHPWord_HashTable
30: */
31: class PHPWord_HashTable
32: {
33: /**
34: * HashTable elements
35: *
36: * @var array
37: */
38: public $_items = array();
39:
40: /**
41: * HashTable key map
42: *
43: * @var array
44: */
45: public $_keyMap = array();
46:
47: /**
48: * Create a new PHPWord_HashTable
49: *
50: * @param PHPWord_IComparable[] $pSource Optional source array to create HashTable from
51: * @throws Exception
52: */
53: public function __construct($pSource = null)
54: {
55: if (!is_null($pSource)) {
56: // Create HashTable
57: $this->addFromSource($pSource);
58: }
59: }
60:
61: /**
62: * Add HashTable items from source
63: *
64: * @param PHPWord_IComparable[] $pSource Source array to create HashTable from
65: * @throws Exception
66: */
67: public function addFromSource($pSource = null)
68: {
69: // Check if an array was passed
70: if ($pSource == null) {
71: return;
72: } else if (!is_array($pSource)) {
73: throw new Exception('Invalid array parameter passed.');
74: }
75:
76: foreach ($pSource as $item) {
77: $this->add($item);
78: }
79: }
80:
81: /**
82: * Add HashTable item
83: *
84: * @param PHPWord_IComparable $pSource Item to add
85: * @throws Exception
86: */
87: public function add(PHPWord_IComparable $pSource = null)
88: {
89: // Determine hashcode
90: $hashCode = null;
91: $hashIndex = $pSource->getHashIndex();
92: if (is_null($hashIndex)) {
93: $hashCode = $pSource->getHashCode();
94: } else if (isset ($this->_keyMap[$hashIndex])) {
95: $hashCode = $this->_keyMap[$hashIndex];
96: } else {
97: $hashCode = $pSource->getHashCode();
98: }
99:
100: // Add value
101: if (!isset($this->_items[$hashCode])) {
102: $this->_items[$hashCode] = $pSource;
103: $index = count($this->_items) - 1;
104: $this->_keyMap[$index] = $hashCode;
105: $pSource->setHashIndex($index);
106: } else {
107: $pSource->setHashIndex($this->_items[$hashCode]->getHashIndex());
108: }
109: }
110:
111: /**
112: * Remove HashTable item
113: *
114: * @param PHPWord_IComparable $pSource Item to remove
115: * @throws Exception
116: */
117: public function remove(PHPWord_IComparable $pSource = null)
118: {
119: if (isset($this->_items[$pSource->getHashCode()])) {
120: unset($this->_items[$pSource->getHashCode()]);
121:
122: $deleteKey = -1;
123: foreach ($this->_keyMap as $key => $value) {
124: if ($deleteKey >= 0) {
125: $this->_keyMap[$key - 1] = $value;
126: }
127:
128: if ($value == $pSource->getHashCode()) {
129: $deleteKey = $key;
130: }
131: }
132: unset($this->_keyMap[count($this->_keyMap) - 1]);
133: }
134: }
135:
136: /**
137: * Clear HashTable
138: *
139: */
140: public function clear()
141: {
142: $this->_items = array();
143: $this->_keyMap = array();
144: }
145:
146: /**
147: * Count
148: *
149: * @return int
150: */
151: public function count()
152: {
153: return count($this->_items);
154: }
155:
156: /**
157: * Get index for hash code
158: *
159: * @param string $pHashCode
160: * @return int Index
161: */
162: public function getIndexForHashCode($pHashCode = '')
163: {
164: return array_search($pHashCode, $this->_keyMap);
165: }
166:
167: /**
168: * Get by index
169: *
170: * @param int $pIndex
171: * @return PHPWord_IComparable
172: *
173: */
174: public function getByIndex($pIndex = 0)
175: {
176: if (isset($this->_keyMap[$pIndex])) {
177: return $this->getByHashCode($this->_keyMap[$pIndex]);
178: }
179:
180: return null;
181: }
182:
183: /**
184: * Get by hashcode
185: *
186: * @param string $pHashCode
187: * @return PHPWord_IComparable
188: *
189: */
190: public function getByHashCode($pHashCode = '')
191: {
192: if (isset($this->_items[$pHashCode])) {
193: return $this->_items[$pHashCode];
194: }
195:
196: return null;
197: }
198:
199: /**
200: * HashTable to array
201: *
202: * @return PHPWord_IComparable[]
203: */
204: public function toArray()
205: {
206: return $this->_items;
207: }
208:
209: /**
210: * Implement PHP __clone to create a deep clone, not just a shallow copy.
211: */
212: public function __clone()
213: {
214: $vars = get_object_vars($this);
215: foreach ($vars as $key => $value) {
216: if (is_object($value)) {
217: $this->$key = clone $value;
218: }
219: }
220: }
221: }
222: