MadelineProto/TL.php

187 lines
6.5 KiB
PHP
Raw Normal View History

2016-06-23 23:51:08 +02:00
<?php
set_include_path(get_include_path() . PATH_SEPARATOR . dirname(__FILE__) . DIRECTORY_SEPARATOR . 'libpy2php');
require_once ('libpy2php.php');
$__author__ = 'agrigoryev';
require_once ('os.php');
class TlConstructor {
function __construct($json_dict) {
$this->id = pyjslib_int($json_dict['id']);
$this->type = $json_dict['type'];
$this->predicate = $json_dict['predicate'];
$this->params = [];
foreach ($json_dict['params'] as $param) {
if (($param['type'] == 'Vector<long>')) {
$param['type'] = 'Vector t';
$param['subtype'] = 'long';
} else if (($param['type'] == 'vector<%Message>')) {
$param['type'] = 'vector';
$param['subtype'] = 'message';
} else if (($param['type'] == 'vector<future_salt>')) {
$param['type'] = 'vector';
$param['subtype'] = 'future_salt';
} else {
$param['subtype'] = null;
}
$this->params[] = $param;
}
}
}
class TlMethod {
function __construct($json_dict) {
$this->id = pyjslib_int($json_dict['id']);
$this->type = $json_dict['type'];
$this->method = $json_dict['method'];
$this->params = $json_dict['params'];
}
}
2016-06-28 17:21:10 +02:00
class TLObject extends ArrayObject {
2016-06-23 23:51:08 +02:00
function __construct($tl_elem) {
$this->name = $tl_elem->predicate;
}
}
class TL {
function __construct($filename) {
2016-06-26 14:53:16 +02:00
$TL_dict = json_decode(file_get_contents($filename), true);
2016-06-23 23:51:08 +02:00
$this->constructors = $TL_dict['constructors'];
$this->constructor_id = [];
$this->constructor_type = [];
foreach ($this->constructors as $elem) {
$z = new TlConstructor($elem);
$this->constructor_id[$z->id] = $z;
$this->constructor_type[$z->predicate] = $z;
}
$this->methods = $TL_dict['methods'];
$this->method_id = [];
$this->method_name = [];
foreach ($this->methods as $elem) {
$z = new TlMethod($elem);
$this->method_id[$z->id] = $z;
$this->method_name[$z->method] = $z;
}
}
}
2016-06-26 12:59:15 +02:00
$tl = new TL(__DIR__ . '/TL_schema.JSON');
2016-06-23 23:51:08 +02:00
function serialize_obj($type_, $kwargs) {
2016-06-28 17:21:10 +02:00
global $tl;
2016-06-27 16:52:28 +02:00
$bytes_io = fopen("php://memory", "w+b");
2016-06-23 23:51:08 +02:00
try {
$tl_constructor = $tl->constructor_type[$type_];
}
catch(KeyError $e) {
throw new $Exception(sprintf('Could not extract type: %s', $type_));
}
2016-06-27 16:52:28 +02:00
fwrite($bytes_io, pack_le('i', $tl_constructor->id));
2016-06-23 23:51:08 +02:00
foreach ($tl_constructor->params as $arg) {
2016-06-27 22:52:07 +02:00
serialize_param($bytes_io, $arg['type'], $kwargs[$arg['name']]);
2016-06-23 23:51:08 +02:00
}
2016-06-27 16:52:28 +02:00
return fread_all($bytes_io);
2016-06-23 23:51:08 +02:00
}
function serialize_method($type_, $kwargs) {
2016-06-27 16:52:28 +02:00
global $tl;
$bytes_io = fopen("php://memory", "rw+b");
2016-06-23 23:51:08 +02:00
try {
$tl_method = $tl->method_name[$type_];
}
catch(KeyError $e) {
throw new $Exception(sprintf('Could not extract type: %s', $type_));
}
2016-06-27 16:52:28 +02:00
fwrite($bytes_io, pack_le('i', $tl_method->id));
2016-06-23 23:51:08 +02:00
foreach ($tl_method->params as $arg) {
2016-06-27 22:52:07 +02:00
serialize_param($bytes_io, $arg['type'], $kwargs[$arg['name']]);
2016-06-23 23:51:08 +02:00
}
2016-06-27 16:52:28 +02:00
return fread_all($bytes_io);
2016-06-23 23:51:08 +02:00
}
function serialize_param($bytes_io, $type_, $value) {
if (($type_ == 'int')) {
2016-06-27 16:52:28 +02:00
assert(is_numeric($value));
2016-06-23 23:51:08 +02:00
assert(($value->bit_length() <= 32));
2016-06-27 16:52:28 +02:00
fwrite($bytes_io, pack_le('i', $value));
2016-06-23 23:51:08 +02:00
} else if (($type_ == 'long')) {
2016-06-27 16:52:28 +02:00
assert(is_numeric($value));
fwrite($bytes_io, pack_le('q', $value));
2016-06-23 23:51:08 +02:00
} else if (in_array($type_, ['int128', 'int256'])) {
2016-06-27 16:52:28 +02:00
assert(!empty($value));
fwrite($bytes_io, $value);
2016-06-23 23:51:08 +02:00
} else if (($type_ == 'string') || 'bytes') {
$l = count($value);
if (($l < 254)) {
2016-06-27 16:52:28 +02:00
fwrite($bytes_io, pack_le('b', $l));
fwrite($bytes_io, $value);
fwrite($bytes_io, ('' * ((-$l - 1) % 4)));
2016-06-23 23:51:08 +02:00
} else {
2016-06-27 16:52:28 +02:00
fwrite($bytes_io, 'þ');
fwrite($bytes_io, array_slice(pack_le('i', $l), null, 3));
fwrite($bytes_io, $value);
fwrite($bytes_io, ('' * (-$l % 4)));
2016-06-23 23:51:08 +02:00
}
}
2016-06-27 16:52:28 +02:00
2016-06-23 23:51:08 +02:00
}
/**
* :type bytes_io: io.BytesIO object
*/
function deserialize($bytes_io, $type_ = null, $subtype = null) {
2016-06-28 16:28:25 +02:00
global $tl;
2016-06-27 16:52:28 +02:00
assert(get_resource_type($bytes_io) == 'file' || get_resource_type($bytes_io) == 'stream');
2016-06-23 23:51:08 +02:00
if (($type_ == 'int')) {
2016-06-28 17:21:10 +02:00
$x = unpack_le('i', fread($bytes_io, 4)) [1];
2016-06-23 23:51:08 +02:00
} else if (($type_ == '#')) {
2016-06-28 17:21:10 +02:00
$x = unpack_le('I', fread($bytes_io, 4)) [1];
2016-06-23 23:51:08 +02:00
} else if (($type_ == 'long')) {
2016-06-28 17:21:10 +02:00
$x = unpack_le('q', fread($bytes_io, 8)) [1];
2016-06-23 23:51:08 +02:00
} else if (($type_ == 'double')) {
2016-06-28 17:21:10 +02:00
$x = unpack_le('d', fread($bytes_io, 8)) [1];
2016-06-23 23:51:08 +02:00
} else if (($type_ == 'int128')) {
2016-06-27 16:52:28 +02:00
$x = fread($bytes_io, 16);
2016-06-23 23:51:08 +02:00
} else if (($type_ == 'int256')) {
2016-06-27 16:52:28 +02:00
$x = fread($bytes_io, 32);
2016-06-23 23:51:08 +02:00
} else if (($type_ == 'string') || ($type_ == 'bytes')) {
2016-06-28 17:21:10 +02:00
$l = unpack_le('C', fread($bytes_io, 1)) [1];
2016-06-23 23:51:08 +02:00
assert(($l <= 254));
if (($l == 254)) {
2016-06-28 17:21:10 +02:00
$long_len = unpack_le('I', fread($bytes_io, 3) . '') [1];
2016-06-27 16:52:28 +02:00
$x = fread($bytes_io, $long_len);
fread($bytes_io, (-$long_len % 4));
2016-06-23 23:51:08 +02:00
} else {
2016-06-27 16:52:28 +02:00
$x = fread($bytes_io, $l);
2016-06-28 17:21:10 +02:00
//var_dump((-($l + 1) % 4));
2016-06-27 16:52:28 +02:00
fread($bytes_io, (-($l + 1) % 4));
2016-06-23 23:51:08 +02:00
}
2016-06-28 17:21:10 +02:00
assert(is_string($x));
2016-06-23 23:51:08 +02:00
} else if (($type_ == 'vector')) {
assert(($subtype != null));
2016-06-28 17:21:10 +02:00
$count = unpack_le('l', fread($bytes_io, 4)) [1];
2016-06-26 12:59:15 +02:00
$x = [];
foreach( pyjslib_range($count) as $i ) {
2016-06-27 16:52:28 +02:00
$x[] = deserialize($bytes_io, $subtype);
2016-06-26 12:59:15 +02:00
}
2016-06-23 23:51:08 +02:00
} else {
try {
$tl_elem = $tl->constructor_type[$type_];
}
2016-06-28 17:21:10 +02:00
catch(Exception $e) {
$i = unpack_le('i', fread($bytes_io, 4)) [1];
2016-06-23 23:51:08 +02:00
try {
$tl_elem = $tl->constructor_id[$i];
}
2016-06-28 17:21:10 +02:00
catch(Exception $e) {
throw new Exception(sprintf('Could not extract type: %s', $type_));
2016-06-23 23:51:08 +02:00
}
}
2016-06-28 17:21:10 +02:00
var_dump($tl_elem);
2016-06-23 23:51:08 +02:00
$base_boxed_types = ['Vector t', 'Int', 'Long', 'Double', 'String', 'Int128', 'Int256'];
if (in_array($tl_elem->type, $base_boxed_types)) {
2016-06-27 16:52:28 +02:00
$x = deserialize($bytes_io, $tl_elem->predicate, $subtype);
2016-06-23 23:51:08 +02:00
} else {
$x = new TLObject($tl_elem);
2016-06-28 17:21:10 +02:00
2016-06-23 23:51:08 +02:00
foreach ($tl_elem->params as $arg) {
2016-06-27 16:52:28 +02:00
$x[$arg['name']] = deserialize($bytes_io, $arg['type'], $arg['subtype']);
2016-06-23 23:51:08 +02:00
}
}
}
return $x;
}