Exemplo n.º 1
0
 protected function decodeMessage(Protobuf\MessageInterface $message, $data)
 {
     // Get message descriptor
     $descriptor = Protobuf\Protobuf::getRegistry()->getDescriptor($message);
     $isLazy = $this->getOption('lazy');
     $useTagNumber = $this->getOption('tags');
     foreach ($data as $key => $v) {
         // Get the field by tag number or name
         $field = $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) && (empty($v) || is_int(key($v))) ? $v : array($v);
             // If we are packing lazy values use a LazyRepeat as container
             if ($isLazy && $field->getType() === Protobuf\Protobuf::TYPE_MESSAGE) {
                 $v = new Protobuf\LazyRepeat($v);
                 $v->codec = $this;
                 $v->descriptor = $field;
             } else {
                 foreach ($v as $k => $vv) {
                     $v[$k] = $this->filterValue($vv, $field);
                 }
             }
         } else {
             $v = $this->filterValue($v, $field);
         }
         $message->initValue($field->getName(), $v);
     }
     return $message;
 }
Exemplo n.º 2
0
 protected function decodeMessage(Protobuf\Message $message, $data)
 {
     // Get message descriptor
     $descriptor = Protobuf\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;
         }
         $name = $field->getName();
         if ($field->getType() === Protobuf\Protobuf::TYPE_MESSAGE) {
             $nested = $field->getReference();
             if ($field->isRepeated()) {
                 foreach ($v as $kk => $vv) {
                     $v[$kk] = $this->decodeMessage(new $nested(), $vv);
                 }
                 $message->initValue($name, $v);
             } else {
                 $obj = $this->decodeMessage(new $nested(), $v);
                 $message->initValue($name, $obj);
             }
         } else {
             $message->initValue($name, $v);
         }
     }
     return $message;
 }
Exemplo n.º 3
0
 public function testSendMessage()
 {
     $message = new RpbPutReq();
     $reqCode = RiakMessageCodes::PUT_REQ;
     $respCode = RiakMessageCodes::PUT_RESP;
     $respBody = Protobuf::encode(new RpbPutResp());
     $stream = $this->getMock('Riak\\Client\\Core\\Transport\\Proto\\ProtoStream', [], [], '', false);
     $this->connection->expects($this->once())->method('send')->willReturn($stream);
     $this->connection->expects($this->once())->method('receive')->willReturn([$respCode, $respBody])->with($this->equalTo($stream));
     $this->assertInstanceOf('Riak\\Client\\ProtoBuf\\RpbPutResp', $this->instance->send($message, $reqCode, $respCode));
 }
