fix text output of Diogenes_Tree_Node
[diogenes.git] / include / Tree / Node.php
1 <?php
2 /*
3 * Copyright (C) 2003-2004 Polytechnique.org
4 * http://opensource.polytechnique.org/
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21 require_once 'diogenes/diogenes.misc.inc.php';
22
23 define('NODE_DUMP_BINARY', 0);
24 define('NODE_DUMP_TEXT', 1);
25 define('NODE_DUMP_NOCHILDREN', 2);
26 define('VAR_TYPE_NULL', 0);
27 define('VAR_TYPE_INT', 1);
28 define('VAR_TYPE_STRING', 2);
29 define('VAR_TYPE_ARRAY', 3);
30 define('VAR_TYPE_NODE', 4);
31
32 function var_encode_text($var, $level = 0, $no_children = FALSE, $tabstr = ' ', $eol = "\n")
33 {
34 if (is_object($var) && (get_class($var) == 'Diogenes_Tree_Node')) {
35 // node name
36 $code = str_repeat($tabstr, $level) . "node : {$var->name}" . $eol;
37
38 // encode this node's data
39 $code .= str_repeat($tabstr, $level+1) . "* data : " . var_encode_text($var->data, $level + 2, $no_children, $tabstr, $eol). $eol;
40
41 // encode this node's children
42 if (!$no_children)
43 {
44 $code .= str_repeat($tabstr, $level+1) . "* children" . $eol;
45 foreach ($var->children as $index => $child)
46 $code .= str_repeat($tabstr, $level+2) . "index : $index" . $eol;
47 $code .= var_encode_text($child, $level+2, $no_children, $tabstr, $eol);
48 }
49 return $code;
50 } elseif (is_array($var)) {
51 $arraysep = ",$eol";
52 $vcode = '';
53 foreach ($var as $key => $value) {
54 $vcode .= str_repeat($tabstr, $level + 1);
55 $vcode .= "'$key'=>".var_encode_text($value, $level + 1, $no_children, $tabstr, $eol);
56 $vcode .= $arraysep;
57 }
58 if (substr($vcode, -strlen($arraysep)) == $arraysep)
59 $vcode = substr($vcode, 0, - strlen($arraysep));
60
61 $code = "array(".($vcode ? "$eol$vcode$eol".str_repeat($tabstr, $level) : ""). ")";
62 return $code;
63 } elseif (is_scalar($var)) {
64 return "'".$var."'";
65 } else {
66 return 'NULL';
67 }
68 }
69
70 function var_encode_html($var, $level = 0, $no_children = FALSE)
71 {
72 return var_encode_text($var, $level, $no_children, '&nbsp;&nbsp;', $eol = "<br/>\n");
73 }
74
75 function var_encode_bin($var, $no_children = FALSE)
76 {
77 if (is_object($var) && (get_class($var) == 'Diogenes_Tree_Node')) {
78 $code = pack('C', VAR_TYPE_NODE);
79 $code .= var_encode_bin($var->name);
80 $code .= var_encode_bin($var->data);
81 if ($no_children)
82 $code .= var_encode_bin(array());
83 else
84 $code .= var_encode_bin($var->children);
85 } elseif (is_array($var)) {
86 $code = pack('C', VAR_TYPE_ARRAY);
87 $contents = '';
88 foreach ($var as $key => $value) {
89 $contents .= var_encode_bin($key);
90 $contents .= var_encode_bin($value);
91 }
92 $code .= pack('L', strlen($contents));
93 $code .= $contents;
94 } elseif (is_scalar($var)) {
95 $str = "$var";
96 $code = pack('C', VAR_TYPE_STRING);
97 $code .= pack('L', strlen($str));
98 $code .= $str;
99 } else {
100 $code = pack('C', VAR_TYPE_NULL);
101 }
102 return $code;
103 }
104
105 function var_decode_bin(&$bin)
106 {
107 list(,$type) = unpack('C', $bin);
108 $bin = substr($bin, 1);
109 if ($type == VAR_TYPE_NODE)
110 {
111 $name = var_decode_bin($bin);
112 $data = var_decode_bin($bin);
113 $children = var_decode_bin($bin);
114 $var = new Diogenes_Tree_Node($data, $name, $children);
115 } elseif ($type == VAR_TYPE_ARRAY)
116 {
117 list(,$length) = unpack('L', $bin);
118 $bin = substr($bin, 4);
119 $contents = substr($bin, 0, $length);
120 $bin = substr($bin, $length);
121
122 $var = array();
123 while(strlen($contents)) {
124 $key = var_decode_bin($contents);
125 $var[$key] = var_decode_bin($contents);
126 }
127 } elseif ($type == VAR_TYPE_STRING) {
128 list(,$length) = unpack('L', $bin);
129 $bin = substr($bin, 4);
130 $var = substr($bin, 0, $length);
131 $bin = substr($bin, $length);
132 } elseif ($type == VAR_TYPE_NULL) {
133 $var = NULL;
134 } else {
135 trigger_error("unknown type in var_decode_bin : ". $type);
136 }
137 return $var;
138 }
139
140 /** This class describes Diogenes' plugins.
141 */
142 class Diogenes_Tree_Node
143 {
144 /** Data for the current node */
145 var $data;
146
147 /** Name for the current node */
148 var $name;
149
150 /** An array of child nodes */
151 var $children = array();
152
153 /** The parent of this node */
154 // var $parent;
155
156 /** Construct a new tree node.
157 */
158 function Diogenes_Tree_Node($data, $name = '', $children=array())
159 {
160 $this->data = $data;
161 $this->name = $name;
162 $this->children = $children;
163 }
164
165 /** Return the specified child of this node.
166 */
167 function getChild($index)
168 {
169 return $this->children[$index];
170 }
171
172 /** Assign the specified child of this node.
173 */
174 function setChild($index, $node)
175 {
176 $this->children[$index] = $node;
177 }
178
179 /** Read a dump of a node and its children.
180 */
181 function readFile($filename)
182 {
183 $bin = file_get_contents($filename);
184 $node = var_decode_bin($bin);
185 if (!is_object($node) || get_class($node) != 'Diogenes_Tree_Node')
186 {
187 trigger_error('readFile : not a Diogenes_Tree_Node', E_USER_ERROR);
188 }
189 return $node;
190 }
191
192 /** Write a dump of this node and its children.
193 */
194 function writeFile($filename, $mode = NODE_DUMP_IO)
195 {
196 if (!$fp = fopen($filename, "w")) {
197 trigger_error("writeFile : failed to open '$cachefile' for writing", E_USER_ERROR);
198 }
199
200 if ($mode & NODE_DUMP_TEXT) {
201 $out = var_encode_text($this, $level, ($mode & NODE_DUMP_NOCHILDREN));
202 } else {
203 $out = var_encode_bin($this, ($mode & NODE_DUMP_NOCHILDREN));
204 }
205 fputs($fp, $out);
206
207 fclose($fp);
208 }
209
210 }
211
212 ?>