Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PHP TL GEN: PART 1 #59

Merged
merged 26 commits into from
Dec 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
2a20081
add basic writer
Brat-vseznamus Nov 2, 2024
5c67297
add reader and writer + basic tests
Brat-vseznamus Nov 6, 2024
d521a24
update php helper
Brat-vseznamus Nov 13, 2024
0ccdf7e
commit new abstractions
Brat-vseznamus Nov 13, 2024
828236a
reverse engineered php names
Brat-vseznamus Dec 9, 2024
ffe767e
add paths
Brat-vseznamus Dec 9, 2024
a77527d
add non function struct body
Brat-vseznamus Dec 10, 2024
e71c8f6
add non function union body
Brat-vseznamus Dec 10, 2024
b2f099a
zero args constructor + skip internal methods
Brat-vseznamus Dec 10, 2024
e0bc3f6
php function bodies and smth else
Brat-vseznamus Dec 11, 2024
40b2df8
add small fixes
Brat-vseznamus Dec 11, 2024
f72ac0e
mystery solved: type arguments are always boxed, types are bare
Brat-vseznamus Dec 11, 2024
30ca948
check nullable field
Brat-vseznamus Dec 11, 2024
641449b
kphp special code
Brat-vseznamus Dec 12, 2024
2ccac3d
add rpc function and response
Brat-vseznamus Dec 12, 2024
f3ed619
merged masks for same bit
Brat-vseznamus Dec 12, 2024
795da08
float default update + correct order on fieldmask methods
Brat-vseznamus Dec 12, 2024
08ff321
online useable types
Brat-vseznamus Dec 12, 2024
abb724f
fix small diff
Brat-vseznamus Dec 15, 2024
3354eb2
zero diff without absences
Brat-vseznamus Dec 15, 2024
f1f57bd
diff in generic functions
Brat-vseznamus Dec 16, 2024
4c4f005
diff 12
Brat-vseznamus Dec 16, 2024
5d4efd3
php rpc stuff
Brat-vseznamus Dec 17, 2024
90f14ea
php rpc methods
Brat-vseznamus Dec 17, 2024
af74804
0% diff
Brat-vseznamus Dec 17, 2024
a887d5d
linter fixes
Brat-vseznamus Dec 23, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
299 changes: 299 additions & 0 deletions internal/tlcodegen/helpers_php.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,299 @@
package tlcodegen

