summaryrefslogtreecommitdiff
path: root/wrappers/php/src/Impl/GoSlice.php
blob: b285cfdebd73f3a72a66ceb0e6f9f6ca9c77f228 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
<?php declare(strict_types=1);

/** @internal */

namespace EduVpn\Common\Impl;

use FFI;
use FFI\CData;
use RuntimeException;

/** @internal */
class GoSlice
{
	// Will be destroyed along with this GoSlice
	private CData $cData, $slice;

	public function __construct(FFI $ffi, string $data)
	{
		$len   = strlen($data);
		$cData = FFI::new(FFI::arrayType(FFI::type('char'), [$len]), false);
		if ($cData === null) throw new RuntimeException('error allocating buffer');
		$this->cData = $cData;
		FFI::memcpy($cData, $data, $len);

		$slice = $ffi->new('GoSlice');
		if ($slice === null) throw new RuntimeException('error allocating buffer');
		$this->slice = $slice;
		$slice->data = FFI::addr($cData); // $cData must not be destroyed while $slice is in use
		$slice->cap  = $slice->len = $len;
	}

	public function slice(): CData
	{
		return $this->slice;
	}

	public function __destruct()
	{
		// Make sure we do not unknowingly use a slice with deallocated data
		$this->slice->data = null;
		$this->slice->cap  = $this->slice->len = 0;
	}
}