Moving bugfixes from 2.3 to 2.4 and updated install languages for Denmark and Sweden.
[fa-stable.git] / reporting / includes / Workbook.php
index 56e4c483d6e37d40fdf036a088478cd4c6780b94..718bdb66343e1bec237c5d543d7ce6af309e799f 100644 (file)
@@ -102,7 +102,6 @@ define('SPREADSHEET_EXCEL_WRITER_EQ', "=");
 */
 define('SPREADSHEET_EXCEL_WRITER_NE', "<>");
 
-$encoding_string='';
 /**
 * Class for creating OLE streams for Excel Spreadsheets
 *
@@ -3118,7 +3117,7 @@ class Spreadsheet_Excel_Writer_Parser
     function _expression()
     {
         // If it's a string return a string node
-        if (ereg("^\"[^\"]{0,255}\"$", $this->_current_token)) {
+        if (preg_match("/^\"[^\"]{0,255}\"$/", $this->_current_token)) {
             $result = $this->_createTree($this->_current_token, '', '');
             $this->_advance();
             return $result;
@@ -4878,11 +4877,10 @@ class Spreadsheet_Excel_Writer_Worksheet extends Spreadsheet_Excel_Writer_BIFFwr
     */
     function setInputEncoding($encoding)
     {
-       global $encoding_string;
          if ($encoding != 'UTF-16LE' && !function_exists('iconv')) {
              die("Using an input encoding other than UTF-16LE requires PHP support for iconv");
          }
-         $this->_input_encoding = $encoding_string = $encoding;
+         $this->_input_encoding = $encoding;
     }
 
     /** added 2009-03-05 by Joe Hunt, FA for arabic languages */
@@ -7744,7 +7742,7 @@ class Spreadsheet_Excel_Writer_Workbook extends Spreadsheet_Excel_Writer_BIFFwri
 /*        
         if ($this->_BIFF_version == 0x0600)    // Tried to fix the correct handling here, with the
         {                                                                              // corrected specification from M$ - Joe Hunt 2009-03-08
-               global $encoding_string;
+               $encoding_string = $this->_input_encoding;
                if ($encoding_string == 'UTF-16LE')
                {
                    $strlen = function_exists('mb_strlen') ? mb_strlen($sheetname, 'UTF-16LE') : (strlen($sheetname) / 2);
@@ -8156,9 +8154,9 @@ class Spreadsheet_Excel_Writer_Workbook extends Spreadsheet_Excel_Writer_BIFFwri
            8228 : Maximum Excel97 block size
              -4 : Length of block header
              -8 : Length of additional SST header information
-         = 8216
+             -8 : Arbitrary number to keep within _add_continue() limit = 8208
         */
-        $continue_limit     = 8216;
+        $continue_limit     = 8208;
         $block_length       = 0;
         $written            = 0;
         $this->_block_sizes = array();
