<commit_before><?php
/*
 * Part of tivars_lib
 * (C) 2015 Adrien 'Adriweb' Bertrand
 * https://github.com/adriweb/tivars_lib
 * License: MIT
 */

namespace tivars;

date_default_timezone_set('UTC');

include_once "BinaryFile.php";

class TIVarFile extends BinaryFile
{
    private $header = [
        'signature'     => null,
        'sig_extra'     => null,
        'comment'       => null,
        'entries_len'   => null
    ];
    private $varEntry = [
        'constBytes'    => null,
        'data_length'   => null,
        'typeID'        => null,
        'varname'       => null,
        'version'       => null,
        'archivedFlag'  => null,
        'data_length2'  => null,
        'data'          => null
    ];
    /** @var TIVarType */
    private $type = null;
    /** @var TIModel */
    private $calcModel = null;
    private $computedChecksum = null;
    private $inFileChecksum = null;
    private $isFromFile = null;

    // TODO: Handle multiple varEntries


    /*** Constructors ***/

    /**
     * Internal constructor, called from loadFromFile and createNew.
     * @param   string  $filePath
     * @throws  \Exception
     */
    protected function __construct($filePath = '')
    {
        if ($filePath !== '')
        {
            $this->isFromFile = true;
            parent::__construct($filePath);
            if ($this->fileSize < 76) // bare minimum for header + a var entry
            {
                throw new \Exception("This file is not a valid TI-[e]z80 variable file");
            }
            $this->makeHeaderFromFile();
            $this->makeVarEntryFromFile();
            $this->computedChecksum = $this->computeChecksumFromFileData();
            $this->inFileChecksum = $this->getChecksumValueFromFile();
            $this->type = TIVarType::createFromID($this->varEntry['typeID']);
        } else {
            $this->isFromFile = false;
        }
    }

    public static function loadFromFile($filePath = '')
    {
        if ($filePath !== '')
        {
            return new self($filePath);
        } else {
            throw new \Exception("No file path given");
        }
    }

    public static function createNew(TIVarType $type = null, $name = '', TIModel $version = null)
    {
        if ($type !== null)
        {
            if ($name === '')
            {
                $name = 'FILE' . ((count($type->getExts()) > 0) ? $type->getExts()[0] : '');
            }
            $newName = preg_replace('/[^a-zA-Z0-9]/', '', $name);
            if ($newName !== $name || strlen($newName) > 8 || $newName === '' || is_numeric($newName[0]))
            {
                throw new \Exception("Invalid name given. 8 chars (A-Z, 0-9) max, starting by a letter");
            }
            $name = strtoupper(substr($name, 0, 8));

            $instance = new self();
            $instance->type = $type;
            $instance->calcModel = ($version !== null) ? $version : TIModel::createFromName('84+'); // default

            if (!$instance->calcModel->supportsType($instance->type))
            {
                throw new \Exception('This calculator model (' . $instance->calcModel->getName() . ') does not support the type ' . $instance->type->getName());
            }

            $instance->header = [
                'signature'     =>  $instance->calcModel->getSig(),
                'sig_extra'     =>  [ 0x1A, 0x0A, 0x00 ],
                'comment'       =>  str_pad("Created by tivars_lib on " . date("M j, Y"), 42, "\0"),
                'entries_len'   =>  0 // will have to be overwritten later
            ];
            $calcFlags = $instance->calcModel->getFlags();
            $instance->varEntry = [
                'constBytes'    =>  [ 0x0D, 0x00 ],
                'data_length'   =>  0, // will have to be overwritten later
                'typeID'        =>  $type->getId(),
                'varname'       =>  str_pad($name, 8, "\0"),
                'version'       =>  ($calcFlags >= TIFeatureFlags::hasFlash) ? 0 : null,
                'archivedFlag'  =>  ($calcFlags >= TIFeatureFlags::hasFlash) ? 0 : null, // TODO: check when that needs to be 1.
                'data_length2'  =>  0, // will have to be overwritten later
                'data'          =>  [] // will have to be overwritten later
            ];
            return $instance;
        } else {
            throw new \Exception("No file path given");
        }
    }


    /*** Makers ***/

