object_.diff

LupusMichaelis, 07/26/2009 02:22 am

Download (3.7 kB)

b/ryzom_api/tool_registry.php
1
<?php
2
/* Copyright (C) 2009 Winch Gate Property Limited
3
 *
4
 * This file is part of ryzom_api.
5
 * ryzom_api is free software: you can redistribute it and/or modify
6
 * it under the terms of the GNU Lesser General Public License as published by
7
 * the Free Software Foundation, either version 3 of the License, or
8
 * (at your option) any later version.
9
 *
10
 * ryzom_api is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU Lesser General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU Lesser General Public License
16
 * along with ryzom_api.  If not, see <http://www.gnu.org/licenses/>.
17
 */
18

19
class registry
20
	implements	ArrayAccess
21
{
22
	protected	$_tree = array(0 => null) ;
23
	protected	$_current ;
24

25
	static
26
	public		function load($array)
27
	{
28
		$registry = new self ;
29
		$registry->_tree = $array ;
30
		$registry->cd('/') ;
31

32
		return $registry ;
33
	}
34

35
	public		function __construct()
36
	{
37
		$ref = & $this->_tree ;
38
		$this->_current = (object) array('ref' => &$ref) ;
39
	}
40

41
	public		function cd($path)
42
	{
43
		$current = & $this->_seek_node($path) ;
44
		unset($this->_current->ref) ;
45
		$this->_current->ref = & $current ;
46
		return $this ;
47
	}
48

49
	public		function offsetExists($path)
50
	{
51
		try
52
		{
53
			$node = & $this->_seek_node($path) ;
54
			return is_array($node) ;
55
		}
56
		catch(exception $e)
57
		{
58
			return false ;
59
		}
60
	}
61

62
	public		function offsetGet($path)
63
	{
64
		$node = & $this->_seek_node($path) ;
65
		return isset($node[0]) ? $node[0] : null ;
66
	}
67

68
	public		function offsetUnset($path)
69
	{
70
		$node = & $this->_seek_node($path) ;
71
		$node = null ;
72
	}
73

74
	public		function offsetSet($path, $value)
75
	{
76
		$keys = $this->_explode_path($path) ;
77

78
		// If it is absolute path
79
		if(strpos($path, '/') === 0)
80
		{
81
			$node = & $this->_tree ;
82
			array_shift($keys) ;
83
		}
84
		else
85
			$node = & $this->_current->ref ;
86

87
		// go in tree as deeper as we can
88
		while(is_string($key = array_shift($keys)))
89
		{
90
			if(!empty($key) && isset($node[$key]) && is_array($node[$key]))
91
			{
92
				// reference swaping
93
				unset($n) ;		$n = & $node[$key] ;
94
				unset($node) ;	$node = & $n ;
95
			}
96
			else
97
				break ;
98
		}
99

100
		// create branch if it doesn't exist
101
		do
102
		{
103
			if(!empty($key))
104
			{
105
				$node[$key] = array(0 => null) ;
106
				// reference swaping
107
				unset($n) ;		$n = & $node[$key] ;
108
				unset($node) ;	$node = & $n ;
109
			}
110
		}
111
		while(is_string($key = array_shift($keys))) ;
112

113
		$node[0] = $value ;
114
	}
115

116
	public		function childs($path = '')
117
	{
118
		$node = & $this->_seek_node($path) ;
119
		return array_filter(array_keys($node), 'is_string') ;
120
	}
121

122
	protected	function & _seek_node($path)
123
	{
124
		$keys = $this->_explode_path($path) ;
125

126
		if(strpos($path, '/') === 0)
127
		{
128
			$node = & $this->_tree ;
129
			array_shift($keys) ;
130
		}
131
		else
132
			$node = & $this->_current->ref ;
133

134
		while(is_string($key = array_shift($keys)))
135
		{
136
			if(!empty($key))
137
				if(isset($node[$key]) && is_array($node[$key]))
138
				{
139
					// reference swaping
140
					unset($n) ;		$n = & $node[$key] ;
141
					unset($node) ;	$node = & $n ;
142
				}
143
				else
144
					throw new exception(sprintf('Couldn\'t path to (%s).', $path)) ;
145
		}
146

147
		return $node ;
148
	}
149

150
	protected	function _explode_path($path)
151
	{
152
		$keys = explode('/', $path) ;
153

154
		if(count($keys) < 1)
155
			throw new exception(sprintf('Invalid path "%s".', $path)) ;
156

157
		return $keys ;
158
	}
159
}
160