Exemplo n.º 1
0
 protected function decodeMessage(Protobuf\Message $message, $data)
 {
     // Get message descriptor
     $descriptor = Protobuf::getRegistry()->getDescriptor($message);
     foreach ($data as $key => $v) {
         // Get the field by tag number or name
         $field = $this->useTagNumber ? $descriptor->getField($key) : $descriptor->getFieldByName($key);
         // Unknown field found
         if (!$field) {
             $unknown = new PhpArray\Unknown($key, gettype($v), $v);
             $message->addUnknown($unknown);
             continue;
         }
         if ($field->isRepeated()) {
             // Make sure the value is an array of values
             $v = is_array($v) && is_int(key($v)) ? $v : array($v);
             foreach ($v as $k => $vv) {
                 $v[$k] = $this->filterValue($vv, $field);
             }
         } else {
             $v = $this->filterValue($v, $field);
         }
         $message->_set($field->getNumber(), $v);
     }
     return $message;
 }
Exemplo n.º 2
0
 protected function decodeMessage(Protobuf\Message $message, $data)
 {
     // Get message descriptor
     $descriptor = Protobuf::getRegistry()->getDescriptor($message);
     // Split the index in UTF8 characters
     preg_match_all('/./u', $data[0], $chars);
     $chars = $chars[0];
     for ($i = 1; $i < count($data); $i++) {
         $k = $this->c2i($chars[$i - 1]) - 48;
         $v = $data[$i];
         $field = $descriptor->getField($k);
         if (NULL === $field) {
             // Unknown
             $unknown = new PhpArray\Unknown($k, gettype($v), $v);
             $message->addUnknown($unknown);
             continue;
         }
         if ($field->getType() === Protobuf::TYPE_MESSAGE) {
             $nested = $field->getReference();
             if ($field->isRepeated()) {
                 foreach ($v as $vv) {
                     $obj = $this->decodeMessage(new $nested(), $vv);
                     $message->_add($k, $obj);
                 }
             } else {
                 $obj = $this->decodeMessage(new $nested(), $v);
                 $message->_set($k, $obj);
             }
         } else {
             $message->_set($k, $v);
         }
     }
     return $message;
 }
Exemplo n.º 3
0
 protected function encodeMessage(Protobuf\Message $message, $level = 0)
 {
     $descriptor = Protobuf::getRegistry()->getDescriptor($message);
     $indent = str_repeat('  ', $level);
     $data = '';
     foreach ($descriptor->getFields() as $tag => $field) {
         $empty = !$message->_has($tag);
         if ($field->isRequired() && $empty) {
             throw new \UnexpectedValueException('Message ' . get_class($message) . '\'s field tag ' . $tag . '(' . $field->getName() . ') is required but has no value');
         }
         if ($empty) {
             continue;
         }
         $name = $field->getName();
         $value = $message->_get($tag);
         if ($field->isRepeated()) {
             foreach ($value as $val) {
                 // Skip nullified repeated values
                 if (NULL === $val) {
                     continue;
                 } else {
                     if ($field->getType() !== Protobuf::TYPE_MESSAGE) {
                         $data .= $indent . $name . ': ' . json_encode($val) . "\n";
                     } else {
                         $data .= $indent . $name . " {\n";
                         $data .= $this->encodeMessage($val, $level + 1);
                         $data .= $indent . "}\n";
                     }
                 }
             }
         } else {
             if ($field->getType() === Protobuf::TYPE_MESSAGE) {
                 $data .= $indent . $name . " {\n";
                 $data .= $this->encodeMessage($value, $level + 1);
                 $data .= $indent . "}\n";
             } else {
                 $data .= $indent . $name . ': ' . json_encode($value) . "\n";
             }
         }
     }
     return $data;
 }
Exemplo n.º 4
0
 /**
  * Serialize the current object data
  *
  * @param CodecInterface|null $codec
  * @return string
  */
 public function serialize(Protobuf\CodecInterface $codec = null)
 {
     $codec = Protobuf::getCodec($codec);
     return $codec->encode($this);
 }
Exemplo n.º 5
0
 /**
  * @param \StudyDrSlump\Protobuf\Codec\Binary\Reader $reader
  * @param \StudyDrSlump\Protobuf\Message             $message
  * @param int                                   $length 
  * @return \StudyDrSlump\Protobuf\Message
  */
 protected function decodeMessage($reader, \StudyDrSlump\Protobuf\Message $message, $length = NULL)
 {
     /** @var $message \StudyDrSlump\Protobuf\Message */
     /** @var $descriptor \StudyDrSlump\Protobuf\Descriptor */
     // Get message descriptor
     $descriptor = Protobuf::getRegistry()->getDescriptor($message);
     // Cache locally the message fields
     $fields = $descriptor->getFields();
     // Calculate the maximum offset if we have defined a length
     $limit = !is_null($length) ? $reader->pos() + $length : NULL;
     $pos = $reader->pos();
     // Keep reading until we reach the end or the limit
     while ($limit === NULL && !$reader->eof() || $limit !== NULL && $reader->pos() < $limit) {
         // Get initial varint with tag number and wire type
         $key = $reader->varint();
         if ($reader->eof()) {
             break;
         }
         $wire = $key & 0x7;
         $tag = $key >> 3;
         // Find the matching field for the tag number
         if (!isset($fields[$tag])) {
             $data = $this->decodeUnknown($reader, $wire);
             $unknown = new Binary\Unknown($tag, $wire, $data);
             $message->addUnknown($unknown);
             continue;
         }
         $field = $fields[$tag];
         $type = $field->getType();
         // Check if we are dealing with a packed stream, we cannot rely on the packed
         // flag of the message since we cannot be certain if the creator of the message
         // was using it.
         if ($wire === self::WIRE_LENGTH && $field->isRepeated() && self::$PACKABLE[$type]) {
             $len = $reader->varint();
             $until = $reader->pos() + $len;
             $wire = $this->getWireType($type);
             while ($reader->pos() < $until) {
                 $item = $this->decodeSimpleType($reader, $type, $wire);
                 $message->_add($tag, $item);
             }
         } else {
             // Assert wire and type match
             $this->assertWireType($wire, $type);
             // Check if it's a sub-message
             if ($type === Protobuf::TYPE_MESSAGE) {
                 $submessage = $field->getReference();
                 $submessage = new $submessage();
                 $len = $reader->varint();
                 $value = $this->decodeMessage($reader, $submessage, $len);
             } else {
                 $value = $this->decodeSimpleType($reader, $type, $wire);
             }
             // Support non-packed repeated fields
             if ($field->isRepeated()) {
                 $message->_add($tag, $value);
             } else {
                 $message->_set($tag, $value);
             }
         }
     }
     return $message;
 }