Fix DB_MySQL_PDO::escape_binary().
[bugdar.git] / includes / class_mo.php
1 <?php
2 /*=====================================================================*\
3 || ###################################################################
4 || # Bugdar
5 || # Copyright (c)2002-2007 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 * @version $Revision$
32 * @package Bugdar
33 *
34 */
35 class MOReader
36 {
37 /**
38 * The name of the file to use
39 * @var string
40 */
41 var $filename;
42
43 /**
44 * The file pointer of the MO file
45 * @var resource
46 */
47 var $file = null;
48
49 /**
50 * Is the MO file a big endian one?
51 * @var boolean
52 */
53 var $bigEndian = false;
54
55 /**
56 * The string table as an array
57 * @var array
58 */
59 var $strings = array();
60
61 /**
62 * Creates a new MOReader given a path to a MO file
63 */
64 function MOReader($filename)
65 {
66 $this->filename = $filename;
67 $this->_loadFile();
68 }
69
70 /**
71 * Returns the translated string for T, or the original if none exists
72 *
73 * @param string Native string to look up a translation for
74 *
75 * @return string
76 */
77 function T($str)
78 {
79 if (empty($this->strings[$str]))
80 {
81 return $str;
82 }
83 return $this->strings[$str];
84 }
85
86 /**
87 * Reads $size number of bytes
88 *
89 * @param integer Number of bytes to read
90 *
91 * @return string
92 */
93 function _readBytes($size)
94 {
95 $stream = fread($this->file, 4 * $size);
96 if ($this->bigEndian)
97 {
98 return unpack('N' . $size, $stream);
99 }
100 else
101 {
102 return unpack('V' . $size, $stream);
103 }
104 }
105
106 /**
107 * Lodas the MO data information into the stirng table
108 */
109 function _loadFile()
110 {
111 global $bugsys;
112
113
114 if (!file_exists($this->filename))
115 {
116 $bugsys->debug("could not find MO file {$this->filename}");
117 return;
118 }
119
120 $this->file = fopen($this->filename, 'r');
121 if (!$this->file)
122 {
123 $bugsys->debug("could not open MO file {$this->filename}");
124 return;
125 }
126
127 // read the magic number
128 $stream = $this->_readBytes(1);
129 $stream = dechex($stream[1]);
130 if ($stream == '950412de')
131 {
132 $this->bigEndian = false;
133 }
134 else if ($stream == 'de120495')
135 {
136 $this->bigEndian = true;
137 }
138 else
139 {
140 trigger_error('Invalid MO file format');
141 }
142
143 // read the revision (unused in MOs)
144 $this->_readBytes(1);
145
146 // read the number of strings
147 $count = $this->_readBytes(1);
148 $count = $count[1];
149
150 // get the start positions of the original and translated tables
151 $offsetO = $this->_readBytes(1);
152 $offsetT = $this->_readBytes(1);
153
154 fseek($this->file, $offsetO[1]);
155 $tableO = $this->_readBytes(2 * $count);
156 fseek($this->file, $offsetT[1]);
157 $tableT = $this->_readBytes(2 * $count);
158
159 for ($i = 0; $i < $count; $i++)
160 {
161 if ($tableO[$i * 2 + 1] > 0)
162 {
163 fseek($this->file, $tableO[$i * 2 + 2]);
164 $O = fread($this->file, $tableO[$i * 2 + 1]);
165 }
166
167 if ($tableT[$i * 2 + 1] > 0)
168 {
169 fseek($this->file, $tableT[$i * 2 + 2]);
170 $this->strings[$O] = fread($this->file, $tableT[$i * 2 + 1]);
171 }
172 }
173
174 fclose($this->file);
175 }
176 }
177