~canonical-sysadmins/wordpress/3.9.x

« back to all changes in this revision

Viewing changes to wp-includes/pomo/mo.php

  • Committer: Chris Jones
  • Date: 2010-01-19 13:17:33 UTC
  • Revision ID: cmsj@tenshu.net-20100119131733-rf31jv9k1v0xzo2h
[CJ] Import wordpress 2.9.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
/**
3
3
 * Class for working with MO files
4
4
 *
5
 
 * @version $Id: mo.php 106 2009-04-23 19:48:22Z nbachiyski $
 
5
 * @version $Id: mo.php 293 2009-11-12 15:43:50Z nbachiyski $
6
6
 * @package pomo
7
7
 * @subpackage mo
8
8
 */
10
10
require_once dirname(__FILE__) . '/translations.php';
11
11
require_once dirname(__FILE__) . '/streams.php';
12
12
 
 
13
if ( !class_exists( 'MO' ) ):
13
14
class MO extends Gettext_Translations {
14
15
 
15
16
        var $_nplurals = 2;
20
21
         * @param string $filename MO file to load
21
22
         */
22
23
        function import_from_file($filename) {
23
 
                $reader = new POMO_CachedIntFileReader($filename);
24
 
                if (isset($reader->error)) {
 
24
                $reader = new POMO_FileReader($filename);
 
25
                if (!$reader->is_resource())
25
26
                        return false;
26
 
                }
27
27
                return $this->import_from_reader($reader);
28
28
        }
29
29
        
95
95
        }
96
96
 
