Code

* Created "old" branch and moved stuff
[gosa.git] / branches / old / gosa-core / include / utils / excel / class.writeexcel_biffwriter.inc.php
diff --git a/branches/old/gosa-core/include/utils/excel/class.writeexcel_biffwriter.inc.php b/branches/old/gosa-core/include/utils/excel/class.writeexcel_biffwriter.inc.php
new file mode 100644 (file)
index 0000000..d9c0d41
--- /dev/null
@@ -0,0 +1,208 @@
+<?php
+
+/*
+ * Copyleft 2002 Johann Hanne
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place,
+ * Suite 330, Boston, MA  02111-1307 USA
+ */
+
+/*
+ * This is the Spreadsheet::WriteExcel Perl package ported to PHP
+ * Spreadsheet::WriteExcel was written by John McNamara, jmcnamara@cpan.org
+ */
+
+class writeexcel_biffwriter {
+    var $byte_order;
+    var $BIFF_version;
+    var $_byte_order;
+    var $_data;
+    var $_datasize;
+    var $_limit;
+
+    /*
+     * Constructor
+     */
+    function writeexcel_biffwriter() {
+
+        $this->byte_order   = '';
+        $this->BIFF_version = 0x0500;
+        $this->_byte_order  = '';
+        $this->_data        = false;
+        $this->_datasize    = 0;
+        $this->_limit       = 2080;
+
+        $this->_set_byte_order();
+    }
+
+    /*
+     * Determine the byte order and store it as class data to avoid
+     * recalculating it for each call to new().
+     */
+    function _set_byte_order() {
+        $this->byteorder=0;
+        // Check if "pack" gives the required IEEE 64bit float
+        $teststr = pack("d", 1.2345);
+        $number  = pack("C8", 0x8D, 0x97, 0x6E, 0x12, 0x83, 0xC0, 0xF3, 0x3F);
+
+        if ($number == $teststr) {
+            $this->byte_order = 0; // Little Endian
+        } elseif ($number == strrev($teststr)) {
+            $this->byte_order = 1; // Big Endian
+        } else {
+            // Give up
+            trigger_error("Required floating point format not supported ".
+                          "on this platform. See the portability section ".
+                          "of the documentation.", E_USER_ERROR);
+        }
+
+        $this->_byte_order = $this->byte_order;
+    }
+
+    /*
+     * General storage function
+     */
+    function _prepend($data) {
+
+        if (func_num_args()>1) {
+            trigger_error("writeexcel_biffwriter::_prepend() ".
+                          "called with more than one argument", E_USER_ERROR);
+        }
+
+        if ($this->_debug) {
+            print "*** writeexcel_biffwriter::_prepend() called:";
+            for ($c=0;$c<strlen($data);$c++) {
+                if ($c%16==0) {
+                    print "\n";
+                }
+                printf("%02X ", ord($data[$c]));
+            }
+            print "\n";
+        }
+
+        if (strlen($data) > $this->_limit) {
+            $data = $this->_add_continue($data);
+        }
+
+        $this->_data      = $data . $this->_data;
+        $this->_datasize += strlen($data);
+    }
+
+    /*
+     * General storage function
+     */
+    function _append($data) {
+
+        if (func_num_args()>1) {
+            trigger_error("writeexcel_biffwriter::_append() ".
+                          "called with more than one argument", E_USER_ERROR);
+        }
+
+        if ($this->_debug) {
+            print "*** writeexcel_biffwriter::_append() called:";
+            for ($c=0;$c<strlen($data);$c++) {
+                if ($c%16==0) {
+                    print "\n";
+                }
+                printf("%02X ", ord($data[$c]));
+            }
+            print "\n";
+        }
+
+        if (strlen($data) > $this->_limit) {
+            $data = $this->_add_continue($data);
+        }
+
+        $this->_data      = $this->_data . $data;
+        $this->_datasize += strlen($data);
+    }
+
+    /*
+     * Writes Excel BOF record to indicate the beginning of a stream or
+     * sub-stream in the BIFF file.
+     *
+     * $type = 0x0005, Workbook
+     * $type = 0x0010, Worksheet
+     */
+    function _store_bof($type) {
+
+        $record  = 0x0809; // Record identifier
+        $length  = 0x0008; // Number of bytes to follow
+
+        $version = $this->BIFF_version;
+
+        // According to the SDK $build and $year should be set to zero.
+        // However, this throws a warning in Excel 5. So, use these
+        // magic numbers.
+        $build  = 0x096C;
+        $year   = 0x07C9;
+
+        $header = pack("vv",   $record, $length);
+        $data   = pack("vvvv", $version, $type, $build, $year);
+
+        $this->_prepend($header . $data);
+    }
+
+    /*
+     * Writes Excel EOF record to indicate the end of a BIFF stream.
+     */
+    function _store_eof() {
+
+        $record = 0x000A; // Record identifier
+        $length = 0x0000; // Number of bytes to follow
+
+        $header = pack("vv", $record, $length);
+
+        $this->_append($header);
+    }
+
+    /*
+     * Excel limits the size of BIFF records. In Excel 5 the limit is 2084
+     * bytes. In Excel 97 the limit is 8228 bytes. Records that are longer
+     * than these limits must be split up into CONTINUE blocks.
+     *
+     * This function take a long BIFF record and inserts CONTINUE records as
+     * necessary.
+     */
+    function _add_continue($data) {
+
+        $limit  = $this->_limit;
+        $record = 0x003C; // Record identifier
+
+        // The first 2080/8224 bytes remain intact. However, we have to change
+        // the length field of the record.
+        $tmp = substr($data, 0, $limit);
+        $data = substr($data, $limit);
+        $tmp = substr($tmp, 0, 2) . pack ("v", $limit-4) . substr($tmp, 4);
+
+        // Strip out chunks of 2080/8224 bytes +4 for the header.
+        while (strlen($data) > $limit) {
+            $header  = pack("vv", $record, $limit);
+            $tmp    .= $header;
+            $tmp    .= substr($data, 0, $limit);
+            $data    = substr($data, $limit);
+        }
+
+        // Mop up the last of the data
+        $header  = pack("vv", $record, strlen($data));
+        $tmp    .= $header;
+        $tmp    .= $data;
+
+        return $tmp;
+    }
+
+}
+
+?>