ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
Mo.php
Go to the documentation of this file.
1 <?php
2 
3 namespace Gettext\Extractors;
4 
5 use Exception;
8 
12 class Mo extends Extractor implements ExtractorInterface
13 {
14  const MAGIC1 = -1794895138;
15  const MAGIC2 = -569244523;
16  const MAGIC3 = 2500072158;
17 
21  public static function fromString($string, Translations $translations = null, $file = '')
22  {
23  if ($translations === null) {
24  $translations = new Translations();
25  }
26 
27  $stream = new StringReader($string);
28  $magic = self::readInt($stream, 'V');
29 
30  if (($magic === self::MAGIC1) || ($magic === self::MAGIC3)) { //to make sure it works for 64-bit platforms
31  $byteOrder = 'V'; //low endian
32  } elseif ($magic === (self::MAGIC2 & 0xFFFFFFFF)) {
33  $byteOrder = 'N'; //big endian
34  } else {
35  throw new Exception('Not MO file');
36  }
37 
38  self::readInt($stream, $byteOrder);
39 
40  $total = self::readInt($stream, $byteOrder); //total string count
41  $originals = self::readInt($stream, $byteOrder); //offset of original table
42  $tran = self::readInt($stream, $byteOrder); //offset of translation table
43 
44  $stream->seekto($originals);
45  $table_originals = self::readIntArray($stream, $byteOrder, $total * 2);
46 
47  $stream->seekto($tran);
48  $table_translations = self::readIntArray($stream, $byteOrder, $total * 2);
49 
50  for ($i = 0; $i < $total; ++$i) {
51  $next = $i * 2;
52 
53  $stream->seekto($table_originals[$next + 2]);
54  $original = $stream->read($table_originals[$next + 1]);
55 
56  $stream->seekto($table_translations[$next + 2]);
57  $translated = $stream->read($table_translations[$next + 1]);
58 
59  if ($original === '') {
60  // Headers
61  foreach (explode("\n", $translated) as $headerLine) {
62  if ($headerLine === '') {
63  continue;
64  }
65 
66  $headerChunks = preg_split('/:\s*/', $headerLine, 2);
67  $translations->setHeader($headerChunks[0], isset($headerChunks[1]) ? $headerChunks[1] : '');
68  }
69 
70  continue;
71  }
72 
73  $chunks = explode("\x04", $original, 2);
74 
75  if (isset($chunks[1])) {
76  $context = $chunks[0];
77  $original = $chunks[1];
78  } else {
79  $context = '';
80  }
81 
82  $chunks = explode("\x00", $original, 2);
83 
84  if (isset($chunks[1])) {
85  $original = $chunks[0];
86  $plural = $chunks[1];
87  } else {
88  $plural = '';
89  }
90 
91  $translation = $translations->insert($context, $original, $plural);
92 
93  if ($translated === '') {
94  continue;
95  }
96 
97  if ($plural === '') {
98  $translation->setTranslation($translated);
99  continue;
100  }
101 
102  foreach (explode("\x00", $translated) as $pluralIndex => $pluralValue) {
103  if ($pluralIndex === 0) {
104  $translation->setTranslation($pluralValue);
105  } else {
106  $translation->setPluralTranslation($pluralValue, $pluralIndex - 1);
107  }
108  }
109  }
110 
111  return $translations;
112  }
113 
118  private static function readInt(StringReader $stream, $byteOrder)
119  {
120  if (($read = $stream->read(4)) === false) {
121  return false;
122  }
123 
124  $read = unpack($byteOrder, $read);
125 
126  return array_shift($read);
127  }
128 
134  private static function readIntArray(StringReader $stream, $byteOrder, $count)
135  {
136  return unpack($byteOrder.$count, $stream->read(4 * $count));
137  }
138 }
$context
Definition: webdav.php:25
$stream
PHP stream implementation.
Class to get gettext strings from .mo files.
Definition: Mo.php:12
static fromString($string, Translations $translations=null, $file='')
{Parses a string and append the translations found in the Translations instance.The file path to inse...
Definition: Mo.php:21
$total
Definition: Utf8Test.php:87
read($bytes)
Read and returns a part of the string.
static readInt(StringReader $stream, $byteOrder)
Definition: Mo.php:118
Class to manage a collection of translations.
$i
Definition: disco.tpl.php:19
static readIntArray(StringReader $stream, $byteOrder, $count)
Definition: Mo.php:134