<commit_before><?php

/**
 * @author <NAME> <<EMAIL>>
 * @copyright Copyright (c) 2013, <NAME>
 */

namespace Fxrm\Store;

class ValueSerializer implements Serializer {
    private $class;

    function __construct($class) {
        $this->class = $class;
    }

    function extern($obj) {
        // passthrough null
        if ($obj === null) {
            return null;
        }

        // use serialization trick to extract value
        $class = get_class($obj);

        if($this->class !== get_class($obj)) {
            throw new \Exception('class mismatch'); // developer error
        }

        $bin = serialize($obj);
        $internalName = $this->getValuePropertyInternalName($class);

        $binPrefix = 'O:' . strlen($class) . ':"' . $class . '":1:{s:' . strlen($internalName) . ':"' . $internalName . '";';
        $binSuffix = '}';

        if (substr($bin, 0, strlen($binPrefix)) !== $binPrefix || substr($bin, -strlen($binSuffix)) !== $binSuffix) {
            throw new \Exception('could not serialize value');
        }

        $valueBin = substr($bin, strlen($binPrefix), -strlen($binSuffix));

        return unserialize($valueBin);
    }

    function intern($v) {
        // passthrough null
        if ($v === null) {
            return null;
        }

        // reify using deserialization trick to avoid triggering validation
        $internalName = $this->getValuePropertyInternalName($this->class);

        $bin = 'O:' . strlen($this->class) . ':"' . $this->class . '":1:{s:' . strlen($internalName) . ':"' . $internalName . '";s:' . strlen($v) . ':"' . $v . '";}';
        $obj = unserialize($bin);

        if ($obj === false) {
            throw new \Exception('error reifying value object');
        }

        return $obj;
    }

    private function getValuePropertyInternalName($class) {
        $classInfo = new \ReflectionClass($class);
        $properties = $classInfo->getProperties();

        if (count($properties) === 0 && $classInfo->getParentClass()) {
            return $this->getValuePropertyInternalName($classInfo->getParentClass()->getName()); // @todo pass class ref itself for speed
        }

        if (count($properties) !== 1) {
            throw new \Exception('value class must have one property');
        }

        return "\x00" . $class . "\x00" . $properties[0]->getName();
    }
}

?>
<commit_msg>Using built-in reflection mechanisms instead of goofy serialization tricks<commit_after><?php

/**
 * @author <NAME> <<EMAIL>>
 * @copyright Copyright (c) 2013, <NAME>
 */

namespace Fxrm\Store;

class ValueSerializer implements Serializer {
    private $class;

    function __construct($class) {
        $this->class = $class;
    }

    function extern($obj) {
        // passthrough null
        if ($obj === null) {
            return null;
        }

        // use serialization trick to extract value
        $class = get_class($obj);

        if($this->class !== get_class($obj)) {
            throw new \Exception('class mismatch'); // developer error
        }

        $property = $this->getValueProperty($class);
        return $property->getValue($obj);
    }

    function intern($v) {
        // passthrough null
        if ($v === null) {
            return null;
        }

        // reify using deserialization trick to avoid triggering validation
        $property = $this->getValueProperty($this->class);

        $bin = 'O:' . strlen($this->class) . ':"' . $this->class . '":0:{}';
        $obj = unserialize($bin);

        $property->setValue($obj, $v);

        if ($obj === false) {
            throw new \Exception('error reifying value object');
        }

        return $obj;
    }

    private function getValueProperty($class) {
        $classInfo = new \ReflectionClass($class);
        $properties = $classInfo->getProperties();

        if (count($properties) === 0 && $classInfo->getParentClass()) {
            return $this->getValueProperty($classInfo->getParentClass()->getName()); // @todo pass class ref itself for speed
        }

        if (count($properties) !== 1) {
            throw new \Exception('value class must have one property');
        }

        $properties[0]->setAccessible(true);

        return $properties[0];
    }
}

?>

{'fraction_non_alphanumeric': 0.16126760563380282, 'fraction_numerical': 0.00539906103286385, 'mean_word_length': 2.272657450076805, 'pattern_counts': {'":': 3, '<': 13, '<?xml version=': 0, '>': 41, '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': '7569839', 'n_tokens_mistral': 1224, 'n_tokens_neox': 1175, 'n_words': 289}