73 // headers' msgid is an empty string |
73 // headers' msgid is an empty string |
74 fwrite($fh, pack('VV', 0, $current_addr)); |
74 fwrite($fh, pack('VV', 0, $current_addr)); |
75 $current_addr++; |
75 $current_addr++; |
76 $originals_table = chr(0); |
76 $originals_table = chr(0); |
77 |
77 |
|
78 $reader = new POMO_Reader(); |
|
79 |
78 foreach($entries as $entry) { |
80 foreach($entries as $entry) { |
79 $originals_table .= $this->export_original($entry) . chr(0); |
81 $originals_table .= $this->export_original($entry) . chr(0); |
80 $length = strlen($this->export_original($entry)); |
82 $length = $reader->strlen($this->export_original($entry)); |
81 fwrite($fh, pack('VV', $length, $current_addr)); |
83 fwrite($fh, pack('VV', $length, $current_addr)); |
82 $current_addr += $length + 1; // account for the NULL byte after |
84 $current_addr += $length + 1; // account for the NULL byte after |
83 } |
85 } |
84 |
86 |
85 $exported_headers = $this->export_headers(); |
87 $exported_headers = $this->export_headers(); |
86 fwrite($fh, pack('VV', strlen($exported_headers), $current_addr)); |
88 fwrite($fh, pack('VV', $reader->strlen($exported_headers), $current_addr)); |
87 $current_addr += strlen($exported_headers) + 1; |
89 $current_addr += strlen($exported_headers) + 1; |
88 $translations_table = $exported_headers . chr(0); |
90 $translations_table = $exported_headers . chr(0); |
89 |
91 |
90 foreach($entries as $entry) { |
92 foreach($entries as $entry) { |
91 $translations_table .= $this->export_translations($entry) . chr(0); |
93 $translations_table .= $this->export_translations($entry) . chr(0); |
92 $length = strlen($this->export_translations($entry)); |
94 $length = $reader->strlen($this->export_translations($entry)); |
93 fwrite($fh, pack('VV', $length, $current_addr)); |
95 fwrite($fh, pack('VV', $length, $current_addr)); |
94 $current_addr += $length + 1; |
96 $current_addr += $length + 1; |
95 } |
97 } |
96 |
98 |
97 fwrite($fh, $originals_table); |
99 fwrite($fh, $originals_table); |
153 // parse header |
158 // parse header |
154 $header = unpack("{$endian}revision/{$endian}total/{$endian}originals_lenghts_addr/{$endian}translations_lenghts_addr/{$endian}hash_length/{$endian}hash_addr", $header); |
159 $header = unpack("{$endian}revision/{$endian}total/{$endian}originals_lenghts_addr/{$endian}translations_lenghts_addr/{$endian}hash_length/{$endian}hash_addr", $header); |
155 if (!is_array($header)) |
160 if (!is_array($header)) |
156 return false; |
161 return false; |
157 |
162 |
158 extract( $header ); |
|
159 |
|
160 // support revision 0 of MO format specs, only |
163 // support revision 0 of MO format specs, only |
161 if ($revision != 0) |
164 if ( $header['revision'] != 0 ) { |
162 return false; |
165 return false; |
|
166 } |
163 |
167 |
164 // seek to data blocks |
168 // seek to data blocks |
165 $reader->seekto($originals_lenghts_addr); |
169 $reader->seekto( $header['originals_lenghts_addr'] ); |
166 |
170 |
167 // read originals' indices |
171 // read originals' indices |
168 $originals_lengths_length = $translations_lenghts_addr - $originals_lenghts_addr; |
172 $originals_lengths_length = $header['translations_lenghts_addr'] - $header['originals_lenghts_addr']; |
169 if ( $originals_lengths_length != $total * 8 ) |
173 if ( $originals_lengths_length != $header['total'] * 8 ) { |
170 return false; |
174 return false; |
|
175 } |
171 |
176 |
172 $originals = $reader->read($originals_lengths_length); |
177 $originals = $reader->read($originals_lengths_length); |
173 if ( $reader->strlen( $originals ) != $originals_lengths_length ) |
178 if ( $reader->strlen( $originals ) != $originals_lengths_length ) { |
174 return false; |
179 return false; |
|
180 } |
175 |
181 |
176 // read translations' indices |
182 // read translations' indices |
177 $translations_lenghts_length = $hash_addr - $translations_lenghts_addr; |
183 $translations_lenghts_length = $header['hash_addr'] - $header['translations_lenghts_addr']; |
178 if ( $translations_lenghts_length != $total * 8 ) |
184 if ( $translations_lenghts_length != $header['total'] * 8 ) { |
179 return false; |
185 return false; |
|
186 } |
180 |
187 |
181 $translations = $reader->read($translations_lenghts_length); |
188 $translations = $reader->read($translations_lenghts_length); |
182 if ( $reader->strlen( $translations ) != $translations_lenghts_length ) |
189 if ( $reader->strlen( $translations ) != $translations_lenghts_length ) { |
183 return false; |
190 return false; |
|
191 } |
184 |
192 |
185 // transform raw data into set of indices |
193 // transform raw data into set of indices |
186 $originals = $reader->str_split( $originals, 8 ); |
194 $originals = $reader->str_split( $originals, 8 ); |
187 $translations = $reader->str_split( $translations, 8 ); |
195 $translations = $reader->str_split( $translations, 8 ); |
188 |
196 |
189 // skip hash table |
197 // skip hash table |
190 $strings_addr = $hash_addr + $hash_length * 4; |
198 $strings_addr = $header['hash_addr'] + $header['hash_length'] * 4; |
191 |
199 |
192 $reader->seekto($strings_addr); |
200 $reader->seekto($strings_addr); |
193 |
201 |
194 $strings = $reader->read_all(); |
202 $strings = $reader->read_all(); |
195 $reader->close(); |
203 $reader->close(); |
196 |
204 |
197 for ( $i = 0; $i < $total; $i++ ) { |
205 for ( $i = 0; $i < $header['total']; $i++ ) { |
198 $o = unpack( "{$endian}length/{$endian}pos", $originals[$i] ); |
206 $o = unpack( "{$endian}length/{$endian}pos", $originals[$i] ); |
199 $t = unpack( "{$endian}length/{$endian}pos", $translations[$i] ); |
207 $t = unpack( "{$endian}length/{$endian}pos", $translations[$i] ); |
200 if ( !$o || !$t ) return false; |
208 if ( !$o || !$t ) return false; |
201 |
209 |
202 // adjust offset due to reading strings to separate space before |
210 // adjust offset due to reading strings to separate space before |