55use Bolt \PackStream \IPacker ;
66use Bolt \error \PackException ;
77use Generator ;
8+ use Bolt \structures \{
9+ IStructure ,
10+ Relationship ,
11+ Date ,
12+ Time ,
13+ LocalTime ,
14+ DateTime ,
15+ DateTimeZoneId ,
16+ LocalDateTime ,
17+ Duration ,
18+ Point2D ,
19+ Point3D
20+ };
821
922/**
1023 * Class Packer of PackStream version 1
@@ -20,6 +33,19 @@ class Packer implements IPacker
2033 private const LARGE = 65536 ;
2134 private const HUGE = 4294967295 ;
2235
36+ private $ structuresLt = [
37+ Relationship::class => [0x52 , 'packInteger ' , 'packInteger ' , 'packInteger ' , 'packString ' , 'packMap ' ],
38+ Date::class => [0x44 , 'packInteger ' ],
39+ Time::class => [0x54 , 'packInteger ' , 'packInteger ' ],
40+ LocalTime::class => [0x74 , 'packInteger ' ],
41+ DateTime::class => [0x46 , 'packInteger ' , 'packInteger ' , 'packInteger ' ],
42+ DateTimeZoneId::class => [0x66 , 'packInteger ' , 'packInteger ' , 'packString ' ],
43+ LocalDateTime::class => [0x64 , 'packInteger ' , 'packInteger ' ],
44+ Duration::class => [0x45 , 'packInteger ' , 'packInteger ' , 'packInteger ' , 'packInteger ' ],
45+ Point2D::class => [0x58 , 'packInteger ' , 'packFloat ' , 'packFloat ' ],
46+ Point3D::class => [0x59 , 'packInteger ' , 'packFloat ' , 'packFloat ' , 'packFloat ' ]
47+ ];
48+
2349 /**
2450 * Pack message with parameters
2551 * @param $signature
@@ -77,6 +103,8 @@ private function p($param): string
77103 $ output .= chr ($ param ? 0xC3 : 0xC2 );
78104 } elseif (is_string ($ param )) {
79105 $ output .= $ this ->packString ($ param );
106+ } elseif ($ param instanceof IStructure) {
107+ $ output .= $ this ->packStructure ($ param );
80108 } elseif (is_array ($ param )) {
81109 $ keys = array_keys ($ param );
82110 if (count ($ param ) == 0 || count (array_filter ($ keys , 'is_int ' )) == count ($ keys )) {
@@ -222,4 +250,34 @@ private function packList(array $arr): string
222250 return $ output ;
223251 }
224252
253+ /**
254+ * @param IStructure $structure
255+ * @return string
256+ * @throws PackException
257+ */
258+ private function packStructure (IStructure $ structure ): string
259+ {
260+ $ reflection = new \ReflectionClass ($ structure );
261+ $ properties = $ reflection ->getProperties ();
262+ $ cnt = count ($ properties );
263+
264+ if (!array_key_exists (get_class ($ structure ), $ this ->structuresLt )) {
265+ throw new PackException ('Provided structure as parameter is not supported ' );
266+ }
267+
268+ $ arr = $ this ->structuresLt [get_class ($ structure )];
269+ if (count ($ arr ) != $ cnt + 1 ) {
270+ throw new PackException ('Invalid amount of structure properties ' );
271+ }
272+
273+ $ output = pack ('C ' , 0b10110000 | $ cnt );
274+ $ output .= chr (array_shift ($ arr ));
275+ foreach ($ arr as $ i => $ method ) {
276+ $ properties [$ i ]->setAccessible (true );
277+ $ output .= $ this ->{$ method }($ properties [$ i ]->getValue ($ structure ));
278+ }
279+
280+ return $ output ;
281+ }
282+
225283}
0 commit comments