Decoder.php 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. <?php
  2. namespace PHPSocketIO\Parser;
  3. use Exception;
  4. use PHPSocketIO\Event\Emitter;
  5. use PHPSocketIO\Debug;
  6. class Decoder extends Emitter
  7. {
  8. public function __construct()
  9. {
  10. Debug::debug('Decoder __construct');
  11. }
  12. public function __destruct()
  13. {
  14. Debug::debug('Decoder __destruct');
  15. }
  16. /**
  17. * @throws Exception
  18. */
  19. public function add($obj): void
  20. {
  21. if (is_string($obj)) {
  22. $packet = self::decodeString($obj);
  23. $this->emit('decoded', $packet);
  24. }
  25. }
  26. /**
  27. * @throws Exception
  28. */
  29. public function decodeString($str): array
  30. {
  31. $p = [];
  32. $i = 0;
  33. // look up type
  34. $p['type'] = $str[0];
  35. if (! isset(Parser::$types[$p['type']])) {
  36. return self::error();
  37. }
  38. // look up attachments if type binary
  39. if (Parser::BINARY_EVENT == $p['type'] || Parser::BINARY_ACK == $p['type']) {
  40. $buf = '';
  41. while ($str[++$i] != '-') {
  42. $buf .= $str[$i];
  43. if ($i == strlen($str)) {
  44. break;
  45. }
  46. }
  47. if ($buf != intval($buf) || $str[$i] != '-') {
  48. throw new Exception('Illegal attachments');
  49. }
  50. $p['attachments'] = intval($buf);
  51. }
  52. // look up namespace (if any)
  53. if (isset($str[$i + 1]) && '/' === $str[$i + 1]) {
  54. $p['nsp'] = '';
  55. while (++$i) {
  56. if ($i === strlen($str)) {
  57. break;
  58. }
  59. $c = $str[$i];
  60. if (',' === $c) {
  61. break;
  62. }
  63. $p['nsp'] .= $c;
  64. }
  65. } else {
  66. $p['nsp'] = '/';
  67. }
  68. // look up id
  69. if (isset($str[$i + 1])) {
  70. $next = $str[$i + 1];
  71. if ('' !== $next && strval((int)$next) === strval($next)) {
  72. $p['id'] = '';
  73. while (++$i) {
  74. $c = $str[$i];
  75. if (null == $c || strval((int)$c) != strval($c)) {
  76. --$i;
  77. break;
  78. }
  79. $p['id'] .= $str[$i];
  80. if ($i == strlen($str)) {
  81. break;
  82. }
  83. }
  84. $p['id'] = (int)$p['id'];
  85. }
  86. }
  87. // look up json data
  88. if (isset($str[++$i])) {
  89. $p['data'] = json_decode(substr($str, $i), true);
  90. }
  91. return $p;
  92. }
  93. public static function error(): array
  94. {
  95. return [
  96. 'type' => Parser::ERROR,
  97. 'data' => 'parser error'
  98. ];
  99. }
  100. }