Skip to content

Commit a574932

Browse files
committed
Add support for integer encoding types
1 parent 5207ec1 commit a574932

File tree

3 files changed

+79
-6
lines changed

3 files changed

+79
-6
lines changed

src/Encoder/FloatEncoder.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ private function encodeNumber($float, array $options, callable $encode)
5555
} elseif ($float === 0.0) {
5656
return '0.0';
5757
} elseif ($options['float.export']) {
58-
return var_export($float, true);
58+
return var_export((float) $float, true);
5959
}
6060

6161
return $this->encodeFloat($float, $this->determinePrecision($options));

src/Encoder/IntegerEncoder.php

Lines changed: 58 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,14 @@
1010
*/
1111
class IntegerEncoder implements Encoder
1212
{
13+
/** @var array Default values for options in the encoder */
14+
private static $defaultOptions = [
15+
'integer.type' => 'decimal',
16+
];
17+
1318
public function getDefaultOptions()
1419
{
15-
return [];
20+
return self::$defaultOptions;
1621
}
1722

1823
public function supports($value)
@@ -22,12 +27,60 @@ public function supports($value)
2227

2328
public function encode($value, $depth, array $options, callable $encode)
2429
{
25-
$string = (string) $value;
30+
$encoders = [
31+
'binary' => function ($value) {
32+
return $this->encodeBinary($value);
33+
},
34+
'octal' => function ($value) {
35+
return $this->encodeOctal($value);
36+
},
37+
'decimal' => function ($value, $options) {
38+
return $this->encodeDecimal($value, $options);
39+
},
40+
'hexadecimal' => function ($value) {
41+
return $this->encodeHexadecimal($value);
42+
},
43+
];
44+
45+
if (!isset($encoders[$options['integer.type']])) {
46+
throw new \InvalidArgumentException('Invalid integer encoding type');
47+
}
48+
49+
$callback = $encoders[$options['integer.type']];
50+
51+
return $callback((int) $value, $options);
52+
}
2653

27-
if ($value === 1 << (PHP_INT_SIZE * 8 - 1)) {
28-
$string = sprintf('(int)%s%s', $options['whitespace'] ? ' ' : '', $string);
54+
public function encodeBinary($integer)
55+
{
56+
return sprintf('%s0b%s', $this->sign($integer), decbin(abs($integer)));
57+
}
58+
59+
public function encodeOctal($integer)
60+
{
61+
return sprintf('%s0%s', $this->sign($integer), decoct(abs($integer)));
62+
}
63+
64+
public function encodeDecimal($integer, $options)
65+
{
66+
if ($integer === 1 << (PHP_INT_SIZE * 8 - 1)) {
67+
return sprintf('(int)%s%s', $options['whitespace'] ? ' ' : '', $integer);
68+
}
69+
70+
return var_export($integer, true);
71+
}
72+
73+
public function encodeHexadecimal($integer)
74+
{
75+
return sprintf('%s0x%s', $this->sign($integer), dechex(abs($integer)));
76+
}
77+
78+
private function sign($integer)
79+
{
80+
if ($integer < 0) {
81+
return '-';
2982
}
3083

31-
return $string;
84+
return '';
3285
}
3386
}

tests/tests/EncodingTest.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,26 @@ public function testMinimumInteger()
7171
$this->assertEncode('(int)' . (-PHP_INT_MAX - 1), -PHP_INT_MAX - 1, ['whitespace' => false]);
7272
}
7373

74+
public function testIntegerTypes()
75+
{
76+
$this->assertEncode('0b110011000000011111001001', 13371337, ['integer.type' => 'binary']);
77+
$this->assertEncode('-0b110011000000011111001001', -13371337, ['integer.type' => 'binary']);
78+
$this->assertEncode('063003711', 13371337, ['integer.type' => 'octal']);
79+
$this->assertEncode('-063003711', -13371337, ['integer.type' => 'octal']);
80+
$this->assertEncode('13371337', 13371337, ['integer.type' => 'decimal']);
81+
$this->assertEncode('-13371337', -13371337, ['integer.type' => 'decimal']);
82+
$this->assertEncode('0xcc07c9', 13371337, ['integer.type' => 'hexadecimal']);
83+
$this->assertEncode('-0xcc07c9', -13371337, ['integer.type' => 'hexadecimal']);
84+
}
85+
86+
public function testInvalidIntegerType()
87+
{
88+
$encoder = new PHPEncoder();
89+
90+
$this->expectException(\InvalidArgumentException::class);
91+
$encoder->encode(1, ['integer.type' => 'invalid']);
92+
}
93+
7494
public function testFloatEncoding()
7595
{
7696
$this->assertEncode('0.0', 0.0);

0 commit comments

Comments
 (0)