Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 19 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,12 @@ The above outputs the bencode encoded string `d5:arrayl3:one3:two5:threee7:integ
```php
<?php

use Rych\Bencode\Bencode;
use Rych\Bencode;
require 'Rych/Bencode.php';

$string = "d5:arrayl3:one3:two5:threee7:integeri42e6:string3:bare";

print_r(Bencode::decode($string));
print_r(Bencode::decode($string);
```

The above results the the following output:
Expand All @@ -72,6 +73,22 @@ Array
)
```

### Decoding a file

Large bencoded files can be read efficiently from disk by passing an instance of `Rych\Bencode\DataSource\FileHandle` to `Bencode::decode`, instead of loading the file into a string.

```php
<?php

use Rych\Bencode;
use Rych\Bencode\DataSource\FileHandle;
require 'Rych/Bencode.php';

$file = fopen('path/to/file.bin', 'r');
$decoded = Bencode::decode( new FileHandle($file) );
```


Installation via [Composer](http://getcomposer.org/)
------------

Expand Down
30 changes: 30 additions & 0 deletions src/DataSource.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php
/**
* Rych Bencode Component
*
* @package Rych\Bencode
* @author Ryan Chouinard <rchouinard@gmail.com>
* @copyright Copyright (c) 2014, Ryan Chouinard
* @license MIT License - http://www.opensource.org/licenses/mit-license.php
*/

namespace Rych\Bencode;

interface DataSource
{
/**
* Get the length of the data source
*
* @return integer
*/
public function getLength();

/**
* Read bytes from the data source
*
* @param integer $offset
* @param integer $length
* @return string
*/
public function read($offset, $length = null);
}
62 changes: 62 additions & 0 deletions src/DataSource/FileHandle.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<?php

/**
* Rych Bencode Component
*
* @package Rych\Bencode
* @author Ryan Chouinard <rchouinard@gmail.com>
* @copyright Copyright (c) 2014, Ryan Chouinard
* @license MIT License - http://www.opensource.org/licenses/mit-license.php
*/

namespace Rych\Bencode\DataSource;

use Rych\Bencode\DataSource;
use Rych\Bencode\Exception\RuntimeException;

class FileHandle implements DataSource
{
protected $handle;

protected $length;

public function __construct($handle)
{
if (!is_resource($handle)) {
throw new RuntimeException('Expected resource, got '. gettype($string));
}

$this->handle = $handle;
}

public function getLength()
{
if (is_null($this->length)) {
$stat = fstat($this->handle);
$this->length = $stat['size'];
}

return $this->length;
}

public function read($offset, $length = 1)
{
$length = intval($length);

if ($offset < 0 || $offset > $this->getLength() - 1) {
throw new RuntimeException('Invalid offset');
}

if ($length < 1) {
throw new RuntimeException('Invalid length');
}

fseek($this->handle, $offset);

if ($length === 1) {
return fgetc($this->handle);
} else {
return fread($this->handle, $length);
}
}
}
59 changes: 59 additions & 0 deletions src/DataSource/String.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php

/**
* Rych Bencode Component
*
* @package Rych\Bencode
* @author Ryan Chouinard <rchouinard@gmail.com>
* @copyright Copyright (c) 2014, Ryan Chouinard
* @license MIT License - http://www.opensource.org/licenses/mit-license.php
*/

namespace Rych\Bencode\DataSource;

use Rych\Bencode\DataSource;
use Rych\Bencode\Exception\RuntimeException;

class String implements DataSource
{
protected $string;

protected $length;

public function __construct($string)
{
if (!is_string($string)) {
throw new RuntimeException('Expected string, got '. gettype($string));
}

$this->string = $string;
}

public function getLength()
{
if (is_null($this->length)) {
$this->length = strlen($this->string);
}

return $this->length;
}

public function read($offset, $length = 1)
{
$length = intval($length);

if ($offset < 0 || $offset > $this->getLength() - 1) {
throw new RuntimeException('Invalid offset');
}

if ($length < 1) {
throw new RuntimeException('Invalid length');
}

if ($length === 1) {
return $this->string[$offset];
} else {
return substr($this->string, $offset, $length);
}
}
}
Loading