@@ -8166,6 +8164,9 @@ class Spreadsheet_Excel_Writer_Workbook extends Spreadsheet_Excel_Writer_BIFFwri
 
         foreach (array_keys($this->_str_table) as $string) {
             $string_length = strlen($string);
+            $headerinfo    = unpack("vlength/Cencoding", $string);
+            $encoding      = $headerinfo["encoding"];
+            $split_string  = 0;
 
             // Block length is the total length of the strings that will be
             // written out in a single SST or CONTINUE block.
@@ -8192,16 +8193,39 @@ class Spreadsheet_Excel_Writer_Workbook extends Spreadsheet_Excel_Writer_BIFFwri
                 boundaries. Therefore, in some cases we need to reduce the
                 amount of available
                 */
+                $align = 0;
+
+                // Only applies to Unicode strings
+                if ($encoding == 1) {
+                    // Min string + header size -1
+                    $header_length = 4;
+
+                    if ($space_remaining > $header_length) {
+                        // String contains 3 byte header => split on odd boundary
+                        if (!$split_string && $space_remaining % 2 != 1) {
+                            $space_remaining--;
+                            $align = 1;
+                        }
+                        // Split section without header => split on even boundary
+                        else if ($split_string && $space_remaining % 2 == 1) {
+                            $space_remaining--;
+                            $align = 1;
+                        }
+
+                        $split_string = 1;
+                    }
+                }
+
 
                 if ($space_remaining > $header_length) {
                     // Write as much as possible of the string in the current block
                     $written      += $space_remaining;
 
                     // Reduce the current block length by the amount written
-                    $block_length -= $continue_limit - $continue;
+                    $block_length -= $continue_limit - $continue - $align;
 
                     // Store the max size for this block
-                    $this->_block_sizes[] = $continue_limit;
+                    $this->_block_sizes[] = $continue_limit - $align;
 
                     // If the current string was split then the next CONTINUE block
                     // should have the string continue flag (grbit) set unless the
@@ -8243,13 +8267,19 @@ class Spreadsheet_Excel_Writer_Workbook extends Spreadsheet_Excel_Writer_BIFFwri
          This length is required to set the offsets in the BOUNDSHEET records since
          they must be written before the SST records
         */
-        $total_offset = array_sum($this->_block_sizes);
-        // SST information
-        $total_offset += 8;
-        if (!empty($this->_block_sizes)) {
-            $total_offset += (count($this->_block_sizes)) * 4; // add CONTINUE headers
+
+        $tmp_block_sizes = array();
+        $tmp_block_sizes = $this->_block_sizes;
+
+        $length  = 12;
+        if (!empty($tmp_block_sizes)) {
+            $length += array_shift($tmp_block_sizes); // SST
         }
-        return $total_offset;
+        while (!empty($tmp_block_sizes)) {
+            $length += 4 + array_shift($tmp_block_sizes); // CONTINUEs
+        }
+
+        return $length;
     }
 
     /**
@@ -8266,28 +8296,41 @@ class Spreadsheet_Excel_Writer_Workbook extends Spreadsheet_Excel_Writer_BIFFwri
     function _storeSharedStringsTable()
     {
         $record  = 0x00fc;  // Record identifier
-        // sizes are upside down
-        $this->_block_sizes = array_reverse($this->_block_sizes);
-        $length = array_pop($this->_block_sizes) + 8; // First block size plus SST information
-
-        // Write the SST block header information
-        $header      = pack("vv", $record, $length);
-        $data        = pack("VV", $this->_str_total, $this->_str_unique);
-        $this->_append($header . $data);
-
+        $length  = 0x0008;  // Number of bytes to follow
+        $total   = 0x0000;
 
         // Iterate through the strings to calculate the CONTINUE block sizes
-        $continue_limit = 8216;
+        $continue_limit = 8208;
         $block_length   = 0;
         $written        = 0;
         $continue       = 0;
 
+        // sizes are upside down
+        $tmp_block_sizes = $this->_block_sizes;
+        // $tmp_block_sizes = array_reverse($this->_block_sizes);
+
+        // The SST record is required even if it contains no strings. Thus we will
+        // always have a length
+        //
+        if (!empty($tmp_block_sizes)) {
+            $length = 8 + array_shift($tmp_block_sizes);
+        }
+        else {
+            // No strings
+            $length = 8;
+        }
+
+        // Write the SST block header information
+        $header      = pack("vv", $record, $length);
+        $data        = pack("VV", $this->_str_total, $this->_str_unique);
+        $this->_append($header . $data);
 
         /* TODO: not good for performance */
         foreach (array_keys($this->_str_table) as $string) {
 
             $string_length = strlen($string);
-            $encoding      = 0; // assume there are no Unicode strings
+            $headerinfo    = unpack("vlength/Cencoding", $string);
+            $encoding      = $headerinfo["encoding"];
             $split_string  = 0;
 
             // Block length is the total length of the strings that will be
@@ -8318,6 +8361,30 @@ class Spreadsheet_Excel_Writer_Workbook extends Spreadsheet_Excel_Writer_BIFFwri
 
                 // Unicode data should only be split on char (2 byte) boundaries.
                 // Therefore, in some cases we need to reduce the amount of available
+                // space by 1 byte to ensure the correct alignment.
+                $align = 0;
+
+                // Only applies to Unicode strings
+                if ($encoding == 1) {
+                    // Min string + header size -1
+                    $header_length = 4;
+
+                    if ($space_remaining > $header_length) {
+                        // String contains 3 byte header => split on odd boundary
+                        if (!$split_string && $space_remaining % 2 != 1) {
+                            $space_remaining--;
+                            $align = 1;
+                        }
+                        // Split section without header => split on even boundary
+                        else if ($split_string && $space_remaining % 2 == 1) {
+                            $space_remaining--;
+                            $align = 1;
+                        }
+
+                        $split_string = 1;
+                    }
+                }
+
 
                 if ($space_remaining > $header_length) {
                     // Write as much as possible of the string in the current block
@@ -8328,7 +8395,7 @@ class Spreadsheet_Excel_Writer_Workbook extends Spreadsheet_Excel_Writer_BIFFwri
                     $string = substr($string, $space_remaining);
 
                     // Reduce the current block length by the amount written
-                    $block_length -= $continue_limit - $continue;
+                    $block_length -= $continue_limit - $continue - $align;
 
                     // If the current string was split then the next CONTINUE block
                     // should have the string continue flag (grbit) set unless the
@@ -8348,7 +8415,8 @@ class Spreadsheet_Excel_Writer_Workbook extends Spreadsheet_Excel_Writer_BIFFwri
                 // Write the CONTINUE block header
                 if (!empty($this->_block_sizes)) {
                     $record  = 0x003C;
-                    $length  = array_pop($this->_block_sizes);
+                    $length  = array_shift($tmp_block_sizes);
+
                     $header  = pack('vv', $record, $length);
                     if ($continue) {
                         $header .= pack('C', $encoding);
@@ -8370,4 +8438,3 @@ class Spreadsheet_Excel_Writer_Workbook extends Spreadsheet_Excel_Writer_BIFFwri
         }
     }
 }
-?>