Permalink
Browse files

Added $offset and $length to send().

  • Loading branch information...
1 parent b7c234b commit 5b39200641a03b510f02fd59a97c668c74ec1dae @boenrobot boenrobot committed Oct 15, 2011
Showing with 77 additions and 2 deletions.
  1. +1 −0 RELEASE-1.0.0a2
  2. +32 −2 src/PEAR2/Net/Transmitter/Stream.php
  3. +28 −0 tests/ClientTest.php
  4. +16 −0 tests/ServerTest.php
View
@@ -7,5 +7,6 @@ Lots of reorganization and initial test suite.
* IPv6 addresses must now be written literally, without the surrounding "[" and "]".
* TcpServerConnection can now accept IPv6 connections.
* Merged sendStream() into send().
+* Added $offset and $length to send().
* Removed redundant error variables in TcpServerConnection.
* Removed the TcpServerConnection::isServer() function (can't tell apart server and client).
@@ -204,17 +204,37 @@ public function getChunk($direction = self::DIRECTION_ALL)
/**
* Sends a string or stream over the wrapped stream.
*
+ * Sends a string or stream over the wrapped stream. If a seekable stream is
+ * provided, it will be seeked back to the same position it was passed as,
+ * regardless of the $offset parameter.
+ *
* @param string|resource $contents The string or stream to send.
+ * @param int $offset The offset from which to start sending.
+ * If a stream is provided, and this is set to NULL, sending will start from
+ * the current stream position.
+ * @param int $length The maximum length to send. If omitted,
+ * the string/stream will be sent to its end.
*
* @return int The number of bytes sent.
*/
- public function send($contents)
+ public function send($contents, $offset = null, $length = null)
{
$bytes = 0;
$chunkSize = $this->chunkSize[self::DIRECTION_SEND];
+ $lengthIsNotNull = null !== $length;
+ $offsetIsNotNull = null !== $offset;
if (self::isStream($contents)) {
+ if ($offsetIsNotNull) {
+ $oldPos = ftell($contents);
+ fseek($contents, $offset, SEEK_SET);
+ }
while (!feof($contents)) {
if ($this->isAcceptingData()) {
+ if ($lengthIsNotNull
+ && 0 === $chunkSize = min($chunkSize, $length - $bytes)
+ ) {
+ break;
+ }
$bytesNow = @stream_copy_to_stream(
$contents, $this->stream, $chunkSize
);
@@ -227,9 +247,19 @@ public function send($contents)
}
}
}
- fseek($contents, -$bytes, SEEK_CUR);
+ if ($offsetIsNotNull) {
+ fseek($contents, $oldPos, SEEK_SET);
+ } else {
+ fseek($contents, -$bytes, SEEK_CUR);
+ }
} else {
$contents = (string) $contents;
+ if ($offsetIsNotNull) {
+ $contents = substr($contents, $offset);
+ }
+ if ($lengthIsNotNull) {
+ $contents = substr($contents, 0, $length);
+ }
$bytesToSend = (double) sprintf('%u', strlen($contents));
while ($bytes < $bytesToSend) {
if ($this->isAcceptingData()) {
View
@@ -85,6 +85,34 @@ public function test3MegaBytesEchoStreamReceive()
);
}
+ public function testOffsetSend()
+ {
+ $contents = 'abcd';
+ $this->assertEquals(3, $this->client->send($contents, 1));
+
+ $stream = fopen('php://temp', 'r+b');
+ fwrite($stream, $contents);
+ rewind($stream);
+ $this->assertEquals(3, $this->client->send($stream, 1));
+ fseek($stream, 3, SEEK_SET);
+ $this->assertEquals(1, $this->client->send($stream));
+ $this->assertEquals(2, $this->client->send($stream, 2));
+ }
+
+ public function testLengthSend()
+ {
+ $contents = 'abcd';
+ $this->assertEquals(1, $this->client->send($contents, null, 1));
+
+ $stream = fopen('php://temp', 'r+b');
+ fwrite($stream, $contents);
+ rewind($stream);
+ $this->assertEquals(1, $this->client->send($stream, null, 1));
+ fseek($stream, 2, SEEK_SET);
+ $this->assertEquals(1, $this->client->send($stream, null, 1));
+ $this->assertEquals(2, $this->client->send($stream, 1, 2));
+ }
+
public function testClientReceivingFilterCollection()
{
$filters = new FilterCollection();
View
@@ -116,6 +116,22 @@ public function test3MegaBytesEchoStreamReceive()
);
}
+ public function testOffsetSend()
+ {
+ $this->assertEquals('bcd', $this->conn->receive(3));
+ $this->assertEquals('bcd', $this->conn->receive(3));
+ $this->assertEquals('d', $this->conn->receive(1));
+ $this->assertEquals('cd', $this->conn->receive(2));
+ }
+
+ public function testLengthSend()
+ {
+ $this->assertEquals('a', $this->conn->receive(1));
+ $this->assertEquals('a', $this->conn->receive(1));
+ $this->assertEquals('c', $this->conn->receive(1));
+ $this->assertEquals('bc', $this->conn->receive(2));
+ }
+
public function testClientReceivingFilterCollection()
{
$this->assertEquals(1, $this->conn->send('t'), 'Wrong amount sent.');

0 comments on commit 5b39200

Please sign in to comment.