+ $endian_string = MO::get_byteorder($reader->readint32());
+ if (false === $endian_string) {
+ return false;
+ }
+ $reader->setEndian($endian_string);
+
+ $endian = ('big' == $endian_string)? 'N' : 'V';
+
+ $header = $reader->read(24);
+ if ($reader->strlen($header) != 24)
+ return false;
+
+ // parse header
+ $header = unpack("{$endian}revision/{$endian}total/{$endian}originals_lenghts_addr/{$endian}translations_lenghts_addr/{$endian}hash_length/{$endian}hash_addr", $header);
+ if (!is_array($header))
+ return false;
+
+ // support revision 0 of MO format specs, only
+ if ( $header['revision'] != 0 ) {
+ return false;
+ }
+
+ // seek to data blocks
+ $reader->seekto( $header['originals_lenghts_addr'] );
+
+ // read originals' indices
+ $originals_lengths_length = $header['translations_lenghts_addr'] - $header['originals_lenghts_addr'];
+ if ( $originals_lengths_length != $header['total'] * 8 ) {
+ return false;
+ }
+
+ $originals = $reader->read($originals_lengths_length);
+ if ( $reader->strlen( $originals ) != $originals_lengths_length ) {
+ return false;
+ }
+
+ // read translations' indices
+ $translations_lenghts_length = $header['hash_addr'] - $header['translations_lenghts_addr'];
+ if ( $translations_lenghts_length != $header['total'] * 8 ) {
+ return false;
+ }
+
+ $translations = $reader->read($translations_lenghts_length);
+ if ( $reader->strlen( $translations ) != $translations_lenghts_length ) {