1<?php 2 3/* 4 * This file is part of the Symfony package. 5 * 6 * (c) Fabien Potencier <fabien@symfony.com> 7 * 8 * For the full copyright and license information, please view the LICENSE 9 * file that was distributed with this source code. 10 */ 11 12namespace Symfony\Component\Translation\Dumper; 13 14use Symfony\Component\Translation\MessageCatalogue; 15 16/** 17 * IcuResDumper generates an ICU ResourceBundle formatted string representation of a message catalogue. 18 * 19 * @author Stealth35 20 */ 21class IcuResFileDumper extends FileDumper 22{ 23 /** 24 * {@inheritdoc} 25 */ 26 protected $relativePathTemplate = '%domain%/%locale%.%extension%'; 27 28 /** 29 * {@inheritdoc} 30 */ 31 public function formatCatalogue(MessageCatalogue $messages, $domain, array $options = []) 32 { 33 $data = $indexes = $resources = ''; 34 35 foreach ($messages->all($domain) as $source => $target) { 36 $indexes .= pack('v', \strlen($data) + 28); 37 $data .= $source."\0"; 38 } 39 40 $data .= $this->writePadding($data); 41 42 $keyTop = $this->getPosition($data); 43 44 foreach ($messages->all($domain) as $source => $target) { 45 $resources .= pack('V', $this->getPosition($data)); 46 47 $data .= pack('V', \strlen($target)) 48 .mb_convert_encoding($target."\0", 'UTF-16LE', 'UTF-8') 49 .$this->writePadding($data) 50 ; 51 } 52 53 $resOffset = $this->getPosition($data); 54 55 $data .= pack('v', \count($messages->all($domain))) 56 .$indexes 57 .$this->writePadding($data) 58 .$resources 59 ; 60 61 $bundleTop = $this->getPosition($data); 62 63 $root = pack('V7', 64 $resOffset + (2 << 28), // Resource Offset + Resource Type 65 6, // Index length 66 $keyTop, // Index keys top 67 $bundleTop, // Index resources top 68 $bundleTop, // Index bundle top 69 \count($messages->all($domain)), // Index max table length 70 0 // Index attributes 71 ); 72 73 $header = pack('vC2v4C12@32', 74 32, // Header size 75 0xDA, 0x27, // Magic number 1 and 2 76 20, 0, 0, 2, // Rest of the header, ..., Size of a char 77 0x52, 0x65, 0x73, 0x42, // Data format identifier 78 1, 2, 0, 0, // Data version 79 1, 4, 0, 0 // Unicode version 80 ); 81 82 return $header.$root.$data; 83 } 84 85 private function writePadding(string $data): ?string 86 { 87 $padding = \strlen($data) % 4; 88 89 return $padding ? str_repeat("\xAA", 4 - $padding) : null; 90 } 91 92 private function getPosition(string $data) 93 { 94 return (\strlen($data) + 28) / 4; 95 } 96 97 /** 98 * {@inheritdoc} 99 */ 100 protected function getExtension() 101 { 102 return 'res'; 103 } 104} 105