Decoder.php 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. <?php
  2. namespace PHPSocketIO\Parser;
  3. use \PHPSocketIO\Parser\Parser;
  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. public function add($obj)
  17. {
  18. if (is_string($obj))
  19. {
  20. $packet = self::decodeString($obj);
  21. if(Parser::BINARY_EVENT == $packet['type'] || Parser::BINARY_ACK == $packet['type'])
  22. {
  23. // binary packet's json todo BinaryReconstructor
  24. $this->reconstructor = new BinaryReconstructor(packet);
  25. // no attachments, labeled binary but no binary data to follow
  26. if ($this->reconstructor->reconPack->attachments === 0)
  27. {
  28. $this->emit('decoded', $packet);
  29. }
  30. } else { // non-binary full packet
  31. $this->emit('decoded', $packet);
  32. }
  33. }
  34. else if (isBuf($obj) || !empty($obj['base64']))
  35. { // raw binary data
  36. if (!$this->reconstructor)
  37. {
  38. throw new \Exception('got binary data when not reconstructing a packet');
  39. } else {
  40. $packet = $this->reconstructor->takeBinaryData($obj);
  41. if ($packet)
  42. { // received final buffer
  43. $this->reconstructor = null;
  44. $this->emit('decoded', $packet);
  45. }
  46. }
  47. }
  48. else {
  49. throw new \Exception('Unknown type: ' + obj);
  50. }
  51. }
  52. public function decodeString($str)
  53. {
  54. $p = array();
  55. $i = 0;
  56. // look up type
  57. $p['type'] = $str[0];
  58. if(!isset(Parser::$types[$p['type']])) return self::error();
  59. // look up attachments if type binary
  60. if(Parser::BINARY_EVENT == $p['type'] || Parser::BINARY_ACK == $p['type'])
  61. {
  62. $buf = '';
  63. while ($str[++$i] != '-')
  64. {
  65. $buf .= $str[$i];
  66. if($i == strlen(str)) break;
  67. }
  68. if ($buf != intval($buf) || $str[$i] != '-')
  69. {
  70. throw new \Exception('Illegal attachments');
  71. }
  72. $p['attachments'] = intval($buf);
  73. }
  74. // look up namespace (if any)
  75. if(isset($str[$i + 1]) && '/' === $str[$i + 1])
  76. {
  77. $p['nsp'] = '';
  78. while (++$i)
  79. {
  80. if ($i === strlen($str)) break;
  81. $c = $str[$i];
  82. if (',' === $c) break;
  83. $p['nsp'] .= $c;
  84. }
  85. } else {
  86. $p['nsp'] = '/';
  87. }
  88. // look up id
  89. if(isset($str[$i+1]))
  90. {
  91. $next = $str[$i+1];
  92. if ('' !== $next && strval((int)$next) === strval($next))
  93. {
  94. $p['id'] = '';
  95. while (++$i)
  96. {
  97. $c = $str[$i];
  98. if (null == $c || strval((int)$c) != strval($c))
  99. {
  100. --$i;
  101. break;
  102. }
  103. $p['id'] .= $str[$i];
  104. if($i == strlen($str)) break;
  105. }
  106. $p['id'] = (int)$p['id'];
  107. }
  108. }
  109. // look up json data
  110. if (isset($str[++$i]))
  111. {
  112. // todo try
  113. $p['data'] = json_decode(substr($str, $i), true);
  114. }
  115. return $p;
  116. }
  117. public static function error()
  118. {
  119. return array(
  120. 'type'=> Parser::ERROR,
  121. 'data'=> 'parser error'
  122. );
  123. }
  124. public function destroy()
  125. {
  126. }
  127. }