    private function makeHeaderFromFile()
    {
        rewind($this->file);
        $this->header = [];
        $this->header['signature']   = $this->get_string_bytes(8);
        $this->header['sig_extra']   = $this->get_raw_bytes(3);
        $this->header['comment']     = $this->get_string_bytes(42);<commit_msg>Update TIVarFile.php<commit_after><?php
/*
 * Part of tivars_lib
 * (C) 2015 Adrien 'Adriweb' Bertrand
 * https://github.com/adriweb/tivars_lib
 * License: MIT
 */

namespace tivars;

date_default_timezone_set('UTC');

include_once "BinaryFile.php";

class TIVarFile extends BinaryFile
{
    private $header = [
        'signature'     => null,
        'sig_extra'     => null,
        'comment'       => null,
        'entries_len'   => null
    ];
    private $varEntry = [
        'constBytes'    => null,
        'data_length'   => null,
        'typeID'        => null,
        'varname'       => null,
        'version'       => null,
        'archivedFlag'  => null,
        'data_length2'  => null,
        'data'          => null
    ];
    /** @var TIVarType */
    private $type = null;
    /** @var TIModel */
    private $calcModel = null;
    private $computedChecksum = null;
    private $inFileChecksum = null;
    private $isFromFile = null;

    // TODO: Handle multiple varEntries


    /*** Constructors ***/

    /**
     * Internal constructor, called from loadFromFile and createNew.
     * @param   string  $filePath
     * @throws  \Exception
     */
    protected function __construct($filePath = '')
    {
        if ($filePath !== '')
        {
            $this->isFromFile = true;
            parent::__construct($filePath);
            if ($this->fileSize < 76) // bare minimum for header + a var entry
            {
                throw new \Exception("This file is not a valid TI-[e]z80 variable file");
            }
            $this->makeHeaderFromFile();
            $this->makeVarEntryFromFile();
            $this->computedChecksum = $this->computeChecksumFromFileData();
            $this->inFileChecksum = $this->getChecksumValueFromFile();
            $this->type = TIVarType::createFromID($this->varEntry['typeID']);
        } else {
            $this->isFromFile = false;
        }
    }

    public static function loadFromFile($filePath = '')
    {
        if ($filePath !== '')
        {
            return new self($filePath);
        } else {
            throw new \Exception("No file path given");
        }
    }

    public static function createNew(TIVarType $type = null, $name = '', TIModel $version = null)
    {
        if ($type !== null)
        {
            if ($name === '')
            {
                $name = 'FILE' . ((count($type->getExts()) > 0) ? $type->getExts()[0] : '');
            }
            $newName = preg_replace('/[^a-zA-Z0-9]/', '', $name);
            if ($newName !== $name || strlen($newName) > 8 || $newName === '' || is_numeric($newName[0]))
            {
                throw new \Exception("Invalid name given. 8 chars (A-Z, 0-9) max, starting by a letter");
            }
            $name = strtoupper(substr($name, 0, 8));

            $instance = new self();
            $instance->type = $type;
            $instance->calcModel = ($version !== null) ? $version : TIModel::createFromName('84+'); // default

            if (!$instance->calcModel->supportsType($instance->type))
            {
                throw new \Exception('This calculator model (' . $instance->calcModel->getName() . ') does not support the type ' . $instance->type->getName());
            }

            $instance->header = [
                'signature'     =>  $instance->calcModel->getSig(),
                'sig_extra'     =>  [ 0x1A, 0x0A, 0x00 ],
                'comment'       =>  str_pad("Created by tivars_lib on " . date("M j, Y"), 42, "\0"),
                'entries_len'   =>  0 // will have to be overwritten later
            ];
            $calcFlags = $instance->calcModel->getFlags();
            $instance->varEntry = [
                'constBytes'    =>  [ 0x0D, 0x00 ],
                'data_length'   =>  0, // will have to be overwritten later
                'typeID'        =>  $type->getId(),
                'varname'       =>  str_pad($name, 8, "\0"),
                'version'       =>  ($calcFlags >= TIFeatureFlags::hasFlash) ? 0 : null,
                'archivedFlag'  =>  ($calcFlags >= TIFeatureFlags::hasFlash) ? 0 : null, // TODO: check when that needs to be 1.
                'data_length2'  =>  0, // will have to be overwritten later
                'data'          =>  [] // will have to be overwritten later
            ];
            return $instance;
        } else {
            throw new \Exception("No type given");
        }
    }


    /*** Makers ***/

    private function makeHeaderFromFile()
    {
        rewind($this->file);
        $this->header = [];
        $this->header['signature']   = $this->get_string_bytes(8);
        $this->header['sig_extra']   = $this->get_raw_bytes(3);
        $this->header['comment']     = $this->get_string_bytes(42);
{'fraction_non_alphanumeric': 0.15316164154103853, 'fraction_numerical': 0.010469011725293133, 'mean_word_length': 1.7451149425287356, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 133, 'https://': 2, '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': '3599773', 'n_tokens_mistral': 2894, 'n_tokens_neox': 2783, 'n_words': 625}