44
55use 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};
1120use Bolt \PackStream \IUnpacker ;
1221use 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 /**
0 commit comments