<commit_before><?php
/**
 * Created by PhpStorm.
 * User: jkuchar1
 * Date: 31.1.2016
 * Time: 12:36
 */

namespace BigFileTools\Driver;

use Brick\Math\BigInteger;

class NativeSeekDriver implements ISizeDriver
{
	/**
	 * Returns file size by using native fseek function
	 * @see http://www.php.net/manual/en/function.filesize.php#79023
	 * @see http://www.php.net/manual/en/function.filesize.php#102135
	 * @param string $path Full path to file
	 * @return BigInteger
	 * @throws Exception
	 */
	public function getFileSize($path)
	{
		// This should work for large files on 64bit platforms and for small files everywhere
		$fp = fopen($path, "rb");
		if (!$fp) {
			// file not readable
			// todo: throw exception?
			throw new Exception("Cannot open file for reading.");
		}
		flock($fp, LOCK_SH);
		$res = fseek($fp, 0, SEEK_END);
		// TODO: use incremental seek instead this can return wrong value on some platforms
		if ($res === 0) {
			$pos = ftell($fp);
			flock($fp, LOCK_UN);
			fclose($fp);
			// $pos will be positive int if file is <2GB
			// if is >2GB <4GB it will be negative number
			if($pos>=0) {
				return (string)$pos;
			} else {
				return sprintf("%u", $pos);
			}
		} else {
			flock($fp, LOCK_UN);
			fclose($fp);
			throw new Exception("Seeking to end of file failed");
		}
	}
}<commit_msg>NativeSeekDriver: rewritten internal to be more understandable<commit_after><?php
/**
 * Created by PhpStorm.
 * User: jkuchar1
 * Date: 31.1.2016
 * Time: 12:36
 */

namespace BigFileTools\Driver;

use Brick\Math\BigInteger;

class NativeSeekDriver implements ISizeDriver
{
	/**
	 * Returns file size by seeking at the end of file
	 * @see http://www.php.net/manual/en/function.filesize.php#79023
	 * @see http://www.php.net/manual/en/function.filesize.php#102135
	 * @param string $path Full path to file
	 * @return BigInteger
	 * @throws Exception
	 */
	public function getFileSize($path)
	{
		// This should work for large files on 64bit platforms and for small files everywhere
		$fp = fopen($path, "rb");
		if (!$fp) {
			throw new Exception("Cannot open specified file for reading.");
		}

		$flockResult = flock($fp, LOCK_SH);
		$seekResult = fseek($fp, 0, SEEK_END);
		$position = ftell($fp);
		flock($fp, LOCK_UN);
		fclose($fp);

		// TODO: There is *hope* that ftell() or fseek() fails when file is over 4GB
		// TODO: This really needs tests, any ideas how to test this in CI? (please let me know)

		if($flockResult !== 0) {
			throw new Exception("Couldn't get file lock. Operation abandoned.");
		}

		if($seekResult !== 0) {
			throw new Exception("Seeking to end of file failed");
		}

		if($position === false) {
			throw new Exception("Cannot determine position in file. ftell() failed.");
		}

		// PHP uses internally (in C) UNSIGNED integer for file size.
		// PHP uses signed implicitly
		// convert signed (max val +2^31) -> unsigned integer will extend range for 32-bit to (+2^32)
		return BigInteger::of(
			sprintf("%u", $position)
		);
	}
}
{'fraction_non_alphanumeric': 0.1354062186559679, 'fraction_numerical': 0.02273487128050819, 'mean_word_length': 3.406480117820324, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 6, 'https://': 0, 'lorem ipsum': 0, 'www.': 4, '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': '2467387', 'n_tokens_mistral': 1125, 'n_tokens_neox': 971, 'n_words': 325}