Update rar Viewer.
authorMichael M Slusarz <slusarz@curecanti.org>
Wed, 12 Nov 2008 05:18:48 +0000 (22:18 -0700)
committerMichael M Slusarz <slusarz@curecanti.org>
Wed, 12 Nov 2008 05:18:48 +0000 (22:18 -0700)
framework/Mime/lib/Horde/Mime/Viewer/rar.php

index 37a031c..653dd6a 100644 (file)
 class Horde_Mime_Viewer_rar extends Horde_Mime_Viewer_Driver
 {
     /**
-     * Rar compression methods.
+     * Can this driver render various views?
      *
-     * @var array
+     * @var boolean
      */
-    protected $_methods = array(
-        0x30 => 'Store',
-        0x31 => 'Fastest',
-        0x32 => 'Fast',
-        0x33 => 'Normal',
-        0x34 => 'Good',
-        0x35 => 'Best'
+    protected $_capability = array(
+        'embedded' => false,
+        'full' => true,
+        'info' => false,
+        'inline' => true
     );
 
     /**
-     * Render out the currently set contents using rar.
+     * Return the full rendered version of the Horde_Mime_Part object.
      *
-     * @param array $params  Any parameters the Viewer may need.
-     *
-     * @return string  The rendered contents.
+     * @return array  See Horde_Mime_Viewer_Driver::render().
      */
-    public function render($params = array())
+    protected function _render()
     {
-        $contents = $this->mime_part->getContents();
-
-        /* Make sure this is a valid rar file. */
-        if ($this->checkRarData($contents) === false) {
-            return '<pre>' . _("This does not appear to be a valid rar archive.") . '</pre>';
-        }
+        $contents = $this->_mimepart->getContents();
 
-        require_once 'Horde/Text.php';
+        require_once 'Horde/Compress.php';
+        $rar = &Horde_Compress::factory('rar');
 
-        $rarData = $this->getRarData($contents);
+        $rarData = $this->decompress($contents);
+        if (is_a($rarData, 'PEAR_Error')) {
+            return array();
+        }
         $fileCount = count($rarData);
 
-        $text  = '<strong>' . htmlspecialchars(sprintf(_("Contents of \"%s\""), $this->mime_part->getName())) . ':</strong>' . "\n";
-        $text .= '<table><tr><td align="left"><tt><span class="fixed">';
-        $text .= Text::htmlAllSpaces(_("Archive Name") . ':  ' . $this->mime_part->getName()) . "\n";
-        $text .= Text::htmlAllSpaces(_("Archive File Size") . ': ' . strlen($contents) . ' bytes') . "\n";
-        $text .= Text::htmlAllSpaces(sprintf(ngettext("File Count: %d file", "File Count: %d files", $fileCount), $fileCount));
-        $text .= "\n\n";
-        $text .= Text::htmlAllSpaces(
-                     String::pad(_("File Name"),     50, ' ', STR_PAD_RIGHT) .
-                     String::pad(_("Attributes"),    10, ' ', STR_PAD_LEFT) .
-                     String::pad(_("Size"),          10, ' ', STR_PAD_LEFT) .
-                     String::pad(_("Modified Date"), 19, ' ', STR_PAD_LEFT) .
-                     String::pad(_("Method"),        10, ' ', STR_PAD_LEFT) .
-                     String::pad(_("Ratio"),         10, ' ', STR_PAD_LEFT)
-                 ) . "\n";
+        require_once 'Horde/Text.php';
 
-        $text .= str_repeat('-', 109) . "\n";
+        $text = '<strong>' . htmlspecialchars(sprintf(_("Contents of \"%s\""), $this->_mimepart->getName(true))) . ':</strong>' . "\n" .
+            '<table><tr><td align="left"><tt><span class="fixed">' .
+            Text::htmlAllSpaces(_("Archive Name") . ':  ' . $this->_mimepart->getName(true)) . "\n" .
+            Text::htmlAllSpaces(_("Archive File Size") . ': ' . strlen($contents) . ' bytes') . "\n" .
+            Text::htmlAllSpaces(sprintf(ngettext("File Count: %d file", "File Count: %d files", $fileCount), $fileCount)) .
+            "\n\n" .
+            Text::htmlAllSpaces(
+                String::pad(_("File Name"), 50, ' ', STR_PAD_RIGHT) .
+                String::pad(_("Attributes"), 10, ' ', STR_PAD_LEFT) .
+                String::pad(_("Size"), 10, ' ', STR_PAD_LEFT) .
+                String::pad(_("Modified Date"), 19, ' ', STR_PAD_LEFT) .
+                String::pad(_("Method"), 10, ' ', STR_PAD_LEFT) .
+                String::pad(_("Ratio"), 10, ' ', STR_PAD_LEFT)
+            ) . "\n" .
+            str_repeat('-', 109) . "\n";
 
         foreach ($rarData as $val) {
-            $ratio = (empty($val['size'])) ? 0 : 100 * ($val['csize'] / $val['size']);
-            $text .= Text::htmlAllSpaces(
-                         String::pad($val['name'], 50, ' ', STR_PAD_RIGHT) .
-                         String::pad($val['attr'], 10, ' ', STR_PAD_LEFT) .
-                         String::pad($val['size'], 10, ' ', STR_PAD_LEFT) .
-                         String::pad(strftime("%d-%b-%Y %H:%M", $val['date']), 19, ' ', STR_PAD_LEFT) .
-                         String::pad($val['method'], 10, ' ', STR_PAD_LEFT) .
-                         String::pad(sprintf("%1.1f%%", $ratio), 10, ' ', STR_PAD_LEFT)
-                     ) . "\n";
-        }
-
-        $text .= str_repeat('-', 106) . "\n";
-        $text .= '</span></tt></td></tr></table>';
-
-        return nl2br($text);
-    }
-
-    /**
-     * Returns the MIME type of this part.
-     *
-     * @return string  The MIME type of this part.
-     */
-    public function getType()
-    {
-        return 'text/html; charset=' . NLS::getCharset();
-    }
+            $ratio = empty($val['size'])
+                ? 0
+                : 100 * ($val['csize'] / $val['size']);
 
-    /**
-     * Checks to see if the data is a valid Rar archive.
-     *
-     * @param string &$data  The rar archive data.
-     *
-     * @return boolean  True if valid, false if invalid.
-     */
-    public function checkRarData(&$data)
-    {
-        $fileHeader = "\x52\x61\x72\x21\x1a\x07\x00";
-        if (strpos($data, $fileHeader) === false) {
-            return false;
-        } else {
-            return true;
-        }
-    }
-
-    /**
-     * Get the list of files/data from the rar archive.
-     *
-     * @param string &$data  The rar archive data.
-     *
-     * @return array  KEY: Position in RAR archive
-     *                VALUES: 'attr'    --  File attributes
-     *                        'date'    --  File modification time
-     *                        'csize'   --  Compressed file size
-     *                        'method'  --  Compression method
-     *                        'name'    --  Filename
-     *                        'size'    --  Original file size
-     */
-    public function getRarData(&$data)
-    {
-        $return_array = array();
-
-        $blockStart = strpos($data, "\x52\x61\x72\x21\x1a\x07\x00");
-        $position = $blockStart + 7;
-
-        while ($position < strlen($data)) {
-            $head_crc   = substr($data, $position + 0, 2);
-            $head_type  = ord(substr($data, $position + 2, 1));
-            $head_flags = unpack('vFlags', substr($data, $position + 3, 2));
-            $head_flags = $head_flags['Flags'];
-            $head_size  = unpack('vSize', substr($data, $position + 5, 2));
-            $head_size  = $head_size['Size'];
-
-            $position += 7;
-            $head_size -= 7;
-
-            switch ($head_type) {
-
-            case 0x73:
-                /* Archive header */
-                $position += $head_size;
-
-                break;
-
-            case 0x74:
-                $file = array();
-
-                /* File Header */
-                $info = unpack('VPacked/VUnpacked/COS/VCRC32/VTime/CVersion/CMethod/vLength/vAttrib', substr($data, $position));
-
-                $file['name'] = substr($data, $position + 25, $info['Length']);
-                $file['size'] = $info['Unpacked'];
-                $file['csize'] = $info['Packed'];
-
-                $file['date'] = mktime((($info['Time'] >> 11) & 0x1f),
-                                       (($info['Time'] >> 5) & 0x3f),
-                                       (($info['Time'] << 1) & 0x3e),
-                                       (($info['Time'] >> 21) & 0x07),
-                                       (($info['Time'] >> 16) & 0x1f),
-                                       ((($info['Time'] >> 25) & 0x7f) + 80));
-
-                $file['method'] = $this->_methods[$info['Method']];
-
-                $file['attr']  = '';
-                $file['attr'] .= ($info['Attrib'] & 0x10) ? 'D' : '-';
-                $file['attr'] .= ($info['Attrib'] & 0x20) ? 'A' : '-';
-                $file['attr'] .= ($info['Attrib'] & 0x03) ? 'S' : '-';
-                $file['attr'] .= ($info['Attrib'] & 0x02) ? 'H' : '-';
-                $file['attr'] .= ($info['Attrib'] & 0x01) ? 'R' : '-';
-
-                $return_array[] = $file;
-
-                $position += $head_size;
-                $position += $info['Packed'];
-                break;
-
-            default:
-                $position += $head_size;
-                if (isset($add_size)) {
-                    $position += $add_size;
-                }
-                break;
-
-            }
+            $text .= Text::htmlAllSpaces(
+                String::pad($val['name'], 50, ' ', STR_PAD_RIGHT) .
+                String::pad($val['attr'], 10, ' ', STR_PAD_LEFT) .
+                String::pad($val['size'], 10, ' ', STR_PAD_LEFT) .
+                String::pad(strftime("%d-%b-%Y %H:%M", $val['date']), 19, ' ', STR_PAD_LEFT) .
+                String::pad($val['method'], 10, ' ', STR_PAD_LEFT) .
+                String::pad(sprintf("%1.1f%%", $ratio), 10, ' ', STR_PAD_LEFT)
+            ) . "\n";
         }
 
-        return $return_array;
+        return nl2br($text . str_repeat('-', 106) . "\n" . '</span></tt></td></tr></table>');
     }
 }