Source of file Gettext.php
Size: 5,905 Bytes - Last Modified: 2014-03-12T23:21:18+01:00
/home/theseer/Downloads/ZendFramework-2.3.0/library/Zend/I18n/Translator/Loader/Gettext.php
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190 | <?php /** * Zend Framework (http://framework.zend.com/) * * @link http://github.com/zendframework/zf2 for the canonical source repository * @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com) * @license http://framework.zend.com/license/new-bsd New BSD License */ namespace Zend\I18n\Translator\Loader; use Zend\I18n\Exception; use Zend\I18n\Translator\Plural\Rule as PluralRule; use Zend\I18n\Translator\TextDomain; use Zend\Stdlib\ErrorHandler; /** * Gettext loader. */ class Gettext extends AbstractFileLoader { /** * Current file pointer. * * @var resource */ protected $file; /** * Whether the current file is little endian. * * @var bool */ protected $littleEndian; /** * load(): defined by FileLoaderInterface. * * @see FileLoaderInterface::load() * @param string $locale * @param string $filename * @return TextDomain * @throws Exception\InvalidArgumentException */ public function load($locale, $filename) { $resolvedFile = $this->resolveFile($filename); if (!$resolvedFile) { throw new Exception\InvalidArgumentException(sprintf( 'Could not find or open file %s for reading', $filename )); } $textDomain = new TextDomain(); ErrorHandler::start(); $this->file = fopen($resolvedFile, 'rb'); $error = ErrorHandler::stop(); if (false === $this->file) { throw new Exception\InvalidArgumentException(sprintf( 'Could not open file %s for reading', $filename ), 0, $error); } // Verify magic number $magic = fread($this->file, 4); if ($magic == "\x95\x04\x12\xde") { $this->littleEndian = false; } elseif ($magic == "\xde\x12\x04\x95") { $this->littleEndian = true; } else { fclose($this->file); throw new Exception\InvalidArgumentException(sprintf( '%s is not a valid gettext file', $filename )); } // Verify major revision (only 0 and 1 supported) $majorRevision = ($this->readInteger() >> 16); if ($majorRevision !== 0 && $majorRevision !== 1) { fclose($this->file); throw new Exception\InvalidArgumentException(sprintf( '%s has an unknown major revision', $filename )); } // Gather main information $numStrings = $this->readInteger(); $originalStringTableOffset = $this->readInteger(); $translationStringTableOffset = $this->readInteger(); // Usually there follow size and offset of the hash table, but we have // no need for it, so we skip them. fseek($this->file, $originalStringTableOffset); $originalStringTable = $this->readIntegerList(2 * $numStrings); fseek($this->file, $translationStringTableOffset); $translationStringTable = $this->readIntegerList(2 * $numStrings); // Read in all translations for ($current = 0; $current < $numStrings; $current++) { $sizeKey = $current * 2 + 1; $offsetKey = $current * 2 + 2; $originalStringSize = $originalStringTable[$sizeKey]; $originalStringOffset = $originalStringTable[$offsetKey]; $translationStringSize = $translationStringTable[$sizeKey]; $translationStringOffset = $translationStringTable[$offsetKey]; $originalString = array(''); if ($originalStringSize > 0) { fseek($this->file, $originalStringOffset); $originalString = explode("\0", fread($this->file, $originalStringSize)); } if ($translationStringSize > 0) { fseek($this->file, $translationStringOffset); $translationString = explode("\0", fread($this->file, $translationStringSize)); if (count($originalString) > 1 && count($translationString) > 1) { $textDomain[$originalString[0]] = $translationString; array_shift($originalString); foreach ($originalString as $string) { $textDomain[$string] = ''; } } else { $textDomain[$originalString[0]] = $translationString[0]; } } } // Read header entries if (array_key_exists('', $textDomain)) { $rawHeaders = explode("\n", trim($textDomain[''])); foreach ($rawHeaders as $rawHeader) { list($header, $content) = explode(':', $rawHeader, 2); if (trim(strtolower($header)) === 'plural-forms') { $textDomain->setPluralRule(PluralRule::fromString($content)); } } unset($textDomain['']); } fclose($this->file); return $textDomain; } /** * Read a single integer from the current file. * * @return int */ protected function readInteger() { if ($this->littleEndian) { $result = unpack('Vint', fread($this->file, 4)); } else { $result = unpack('Nint', fread($this->file, 4)); } return $result['int']; } /** * Read an integer from the current file. * * @param int $num * @return int */ protected function readIntegerList($num) { if ($this->littleEndian) { return unpack('V' . $num, fread($this->file, 4 * $num)); } return unpack('N' . $num, fread($this->file, 4 * $num)); } } |