<commit_before><?php

namespace Aidantwoods\Phpmd\Lines;

use Iterator;

/**
 * Stores text and is iterable, but defers iteration task
 * to its LinePointer.
 * Implements the extended functionality provided by
 * Pointer, by again deferring tasks to the LinePointer.
 */
class Lines extends LineIterator implements Iterator, Pointer
{
    private $lines;

    protected $pointer;

    public function __construct(?string $lines = null)
    {
        if (isset($lines))
        {
            $lines = str_replace("\0", "\u{fffd}", $lines);
            $lines = str_replace("\r\n", "\n", $lines);
            $lines = str_replace("\r", "\n", $lines);

            $this->lines = explode("\n", $lines);
        }
        else
        {
            $this->lines = array();
        }

        $this->pointer = new LinePointer(count($this->lines));

        $this->transformWhitespace();
    }

    public function current() : string
    {
        return $this->lines[$this->key()];
    }

    public function setCurrent(string $new)
    {
        $this->lines[$this->key()] = $new;

        $this->transformWhitespace($this->key());
    }

    public function lookup(int $position) : ?string
    {
        if ($position >= 0 and $position < $this->pointer->count())
        {
            return $this->lines[$position];
        }

        return null;
    }

    /**
     * Append $text to the content at {@see current} if $toCurrentLine is set
     * to true, otherwise append as a new line after all elements
     *
     * @param string $text
     * @param bool $toCurrentLine
     *
     * @return &string
     */
    public function append(
        string $line,
        bool   $toCurrentLine = false,
        bool   $withSpace     = true
    ) {
        if ($toCurrentLine and $this->count() > 0)
        {
            $this->lines[$this->key()]
                .= ($withSpace ? ' ' : '') . $line;
        }
        else
        {
            $this->lines[] = $line;

            $this->pointer->extendRange();

            $this->pointer->jump($this->count() -1);
        }

        $this->transformWhitespace($this->key());
    }

    public function pop() : Lines
    {
        $instance = clone($this);

        $this->__construct();

        return $instance;
    }

    public function subset(int $start, int $end) : Lines
    {
        $Lines = new Lines;

        for ($i = $start; $i < $end; $i++)
        {
            $Lines->append($this->lines[$i]);
        }

        return $Lines;
    }

    private function transformWhitespace(?int $at = null)
    {
        if ( ! isset($at))<commit_msg>default $end when making a subset<commit_after><?php

namespace Aidantwoods\Phpmd\Lines;

use Iterator;

/**
 * Stores text and is iterable, but defers iteration task
 * to its LinePointer.
 * Implements the extended functionality provided by
 * Pointer, by again deferring tasks to the LinePointer.
 */
class Lines extends LineIterator implements Iterator, Pointer
{
    private $lines;

    protected $pointer;

    public function __construct(?string $lines = null)
    {
        if (isset($lines))
        {
            $lines = str_replace("\0", "\u{fffd}", $lines);
            $lines = str_replace("\r\n", "\n", $lines);
            $lines = str_replace("\r", "\n", $lines);

            $this->lines = explode("\n", $lines);
        }
        else
        {
            $this->lines = array();
        }

        $this->pointer = new LinePointer(count($this->lines));

        $this->transformWhitespace();
    }

    public function current() : string
    {
        return $this->lines[$this->key()];
    }

    public function setCurrent(string $new)
    {
        $this->lines[$this->key()] = $new;

        $this->transformWhitespace($this->key());
    }

    public function lookup(int $position) : ?string
    {
        if ($position >= 0 and $position < $this->pointer->count())
        {
            return $this->lines[$position];
        }

        return null;
    }

    /**
     * Append $text to the content at {@see current} if $toCurrentLine is set
     * to true, otherwise append as a new line after all elements
     *
     * @param string $text
     * @param bool $toCurrentLine
     *
     * @return &string
     */
    public function append(
        string $line,
        bool   $toCurrentLine = false,
        bool   $withSpace     = true
    ) {
        if ($toCurrentLine and $this->count() > 0)
        {
            $this->lines[$this->key()]
                .= ($withSpace ? ' ' : '') . $line;
        }
        else
        {
            $this->lines[] = $line;

            $this->pointer->extendRange();

            $this->pointer->jump($this->count() -1);
        }

        $this->transformWhitespace($this->key());
    }

    public function pop() : Lines
    {
        $instance = clone($this);

        $this->__construct();

        return $instance;
    }

    public function subset(int $start, ?int $end = null) : Lines
    {
        $Lines = new Lines;

        $end = $end ?? $this->count();

        for ($i = $start; $i < $end; $i++)
        {
            $Lines->append($this->lines[$i]);
        }

        return $Lines;
    }

    private function transformWhitespace(?int $at = null)
    {
        if ( ! isset($at))
{'fraction_non_alphanumeric': 0.1488072699734949, 'fraction_numerical': 0.0015145778114350624, 'mean_word_length': 1.8541329011345218, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 64, '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': '3056419', 'n_tokens_mistral': 1572, 'n_tokens_neox': 1510, 'n_words': 390}