@@ -30,7 +30,17 @@ public function encode(Protobuf\Message $message)
30
30
*/
31
31
public function decode (Protobuf \Message $ message , $ data )
32
32
{
33
- return $ this ->decodeMessage ($ message , $ data );
33
+ static $ reader ;
34
+
35
+ // Create a single reader for all messages to be parsed
36
+ if (!$ reader ) {
37
+ $ reader = new Protobuf \Codec \Binary \Reader ();
38
+ }
39
+
40
+ // Initialize the reader with the current message data
41
+ $ reader ->init ($ data );
42
+
43
+ return $ this ->decodeMessage ($ reader , $ message );
34
44
}
35
45
36
46
@@ -167,19 +177,26 @@ protected function encodeSimpleType($writer, $type, $value)
167
177
}
168
178
}
169
179
170
-
171
- protected function decodeMessage (\DrSlump \Protobuf \Message $ message , $ data )
180
+ /**
181
+ * @param \DrSlump\Protobuf\Codec\Binary\Reader $reader
182
+ * @param \DrSlump\Protobuf\Message $message
183
+ * @param int $length
184
+ * @return \DrSlump\Protobuf\Message
185
+ */
186
+ protected function decodeMessage ($ reader , \DrSlump \Protobuf \Message $ message , $ length = NULL )
172
187
{
173
188
/** @var $message \DrSlump\Protobuf\Message */
174
189
/** @var $descriptor \DrSlump\Protobuf\Descriptor */
175
190
176
- // Create a binary reader for the data
177
- $ reader = new Protobuf \Codec \Binary \Reader ($ data );
178
-
179
191
// Get message descriptor
180
192
$ descriptor = Protobuf::getRegistry ()->getDescriptor ($ message );
181
193
182
- while (!$ reader ->eof ()) {
194
+ // Calculate the maximum offset if we have defined a length
195
+ $ limit = $ length ? $ reader ->pos () + $ length : NULL ;
196
+ $ pos = $ reader ->pos ();
197
+
198
+ // Keep reading until we reach the end or the limit
199
+ while ($ limit === NULL && !$ reader ->eof () || $ limit !== NULL && $ reader ->pos () < $ limit ) {
183
200
184
201
// Get initial varint with tag number and wire type
185
202
$ key = $ reader ->varint ();
@@ -203,10 +220,11 @@ protected function decodeMessage(\DrSlump\Protobuf\Message $message, $data)
203
220
// flag of the message since we cannot be certain if the creator of the message
204
221
// was using it.
205
222
if ($ wire === self ::WIRE_LENGTH && $ field ->isRepeated () && $ this ->isPackable ($ type )) {
206
- $ length = $ reader ->varint ();
207
- $ until = $ reader ->pos () + $ length ;
223
+ $ len = $ reader ->varint ();
224
+ $ until = $ reader ->pos () + $ len ;
225
+ $ wire = $ this ->getWireType ($ type );
208
226
while ($ reader ->pos () < $ until ) {
209
- $ item = $ this ->decodeSimpleType ($ reader , $ type , self :: WIRE_VARINT );
227
+ $ item = $ this ->decodeSimpleType ($ reader , $ type , $ wire );
210
228
$ message ->_add ($ tag , $ item );
211
229
}
212
230
@@ -220,10 +238,10 @@ protected function decodeMessage(\DrSlump\Protobuf\Message $message, $data)
220
238
$ submessage = $ field ->getReference ();
221
239
$ submessage = new $ submessage ;
222
240
223
- $ length = $ this ->decodeSimpleType ($ reader , Protobuf::TYPE_INT64 , self ::WIRE_VARINT );
224
- $ data = $ reader ->read ($ length );
241
+ $ len = $ reader ->varint ();
225
242
226
- $ value = $ this ->decodeMessage ($ submessage , $ data );
243
+ //$reader2 = new Binary\Reader( $reader->read($len) );
244
+ $ value = $ this ->decodeMessage ($ reader , $ submessage , $ len );
227
245
} else {
228
246
$ value = $ this ->decodeSimpleType ($ reader , $ type , $ wire );
229
247
}
@@ -292,32 +310,28 @@ protected function assertWireType($wire, $type)
292
310
293
311
protected function getWireType ($ type , $ default )
294
312
{
295
- switch ($ type ) {
296
- case Protobuf::TYPE_INT32 :
297
- case Protobuf::TYPE_INT64 :
298
- case Protobuf::TYPE_UINT32 :
299
- case Protobuf::TYPE_UINT64 :
300
- case Protobuf::TYPE_SINT32 :
301
- case Protobuf::TYPE_SINT64 :
302
- case Protobuf::TYPE_BOOL :
303
- case Protobuf::TYPE_ENUM :
304
- return self ::WIRE_VARINT ;
305
- case Protobuf::TYPE_FIXED64 :
306
- case Protobuf::TYPE_SFIXED64 :
307
- case Protobuf::TYPE_DOUBLE :
308
- return self ::WIRE_FIXED64 ;
309
- case Protobuf::TYPE_STRING :
310
- case Protobuf::TYPE_BYTES :
311
- case Protobuf::TYPE_MESSAGE :
312
- return self ::WIRE_LENGTH ;
313
- case Protobuf::TYPE_FIXED32 :
314
- case Protobuf::TYPE_SFIXED32 :
315
- case Protobuf::TYPE_FLOAT :
316
- return self ::WIRE_FIXED32 ;
317
- default :
318
- // Unknown fields just return the reported wire type
319
- return $ default ;
320
- }
313
+ static $ map = array (
314
+ Protobuf::TYPE_INT32 => self ::WIRE_VARINT ,
315
+ Protobuf::TYPE_INT64 => self ::WIRE_VARINT ,
316
+ Protobuf::TYPE_UINT32 => self ::WIRE_VARINT ,
317
+ Protobuf::TYPE_UINT64 => self ::WIRE_VARINT ,
318
+ Protobuf::TYPE_SINT32 => self ::WIRE_VARINT ,
319
+ Protobuf::TYPE_SINT64 => self ::WIRE_VARINT ,
320
+ Protobuf::TYPE_BOOL => self ::WIRE_VARINT ,
321
+ Protobuf::TYPE_ENUM => self ::WIRE_VARINT ,
322
+ Protobuf::TYPE_FIXED64 => self ::WIRE_FIXED64 ,
323
+ Protobuf::TYPE_SFIXED64 => self ::WIRE_FIXED64 ,
324
+ Protobuf::TYPE_DOUBLE => self ::WIRE_FIXED64 ,
325
+ Protobuf::TYPE_STRING => self ::WIRE_LENGTH ,
326
+ Protobuf::TYPE_BYTES => self ::WIRE_LENGTH ,
327
+ Protobuf::TYPE_MESSAGE => self ::WIRE_LENGTH ,
328
+ Protobuf::TYPE_FIXED32 => self ::WIRE_FIXED32 ,
329
+ Protobuf::TYPE_SFIXED32 => self ::WIRE_FIXED32 ,
330
+ Protobuf::TYPE_FLOAT => self ::WIRE_FIXED32
331
+ );
332
+
333
+ // Unknown types just return the reported wire type
334
+ return isset ($ map [$ type ]) ? $ map [$ type ] : $ default ;
321
335
}
322
336
323
337
protected function decodeSimpleType ($ reader , $ type , $ wireType )
@@ -327,6 +341,7 @@ protected function decodeSimpleType($reader, $type, $wireType)
327
341
case Protobuf::TYPE_UINT64 :
328
342
case Protobuf::TYPE_INT32 :
329
343
case Protobuf::TYPE_UINT32 :
344
+ case Protobuf::TYPE_ENUM :
330
345
return $ reader ->varint ();
331
346
332
347
case Protobuf::TYPE_SINT32 : // ZigZag
@@ -351,19 +366,12 @@ protected function decodeSimpleType($reader, $type, $wireType)
351
366
return (bool )$ reader ->varint ();
352
367
353
368
case Protobuf::TYPE_STRING :
354
- $ length = $ reader ->varint ();
355
- return $ reader ->read ($ length );
356
-
357
- case Protobuf::TYPE_MESSAGE :
358
- // Messages are not supported in this method
359
- return null ;
360
-
361
369
case Protobuf::TYPE_BYTES :
362
370
$ length = $ reader ->varint ();
363
371
return $ reader ->read ($ length );
364
372
365
- case Protobuf::TYPE_ENUM :
366
- return $ reader -> varint ( );
373
+ case Protobuf::TYPE_MESSAGE :
374
+ throw new \ RuntimeException ( ' Nested messages are not supported in this method ' );
367
375
368
376
default :
369
377
// Unknown type, follow wire type rules
0 commit comments