| 467 | } |
| 468 | |
| 469 | void ConfigObject::DumpObjects(const String& filename, int attributeTypes) |
| 470 | { |
| 471 | Log(LogInformation, "ConfigObject") |
| 472 | << "Dumping program state to file '" << filename << "'"; |
| 473 | |
| 474 | try { |
| 475 | Utility::Glob(filename + ".tmp.*", &Utility::Remove, GlobFile); |
| 476 | } catch (const std::exception& ex) { |
| 477 | Log(LogWarning, "ConfigObject") << DiagnosticInformation(ex); |
| 478 | } |
| 479 | |
| 480 | AtomicFile fp (filename, 0600); |
| 481 | StdioStream::Ptr sfp = new StdioStream(&fp, false); |
| 482 | |
| 483 | for (const Type::Ptr& type : Type::GetAllTypes()) { |
| 484 | auto *dtype = dynamic_cast<ConfigType *>(type.get()); |
| 485 | |
| 486 | if (!dtype) |
| 487 | continue; |
| 488 | |
| 489 | for (const ConfigObject::Ptr& object : dtype->GetObjects()) { |
| 490 | Dictionary::Ptr update = Serialize(object, attributeTypes); |
| 491 | |
| 492 | if (!update) |
| 493 | continue; |
| 494 | |
| 495 | Dictionary::Ptr persistentObject = new Dictionary({ |
| 496 | { "type", type->GetName() }, |
| 497 | { "name", object->GetName() }, |
| 498 | { "update", update } |
| 499 | }); |
| 500 | |
| 501 | String json = JsonEncode(persistentObject); |
| 502 | |
| 503 | NetString::WriteStringToStream(sfp, json); |
| 504 | } |
| 505 | } |
| 506 | |
| 507 | sfp->Close(); |
| 508 | fp.Commit(); |
| 509 | } |
| 510 | |
| 511 | void ConfigObject::RestoreObject(const String& message, int attributeTypes) |
| 512 | { |