duoshuo/php-cassandra

View on GitHub
src/Type/Decimal.php

Summary

Maintainability
A
0 mins
Test Coverage
<?php
namespace Cassandra\Type;

class Decimal extends Base{

    /**
     * @param string $value
     * @throws Exception
     */
    public function __construct($value = null){
        if (!is_numeric($value))
            throw new Exception('Incoming value must be numeric string.');

        $this->_value = $value;
    }
    
    public static function binary($value){
            $pos = strpos($value, '.');
            $scaleLen = $pos === false ? 0 : strlen($value) - $pos - 1;
            $value *= pow(10, $scaleLen);
            $higher = ($value & 0xffffffff00000000) >> 32;
            $lower = $value & 0x00000000ffffffff;
            $binary = pack('NNN', $scaleLen, $higher, $lower);
        return $binary;
    }
    
    /**
     * @return string
     */
    public static function parse($binary){
        $unpacked = unpack('N1scale/C*', $this->_binary);
        $valueByteLen = $length - 4;
        $value = 0;
        for ($i = 1; $i <= $valueByteLen; ++$i)
            $value |= $unpacked[$i] << (($valueByteLen - $i) * 8);
        $shift = (\PHP_INT_SIZE - $valueByteLen) * 8;
        $value = $value << $shift >> $shift;
        if ($unpacked['scale'] === 0)
            return (string) $value;
        elseif (strlen($value) > $unpacked['scale'])
            return substr($value, 0, -$unpacked['scale']) . '.' . substr($value, -$unpacked['scale']);
        else
            return $value >= 0 ? sprintf("0.%0$unpacked[scale]d", $value) : sprintf("-0.%0$unpacked[scale]d", -$value);
    }
}