forked from rchouinard/bencode
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathEncoder.php
More file actions
153 lines (133 loc) · 3.79 KB
/
Copy pathEncoder.php
File metadata and controls
153 lines (133 loc) · 3.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
<?php
/**
* Power2All Bencode
*
* Bencode serializer for PHP 5.3+.
*
* @package Power2All\Bencode
* @copyright Copyright (c) 2014, Ryan Chouinard, modded by Power2All
* @author Ryan Chouinard <rchouinard@gmail.com>, Power2All <info@power2all.com>
* @license MIT License - http://www.opensource.org/licenses/mit-license.php
*/
namespace Power2All\Bencode;
use Power2All\Bencode\Exception\RuntimeException;
/**
* Bencode encoder class
*
* Encode values into bencode encoded strings.
*/
class Encoder
{
/**
* Value to encode
*
* @var mixed
*/
private $data;
/**
* Encoder constructor
*
* @param mixed $data The value to encode.
* @return void
*/
private function __construct($data)
{
$this->data = $data;
}
/**
* Encode a value into a bencode encoded string
*
* @param mixed $data The value to encode.
* @return string Returns the bencode encoded string.
*/
public static function encode($data)
{
try {
if (is_object($data)) {
if (method_exists($data, "toArray")) {
$data = $data->toArray();
} else {
$data = (array) $data;
}
}
$encoder = new self($data);
$encoded = $encoder->doEncode();
return $encoded;
} catch (Exception $e) {
throw new RuntimeException("Unexpected Error: " . $e->getMessage());
}
}
/**
* Iterate over values and encode them
*
* @param mixed $data The value to encode.
* @return string Returns the bencode encoded string.
*/
private function doEncode($data = null)
{
$data = is_null($data) ? $this->data : $data;
if (is_array($data) && (isset ($data[0]) || empty ($data))) {
return $this->encodeList($data);
} elseif (is_array($data)) {
return $this->encodeDict($data);
} elseif (is_integer($data) || is_float($data)) {
$data = sprintf("%.0f", round($data, 0));
return $this->encodeInteger($data);
} else {
return $this->encodeString($data);
}
}
/**
* Encode an integer
*
* @param integer $data The integer to be encoded.
* @return string Returns the bencode encoded integer.
*/
private function encodeInteger($data = null)
{
$data = is_null($data) ? $this->data : $data;
return sprintf("i%.0fe", $data);
}
/**
* Encode a string
*
* @param string $data The string to be encoded.
* @return string Returns the bencode encoded string.
*/
private function encodeString($data = null)
{
$data = is_null($data) ? $this->data : $data;
return sprintf("%d:%s", strlen($data), $data);
}
/**
* Encode a list
*
* @param array $data The list to be encoded.
* @return string Returns the bencode encoded list.
*/
private function encodeList(array $data = null)
{
$data = is_null($data) ? $this->data : $data;
$list = "";
foreach ($data as $value) {
$list .= $this->doEncode($value);
}
return "l{$list}e";
}
/**
* Encode a dictionary
*
* @param array $data The dictionary to be encoded.
* @return string Returns the bencode encoded dictionary.
*/
private function encodeDict(array $data = null)
{
$data = is_null($data) ? $this->data : $data;
ksort($data); // bencode spec requires dicts to be sorted alphabetically
$dict = "";
foreach ($data as $key => $value) {
$dict .= $this->encodeString($key) . $this->doEncode($value);
}
return "d{$dict}e";
}
}