2
0
mirror of https://github.com/boostorg/website.git synced 2026-01-19 04:42:17 +00:00
Files
website/common/code/boost_state.php
Daniel James 40688e1552 Update links for https
Mostly in comments. Might be better to use relative links from html.
2018-04-13 09:14:48 +01:00

190 lines
6.4 KiB
PHP

<?php
# Copyright 2011, 2015 Daniel James
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt || https://www.boost.org/LICENSE_1_0.txt)
class BoostState_ParseError extends BoostException {}
class BoostState {
static function load($file_path) {
$state = Array();
if ($file_path && is_file($file_path)) {
$file = fopen($file_path, 'rb');
while (true) {
$c = fgetc($file);
if ($c === false) { break; }
if ($c == '#') {
fgets($file);
} else if ($c == '(') {
$record_key = rtrim(fgets($file));
if (!$record_key) {
fclose($file);
throw new BoostState_ParseError();
}
$state[$record_key] = self::read_record($file);
} else {
fclose($file);
throw new BoostState_ParseError();
}
}
fclose($file);
}
return $state;
}
static function read_record($file) {
$record = Array();
# This function sometimes needs to lookahead at the first character in a
# line, so always read it in advance.
$c = fgetc($file);
while (true) {
if (!$c) { throw new BoostState_ParseError(); }
if ($c == ')') {
if (fgets($file) != "\n") { throw new BoostState_ParseError(); }
return $record;
}
if ($c != '-') { throw new BoostState_ParseError(); }
$key = rtrim(fgets($file));
$c = fgetc($file);
if ($c == ')' || $c == '-') {
# The key has no value, so don't read anything. This '$c' will
# be dealt with in the next loop.
$record["$key"] = null;
} else if ($c == '.') {
$record["$key"] = floatval(trim(fgets($file)));
$c = fgetc($file);
} else if ($c == '!') {
$record["$key"] = trim(fgets($file)) ? true : false;
$c = fgetc($file);
} else if ($c == '=') {
$record["$key"] = intval(trim(fgets($file)));
$c = fgetc($file);
} else if ($c == '"') {
$values = Array();
while ($c == '"') {
$values[] = fgets($file);
$c = fgetc($file);
}
$record["$key"] = substr(implode('', $values), 0, -1);
} else if ($c == '@') {
$record["$key"] = new DateTime(fgets($file));
$c = fgetc($file);
} else {
throw new BoostState_ParseError();
}
}
}
static function save($state, $file_path) {
$file = fopen($file_path, "wb");
ksort($state);
foreach ($state as $record_key => $record) {
fputs($file, "(");
fputs($file, $record_key);
fputs($file, "\n");
ksort($record);
foreach ($record as $key => $value) {
fputs($file, "-");
fputs($file, $key);
fputs($file, "\n");
if ($value !== null) {
if (is_string($value)) {
fputs($file, '"');
fputs($file, str_replace("\n", "\n\"", $value));
fputs($file, "\n");
} else if (is_bool($value)) {
fputs($file, '!');
fputs($file, $value ? 1 : 0);
fputs($file, "\n");
} else if (is_int($value)) {
fputs($file, '=');
fputs($file, $value);
fputs($file, "\n");
} else if (is_float($value)) {
fputs($file, '.');
fputs($file, $value);
fputs($file, "\n");
} else if ($value instanceof \DateTime || $value instanceof \DateTimeInterface) {
fputs($file, '@');
fputs($file, $value->format(DATE_RSS));
fputs($file, "\n");
} else {
print_r($value);
assert(false);
}
}
}
fputs($file, ")\n");
}
fclose($file);
}
static function load_json($file_path) {
if ($file_path && is_file($file_path)) {
$v = json_decode(file_get_contents($file_path), true);
if (is_null($v)) { throw new BoostState_ParseError(); }
return $v;
} else {
return array();
}
}
static function save_json($state, $file_path) {
$file = fopen($file_path, "wb");
ksort($state);
fputs($file, "{\n");
$first_record = true;
foreach ($state as $record_key => $record) {
if (!$first_record) { fputs($file, ",\n"); }
$first_record = false;
fputs($file, " ");
fputs($file, json_encode($record_key));
fputs($file, ": {\n");
ksort($record);
$first = true;
foreach ($record as $key => $value) {
if (!$first) { fputs($file, ",\n"); }
$first = false;
fputs($file, " ");
fputs($file, json_encode($key));
fputs($file, ":\n");
fputs($file, " ");
if (is_float($value)) {
$v = json_encode($value);
if (ctype_digit($v)) { $v .= '.0'; }
fputs($file, $v);
} else if ($value instanceof \DateTime || $value instanceof \DateTimeInterface) {
// Will load as a string, but can be decoded.
fputs($file, json_encode($value->format(DATE_RSS)));
} else {
// Should possibly check that this is an atom.
// Maybe write a recursive thing?
fputs($file, json_encode($value));
}
}
fputs($file, "\n");
fputs($file, " }");
}
fputs($file, "\n");
fputs($file, "}\n");
fclose($file);
}
}