<commit_before><?php
namespace wapmorgan\UnifiedArchive\Formats;

use Archive_Tar;
use wapmorgan\UnifiedArchive\ArchiveEntry;
use wapmorgan\UnifiedArchive\ArchiveInformation;
use wapmorgan\UnifiedArchive\Exceptions\ArchiveCreationException;
use wapmorgan\UnifiedArchive\Exceptions\ArchiveExtractionException;
use wapmorgan\UnifiedArchive\Exceptions\ArchiveModificationException;
use wapmorgan\UnifiedArchive\Exceptions\NonExistentArchiveFileException;
use wapmorgan\UnifiedArchive\Exceptions\UnsupportedOperationException;
use wapmorgan\UnifiedArchive\Formats;
use wapmorgan\UnifiedArchive\LzwStreamWrapper;

class TarByPear extends BasicDriver
{
    /**
     * @var string Full path to archive
     */
    protected $archiveFileName;

    /**
     * @var Archive_Tar
     */
    protected $tar;

    /**
     * @var float Overall compression ratio of Tar archive when Archive_Tar is used
     */
    protected $pearCompressionRatio;

    /**
     * @var array<string, integer> List of files and their index in listContent() result
     */
    protected $pearFilesIndex;

    /**
     * @return array
     */
    public static function getSupportedFormats()
    {
        return [
            Formats::TAR,
            Formats::TAR_GZIP,
            Formats::TAR_BZIP,
            Formats::TAR_LZMA,
            Formats::TAR_LZW,
        ];
    }

    /**
     * @param $format
     * @return bool
     * @throws \Exception
     */
    public static function checkFormatSupport($format)
    {
        $availability = class_exists('\Archive_Tar');
        switch ($format) {
            case Formats::TAR:
                return $availability;

            case Formats::TAR_GZIP:
                return $availability && extension_loaded('zlib');

            case Formats::TAR_BZIP:
                return $availability && extension_loaded('bz2');

            case Formats::TAR_LZMA:
                return $availability && extension_loaded('xz');

            case Formats::TAR_LZW:
                return $availability && LzwStreamWrapper::isBinaryAvailable();
        }
    }

    /**
     * @inheritDoc
     */
    public static function getDescription()
    {
        return 'php-library for tar';
    }

    /**
     * @inheritDoc
     */
    public static function getInstallationInstruction()
    {
        return 'install library `pear/archive_tar` and optionally php-extensions (zlib, bzip2)';
    }

    /**
     * @param array $files
     * @param string $archiveFileName
     * @param int $compressionLevel
     * @return int
     * @throws ArchiveCreationException
     */
    public static function createArchive(array $files, $archiveFileName, $compressionLevel = self::COMPRESSION_AVERAGE)
    {
        $compression = null;
        switch (strtolower(pathinfo($archiveFileName, PATHINFO_EXTENSION))) {
            case 'gz':
            case 'tgz':
                $compression = 'gz';
                break;
            case 'bz2':
            case 'tbz2':
                $compression = 'bz2';
                break;
            case 'xz':
                $compression = 'lzma2';
                break;
            case 'z':
                $tar_aname = 'compress.lzw://' . $archiveFileName;
                break;
        }

        if (isset($tar_aname))
            $tar = new Archive_Tar($tar_aname, $compression);
        else
            $tar = new Archive_Tar($archiveFileName, $compression);

        foreach ($files  as $localName => $filename) {
            $remove_dir = dirname($filename);
            $add_dir = dirname($localName);

            if (is_null($filename)) {
                if ($tar->addString($localName, '') === false)
                    throw new ArchiveCreationException('Error when adding directory '.$localName.' to archive');
            } else {
                if ($tar->addModify($filename, $add_dir, $remove_dir) === false)
                    throw new ArchiveCreationException('Error when adding file '.$filename.' to archive');
            }
        }
        $tar = null;

        return count($files);
    }

    /**
     * @inheritDoc
     */
    public function __construct($archiveFileName, $format, $password = null)
    {
        $this->archiveFileName = realpath($archiveFileName);
        $this->open($format);
    }

