diff options
-rw-r--r-- | php/int.php | 108 | ||||
-rw-r--r-- | php/phpgats.php | 468 |
2 files changed, 468 insertions, 108 deletions
diff --git a/php/int.php b/php/int.php deleted file mode 100644 index 478af73..0000000 --- a/php/int.php +++ /dev/null | |||
@@ -1,108 +0,0 @@ | |||
1 | <?php | ||
2 | |||
3 | /* | ||
4 | function writeInta( $iIn ) | ||
5 | { | ||
6 | $ret = ""; | ||
7 | if( $iIn < 0 ) | ||
8 | { | ||
9 | $iIn = -$iIn; | ||
10 | $b = ($iIn&0x3f); | ||
11 | if( $iIn > $b ) | ||
12 | $b |= 0x80 | 0x40; | ||
13 | else | ||
14 | $b |= 0x40; | ||
15 | } | ||
16 | else | ||
17 | { | ||
18 | $b = ($iIn&0x3f); | ||
19 | if( $iIn > $b ) | ||
20 | $b |= 0x80; | ||
21 | } | ||
22 | |||
23 | $ret .= chr( $b ); | ||
24 | $iIn = $iIn >> 6; | ||
25 | |||
26 | while( $iIn > 0 ) | ||
27 | { | ||
28 | $b = ($iIn&0x7f); | ||
29 | if( $iIn > $b ) | ||
30 | $b |= 0x80; | ||
31 | $ret .= chr( $b ); | ||
32 | $iIn = $iIn >> 7; | ||
33 | } | ||
34 | |||
35 | return $ret; | ||
36 | } */ | ||
37 | |||
38 | function writeInt( $iIn ) | ||
39 | { | ||
40 | $ret = ""; | ||
41 | if( gmp_cmp( $iIn, 0 ) < 0 ) | ||
42 | { | ||
43 | $iIn = gmp_mul( $iIn, -1 ); | ||
44 | $b = gmp_intval( gmp_and( $iIn, 0x3f ) ); | ||
45 | if( gmp_cmp( $iIn, $b ) > 0 ) | ||
46 | $b |= 0x80 | 0x40; | ||
47 | else | ||
48 | $b |= 0x40; | ||
49 | } | ||
50 | else | ||
51 | { | ||
52 | $b = gmp_intval( gmp_and( $iIn, 0x3f ) ); | ||
53 | if( gmp_cmp( $iIn, $b ) > 0 ) | ||
54 | $b |= 0x80; | ||
55 | } | ||
56 | |||
57 | $ret .= chr( $b ); | ||
58 | $iIn = gmp_div( $iIn, 64 ); | ||
59 | |||
60 | while( gmp_cmp( $iIn, 0 ) > 0 ) | ||
61 | { | ||
62 | $b = gmp_intval( gmp_and( $iIn, 0x7f ) ); | ||
63 | if( gmp_cmp( $iIn, $b ) > 0 ) | ||
64 | $b |= 0x80; | ||
65 | $ret .= chr( $b ); | ||
66 | $iIn = gmp_div( $iIn, 128 ); | ||
67 | } | ||
68 | |||
69 | return $ret; | ||
70 | } | ||
71 | |||
72 | function readInt( $sIn, &$pos ) | ||
73 | { | ||
74 | $neg = false; | ||
75 | |||
76 | $b = ord($sIn[$pos++]); | ||
77 | if( ($b&0x40) == 0x40 ) | ||
78 | $neg = true; | ||
79 | $iOut = gmp_init( $b&0x3f ); | ||
80 | $mult = gmp_init( 64 ); | ||
81 | while( ($b&0x80) ) | ||
82 | { | ||
83 | $b = ord($sIn[$pos++]); | ||
84 | $iOut = gmp_or( $iOut, gmp_mul( $b&0x7f, $mult ) ); | ||
85 | $mult = gmp_mul( $mult, 128 ); | ||
86 | } | ||
87 | if( $neg == true ) | ||
88 | $iOut = gmp_mul( $iOut, -1 ); | ||
89 | |||
90 | return $iOut; | ||
91 | } | ||
92 | |||
93 | function teststr( $str ) | ||
94 | { | ||
95 | $pos = 0; | ||
96 | $enc = writeInt( $str ); | ||
97 | $out = gmp_strval( readInt( $enc, $pos ) ); | ||
98 | print( $str . " => " . $out ); | ||
99 | if( $out == $str ) | ||
100 | print(", correct.\n"); | ||
101 | else | ||
102 | print(", incorrect.\n"); | ||
103 | } | ||
104 | //print( bin2hex( writeInt("3898993999921") ) . "\n" ); | ||
105 | teststr("-7"); | ||
106 | |||
107 | |||
108 | ?> | ||
diff --git a/php/phpgats.php b/php/phpgats.php new file mode 100644 index 0000000..20e5ef2 --- /dev/null +++ b/php/phpgats.php | |||
@@ -0,0 +1,468 @@ | |||
1 | <?php | ||
2 | |||
3 | /* | ||
4 | * @function phpgats_parseGats( $str_data (string) ); | ||
5 | * @returns gats element | ||
6 | * | ||
7 | * @function phpgats_writeGats( $elem (phpgats_Element subclass) ); | ||
8 | * @returns binary encoded gats string | ||
9 | */ | ||
10 | |||
11 | class phpgats_Element | ||
12 | { | ||
13 | function encode() | ||
14 | { | ||
15 | return ""; | ||
16 | } | ||
17 | function getStr() | ||
18 | { | ||
19 | return ""; | ||
20 | } | ||
21 | function getGatsType() | ||
22 | { | ||
23 | return ""; | ||
24 | } | ||
25 | } | ||
26 | |||
27 | function phpgats_writeInt( $iIn ) | ||
28 | { | ||
29 | $ret = ""; | ||
30 | if( gmp_cmp( $iIn, 0 ) < 0 ) | ||
31 | { | ||
32 | $iIn = gmp_mul( $iIn, -1 ); | ||
33 | $b = gmp_intval( gmp_and( $iIn, 0x3f ) ); | ||
34 | if( gmp_cmp( $iIn, $b ) > 0 ) | ||
35 | $b |= 0x80 | 0x40; | ||
36 | else | ||
37 | $b |= 0x40; | ||
38 | } | ||
39 | else | ||
40 | { | ||
41 | $b = gmp_intval( gmp_and( $iIn, 0x3f ) ); | ||
42 | if( gmp_cmp( $iIn, $b ) > 0 ) | ||
43 | $b |= 0x80; | ||
44 | } | ||
45 | |||
46 | $ret .= chr( $b ); | ||
47 | $iIn = gmp_div( $iIn, 64 ); | ||
48 | |||
49 | while( gmp_cmp( $iIn, 0 ) > 0 ) | ||
50 | { | ||
51 | $b = gmp_intval( gmp_and( $iIn, 0x7f ) ); | ||
52 | if( gmp_cmp( $iIn, $b ) > 0 ) | ||
53 | $b |= 0x80; | ||
54 | $ret .= chr( $b ); | ||
55 | $iIn = gmp_div( $iIn, 128 ); | ||
56 | } | ||
57 | |||
58 | return $ret; | ||
59 | } | ||
60 | |||
61 | function phpgats_readInt( $sIn, &$pos ) | ||
62 | { | ||
63 | $neg = false; | ||
64 | |||
65 | $b = ord($sIn[$pos++]); | ||
66 | if( ($b&0x40) == 0x40 ) | ||
67 | $neg = true; | ||
68 | $iOut = gmp_init( $b&0x3f ); | ||
69 | $mult = gmp_init( 64 ); | ||
70 | while( ($b&0x80) ) | ||
71 | { | ||
72 | $b = ord($sIn[$pos++]); | ||
73 | $iOut = gmp_or( $iOut, gmp_mul( $b&0x7f, $mult ) ); | ||
74 | $mult = gmp_mul( $mult, 128 ); | ||
75 | } | ||
76 | if( $neg == true ) | ||
77 | $iOut = gmp_mul( $iOut, -1 ); | ||
78 | |||
79 | return $iOut; | ||
80 | } | ||
81 | |||
82 | class phpgats_Boolean extends phpgats_Element | ||
83 | { | ||
84 | public $elem = false; | ||
85 | |||
86 | function __construct( $_elem ) | ||
87 | { | ||
88 | $this->elem = ($_elem==true)?true:false; | ||
89 | } | ||
90 | |||
91 | function set( $_elem ) | ||
92 | { | ||
93 | $this->elem = ($_elem==true)?true:false; | ||
94 | } | ||
95 | |||
96 | function get() | ||
97 | { | ||
98 | return $this->elem; | ||
99 | } | ||
100 | |||
101 | function encode() | ||
102 | { | ||
103 | return ($this->elem==true)?"1":"0"; | ||
104 | } | ||
105 | |||
106 | function getStr() | ||
107 | { | ||
108 | return ($this->elem==true)?"true":"false"; | ||
109 | } | ||
110 | |||
111 | function getGatsType() | ||
112 | { | ||
113 | return "boolean"; | ||
114 | } | ||
115 | } | ||
116 | |||
117 | class phpgats_String extends phpgats_Element | ||
118 | { | ||
119 | public $elem = ""; | ||
120 | |||
121 | function __construct( $_elem ) | ||
122 | { | ||
123 | $this->elem = $_elem . ""; | ||
124 | } | ||
125 | |||
126 | function set( $_elem ) | ||
127 | { | ||
128 | $this->elem = $_elem . ""; | ||
129 | } | ||
130 | |||
131 | function get() | ||
132 | { | ||
133 | return $this->elem; | ||
134 | } | ||
135 | |||
136 | function encode() | ||
137 | { | ||
138 | return 's' . phpgats_writeInt(strlen($this->elem)) . $this->elem; | ||
139 | } | ||
140 | |||
141 | function getStr() | ||
142 | { | ||
143 | return $this->get(); | ||
144 | } | ||
145 | |||
146 | function getGatsType() | ||
147 | { | ||
148 | return "string"; | ||
149 | } | ||
150 | } | ||
151 | |||
152 | class phpgats_Integer extends phpgats_Element | ||
153 | { | ||
154 | public $elem = 0; | ||
155 | |||
156 | function __construct( $_elem ) | ||
157 | { | ||
158 | if( getType($_elem) != "resource" ) | ||
159 | $this->elem = gmp_init($_elem); | ||
160 | } | ||
161 | |||
162 | function set( $_elem ) | ||
163 | { | ||
164 | $this->elem = gmp_init($_elem); | ||
165 | } | ||
166 | |||
167 | function get() | ||
168 | { | ||
169 | return $this->elem; | ||
170 | } | ||
171 | |||
172 | function encode() | ||
173 | { | ||
174 | return "i" . phpgats_writeInt($this->elem); | ||
175 | } | ||
176 | |||
177 | function getStr() | ||
178 | { | ||
179 | return gmp_strval($this->elem); | ||
180 | } | ||
181 | |||
182 | function getGatsType() | ||
183 | { | ||
184 | return "integer"; | ||
185 | } | ||
186 | } | ||
187 | |||
188 | class phpgats_Float extends phpgats_Element | ||
189 | { | ||
190 | public $elem = 0; | ||
191 | |||
192 | function __construct( $_elem ) | ||
193 | { | ||
194 | $this->elem = $_elem+0.0; | ||
195 | } | ||
196 | |||
197 | function set( $_elem ) | ||
198 | { | ||
199 | $this->elem = $_elem+0.0; | ||
200 | } | ||
201 | |||
202 | function get() | ||
203 | { | ||
204 | return $this->elem; | ||
205 | } | ||
206 | |||
207 | function encode() | ||
208 | { | ||
209 | throw "Encoding Floats in phpgats doesn't yet work..."; | ||
210 | } | ||
211 | |||
212 | function getStr() | ||
213 | { | ||
214 | return $this->elem+""; | ||
215 | } | ||
216 | |||
217 | function getGatsType() | ||
218 | { | ||
219 | return "float"; | ||
220 | } | ||
221 | } | ||
222 | |||
223 | class phpgats_List extends phpgats_Element | ||
224 | { | ||
225 | public $elems = array(); | ||
226 | |||
227 | function append( $_elem ) | ||
228 | { | ||
229 | if( !is_subclass_of( $_elem, "phpgats_Element" ) ) | ||
230 | throw new Exception( | ||
231 | "can only call phpgats_List::append with phpgats_Element." ); | ||
232 | array_push( $this->elems, $_elem ); | ||
233 | } | ||
234 | |||
235 | function get() | ||
236 | { | ||
237 | return $this->elems; | ||
238 | } | ||
239 | |||
240 | function size() | ||
241 | { | ||
242 | return count($this->elems); | ||
243 | } | ||
244 | |||
245 | function encode() | ||
246 | { | ||
247 | $s_out = "l"; | ||
248 | foreach( $this->elems as $val ) | ||
249 | { | ||
250 | $s_out .= $val->encode(); | ||
251 | } | ||
252 | $s_out .= "e"; | ||
253 | return $s_out; | ||
254 | } | ||
255 | |||
256 | function getGatsType() | ||
257 | { | ||
258 | return "list"; | ||
259 | } | ||
260 | } | ||
261 | |||
262 | class phpgats_Dictionary extends phpgats_Element | ||
263 | { | ||
264 | public $elems = array(); | ||
265 | |||
266 | function append( $_name, $_val ) | ||
267 | { | ||
268 | if( !is_subclass_of( $_val, "phpgats_Element" ) || | ||
269 | gettype($_name)!="string") | ||
270 | throw new Exception( | ||
271 | "can only call phpgats_Dictionary::append with str,phpgats_Element." ); | ||
272 | $this->elems[$_name] = $_val; | ||
273 | } | ||
274 | |||
275 | function get() | ||
276 | { | ||
277 | return $this->elems; | ||
278 | } | ||
279 | |||
280 | function size() | ||
281 | { | ||
282 | return count($this->elems); | ||
283 | } | ||
284 | |||
285 | function encode() | ||
286 | { | ||
287 | $s_out = "d"; | ||
288 | foreach( $this->elems as $key => $val ) | ||
289 | { | ||
290 | $n = new phpgats_String( $key ); | ||
291 | $s_out .= $n->encode(); | ||
292 | $s_out .= $val->encode(); | ||
293 | } | ||
294 | $s_out .= "e"; | ||
295 | return $s_out; | ||
296 | } | ||
297 | |||
298 | function getGatsType() | ||
299 | { | ||
300 | return "dictionary"; | ||
301 | } | ||
302 | } | ||
303 | |||
304 | function phpgats_pC( $str_data, $offset ) | ||
305 | { | ||
306 | if($offset>strlen($str_data)) | ||
307 | throw new Exception("Not enough data"); | ||
308 | } | ||
309 | |||
310 | function phpgats_pS( $str_data, &$offset, $dbg ) | ||
311 | { | ||
312 | $str_tmp = ""; | ||
313 | $gmpSize = phpgats_readInt( $str_data, $offset ); | ||
314 | if( gmp_cmp( $gmpSize, 2147483647 ) > 0 ) | ||
315 | { | ||
316 | throw new Exception( | ||
317 | "size (" . gmp_strval($gmpSize) . ") > phpgats can handle\n"); | ||
318 | } | ||
319 | $iSize = gmp_intval($gmpSize); | ||
320 | $i=0; | ||
321 | $str_tmp = ""; | ||
322 | while( $i<$iSize ) | ||
323 | { | ||
324 | phpgats_pC( $str_data, $offset+1 ); | ||
325 | $str_tmp .= $str_data[$offset++]; | ||
326 | ++$i; | ||
327 | } | ||
328 | return new phpgats_String($str_tmp); | ||
329 | } | ||
330 | |||
331 | function phpgats_pI( $str_data, &$offset, $dbg ) | ||
332 | { | ||
333 | return new phpgats_Integer(phpgats_readInt($str_data, $offset)); | ||
334 | } | ||
335 | |||
336 | function phpgats_pF( $str_data, &$offset, $dbg ) | ||
337 | { | ||
338 | throw "The phpgats Float parsing code doesn't work yet..."; | ||
339 | } | ||
340 | |||
341 | function phpgats_pL( $str_data, &$offset, $dbg ) | ||
342 | { | ||
343 | phpgats_pC( $str_data, $offset ); | ||
344 | $c = $str_data[$offset]; | ||
345 | $l_out = new phpgats_List(); | ||
346 | while( $c != "e" ) | ||
347 | { | ||
348 | $obj = phpgats_pM( $str_data, $offset, $dbg ); | ||
349 | $l_out->append( $obj ); | ||
350 | phpgats_pC( $str_data, $offset ); | ||
351 | $c = $str_data[$offset]; | ||
352 | } | ||
353 | $offset++; | ||
354 | return $l_out; | ||
355 | } | ||
356 | |||
357 | function phpgats_pD( $str_data, &$offset, $dbg ) | ||
358 | { | ||
359 | phpgats_pC( $str_data, $offset ); | ||
360 | $c = $str_data[$offset]; | ||
361 | $d_out = new phpgats_Dictionary(); | ||
362 | while( $c != "e" ) | ||
363 | { | ||
364 | $obj1 = phpgats_pM( $str_data, $offset, $dbg ); | ||
365 | $obj2 = phpgats_pM( $str_data, $offset, $dbg ); | ||
366 | $d_out->append( $obj1->get(), $obj2 ); | ||
367 | phpgats_pC( $str_data, $offset ); | ||
368 | $c = $str_data[$offset]; | ||
369 | } | ||
370 | $offset++; | ||
371 | return $d_out; | ||
372 | } | ||
373 | |||
374 | function phpgats_pM( $str_data, &$offset, $dbg=0 ) | ||
375 | { | ||
376 | phpgats_pC( $str_data, $offset ); | ||
377 | $c = $str_data[$offset++]; | ||
378 | //for( $meme=0; $meme<$dbg; $meme++ ) | ||
379 | // echo " "; | ||
380 | switch( $c ) | ||
381 | { | ||
382 | case 'i': | ||
383 | echo "int:"; | ||
384 | $obj = phpgats_pI( $str_data, $offset, $dbg ); | ||
385 | echo gmp_strval($obj->get()) . "\n"; | ||
386 | return $obj; | ||
387 | break; | ||
388 | case 'l': | ||
389 | echo "list:\n"; | ||
390 | $obj = phpgats_pL( $str_data, $offset, $dbg+1 ); | ||
391 | return $obj; | ||
392 | break; | ||
393 | case 'd': | ||
394 | echo "dic:\n"; | ||
395 | $obj = phpgats_pD( $str_data, $offset, $dbg+1 ); | ||
396 | return $obj; | ||
397 | break; | ||
398 | case 'f': | ||
399 | echo "float:\n"; | ||
400 | $obj = phpgats_pF( $str_data, $offset, $dbg ); | ||
401 | return $obj; | ||
402 | break; | ||
403 | case '1': | ||
404 | echo "true\n"; | ||
405 | return new phpgats_Boolean( true ); | ||
406 | break; | ||
407 | case '0': | ||
408 | echo "false\n"; | ||
409 | return new phpgats_Boolean( false ); | ||
410 | break; | ||
411 | default: | ||
412 | echo "str:"; | ||
413 | $obj = phpgats_pS( $str_data, $offset, $dbg ); | ||
414 | echo $obj->get() . "\n"; | ||
415 | return $obj; | ||
416 | break; | ||
417 | } | ||
418 | } | ||
419 | |||
420 | function phpgats_parseGats( $str_data ) | ||
421 | { | ||
422 | print "parsing\n"; | ||
423 | $offset = 0; | ||
424 | $data_size = strlen( $str_data ); | ||
425 | if( $data_size < 5 ) | ||
426 | { | ||
427 | print "invalid size (< 5)\n"; | ||
428 | return false; | ||
429 | } | ||
430 | if( ord($str_data) != 1 ) //version | ||
431 | return false; | ||
432 | $size = "" . $str_data[1] . $str_data[2] . $str_data[3] . $str_data[4]; | ||
433 | $size = unpack( "Nsize", $size ); | ||
434 | $size = $size["size"]; | ||
435 | if( $data_size < $size ) | ||
436 | { | ||
437 | print "invalid size (needed: " . $size . ", was: " . $data_size . ")\n"; | ||
438 | return false; | ||
439 | } | ||
440 | $offset+=5; | ||
441 | return phpgats_pM( $str_data, $offset ); | ||
442 | } | ||
443 | |||
444 | function phpgats_writeGats( $elem ) | ||
445 | { | ||
446 | $str_out = $elem->encode(); | ||
447 | $str_out = "\x01" . pack( "N", strlen($str_out)+5 ) . $str_out; | ||
448 | return $str_out; | ||
449 | } | ||
450 | |||
451 | /*$l = new phpgats_List(); | ||
452 | $l->append( new phpgats_Integer("27") ); | ||
453 | $l->append( new phpgats_Boolean(true) ); | ||
454 | $l->append( new phpgats_String("testing your monkey") ); | ||
455 | |||
456 | $d = new phpgats_Dictionary(); | ||
457 | $d->append( "theList", $l ); | ||
458 | $d->append( "theFalse", new phpgats_Boolean(false) ); | ||
459 | |||
460 | $f = fopen("testinggats.gats", "w"); | ||
461 | $theStr = phpgats_writeGats($d); | ||
462 | fwrite( $f, $theStr ); | ||
463 | fclose( $f ); | ||
464 | |||
465 | $obj = phpgats_parseGats( $theStr );*/ | ||
466 | |||
467 | ?> | ||
468 | |||