97
97
        function get_byteorder($magic) {
98
 
 
99
98
                // The magic is 0x950412de
100
99
 
101
100
                // bug in PHP 5.0.2, see https://savannah.nongnu.org/bugs/?func=detailitem&item_id=10565
102
101
                $magic_little = (int) - 1794895138;
103
102
                $magic_little_64 = (int) 2500072158;
104
103
                // 0xde120495
105
 
                $magic_big = ((int) - 569244523) && 0xFFFFFFFF;
106
 
                
 
104
                $magic_big = ((int) - 569244523) & 0xFFFFFFFF;
107
105
                if ($magic_little == $magic || $magic_little_64 == $magic) {
108
106
                        return 'little';
109
107
                } else if ($magic_big == $magic) {
114
112
        }
115
113
 
116
114
        function import_from_reader($reader) {
117
 
                $reader->setEndian('little');
118
 
                $endian = MO::get_byteorder($reader->readint32());
119
 
                if (false === $endian) {
 
115
                $endian_string = MO::get_byteorder($reader->readint32());
 
116
                if (false === $endian_string) {
120
117
                        return false;
121
118
                }
122
 
                $reader->setEndian($endian);
123
 
 
124
 
                $revision = $reader->readint32();
125
 
                $total = $reader->readint32();
126
 
                // get addresses of array of lenghts and offsets for original string and translations
127
 
                $originals_lenghts_addr = $reader->readint32();
128
 
                $translations_lenghts_addr = $reader->readint32();
129
 
 
 
119
                $reader->setEndian($endian_string);
 
120
 
 
121
                $endian = ('big' == $endian_string)? 'N' : 'V';
 
122
 
 
123
                $header = $reader->read(24);
 
124
                if ($reader->strlen($header) != 24)
 
125
                        return false;
 
126
 
 
127
                // parse header
 
128
                $header = unpack("{$endian}revision/{$endian}total/{$endian}originals_lenghts_addr/{$endian}translations_lenghts_addr/{$endian}hash_length/{$endian}hash_addr", $header);
 
129
                if (!is_array($header))
 
130
                        return false;
 
131
 
 
132
                extract( $header );
 
133
 
 
134
                // support revision 0 of MO format specs, only
 
135
                if ($revision != 0)
 
136
                        return false;
 
137
 
 
138
                // seek to data blocks
130
139
                $reader->seekto($originals_lenghts_addr);
131
 
                $originals_lenghts = $reader->readint32array($total * 2); // each of 
132
 
                $reader->seekto($translations_lenghts_addr);
133
 
                $translations_lenghts = $reader->readint32array($total * 2);
134
 
 
135
 
                $length = create_function('$i', 'return $i * 2 + 1;');
136
 
                $offset = create_function('$i', 'return $i * 2 + 2;');
137
 
 
138
 
                for ($i = 0; $i < $total; ++$i) {
139
 
                        $reader->seekto($originals_lenghts[$offset($i)]);
140
 
                        $original = $reader->read($originals_lenghts[$length($i)]);
141
 
                        $reader->seekto($translations_lenghts[$offset($i)]);
142
 
                        $translation = $reader->read($translations_lenghts[$length($i)]);
143
 
                        if ('' == $original) {
 
140
 
 
141
                // read originals' indices
 
142
                $originals_lengths_length = $translations_lenghts_addr - $originals_lenghts_addr;
 
143
                if ( $originals_lengths_length != $total * 8 )
 
144
                        return false;
 
145
 
 
146
                $originals = $reader->read($originals_lengths_length);
 
147
                if ( $reader->strlen( $originals ) != $originals_lengths_length )
 
148
                        return false;
 
149
 
 
150
                // read translations' indices
 
151
                $translations_lenghts_length = $hash_addr - $translations_lenghts_addr;
 
152
                if ( $translations_lenghts_length != $total * 8 )
 
153
                        return false;
 
154
 
 
155
                $translations = $reader->read($translations_lenghts_length);
 
156
                if ( $reader->strlen( $translations ) != $translations_lenghts_length )
 
157
                        return false;
 
158
 
 
159
                // transform raw data into set of indices
 
160
                $originals    = $reader->str_split( $originals, 8 );
 
161
                $translations = $reader->str_split( $translations, 8 );
 
162
 
 
163
                // skip hash table
 
164
                $strings_addr = $hash_addr + $hash_length * 4;
 
165
 
 
166
                $reader->seekto($strings_addr);
 
167
 
 
168
                $strings = $reader->read_all();
 
169
                $reader->close();
 
170
 
 
171
                for ( $i = 0; $i < $total; $i++ ) {
 
172
                        $o = unpack( "{$endian}length/{$endian}pos", $originals[$i] );
 
173
                        $t = unpack( "{$endian}length/{$endian}pos", $translations[$i] );
 
174
                        if ( !$o || !$t ) return false;
 
175
 
 
176
                        // adjust offset due to reading strings to separate space before
 
177
                        $o['pos'] -= $strings_addr;
 
178
                        $t['pos'] -= $strings_addr;
 
179
 
 
180
                        $original    = $reader->substr( $strings, $o['pos'], $o['length'] );
 
181
                        $translation = $reader->substr( $strings, $t['pos'], $t['length'] );
 
182
 
 
183
                        if ('' === $original) {
144
184
                                $this->set_headers($this->make_headers($translation));
145
185
                        } else {
146
 
                                $this->add_entry($this->make_entry($original, $translation));
 
186
                                $entry = &$this->make_entry($original, $translation);
 
187
                                $this->entries[$entry->key()] = &$entry;
147
188
                        }
148
189
                }
149
190
                return true;
150
191
        }
151
192
 
152
193
        /**
 
194
         * Build a Translation_Entry from original string and translation strings,
 
195
         * found in a MO file
 
196
         * 
153
197
         * @static
 
198
         * @param string $original original string to translate from MO file. Might contain
 
199
         *      0x04 as context separator or 0x00 as singular/plural separator
 
200
         * @param string $translation translation string from MO file. Might contain
 
201
         *      0x00 as a plural translations separator
154
202
         */
155
203
        function &make_entry($original, $translation) {
156
 
                $args = array();
 
204
                $entry = & new Translation_Entry();
157
205
                // look for context
158
206
                $parts = explode(chr(4), $original);
159
207
                if (isset($parts[1])) {
160
208
                        $original = $parts[1];
161
 
                        $args['context'] = $parts[0];
 
209
                        $entry->context = $parts[0];
162
210
                }
163
211
                // look for plural original
164
212
                $parts = explode(chr(0), $original);
165
 
                $args['singular'] = $parts[0];
 
213
                $entry->singular = $parts[0];
166
214
                if (isset($parts[1])) {
167
 
                        $args['plural'] = $parts[1];
 
215
                        $entry->is_plural = true;
 
216
                        $entry->plural = $parts[1];
168
217
                }
169
218
                // plural translations are also separated by \0
170
 
                $args['translations'] = explode(chr(0), $translation);
171
 
                $entry = & new Translation_Entry($args);
 
219
                $entry->translations = explode(chr(0), $translation);
172
220
                return $entry;
173
221
        }
174
222
 
179
227
        function get_plural_forms_count() {
180
228
                return $this->_nplurals;
181
229
        }
182
 
 
183
 
 
184
230
}
185
 
?>
 
231
endif;
 
 
b'\\ No newline at end of file'