Advertisement
Guest User

Untitled

a guest
Nov 10th, 2013
183
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 5.75 KB | None | 0 0
  1.     function _storeSharedStringsTable()
  2.     {
  3.         $record  = 0x00fc;  // Record identifier
  4.         $length  = 0x0008;  // Number of bytes to follow
  5.         $total   = 0x0000;
  6.  
  7.         // Iterate through the strings to calculate the CONTINUE block sizes
  8.         $continue_limit = 8208;
  9.         $block_length   = 0;
  10.         $written        = 0;
  11.         $continue       = 0;
  12.  
  13.         // sizes are upside down
  14.         $tmp_block_sizes = $this->_block_sizes;
  15.         // $tmp_block_sizes = array_reverse($this->_block_sizes);
  16.  
  17.         // The SST record is required even if it contains no strings. Thus we will
  18.         // always have a length
  19.         //
  20.         if (!empty($tmp_block_sizes)) {
  21.             $length = 8 + array_shift($tmp_block_sizes);
  22.         }
  23.         else {
  24.             // No strings
  25.             $length = 8;
  26.         }
  27.  
  28.  
  29.  
  30.         // Write the SST block header information
  31.         $header      = pack("vv", $record, $length);
  32.         $data        = pack("VV", $this->_str_total, $this->_str_unique);
  33.         $this->_append($header . $data);
  34.  
  35.  
  36.  
  37.  
  38.         /* TODO: not good for performance */
  39.         foreach (array_keys($this->_str_table) as $string) {
  40.  
  41.             $string_length = strlen($string);
  42.             $headerinfo    = unpack("vlength/Cencoding", $string);
  43.             $encoding      = $headerinfo["encoding"];
  44.             $split_string  = 0;
  45.  
  46.             // Block length is the total length of the strings that will be
  47.             // written out in a single SST or CONTINUE block.
  48.             //
  49.             $block_length += $string_length;
  50.  
  51.  
  52.             // We can write the string if it doesn't cross a CONTINUE boundary
  53.             if ($block_length < $continue_limit) {
  54.                 $this->_append($string);
  55.                 $written += $string_length;
  56.                 continue;
  57.             }
  58.  
  59.             // Deal with the cases where the next string to be written will exceed
  60.             // the CONTINUE boundary. If the string is very long it may need to be
  61.             // written in more than one CONTINUE record.
  62.             //
  63.             while ($block_length >= $continue_limit) {
  64.  
  65.                 // We need to avoid the case where a string is continued in the first
  66.                 // n bytes that contain the string header information.
  67.                 //
  68.                 $header_length   = 3; // Min string + header size -1
  69.                 $space_remaining = $continue_limit - $written - $continue;
  70.  
  71.  
  72.                 // Unicode data should only be split on char (2 byte) boundaries.
  73.                 // Therefore, in some cases we need to reduce the amount of available
  74.                 // space by 1 byte to ensure the correct alignment.
  75.                 $align = 0;
  76.  
  77.                 // Only applies to Unicode strings
  78.                 if ($encoding == 1) {
  79.                     // Min string + header size -1
  80.                     $header_length = 4;
  81.  
  82.                     if ($space_remaining > $header_length) {
  83.                         // String contains 3 byte header => split on odd boundary
  84.                         if (!$split_string && $space_remaining % 2 != 1) {
  85.                             $space_remaining--;
  86.                             $align = 1;
  87.                         }
  88.                         // Split section without header => split on even boundary
  89.                         else if ($split_string && $space_remaining % 2 == 1) {
  90.                             $space_remaining--;
  91.                             $align = 1;
  92.                         }
  93.  
  94.                         $split_string = 1;
  95.                     }
  96.                 }
  97.  
  98.  
  99.                 if ($space_remaining > $header_length) {
  100.                     // Write as much as possible of the string in the current block
  101.                     $tmp = substr($string, 0, $space_remaining);
  102.                     $this->_append($tmp);
  103.  
  104.                     // The remainder will be written in the next block(s)
  105.                     $string = substr($string, $space_remaining);
  106.  
  107.                     // Reduce the current block length by the amount written
  108.                     $block_length -= $continue_limit - $continue - $align;
  109.  
  110.                     // If the current string was split then the next CONTINUE block
  111.                     // should have the string continue flag (grbit) set unless the
  112.                     // split string fits exactly into the remaining space.
  113.                     //
  114.                     if ($block_length > 0) {
  115.                         $continue = 1;
  116.                     } else {
  117.                         $continue = 0;
  118.                     }
  119.                 } else {
  120.                     // Not enough space to start the string in the current block
  121.                     $block_length -= $continue_limit - $space_remaining - $continue;
  122.                     $continue = 0;
  123.                 }
  124.  
  125.                 // Write the CONTINUE block header
  126.                 if (!empty($this->_block_sizes)) {
  127.                     $record  = 0x003C;
  128.                     $length  = array_shift($tmp_block_sizes);
  129.  
  130.                     $header  = pack('vv', $record, $length);
  131.                     if ($continue) {
  132.                         $header .= pack('C', $encoding);
  133.                     }
  134.                     $this->_append($header);
  135.                 }
  136.  
  137.                 // If the string (or substr) is small enough we can write it in the
  138.                 // new CONTINUE block. Else, go through the loop again to write it in
  139.                 // one or more CONTINUE blocks
  140.                 //
  141.                 if ($block_length < $continue_limit) {
  142.                     $this->_append($string);
  143.                     $written = $block_length;
  144.                 } else {
  145.                     $written = 0;
  146.                 }
  147.             }
  148.         }
  149.     }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement