diff --git a/src/Providers/ReaderProvider.php b/src/Providers/ReaderProvider.php new file mode 100644 index 0000000..d89dd70 --- /dev/null +++ b/src/Providers/ReaderProvider.php @@ -0,0 +1,43 @@ +. + +namespace Throttr\SDK\Providers; + +use Throttr\SDK\Requests\BaseRequest; + +class ReaderProvider +{ + /** + * Read integers + * + * @param string $data + * @param array $columns + * @param int $offset + * @return array + */ + public static function readIntegers(string $data, array $columns, int &$offset): array + { + $result = []; + + foreach ($columns as $column => $size) { + $result[$column] = unpack(BaseRequest::pack($size), substr($data, $offset, $size->value))[1]; + $offset += $size->value; + } + + return $result; + } +} diff --git a/src/Responses/ChannelResponse.php b/src/Responses/ChannelResponse.php index 52ef987..0ac43ee 100644 --- a/src/Responses/ChannelResponse.php +++ b/src/Responses/ChannelResponse.php @@ -20,6 +20,7 @@ use Throttr\SDK\Enum\KeyType; use Throttr\SDK\Enum\TTLType; use Throttr\SDK\Enum\ValueSize; +use Throttr\SDK\Providers\ReaderProvider; use Throttr\SDK\Requests\BaseRequest; /** @@ -47,71 +48,40 @@ public function __construct(public string $data, public bool $status, public arr */ public static function fromBytes(string $data, ValueSize $size): ChannelResponse|null { - $valueSize = $size->value; $offset = 0; - // Less than 1 byte? not enough for status. - if (strlen($data) < 1) { - return null; - } - $status = ord($data[$offset]) === 1; $offset++; if ($status) { - // Less than 1 + N bytes? not enough for number of subscribers. - if (strlen($data) < 1 + 8) { + // Less than 8 bytes? not enough for status and number of subscribers. + if (strlen($data) < $offset + 8) { return null; } $subscribers = unpack(BaseRequest::pack(ValueSize::UINT64), substr($data, $offset, ValueSize::UINT64->value))[1]; $offset += ValueSize::UINT64->value; - if ($subscribers === 0) { - return new ChannelResponse($data, true, []); - } - $subscribers_container = []; - for ($i = 0; $i < $subscribers; ++$i) { - // Less than offset + 16 bytes? not enough for connection id. - if (strlen($data) < $offset + 16) { - return null; - } + if (strlen($data) < $offset + (16 + ValueSize::UINT64->value * 3) * $subscribers) { + return null; + } + for ($i = 0; $i < $subscribers; ++$i) { $id = substr($data, $offset, 16); $offset += 16; - // Less than offset + 8 bytes? not enough for subscribed at. - if (strlen($data) < $offset + ValueSize::UINT64->value) { - return null; - } - - $subscribed_at = unpack(BaseRequest::pack(ValueSize::UINT64), substr($data, $offset, ValueSize::UINT64->value))[1]; - $offset += ValueSize::UINT64->value; - - // Less than offset + 8 bytes? not enough for read bytes. - if (strlen($data) < $offset + ValueSize::UINT64->value) { - return null; - } - - $read_bytes = unpack(BaseRequest::pack(ValueSize::UINT64), substr($data, $offset, ValueSize::UINT64->value))[1]; - $offset += ValueSize::UINT64->value; - - // Less than offset + 8 bytes? not enough for write bytes. - if (strlen($data) < $offset + ValueSize::UINT64->value) { - return null; - } - - $write_bytes = unpack(BaseRequest::pack(ValueSize::UINT64), substr($data, $offset, ValueSize::UINT64->value))[1]; - $offset += ValueSize::UINT64->value; + $values = ReaderProvider::readIntegers($data, [ + "subscribed_at" => ValueSize::UINT64, + "read_bytes" => ValueSize::UINT64, + "write_bytes" => ValueSize::UINT64, + ], $offset); - $subscribers_container[] = [ - "id" => bin2hex($id), - "subscribed_at" => $subscribed_at, - "read_bytes" => $read_bytes, - "write_bytes" => $write_bytes, - ]; + $subscribers_container[] = array_merge( + ["id" => bin2hex($id)], + $values + ); } return new ChannelResponse($data, true, $subscribers_container); diff --git a/src/Responses/ChannelsResponse.php b/src/Responses/ChannelsResponse.php index 343995d..9eb6e7d 100644 --- a/src/Responses/ChannelsResponse.php +++ b/src/Responses/ChannelsResponse.php @@ -17,9 +17,8 @@ namespace Throttr\SDK\Responses; -use Throttr\SDK\Enum\KeyType; -use Throttr\SDK\Enum\TTLType; use Throttr\SDK\Enum\ValueSize; +use Throttr\SDK\Providers\ReaderProvider; use Throttr\SDK\Requests\BaseRequest; /** @@ -79,7 +78,6 @@ public static function fromBytes(string $data, ValueSize $size): ChannelsRespons return null; } - $fragment = unpack(BaseRequest::pack(ValueSize::UINT64), substr($data, $offset, ValueSize::UINT64->value))[1]; $offset += ValueSize::UINT64->value; // Less than offset + 8 bytes? not enough for fragment keys count. @@ -92,46 +90,18 @@ public static function fromBytes(string $data, ValueSize $size): ChannelsRespons $channels_in_fragment = []; + if (strlen($data) < $offset + (ValueSize::UINT8->value + ValueSize::UINT64->value * 3) * $number_of_channels) { + return null; + } + // Per key in fragment for ($e = 0; $e < $number_of_channels; ++$e) { - // Less than offset + 1 byte? not enough for key size. - if (strlen($data) < $offset + ValueSize::UINT8->value) { - return null; - } - - $channel_size = unpack(BaseRequest::pack(ValueSize::UINT8), substr($data, $offset, ValueSize::UINT8->value))[1]; - $offset += ValueSize::UINT8->value; - - // Less than offset + 8 bytes? not enough for read bytes. - if (strlen($data) < $offset + ValueSize::UINT64->value) { - return null; - } - - $read_bytes = unpack(BaseRequest::pack(ValueSize::UINT64), substr($data, $offset, ValueSize::UINT64->value))[1]; - $offset += ValueSize::UINT64->value; - - // Less than offset + 8 bytes? not enough for write bytes. - if (strlen($data) < $offset + ValueSize::UINT64->value) { - return null; - } - - $write_bytes = unpack(BaseRequest::pack(ValueSize::UINT64), substr($data, $offset, ValueSize::UINT64->value))[1]; - $offset += ValueSize::UINT64->value; - - // Less than offset + 8 bytes? not enough for subscriptions. - if (strlen($data) < $offset + ValueSize::UINT64->value) { - return null; - } - - $subscriptions = unpack(BaseRequest::pack(ValueSize::UINT64), substr($data, $offset, ValueSize::UINT64->value))[1]; - $offset += ValueSize::UINT64->value; - - $channels_in_fragment[] = [ - "size" => $channel_size, - "read_bytes" => $read_bytes, - "write_bytes" => $write_bytes, - "subscriptions" => $subscriptions, - ]; + $channels_in_fragment[] = ReaderProvider::readIntegers($data, [ + "size" => ValueSize::UINT8, + "read_bytes" => ValueSize::UINT64, + "write_bytes" => ValueSize::UINT64, + "subscriptions" => ValueSize::UINT64, + ], $offset); } $total = array_sum(array_column($channels_in_fragment, 'size')); diff --git a/src/Responses/ConnectionResponse.php b/src/Responses/ConnectionResponse.php index f069f41..3beecf2 100644 --- a/src/Responses/ConnectionResponse.php +++ b/src/Responses/ConnectionResponse.php @@ -23,6 +23,7 @@ use Throttr\SDK\Enum\KeyType; use Throttr\SDK\Enum\TTLType; use Throttr\SDK\Enum\ValueSize; +use Throttr\SDK\Providers\ReaderProvider; use Throttr\SDK\Requests\BaseRequest; /** @@ -42,24 +43,24 @@ public function __construct(public string $data, public bool $status, public arr } public static array $types = [ - "INSERT", - "SET", - "QUERY", - "GET", - "UPDATE", - "PURGE", - "LIST", - "INFO", - "STAT", - "STATS", - "PUBLISH", - "SUBSCRIBE", - "UNSUBSCRIBE", - "CONNECTIONS", - "CONNECTION", - "CHANNELS", - "CHANNEL", - "WHOAMI" + "INSERT" => ValueSize::UINT64, + "SET" => ValueSize::UINT64, + "QUERY" => ValueSize::UINT64, + "GET" => ValueSize::UINT64, + "UPDATE" => ValueSize::UINT64, + "PURGE" => ValueSize::UINT64, + "LIST" => ValueSize::UINT64, + "INFO" => ValueSize::UINT64, + "STAT" => ValueSize::UINT64, + "STATS" => ValueSize::UINT64, + "PUBLISH" => ValueSize::UINT64, + "SUBSCRIBE" => ValueSize::UINT64, + "UNSUBSCRIBE" => ValueSize::UINT64, + "CONNECTIONS" => ValueSize::UINT64, + "CONNECTION" => ValueSize::UINT64, + "CHANNELS" => ValueSize::UINT64, + "CHANNEL" => ValueSize::UINT64, + "WHOAMI" => ValueSize::UINT64, ]; /** @@ -73,11 +74,6 @@ public static function fromBytes(string $data, ValueSize $size): ConnectionRespo { $offset = 0; - // Less than 1 byte? not enough for status. - if (strlen($data) < 1) { - return null; - } - $status = ord($data[$offset]) === 1; $offset++; @@ -122,96 +118,36 @@ public static function fromBytes(string $data, ValueSize $size): ConnectionRespo $ip = substr($data, $offset, 16); $offset += 16; - // Less than offset + 2 bytes? not enough for port. - if (strlen($data) < $offset + ValueSize::UINT16->value) { - return null; - } - - $port = unpack(BaseRequest::pack(ValueSize::UINT16), substr($data, $offset, ValueSize::UINT16->value))[1]; - $offset += ValueSize::UINT16->value; - - // Less than offset + 8 bytes? not enough for connected at. - if (strlen($data) < $offset + ValueSize::UINT64->value) { - return null; - } - - $connected_at = unpack(BaseRequest::pack(ValueSize::UINT64), substr($data, $offset, ValueSize::UINT64->value))[1]; - $offset += ValueSize::UINT64->value; - - // Less than offset + 8 bytes? not enough for read bytes. - if (strlen($data) < $offset + ValueSize::UINT64->value) { - return null; - } - - $ready_bytes = unpack(BaseRequest::pack(ValueSize::UINT64), substr($data, $offset, ValueSize::UINT64->value))[1]; - $offset += ValueSize::UINT64->value; - - // Less than offset + 8 bytes? not enough for write bytes. - if (strlen($data) < $offset + ValueSize::UINT64->value) { + // Less than offset + 2 + 8 * 7 bytes? not enough for attributes. + if (strlen($data) < $offset + ValueSize::UINT16->value + ValueSize::UINT64->value * 7) { return null; } - $write_bytes = unpack(BaseRequest::pack(ValueSize::UINT64), substr($data, $offset, ValueSize::UINT64->value))[1]; - $offset += ValueSize::UINT64->value; - - // Less than offset + 8 bytes? not enough for published bytes. - if (strlen($data) < $offset + ValueSize::UINT64->value) { - return null; - } - - $published_bytes = unpack(BaseRequest::pack(ValueSize::UINT64), substr($data, $offset, ValueSize::UINT64->value))[1]; - $offset += ValueSize::UINT64->value; - - // Less than offset + 8 bytes? not enough for received bytes. - if (strlen($data) < $offset + ValueSize::UINT64->value) { - return null; - } - - $received_bytes = unpack(BaseRequest::pack(ValueSize::UINT64), substr($data, $offset, ValueSize::UINT64->value))[1]; - $offset += ValueSize::UINT64->value; - - // Less than offset + 8 bytes? not enough for allocated bytes. - if (strlen($data) < $offset + ValueSize::UINT64->value) { + $attributes = ReaderProvider::readIntegers($data, [ + "port" => ValueSize::UINT16, + "connected_at" => ValueSize::UINT64, + "read_bytes" => ValueSize::UINT64, + "write_bytes" => ValueSize::UINT64, + "published_bytes" => ValueSize::UINT64, + "received_bytes" => ValueSize::UINT64, + "allocated_bytes" => ValueSize::UINT64, + "consumed_bytes" => ValueSize::UINT64, + ], $offset); + + if (strlen($data) < $offset + ValueSize::UINT64->value * count(static::$types)) { return null; } - $allocated_bytes = unpack(BaseRequest::pack(ValueSize::UINT64), substr($data, $offset, ValueSize::UINT64->value))[1]; - $offset += ValueSize::UINT64->value; - - // Less than offset + 8 bytes? not enough for consumed bytes. - if (strlen($data) < $offset + ValueSize::UINT64->value) { - return null; - } - - $consumed_bytes = unpack(BaseRequest::pack(ValueSize::UINT64), substr($data, $offset, ValueSize::UINT64->value))[1]; - $offset += ValueSize::UINT64->value; - - $requests = []; - foreach (static::$types as $request_type) { - // Less than offset + 8 bytes? not enough for requests metric. - if (strlen($data) < $offset + ValueSize::UINT64->value) { - return null; - } - $requests[$request_type] = unpack(BaseRequest::pack(ValueSize::UINT64), substr($data, $offset, ValueSize::UINT64->value))[1]; - $offset += ValueSize::UINT64->value; - } + $requests = ReaderProvider::readIntegers($data, static::$types, $offset); - return new ConnectionResponse($data, true, [ + return new ConnectionResponse($data, true, array_merge([ "id" => bin2hex($id), "type" => $type, "kind" => $kind, "ip_version" => $ip_version, "ip" => $ip, - "port" => $port, - "connected_at" => $connected_at, - "read_bytes" => $ready_bytes, - "write_bytes" => $write_bytes, - "published_bytes" => $published_bytes, - "received_bytes" => $received_bytes, - "allocated_bytes" => $allocated_bytes, - "consumed_bytes" => $consumed_bytes, "requests" => $requests, - ]); + ], $attributes)); } return new ConnectionResponse($data, false, []); diff --git a/src/Responses/ConnectionsResponse.php b/src/Responses/ConnectionsResponse.php index 803ccce..72c0300 100644 --- a/src/Responses/ConnectionsResponse.php +++ b/src/Responses/ConnectionsResponse.php @@ -23,6 +23,7 @@ use Throttr\SDK\Enum\KeyType; use Throttr\SDK\Enum\TTLType; use Throttr\SDK\Enum\ValueSize; +use Throttr\SDK\Providers\ReaderProvider; use Throttr\SDK\Requests\BaseRequest; /** @@ -42,24 +43,24 @@ public function __construct(public string $data, public bool $status, public arr } public static array $types = [ - "INSERT", - "SET", - "QUERY", - "GET", - "UPDATE", - "PURGE", - "LIST", - "INFO", - "STAT", - "STATS", - "PUBLISH", - "SUBSCRIBE", - "UNSUBSCRIBE", - "CONNECTION", - "CONNECTIONS", - "CHANNELS", - "CHANNEL", - "WHOAMI" + "INSERT" => ValueSize::UINT64, + "SET" => ValueSize::UINT64, + "QUERY" => ValueSize::UINT64, + "GET" => ValueSize::UINT64, + "UPDATE" => ValueSize::UINT64, + "PURGE" => ValueSize::UINT64, + "LIST" => ValueSize::UINT64, + "INFO" => ValueSize::UINT64, + "STAT" => ValueSize::UINT64, + "STATS" => ValueSize::UINT64, + "PUBLISH" => ValueSize::UINT64, + "SUBSCRIBE" => ValueSize::UINT64, + "UNSUBSCRIBE" => ValueSize::UINT64, + "CONNECTION" => ValueSize::UINT64, + "CONNECTIONS" => ValueSize::UINT64, + "CHANNELS" => ValueSize::UINT64, + "CHANNEL" => ValueSize::UINT64, + "WHOAMI" => ValueSize::UINT64 ]; /** @@ -102,7 +103,6 @@ public static function fromBytes(string $data, ValueSize $size): ConnectionsResp return null; } - $fragment = unpack(BaseRequest::pack(ValueSize::UINT64), substr($data, $offset, ValueSize::UINT64->value))[1]; $offset += ValueSize::UINT64->value; // Less than offset + 8 bytes? not enough for fragment keys count. @@ -113,130 +113,60 @@ public static function fromBytes(string $data, ValueSize $size): ConnectionsResp $number_of_connections = unpack(BaseRequest::pack(ValueSize::UINT64), substr($data, $offset, ValueSize::UINT64->value))[1]; $offset += ValueSize::UINT64->value; + $expected_fragment_size = ( + 16 + // id + ValueSize::UINT8->value * 3 + // type, kind and ip version + 16 + // ip + ValueSize::UINT16->value + // port + ( + ValueSize::UINT64->value * ( + 6 + // connected_at, read_bytes, write_bytes, published_bytes, received_bytes, allocated_bytes + count(static::$types) // per request type metrics + ) + ) + ) * $number_of_connections; + + if (strlen($data) < $offset + $expected_fragment_size) { + return null; + } + // Per connection in fragment for ($e = 0; $e < $number_of_connections; ++$e) { - - // Less than offset + 16 bytes? not enough for uuid. - if (strlen($data) < $offset + 16) { - return null; - } - $id = substr($data, $offset, 16); $offset += 16; - // Less than offset + 1 byte? not enough for type. - if (strlen($data) < $offset + ValueSize::UINT8->value) { - return null; - } - $type = ConnectionType::from(unpack(BaseRequest::pack(ValueSize::UINT8), substr($data, $offset, ValueSize::UINT8->value))[1]); $offset += ValueSize::UINT8->value; - // Less than offset + 1 byte? not enough for kind. - if (strlen($data) < $offset + ValueSize::UINT8->value) { - return null; - } - $kind = ConnectionKind::from(unpack(BaseRequest::pack(ValueSize::UINT8), substr($data, $offset, ValueSize::UINT8->value))[1]); $offset += ValueSize::UINT8->value; - // Less than offset + 1 byte? not enough for ip version. - if (strlen($data) < $offset + ValueSize::UINT8->value) { - return null; - } - $ip_version = IpVersion::from(unpack(BaseRequest::pack(ValueSize::UINT8), substr($data, $offset, ValueSize::UINT8->value))[1]); $offset += ValueSize::UINT8->value; - // Less than offset + 16 bytes? not enough for ip. - if (strlen($data) < $offset + 16) { - return null; - } - $ip = substr($data, $offset, 16); $offset += 16; - // Less than offset + 2 bytes? not enough for port. - if (strlen($data) < $offset + ValueSize::UINT16->value) { - return null; - } - - $port = unpack(BaseRequest::pack(ValueSize::UINT16), substr($data, $offset, ValueSize::UINT16->value))[1]; - $offset += ValueSize::UINT16->value; - - // Less than offset + 8 bytes? not enough for connected at. - if (strlen($data) < $offset + ValueSize::UINT64->value) { - return null; - } - - $connected_at = unpack(BaseRequest::pack(ValueSize::UINT64), substr($data, $offset, ValueSize::UINT64->value))[1]; - $offset += ValueSize::UINT64->value; - - // Less than offset + 8 bytes? not enough for read bytes. - if (strlen($data) < $offset + ValueSize::UINT64->value) { - return null; - } - - $ready_bytes = unpack(BaseRequest::pack(ValueSize::UINT64), substr($data, $offset, ValueSize::UINT64->value))[1]; - $offset += ValueSize::UINT64->value; - - // Less than offset + 8 bytes? not enough for write bytes. - if (strlen($data) < $offset + ValueSize::UINT64->value) { - return null; - } - - $write_bytes = unpack(BaseRequest::pack(ValueSize::UINT64), substr($data, $offset, ValueSize::UINT64->value))[1]; - $offset += ValueSize::UINT64->value; - - // Less than offset + 8 bytes? not enough for published bytes. - if (strlen($data) < $offset + ValueSize::UINT64->value) { - return null; - } - - $published_bytes = unpack(BaseRequest::pack(ValueSize::UINT64), substr($data, $offset, ValueSize::UINT64->value))[1]; - $offset += ValueSize::UINT64->value; - - // Less than offset + 8 bytes? not enough for received bytes. - if (strlen($data) < $offset + ValueSize::UINT64->value) { - return null; - } - - $received_bytes = unpack(BaseRequest::pack(ValueSize::UINT64), substr($data, $offset, ValueSize::UINT64->value))[1]; - $offset += ValueSize::UINT64->value; - - // Less than offset + 8 bytes? not enough for allocated bytes. - if (strlen($data) < $offset + ValueSize::UINT64->value) { - return null; - } - - $allocated_bytes = unpack(BaseRequest::pack(ValueSize::UINT64), substr($data, $offset, ValueSize::UINT64->value))[1]; - $offset += ValueSize::UINT64->value; - - $requests = []; - foreach (static::$types as $request_type) { - // Less than offset + 8 bytes? not enough for requests metric. - if (strlen($data) < $offset + ValueSize::UINT64->value) { - return null; - } - $requests[$request_type] = unpack(BaseRequest::pack(ValueSize::UINT64), substr($data, $offset, ValueSize::UINT64->value))[1]; - $offset += ValueSize::UINT64->value; - } - - $connections[] = [ + $attributes = ReaderProvider::readIntegers($data, [ + "port" => ValueSize::UINT16, + "connected_at" => ValueSize::UINT64, + "read_bytes" => ValueSize::UINT64, + "write_bytes" => ValueSize::UINT64, + "published_bytes" => ValueSize::UINT64, + "received_bytes" => ValueSize::UINT64, + "allocated_bytes" => ValueSize::UINT64, + ], $offset); + + $requests = ReaderProvider::readIntegers($data, static::$types, $offset); + + $connections[] = array_merge([ "id" => bin2hex($id), "type" => $type, "kind" => $kind, "ip_version" => $ip_version, "ip" => $ip, - "port" => $port, - "connected_at" => $connected_at, - "read_bytes" => $ready_bytes, - "write_bytes" => $write_bytes, - "published_bytes" => $published_bytes, - "received_bytes" => $received_bytes, - "allocated_bytes" => $allocated_bytes, "requests" => $requests, - ]; + ], $attributes); } } diff --git a/src/Responses/InfoResponse.php b/src/Responses/InfoResponse.php index d7e2c15..7535c40 100644 --- a/src/Responses/InfoResponse.php +++ b/src/Responses/InfoResponse.php @@ -20,6 +20,7 @@ use Throttr\SDK\Enum\KeyType; use Throttr\SDK\Enum\TTLType; use Throttr\SDK\Enum\ValueSize; +use Throttr\SDK\Providers\ReaderProvider; use Throttr\SDK\Requests\BaseRequest; /** @@ -27,6 +28,27 @@ */ class InfoResponse extends Response implements IResponse { + public static array $types = [ + 'INSERT', + 'QUERY', + 'UPDATE', + 'PURGE', + 'GET', + 'SET', + 'LIST', + 'INFO', + 'STATS', + 'STAT', + 'SUBSCRIBE', + 'UNSUBSCRIBE', + 'PUBLISH', + 'CHANNEL', + 'CHANNELS', + 'WHOAMI', + 'CONNECTION', + 'CONNECTIONS', + ]; + /** * Constructor * @@ -47,7 +69,6 @@ public function __construct(public string $data, public bool $status, public arr */ public static function fromBytes(string $data, ValueSize $size): InfoResponse|null { - $valueSize = $size->value; $offset = 0; if (strlen($data) < 433) { @@ -58,106 +79,43 @@ public static function fromBytes(string $data, ValueSize $size): InfoResponse|nu $offset++; if ($status) { - $now = unpack(BaseRequest::pack(ValueSize::UINT64), substr($data, $offset, ValueSize::UINT64->value))[1]; - $offset += 8; - - - $total_requests = unpack(BaseRequest::pack(ValueSize::UINT64), substr($data, $offset, ValueSize::UINT64->value))[1]; - $offset += 8; - - - $total_requests_per_minute = unpack(BaseRequest::pack(ValueSize::UINT64), substr($data, $offset, ValueSize::UINT64->value))[1]; - $offset += 8; - - $types = [ - 'INSERT' => ["total" => 0, "per_minute" => 0], - 'QUERY' => ["total" => 0, "per_minute" => 0], - 'UPDATE' => ["total" => 0, "per_minute" => 0], - 'PURGE' => ["total" => 0, "per_minute" => 0], - 'GET' => ["total" => 0, "per_minute" => 0], - 'SET' => ["total" => 0, "per_minute" => 0], - 'LIST' => ["total" => 0, "per_minute" => 0], - 'INFO' => ["total" => 0, "per_minute" => 0], - 'STATS' => ["total" => 0, "per_minute" => 0], - 'STAT' => ["total" => 0, "per_minute" => 0], - 'SUBSCRIBE' => ["total" => 0, "per_minute" => 0], - 'UNSUBSCRIBE' => ["total" => 0, "per_minute" => 0], - 'PUBLISH' => ["total" => 0, "per_minute" => 0], - 'CHANNEL' => ["total" => 0, "per_minute" => 0], - 'CHANNELS' => ["total" => 0, "per_minute" => 0], - 'WHOAMI' => ["total" => 0, "per_minute" => 0], - 'CONNECTION' => ["total" => 0, "per_minute" => 0], - 'CONNECTIONS' => ["total" => 0, "per_minute" => 0], - ]; - - foreach ($types as $key => $type) { - $types[$key]["total"] = unpack(BaseRequest::pack(ValueSize::UINT64), substr($data, $offset, ValueSize::UINT64->value))[1]; - $offset += 8; - $types[$key]["per_minute"] = unpack(BaseRequest::pack(ValueSize::UINT64), substr($data, $offset, ValueSize::UINT64->value))[1]; - $offset += 8; + $header = ReaderProvider::readIntegers($data, [ + "now" => ValueSize::UINT64, + "total_requests" => ValueSize::UINT64, + "total_requests_per_minute" => ValueSize::UINT64, + ], $offset); + + $types = []; + + foreach (static::$types as $key) { + $types[$key] = ReaderProvider::readIntegers($data, [ + "total" => ValueSize::UINT64, + "per_minute" => ValueSize::UINT64, + ], $offset); } - $total_read = unpack(BaseRequest::pack(ValueSize::UINT64), substr($data, $offset, ValueSize::UINT64->value))[1]; - $offset += 8; - - $total_read_per_minute = unpack(BaseRequest::pack(ValueSize::UINT64), substr($data, $offset, ValueSize::UINT64->value))[1]; - $offset += 8; - - $total_write = unpack(BaseRequest::pack(ValueSize::UINT64), substr($data, $offset, ValueSize::UINT64->value))[1]; - $offset += 8; - - $total_write_per_minute = unpack(BaseRequest::pack(ValueSize::UINT64), substr($data, $offset, ValueSize::UINT64->value))[1]; - $offset += 8; - - $total_keys = unpack(BaseRequest::pack(ValueSize::UINT64), substr($data, $offset, ValueSize::UINT64->value))[1]; - $offset += 8; - - $total_counters = unpack(BaseRequest::pack(ValueSize::UINT64), substr($data, $offset, ValueSize::UINT64->value))[1]; - $offset += 8; - - $total_buffers = unpack(BaseRequest::pack(ValueSize::UINT64), substr($data, $offset, ValueSize::UINT64->value))[1]; - $offset += 8; - - $total_allocated_bytes_on_counters = unpack(BaseRequest::pack(ValueSize::UINT64), substr($data, $offset, ValueSize::UINT64->value))[1]; - $offset += 8; - - $total_allocated_bytes_on_buffers = unpack(BaseRequest::pack(ValueSize::UINT64), substr($data, $offset, ValueSize::UINT64->value))[1]; - $offset += 8; - - $total_subscriptions = unpack(BaseRequest::pack(ValueSize::UINT64), substr($data, $offset, ValueSize::UINT64->value))[1]; - $offset += 8; - - $total_channels = unpack(BaseRequest::pack(ValueSize::UINT64), substr($data, $offset, ValueSize::UINT64->value))[1]; - $offset += 8; - - $started_at = unpack(BaseRequest::pack(ValueSize::UINT64), substr($data, $offset, ValueSize::UINT64->value))[1]; - $offset += 8; - - $total_connections = unpack(BaseRequest::pack(ValueSize::UINT64), substr($data, $offset, ValueSize::UINT64->value))[1]; - $offset += 8; + $attributes = ReaderProvider::readIntegers($data, [ + "total_read" => ValueSize::UINT64, + "total_read_per_minute" => ValueSize::UINT64, + "total_write" => ValueSize::UINT64, + "total_write_per_minute" => ValueSize::UINT64, + "total_keys" => ValueSize::UINT64, + "total_counters" => ValueSize::UINT64, + "total_buffers" => ValueSize::UINT64, + "total_allocated_bytes_on_counters" => ValueSize::UINT64, + "total_allocated_bytes_on_buffers" => ValueSize::UINT64, + "total_subscriptions" => ValueSize::UINT64, + "total_channels" => ValueSize::UINT64, + "started_at" => ValueSize::UINT64, + "total_connections" => ValueSize::UINT64, + ], $offset); $version = substr($data, $offset, 16); - return new InfoResponse($data, true, [ - "now" => $now, - "total_requests" => $total_requests, - "total_requests_per_minute" => $total_requests_per_minute, - "requests" => $types, - "total_read" => $total_read, - "total_read_per_minute" => $total_read_per_minute, - "total_write" => $total_write, - "total_write_per_minute" => $total_write_per_minute, - "total_keys" => $total_keys, - "total_counters" => $total_counters, - "total_buffers" => $total_buffers, - "total_allocated_bytes_on_counters" => $total_allocated_bytes_on_counters, - "total_allocated_bytes_on_buffers" => $total_allocated_bytes_on_buffers, - "total_subscriptions" => $total_subscriptions, - "total_channels" => $total_channels, - "started_at" => $started_at, - "total_connections" => $total_connections, + return new InfoResponse($data, true, array_merge($header, [ + "requests" => $types, "version" => $version, - ]); + ], $attributes)); } return new InfoResponse($data, false, []); diff --git a/src/Responses/ListResponse.php b/src/Responses/ListResponse.php index 5c1011d..e6cf47b 100644 --- a/src/Responses/ListResponse.php +++ b/src/Responses/ListResponse.php @@ -47,7 +47,6 @@ public function __construct(public string $data, public bool $status, public arr */ public static function fromBytes(string $data, ValueSize $size): ListResponse|null { - $valueSize = $size->value; $offset = 0; // Less than 1 byte? not enough for status. @@ -79,7 +78,6 @@ public static function fromBytes(string $data, ValueSize $size): ListResponse|nu return null; } - $fragment = unpack(BaseRequest::pack(ValueSize::UINT64), substr($data, $offset, ValueSize::UINT64->value))[1]; $offset += ValueSize::UINT64->value; // Less than offset + 8 bytes? not enough for fragment keys count. @@ -92,45 +90,30 @@ public static function fromBytes(string $data, ValueSize $size): ListResponse|nu $keys_in_fragment = []; + $expected_fragment_size = ( + ValueSize::UINT8->value * 3 + // key size, key type, ttl type + ValueSize::UINT64->value + // ttl + $size->value // value size + ) * $number_of_keys; + + if (strlen($data) < $offset + $expected_fragment_size) { + return null; + } + // Per key in fragment for ($e = 0; $e < $number_of_keys; ++$e) { - // Less than offset + 1 byte? not enough for key size. - if (strlen($data) < $offset + ValueSize::UINT8->value) { - return null; - } - $key_size = unpack(BaseRequest::pack(ValueSize::UINT8), substr($data, $offset, ValueSize::UINT8->value))[1]; $offset += ValueSize::UINT8->value; - // Less than offset + 1 byte? not enough for key type. - if (strlen($data) < $offset + ValueSize::UINT8->value) { - return null; - } - $key_type = KeyType::from(unpack(BaseRequest::pack(ValueSize::UINT8), substr($data, $offset, ValueSize::UINT8->value))[1]); $offset += ValueSize::UINT8->value; - // Less than offset + 1 byte? not enough for ttl type. - if (strlen($data) < $offset + ValueSize::UINT8->value) { - return null; - } - $ttl_type = TTLType::from(unpack(BaseRequest::pack(ValueSize::UINT8), substr($data, $offset, ValueSize::UINT8->value))[1]); $offset += ValueSize::UINT8->value; - // Less than offset + 8 bytes? not enough for ttl. - if (strlen($data) < $offset + ValueSize::UINT64->value) { - return null; - } - $ttl = unpack(BaseRequest::pack(ValueSize::UINT64), substr($data, $offset, ValueSize::UINT64->value))[1]; $offset += ValueSize::UINT64->value; - // Less than offset + N bytes? not enough for bytes used. - if (strlen($data) < $offset + $size->value) { - return null; - } - $bytes_used = unpack(BaseRequest::pack($size), substr($data, $offset, $size->value))[1]; $offset += $size->value; diff --git a/src/Responses/StatResponse.php b/src/Responses/StatResponse.php index fd17c3a..95d2d56 100644 --- a/src/Responses/StatResponse.php +++ b/src/Responses/StatResponse.php @@ -18,6 +18,7 @@ namespace Throttr\SDK\Responses; use Throttr\SDK\Enum\ValueSize; +use Throttr\SDK\Providers\ReaderProvider; use Throttr\SDK\Requests\BaseRequest; /** @@ -63,24 +64,14 @@ public static function fromBytes(string $data, ValueSize $size): StatResponse|nu return null; } - $reads_per_minute = unpack(BaseRequest::pack(ValueSize::UINT64), substr($data, $offset, ValueSize::UINT64->value))[1]; - $offset += ValueSize::UINT64->value; + $stats = ReaderProvider::readIntegers($data, [ + "reads_per_minute" => ValueSize::UINT64, + "writes_per_minute" => ValueSize::UINT64, + "total_reads" => ValueSize::UINT64, + "total_writes" => ValueSize::UINT64, + ], $offset); - $writes_per_minute = unpack(BaseRequest::pack(ValueSize::UINT64), substr($data, $offset, ValueSize::UINT64->value))[1]; - $offset += ValueSize::UINT64->value; - - $total_reads = unpack(BaseRequest::pack(ValueSize::UINT64), substr($data, $offset, ValueSize::UINT64->value))[1]; - $offset += ValueSize::UINT64->value; - - $total_writes = unpack(BaseRequest::pack(ValueSize::UINT64), substr($data, $offset, ValueSize::UINT64->value))[1]; - $offset += ValueSize::UINT64->value; - - return new StatResponse($data, true, [ - "reads_per_minute" => $reads_per_minute, - "writes_per_minute" => $writes_per_minute, - "total_reads" => $total_reads, - "total_writes" => $total_writes, - ]); + return new StatResponse($data, true, $stats); } return new StatResponse($data, false, []); diff --git a/src/Responses/StatsResponse.php b/src/Responses/StatsResponse.php index 01b834f..ee6d3b5 100644 --- a/src/Responses/StatsResponse.php +++ b/src/Responses/StatsResponse.php @@ -20,6 +20,7 @@ use Throttr\SDK\Enum\KeyType; use Throttr\SDK\Enum\TTLType; use Throttr\SDK\Enum\ValueSize; +use Throttr\SDK\Providers\ReaderProvider; use Throttr\SDK\Requests\BaseRequest; /** @@ -92,55 +93,24 @@ public static function fromBytes(string $data, ValueSize $size): StatsResponse|n $keys_in_fragment = []; + $expected_fragment_size = ( + ValueSize::UINT8->value + // key size + ValueSize::UINT64->value * 4 // reads_per_minute, writes_per_minute, total_reads, total_writes + ) * $number_of_keys; + + if (strlen($data) < $offset + $expected_fragment_size) { + return null; + } + // Per key in fragment for ($e = 0; $e < $number_of_keys; ++$e) { - // Less than offset + 1 byte? not enough for key size. - if (strlen($data) < $offset + ValueSize::UINT8->value) { - return null; - } - - $key_size = unpack(BaseRequest::pack(ValueSize::UINT8), substr($data, $offset, ValueSize::UINT8->value))[1]; - $offset += ValueSize::UINT8->value; - - // Less than offset + 8 bytes? not enough for reads per minute. - if (strlen($data) < $offset + ValueSize::UINT64->value) { - return null; - } - - $reads_per_minute = unpack(BaseRequest::pack(ValueSize::UINT64), substr($data, $offset, ValueSize::UINT64->value))[1]; - $offset += ValueSize::UINT64->value; - - // Less than offset + 8 bytes? not enough for writes per minute. - if (strlen($data) < $offset + ValueSize::UINT64->value) { - return null; - } - - $writes_per_minute = unpack(BaseRequest::pack(ValueSize::UINT64), substr($data, $offset, ValueSize::UINT64->value))[1]; - $offset += ValueSize::UINT64->value; - - // Less than offset + 8 bytes? not enough for total reads. - if (strlen($data) < $offset + ValueSize::UINT64->value) { - return null; - } - - $total_reads = unpack(BaseRequest::pack(ValueSize::UINT64), substr($data, $offset, ValueSize::UINT64->value))[1]; - $offset += ValueSize::UINT64->value; - - // Less than offset + 8 bytes? not enough for total reads. - if (strlen($data) < $offset + ValueSize::UINT64->value) { - return null; - } - - $total_writes = unpack(BaseRequest::pack(ValueSize::UINT64), substr($data, $offset, ValueSize::UINT64->value))[1]; - $offset += ValueSize::UINT64->value; - - $keys_in_fragment[] = [ - "size" => $key_size, - "reads_per_minute" => $reads_per_minute, - "writes_per_minute" => $writes_per_minute, - "total_reads" => $total_reads, - "total_writes" => $total_writes, - ]; + $keys_in_fragment[] = ReaderProvider::readIntegers($data, [ + "size" => ValueSize::UINT8, + "reads_per_minute" => ValueSize::UINT64, + "writes_per_minute" => ValueSize::UINT64, + "total_reads" => ValueSize::UINT64, + "total_writes" => ValueSize::UINT64, + ], $offset); } $total = array_sum(array_column($keys_in_fragment, 'size'));