- Update the copyright notices to use the correct year and not a non-ASCII symbol
[bugdar.git] / includes / class_mo.php
1 <?php
2 /*=====================================================================*\
3 || ###################################################################
4 || # Bugdar
5 || # Copyright (c)2004-2008 Blue Static
6 || #
7 || # This program is free software; you can redistribute it and/or modify
8 || # it under the terms of the GNU General Public License as published by
9 || # the Free Software Foundation; version 2 of the License.
10 || #
11 || # This program is distributed in the hope that it will be useful, but
12 || # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 || # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 || # more details.
15 || #
16 || # You should have received a copy of the GNU General Public License along
17 || # with this program; if not, write to the Free Software Foundation, Inc.,
18 || # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
19 || ###################################################################
20 \*=====================================================================*/
21
22 /**
23 * Message Object File Reader (.mo reader)
24 *
25 * Reads a MO file that is used by gettext but without needing the gettext
26 * extension. The format is detailed here:
27 * http://www.gnu.org/software/gettext/manual/html_node/MO-Files.html
28 *
29 * @author rsesek
30 * @copyright Copyright (c)2006 - 2008, Blue Static
31 * @package Bugdar
32 *
33 */
34 class MOReader
35 {
36 /**
37 * The name of the file to use
38 * @var string
39 */
40 var $filename;
41
42 /**
43 * The file pointer of the MO file
44 * @var resource
45 */
46 var $file = null;
47
48 /**
49 * Is the MO file a big endian one?
50 * @var boolean
51 */
52 var $bigEndian = false;
53
54 /**
55 * The string table as an array
56 * @var array
57 */
58 var $strings = array();
59
60 /**
61 * Creates a new MOReader given a path to a MO file
62 */
63 function MOReader($filename)
64 {
65 $this->filename = $filename;
66 $this->_loadFile();
67 }
68
69 /**
70 * Returns the translated string for T, or the original if none exists
71 *
72 * @param string Native string to look up a translation for
73 *
74 * @return string
75 */
76 function T($str)
77 {
78 if (empty($this->strings[$str]))
79 {
80 return $str;
81 }
82 return $this->strings[$str];
83 }
84
85 /**
86 * Reads $size number of bytes
87 *
88 * @param integer Number of bytes to read
89 *
90 * @return string
91 */
92 function _readBytes($size)
93 {
94 $stream = fread($this->file, 4 * $size);
95 if ($this->bigEndian)
96 {
97 return unpack('N' . $size, $stream);
98 }
99 else
100 {
101 return unpack('V' . $size, $stream);
102 }
103 }
104
105 /**
106 * Lodas the MO data information into the stirng table
107 */
108 function _loadFile()
109 {
110 $this->file = @fopen($this->filename, 'r');
111 if (!$this->file)
112 {
113 BSApp::debug("could not open MO file {$this->filename}");
114 return;
115 }
116
117 // read the magic number
118 $stream = $this->_readBytes(1);
119 $stream = dechex($stream[1]);
120 if ($stream == '950412de')
121 {
122 $this->bigEndian = false;
123 }
124 else if ($stream == 'de120495')
125 {
126 $this->bigEndian = true;
127 }
128 else
129 {
130 throw new Exception('Invalid MO file format');
131 }
132
133 // read the revision (unused in MOs)
134 $this->_readBytes(1);
135
136 // read the number of strings
137 $count = $this->_readBytes(1);
138 $count = $count[1];
139
140 // get the start positions of the original and translated tables
141 $offsetO = $this->_readBytes(1);
142 $offsetT = $this->_readBytes(1);
143
144 fseek($this->file, $offsetO[1]);
145 $tableO = $this->_readBytes(2 * $count);
146 fseek($this->file, $offsetT[1]);
147 $tableT = $this->_readBytes(2 * $count);
148
149 for ($i = 0; $i < $count; $i++)
150 {
151 if ($tableO[$i * 2 + 1] > 0)
152 {
153 fseek($this->file, $tableO[$i * 2 + 2]);
154 $O = fread($this->file, $tableO[$i * 2 + 1]);
155 }
156
157 if ($tableT[$i * 2 + 1] > 0)
158 {
159 fseek($this->file, $tableT[$i * 2 + 2]);
160 $this->strings[$O] = fread($this->file, $tableT[$i * 2 + 1]);
161 }
162 }
163
164 fclose($this->file);
165 }
166 }
167
168 ?>