42 class ReadStreamJSON :
public ReadStream {
44 ReadStreamJSON(std::istream&
file,
const std::map<std::string, std::string>& rwOperation,
49 if (
err.length() > 0) {
50 fatal(
"cannot get internal params: %s",
err);
68 std::string error =
"";
69 std::string source(std::istreambuf_iterator<char>(
file), {});
74 fatal(
"cannot deserialize json because %s:\n%s", error, source);
84 for (
auto param :
params[
"relation"][
"params"].array_items()) {
85 paramIndex.insert(std::make_pair(param.string_value(), index_pos));
89 fatal(
"the input is neither list nor object format");
107 assert(jsonObj.
is_array() &&
"the input is not json array");
133 default:
fatal(
"invalid type attribute: `%c`", ty[0]);
136 std::stringstream errorMessage;
138 errorMessage <<
"Error converting: " << jsonObj[
i].
dump();
140 errorMessage <<
"Invalid index: " <<
i;
142 throw std::invalid_argument(errorMessage.str());
150 auto&& recordInfo =
types[
"records"][recordTypeName];
152 if (recordInfo.is_null()) {
153 throw std::invalid_argument(
"Missing record type information: " + recordTypeName);
157 if (source.is_null()) {
161 assert(source.is_array() &&
"the input is not json array");
162 auto&& recordTypes = recordInfo[
"types"];
163 const size_t recordArity = recordInfo[
"arity"].long_value();
164 std::vector<RamDomain> recordValues(recordArity);
165 for (
size_t i = 0;
i < recordArity; ++
i) {
166 const std::string& recordType = recordTypes[
i].string_value();
167 switch (recordType[0]) {
169 recordValues[
i] =
symbolTable.unsafeLookup(source[
i].string_value());
177 recordValues[
i] = source[
i].int_value();
181 recordValues[
i] = source[
i].int_value();
185 recordValues[
i] =
static_cast<RamDomain>(source[
i].number_value());
188 default:
fatal(
"invalid type attribute");
192 return recordTable.pack(recordValues.data(), recordValues.size());
202 assert(jsonObj.
is_object() &&
"the input is not json object");
208 fatal(
"invalid parameter: %s",
p.first);
222 tuple[
i] =
p.second.int_value();
226 tuple[
i] =
p.second.int_value();
230 tuple[
i] =
static_cast<RamDomain>(
p.second.number_value());
233 default:
fatal(
"invalid type attribute: `%c`", ty[0]);
236 std::stringstream errorMessage;
237 errorMessage <<
"Error converting: " <<
p.second.dump();
238 throw std::invalid_argument(errorMessage.str());
246 auto&& recordInfo =
types[
"records"][recordTypeName];
247 const std::string recordName = recordTypeName.substr(2);
248 std::map<const std::string, const size_t> recordIndex;
250 size_t index_pos = 0;
251 for (
auto param :
params[
"records"][recordName][
"params"].array_items()) {
252 recordIndex.insert(std::make_pair(param.string_value(), index_pos));
256 if (recordInfo.is_null()) {
257 throw std::invalid_argument(
"Missing record type information: " + recordTypeName);
261 if (source.is_null()) {
265 assert(source.is_object() &&
"the input is not json object");
266 auto&& recordTypes = recordInfo[
"types"];
267 const size_t recordArity = recordInfo[
"arity"].long_value();
268 std::vector<RamDomain> recordValues(recordArity);
269 recordValues.reserve(recordIndex.size());
270 for (
auto readParam : source.object_items()) {
272 if (recordIndex.find(readParam.first) == recordIndex.end()) {
273 fatal(
"invalid parameter: %s", readParam.first);
275 size_t i = recordIndex.at(readParam.first);
276 auto&&
type = recordTypes[
i].string_value();
279 recordValues[
i] =
symbolTable.unsafeLookup(readParam.second.string_value());
287 recordValues[
i] = readParam.second.int_value();
291 recordValues[
i] = readParam.second.int_value();
295 recordValues[
i] =
static_cast<RamDomain>(readParam.second.number_value());
298 default:
fatal(
"invalid type attribute: `%c`",
type[0]);
302 return recordTable.pack(recordValues.data(), recordValues.size());
306 class ReadFileJSON :
public ReadStreamJSON {
314 throw std::invalid_argument(
"Cannot open json file " +
baseName +
"\n");
328 static std::string
getFileName(
const std::map<std::string, std::string>& rwOperation) {
329 auto name =
getOr(rwOperation,
"filename", rwOperation.at(
"name") +
".json");
330 if (name.front() !=
'/') {
331 name =
getOr(rwOperation,
"fact-dir",
".") +
"/" + name;
344 return mk<ReadStreamJSON>(std::cin, rwOperation, symbolTable, recordTable);
347 const std::string&
getName()
const override {
348 static const std::string name =
"json";
358 return mk<ReadFileJSON>(rwOperation, symbolTable, recordTable);
361 const std::string&
getName()
const override {
362 static const std::string name =
"jsonfile";