/** * Extracts a new response from a communicator. * * This is the function that performs the actual receiving, while the * constructor is also involved in locks and registry sync. * * @param Communicator $com The communicator from which to extract * the new response. * @param bool $asStream Whether to populate the argument values * with streams instead of strings. * @param int $sTimeout If a response is not immediatly * available, wait this many seconds. If NULL, wait indefinetly. * Note that if an empty sentence is received, the timeout will be * reset for another sentence receiving. * @param int $usTimeout Microseconds to add to the waiting time. * * @return void */ private function _receive(Communicator $com, $asStream = false, $sTimeout = 0, $usTimeout = null) { do { if (!$com->getTransmitter()->isDataAwaiting($sTimeout, $usTimeout)) { throw new SocketException('No data within the time limit', SocketException::CODE_NO_DATA); } $type = $com->getNextWord(); } while ('' === $type); $this->setType($type); if ($asStream) { for ($word = $com->getNextWordAsStream(), fseek($word, 0, SEEK_END); ftell($word) !== 0; $word = $com->getNextWordAsStream(), fseek($word, 0, SEEK_END)) { rewind($word); $ind = fread($word, 1); if ('=' === $ind || '.' === $ind) { $prefix = stream_get_line($word, null, '='); } if ('=' === $ind) { $value = fopen('php://temp', 'r+b'); $bytesCopied = ftell($word); while (!feof($word)) { $bytesCopied += stream_copy_to_stream($word, $value, 0xfffff, $bytesCopied); } rewind($value); $this->setAttribute($prefix, $value); continue; } if ('.' === $ind && 'tag' === $prefix) { $this->setTag(stream_get_contents($word, -1, -1)); continue; } rewind($word); $this->unrecognizedWords[] = $word; } } else { for ($word = $com->getNextWord(); '' !== $word; $word = $com->getNextWord()) { if (preg_match('/^=([^=]+)=(.*)$/sS', $word, $matches)) { $this->setAttribute($matches[1], $matches[2]); } elseif (preg_match('/^\\.tag=(.*)$/sS', $word, $matches)) { $this->setTag($matches[1]); } else { $this->unrecognizedWords[] = $word; } } } }