X-Git-Url: http://www.codesrc.com/gitweb/index.cgi?p=SCSI2SD-V6.git;a=blobdiff_plain;f=software%2Fscsi2sd-util%2FConfigUtil.cc;h=38ba70fa509da92534db428e2c3922f798fb98b9;hp=446a91b7c4c070207c7089eae844c68e27e0955b;hb=446892cde07dd2afb1a003ca50ef2db1d1c4616e;hpb=9ad7cc15d0af9c62e642fc7431ab15b3ac66113d diff --git a/software/scsi2sd-util/ConfigUtil.cc b/software/scsi2sd-util/ConfigUtil.cc index 446a91b7..38ba70fa 100644 --- a/software/scsi2sd-util/ConfigUtil.cc +++ b/software/scsi2sd-util/ConfigUtil.cc @@ -18,9 +18,13 @@ #include "ConfigUtil.hh" #include +#include +#include #include +#include + using namespace SCSI2SD; @@ -145,62 +149,283 @@ ConfigUtil::toBytes(const TargetConfig& _config) return std::vector(begin, begin + sizeof(config)); } -/* -wxXmlNode* +std::string ConfigUtil::toXML(const TargetConfig& config) { - wxXmlNode* target = new wxXmlNode(wxXML_ELEMENT_NODE, "SCSITarget"); + std::stringstream s; + + s << + "(config.scsiId & CONFIG_TARGET_ID_BITS) << "\">\n" << + + " " << + (config.scsiId & CONFIG_TARGET_ENABLED ? "true" : "false") << + "\n" << + + " " << + (config.flags & CONFIG_ENABLE_UNIT_ATTENTION ? "true" : "false") << + "\n" << + + " " << + (config.flags & CONFIG_ENABLE_PARITY ? "true" : "false") << + "\n" << + + "\n" << + " \n" << + " " << + (config.quirks & CONFIG_QUIRKS_APPLE ? "apple" : "") << + "\n" << + + "\n\n" << + " \n" << + " 0x" << + std::hex << static_cast(config.deviceType) << + "\n" << + + "\n\n" << + " \n" << + " 0x" << + std::hex << static_cast(config.deviceTypeModifier) << + "\n" << + + "\n\n" << + " \n" << + " " << std::dec << config.sdSectorStart << "\n" << + "\n\n" << + " \n" << + "\n" + " " << std::dec << config.scsiSectors << "\n" << + " " << std::dec << config.bytesPerSector << "\n" << + " " << std::dec << config.sectorsPerTrack<< "\n" << + " " << std::dec << config.headsPerCylinder << "\n" << + "\n\n" << + " \n" << + "\n" + " \n" << + " \n" << + " " << std::string(config.vendor, 8) << "\n" << + "\n" << + " \n" << + " \n" << + " " << std::string(config.prodId, 16) << "\n" << + "\n" << + " \n" << + " \n" << + " " << std::string(config.revision, 4) << "\n" << + "\n" << + " \n" << + " " << std::string(config.serial, 16) << "\n" << + "\n"; + + return s.str(); +} + +static uint64_t parseInt(wxXmlNode* node, uint64_t limit) +{ + std::string str(node->GetNodeContent().mb_str()); + if (str.empty()) + { + throw std::runtime_error("Empty " + node->GetName()); + } + std::stringstream s; + if (str.find("0x") == 0) { - std::stringstream s; s << scsiId & CONFIG_TARGET_ID_BITS; - target.AddAttribute("id", s.str()); + s << std::hex << str.substr(2); } + else { - std::stringstream s; s << config.deviceType; - new wxXmlNode( - new wxXmlNode(target, wxXML_ELEMENT_NODE, "deviceType"), - wxXML_TEXT_NODE, "", s.str()); + s << str; } + uint64_t result; + s >> result; + if (!s) { - std::stringstream s; s << "0x" << std::hex << config.deviceTypeModifier; - new wxXmlNode( - new wxXmlNode(target, wxXML_ELEMENT_NODE, "deviceTypeModifier"), - wxXML_TEXT_NODE, "", s.str()); + throw std::runtime_error("Invalid value for " + node->GetName()); } - wxXmlNode* flags(new wxXmlNode(target, wxXML_ELEMENT_NODE, "flags")); - - new wxXmlNode( - new wxXmlNode(flags, wxXML_ELEMENT_NODE, "enabled"), - wxXML_TEXT_NODE, - "", - config.scsiId & CONFIG_TARGET_ENABLED ? "true" : "false"); - - "" << - (config.flags & CONFIG_ENABLE_UNIT_ATTENTION ? "true" : "false") << - "\n" << - "" << - (config.flags & CONFIG_ENABLE_PARITY ? "true" : "false") << - "\n" << + if (result > limit) + { + std::stringstream msg; + msg << "Invalid value for " << node->GetName() << + " (max=" << limit << ")"; + throw std::runtime_error(msg.str()); + } + return result; +} - "" << config.sdSectorStart << "\n" << - "" << config.scsiSectors << "\n" << - "" << config.bytesPerSector << "\n" << - "" << config.sectorsPerTrack<< "\n" << - "" << config.headsPerCylinder << "\n" << +static TargetConfig +parseTarget(wxXmlNode* node) +{ + int id; + { + std::stringstream s; + s << node->GetAttribute("id", "7"); + s >> id; + if (!s) throw std::runtime_error("Could not parse SCSITarget id attr"); + } + TargetConfig result = ConfigUtil::Default(id & 0x7); - "" << std::string(config.vendor, 8) << "" << - "" << std::string(config.prodId, 16) << "" << - "" << std::string(config.revision, 4) << "" << - "" << std::string(config.serial, 16) << "" << + wxXmlNode *child = node->GetChildren(); + while (child) + { + if (child->GetName() == "enabled") + { + std::string s(child->GetNodeContent().mb_str()); + if (s == "true") + { + result.scsiId |= CONFIG_TARGET_ENABLED; + } + else + { + result.scsiId = result.scsiId & ~CONFIG_TARGET_ENABLED; + } + } + if (child->GetName() == "unitAttention") + { + std::string s(child->GetNodeContent().mb_str()); + if (s == "true") + { + result.flags |= CONFIG_ENABLE_UNIT_ATTENTION; + } + else + { + result.flags = result.flags & ~CONFIG_ENABLE_UNIT_ATTENTION; + } + } + if (child->GetName() == "parity") + { + std::string s(child->GetNodeContent().mb_str()); + if (s == "true") + { + result.flags |= CONFIG_ENABLE_PARITY; + } + else + { + result.flags = result.flags & ~CONFIG_ENABLE_PARITY; + } + } + else if (child->GetName() == "quirks") + { + std::stringstream s(std::string(child->GetNodeContent().mb_str())); + std::string quirk; + while (s >> quirk) + { + if (quirk == "apple") + { + result.quirks |= CONFIG_QUIRKS_APPLE; + } + } + } + else if (child->GetName() == "deviceType") + { + result.deviceType = parseInt(child, 0xFF); + } + else if (child->GetName() == "deviceTypeModifier") + { + result.deviceTypeModifier = parseInt(child, 0xFF); + } + else if (child->GetName() == "sdSectorStart") + { + result.sdSectorStart = parseInt(child, 0xFFFFFFFF); + } + else if (child->GetName() == "scsiSectors") + { + result.scsiSectors = parseInt(child, 0xFFFFFFFF); + } + else if (child->GetName() == "bytesPerSector") + { + result.bytesPerSector = parseInt(child, 8192); + } + else if (child->GetName() == "sectorsPerTrack") + { + result.sectorsPerTrack = parseInt(child, 255); + } + else if (child->GetName() == "headsPerCylinder") + { + result.headsPerCylinder = parseInt(child, 255); + } + else if (child->GetName() == "vendor") + { + std::string s(child->GetNodeContent().mb_str()); + s = s.substr(0, sizeof(result.vendor)); + memset(result.vendor, ' ', sizeof(result.vendor)); + memcpy(result.vendor, s.c_str(), s.size()); + } + else if (child->GetName() == "prodId") + { + std::string s(child->GetNodeContent().mb_str()); + s = s.substr(0, sizeof(result.prodId)); + memset(result.prodId, ' ', sizeof(result.prodId)); + memcpy(result.prodId, s.c_str(), s.size()); + } + else if (child->GetName() == "revision") + { + std::string s(child->GetNodeContent().mb_str()); + s = s.substr(0, sizeof(result.revision)); + memset(result.revision, ' ', sizeof(result.revision)); + memcpy(result.revision, s.c_str(), s.size()); + } + else if (child->GetName() == "serial") + { + std::string s(child->GetNodeContent().mb_str()); + s = s.substr(0, sizeof(result.serial)); + memset(result.serial, ' ', sizeof(result.serial)); + memcpy(result.serial, s.c_str(), s.size()); + } - ""; + child = child->GetNext(); + } + return result; } -void -ConfigUtil::deserialise(const std::string& in) +std::vector +ConfigUtil::fromXML(const std::string& filename) { + wxXmlDocument doc; + if (!doc.Load(filename)) + { + throw std::runtime_error("Could not load XML file"); + } + + // start processing the XML file + if (doc.GetRoot()->GetName() != "SCSI2SD") + { + throw std::runtime_error("Invalid root node, expected "); + } + std::vector result; + wxXmlNode *child = doc.GetRoot()->GetChildren(); + while (child) + { + if (child->GetName() == "SCSITarget") + { + result.push_back(parseTarget(child)); + } + child = child->GetNext(); + } + return result; } -*/ +