    protected function open($archiveType)
    {
        switch ($archiveType) {
            case Formats::TAR_GZIP:
                $this->tar = new Archive_Tar($this->archiveFileName, 'gz');
                break;

            case Formats::TAR_BZIP:
                $this->tar = new Archive_Tar($this->archiveFileName, 'bz2');
                break;

            case Formats::TAR_LZMA:
                $this->tar = new Archive_Tar($this->archiveFileName, 'lzma2');
                break;

            case Formats::TAR_LZW:
                LzwStreamWrapper::registerWrapper();
                $this->tar = new Archive_Tar('compress.lzw://' . $this->archiveFileName);
                break;

            default:
                $this->tar = new Archive_Tar($this->archiveFileName);
                break;
        }
    }

    /**
     * @inheritDoc
     */
    public function getArchiveInformation()
    {
        $information = new ArchiveInformation();
        $this->pearFilesIndex = [];

        foreach ($this->tar->listContent() as $i => $file) {
            // BUG workaround: http://pear.php.net/bugs/bug.php?id=20275
            if ($file['filename'] === 'pax_global_header') {
                continue;
            }
            $information->files[] = $file['filename'];
            $information->uncompressedFilesSize += $file['size'];
            $this->pearFilesIndex[$file['filename']] = $i;
        }

        $information->uncompressedFilesSize = filesize($this->archiveFileName);
        $this->pearCompressionRatio = $information->uncompressedFilesSize != 0
            ? ceil($information->compressedFilesSize / $information->uncompressedFilesSize)
            : 1;
        return $information;
    }