Exemplo n.º 4
0
 protected function encodeMessage(Protobuf\MessageInterface $message, $level = 0)
 {
     $descriptor = Protobuf\Protobuf::getRegistry()->getDescriptor($message);
     $strict = $this->getOption('strict');
     $indent = str_repeat('  ', $level);
     $data = '';
     foreach ($descriptor->getFields() as $tag => $field) {
         $empty = !isset($message[$tag]);
         if ($strict && $empty && $field->isRequired() && !$field->hasDefault()) {
             throw new \UnexpectedValueException('Message ' . $descriptor->getName() . '\'s field tag ' . $tag . '(' . $field->getName() . ') is required but has no value');
         }
         // skip not set values
         if ($empty) {
             continue;
         }
         $value = $message[$tag];
         // don't send nulls or defaults over the wire
         if (NULL === $value || $field->hasDefault() && $field->getDefault() === $value) {
             continue;
         }
         $name = $field->getName();
         if ($field->isRepeated()) {
             foreach ($value as $val) {
                 // Skip nullified repeated values
                 if (NULL === $val) {
                     continue;
                 } else {
                     if ($field->getType() !== Protobuf\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\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.º 5
0
 /**
  * @param \DrSlump\Protobuf\MessageInterface    $message
  * @param string                                $data
  * @return \DrSlump\Protobuf\MessageInterface
  */
 protected function _decodeMessage(\DrSlump\Protobuf\MessageInterface $message, $data)
 {
     $descriptor = Protobuf\Protobuf::getRegistry()->getDescriptor($message);
     $name = $descriptor->getName();
     $res = $this->_describe($descriptor);
     $ret = \protobuf_decode($res, $data);
     // In non lazy mode we just pass the returned array thru the PhpArray codec
     if (!$this->getOption('lazy')) {
         if (!$this->_codec) {
             $this->_codec = new PhpArray();
             $this->_codec->setOption('lazy', false);
         }
         return $this->_codec->decode($message, $ret);
     }
     // In lazy mode we need to walk thru the fields to convert message strings
     // to LazyValue / LazyRepeat
     foreach ($descriptor->getFields() as $field) {
         $name = $field->getName();
         if (!isset($ret[$name])) {
             continue;
         }
         $value = $ret[$name];
         if ($field->getType() === Protobuf\Protobuf::TYPE_MESSAGE) {
             if ($field->getRule() === Protobuf\Protobuf::RULE_REPEATED) {
                 $value = new Protobuf\LazyRepeat($value);
                 $value->codec = $this;
                 $value->descriptor = $field;
             } else {
                 $lazy = new Protobuf\LazyValue();
                 $lazy->codec = $this;
                 $lazy->descriptor = $field;
                 $lazy->value = $value;
                 $value = $lazy;
             }
         }
         $message->initValue($name, $value);
     }
     return $message;
 }
Exemplo n.º 6
0
 protected function encodeMessage(Protobuf\Message $message)
 {
     $writer = new NativeWriter();
     // Get message descriptor
     $descriptor = Protobuf\Protobuf::getRegistry()->getDescriptor($message);
     $strict = $this->getOption('strict');
     foreach ($descriptor->getFields() as $tag => $field) {
         $empty = !isset($message[$tag]);
         if ($strict && $empty && $field->isRequired() && !$field->hasDefault()) {
             throw new \UnexpectedValueException('Message ' . get_class($message) . '\'s field tag ' . $tag . '(' . $field->getName() . ') is required but has no value');
         }
         // skip not set values
         if ($empty) {
             continue;
         }
         $value = $message[$tag];
         // don't send nulls or defaults over the wire
         if (NULL === $value || $field->hasDefault() && $field->getDefault() === $value) {
             continue;
         }
         $type = $field->getType();
         $wire = $field->isPacked() ? self::WIRE_LENGTH : $this->getWireType($type, null);
         // Compute key with tag number and wire type
         $key = $tag << 3 | $wire;
         if ($field->isRepeated()) {
             // Packed fields are encoded as a length-delimited stream containing
             // the concatenated encoding of each value.
             if ($field->isPacked() && !empty($value)) {
                 $subwriter = new NativeWriter();
                 foreach ($value as $val) {
                     $this->encodeSimpleType($subwriter, $type, $val);
                 }
                 $data = $subwriter->getBytes();
                 $writer->varint($key);
                 $writer->varint(mb_strlen($data, '8bit'));
                 $writer->write($data);
             } else {
                 foreach ($value as $val) {
                     // Skip nullified repeated values
                     if (NULL === $val) {
                         continue;
                     } else {
                         if ($type !== Protobuf\Protobuf::TYPE_MESSAGE) {
                             $writer->varint($key);
                             $this->encodeSimpleType($writer, $type, $val);
                         } else {
                             $writer->varint($key);
                             $data = $this->encodeMessage($val);
                             $writer->varint(mb_strlen($data, '8bit'));
                             $writer->write($data);
                         }
                     }
                 }
             }
         } else {
             if ($type !== Protobuf\Protobuf::TYPE_MESSAGE) {
                 $writer->varint($key);
                 $this->encodeSimpleType($writer, $type, $value);
             } else {
                 $writer->varint($key);
                 $data = $this->encodeMessage($value);
                 $writer->varint(mb_strlen($data, '8bit'));
                 $writer->write($data);
             }
         }
     }
     return $writer->getBytes();
 }
Exemplo n.º 7
0
 function testMultiCodecMessageWithRepeatedFields()
 {
     $jsonCodec = new Codec\Json();
     $repeated = Protobuf\Protobuf::decode(Repeated::class, $this->bin_repeated_nested);
     $json = $jsonCodec->encode($repeated);
     $repeated = $jsonCodec->decode(new Repeated(), $json);
     $bin = Protobuf\Protobuf::encode($repeated);
     $this->assertEquals($bin, $this->bin_repeated_nested);
 }
Exemplo n.º 8
0
 /**
  * @param \DrSlump\Protobuf\Message $message
  * @param integer                   $code
  *
  * @return string
  */
 private function encodeMessage(Message $message, $code)
 {
     return $this->connection->encode(Protobuf::encode($message), $code);
 }
Exemplo n.º 9
0
require dirname(__FILE__) . '/../conf/db.php';
require dirname(__FILE__) . '/../vendor/autoload.php';
require dirname(__FILE__) . '/../proto/ping.php';
require dirname(__FILE__) . '/../proto/pong.php';
$receive_len = 30;
$udp_socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
socket_bind($udp_socket, '0.0.0.0', 42001);
$query_server_log = $db->prepare("\nSELECT\n    server_log.server_id,\n    server_log.nonce,\n    server.session\nFROM\n    server_log\nJOIN\n    server\n        ON\n            server.id = server_log.server_id\nWHERE\n    server_log.id = ?\nAND\n    server_log.status = 'new'\n");
$query_update_server_log = $db->prepare("\nUPDATE\n    server_log\nSET\n    status = 'online',\n    nonce = NULL,\n    latency = 1000 * (NOW(6) - created),\n    players = ?\nWHERE\n    id = ?\n");
$query_update_server = $db->prepare("\nUPDATE\n    server\nSET\n    status = 'online',\n    latency = (SELECT latency FROM server_log WHERE server_log.id = ?),\n    players = ?,\n    updated = NOW()\nWHERE\n    id = ?\n");
print 'pongd started' . PHP_EOL;
while (socket_recvfrom($udp_socket, $buf, $receive_len, 0, $ip, $port)) {
    print 'received ' . $receive_len . ' bytes from ' . $ip . PHP_EOL;
    if ('pong' === substr($buf, 0, 4)) {
        print 'looks like a pong' . PHP_EOL;
        $pong = \DrSlump\Protobuf\Protobuf::decode('Pong', substr($buf, 4));
        $query_server_log->execute(array($pong->server_log_id));
        if ($server_log = $query_server_log->fetch()) {
            print 'found server_log_id' . PHP_EOL;
            if ($pong->key === hash('sha1', $server_log->session . $server_log->nonce, true)) {
                print 'sha1 validated' . PHP_EOL;
                $query_update_server_log->execute(array($pong->player_count, $pong->server_log_id));
                $query_update_server->execute(array($pong->server_log_id, $pong->player_count, $server_log->server_id));
                print 'database updated' . PHP_EOL;
            } else {
                print 'invalid sha1!' . PHP_EOL;
            }
        } else {
            print 'invalid server_log_id!' . PHP_EOL;
        }
    }