Skip to content

Commit 24f5955

Browse files
Merge pull request #7 from stefanak-michal/all_structures
added missing structures
2 parents 38527dc + 0be5cbc commit 24f5955

File tree

14 files changed

+678
-197
lines changed

14 files changed

+678
-197
lines changed

PackStream/v1/Unpacker.php

Lines changed: 49 additions & 157 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,18 @@
44

55
use Bolt\structures\{
66
Node,
7-
Path,
87
Relationship,
9-
UnboundRelationship
8+
UnboundRelationship,
9+
Path,
10+
Date,
11+
Time,
12+
LocalTime,
13+
DateTime,
14+
DateTimeZoneId,
15+
LocalDateTime,
16+
Duration,
17+
Point2D,
18+
Point3D
1019
};
1120
use Bolt\PackStream\IUnpacker;
1221
use Exception;
@@ -25,6 +34,22 @@ class Unpacker implements IUnpacker
2534
*/
2635
private $message;
2736

37+
private $structuresLt = [
38+
0x4E => [Node::class, 'unpackInteger', 'unpackList', 'unpackMap'],
39+
0x52 => [Relationship::class, 'unpackInteger', 'unpackInteger', 'unpackInteger', 'unpackString', 'unpackMap'],
40+
0x72 => [UnboundRelationship::class, 'unpackInteger', 'unpackString', 'unpackMap'],
41+
0x50 => [Path::class, 'unpackList', 'unpackList', 'unpackList'],
42+
0x44 => [Date::class, 'unpackInteger'],
43+
0x54 => [Time::class, 'unpackInteger', 'unpackInteger'],
44+
0x74 => [LocalTime::class, 'unpackInteger'],
45+
0x46 => [DateTime::class, 'unpackInteger', 'unpackInteger', 'unpackInteger'],
46+
0x66 => [DateTimeZoneId::class, 'unpackInteger', 'unpackInteger', 'unpackInteger'],
47+
0x64 => [LocalDateTime::class, 'unpackInteger', 'unpackInteger'],
48+
0x45 => [Duration::class, 'unpackInteger', 'unpackInteger', 'unpackInteger', 'unpackInteger'],
49+
0x58 => [Point2D::class, 'unpackInteger', 'unpackFloat', 'unpackFloat'],
50+
0x59 => [Point3D::class, 'unpackInteger', 'unpackFloat', 'unpackFloat', 'unpackFloat']
51+
];
52+
2853
/**
2954
* Unpack message
3055
* @param string $msg
@@ -79,7 +104,7 @@ private function u()
79104
if ($result) {
80105
return $output;
81106
}
82-
107+
83108
if ($marker == 0xC3) {
84109
return true;
85110
}
@@ -89,7 +114,7 @@ private function u()
89114
if ($marker == 0xC0) {
90115
return null;
91116
}
92-
117+
93118
$output = $this->unpackFloat($marker, $result);
94119
if ($result) {
95120
return $output;
@@ -133,176 +158,43 @@ private function unpackStruct(int $marker, bool &$result = false)
133158
$size = 0b10110000 ^ $marker;
134159
$result = true;
135160
}
136-
137-
if (!$result) {
138-
return null;
139-
}
140-
141-
$marker = ord($this->next(1));
142-
$result = false;
143-
144-
$output = $this->unpackNode($marker, $result);
145-
if ($result) {
146-
return $output;
147-
}
148-
$output = $this->unpackRelationship($marker, $result);
149-
if ($result) {
150-
return $output;
151-
}
152-
$output = $this->unpackPath($marker, $result);
153-
if ($result) {
154-
return $output;
155-
}
156-
$output = $this->unpackUnboundRelationship($marker, $result);
157-
if ($result) {
158-
return $output;
159-
}
160-
161-
return null;
162-
}
163-
164-
/**
165-
* @param int $marker
166-
* @param bool $result
167-
* @return Node|null
168-
* @throws Exception
169-
*/
170-
private function unpackNode(int $marker, bool &$result = false): ?Node
171-
{
172-
if ($marker != 0x4E) {
173-
return null;
174-
}
175-
176-
$identityMarker = ord($this->next(1));
177-
$identity = $this->unpackInteger($identityMarker, $result);
178-
if (!$result) {
179-
throw new Exception('Node structure identifier unpack error');
180-
}
181-
182-
$labelsMarker = ord($this->next(1));
183-
$labels = $this->unpackList($labelsMarker, $result);
184-
if (!$result) {
185-
throw new Exception('Node structure labels unpack error');
186-
}
187-
188-
$propertiesMarker = ord($this->next(1));
189-
$properties = $this->unpackMap($propertiesMarker, $result);
190-
if (!$result) {
191-
throw new Exception('Node structure properties unpack error');
192-
}
193-
194-
return new Node($identity, $labels, $properties);
195-
}
196-
197-
/**
198-
* @param int $marker
199-
* @param bool $result
200-
* @return Relationship|null
201-
* @throws Exception
202-
*/
203-
private function unpackRelationship(int $marker, bool &$result = false): ?Relationship
204-
{
205-
if ($marker != 0x52) {
206-
return null;
207-
}
208161

209-
$identityMarker = ord($this->next(1));
210-
$identity = $this->unpackInteger($identityMarker, $result);
211162
if (!$result) {
212-
throw new Exception('Relationship structure identifier unpack error');
213-
}
214-
215-
$startNodeIdentityMarker = ord($this->next(1));
216-
$startNodeIdentity = $this->unpackInteger($startNodeIdentityMarker, $result);
217-
if (!$result) {
218-
throw new Exception('Relationship structure start node identifier unpack error');
219-
}
220-
221-
$endNodeIdentityMarker = ord($this->next(1));
222-
$endNodeIdentity = $this->unpackInteger($endNodeIdentityMarker, $result);
223-
if (!$result) {
224-
throw new Exception('Relationship structure end node identifier unpack error');
225-
}
226-
227-
$typeMarker = ord($this->next(1));
228-
$type = $this->unpackString($typeMarker, $result);
229-
if (!$result) {
230-
throw new Exception('Relationship structure type unpack error');
231-
}
232-
233-
$propertiesMarker = ord($this->next(1));
234-
$properties = $this->unpackMap($propertiesMarker, $result);
235-
if (!$result) {
236-
throw new Exception('Relationship structure properties unpack error');
237-
}
238-
239-
return new Relationship($identity, $startNodeIdentity, $endNodeIdentity, $type, $properties);
240-
}
241-
242-
/**
243-
* @param int $marker
244-
* @param bool $result
245-
* @return UnboundRelationship|null
246-
* @throws Exception
247-
*/
248-
private function unpackUnboundRelationship(int $marker, bool &$result = false): ?UnboundRelationship
249-
{
250-
if ($marker != 0x72) {
251163
return null;
252164
}
253165

254-
$identityMarker = ord($this->next(1));
255-
$identity = $this->unpackInteger($identityMarker, $result);
256-
if (!$result) {
257-
throw new Exception('UnboundRelationship structure identifier unpack error');
258-
}
259-
260-
$typeMarker = ord($this->next(1));
261-
$type = $this->unpackString($typeMarker, $result);
262-
if (!$result) {
263-
throw new Exception('UnboundRelationship structure type unpack error');
264-
}
166+
$marker = ord($this->next(1));
167+
$result = false;
265168

266-
$propertiesMarker = ord($this->next(1));
267-
$properties = $this->unpackMap($propertiesMarker, $result);
268-
if (!$result) {
269-
throw new Exception('UnboundRelationship structure properties unpack error');
169+
if (array_key_exists($marker, $this->structuresLt)) {
170+
$output = $this->unpackSpecificStructure($result, ...$this->structuresLt[$marker]);
171+
if ($result)
172+
return $output;
270173
}
271174

272-
return new UnboundRelationship($identity, $type, $properties);
175+
return null;
273176
}
274177

275178
/**
276-
* @param int $marker
179+
* Dynamic predefined specific structure unpacking
277180
* @param bool $result
278-
* @return Path|null
181+
* @param string $class
182+
* @param mixed ...$methods
183+
* @return mixed
279184
* @throws Exception
280185
*/
281-
private function unpackPath(int $marker, bool &$result = false): ?Path
186+
private function unpackSpecificStructure(bool &$result, string $class, ...$methods)
282187
{
283-
if ($marker != 0x50) {
284-
return null;
285-
}
286-
287-
$nodesMarker = ord($this->next(1));
288-
$nodes = $this->unpackList($nodesMarker, $result);
289-
if (!$result) {
290-
throw new Exception('Path structure nodes unpack error');
291-
}
292-
293-
$relationshipsMarker = ord($this->next(1));
294-
$relationships = $this->unpackList($relationshipsMarker, $result);
295-
if (!$result) {
296-
throw new Exception('Path structure relationships unpack error');
297-
}
298-
299-
$sequenceMarker = ord($this->next(1));
300-
$sequence = $this->unpackList($sequenceMarker, $result);
301-
if (!$result) {
302-
throw new Exception('Path structure sequence unpack error');
188+
$output = [];
189+
foreach ($methods as $method) {
190+
$result = false;
191+
$marker = ord($this->next(1));
192+
$output[] = $this->{$method}($marker, $result);
193+
if (!$result)
194+
throw new Exception('Structure call for method "' . $method . '" generated unpack error');
303195
}
304196

305-
return new Path($nodes, $relationships, $sequence);
197+
return new $class(...$output);
306198
}
307199

308200
/**

structures/Date.php

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
3+
namespace Bolt\structures;
4+
5+
/**
6+
* Class Date
7+
* Immutable
8+
*
9+
* An instant capturing the date, but not the time, nor the time zone
10+
*
11+
* @author Michal Stefanak
12+
* @link https://github.com/stefanak-michal/Bolt
13+
* @package Bolt\structures
14+
*/
15+
class Date
16+
{
17+
/**
18+
* @var int
19+
*/
20+
private $days;
21+
22+
/**
23+
* Date constructor.
24+
* @param int $days
25+
*/
26+
public function __construct(int $days)
27+
{
28+
$this->days = $days;
29+
}
30+
31+
/**
32+
* days since the Unix epoch
33+
* @return int
34+
*/
35+
public function days(): int
36+
{
37+
return $this->days;
38+
}
39+
40+
}

structures/DateTime.php

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
<?php
2+
3+
namespace Bolt\structures;
4+
5+
/**
6+
* Class DateTime
7+
* Immutable
8+
*
9+
* An instant capturing the date, the time, and the time zone.
10+
* The time zone information is specified with a zone offset.
11+
*
12+
* To convert to UTC:
13+
* <pre> utc_nanoseconds = (seconds * 1000000000) + nanoseconds - (tx_offset_minutes * 60 * 1000000000) </pre>
14+
*
15+
* @author Michal Stefanak
16+
* @link https://github.com/stefanak-michal/Bolt
17+
* @package Bolt\structures
18+
*/
19+
class DateTime
20+
{
21+
22+
/**
23+
* @var int
24+
*/
25+
private $seconds;
26+
27+
/**
28+
* @var int
29+
*/
30+
private $nanoseconds;
31+
32+
/**
33+
* @var int
34+
*/
35+
private $tz_offset_seconds;
36+
37+
/**
38+
* DateTime constructor.
39+
* @param int $seconds
40+
* @param int $nanoseconds
41+
* @param int $tz_offset_seconds
42+
*/
43+
public function __construct(int $seconds, int $nanoseconds, int $tz_offset_seconds)
44+
{
45+
$this->seconds = $seconds;
46+
$this->nanoseconds = $nanoseconds;
47+
$this->tz_offset_seconds = $tz_offset_seconds;
48+
}
49+
50+
/**
51+
* seconds since the adjusted Unix epoch. This is not UTC
52+
* @return int
53+
*/
54+
public function seconds(): int
55+
{
56+
return $this->seconds;
57+
}
58+
59+
/**
60+
* @return int
61+
*/
62+
public function nanoseconds(): int
63+
{
64+
return $this->nanoseconds;
65+
}
66+
67+
/**
68+
* specifies the offset in minutes from UTC
69+
* @return int
70+
*/
71+
public function tz_offset_seconds(): int
72+
{
73+
return $this->tz_offset_seconds;
74+
}
75+
76+
}

0 commit comments

Comments
 (0)