Skip to content

Instantly share code, notes, and snippets.

@jesseschalken
Last active August 29, 2015 14:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jesseschalken/f5f772a283260af65119 to your computer and use it in GitHub Desktop.
Save jesseschalken/f5f772a283260af65119 to your computer and use it in GitHub Desktop.
Simple fast bidirectional mapping between scalars and strings
<?php
class ScalarSerializer {
/**
* @param string $s
* @return string|int|float|bool|null
*/
static function unserialize($s) {
$t = (string)substr($s, 0, 1);
$v = (string)substr($s, 1);
switch ($t) {
case 'b':
return (bool) $v;
case 'i':
return (int) $v;
case 'f':
return (float) $v;
case ':':
return $v;
case '~':
return null;
default:
throw new \Exception('Unhandled type tag: ' . $t);
}
}
/**
* @param string|int|float|bool|null $x
* @return string
*/
static function serialize($x) {
if (is_string($x)) {
return ':' . $x;
} else if (is_int($x)) {
return 'i' . $x;
} else if (is_null($x)) {
return '~';
} else if (is_bool($x)) {
return 'b' . ($x ? '1' : '0');
} else if (is_float($x)) {
if (is_finite($x)) {
list($l, $r) = explode('.', number_format(abs($x), 400, '.', ''), 2);
$l = $l ?: '0';
$r = $r ?: '0';
$n = $x < 0 ? '-' : '';
return "f$n$l.$r";
} else {
throw new \Exception('INF, -INF and NAN are not supported');
}
} else {
throw new \Exception('Unhandled type: ' . gettype($x));
}
}
/**
* @return void
*/
static function test() {
static $values = array(
'hello',
'',
"\x00",
null,
true,
false,
-1.0/3.0,
0,
2,
-9,
PHP_INT_MAX,
);
foreach ($values as $v1) {
$s = ScalarSerializer::serialize($v1);
$v2 = ScalarSerializer::unserialize($s);
if ($v1 !== $v2) {
$v1 = var_export($v1, true);
$v2 = var_export($v2, true);
throw new \Exception("Failed to serialize $v1 (serialized: $s, unserialized: $v2)");
}
}
}
}
ScalarSerializer::test();
print "done\n";
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment