Updating functions_datastore.php
[bugdar.git] / includes / class_mo.php
1 <?php
2 /*=====================================================================*\
3 || ###################################################################
4 || # Bugdar
5 || # Copyright ©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 $this->file = @fopen($this->filename, 'r');
114 if (!$this->file)
115 {
116 BSApp::debug("could not open MO file {$this->filename}");
117 return;
118 }
119
120 // read the magic number
121 $stream = $this->_readBytes(1);
122 $stream = dechex($stream[1]);
123 if ($stream == '950412de')
124 {
125 $this->bigEndian = false;
126 }
127 else if ($stream == 'de120495')
128 {
129 $this->bigEndian = true;
130 }
131 else
132 {
133 throw new Exception('Invalid MO file format');
134 }
135
136 // read the revision (unused in MOs)
137 $this->_readBytes(1);
138
139 // read the number of strings
140 $count = $this->_readBytes(1);
141 $count = $count[1];
142
143 // get the start positions of the original and translated tables
144 $offsetO = $this->_readBytes(1);
145 $offsetT = $this->_readBytes(1);
146
147 fseek($this->file, $offsetO[1]);
148 $tableO = $this->_readBytes(2 * $count);
149 fseek($this->file, $offsetT[1]);
150 $tableT = $this->_readBytes(2 * $count);
151
152 for ($i = 0; $i < $count; $i++)
153 {
154 if ($tableO[$i * 2 + 1] > 0)
155 {
156 fseek($this->file, $tableO[$i * 2 + 2]);
157 $O = fread($this->file, $tableO[$i * 2 + 1]);
158 }
159
160 if ($tableT[$i * 2 + 1] > 0)
161 {
162 fseek($this->file, $tableT[$i * 2 + 2]);
163 $this->strings[$O] = fread($this->file, $tableT[$i * 2 + 1]);
164 }
165 }
166
167 fclose($this->file);
168 }
169 }
170
171 /*=====================================================================*\
172 || ###################################################################
173 || # $HeadURL$
174 || # $Id$
175 || ###################################################################
176 \*=====================================================================*/
177 ?>