/**
  * 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 === false) {
         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));
 }
예제 #2
0
 /**
  * {@inheritdoc}
  */
 public function convertToPHPValue($value, AbstractPlatform $platform)
 {
     if ($value === null) {
         return null;
     }
     return BigInteger::of($value);
 }
예제 #3
0
 /**
  * Returns file size by using Windows COM interface
  * @inheritdoc
  * @link http://stackoverflow.com/questions/5501451/php-x86-how-to-get-filesize-of-2gb-file-without-external-program/5502328#5502328
  */
 public function getFileSize($path)
 {
     // Use the Windows COM interface
     $fsobj = new \COM('Scripting.FileSystemObject');
     if (dirname($path) == '.') {
         $this->path = substr(getcwd(), -1) == DIRECTORY_SEPARATOR ? getcwd() . basename($path) : getcwd() . DIRECTORY_SEPARATOR . basename($path);
     }
     $f = $fsobj->GetFile($path);
     return BigInteger::of($f->Size);
 }
예제 #4
0
 /**
  * Convert string into integer
  * Must be precise number, otherwise you will see and exception.
  *
  * @param $valueAsString
  * @return BigInteger
  * @throws Exception
  */
 private function convertToInteger($valueAsString)
 {
     if (!is_string($valueAsString)) {
         throw new Exception("Cannot convert to integer. Expected string, but got " . gettype($valueAsString) . ".");
     }
     $trimmedInput = trim($valueAsString);
     try {
         return BigInteger::of($trimmedInput);
     } catch (ArithmeticException $e) {
         throw new Exception("Returned value cannot be converted to an integer.", 0, $e);
     }
 }
예제 #5
0
 /**
  * Returns file size by using CURL extension
  * @inheritdoc
  * @link http://www.php.net/manual/en/function.filesize.php#100434
  */
 public function getFileSize($path)
 {
     $ch = curl_init("file://" . rawurlencode($path));
     curl_setopt($ch, CURLOPT_NOBODY, true);
     curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
     curl_setopt($ch, CURLOPT_HEADER, true);
     $data = curl_exec($ch);
     curl_close($ch);
     if ($data !== false && preg_match('/Content-Length: (\\d+)/', $data, $matches)) {
         return BigInteger::of($matches[1]);
     }
     throw new Exception("Curl haven't returned file size.");
 }
 /**
  * Returns file size by reading whole files and counting read bites
  * @link http://stackoverflow.com/questions/5501451/php-x86-how-to-get-filesize-of-2gb-file-without-external-program/5504829#5504829
  * @inheritdoc
  */
 public function getFileSize($path)
 {
     $fp = fopen($path, "rb");
     if (!$fp) {
         throw new Exception("Cannot read from file.");
     }
     flock($fp, LOCK_SH);
     rewind($fp);
     $fileSize = BigInteger::zero();
     $chunkSize = 1024 * 1024;
     while (!feof($fp)) {
         $readBytes = strlen(fread($fp, $chunkSize));
         $fileSize = $fileSize->plus($readBytes);
     }
     flock($fp, LOCK_UN);
     fclose($fp);
     return $fileSize;
 }
예제 #7
0
 /**
  * Returns file size by using system shell/cmd commands
  * @inheritdoc
  * @link http://stackoverflow.com/questions/5501451/php-x86-how-to-get-filesize-of-2gb-file-without-external-program/5502328#5502328
  */
 public function getFileSize($path)
 {
     $escapedPath = escapeshellarg($path);
     if (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN') {
         // Windows
         // Try using the NT substitution modifier %~z
         $size = trim(exec("for %F in ({$escapedPath}) do @echo %~zF"));
     } else {
         // other OS
         // If the platform is not Windows, use the stat command (should work for *nix and MacOS)
         $size = trim(exec("stat -Lc%s {$escapedPath}"));
     }
     // If the return is not blank, not zero, and is number
     if ($size and ctype_digit($size)) {
         return BigInteger::of($size);
     } else {
         throw new Exception("Exec returned invalid value");
     }
 }
