-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmo2array.php
130 lines (100 loc) · 3.79 KB
/
mo2array.php
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
<?php
namespace xenocrat;
class mo2array {
const VERSION_MAJOR = 3;
const VERSION_MINOR = 4;
const VERSION_PATCH = 0;
const MO_MAGIC_WORD_BE = "950412de";
const MO_MAGIC_WORD_LE = "de120495";
const MO_SIZEOF_HEADER = 28;
public static function decode(
$mo,
$throw = false
): array|false {
if (!is_string($mo))
throw new \InvalidArgumentException(
"File must be supplied as a string."
);
$array = array();
$length = strlen($mo);
$big_endian = null;
if (self::MO_SIZEOF_HEADER > $length) {
if (!$throw)
return false;
throw new \RangeException(
"File does not contain MO data."
);
}
$id = unpack("H8magic", $mo);
if ($id["magic"] == self::MO_MAGIC_WORD_BE)
$big_endian = true;
if ($id["magic"] == self::MO_MAGIC_WORD_LE)
$big_endian = false;
# Neither magic word matches; not a valid .mo file.
if (!isset($big_endian)) {
if (!$throw)
return false;
throw new \RangeException(
"File does not contain MO data."
);
}
$unpack = ($big_endian) ?
"Nformat/Nnum/Nor/Ntr" :
"Vformat/Vnum/Vor/Vtr" ;
$mo_offset = unpack($unpack, $mo, 4);
$unpack = ($big_endian) ?
"Nlength/Noffset" :
"Vlength/Voffset" ;
for ($i = 0; $i < $mo_offset["num"]; $i++) {
$or_str_offset = $mo_offset["or"] + ($i * 8);
$tr_str_offset = $mo_offset["tr"] + ($i * 8);
if (($or_str_offset + 8) > $length) {
if (!$throw)
return false;
throw new \LengthException(
"File ended unexpectedly."
);
}
if (($tr_str_offset + 8) > $length) {
if (!$throw)
return false;
throw new \LengthException(
"File ended unexpectedly."
);
}
$or_str_meta = unpack($unpack, $mo, $or_str_offset);
$tr_str_meta = unpack($unpack, $mo, $tr_str_offset);
$or_str_end = $or_str_meta["offset"] + $or_str_meta["length"];
$tr_str_end = $tr_str_meta["offset"] + $tr_str_meta["length"];
if ($or_str_end > $length) {
if (!$throw)
return false;
throw new \LengthException(
"File ended unexpectedly."
);
}
if ($tr_str_end > $length) {
if (!$throw)
return false;
throw new \LengthException(
"File ended unexpectedly."
);
}
$or_str_data = substr(
$mo,
$or_str_meta["offset"],
$or_str_meta["length"]
);
$tr_str_data = substr(
$mo,
$tr_str_meta["offset"],
$tr_str_meta["length"]
);
# Discover null-separated plural forms.
$or_str_data = explode("\0", $or_str_data);
$tr_str_data = explode("\0", $tr_str_data);
$array[] = array($or_str_data, $tr_str_data);
}
return $array;
}
}