Blame view

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