    /**
     * @inheritDoc
     */
    public function getFileNames()
    {
        $files = [];

        $Content = $this->tar->listContent();
        foreach ($Content as $i => $file) {
            // BUG workaround: http://pear.php.net/bugs/bug.php?id=20275
            if ($file['filename'] === 'pax_global_header') {
                continue;
            }
            $files[] = $file['filename'];
        }

        return $files;<commit_msg>Correct calculation of TarByPear archive compression and skip folders<commit_after><?php
namespace wapmorgan\UnifiedArchive\Formats;

use Archive_Tar;
use wapmorgan\UnifiedArchive\ArchiveEntry;
use wapmorgan\UnifiedArchive\ArchiveInformation;
use wapmorgan\UnifiedArchive\Exceptions\ArchiveCreationException;
use wapmorgan\UnifiedArchive\Exceptions\ArchiveExtractionException;
use wapmorgan\UnifiedArchive\Exceptions\ArchiveModificationException;
use wapmorgan\UnifiedArchive\Exceptions\NonExistentArchiveFileException;
use wapmorgan\UnifiedArchive\Exceptions\UnsupportedOperationException;
use wapmorgan\UnifiedArchive\Formats;
use wapmorgan\UnifiedArchive\LzwStreamWrapper;

class TarByPear extends BasicDriver
{
    /**
     * @var string Full path to archive
     */
    protected $archiveFileName;

    /**
     * @var Archive_Tar
     */
    protected $tar;

    /**
     * @var float Overall compression ratio of Tar archive when Archive_Tar is used
     */
    protected $pearCompressionRatio;

    /**
     * @var array<string, integer> List of files and their index in listContent() result
     */
    protected $pearFilesIndex;

    /**
     * @return array
     */
    public static function getSupportedFormats()
    {
        return [
            Formats::TAR,
            Formats::TAR_GZIP,
            Formats::TAR_BZIP,
            Formats::TAR_LZMA,
            Formats::TAR_LZW,
        ];
    }

    /**
     * @param $format
     * @return bool
     * @throws \Exception
     */
    public static function checkFormatSupport($format)
    {
        $availability = class_exists('\Archive_Tar');
        switch ($format) {
            case Formats::TAR:
                return $availability;

            case Formats::TAR_GZIP:
                return $availability && extension_loaded('zlib');

            case Formats::TAR_BZIP:
                return $availability && extension_loaded('bz2');

            case Formats::TAR_LZMA:
                return $availability && extension_loaded('xz');

            case Formats::TAR_LZW:
                return $availability && LzwStreamWrapper::isBinaryAvailable();
        }
    }

    /**
     * @inheritDoc
     */
    public static function getDescription()
    {
        return 'php-library for tar';
    }

    /**
     * @inheritDoc
     */
    public static function getInstallationInstruction()
    {
        return 'install library `pear/archive_tar` and optionally php-extensions (zlib, bzip2)';
    }

    /**
     * @param array $files
     * @param string $archiveFileName
     * @param int $compressionLevel
     * @return int
     * @throws ArchiveCreationException
     */
    public static function createArchive(array $files, $archiveFileName, $compressionLevel = self::COMPRESSION_AVERAGE)
    {
        $compression = null;
        switch (strtolower(pathinfo($archiveFileName, PATHINFO_EXTENSION))) {
            case 'gz':
            case 'tgz':
                $compression = 'gz';
                break;
            case 'bz2':
            case 'tbz2':
                $compression = 'bz2';
                break;
            case 'xz':
                $compression = 'lzma2';
                break;
            case 'z':
                $tar_aname = 'compress.lzw://' . $archiveFileName;
                break;
        }

        if (isset($tar_aname))
            $tar = new Archive_Tar($tar_aname, $compression);
        else
            $tar = new Archive_Tar($archiveFileName, $compression);

        foreach ($files  as $localName => $filename) {
            $remove_dir = dirname($filename);
            $add_dir = dirname($localName);

            if (is_null($filename)) {
                if ($tar->addString($localName, '') === false)
                    throw new ArchiveCreationException('Error when adding directory '.$localName.' to archive');
            } else {
                if ($tar->addModify($filename, $add_dir, $remove_dir) === false)
                    throw new ArchiveCreationException('Error when adding file '.$filename.' to archive');
            }
        }
        $tar = null;

        return count($files);
    }

    /**
     * @inheritDoc
     */
    public function __construct($archiveFileName, $format, $password = null)
    {
        $this->archiveFileName = realpath($archiveFileName);
        $this->open($format);
    }

    protected function open($archiveType)
    {
        switch ($archiveType) {
            case Formats::TAR_GZIP:
                $this->tar = new Archive_Tar($this->archiveFileName, 'gz');
                break;

            case Formats::TAR_BZIP:
                $this->tar = new Archive_Tar($this->archiveFileName, 'bz2');
                break;

            case Formats::TAR_LZMA:
                $this->tar = new Archive_Tar($this->archiveFileName, 'lzma2');
                break;

            case Formats::TAR_LZW:
                LzwStreamWrapper::registerWrapper();
                $this->tar = new Archive_Tar('compress.lzw://' . $this->archiveFileName);
                break;

            default:
                $this->tar = new Archive_Tar($this->archiveFileName);
                break;
        }
    }

    /**
     * @inheritDoc
     */
    public function getArchiveInformation()
    {
        $information = new ArchiveInformation();
        $this->pearFilesIndex = [];

        foreach ($this->tar->listContent() as $i => $file) {
            // BUG workaround: http://pear.php.net/bugs/bug.php?id=20275
            if ($file['filename'] === 'pax_global_header') {
                continue;
            }
            // skip directories
            if ($file['typeflag'] == '5')
                continue;
            $information->files[] = $file['filename'];
            $information->uncompressedFilesSize += $file['size'];
            $this->pearFilesIndex[$file['filename']] = $i;
        }

        $information->compressedFilesSize = filesize($this->archiveFileName);
        $this->pearCompressionRatio = $information->uncompressedFilesSize != 0
            ? ceil($information->compressedFilesSize / $information->uncompressedFilesSize)
            : 1;
        return $information;
    }

    /**
     * @inheritDoc
     */
    public function getFileNames()
    {
        $files = [];

        $Content = $this->tar->listContent();
        foreach ($Content as $i => $file) {
            // BUG workaround: http://pear.php.net/bugs/bug.php?id=20275
            if ($file['filename'] === 'pax_global_header') {
                continue;
            }
            $files[] = $file['filename'];
        }

        return $files;
{'fraction_non_alphanumeric': 0.11815958422500765, 'fraction_numerical': 0.0031335982879853257, 'mean_word_length': 1.9745396681063878, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 67, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2455827', 'n_tokens_mistral': 3801, 'n_tokens_neox': 3558, 'n_words': 717}