summaryrefslogtreecommitdiff
path: root/wrappers/php/src/Impl/GoSlice.php
diff options
context:
space:
mode:
Diffstat (limited to 'wrappers/php/src/Impl/GoSlice.php')
-rw-r--r--wrappers/php/src/Impl/GoSlice.php43
1 files changed, 43 insertions, 0 deletions
diff --git a/wrappers/php/src/Impl/GoSlice.php b/wrappers/php/src/Impl/GoSlice.php
new file mode 100644
index 0000000..441b460
--- /dev/null
+++ b/wrappers/php/src/Impl/GoSlice.php
@@ -0,0 +1,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) throw new RuntimeException('error allocating buffer');
+ $this->cData = $cData;
+ FFI::memcpy($cData, $data, $len);
+
+ $slice = $ffi->new('GoSlice');
+ if (!$slice) 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;
+ }
+}