Skip to content

Commit 67fb4f3

Browse files
authored
Merge pull request #160 from php-java/add-type-validation
Add type validation
2 parents 923d705 + b7e329b commit 67fb4f3

12 files changed

Lines changed: 192 additions & 33 deletions

File tree

src/Kernel/Types/Type.php

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,25 @@ class Type
1111

1212
public function __construct($value)
1313
{
14-
// Validate value which is scalar.
15-
if (!is_scalar($value) &&
16-
!is_array($value) &&
17-
!is_null($value) &&
18-
!($value instanceof self)
14+
if (!($value instanceof self) &&
15+
$value !== null &&
16+
!static::isValid($value)
1917
) {
20-
$type = gettype($value);
2118
throw new TypeException(
22-
'Passed value is not scalar or miss match type. The value is "' . ($type === 'object' ? get_class($value) : $type) . '"'
19+
'"' . ((string) $value) . '" is not expected in ' . get_class($this) . '.'
2320
);
2421
}
22+
2523
$this->value = ($value instanceof self)
2624
? $value->getValue()
27-
: $value;
25+
: static::filter($value);
26+
}
27+
28+
public function __debugInfo()
29+
{
30+
return [
31+
'value' => $this->value,
32+
];
2833
}
2934

3035
/**
@@ -58,4 +63,14 @@ public function __toString()
5863
{
5964
return (string) $this->getValue();
6065
}
66+
67+
public static function isValid($value)
68+
{
69+
throw new TypeException('Not implemented type validation.');
70+
}
71+
72+
protected static function filter($value)
73+
{
74+
return $value;
75+
}
6176
}

src/Kernel/Types/_Boolean.php

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,22 @@ class _Boolean extends Type
1010
const TRUE = 'true';
1111
const FALSE = 'false';
1212

13-
public function __toString()
13+
public static function isValid($value)
1414
{
15-
$value = (int) $this->getValue();
16-
return $value === 1
15+
return $value == 0 ||
16+
$value == 1 ||
17+
$value === true ||
18+
$value === false;
19+
}
20+
21+
protected static function filter($value)
22+
{
23+
return $value ? true : false;
24+
}
25+
26+
public function getValue()
27+
{
28+
return $this->value
1729
? static::TRUE
1830
: static::FALSE;
1931
}

src/Kernel/Types/_Byte.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,21 @@ class _Byte extends Type
66
{
77
protected $nameInJava = 'byte';
88
protected $nameInPHP = 'int';
9+
10+
const MIN = -128;
11+
const MAX = 127;
12+
13+
public static function isValid($value)
14+
{
15+
if (!ctype_digit((string) abs($value))) {
16+
return false;
17+
}
18+
19+
return $value >= static::MIN && $value <= static::MAX;
20+
}
21+
22+
protected static function filter($value)
23+
{
24+
return (int) $value;
25+
}
926
}

src/Kernel/Types/_Char.php

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,27 @@ class _Char extends Type
77
protected $nameInJava = 'char';
88
protected $nameInPHP = 'string';
99

10-
public function __toString()
10+
const MIN = 0;
11+
const MAX = 65535;
12+
13+
public static function isValid($value)
14+
{
15+
if (ctype_alpha($value) && strlen($value) === 1) {
16+
$value = ord($value);
17+
}
18+
19+
if (!ctype_digit((string) abs($value))) {
20+
return false;
21+
}
22+
23+
return $value >= static::MIN && $value <= static::MAX;
24+
}
25+
26+
protected static function filter($value)
1127
{
12-
$value = $this->getValue();
13-
return ctype_digit($value)
14-
? chr($value)
15-
: $value;
28+
if (ctype_alpha($value) && strlen($value) === 1) {
29+
return $value;
30+
}
31+
return chr($value);
1632
}
1733
}

src/Kernel/Types/_Double.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,32 @@
22

33
namespace PHPJava\Kernel\Types;
44

5+
use Brick\Math\BigDecimal;
6+
57
class _Double extends Type
68
{
79
protected $nameInJava = 'double';
810
protected $nameInPHP = 'float';
11+
12+
const MIN = '4.9E-324';
13+
const MAX = '1.7976931348623157E308';
14+
15+
public static function isValid($value)
16+
{
17+
if (!is_numeric((string) abs($value))) {
18+
return false;
19+
}
20+
21+
$value = BigDecimal::of($value)->abs();
22+
23+
return $value->isEqualTo('0') || (
24+
$value->isGreaterThan(static::MIN) &&
25+
$value->isLessThan(static::MAX)
26+
);
27+
}
28+
29+
protected static function filter($value)
30+
{
31+
return (string) $value;
32+
}
933
}

src/Kernel/Types/_Float.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,22 @@ class _Float extends Type
66
{
77
protected $nameInJava = 'float';
88
protected $nameInPHP = 'float';
9+
10+
const MIN = 1.4E-45;
11+
const MAX = 3.4028235E38;
12+
13+
public static function isValid($value)
14+
{
15+
$value = (string) abs($value);
16+
if (!is_numeric($value)) {
17+
return false;
18+
}
19+
20+
return $value == 0 || ($value >= static::MIN && $value <= static::MAX);
21+
}
22+
23+
protected static function filter($value)
24+
{
25+
return (float) $value;
26+
}
927
}

src/Kernel/Types/_Int.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,30 @@ class _Int extends Type
66
{
77
protected $nameInJava = 'int';
88
protected $nameInPHP = 'integer';
9+
10+
const MIN = -2147483648;
11+
const MAX = 2147483647;
12+
13+
public static function isValid($value)
14+
{
15+
if (ctype_alpha($value) && strlen($value) === 1) {
16+
$value = ord($value);
17+
}
18+
19+
$value = ($value << 32) >> 32;
20+
if (!ctype_digit((string) abs($value))) {
21+
return false;
22+
}
23+
24+
return $value >= static::MIN && $value <= static::MAX;
25+
}
26+
27+
protected static function filter($value)
28+
{
29+
if (ctype_alpha($value) && strlen($value) === 1) {
30+
return ord($value);
31+
}
32+
33+
return ($value << 32) >> 32;
34+
}
935
}

src/Kernel/Types/_Long.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,20 @@ class _Long extends Type
66
{
77
protected $nameInJava = 'long';
88
protected $nameInPHP = 'integer';
9+
10+
const MIN = -9223372036854775808;
11+
const MAX = 9223372036854775807;
12+
13+
public static function isValid($value)
14+
{
15+
if (!ctype_digit((string) abs($value))) {
16+
return false;
17+
}
18+
return $value >= static::MIN && $value <= static::MAX;
19+
}
20+
21+
protected static function filter($value)
22+
{
23+
return (int) $value;
24+
}
925
}

src/Kernel/Types/_Short.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,19 @@ class _Short extends Type
66
{
77
protected $nameInJava = 'short';
88
protected $nameInPHP = 'integer';
9+
10+
const MIN = -32768;
11+
const MAX = 32767;
12+
13+
public static function isValid($value)
14+
{
15+
return ctype_digit((string) abs($value)) &&
16+
$value >= static::MIN &&
17+
$value <= static::MAX;
18+
}
19+
20+
protected static function filter($value)
21+
{
22+
return (int) $value;
23+
}
924
}

tests/BigNumberCalculationTest.php

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,43 +23,43 @@ public function testAdd()
2323
{
2424
$result = $this->call(
2525
explode('::', __METHOD__)[1],
26-
_Long::get(PHP_INT_MAX),
27-
_Long::get(PHP_INT_MAX)
26+
_Long::get(PHP_INT_MAX - 1),
27+
_Long::get(1)
2828
);
2929

30-
$this->assertEquals('18446744073709551614', (string) $result);
30+
$this->assertEquals('9223372036854775807', (string) $result);
3131
}
3232

3333
public function testSub()
3434
{
3535
$result = $this->call(
3636
explode('::', __METHOD__)[1],
37-
_Long::get((string) BigInteger::of(PHP_INT_MAX)->multipliedBy(2)),
38-
_Long::get(PHP_INT_MAX)
37+
_Long::get((string) BigInteger::of(PHP_INT_MAX)),
38+
_Long::get(1)
3939
);
4040

41-
$this->assertEquals('9223372036854775807', (string) $result);
41+
$this->assertEquals('9223372036854775806', (string) $result);
4242
}
4343

4444
public function testMul()
4545
{
4646
$result = $this->call(
4747
explode('::', __METHOD__)[1],
48-
_Long::get(PHP_INT_MAX),
48+
_Long::get(2147483647),
4949
_Long::get(3)
5050
);
5151

52-
$this->assertEquals('27670116110564327421', (string) $result);
52+
$this->assertEquals('6442450941', (string) $result);
5353
}
5454

5555
public function testDiv()
5656
{
5757
$result = $this->call(
5858
explode('::', __METHOD__)[1],
59-
_Long::get((string) BigInteger::of(PHP_INT_MAX)->multipliedBy(2)),
60-
_Long::get(2)
59+
_Long::get(6442450947),
60+
_Long::get(2147483649)
6161
);
6262

63-
$this->assertEquals('9223372036854775807', (string) $result);
63+
$this->assertEquals('3', (string) $result);
6464
}
6565
}

0 commit comments

Comments
 (0)