void openOutputFileStream(OFStream& ofs, const String& outFilePath, OFStream::openmode mode) { // Create directories std::string outputDir = sb_dirname(outFilePath); if (mkpath(outputDir)) { SBLog::warning() << "Failed to create " << outputDir << " output directory path." << std::endl; return; } // Open output file ofs.open(outFilePath.c_str(), mode); if (!ofs.is_open()) { SBLog::warning() << "Failed to open " << outFilePath << " for writing." << std::endl; return; } }
// save does the real work with saveToBundle void Network::saveToBundle(const std::string& name) { if (! StringUtils::endsWith(name, ".nta")) NTA_THROW << "saveToBundle: bundle extension must be \".nta\""; std::string fullPath = Path::normalize(Path::makeAbsolute(name)); std::string networkStructureFilename = Path::join(fullPath, "network.yaml"); // Only overwrite an existing path if it appears to be a network bundle if (Path::exists(fullPath)) { if (! Path::isDirectory(fullPath) || ! Path::exists(networkStructureFilename)) { NTA_THROW << "Existing filesystem entry " << fullPath << " is not a network bundle -- refusing to delete"; } Directory::removeTree(fullPath); } Directory::create(fullPath); { YAML::Emitter out; out << YAML::BeginMap; out << YAML::Key << "Version" << YAML::Value << 2; out << YAML::Key << "Regions" << YAML::Value << YAML::BeginSeq; for (size_t regionIndex = 0; regionIndex < regions_.getCount(); regionIndex++) { std::pair<std::string, Region*>& info = regions_.getByIndex(regionIndex); Region *r = info.second; // Network serializes the region directly because it is actually easier // to do here than inside the region, and we don't have the RegionImpl data yet. out << YAML::BeginMap; out << YAML::Key << "name" << YAML::Value << info.first; out << YAML::Key << "nodeType" << YAML::Value << r->getType(); out << YAML::Key << "dimensions" << YAML::Value << r->getDimensions(); // yaml-cpp doesn't come with a default emitter for std::set, so // implement as a sequence by hand. out << YAML::Key << "phases" << YAML::Value << YAML::BeginSeq; std::set<UInt32> phases = r->getPhases(); for (std::set<UInt32>::const_iterator phase = phases.begin(); phase != phases.end(); phase++) { out << *phase; } out << YAML::EndSeq; // label is going to be used to name RegionImpl files within the bundle out << YAML::Key << "label" << YAML::Value << getLabel(regionIndex); out << YAML::EndMap; } out << YAML::EndSeq; // end of regions out << YAML::Key << "Links" << YAML::Value << YAML::BeginSeq; for (size_t regionIndex = 0; regionIndex < regions_.getCount(); regionIndex++) { Region *r = regions_.getByIndex(regionIndex).second; const std::map<const std::string, Input*> inputs = r->getInputs(); for (std::map<const std::string, Input*>::const_iterator input = inputs.begin(); input != inputs.end(); input++) { const std::vector<Link*>& links = input->second->getLinks(); for (std::vector<Link*>::const_iterator link = links.begin(); link != links.end(); link++) { Link& l = *(*link); out << YAML::BeginMap; out << YAML::Key << "type" << YAML::Value << l.getLinkType(); out << YAML::Key << "params" << YAML::Value << l.getLinkParams(); out << YAML::Key << "srcRegion" << YAML::Value << l.getSrcRegionName(); out << YAML::Key << "srcOutput" << YAML::Value << l.getSrcOutputName(); out << YAML::Key << "destRegion" << YAML::Value << l.getDestRegionName(); out << YAML::Key << "destInput" << YAML::Value << l.getDestInputName(); out << YAML::EndMap; } } } out << YAML::EndSeq; // end of links out << YAML::EndMap; // end of network OFStream f; f.open(networkStructureFilename.c_str()); f << out.c_str(); f.close(); } // Now save RegionImpl data for (size_t regionIndex = 0; regionIndex < regions_.getCount(); regionIndex++) { std::pair<std::string, Region*>& info = regions_.getByIndex(regionIndex); Region *r = info.second; std::string label = getLabel(regionIndex); BundleIO bundle(fullPath, label, info.first, /* isInput: */ false); r->serializeImpl(bundle); } }