ID3Helpers::syncSafeInteger()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 2
rs 10
1
<?php
2
/**
3
 * Class ID3Helpers
4
 *
5
 * @created      25.09.2018
6
 * @author       smiley <[email protected]>
7
 * @copyright    2018 smiley
8
 * @license      MIT
9
 */
10
11
namespace chillerlan\ID3Tag;
12
13
use DateInterval, DateTime, RuntimeException;
14
15
use function ord, pow, sprintf, str_replace, strlen;
16
17
use const PHP_INT_SIZE;
18
19
final class ID3Helpers{
20
21
	/**
22
	 *
23
	 */
24
	public static function syncSafeInteger(int $raw):int{
25
		return $raw & 0x0000007F | ($raw & 0x00007F00) >> 1 | ($raw & 0x007F0000) >> 2 | ($raw & 0x7F000000) >> 3;
26
	}
27
28
	/**
29
	 * @link https://github.com/JamesHeinrich/getID3/blob/ec929d85af7b6bc04c10175a37144cdec0f94c72/getid3/getid3.lib.php#L334
30
	 *
31
	 * @throws \Exception
32
	 */
33
	public static function bigEndian2Int(string $byteword, bool $syncsafe = null, bool $signed = null):?int{
34
		$intvalue    = 0;
35
		$bytewordlen = strlen($byteword);
36
37
		if($bytewordlen === 0){
38
			return null;
39
		}
40
41
		for($i = 0; $i < $bytewordlen; $i++){
42
43
			$intvalue += $syncsafe
44
				? (ord($byteword[$i]) & 0x7F) * pow(2, ($bytewordlen - 1 - $i) * 7) // disregard MSB, effectively 7-bit bytes
45
				: ord($byteword[$i]) * pow(256, ($bytewordlen - 1 - $i));
46
47
		}
48
49
		if($signed && !$syncsafe){
0 ignored issues
show
Bug Best Practice introduced by
The expression $syncsafe of type boolean|null is loosely compared to false; this is ambiguous if the boolean can be false. You might want to explicitly use !== null instead.

If an expression can have both false, and null as possible values. It is generally a good practice to always use strict comparison to clearly distinguish between those two values.

$a = canBeFalseAndNull();

// Instead of
if ( ! $a) { }

// Better use one of the explicit versions:
if ($a !== null) { }
if ($a !== false) { }
if ($a !== null && $a !== false) { }
Loading history...
50
51
			// syncsafe ints are not allowed to be signed
52
			if($bytewordlen <= PHP_INT_SIZE){
53
				$signMaskBit = 0x80 << (8 * ($bytewordlen - 1));
54
55
				if($intvalue & $signMaskBit){
56
					$intvalue = 0 - ($intvalue & ($signMaskBit - 1));
57
				}
58
			}
59
			else{
60
				throw new RuntimeException(
61
					sprintf('ERROR: Cannot have signed integers larger than %s bits %s', (8 * PHP_INT_SIZE), strlen($byteword))
62
				);
63
			}
64
		}
65
66
		return $intvalue;
67
	}
68
69
	/**
70
	 *
71
	 */
72
	public static function unsyncString(string $string):string{
73
		return str_replace("\xFF\x00", "\xFF", $string);
74
	}
75
76
	/**
77
	 *
78
	 */
79
	public static function formatTime(int $duration):string{
80
81
		$dt = (new DateTime)
82
			->add(new DateInterval('PT'.$duration.'S'))
83
			->diff(new DateTime)
84
		;
85
86
		$format = '%i:%s';
87
88
		if($dt->h > 0){
89
			$format = '%H:'.$format;
90
		}
91
92
		if($dt->h > 24){
93
			$format = '%D:'.$format;
94
		}
95
96
		return $dt->format($format);
97
	}
98
99
}
100