/** * Loads a ruleset's contents from a YAML file. * @param filename YAML filename. */ void Ruleset::load(const std::string &filename) { std::string s = Options::getDataFolder() + "Ruleset/" + filename + ".rul"; std::ifstream fin(s.c_str()); if (!fin) { throw Exception("Failed to load ruleset"); } YAML::Parser parser(fin); YAML::Node doc; parser.GetNextDocument(doc); for (YAML::Iterator i = doc.begin(); i != doc.end(); ++i) { std::string key; i.first() >> key; if (key == "countries") { for (YAML::Iterator j = i.second().begin(); j != i.second().end(); ++j) { std::string type; (*j)["type"] >> type; RuleCountry *rule; if (_countries.find(type) != _countries.end()) { rule = _countries[type]; } else { rule = new RuleCountry(type); _countries[type] = rule; _countriesIndex.push_back(type); } rule->load(*j); } } else if (key == "regions") { for (YAML::Iterator j = i.second().begin(); j != i.second().end(); ++j) { std::string type; (*j)["type"] >> type; RuleRegion *rule; if (_regions.find(type) != _regions.end()) { rule = _regions[type]; } else { rule = new RuleRegion(type); _regions[type] = rule; _regionsIndex.push_back(type); } rule->load(*j); } } else if (key == "facilities")
Program::Program(const YAML::Node& fns) { for (YAML::Iterator it = fns.begin(); it != fns.end(); ++it) { std::string name; it.first() >> name; ReadFn(name, it.second()); } }
void ExtraStrings::load(const YAML::Node &node) { for (YAML::Iterator i = node.begin(); i != node.end(); ++i) { std::string key; i.first() >> key; if (key == "strings") { for (YAML::Iterator j = i.second().begin(); j != i.second().end(); ++j) { std::string index; j.first() >> index; std::string translation; j.second() >> translation; _strings[index] = translation; } } } }
worker_types_t context::get_worker_types() const { worker_types_t worker_types; if( application_configuration_.count( "configuration-file" ) ) { std::fstream stream( application_configuration_["configuration-file"].as<string>().c_str() ); YAML::Parser parser( stream ); YAML::Node doc; parser.GetNextDocument( doc ); YAML::Iterator it = doc.begin(); it.second() >> worker_types; }
void ExtraSprites::load(const YAML::Node &node) { for (YAML::Iterator i = node.begin(); i != node.end(); ++i) { std::string key; i.first() >> key; if (key == "width") { i.second() >> _width; } else if (key == "height")
/** * Add the weighted options from a YAML::Node to a WeightedOptions. * The weight option list is not replaced, only values in @a nd will be added / * changed. * @param nd The YAML node (containing a map) with the new values. * @param wo The list to change. */ void WeightedOptions::load(const YAML::Node &nd) { for (YAML::Iterator val = nd.begin(); val != nd.end(); ++val) { std::string id; unsigned w; val.first() >> id; val.second() >> w; set(id, w); } }
/* * Loads the extra sound set from yaml. * @param node YAML node. * @param modIndex the internal index of the associated mod. */ void ExtraSounds::load(const YAML::Node &node, int modIndex) { for (YAML::Iterator i = node.begin(); i != node.end(); ++i) { std::string key; i.first() >> key; if (key == "files") { for (YAML::Iterator j = i.second().begin(); j != i.second().end(); ++j) { int index; j.first() >> index; std::string filename; j.second() >> filename; _sounds[index] = filename; } } } _modIndex = modIndex; }
/** * Loads the inventory from a YAML file. * @param node YAML node. */ void RuleInventory::load(const YAML::Node &node) { int a = 0; for (YAML::Iterator i = node.begin(); i != node.end(); ++i) { std::string key; i.first() >> key; if (key == "id") { i.second() >> _id; } else if (key == "x")
/** * Loads the article definition from a YAML file. * @param node YAML node. */ void ArticleDefinition::load(const YAML::Node &node) { int a = 0; for (YAML::Iterator i = node.begin(); i != node.end(); ++i) { std::string key; i.first() >> key; if (key == "id") { i.second() >> id; i.second() >> title; } else if (key == "type_id")
/** * Loads the unit from a YAML file. * @param node YAML node. */ void Unit::load(const YAML::Node &node) { int a = 0; for (YAML::Iterator i = node.begin(); i != node.end(); ++i) { std::string key; i.first() >> key; if (key == "type") { i.second() >> _type; } else if (key == "race")
/*! * Parses the binding config YAML specification. * * \param[in] node The YAML node containing the binding config specification. * \param[out] b The object in which to store the binding configuration information. */ void parse_binding_config(YAML::Node const& node, controlit::BindingConfig& bc) { // Parameters // for (YAML::Iterator it = node["parameters"].begin(); // it !=node["parameters"].end(); ++it) // { // std::string paramName; // *it >> paramName; // bc.addParameter(paramName); // } std::string parameter; node["parameter"] >> parameter; bc.setParameter(parameter); // Direction std::string direction; node["direction"] >> direction; bc.setDirection(controlit::BindingConfig::Direction::Undefined); if (direction == "input") bc.setDirection(controlit::BindingConfig::Direction::Input); if (direction == "output") bc.setDirection(controlit::BindingConfig::Direction::Output); if (direction == "bidirectional") bc.setDirection(controlit::BindingConfig::Direction::Bidirectional); // Target YAML::Node const& targetNode = *(node.FindValue("target")); // targetNode["transportType"] >> bc.transportType; std::string transportType; std::string transportDataType; targetNode["type"] >> transportType; targetNode["dataType"] >> transportDataType; bc.setTransportType(transportType); bc.setTransportDataType(transportDataType); // Target properties YAML::Node const* propertiesNode = targetNode.FindValue("properties"); if (propertiesNode != NULL) { for (YAML::Iterator it = propertiesNode->begin(); it != propertiesNode->end(); ++it) { std::string key, value; it.first() >> key; it.second() >> value; bc.addProperty(key, value); } } }
void Property::loadChildren( const YAML::Node& yaml_node ) { if( yaml_node.Type() != YAML::NodeType::Map ) { printf( "Property::loadChildren() TODO: error handling - unexpected YAML type.\n" ); return; } // A special map entry named "Value" means the value of this property, not a child. if( const YAML::Node *value_node = yaml_node.FindValue( "Value" )) { loadValue( *value_node ); } // Yaml-cpp's FindValue() and operator[] functions are order-N, // according to the docs, so we don't want to use those. Instead we // make a hash table of the existing property children, then loop // over all the yaml key-value pairs, looking up their targets by // key (name) in the map. This should keep this function down to // order-N or close, instead of order N squared. // First make the hash table of all child properties indexed by name. QHash<QString, Property*> child_map; int num_property_children = children_.size(); for( int i = 0; i < num_property_children; i++ ) { Property* child = children_.at( i ); child_map[ child->getName() ] = child; } // Next loop over all yaml key/value pairs, calling load() on each // child whose name we find. for( YAML::Iterator it = yaml_node.begin(); it != yaml_node.end(); ++it ) { QString key; it.first() >> key; QHash<QString, Property*>::const_iterator hash_iter = child_map.find( key ); if( hash_iter != child_map.end() ) { Property* child = hash_iter.value(); child->load( it.second() ); } } }
static ConfigMap parseConfigMapFromYamlNode(const YAML::Node &n) { ConfigMap configMap; for(YAML::Iterator it = n.begin(); it != n.end(); ++it) { if(it.second().Type() == YAML::NodeType::Scalar) { configMap[it.first().to<std::string>()].push_back(parseConfigItemFromYamlNode(it.second())); } else if(it.second().Type() == YAML::NodeType::Sequence) { configMap[it.first().to<std::string>()] = parseConfigVectorFromYamlNode(it.second()); } else if(it.second().Type() == YAML::NodeType::Map) { ConfigItem item; item.children = parseConfigMapFromYamlNode(it.second()); configMap[it.first().to<std::string>()].push_back(item); } else if(it.second().Type() == YAML::NodeType::Null) { continue; } else { fprintf(stderr, "Unknown YAML::NodeType: %d\n", it.second().Type()); continue; } } return configMap; }
void Settings::ParseAppConfig(const YAML::Node* pNode, const char* appType, AppsConfig::AppMap& appMap) { const YAML::Node* pBaseNode = pNode->FindValue(appType); if (pBaseNode) { for (YAML::Iterator iter = pBaseNode->begin(); iter != pBaseNode->end(); ++iter) { #define setString(a, b) {std::string c; b->GetScalar(c); a = c.c_str();} AppConfig config; const YAML::Node* pName = &iter.first(); if (pName) setString(config.m_Name, pName); const YAML::Node& appNode = iter.second(); const YAML::Node* pVer = appNode.FindValue(VERSION); if (pVer) setString(config.m_Version, pVer); const YAML::Node* pRunPath = appNode.FindValue(RUN_PATH); if (pRunPath) setString(config.m_RunPath, pRunPath); const YAML::Node* pInstallCmd = appNode.FindValue(INSTALL_CMD); if (pInstallCmd) setString(config.m_InstallCmd, pInstallCmd); const YAML::Node* pUninstallCmd = appNode.FindValue(UNINSTALL_CMD); if (pUninstallCmd) setString(config.m_UninstallCmd, pUninstallCmd); const YAML::Node* pInstallParams = appNode.FindValue(INSTALL_PARAMS); if (pInstallParams) setString(config.m_InstallParams, pInstallParams); const YAML::Node* pUninstallParams = appNode.FindValue(UNINSTALL_PARAMS); if (pUninstallParams) setString(config.m_UninstallParams, pUninstallParams); const YAML::Node* pInstalledFiles = appNode.FindValue(INSTALLED_FILES); if (pInstalledFiles) { for (YAML::Iterator iter = pInstalledFiles->begin(); iter != pInstalledFiles->end(); ++iter) { std::string a; *iter >> a; config.m_InstalledFiles.push_back(a.c_str()); } } appMap[config.m_Name][config.m_Version] = config; } } }
void YamlConfigReader::readYamlNode( Config& config, const YAML::Node& yaml_node ) { switch( yaml_node.Type() ) { case YAML::NodeType::Map: { for( YAML::Iterator it = yaml_node.begin(); it != yaml_node.end(); ++it ) { std::string key; it.first() >> key; Config child = config.mapMakeChild( QString::fromStdString( key )); readYamlNode( child, it.second() ); } break; } case YAML::NodeType::Sequence: { for( YAML::Iterator it = yaml_node.begin(); it != yaml_node.end(); ++it ) { Config child = config.listAppendNew(); readYamlNode( child, *it ); } break; } case YAML::NodeType::Scalar: { std::string s; yaml_node >> s; config.setValue( QString::fromStdString( s )); break; } case YAML::NodeType::Null: default: break; } }
/* * For converting param specs for Regions and LinkPolicies */ ValueMap toValueMap(const char* yamlstring, Collection<ParameterSpec>& parameters, const std::string & nodeType, const std::string & regionName) { ValueMap vm; // yaml-cpp bug: append a space if it is only one character // This is very inefficient, but should be ok since it is // just used at construction time for short strings std::string paddedstring(yamlstring); // TODO: strip white space to determine if empty bool empty = (paddedstring.size() == 0); if (paddedstring.size() < 2) paddedstring = paddedstring + " "; std::stringstream s(paddedstring); // IMemStream s(yamlstring, ::strlen(yamlstring)); // TODO: utf-8 compatible? YAML::Node doc; if (!empty) { YAML::Parser parser(s); bool success = parser.GetNextDocument(doc); if (!success) NTA_THROW << "Unable to find document in YAML string"; // A ValueMap is specified as a dictionary if (doc.Type() != YAML::NodeType::Map) { std::string ys(yamlstring); if (ys.size() > 30) { ys = ys.substr(0, 30) + "..."; } NTA_THROW << "YAML string '" << ys << "' does not not specify a dictionary of key-value pairs. " << "Region and Link parameters must be specified at a dictionary"; } } // Grab each value out of the YAML dictionary and put into the ValueMap // if it is allowed by the nodespec. YAML::Iterator i; for (i = doc.begin(); i != doc.end(); i++) { const std::string key = i.first().to<std::string>(); if (!parameters.contains(key)) { std::stringstream ss; for (UInt j = 0; j < parameters.getCount(); j++) { ss << " " << parameters.getByIndex(j).first << "\n"; } if (nodeType == std::string("")) { NTA_THROW << "Unknown parameter '" << key << "'\n" << "Valid parameters are:\n" << ss.str(); } else { NTA_CHECK(regionName != std::string("")); NTA_THROW << "Unknown parameter '" << key << "' for region '" << regionName << "' of type '" << nodeType << "'\n" << "Valid parameters are:\n" << ss.str(); } } if (vm.contains(key)) NTA_THROW << "Parameter '" << key << "' specified more than once in YAML document"; ParameterSpec spec = parameters.getByName(key); try { Value v = toValue(i.second(), spec.dataType); if (v.isScalar() && spec.count != 1) { throw std::runtime_error("Expected array value but got scalar value"); } if (!v.isScalar() && spec.count == 1) { throw std::runtime_error("Expected scalar value but got array value"); } vm.add(key, v); } catch (std::runtime_error& e) { NTA_THROW << "Unable to set parameter '" << key << "'. " << e.what(); } } // Populate ValueMap with default values if they were not specified in the YAML dictionary. for (size_t i = 0; i < parameters.getCount(); i++) { std::pair<std::string, ParameterSpec>& item = parameters.getByIndex(i); if (!vm.contains(item.first)) { ParameterSpec & ps = item.second; if (ps.defaultValue != "") { // TODO: This check should be uncommented after dropping NuPIC 1.x nodes (which don't comply) // if (ps.accessMode != ParameterSpec::CreateAccess) // { // NTA_THROW << "Default value for non-create parameter: " << item.first; // } try { #ifdef YAMLDEBUG NTA_DEBUG << "Adding default value '" << ps.defaultValue << "' to parameter " << item.first << " of type " << BasicType::getName(ps.dataType) << " count " << ps.count; #endif Value v = toValue(ps.defaultValue, ps.dataType); vm.add(item.first, v); } catch (...) { NTA_THROW << "Unable to set default value for item '" << item.first << "' of datatype " << BasicType::getName(ps.dataType) <<" with value '" << ps.defaultValue << "'"; } } } } return vm; }
void YamlConfiguration::read_config_doc(const YAML::Node &doc, YamlConfigurationNode *&node) { if (! node) { node = new YamlConfigurationNode("root"); } if (doc.Type() == YAML::NodeType::Map) { #ifdef HAVE_YAMLCPP_0_5 for (YAML::const_iterator it = doc.begin(); it != doc.end(); ++it) { std::string key = it->first.as<std::string>(); #else for (YAML::Iterator it = doc.begin(); it != doc.end(); ++it) { std::string key; it.first() >> key; #endif YamlConfigurationNode *in = node; if (key.find("/") != std::string::npos) { // we need to split and find the proper insertion node std::vector<std::string> pel = str_split(key); for (size_t i = 0; i < pel.size() - 1; ++i) { YamlConfigurationNode *n = (*in)[pel[i]]; if (! n) { n = new YamlConfigurationNode(pel[i]); in->add_child(pel[i], n); } in = n; } key = pel.back(); } YamlConfigurationNode *tmp = (*in)[key]; if (tmp) { #ifdef HAVE_YAMLCPP_0_5 if (tmp->is_scalar() && it->second.Type() != YAML::NodeType::Scalar) #else if (tmp->is_scalar() && it.second().Type() != YAML::NodeType::Scalar) #endif { throw Exception("YamlConfig: scalar %s cannot be overwritten by non-scalar", tmp->name().c_str()); } #ifdef HAVE_YAMLCPP_0_5 tmp->set_scalar(it->second.Scalar()); #else std::string s; if (it.second().GetScalar(s)) { tmp->set_scalar(s); } #endif } else { #ifdef HAVE_YAMLCPP_0_5 YamlConfigurationNode *tmp = new YamlConfigurationNode(key, it->second); in->add_child(key, tmp); read_config_doc(it->second, tmp); #else YamlConfigurationNode *tmp = new YamlConfigurationNode(key, it.second()); in->add_child(key, tmp); read_config_doc(it.second(), tmp); #endif } } } else if (doc.Type() == YAML::NodeType::Scalar) { if (doc.Tag() == "tag:fawkesrobotics.org,cfg/tcp-port" || doc.Tag() == "tag:fawkesrobotics.org,cfg/udp-port") { unsigned int p = 0; try { p = node->get_uint(); } catch (Exception &e) { e.prepend("YamlConfig: Invalid TCP/UDP port number (not an unsigned int)"); throw; } if (p <= 0 || p >= 65535) { throw Exception("YamlConfig: Invalid TCP/UDP port number " "(%u out of allowed range)", p); } } else if (doc.Tag() == "tag:fawkesrobotics.org,cfg/url") { #ifdef HAVE_YAMLCPP_0_5 std::string scalar = doc.Scalar(); #else std::string scalar; doc.GetScalar(scalar); #endif #ifdef USE_REGEX_CPP if (regex_search(scalar, __url_regex)) { # if 0 // just for emacs auto-indentation } # endif #else if (regexec(&__url_regex, scalar.c_str(), 0, NULL, 0) == REG_NOMATCH) { throw Exception("YamlConfig: %s is not a valid URL", scalar.c_str()); } #endif } else if (doc.Tag() == "tag:fawkesrobotics.org,cfg/frame") { #ifdef HAVE_YAMLCPP_0_5 std::string scalar = doc.Scalar(); #else std::string scalar; doc.GetScalar(scalar); #endif #ifdef USE_REGEX_CPP if (regex_search(scalar, __frame_regex)) { # if 0 // just for emacs auto-indentation } # endif #else if (regexec(&__frame_regex, scalar.c_str(), 0, NULL, 0) == REG_NOMATCH) { throw Exception("YamlConfig: %s is not a valid frame ID", scalar.c_str()); } #endif } } }
static void yaml_traverse(struct VMGlobals* g, const YAML::Node & node, PyrObject *parent, PyrSlot *slot) { YAML::NodeType::value type = node.Type(); string out; PyrObject *result = NULL; switch (type) { case YAML::NodeType::Scalar: node >> out; result = (PyrObject*)newPyrString(g->gc, out.c_str(), 0, true); SetObject(slot, result); if(parent) g->gc->GCWriteNew(parent, result); // we know result is white so we can use GCWriteNew break; case YAML::NodeType::Sequence: result = newPyrArray(g->gc, node.size(), 0, true); SetObject(slot, result); if(parent) g->gc->GCWriteNew(parent, result); // we know result is white so we can use GCWriteNew for (unsigned int i = 0; i < node.size(); i++) { const YAML::Node & subnode = node[i]; result->size++; yaml_traverse(g, subnode, result, result->slots+i); } break; case YAML::NodeType::Map: { result = instantiateObject( g->gc, s_dictionary->u.classobj, 0, false, true ); SetObject(slot, result); if(parent) g->gc->GCWriteNew(parent, result); // we know result is white so we can use GCWriteNew PyrObject *array = newPyrArray(g->gc, node.size()*2, 0, true); result->size = 2; SetObject(result->slots, array); // array SetInt(result->slots+1, node.size()); // size g->gc->GCWriteNew(result, array); // we know array is white so we can use GCWriteNew int j = 0; for (YAML::Iterator i = node.begin(); i != node.end(); ++i) { const YAML::Node & key = i.first(); const YAML::Node & value = i.second(); key >> out; PyrObject *pkey = (PyrObject*)newPyrString(g->gc, out.c_str(), 0, true); SetObject(array->slots+j, pkey); array->size++; g->gc->GCWriteNew(array, pkey); // we know pkey is white so we can use GCWriteNew array->size++; yaml_traverse(g, value, array, array->slots+j+1); j += 2; } break; } case YAML::NodeType::Null: SetNil(slot); break; default: postfl("WARNING: yaml_traverse(): unknown/unsupported node type\n"); SetNil(slot); } }
void Robots::loadYaml(string filename) { cout << endl << "Loading yaml configuration " << filename << endl; try { ifstream cfgfile(filename.c_str()); if(!cfgfile) throw string("Failed to open file " + filename); YAML::Parser parser(cfgfile); YAML::Node doc; bool result = parser.GetNextDocument(doc); if(!result) throw string("Parser failed to load document"); if(!doc.FindValue("robots")) { throw string("Config error : no robots entry in yaml doc"); } else { YAML::Iterator it; int i; string name, host, environment, move; int port; vector<string> loadedMoves; for(it=doc["robots"].begin();it!=doc["robots"].end();++it) { loadedMoves.clear(); // Name it.first() >> name; robots[name] = new Robot(new CommandsStore, name); // Host & port if(it.second().FindValue("host")) { if(it.second().FindValue("host")) it.second()["host"] >> host; else host = "localhost"; if(it.second().FindValue("port")) { it.second()["port"] >> port; } else { port = 7777; } robots[name]->connect(host.c_str(), port); } // Environment if(it.second().FindValue("environment")) { it.second()["environment"] >> environment; robots[name]->loadEnvironment(environment); }
Result process() { if (const YAML::Node *n = m_entry.FindValue(kSkip)) return kSkipped; if (const YAML::Node *n = m_entry.FindValue(kPath)) { n->GetScalar(m_path); } else { logerr("no path specified, line %d", n->GetMark().line); return kManifestError; } if (const YAML::Node *n = m_entry.FindValue(kMD5Sum)) { std::string md5 = md5sum(m_path); std::string expectedMD5; n->GetScalar(expectedMD5); if (md5 != expectedMD5) { logerr("md5 checksum differs from expected value"); return kFailure; } } AFfilehandle file = afOpenFile(m_path.c_str(), "r", NULL); if (const YAML::Node *n = m_entry.FindValue(kInvalid)) { if (!file) return kSuccess; logerr("opening invalid file did not fail as expected"); return kFailure; } if (!file) { logerr("could not open file"); return kFailure; } for (YAML::Iterator i = m_entry.begin(); i != m_entry.end(); ++i) { std::string key = i.first().to<std::string>(); std::string value = i.second().to<std::string>(); if (key == kFileFormat) { const char *fileFormat = (const char *) afQueryPointer(AF_QUERYTYPE_FILEFMT, AF_QUERY_LABEL, afGetFileFormat(file, NULL), 0, 0); assert(fileFormat); expect(key, std::string(fileFormat), value); } else if (key == kChannels) { int expectedChannels = atoi(value.c_str()); expect(key, expectedChannels, afGetChannels(file, AF_DEFAULT_TRACK)); } else if (key == kByteOrder) { int expectedByteOrder; if (value == kByteOrder_Big) expectedByteOrder = AF_BYTEORDER_BIGENDIAN; else if (value == kByteOrder_Little) expectedByteOrder = AF_BYTEORDER_LITTLEENDIAN; else { logerr("bad value for byte order: %s, line %d", value.c_str(), i.second().GetMark().line); return kManifestError; } expect(key, expectedByteOrder, afGetByteOrder(file, AF_DEFAULT_TRACK)); } else if (key == kSampleRate) { double expectedSampleRate = atof(value.c_str()); expect(key, expectedSampleRate, afGetRate(file, AF_DEFAULT_TRACK)); } else if (key == kSampleFormat) { std::string width = value.substr(1, value.length() - 1); char format = value[0]; int expectedSampleWidth = atoi(width.c_str()); bool isValidSampleWidth = (expectedSampleWidth >= 1 && expectedSampleWidth <= 32) || expectedSampleWidth == 64; if (!isValidSampleWidth) { logerr("bad value for sample format: %s, line %d", value.c_str(), i.second().GetMark().line); return kManifestError; } int expectedSampleFormat = -1; switch (format) { case 's': expectedSampleFormat = AF_SAMPFMT_TWOSCOMP; break; case 'u': expectedSampleFormat = AF_SAMPFMT_UNSIGNED; break; case 'f': if (expectedSampleWidth == 32) expectedSampleFormat = AF_SAMPFMT_FLOAT; else if (expectedSampleWidth == 64) expectedSampleFormat = AF_SAMPFMT_DOUBLE; break; default: logerr("bad value for sample format: %s, line %d", value.c_str(), i.second().GetMark().line); return kManifestError; } int sampleFormat, sampleWidth; afGetSampleFormat(file, AF_DEFAULT_TRACK, &sampleFormat, &sampleWidth); expect(key, expectedSampleFormat, sampleFormat); expect(key, expectedSampleWidth, sampleWidth); } else if (key == kCompression) { int expectedCompression; if (value == kCompression_None) expectedCompression = AF_COMPRESSION_NONE; else if (value == kCompression_IMA_ADPCM) expectedCompression = AF_COMPRESSION_IMA; else if (value == kCompression_MS_ADPCM) expectedCompression = AF_COMPRESSION_MS_ADPCM; else if (value == kCompression_ulaw) expectedCompression = AF_COMPRESSION_G711_ULAW; else if (value == kCompression_alaw) expectedCompression = AF_COMPRESSION_G711_ALAW; else if (value == kCompression_FLAC) expectedCompression = AF_COMPRESSION_FLAC; else if (value == kCompression_ALAC) expectedCompression = AF_COMPRESSION_ALAC; else { logerr("bad value for compression: %s, line %d", value.c_str(), i.second().GetMark().line); return kManifestError; } expect(key, expectedCompression, afGetCompression(file, AF_DEFAULT_TRACK)); } else if (key == kFrames) { AFframecount expectedFrameCount = atoll(value.c_str()); expect(key, expectedFrameCount, afGetFrameCount(file, AF_DEFAULT_TRACK)); int bufferFrameCount = 1024; int channels = afGetChannels(file, AF_DEFAULT_TRACK); int maxBytesPerFrame = 8; char *buffer = new char[channels * bufferFrameCount * maxBytesPerFrame]; AFframecount framesRead = 0; while (framesRead < expectedFrameCount) { AFframecount framesToRead = std::min<AFframecount>(bufferFrameCount, expectedFrameCount - framesRead); AFframecount result = afReadFrames(file, AF_DEFAULT_TRACK, buffer, framesToRead); if (result != framesToRead) { m_failures++; break; } framesRead += result; } delete [] buffer; } else if (key == kBytes) { AFfileoffset expectedTrackBytes = atoll(value.c_str()); expect(key, expectedTrackBytes, afGetTrackBytes(file, AF_DEFAULT_TRACK)); } } afCloseFile(file); return m_failures == 0 ? kSuccess : kFailure; }