예제 #8
0
function shift_uint(Binary $data)
{
    if (PHP_INT_SIZE === 8) {
        if ($data->endianness === Binary::BIG_ENDIAN) {
            return unpack("N", $data->shift(4))[1];
        } else {
            if ($data->endianness === Binary::LITTLE_ENDIAN) {
                return unpack("V", $data->shift(4))[1];
            }
        }
        throw new \InvalidArgumentException("Unknown endianness provided");
    } else {
        if (PHP_INT_SIZE === 4) {
            /*
             * On 32-bit systems, attempting to store a number of an unsigned 32-bit integer in a standard PHP integer
             * (which is a signed 32-bit) is impossible. PHP will convert such numbers automatically to a float which is
             * a behaviour we do not want.
             *
             * Therefore, it is necessary to manually gather individual bytes and put them back together to preserve
             * precision.
             */
            $v = unpack("C4", $data->shift(4));
            if ($data->endianness === Binary::LITTLE_ENDIAN) {
                $v = array_reverse($v);
            } else {
                if ($data->endianness === Binary::BIG_ENDIAN) {
                    $v = array_values($v);
                    // Otherwise the array will start at index 1
                } else {
                    throw new \InvalidArgumentException("Unknown endianness provided");
                }
            }
            return BigInteger::of($v[0])->multipliedBy(BigInteger::of(2)->power(56))->plus(BigInteger::of($v[1])->multipliedBy(BigInteger::of(2)->power(48)))->plus(BigInteger::of($v[2])->multipliedBy(BigInteger::of(2)->power(40)))->plus(BigInteger::of($v[3])->multipliedBy(BigInteger::of(2)->power(32)))->plus(BigInteger::of($v[4])->multipliedBy(BigInteger::of(2)->power(24)))->plus(BigInteger::of($v[5])->multipliedBy(BigInteger::of(2)->power(16)))->plus(BigInteger::of($v[6])->multipliedBy(BigInteger::of(2)->power(8)))->plus(BigInteger::of($v[7]));
        }
    }
    throw new \RuntimeException("Unknown system architecture");
}
예제 #9
0
 /**
  * This method is required by interface Serializable and MUST NOT be accessed directly.
  *
  * @internal
  *
  * @param string $value
  *
  * @return void
  */
 public function unserialize($value)
 {
     if ($this->numerator !== null || $this->denominator !== null) {
         throw new \LogicException('unserialize() is an internal function, it must not be called directly.');
     }
     list($numerator, $denominator) = explode('/', $value);
     $this->numerator = BigInteger::of($numerator);
     $this->denominator = BigInteger::of($denominator);
 }
예제 #10
0
파일: BigInteger.php 프로젝트: brick/math
 /**
  * {@inheritdoc}
  */
 public function toBigRational()
 {
     return BigRational::create($this, BigInteger::one(), false);
 }
예제 #11
0
 /**
  * @param string     $expected The expected value, as a string.
  * @param BigInteger $actual   The BigInteger instance to test.
  */
 protected final function assertBigIntegerEquals($expected, $actual)
 {
     $this->assertInstanceOf(BigInteger::getNamespace(), $actual);
     $this->assertSame($expected, (string) $actual);
 }
예제 #12
0
 /**
  * @expectedException \LogicException
  */
 public function testDirectCallToUnserialize()
 {
     BigInteger::zero()->unserialize('123');
 }
예제 #13
0
파일: BigDecimal.php 프로젝트: brick/math
 /**
  * {@inheritdoc}
  */
 public function toBigRational()
 {
     $numerator = BigInteger::create($this->value);
     $denominator = BigInteger::create('1' . str_repeat('0', $this->scale));
     return BigRational::create($numerator, $denominator, false);
 }
예제 #14
0
 /**
  * @return array
  */
 public function providerPlus()
 {
     return [['123/456', 1, '579/456'], ['123/456', BigInteger::of(2), '1035/456'], ['123/456', BigRational::nd(2, 3), '1281/1368'], ['234/567', '123/28', '76293/15876'], ['-1234567890123456789/497', '79394345/109859892', '-135629495075630790047217323/54600366324'], ['-1234567890123456789/999', '-98765/43210', '-53345678532234666518925/43166790'], ['123/456789123456789123456789', '-987/654321987654321', '-450850864771369260370369260/298887167199121283949604203169112635269']];
 }