const BasicTlPathPhp = "basictl.php"
const BasicTLCodePHP = `
<?php
include "run.php";

class tl_constants {
const tinyStringLen = 253;
const bigStringMarker = 0xfe;
const hugeStringMarker = 0xff;
const bigStringLen = (1 << 24) - 1;
const hugeStringLen = (1 << 56) - 1;
}

class tl_input_stream {
/** @var string */
private $data = "";
/** @var int */
private $offset = 0;

public function __construct(string $data) {
$this->data = $data;
}

public function get_offset(): int {
return $this->offset;
}

public function remaining_size(): int {
return strlen($this->data) - $this->offset;
}

/** @return tuple(int, bool) */
public function read_int32() {
// TODO: 'l' - signed 32 bit SYSTEM DEPENDENT ENDIAN
$data = unpack('l', $this->data, $this->offset);
if (!$data) {
return [0, false];
} else {
$this->offset += 4;
return [$data[1], true];
}
}

/** @return tuple(int, bool) */
public function read_uint32() {
$data = unpack('V', $this->data, $this->offset);
if (!$data) {
return [0, false];
} else {
$this->offset += 4;
return [$data[1], true];
}
}

/** @return tuple(bool, bool) */
public function read_bool(int $false_tag, $true_tag) {
[$tag, $success] = $this->read_uint32();
if (!$success) {
return [false, false];
} else if ($tag == $false_tag) {
return [false, true];
} else if ($tag == $true_tag) {
return [true, true];
}
return [false, false];
}

/** @return tuple(float, bool) */
public function read_float() {
$data = unpack('f', $this->data, $this->offset);
if (!$data) {
return [0, false];
} else {
$this->offset += 4;
return [$data[1], true];
}
}

/** @return tuple(float, bool) */
public function read_double() {
$data = unpack('d', $this->data, $this->offset);
if (!$data) {
return [0, false];
} else {
$this->offset += 8;
return [$data[1], true];
}
}

/** @return tuple(string, bool) */
public function read_string() {
$size = $this->remaining_size();
if ($size == 0) {
return ["", false];
}
$first_byte = ord($this->data[$this->offset]);
$l = 0;
$p = 0;
if ($first_byte < tl_constants::tinyStringLen) {
$l = $first_byte;
$this->offset += 1;
$p = $l + 1;
} elseif ($first_byte == tl_constants::bigStringMarker) {
if ($size < 4) {
return ["", false];
}
$l = (ord($this->data[$this->offset + 3]) << 16) + (ord($this->data[$this->offset + 2]) << 8) + (ord($this->data[$this->offset + 1]) << 0);
$this->offset += 4;
$p = $l;
if ($l <= tl_constants::tinyStringLen) {
return ["", false];
}
} else {
if ($size < 8) {
return ["", false];
}
$l64 = (ord($this->data[$this->offset + 7]) << 48) + (ord($this->data[$this->offset + 6]) << 40) + (ord($this->data[$this->offset + 5]) << 32) + (ord($this->data[$this->offset + 4]) << 24) + (ord($this->data[$this->offset + 3]) << 16) + (ord($this->data[$this->offset + 2]) << 8) + (ord($this->data[$this->offset + 1]) << 0);
// TODO: check l64 > maxint
$l = $l64;
$this->offset += 8;
$p = $l;
if ($l <= tl_constants::bigStringLen) {
return ["", false];
}
}
$start = $this->offset;
if ($l > 0) {
if ($this->remaining_size() < $l) {
return ["", false];
}
}
$padding = $this->paddingLen($p);
for ($i = 0; $i < $padding; $i++) {
if (ord($this->data[$this->offset + $l + $i]) != 0) {
return ["", false];
}
}
$this->offset += $l + $padding;
return [substr($this->data, $start, $l), true];
}

function paddingLen(int $l): int {
return (4 - ($l % 4)) % 4;
}
}

class tl_output_stream {
/** @var string */
private $data = "";

public function __construct(string $data) {
$this->data = $data;
}

public function get_data(): string {
return $this->data;
}

public function write_uint32(int $value) {
$this->data .= pack('V', $value);
}

public function write_int32(int $value) {
$this->data .= pack('l', $value);
}

public function write_bool(bool $value, int $false_tag, $true_tag) {
if ($value) {
$this->data .= pack('V', $true_tag);
} else {
$this->data .= pack('V', $false_tag);
}
}

public function write_float(float $value) {
$this->data .= pack('f', $value);
}

public function write_double(float $value) {
$this->data .= pack('d', $value);
}

public function write_string(string $value) {
$l = strlen($value);
$p = 0;
if ($l <= tl_constants::tinyStringLen) {
$this->data .= chr($l);
$p = $l + 1;
} else if ($l <= tl_constants::bigStringLen) {
$this->data .= chr(tl_constants::bigStringMarker);
$this->data .= chr(($l & 255));
$this->data .= chr((($l >> 8) & 255));
$this->data .= chr((($l >> 16) & 255));
$p = $l;
} else {
if ($l > tl_constants::hugeStringLen) {
$l = tl_constants::hugeStringLen;
$value = substr($value, 0, $l);
}
$this->data .= chr(tl_constants::hugeStringMarker);
$this->data .= chr(($l & 255));
$this->data .= chr((($l >> 8) & 255));
$this->data .= chr((($l >> 16) & 255));
$this->data .= chr((($l >> 24) & 255));
$this->data .= chr((($l >> 32) & 255));
$this->data .= chr((($l >> 40) & 255));
$this->data .= chr((($l >> 48) & 255));
$p = $l;
}
$this->data .= $value;
if ($p % 4 == 1) {
$this->data .= chr(0);
$this->data .= chr(0);
$this->data .= chr(0);
} else if ($p % 4 == 2) {
$this->data .= chr(0);
$this->data .= chr(0);
} else if ($p % 4 == 3) {
$this->data .= chr(0);
}
}
}
?>
`

const RpcFunctionPHP = `<?php

%s#ifndef KPHP

namespace VK\TL;

/**
* @kphp-tl-class
*/
interface RpcFunction {

/**
* @kphp-inline
*
* @return string
*/
public function getTLFunctionName();
}

/**
* @kphp-tl-class
*/
interface RpcFunctionReturnResult {

}

#endif
`
const RpcResponsePHP = `<?php

%s#ifndef KPHP

namespace VK\TL;

use VK\TL;

/**
* @kphp-tl-class
*/
interface RpcResponse {

/** Allows kphp implicitly load all available constructors */
const CONSTRUCTORS = [
TL\_common\Types\rpcResponseError::class,
TL\_common\Types\rpcResponseHeader::class,
TL\_common\Types\rpcResponseOk::class
];

/**
* @return TL\RpcFunctionReturnResult
*/
public function getResult();

/**
* @return TL\_common\Types\rpcResponseHeader
*/
public function getHeader();

/**
* @return bool
*/
public function isError();

/**
* @return TL\_common\Types\rpcResponseError
*/
public function getError();

}

#endif
`
Loading
Loading