function server_loop() { while (true) { $read_fds = $this->fds; $write = $exp = null; if (stream_select($read_fds, $write, $exp, null)) { foreach ($read_fds as $socket) { $socket_id = (int) $socket; if ($socket_id == $this->server_socket_id) { if ($client_socket_id = parent::accept()) { $this->fds[$client_socket_id] = $this->client_sock[$client_socket_id]; $this->protocol->onConnect($this, $client_socket_id, 0); } } else { $data = Stream::read($socket, $this->buffer_size); if ($data !== false) { $this->protocol->onReceive($this, $socket_id, 0, $data); } else { $this->close($socket_id); } } } } } }
/** * @param int $length * @return string */ public function read($length) { $content = parent::read($length); if ($content && !$this->reachedEof) { $this->cache .= $content; } if ($this->eof()) { $this->reachedEof = true; } return $content; }
function server_loop() { while ($this->client_sock[0] = stream_socket_accept($this->server_sock, -1)) { stream_set_blocking($this->client_sock[0], 1); if (feof($this->client_sock[0])) { $this->close(0); } //堵塞Server必须读完全部数据 $data = Stream::read($this->client_sock[0], $this->buffer_size); $this->protocol->onReceive($this, 0, 0, $data); } }
public function read($bytes, &$bytes_skipped = null) { if ($bytes !== 0) { $this->current_content .= parent::read($bytes, $bytes_skipped); } $misc = null; $matching_content = $this->scan($this->current_content, $misc); if ($matching_content) { $found_pos = strpos($this->current_content, $matching_content); $bytes_skipped = substr($this->current_content, 0, $found_pos); $this->current_content = substr($this->current_content, $found_pos + strlen($matching_content)); return $this->mutateIn($matching_content, $misc); } else { if (parent::eof()) { $this->current_content = ''; } return null; } }
/** * @return array|bool */ protected function parseSizeForJPEG() { $state = null; while (true) { switch ($state) { default: $this->stream->read(2); $state = 'started'; break; case 'started': $b = $this->getByte(); if ($b === false) { return false; } $state = $b == 0xff ? 'sof' : 'started'; break; case 'sof': $b = $this->getByte(); if ($b === 0xe1) { $data = $this->stream->read($this->readInt($this->stream->read(2)) - 2); $stream = new Stream(); $stream->write($data); if ($stream->read(4) === 'Exif') { $stream->read(2); $exif = new Faster_Image_B52f1a8_Exif_Parser($stream); } break; } if (in_array($b, range(0xe0, 0xef))) { $state = 'skipframe'; break; } if (in_array($b, array_merge(range(0xc0, 0xc3), range(0xc5, 0xc7), range(0xc9, 0xcb), range(0xcd, 0xcf)))) { $state = 'readsize'; break; } if ($b == 0xff) { $state = 'sof'; break; } $state = 'skipframe'; break; case 'skipframe': $skip = $this->readInt($this->stream->read(2)) - 2; $this->stream->read($skip); $state = 'started'; break; case 'readsize': $c = $this->stream->read(7); $size = array($this->readInt(substr($c, 5, 2)), $this->readInt(substr($c, 3, 2))); if (isset($exif) && $exif->isRotated()) { return array_reverse($size); } return $size; } } return false; }
/** * Extracts post-game data (achievements etc) from the body stream. * * Post-game data will be set on $this->postgameData. * * @param Stream $stream Body stream to extract from. * * @return void */ protected function readPostgameData($stream) { // Prize for ugliest, most boring method of the project goes to… $data = new \stdClass(); $stream->skip(3); $stream->read($scenarioFilename, 32); $data->scenarioFilename = rtrim($scenarioFilename); $stream->skip(4); $stream->readInt($data->duration); $stream->readChar($data->allowCheats); $stream->readChar($data->complete); $stream->skip(14); $stream->readChar($data->mapSize); $stream->readChar($data->mapId); $stream->readChar($data->population); $stream->skip(1); $stream->readChar($data->victory); $stream->readChar($data->startingAge); $stream->readChar($data->resources); $stream->readChar($data->allTechs); $stream->readChar($data->teamTogether); $stream->readChar($data->revealMap); $stream->skip(3); $stream->readChar($data->lockTeams); $stream->readChar($data->lockSpeed); $stream->skip(1); $players = array(); for ($i = 0; $i < 8; $i++) { $playerStats = new \stdClass(); $stream->read($playerName, 16); $playerStats->name = rtrim($playerName); $stream->readWord($playerStats->totalScore); $totalScores = array(); for ($j = 0; $j < 8; $j++) { $stream->readWord($totalScores[$j]); } $playerStats->totalScores = $totalScores; $stream->readChar($playerStats->victory); $stream->readChar($playerStats->civId); $stream->readChar($playerStats->colorId); $stream->readChar($playerStats->team); $stream->skip(2); $stream->readChar($playerStats->mvp); $stream->skip(3); $stream->readChar($playerStats->result); $stream->skip(3); $militaryStats = new \stdClass(); $stream->readWord($militaryStats->score); $stream->readWord($militaryStats->unitsKilled); $stream->readWord($militaryStats->u0); $stream->readWord($militaryStats->unitsLost); $stream->readWord($militaryStats->buildingsRazed); $stream->readWord($militaryStats->u1); $stream->readWord($militaryStats->buildingsLost); $stream->readWord($militaryStats->unitsConverted); $playerStats->militaryStats = $militaryStats; $stream->skip(32); $economyStats = new \stdClass(); $stream->readWord($economyStats->score); $stream->readWord($economyStats->u0); $stream->readInt($economyStats->foodCollected); $stream->readInt($economyStats->woodCollected); $stream->readInt($economyStats->stoneCollected); $stream->readInt($economyStats->goldCollected); $stream->readWord($economyStats->tributeSent); $stream->readWord($economyStats->tributeReceived); $stream->readWord($economyStats->tradeProfit); $stream->readWord($economyStats->relicGold); $playerStats->economyStats = $economyStats; $stream->skip(16); $techStats = new \stdClass(); $stream->readWord($techStats->score); $stream->readWord($techStats->u0); $stream->readInt($techStats->feudalTime); $stream->readInt($techStats->castleTime); $stream->readInt($techStats->imperialTime); $stream->readChar($techStats->mapExploration); $stream->readChar($techStats->researchCount); $stream->readChar($techStats->researchPercent); $playerStats->techStats = $techStats; $stream->skip(1); $societyStats = new \stdClass(); $stream->readWord($societyStats->score); $stream->readChar($societyStats->totalWonders); $stream->readChar($societyStats->totalCastles); $stream->readChar($societyStats->relicsCaptured); $stream->readChar($societyStats->u0); $stream->readWord($societyStats->villagerHigh); $playerStats->societyStats = $societyStats; $stream->skip(84); $players[] = $playerStats; } $data->players = $players; $stream->skip(4); $this->postgameData = $data; }
/** * 接收到数据后进行处理 * @param $client_socket * @param $events * @param $arg * @return unknown_type */ function event_receive($client_socket, $events, $client_id) { $data = Stream::read($client_socket, $this->buffer_size); if ($data !== false) { $this->protocol->onReceive($this, $client_id, 0, $data); } else { $this->close($client_id); } }
/** * Waits for the server to send the specified tag back. * * @param string $tag Tag to wait for from the server. * * @return boolean|SimpleXMLElement */ protected function waitForServer($tag) { $this->_logger->debug("Tag we're waiting for: " . $tag); $fromServer = false; // If there is nothing left in the buffer, wait for the stream to update if (count($this->_buffer) == 0 && $this->_stream->select() > 0) { $response = ''; $done = false; // Read data from the connection. while (!$done) { $response .= $this->_stream->read(4096); if ($this->_stream->select() == 0) { $done = true; } } $this->_logger->debug('Response (Xmpp_Connection): ' . $response); // If the response isn't empty, load it into a SimpleXML element if (trim($response) != '') { // If the response from the server starts (where "starts // with" means "appears after the xml prologue if one is // present") with "<stream:stream and it doesn't have a // closing "</stream:stream>" then we should append one so // that it can be easily loaded into a SimpleXMLElement, // otherwise it will cause an error to be thrown because of // malformed XML. // Check if response starts with XML Prologue: if (preg_match("/^<\\?xml version='1.0'( encoding='UTF-8')?\\?>/", $response, $matches) == 1) { $offset = strlen($matches[0]); $prologue = $matches[0]; } else { $offset = 0; } // Check if first part of the actual response starts with // <stream:stream if (strpos($response, '<stream:stream ') === $offset) { // If so, append a closing tag $response .= '</stream:stream>'; } // For consistent handling and correct stream namespace // support, we should wrap all responses in the // stream:stream tags to make sure everything works as // expected. Unless the response already contains such tags. if (strpos($response, '<stream:stream') === false) { $response = '<stream:stream ' . 'xmlns:stream="http://etherx.jabber.org/streams" ' . "xmlns:ack='http://www.xmpp.org/extensions/xep-0198.html#ns' " . 'xmlns="jabber:client" ' . 'from="' . $this->_realm . '" ' . 'xml:lang="en" version="1.0">' . $response . '</stream:stream>'; } // If the xml prologue should be at the start, move it // because it will now be in the wrong place. We can assume // if $offset is not 0 that there was a prologue. if ($offset != 0) { $response = $prologue . str_replace($prologue, '', $response); } $xml = simplexml_load_string($response); // If we want the stream element itself, just return that, // otherwise check the contents of the stream. if ($tag == 'stream:stream') { $fromServer = $xml; } else { if ($xml instanceof SimpleXMLElement && $xml->getName() == 'stream') { // Get the namespaces used at the root level of the // document. Add a blank namespace on for anything that // isn't namespaced. Then we can iterate over all of the // elements in the doc. $namespaces = $xml->getNamespaces(); $namespaces['blank'] = ''; foreach ($namespaces as $namespace) { foreach ($xml->children($namespace) as $child) { if ($child instanceof SimpleXMLElement) { $this->_buffer[] = $child; } } } } } } } $this->_logger->debug('Contents of $fromServer: ' . var_export($fromServer, true)); $this->_logger->debug('Contents of $this->_buffer before foreach: ' . var_export($this->_buffer, true)); // Now go over what is in the buffer and return anything necessary foreach ($this->_buffer as $key => $stanza) { // Only bother looking for more tags if one has not yet been found. if ($fromServer === false) { // Remove this element from the buffer because we do not want it to // be processed again. unset($this->_buffer[$key]); // If this the tag we want, save it for returning. if ($tag == '*' || $stanza->getName() == $tag) { $fromServer = $stanza; } } } $this->_logger->debug('Contents of $this->_buffer after foreach: ' . var_export($this->_buffer, true)); return $fromServer; }
public function read($length) { parent::read($length); return fread($this->stream, $length); }
public function positionAfterReOpen() { $s = new Stream(); $s->open(STREAM_MODE_WRITE); $s->write('GIF89a'); $s->close(); $s->open(STREAM_MODE_READ); $this->assertEquals(0, $s->tell()); $this->assertEquals('GIF89a', $s->read()); $s->close(); }