/** * Internal function which bencodes the data * into a valid torrent metainfo string * * @param array file data * @return mixed false on failure or the bencoded metainfo string * @throws File_Bittorrent2_Exception if no file or directory is defined */ protected function encodeTorrent(array $info = array()) { $bencdata = array(); $bencdata['info'] = array(); if ($this->is_file) { $bencdata['info']['length'] = $info['length']; $bencdata['info']['md5sum'] = $info['md5sum']; } else { if ($this->is_dir) { if ($this->data_gap !== false) { $this->pieces .= pack('H*', sha1($this->data_gap)); $this->data_gap = false; } $bencdata['info']['files'] = $this->files; } else { throw new File_Bittorrent2_Exception('Use ' . __CLASS__ . '::setPath() to define a file or directory.', File_Bittorrent2_Exception::make); } } $bencdata['info']['name'] = $this->name; $bencdata['info']['piece length'] = $this->piece_length; $bencdata['info']['pieces'] = $this->pieces; $bencdata['announce'] = $this->announce; $bencdata['creation date'] = time(); $bencdata['comment'] = $this->comment; $bencdata['created by'] = $this->created_by; // $bencdata['announce-list'] = array($this->announce) // Encode it $Encoder = new File_Bittorrent2_Encode(); return $Encoder->encode_array($bencdata); }
<?php /** * Test case for Bug #3970 * * @see http://pear.php.net/bugs/bug.php?id=3970 * * @author Markus Tacker <*****@*****.**> * @version $Id$ * @package File_Bittorrent2 * @subpackage Bugs */ require_once '../File/Bittorrent2/Encode.php'; require_once '../File/Bittorrent2/Decode.php'; $Decoder = new File_Bittorrent2_Decode(); $Encoder = new File_Bittorrent2_Encode(); $torrent = $Decoder->decode(file_get_contents('../freebsd.torrent')); $info_encoded = $Encoder->encode($torrent); $decoded_info_encoded = $Decoder->decode($info_encoded); var_dump($torrent['info']['piece length']); var_dump($decoded_info_encoded['info']['piece length']);
<?php /** * Test case for Bug #4570 * * @see http://pear.php.net/bugs/bug.php?id=4570 * * @author Justin "nagash" Jones <j dot nagash at gmail dot com> * @version $Id$ * @package File_Bittorrent2 * @subpackage Bugs */ require_once '../File/Bittorrent2/Encode.php'; require_once '../File/Bittorrent2/Decode.php'; $decoder = new File_Bittorrent2_Decode(); $encoder = new File_Bittorrent2_Encode(); error_reporting(E_ALL); $data = array('broken' => null, 'bit' => 'torrent'); echo '<pre>'; echo 'The data array:' . "\n"; print_r($data); $encode1 = $encoder->encode_array($data); $decode1 = $decoder->decode($encode1); echo "\n" . 'First decode:' . "\n"; print_r($decode1); // Works fine! // If you add and remove and change these things, your results will vary. // Sometimes I just got an empty Array, other times I got data in the wrong keys. // And for the worst times, it looped indefinately, but I couldn't reproduce that // with this data - see below for an example.' $decode1['bit'] = 'testing';
/** * Decode .torrent file and accumulate information * * @param string Filename * @return mixed Returns an arrayon success or false on error * @throws File_Bittorrent2_Exception if no file given or bencoded data is corrupt */ function decodeFile($file) { // Check file if (!is_file($file)) { throw new File_Bittorrent2_Exception('Given filename \'' . $file . '\' is not a valid file.', File_Bittorrent2_Exception::source); } // Reset public attributes $this->name = ''; $this->filename = ''; $this->comment = ''; $this->date = 0; $this->files = array(); $this->size = 0; $this->created_by = ''; $this->announce = ''; $this->announce_list = array(); $this->position = 0; $this->info_hash = ''; // Decode .torrent $this->source = file_get_contents($file); $this->source_length = strlen($this->source); $this->decoded = $this->bdecode(); if (!is_array($this->decoded)) { throw new File_Bittorrent2_Exception('Corrupted bencoded data. Failed to decode data from file \'$file\'.', File_Bittorrent2_Exception::decode); } // Compute info_hash $Encoder = new File_Bittorrent2_Encode(); $this->info_hash = sha1($Encoder->encode($this->decoded['info'])); // Pull information form decoded data $this->filename = basename($file); // Name of the torrent - statet by the torrent's author $this->name = $this->decoded['info']['name']; // Authors may add comments to a torrent if (isset($this->decoded['comment'])) { $this->comment = $this->decoded['comment']; } // Creation date of the torrent as unix timestamp if (isset($this->decoded['creation date'])) { $this->date = $this->decoded['creation date']; } // This contains the signature of the application used to create the torrent if (isset($this->decoded['created by'])) { $this->created_by = $this->decoded['created by']; } // Get the directory separator $sep = PHP_OS == 'Linux' ? '/' : '\\'; // There is sometimes an array listing all files // in the torrent with their individual filesize if (isset($this->decoded['info']['files']) and is_array($this->decoded['info']['files'])) { foreach ($this->decoded['info']['files'] as $file) { $path = join($sep, $file['path']); // We are computing the total size of the download heres $this->size += $file['length']; $this->files[] = array('filename' => $path, 'size' => $file['length']); } // In case the torrent contains only on file } elseif (isset($this->decoded['info']['name'])) { $this->files[] = array('filename' => $this->decoded['info']['name'], 'size' => $this->decoded['info']['length']); } // If the the info->length field is present we are dealing with // a single file torrent. if (isset($this->decoded['info']['length']) and $this->size == 0) { $this->size = $this->decoded['info']['length']; } // This contains the tracker the torrent has been received from if (isset($this->decoded['announce'])) { $this->announce = $this->decoded['announce']; } // This contains a list of all known trackers for this torrent if (isset($this->decoded['announce-list']) and is_array($this->decoded['announce-list'])) { $this->announce_list = $this->decoded['announce-list']; } // Currently, I'm not sure how to determine an error // Just try to fetch the info from the decoded data // and return it return array('name' => $this->name, 'filename' => $this->filename, 'comment' => $this->comment, 'date' => $this->date, 'created_by' => $this->created_by, 'files' => $this->files, 'size' => $this->size, 'announce' => $this->announce, 'announce_list' => $this->announce_list, 'info_hash' => $this->info_hash); }
// | Free Software Foundation, Inc. | // | 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | // +----------------------------------------------------------------------+ /** * Example usage of File_Bittorrent2 * * @author Markus Tacker <*****@*****.**> * @version $Id$ */ /** * Include class */ require_once 'File/Bittorrent2/Encode.php'; require_once 'File/Bittorrent2/Decode.php'; $File_Bittorrent2_Decode = new File_Bittorrent2_Decode(); $File_Bittorrent2_Encode = new File_Bittorrent2_Encode(); // Encoding vars echo "Encoding integers\n"; $encodedInt = $File_Bittorrent2_Encode->encode(10); var_dump($encodedInt); var_dump($File_Bittorrent2_Decode->decode($encodedInt)); echo "Encoding strings\n"; $encodedStr = $File_Bittorrent2_Encode->encode('This is a string.'); var_dump($encodedStr); var_dump($File_Bittorrent2_Decode->decode($encodedStr)); echo "Encoding arrays as lists\n"; $encodedList = $File_Bittorrent2_Encode->encode(array('Banana', 'Apple', 'Cherry')); var_dump($encodedList); var_dump($File_Bittorrent2_Decode->decode($encodedList)); echo "Encoding arrays as dictionaries\n"; $encodedDict = $File_Bittorrent2_Encode->encode(array('fruits' => array('Banana', 'Apple', 'Cherry', 'subarray' => array(1, 2, 3)), 'ints' => array(1, 2, 3), 'count' => 3));