Esempio n. 1
0
	Vector3D getPosition(boost::property_tree::ptree const & tree, const std::string& prefixe)
	{
		Vector3D position;
		position.x = tree.get(prefixe+"x", 0.f);
		position.y = tree.get(prefixe+"y", 0.f);
		position.z = tree.get(prefixe+"z", 0.f);
		return position;
	}
Esempio n. 2
0
std::shared_ptr<IComponent> MoveComponent::loadFromXml(const boost::property_tree::ptree& tree)
{
	std::shared_ptr<MoveComponent> result = std::make_shared<MoveComponent>();
	result->x = tree.get("x", 0.0f);
	result->y = tree.get("y", 0.0f);
	result->speed = tree.get("speed", 1.0f);
	result->movingLeft = false;
	result->movingRight = false;
	result->movingUp = false;
	result->movingDown = false;
	return result;
}
Esempio n. 3
0
void CompPathMove::loadFromPropertyTree(const boost::property_tree::ptree& propTree)
{
    m_pathId = propTree.get("path_id", "");
    m_repeat = propTree.get("repeat", false);
    m_resetAngle = propTree.get("resetAngle", false);
    //m_velocity = propTree.get<float>("velocity");
    //if (propTree.get<std::string>("mode") != "relative")
    //    throw DataLoadException("CompPathMove: Only 'relatve' mode is supported");

    foreach(const ptree::value_type &v, propTree)
    {
        if (v.first != cPoint) continue;

        const ptree& point = v.second;
        PathMovePoint::MotionMode mode;

        std::string modeStr = point.get<std::string>(cMode);
        if      (modeStr == cModeUniform)     mode = PathMovePoint::Uniform;
        else if (modeStr == cModeAccelerated) mode = PathMovePoint::Accelerated;
        else throw DataLoadException("PathMovePoint: invalid mode '"+modeStr+"'");
        float linAccel  = point.get(cLinAccel, 0.0f);
        float angAccel  = point.get(cAngAccel, 0.0f);
        float topLinVel = point.get(cTopLinVel, 0.0f);
        float topAngVel = point.get(cTopAngVel, 0.0f);
        float linVel    = point.get(cLinVel, 0.0f);
        float angVel    = point.get(cAngVel, 0.0f);
        float time      = point.get(cTime, 0.0f);

        switch (mode)
        {
        case PathMovePoint::Uniform:
            if (time != 0)
                m_points.push_back(PathMovePoint::makeUniformByTime(time));
            else if (linVel != 0)
                m_points.push_back(PathMovePoint::makeUniformByLinVel(linVel));
            else if (angVel != 0)
                m_points.push_back(PathMovePoint::makeUniformByAngVel(angVel));
            else
                throw DataLoadException("invalid uniform PathMovePoint");
            break;
        case PathMovePoint::Accelerated:
            if (linAccel != 0.0f)
                m_points.push_back(PathMovePoint::makeLinAccelerated(linAccel, topLinVel));
            else if (angAccel != 0.0f)
                m_points.push_back(PathMovePoint::makeAngAccelerated(angAccel, topAngVel));
            else
                throw DataLoadException("invalid accelerated PathMovePoint");
            break;
        }
    }
}
Esempio n. 4
0
QueryData parseALFTree(const pt::ptree& tree) {
  Row r;
  for (const auto& it : kTopLevelIntKeys) {
    int val = tree.get(it.first, -1);
    r[it.second] = INTEGER(val);
  }

  for (const auto& it : kTopLevelStringKeys) {
    std::string val = tree.get(it.second, "");
    r[it.first] = val;
  }

  return {r};
}
Esempio n. 5
0
void genXProtectEntry(const pt::ptree &entry, QueryData& results) {
  // Entry is an XProtect dictionary of meta data about the item.
  auto name = entry.get("Description", "");
  auto launch_type = entry.get("LaunchServices.LSItemContentType", "");

  // Get the list of matches
  std::vector<Row> file_matches;
  genMatches(entry, file_matches);

  for (auto& r : file_matches) {
    r["name"] = name;
    r["launch_type"] = launch_type;
    results.push_back(r);
  }
}
Esempio n. 6
0
Status parsePack(const std::string& name, const pt::ptree& data) {
  if (data.count("queries") == 0) {
    return Status(0, "Pack contains no queries");
  }

  // Check the pack-global minimum SDK version and platform.
  auto version = data.get("version", "");
  if (version.size() > 0 && !versionChecker(version, kSDKVersion)) {
    return Status(0, "Minimum SDK version not met");
  }

  auto platform = data.get("platform", "");
  if (platform.size() > 0 && !platformChecker(platform, kSDKPlatform)) {
    return Status(0, "Platform version mismatch");
  }

  // For each query in the pack's queries, check their version/platform.
  for (const auto& query : data.get_child("queries")) {
    auto query_string = query.second.get("query", "");
    if (Config::checkScheduledQuery(query_string)) {
      VLOG(1) << "Query pack " << name
              << " contains a duplicated query: " << query.first;
      continue;
    }

    // Check the specific query's required version.
    version = query.second.get("version", "");
    if (version.size() > 0 && !versionChecker(version, kSDKVersion)) {
      continue;
    }

    // Check the specific query's required platform.
    platform = query.second.get("platform", "");
    if (platform.size() > 0 && !platformChecker(platform, kSDKPlatform)) {
      continue;
    }

    // Hope there is a supplied/non-0 query interval to apply this query pack
    // query to the osquery schedule.
    auto query_interval = query.second.get("interval", 0);
    if (query_interval > 0) {
      auto query_name = "pack_" + name + "_" + query.first;
      Config::addScheduledQuery(query_name, query_string, query_interval);
    }
  }

  return Status(0, "OK");
}
Esempio n. 7
0
void genMatches(const pt::ptree& entry, std::vector<Row>& results) {
  if (entry.count("Matches") == 0) {
    return;
  }

  bool optional = (entry.get("MatchType", "") == "MatchAny");
  for (const auto& match : entry.get_child("Matches")) {
    if (match.second.count("Matches") > 0) {
      genMatches(match.second, results);
      continue;
    }

    Row r;
    r["optional"] = (optional) ? "1" : "0";
    r["identity"] = match.second.get("Identity", "");
    if (match.second.count("MatchFile") == 0) {
      // There is no file in this match entry, odd.
      continue;
    }

    // This can contain any of Foundation/Classes/NSURL_Class keys.
    auto fileinfo = match.second.get_child("MatchFile");
    if (fileinfo.count("LSDownloadContentTypeKey") > 0) {
      r["filetype"] = fileinfo.get<std::string>("LSDownloadContentTypeKey");
    } else {
      r["filetype"] = fileinfo.get("NSURLTypeIdentifierKey", "");
    }

    r["uses_pattern"] = (match.second.count("Pattern") > 0) ? "1" : "0";
    r["filename"] = fileinfo.get("NSURLNameKey", "");
    results.push_back(r);
  }
}
Esempio n. 8
0
draw_state  create_draw_state(boost::property_tree::ptree const&  props)
{
    return{
        nullptr,
        props.get("use_alpha_blending", false),
        read_property(props, "alpha_blending_src_function", get_map_from_alpha_blending_function_names_to_gl_values()),
        read_property(props, "alpha_blending_dst_function", get_map_from_alpha_blending_function_names_to_gl_values())
        };
}
Esempio n. 9
0
	Ogre::Quaternion getQuaternion(boost::property_tree::ptree const & tree)
	{
		Ogre::Quaternion q;
		Vector3D vec(getPosition(tree, "q"));
		q.x = vec.x;
		q.y = vec.y;
		q.z = vec.z;
		q.w = tree.get("qw", 0.f);
		return q;
	}
Esempio n. 10
0
 WeaponDesc(const boost::property_tree::ptree& node)
 {
   memset(this, 0, sizeof(WeaponDesc));
   m_iDefId = node.get<int>("defindex");
   m_sClass = node.get("item_class", "<unknown>");
   m_sName  = node.get("item_name", "<unknown>");
   try
   {
     auto wpnProps = node.get_child("attributes");
     m_bCanCrit = ( std::find_if(wpnProps.begin(), wpnProps.end(), [](const boost::property_tree::ptree::value_type& attrib)
       { 
         return ((attrib.second.get("class", "") == "mult_crit_chance") &&
           (attrib.second.get<float>("value") == 0));
       } ) == wpnProps.end() );
   }
  catch(const boost::property_tree::ptree_error& e)
   {
     m_bCanCrit = true;
  };
  UpdateFilteredName(m_sName);
 };
void XSDSchemaParser::parseKey(const pt::ptree &keyTree)
{
    std::string keyName = getXSDAttributeValue(keyTree, "<xmlattr>.name");
    bool duplicateOk = keyTree.get("<xmlattr>.hpcc:allowDuplicate", "false") == "true";
    std::string elementName = getXSDAttributeValue(keyTree, "xs:selector.<xmlattr>.xpath", false, "");
    std::string attrName = getXSDAttributeValue(keyTree, "xs:field.<xmlattr>.xpath", false, "");
    std::string attributeName;

    if (attrName.find_first_of('@') != std::string::npos)
    {
        attributeName = attrName.substr(attrName.find_first_of('@') + 1);
    }
    else
    {
        attributeName = attrName;
    }

    m_pSchemaItem->addUniqueAttributeValueSetDefinition(keyName, elementName, attributeName, duplicateOk);
}
Esempio n. 12
0
void Split::updateConfig(const boost::property_tree::ptree &pt) 
{
    BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ <<  " " << id();
    


    _in_cloud = pt.get("inputs.cloud", _in_cloud);

    _out_inliers = pt.get("outputs.inliers", _out_inliers);
    _out_outliers = pt.get("outputs.outliers", _out_outliers);

    _axis = pt.get("axis", _axis);
    _min = pt.get("min", _min);
    _max = pt.get("max", _max);

    _axis = pt.get("options.axis", _axis);
    _min = pt.get("options.min", _min);
    _max = pt.get("options.max", _max);

}
Esempio n. 13
0
void hydrator::read_element(const boost::property_tree::ptree& pt,
    yarn::intermediate_model& m) const {

    yarn::name_builder b;
    const auto in_global_module(pt.get(in_global_module_key, false));
    if (!in_global_module)
        b.model_name(m.name().location());

    const auto simple_name_value(pt.get<std::string>(simple_name_key));
    b.simple_name(simple_name_value);

    const auto i(pt.find(internal_modules_key));
    if (i != pt.not_found()) {
        std::list<std::string> ipp;
        for (auto& item : pt.get_child(internal_modules_key))
            ipp.push_back(item.second.get_value<std::string>());

        if (!ipp.empty())
            b.internal_modules(ipp);
        else {
            BOOST_LOG_SEV(lg, debug) << "Ignoring empty internal module path. "
                                     << "Type: " << simple_name_value;
        }
    }

    yarn::name n(b.build());
    const auto documentation(pt.get_optional<std::string>(documentation_key));

    const auto lambda([&](yarn::element& e) {
            BOOST_LOG_SEV(lg, debug) << "Processing element: " << n.qualified();
            e.name(n);
            e.origin_type(m.origin_type());
            e.generation_type(m.generation_type());
            e.in_global_module(in_global_module);

            if (documentation)
                e.documentation(*documentation);

            const auto scope(dynamic::scope_types::entity);
            e.extensions(create_dynamic_extensions(pt, scope));
        });

    const auto meta_type_value(pt.get<std::string>(meta_type_key));
    if (meta_type_value == meta_type_object_value) {
        yarn::object o;
        lambda(o);

        const auto ot(pt.get_optional<std::string>(object_type_key));
        o.object_type(to_object_type(ot));
        m.objects().insert(std::make_pair(n.qualified(), o));
    } else if (meta_type_value == meta_type_primitive_value) {
        yarn::primitive p;
        const auto dit(pt.get(is_default_enumeration_type_key, false));
        p.is_default_enumeration_type(dit);
        lambda(p);
        m.primitives().insert(std::make_pair(n.qualified(), p));
    }
    else {
        BOOST_LOG_SEV(lg, error) << invalid_meta_type << meta_type_value;
        BOOST_THROW_EXCEPTION(
            hydration_error(invalid_meta_type + meta_type_value));
    }
}
Esempio n. 14
0
void CompShapeCircle::loadFromPropertyTree(const boost::property_tree::ptree& propTree)
{
    m_center.x = propTree.get("circle.x", 0.0f);
    m_center.y = propTree.get("circle.y", 0.0f);
    m_radius = propTree.get("circle.r", 1.0f);
}
Esempio n. 15
0
void setup_subchannel_from_ptree(dabSubchannel* subchan,
        boost::property_tree::ptree &pt,
        std::shared_ptr<dabEnsemble> ensemble,
        string subchanuid,
        std::shared_ptr<BaseRemoteController> rc)
{
    using boost::property_tree::ptree;
    using boost::property_tree::ptree_error;

    string type;
    /* Read type first */
    try {
        type = pt.get<string>("type");
    }
    catch (ptree_error &e) {
        stringstream ss;
        ss << "Subchannel with uid " << subchanuid << " has no type defined!";
        throw runtime_error(ss.str());
    }

    string inputUri = "";
    // fail if no inputUri given unless type is test
    if (type != "test") {
        inputUri = pt.get<string>("inputuri", "");

        if (inputUri == "") {
            try {
                inputUri = pt.get<string>("inputfile");
            }
            catch (ptree_error &e) {
                stringstream ss;
                ss << "Subchannel with uid " << subchanuid << " has no inputUri defined!";
                throw runtime_error(ss.str());
            }
        }
    }

    string proto;
    size_t protopos = inputUri.find("://");
    if (protopos == string::npos) {
        proto = "file";
    }
    else {
        proto = inputUri.substr(0, protopos);
    }

    subchan->inputUri = inputUri;

    /* The input is of the old_style type,
     * with the struct of function pointers,
     * and needs to be a DabInputCompatible
     */
    bool input_is_old_style = true;
    dabInputOperations operations;
    dabProtection* protection = &subchan->protection;


    if (0) {
#if defined(HAVE_FORMAT_MPEG)
    } else if (type == "audio") {
        subchan->type = subchannel_type_t::Audio;
        subchan->bitrate = 0;

        if (0) {
#if defined(HAVE_INPUT_FILE)
        } else if (proto == "file") {
            operations = dabInputMpegFileOperations;
#endif // defined(HAVE_INPUT_FILE)
#if defined(HAVE_INPUT_ZEROMQ)
        }
        else if (proto == "tcp"  ||
                 proto == "epmg" ||
                 proto == "ipc") {
            input_is_old_style = false;

            dab_input_zmq_config_t zmqconfig;

            try {
                zmqconfig.buffer_size = pt.get<int>("zmq-buffer");
            }
            catch (ptree_error &e) {
                stringstream ss;
                ss << "ZMQ Subchannel with uid " << subchanuid <<
                    " has no zmq-buffer defined!";
                throw runtime_error(ss.str());
            }
            try {
                zmqconfig.prebuffering = pt.get<int>("zmq-prebuffering");
            }
            catch (ptree_error &e) {
                stringstream ss;
                ss << "ZMQ Subchannel with uid " << subchanuid <<
                    " has no zmq-buffer defined!";
                throw runtime_error(ss.str());
            }
            zmqconfig.enable_encryption = false;

            DabInputZmqMPEG* inzmq =
                new DabInputZmqMPEG(subchanuid, zmqconfig);
            inzmq->enrol_at(*rc);
            subchan->input     = inzmq;

            if (proto == "epmg") {
                etiLog.level(warn) << "Using untested epmg:// zeromq input";
            }
            else if (proto == "ipc") {
                etiLog.level(warn) << "Using untested ipc:// zeromq input";
            }
#endif // defined(HAVE_INPUT_ZEROMQ)
        } else {
            stringstream ss;
            ss << "Subchannel with uid " << subchanuid <<
                ": Invalid protocol for MPEG input (" <<
                proto << ")" << endl;
            throw runtime_error(ss.str());
        }
#endif // defined(HAVE_INPUT_FILE) && defined(HAVE_FORMAT_MPEG)
#if defined(HAVE_FORMAT_DABPLUS)
    } else if (type == "dabplus") {
        subchan->type = subchannel_type_t::Audio;
        subchan->bitrate = 32;

        if (0) {
#if defined(HAVE_INPUT_FILE)
        } else if (proto == "file") {
            operations = dabInputDabplusFileOperations;
#endif // defined(HAVE_INPUT_FILE)
#if defined(HAVE_INPUT_ZEROMQ)
        }
        else if (proto == "tcp"  ||
                 proto == "epmg" ||
                 proto == "ipc") {
            input_is_old_style = false;

            dab_input_zmq_config_t zmqconfig;

            try {
                zmqconfig.buffer_size = pt.get<int>("zmq-buffer");
            }
            catch (ptree_error &e) {
                stringstream ss;
                ss << "ZMQ Subchannel with uid " << subchanuid <<
                    " has no zmq-buffer defined!";
                throw runtime_error(ss.str());
            }

            try {
                zmqconfig.prebuffering = pt.get<int>("zmq-prebuffering");
            }
            catch (ptree_error &e) {
                stringstream ss;
                ss << "ZMQ Subchannel with uid " << subchanuid <<
                    " has no zmq-buffer defined!";
                throw runtime_error(ss.str());
            }

            zmqconfig.curve_encoder_keyfile = pt.get<string>("encoder-key","");
            zmqconfig.curve_secret_keyfile = pt.get<string>("secret-key","");
            zmqconfig.curve_public_keyfile = pt.get<string>("public-key","");

            zmqconfig.enable_encryption = pt.get<int>("encryption", 0);

            DabInputZmqAAC* inzmq =
                new DabInputZmqAAC(subchanuid, zmqconfig);

            inzmq->enrol_at(*rc);
            subchan->input     = inzmq;

            if (proto == "epmg") {
                etiLog.level(warn) << "Using untested epmg:// zeromq input";
            }
            else if (proto == "ipc") {
                etiLog.level(warn) << "Using untested ipc:// zeromq input";
            }
#endif // defined(HAVE_INPUT_ZEROMQ)
        } else {
            stringstream ss;
            ss << "Subchannel with uid " << subchanuid <<
                ": Invalid protocol for DAB+ input (" <<
                proto << ")" << endl;
            throw runtime_error(ss.str());
        }
#endif // defined(HAVE_FORMAT_DABPLUS)
    } else if (type == "bridge") {
        // TODO default proto should be udp://
        if (0) {
#if defined(HAVE_FORMAT_BRIDGE)
#if defined(HAVE_INPUT_UDP)
        } else if (proto == "udp") {
            operations = dabInputBridgeUdpOperations;
#endif // defined(HAVE_INPUT_UDP)
#if defined(HAVE_INPUT_SLIP)
        } else if (proto == "slip") {
            operations = dabInputSlipOperations;
#endif // defined(HAVE_INPUT_SLIP)
#endif // defined(HAVE_FORMAT_BRIDGE)
        }
    } else if (type == "data") {
        // TODO default proto should be udp://
        if (0) {
#if defined(HAVE_INPUT_UDP)
        } else if (proto == "udp") {
            operations = dabInputUdpOperations;
#endif
#if defined(HAVE_INPUT_PRBS) && defined(HAVE_FORMAT_RAW)
        } else if (proto == "prbs") {
            operations = dabInputPrbsOperations;
#endif
#if defined(HAVE_INPUT_FILE) && defined(HAVE_FORMAT_RAW)
        } else if (proto == "file") {
            operations = dabInputRawFileOperations;
#endif
        } else if (proto == "fifo") {
            operations = dabInputRawFifoOperations;
        } else {
            stringstream ss;
            ss << "Subchannel with uid " << subchanuid << 
                ": Invalid protocol for data input (" <<
                proto << ")" << endl;
            throw runtime_error(ss.str());
        }

        subchan->type = subchannel_type_t::DataDmb;
        subchan->bitrate = DEFAULT_DATA_BITRATE;
#if defined(HAVE_INPUT_TEST) && defined(HAVE_FORMAT_RAW)
    } else if (type == "test") {
        subchan->type = subchannel_type_t::DataDmb;
        subchan->bitrate = DEFAULT_DATA_BITRATE;
        operations = dabInputTestOperations;
#endif // defined(HAVE_INPUT_TEST)) && defined(HAVE_FORMAT_RAW)
#ifdef HAVE_FORMAT_PACKET
    } else if (type == "packet") {
        subchan->type = subchannel_type_t::Packet;
        subchan->bitrate = DEFAULT_PACKET_BITRATE;
#ifdef HAVE_INPUT_FILE
        operations = dabInputPacketFileOperations;
#elif defined(HAVE_INPUT_FIFO)
        operations = dabInputFifoOperations;
#else
#   pragma error("Must define at least one packet input")
#endif // defined(HAVE_INPUT_FILE)
#ifdef HAVE_FORMAT_EPM
    } else if (type == "enhancedpacket") {
        subchan->type = subchannel_type_t::Packet;
        subchan->bitrate = DEFAULT_PACKET_BITRATE;
        operations = dabInputEnhancedPacketFileOperations;
#endif // defined(HAVE_FORMAT_EPM)
#endif // defined(HAVE_FORMAT_PACKET)
#ifdef HAVE_FORMAT_DMB
    } else if (type == "dmb") {
        // TODO default proto should be UDP
        if (0) {
#if defined(HAVE_INPUT_UDP)
        } else if (proto == "udp") {
            operations = dabInputDmbUdpOperations;
#endif
        } else if (proto == "file") {
            operations = dabInputDmbFileOperations;
        } else {
            stringstream ss;
            ss << "Subchannel with uid " << subchanuid << 
                ": Invalid protocol for DMB input (" <<
                proto << ")" << endl;
            throw runtime_error(ss.str());
        }

        subchan->type = subchannel_type_t::DataDmb;
        subchan->bitrate = DEFAULT_DATA_BITRATE;
#endif
    } else {
        stringstream ss;
        ss << "Subchannel with uid " << subchanuid << " has unknown type!";
        throw runtime_error(ss.str());
    }
    subchan->startAddress = 0;

    if (type == "audio") {
        protection->form = UEP;
        protection->level = 2;
        protection->uep.tableIndex = 0;
    } else {
        protection->level = 2;
        protection->form = EEP;
        protection->eep.profile = EEP_A;
    }

    /* Get bitrate */
    try {
        subchan->bitrate = pt.get<int>("bitrate");
        if ((subchan->bitrate & 0x7) != 0) {
            stringstream ss;
            ss << "Subchannel with uid " << subchanuid <<
                ": Bitrate (" << subchan->bitrate << " not a multiple of 8!";
            throw runtime_error(ss.str());
        }
    }
    catch (ptree_error &e) {
        stringstream ss;
        ss << "Error, no bitrate defined for subchannel " << subchanuid;
        throw runtime_error(ss.str());
    }

#if defined(HAVE_INPUT_FIFO) && defined(HAVE_INPUT_FILE)
    /* Get nonblock */
    bool nonblock = pt.get("nonblock", false);
    if (nonblock) {
        switch (subchan->type) {
#ifdef HAVE_FORMAT_PACKET
            case subchannel_type_t::Packet:
                if (operations == dabInputPacketFileOperations) {
                    operations = dabInputFifoOperations;
#ifdef HAVE_FORMAT_EPM
                } else if (operations == dabInputEnhancedPacketFileOperations) {
                    operations = dabInputEnhancedFifoOperations;
#endif // defined(HAVE_FORMAT_EPM)
                } else {
                    stringstream ss;
                    ss << "Error, wrong packet operations for subchannel " <<
                        subchanuid;
                    throw runtime_error(ss.str());
                }
                break;
#endif // defined(HAVE_FORMAT_PACKET)
#ifdef HAVE_FORMAT_MPEG
            case subchannel_type_t::Audio:
                if (operations == dabInputMpegFileOperations) {
                    operations = dabInputMpegFifoOperations;
                } else if (operations == dabInputDabplusFileOperations) {
                    operations = dabInputDabplusFifoOperations;
                } else {
                    stringstream ss;
                    ss << "Error, wrong audio operations for subchannel " <<
                        subchanuid;
                    throw runtime_error(ss.str());
                }
                break;
#endif // defined(HAVE_FORMAT_MPEG)
            case subchannel_type_t::DataDmb:
            case subchannel_type_t::Fidc:
            default:
                stringstream ss;
                ss << "Subchannel with uid " << subchanuid <<
                    " non-blocking I/O only available for audio or packet services!";
                throw runtime_error(ss.str());
        }
#endif // defined(HAVE_INPUT_FIFO) && defined(HAVE_INPUT_FILE)
    }


    /* Get id */

    try {
        subchan->id = hexparse(pt.get<std::string>("id"));
    }
    catch (ptree_error &e) {
        for (int i = 0; i < 64; ++i) { // Find first free subchannel
            vector<dabSubchannel*>::iterator subchannel = getSubchannel(ensemble->subchannels, i);
            if (subchannel == ensemble->subchannels.end()) {
                subchannel = ensemble->subchannels.end() - 1;
                subchan->id = i;
                break;
            }
        }
    }

    /* Get optional protection profile */
    string profile = pt.get("protection-profile", "");

    if (profile == "EEP_A") {
        protection->form = EEP;
        protection->eep.profile = EEP_A;
    }
    else if (profile == "EEP_B") {
        protection->form = EEP;
        protection->eep.profile = EEP_B;
    }
    else if (profile == "UEP") {
        protection->form = UEP;
    }

    /* Get protection level */
    try {
        int level = pt.get<int>("protection");

        if (protection->form == UEP) {
            if ((level < 1) || (level > 5)) {
                stringstream ss;
                ss << "Subchannel with uid " << subchanuid <<
                    ": protection level must be between "
                    "1 to 5 inclusively (current = " << level << " )";
                throw runtime_error(ss.str());
            }
        }
        else if (protection->form == EEP) {
            if ((level < 1) || (level > 4)) {
                stringstream ss;
                ss << "Subchannel with uid " << subchanuid <<
                    ": protection level must be between "
                    "1 to 4 inclusively (current = " << level << " )";
                throw runtime_error(ss.str());
            }
        }
        protection->level = level - 1;
    }
    catch (ptree_error &e) {
        stringstream ss;
        ss << "Subchannel with uid " << subchanuid <<
            ": protection level undefined!";
        throw runtime_error(ss.str());
    }

    /* Create object */
    if (input_is_old_style) {
        subchan->input = new DabInputCompatible(operations);
    }
    // else { it's already been created! }
}
void XSDSchemaParser::parseComplexType(const pt::ptree &typeTree)
{
    std::string complexTypeName = getXSDAttributeValue(typeTree, "<xmlattr>.name", false, "");
    std::string className = typeTree.get("<xmlattr>.hpcc:class", "");
    std::string catName = typeTree.get("<xmlattr>.hpcc:category", "");
    std::string componentName = typeTree.get("<xmlattr>.hpcc:componentName", "");
    std::string displayName = typeTree.get("<xmlattr>.hpcc:displayName", "");

    if (!complexTypeName.empty())
    {
        if (!className.empty())
        {
            if (className == "component")
            {
                std::shared_ptr<SchemaItem> pComponent = std::make_shared<SchemaItem>(complexTypeName, "component", m_pSchemaItem);
                pComponent->setProperty("category", catName);
                pComponent->setProperty("componentName", componentName);
                pComponent->setProperty("displayName", displayName);
                pt::ptree componentTree = typeTree.get_child("", pt::ptree());
                if (!componentTree.empty())
                {
                    std::shared_ptr<XSDComponentParser> pComponentXSDParaser = std::make_shared<XSDComponentParser>(std::dynamic_pointer_cast<SchemaItem>(pComponent));
                    pComponentXSDParaser->parseXSD(typeTree);
                    m_pSchemaItem->addSchemaType(pComponent, complexTypeName);
                }
                else
                {
                    throw(ParseException("Component definition empty: " + displayName));
                }
            }
            else
            {
                throw(ParseException("Unrecognized class name for complex type: " + className));
            }
        }

        //
        // This is a complex type definition of just regular XSD statements, no special format. Create a parser and parse it
        // and add it to the
        else
        {
            std::shared_ptr<SchemaItem> pTypeItem = std::make_shared<SchemaItem>(complexTypeName, "", m_pSchemaItem);
            pt::ptree childTree = typeTree.get_child("", pt::ptree());
            if (!childTree.empty())
            {
                std::shared_ptr<XSDSchemaParser> pXSDParaser = std::make_shared<XSDSchemaParser>(pTypeItem);
                pXSDParaser->parseXSD(childTree);
                m_pSchemaItem->addSchemaType(pTypeItem, complexTypeName);
            }
            else
            {
                throw(ParseException("Complex type definition empty: " + displayName));
            }
        }
    }

    //
    // Just a complexType delimiter, ignore and parse the children
    else
    {
        parseXSD(typeTree.get_child("", pt::ptree()));
    }
}
int ConfigurationReader::GetIntValue(const boost::property_tree::ptree& root, std::string path, int defaultValue) {
	return root.get(path, defaultValue);
}
Esempio n. 18
0
 params(const boost::property_tree::ptree &p) {
     std::vector<vex::backend::command_queue> *ptr = 0;
     ptr = p.get("q", ptr);
     if (ptr) q = *ptr;
 }
Esempio n. 19
0
 void populate(boost::property_tree::ptree& tree, Key&& key, Value&& value, Remaining&&... args)
 {
     this->properties.insert(std::make_pair(key, std::make_pair(tree.get(key, value), value)));
     populate(tree, args...);
 }
void XSDSchemaParser::parseElement(const pt::ptree &elemTree)
{
    std::string elementName = elemTree.get("<xmlattr>.name", "");
    std::string className = elemTree.get("<xmlattr>.hpcc:class", "");
    std::string category = elemTree.get("<xmlattr>.hpcc:category", "");
    std::string displayName = elemTree.get("<xmlattr>.hpcc:displayName", "");
    std::string typeName = elemTree.get("<xmlattr>.type", "");
    unsigned minOccurs = elemTree.get("<xmlattr>.minOccurs", 1);
    std::string maxOccursStr = elemTree.get("<xmlattr>.maxOccurs", "1");
    unsigned maxOccurs = (maxOccursStr != "unbounded") ? stoi(maxOccursStr) : UINTMAX_MAX;

    std::shared_ptr<SchemaItem> pConfigElement = std::make_shared<SchemaItem>(elementName, className, m_pSchemaItem);
    pConfigElement->setProperty("displayName", displayName);
    pConfigElement->setMinInstances(minOccurs);
    pConfigElement->setMaxInstances(maxOccurs);
    pConfigElement->setProperty("category", category);

    pt::ptree childTree = elemTree.get_child("", pt::ptree());

    // special case to set the root since the top level schema can't specify it
    if (category == "root")  // special case to set the root since the top level schema can't specify it
    {
        m_pSchemaItem->setProperty("name", elementName);
        parseXSD(childTree);
    }
    else
    {
        //
        // If a type is specified, then either it's a simple value type (which could be previously defined) for this element, or a named complex type.
        if (!typeName.empty())
        {
            const std::shared_ptr<SchemaType> pSimpleType = m_pSchemaItem->getSchemaValueType(typeName, false);
            if (pSimpleType != nullptr)
            {
                std::shared_ptr<SchemaValue> pCfgValue = std::make_shared<SchemaValue>("");  // no name value since it's the element's value
                pCfgValue->setType(pSimpleType);                      // will throw if type is not defined
                pConfigElement->setItemSchemaValue(pCfgValue);
            }
            else
            {
                std::shared_ptr<SchemaItem> pConfigType = m_pSchemaItem->getSchemaType(typeName, false);
                if (pConfigType != nullptr)
                {
                    //
                    // Insert into this config element the component defined data (attributes, references, etc.)
                    pConfigElement->insertSchemaType(pConfigType);

                    //
                    // Set element min/max instances to that defined by the component type def (ignore values parsed above)
                    pConfigElement->setMinInstances(pConfigType->getMinInstances());
                    pConfigElement->setMaxInstances(pConfigType->getMaxInstances());

                    //
                    // If a component, then set element data (allow overriding with locally parsed values)
                    if (pConfigType->getProperty("className") == "component")
                    {
                        pConfigElement->setProperty("name", (!elementName.empty()) ? elementName : pConfigType->getProperty("name"));
                        pConfigElement->setProperty("className", (!className.empty()) ? className : pConfigType->getProperty("className"));
                        pConfigElement->setProperty("category", (!category.empty()) ? category : pConfigType->getProperty("category"));
                        pConfigElement->setProperty("displayName", (!displayName.empty()) ? displayName : pConfigType->getProperty("displayName"));
                        pConfigElement->setProperty("componentName", pConfigType->getProperty("componentName"));
                    }
                }
                else
                {
                    std::string msg = "Unable to find type " + typeName + " when parsing element " + elementName;
                    throw(ParseException(msg));
                }
            }
        }

        //
        // Now, if there are children, create a parser and have at it
        if (!childTree.empty())
        {
            std::shared_ptr<XSDSchemaParser> pXSDParaser = std::make_shared<XSDSchemaParser>(pConfigElement);
            pXSDParaser->parseXSD(childTree);
        }

        //
        // Add the element
        m_pSchemaItem->addChild(pConfigElement);

    }
}
std::shared_ptr<SchemaValue> XSDSchemaParser::getSchemaValue(const pt::ptree &attr)
{
    std::string attrName = getXSDAttributeValue(attr, "<xmlattr>.name");
    std::shared_ptr<SchemaValue> pCfgValue = std::make_shared<SchemaValue>(attrName);
    pCfgValue->setDisplayName(attr.get("<xmlattr>.hpcc:displayName", attrName));
    pCfgValue->setRequired(attr.get("<xmlattr>.use", "optional") == "required");
    pCfgValue->setTooltip(attr.get("<xmlattr>.hpcc:tooltip", ""));
    pCfgValue->setReadOnly(attr.get("<xmlattr>.hpcc:readOnly", "false") == "true");
    pCfgValue->setHidden(attr.get("<xmlattr>.hpcc:hidden", "false") == "true");
    pCfgValue->setDeprecated(attr.get("<xmlattr>.hpcc:deprecated", "false") == "true");
    pCfgValue->setMirrorFromPath(attr.get("<xmlattr>.hpcc:mirrorFrom", ""));
    pCfgValue->setAutoGenerateType(attr.get("<xmlattr>.hpcc:autoGenerateType", ""));
    pCfgValue->setAutoGenerateValue(attr.get("<xmlattr>.hpcc:autoGenerateValue", ""));
    pCfgValue->setDefaultValue(attr.get("<xmlattr>.default", ""));

    std::string modList = attr.get("<xmlattr>.hpcc:modifiers", "");
    if (modList.length())
    {
        pCfgValue->setModifiers(split(modList, ","));
    }

    std::string typeName = attr.get("<xmlattr>.type", "");
    if (!typeName.empty())
    {
        pCfgValue->setType(m_pSchemaItem->getSchemaValueType(typeName));
    }
    else
    {
        std::shared_ptr<SchemaType> pType = getSchemaType(attr.get_child("xs:simpleType", pt::ptree()), false);
        if (!pType->isValid())
        {
            throw(ParseException("Attribute " + attrName + " does not have a valid type"));
        }
        pCfgValue->setType(pType);
    }
    return pCfgValue;
}
Esempio n. 22
0
 Status serialize(const boost::property_tree::ptree& params,
                  std::string& serialized) {
   serialized = params.get("copy", "");
   return Status(0, "OK");
 }
bool ProduceExcelWorkbook(Excel::_WorkbookPtr &pXLBook,
	const std::wstring &wstrFilename,
	const std::string &strPropellant,
	bool bMetric,
	const boost::property_tree::ptree &tree,
	const std::vector<std::tuple<double, double, double, double, double> > &vReadings,
	std::map<std::wstring, std::wstring> &mapProperties)
{
	if(vReadings.empty())
	{
		return false;
	}
	// Get the active Worksheet and set its name.
	Excel::_WorksheetPtr pXLSheet = pXLBook->ActiveSheet;
	_ASSERT(pXLSheet);
	if(nullptr == pXLSheet)
	{
		return false;
	}

	//
	// Get Max Pressure to calculate the 10% line
	double dPmaxtime = 0.0f;
	double dPmax = GetPmax(dPmaxtime, vReadings);
	double dpTenPercent = dPmax * 0.10f;

	//
	// Need to know the start and stop burn time based on 10% of Pmax:
	double dBurnStartTime = 0.0f;
	double dBurnEndTime = 0.0f;
	LONG lIndexBurnStart = 0;
	LONG lIndexBurnEnd = 0;
	LONG lExcelIndex = 1;
	bool bHaveEndTime = false;
	for(auto entry : vReadings)
	{
		double dPressure = std::get<ePressure>(entry);
		double dTime = std::get<eTime>(entry);
		++lExcelIndex;
		if(dTime <= dPmaxtime)
		{
			if(dPressure < dpTenPercent)
			{
				continue;
			}
			if(0 == lIndexBurnStart)
			{
				dBurnStartTime = dTime;
				lIndexBurnStart = lExcelIndex;
			}
		}
		else
		{
			// Watching the curve downward...
			lIndexBurnEnd = lExcelIndex;
			if(dPressure < dpTenPercent)
			{
				break;
			}
			dBurnEndTime = dTime;
		}
	}
	double dBurnTime = dBurnEndTime - dBurnStartTime;

	//
	// Convert name to a wide string and assign it to the sheet
	std::wstring wstrTabName(wstrFilename);
	SanitizeStringName(wstrTabName);

	//
	// Remove any math operators from the name:
	_bstr_t bstrTabName(SysAllocString(wstrTabName.c_str()));
	pXLSheet->Name = bstrTabName;

	std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
	// std::wstring wstrPropellantName(converter.from_bytes(strPropellant.c_str()));

	//
	// Create seven columns of data: Time, Thrust (LBS), Thrust (N), and Pressure (PSI), ...
	// Construct a safearray of the data
	LONG lIndex = 2;		// Note, 1 based not 0 - will contain # of rows...
	VARIANT saData;
	VARIANT saDataReferences;
	saData.vt = VT_ARRAY | VT_VARIANT;
	saDataReferences.vt = VT_ARRAY | VT_VARIANT;
	{
		SAFEARRAYBOUND sab[2];
		sab[0].lLbound = 1;
		sab[0].cElements = vReadings.size() + 2;
		sab[1].lLbound = 1;
		sab[1].cElements = 7;
		saData.parray = SafeArrayCreate(VT_VARIANT, 2, sab);
		if(saData.parray == nullptr)
		{
			MessageBoxW(HWND_TOP, L"Unable to create safearray for passing data to Excel.", L"Memory error...", MB_TOPMOST | MB_ICONERROR);
			return false;
		}

		//
		// Clean-up safe array when done...
		auto cleanArray = std::experimental::make_scope_exit([&saData]() -> void
		{
			VariantClear(&saData);
		});

		sab[0].lLbound = 1;
		sab[0].cElements = vReadings.size() + 2;
		sab[1].lLbound = 1;
		sab[1].cElements = 5;
		saDataReferences.parray = SafeArrayCreate(VT_VARIANT, 2, sab);
		if(saDataReferences.parray == nullptr)
		{
			MessageBoxW(HWND_TOP, L"Unable to create safearray for passing data to Excel.", L"Memory error...", MB_TOPMOST | MB_ICONERROR);
			return false;
		}

		//
		// Clean-up safe array when done...
		auto cleanRefArray = std::experimental::make_scope_exit([&saDataReferences]() -> void
		{
			VariantClear(&saDataReferences);
		});

		//
		// Labels:
		SafeArrayPutString(*saData.parray, 1, 1, L"Time");
		SafeArrayPutString(*saData.parray, 1, 2, L"Thrust\n(lbs.)");
		SafeArrayPutString(*saData.parray, 1, 3, L"Thrust\n(N)");
		SafeArrayPutString(*saData.parray, 1, 4, L"Pressure\n(PSI)");
		SafeArrayPutString(*saData.parray, 1, 5, L"Threshold");
		SafeArrayPutString(*saData.parray, 1, 6, L"Time\nDelta");
		SafeArrayPutString(*saData.parray, 1, 7, L"Thrust Element\n(N)");

		//
		// Labels for reference data
		SafeArrayPutString(*saDataReferences.parray, 1, 1, L"Time Delta");				// AA
		SafeArrayPutString(*saDataReferences.parray, 1, 2, L"Thrust\n(lbs.)");			// AB
		SafeArrayPutString(*saDataReferences.parray, 1, 3, L"Thrust\n(N)");				// AC
		SafeArrayPutString(*saDataReferences.parray, 1, 4, L"Pressure\n(PSI)");			// AD
		SafeArrayPutString(*saDataReferences.parray, 1, 5, L"Thrust Element\n(N)");		// AE

		LONG lIndexBurnStart = lIndex;
		LONG lIndexBurnEnd = lIndex;
		for(auto data : vReadings)
		{
			double dTime = std::get<eTime>(data);
			double dThrust = std::get<eThrust>(data);
			double dPressure = std::get<ePressure>(data);
			double dThrustLBS = bMetric ? dThrust / g_dNewtonsPerPound : dThrust;
			double dThrustN = bMetric ? dThrust : dThrust * g_dNewtonsPerPound;
			double dTimeDelta = std::get<eTimeDelta>(data);
			double dThrustElementN = std::get<eThrustElementN>(data);

			SafeArrayPutDouble(*saData.parray, lIndex, 1, dTime);			// A
			SafeArrayPutDouble(*saData.parray, lIndex, 2, dThrustLBS);		// B
			SafeArrayPutDouble(*saData.parray, lIndex, 3, dThrustN);		// C
			SafeArrayPutDouble(*saData.parray, lIndex, 4, dPressure);		// D
			std::wstring wstrPmaxCalcCell(L"=IF($D$");
			wstrPmaxCalcCell += std::to_wstring(lIndex);
			wstrPmaxCalcCell += L"<$Q$35,0,$Q$35";
			SafeArrayPutString(*saData.parray, lIndex, 5, wstrPmaxCalcCell);// E (pMax threshold)
			SafeArrayPutDouble(*saData.parray, lIndex, 6, dTimeDelta);		// F
			SafeArrayPutDouble(*saData.parray, lIndex, 7, dThrustElementN);	// G

			//
			// Generate a set of data (to be hidden) which is blank when the real value is below the threshold
			auto fnGenThresholdIFStatement = ([lIndex](std::wstring &wstrStatement, wchar_t wcCol)
			{
				wstrStatement = L"=IF($E$";
				wstrStatement += std::to_wstring(lIndex);
				wstrStatement += L",$";
				wstrStatement += wcCol;
				wstrStatement += L"$";
				wstrStatement += std::to_wstring(lIndex);
				wstrStatement += L",\"\")";
			});

			//
			// Now the references to included data  =IF($E$n,$F$n,"")
			std::wstring wstrRef;
			fnGenThresholdIFStatement(wstrRef, L'F');
			SafeArrayPutString(*saDataReferences.parray, lIndex, 1, wstrRef);// AA (Time Delta)
			fnGenThresholdIFStatement(wstrRef, L'B');
			SafeArrayPutString(*saDataReferences.parray, lIndex, 2, wstrRef);// AB (Thrust LBS.)
			fnGenThresholdIFStatement(wstrRef, L'C');
			SafeArrayPutString(*saDataReferences.parray, lIndex, 3, wstrRef);// AC (Thrust N.)
			fnGenThresholdIFStatement(wstrRef, L'D');
			SafeArrayPutString(*saDataReferences.parray, lIndex, 4, wstrRef);// AD (Pressure)
			fnGenThresholdIFStatement(wstrRef, L'G');
			SafeArrayPutString(*saDataReferences.parray, lIndex, 5, wstrRef);// AE (Thrust Element)

			++lIndex;
		}

		//
		// Insert the data into A1-Gx
		std::wstring wstrDataRange(L"A1:G");
		wstrDataRange += std::to_wstring(lIndex);

		Excel::RangePtr pXLRange = pXLSheet->Range[_variant_t(wstrDataRange.c_str())];
		_ASSERT(pXLRange);
		if(nullptr == pXLRange)
		{
			return false;
		}
		pXLRange->Value2 = saData;

		//
		// Insert the Reference Data in AA - EE
		std::wstring wstrDataRangeRef(L"AA1:AE");
		wstrDataRangeRef += std::to_wstring(lIndex);

		Excel::RangePtr pXLRangeRef = pXLSheet->Range[_variant_t(wstrDataRangeRef.c_str())];
		_ASSERT(pXLRangeRef);
		if(nullptr == pXLRangeRef)
		{
			return false;
		}
		pXLRangeRef->Value2 = saDataReferences;
	}

	//
	// Create a chart showing pressure and thrust curves
	// With a secondary axis for thrust so that curves are near in scale
	// e.g. "ASBLUE3_16!$A$1:$B$457,ASBLUE3_16!$D$1:$D$457"
	std::wstring wstrChartRange(wstrTabName + L"!$A$1:$B$");
	wstrChartRange += std::to_wstring(lIndex);
	wstrChartRange += L",";
	wstrChartRange += wstrTabName;
	wstrChartRange += L"!$D$1:$D$";
	wstrChartRange += std::to_wstring(lIndex);
	_variant_t varChartRangeString(wstrChartRange.c_str());

	//
	// Create the range...
	Excel::RangePtr pChartRange = pXLSheet->Range[varChartRangeString];
	_ASSERT(pChartRange);
	if(nullptr == pChartRange)
	{
		return false;
	}

	//
	// Create the chart -- odd, but this the method for getting it embedded on
	// the same page as the data...
	auto pShapes = pXLSheet->GetShapes();
	_ASSERT(pShapes);
	if(nullptr == pShapes)
	{
		return false;
	}

	// auto pChartShape = pShapes->AddChart2(240, Excel::xlXYScatter); <- Requires Excel 2013
	auto pChartShape = pShapes->AddChart(Excel::xlXYScatter);
	_ASSERT(pChartShape);
	if(nullptr == pChartShape)
	{
		return false;
	}
	pChartShape->Select();

	//
	// With the newly created Chart Shape we can access it's chart with Workbook::GetActiveChart()
	// And set the source data to the range created previously...
	auto pChart = pXLBook->GetActiveChart();
	_ASSERT(pChart);
	if(nullptr == pChart)
	{
		return false;
	}
	pChart->SetSourceData(pChartRange);

	//
	// Set the Chart Title
	pChart->PutHasTitle(LOCALE_USER_DEFAULT, VARIANT_TRUE);
	auto pChartTitle = pChart->ChartTitle;
	_ASSERT(pChartTitle);
	if(nullptr != pChartTitle)
	{
		pChartTitle->Select();
		pChartTitle->Text = _bstr_t(L"Pressure and Thrust");
	}

	//
	// Setup as a custom chart with stacked lines and a secondary axis
	Excel::SeriesPtr pFSC1 = pChart->SeriesCollection(variant_t(1));
	Excel::SeriesPtr pFSC2 = pChart->SeriesCollection(variant_t(2));
	_ASSERT(pFSC1);
	_ASSERT(pFSC2);
	if(nullptr == pFSC1 || nullptr == pFSC2)
	{
		return false;
	}
	pFSC1->ChartType = Excel::xlLineStacked;
	pFSC1->AxisGroup = Excel::xlSecondary;
	pFSC2->ChartType = Excel::xlLineStacked;
	pFSC2->AxisGroup = Excel::xlPrimary;

	//
	// Make the axis labels appear (left for PSI, bottom for time, and right for thrust)
	pChart->SetElement(Office::msoElementPrimaryCategoryAxisTitleAdjacentToAxis);
	pChart->SetElement(Office::msoElementPrimaryValueAxisTitleRotated);
	pChart->SetElement(Office::msoElementSecondaryValueAxisTitleAdjacentToAxis);

	//
	// Set the bottom (Primary - Category) axis title to "time":
	Excel::AxisPtr pPrimaryAxes = pChart->Axes(Excel::xlCategory, Excel::xlPrimary);
	_ASSERT(pPrimaryAxes);
	if(nullptr == pPrimaryAxes)
	{
		return false;
	}

	Excel::AxisTitlePtr pPrimaryAxisTitle = pPrimaryAxes->AxisTitle;
	_ASSERT(pPrimaryAxisTitle);
	if(nullptr == pPrimaryAxisTitle)
	{
		return false;
	}
	pPrimaryAxisTitle->Select();
	_bstr_t bstrTime(L"Time");
	pPrimaryAxisTitle->Text = bstrTime;

	//
	// Set the left (Primary - Value) axis title to "PSI":
	_bstr_t bstrPSI(L"PSI");
	Excel::AxisPtr pPrimaryVAxes = pChart->Axes(Excel::xlValue, Excel::xlPrimary);
	_ASSERT(pPrimaryVAxes);
	if(nullptr == pPrimaryVAxes)
	{
		return false;
	}
	Excel::AxisTitlePtr pPrimaryVAxisTitle = pPrimaryVAxes->AxisTitle;
	_ASSERT(pPrimaryVAxisTitle);
	if(nullptr == pPrimaryVAxisTitle)
	{
		return false;
	}
	pPrimaryVAxisTitle->Select();
	pPrimaryVAxisTitle->Text = bstrPSI;

	//
	// Set the right (Secondary - Value) axis title to "Pounds of Thrust"
	Excel::AxisPtr pSecondaryAxes = pChart->Axes(Excel::xlValue, Excel::xlSecondary);
	_ASSERT(pSecondaryAxes);
	if(nullptr == pSecondaryAxes)
	{
		return false;
	}
	Excel::AxisTitlePtr pSecondaryAxisTitle = pSecondaryAxes->AxisTitle;
	_ASSERT(pSecondaryAxisTitle);
	if(nullptr == pSecondaryAxisTitle)
	{
		return false;
	}
	pSecondaryAxisTitle->Text = _bstr_t(L"Pounds of Thrust");

	//
	// Move chart into place and give a good size:
	Excel::ChartAreaPtr pChartArea = pChart->GetChartArea(0);
	_ASSERT(pChartArea);
	if(nullptr == pChartArea)
	{
		return false;
	}
	pChartArea->PutLeft(365.0f);
	pChartArea->PutTop(52.0f);
	pChartArea->PutHeight(300.0f);
	pChartArea->PutWidth(500.0f);

	//
	// Set Gridlines
	pChart->SetElement(Office::msoElementPrimaryCategoryGridLinesNone);
	pChart->SetElement(Office::msoElementPrimaryValueGridLinesNone);
	pChart->SetElement(Office::msoElementPrimaryValueGridLinesMajor);
	pChart->SetElement(Office::msoElementPrimaryValueGridLinesNone);
	pChart->SetElement(Office::msoElementPrimaryValueGridLinesMinor);

	//
	// Add the 10% Pmax line:
	Excel::SeriesCollectionPtr pSeriesCol = pChart->SeriesCollection();
	_ASSERT(pSeriesCol);
	if(nullptr == pSeriesCol)
	{
		return false;
	}
	Excel::SeriesPtr pPmaxSeries = pSeriesCol->NewSeries();
	_ASSERT(pPmaxSeries);
	if(nullptr == pPmaxSeries)
	{
		return false;
	}
	pPmaxSeries->Name = _bstr_t(L"Action Time");

	std::wstring wstrPmaxValue(L"=");
	wstrPmaxValue += wstrTabName;
	std::wstring wstrPmaxXValue(wstrPmaxValue);
	wstrPmaxValue += L"!$E$2:$E$";
	wstrPmaxXValue += L"!$A$2:$A$";
	wstrPmaxValue += std::to_wstring(lIndex);
	wstrPmaxXValue += std::to_wstring(lIndex);
	pPmaxSeries->Values = _bstr_t(wstrPmaxValue.c_str());
	pPmaxSeries->XValues = _bstr_t(wstrPmaxXValue.c_str());
	pPmaxSeries->ChartType = Excel::xlLine;
	pPmaxSeries->AxisGroup = Excel::xlPrimary;

	std::wstring wstrPressureRange(L"(D2:D");
	wstrPressureRange += std::to_wstring(lIndex);
	wstrPressureRange += L")";

	//
	// Display other file data...
	const std::string strGrains(tree.get("Document.MotorData.Grains", "0"));
	const std::string strCaseDiameter(tree.get("Document.MotorData.CaseDiameter", "0 mm"));
	const std::string strNozzleThroat(tree.get("Document.MotorData.NozzleThroatDiameter", "0"));
	std::string strInfo(strGrains + " grain " + strCaseDiameter + " " + strPropellant + " with " + strNozzleThroat + "\" throat 'nozzle'");
	std::wstring wstrInfo(converter.from_bytes(strInfo.c_str()));
	std::wstring wstrInfoRange(L"K1");

	Excel::RangePtr pInfoRange = pXLSheet->Range[_variant_t(wstrInfoRange.c_str())];
	_ASSERT(pInfoRange);
	if(nullptr == pInfoRange)
	{
		return false;
	}
	pInfoRange->Value2 = _bstr_t(wstrInfo.c_str());

	//
	// Add calculated data: ???  5% line and other calculated data...
	// <doc name, display name, display location row letter, display location cell number, metric conversion>
	std::vector<std::tuple<std::string, std::wstring, wchar_t, int, bool> > vFileItemDisplay;
	vFileItemDisplay.push_back(std::make_tuple("Document.MotorData.MaxThrust", L"Maximum Thrust:", L'K', 25, true));
	vFileItemDisplay.push_back(std::make_tuple("Document.MotorData.AvgThrust", L"Average Thrust:", L'K', 26, true));
	vFileItemDisplay.push_back(std::make_tuple("Document.MotorData.MaxPressure", L"Maximum Pressure:", L'K', 28, false));
	vFileItemDisplay.push_back(std::make_tuple("Document.MotorData.AvgPressure", L"Average Pressure:", L'K', 29, false));
	vFileItemDisplay.push_back(std::make_tuple("Document.MotorData.BurnTime", L"Burn Time:", L'K', 31, false));
	vFileItemDisplay.push_back(std::make_tuple("Document.MotorData.Impuse", L"Impulse:", L'K', 32, false));	// NOTE: Spelling mistake in the TC Logger data!

	PlaceStringInCell(pXLSheet, L'L', 24, L"TC Logger File Data:");
	for(auto entry : vFileItemDisplay)
	{
		std::wstring wstrDisplay(std::get<1>(entry));

		double dData = tree.get(std::get<0>(entry).c_str(), 0.0f);
		bool bConversion = std::get<4>(entry);

		const wchar_t wcColumn = std::get<2>(entry);
		const wchar_t wcDataColumn = wcColumn + 2;
		int row = std::get<3>(entry);

		PlaceStringInCell(pXLSheet, wcColumn, row, wstrDisplay);
		if(bConversion)
		{
			double dThrustLBS = bMetric ? dData / g_dNewtonsPerPound : dData;
			double dThrustN = bMetric ? dData : dData * g_dNewtonsPerPound;

			PlaceStringInCell(pXLSheet, wcDataColumn, row, std::to_wstring(dThrustLBS));
			PlaceStringInCell(pXLSheet, wcDataColumn + 1, row, L"LBS.");
			PlaceStringInCell(pXLSheet, wcDataColumn + 2, row, std::to_wstring(dThrustN));
			PlaceStringInCell(pXLSheet, wcDataColumn + 3, row, L"N");
		}
		else
		{
			PlaceStringInCell(pXLSheet, wcDataColumn, row, std::to_wstring(dData));
		}
	}

	PlaceStringInCell(pXLSheet, L'I', 34, L"VARIABLES:");
	//
	// Percent of Pmax used for calculations
	PlaceStringInCell(pXLSheet, L'I', 35, L"% Pmax for Burn threshold:");
	PlaceStringInCell(pXLSheet, L'L', 35, mapProperties[L"PmaxThreshold"]);		// 10% by default gives Action Time according to Sutton
	PlaceStringInCell(pXLSheet, L'M', 35, L"Pmax:");
	std::wstring wstrPmaxCalc(L"=MAX");
	wstrPmaxCalc += wstrPressureRange;
	PlaceStringInCell(pXLSheet, L'N', 35, wstrPmaxCalc);
	PlaceStringInCell(pXLSheet, L'O', 35, L"Pmax Threshold:");
	PlaceStringInCell(pXLSheet, L'Q', 35, L"=($N$35*($L$35/100))");		// Q35

	//
	// Grain Weight (g):			[178]
	PlaceStringInCell(pXLSheet, L'I', 36, L"Grain Weight (g):");
	PlaceStringInCell(pXLSheet, L'L', 36, mapProperties[L"GrainWeight"]);

	// Liner Weight g/in:			[ 1.9197342 ] or [ 3.030928 ]
	PlaceStringInCell(pXLSheet, L'I', 37, L"Casting Tube Weight (g/in.):");
	PlaceStringInCell(pXLSheet, L'L', 37, mapProperties[L"CastingTubeWeight"]);
	// PlaceStringInCell(pXLSheet, L'M', 37, L"White 54mm casting tube: 1.9197342 g/in.  Tru-Core Waxy 54mm: 3.030928 g/in");

	// Grain Length:				[ 3.0625 ]
	PlaceStringInCell(pXLSheet, L'I', 38, L"Grain Length (in.):");
	PlaceStringInCell(pXLSheet, L'L', 38, mapProperties[L"GrainLength"]);

	// Grain Diameter (in.):		[ 1.75 ]
	PlaceStringInCell(pXLSheet, L'I', 39, L"Grain Diameter (in.):");
	PlaceStringInCell(pXLSheet, L'L', 39, mapProperties[L"GrainDiameter"]);

	// Grain Core (in.):			[ 0.625 ]
	PlaceStringInCell(pXLSheet, L'I', 40, L"Grain Core (in.):");
	PlaceStringInCell(pXLSheet, L'L', 40, mapProperties[L"GrainCore"]);

	//
	// Our calculations (using Excel formulas so input can be changed)...
	PlaceStringInCell(pXLSheet, L'I', 42, L"Calculations based on Pmax Threshold:");

	// Density:
	PlaceStringInCell(pXLSheet, L'I', 43, L"Density:");
	PlaceStringInCell(pXLSheet, L'L', 43, L"=((L36-(L38*L37))/453.59237)/(((((L39/2)^2)-(L40/2)^2))*PI()*L38)");

	// Web
	PlaceStringInCell(pXLSheet, L'I', 44, L"Web:");
	PlaceStringInCell(pXLSheet, L'L', 44, L"=(L39-L40)/2");

	// Burn Time (s)
	PlaceStringInCell(pXLSheet, L'I', 45, L"Burn Time (s):");
	std::wstring wstrBurnTime(L"=SUM(AA1:AA");
	wstrBurnTime += std::to_wstring(lIndex);
	PlaceStringInCell(pXLSheet, L'L', 45, wstrBurnTime);
	PlaceStringInCell(pXLSheet, L'M', 45, std::wstring(L"10% = " + std::to_wstring(dBurnTime)));

	// Max Pressure
	PlaceStringInCell(pXLSheet, L'I', 46, L"Max Pressure (PSI):");
	std::wstring wstrBtPressureRange(L"(AD1:AD");
	wstrBtPressureRange += std::to_wstring(lIndex);
	wstrBtPressureRange += L")";

	std::wstring wstrMaxPressure(L"=MAX");
	wstrMaxPressure += wstrBtPressureRange;
	PlaceStringInCell(pXLSheet, L'L', 46, wstrMaxPressure);

	// Average Pressure
	PlaceStringInCell(pXLSheet, L'I', 47, L"Average Pressure (PSI):");
	std::wstring wstrAvgPressure(L"=AVERAGE");
	wstrAvgPressure += wstrBtPressureRange;
	PlaceStringInCell(pXLSheet, L'L', 47, wstrAvgPressure);

	std::wstring wstrThrustRange(L"(AB1:AB");
	std::wstring wstrThrustRangeN(L"(AC1:AC");
	std::wstring wstrThrustElementRangeN(L"(AE1:AE");
	wstrThrustRange += std::to_wstring(lIndex);
	wstrThrustRangeN += std::to_wstring(lIndex);
	wstrThrustElementRangeN += std::to_wstring(lIndex);
	wstrThrustRange += L")";
	wstrThrustRangeN += L")";
	wstrThrustElementRangeN += L")";

	// Max Thrust (LBS)
	PlaceStringInCell(pXLSheet, L'I', 48, L"Max Thrust (LBS):");
	std::wstring wstrMaxThrust(L"=MAX");
	wstrMaxThrust += wstrThrustRange;
	PlaceStringInCell(pXLSheet, L'L', 48, wstrMaxThrust);

	// Max Thrust (N)
	PlaceStringInCell(pXLSheet, L'I', 49, L"Max Thrust (N):");
	std::wstring wstrMaxThrustN(L"=MAX");
	wstrMaxThrustN += wstrThrustRangeN;
	PlaceStringInCell(pXLSheet, L'L', 49, wstrMaxThrustN);

	// Average Thrust (LBS)
	PlaceStringInCell(pXLSheet, L'I', 50, L"Average Thrust (LBS):");
	std::wstring wstrAvgThrust(L"=AVERAGE");
	wstrAvgThrust += wstrThrustRange;
	PlaceStringInCell(pXLSheet, L'L', 50, wstrAvgThrust);

	// Average Thrust (N)
	PlaceStringInCell(pXLSheet, L'I', 51, L"Average Thrust (N):");
	std::wstring wstrAvgThrustN(L"=AVERAGE");
	wstrAvgThrustN += wstrThrustRangeN;
	PlaceStringInCell(pXLSheet, L'L', 51, wstrAvgThrustN);

	// Total Thrust:
	PlaceStringInCell(pXLSheet, L'I', 52, L"Total Thrust (N):");
	std::wstring wstrTotalThrustN(L"=SUM");
	wstrTotalThrustN += wstrThrustElementRangeN;
	PlaceStringInCell(pXLSheet, L'L', 52, wstrTotalThrustN);

	// Grain Weight minus Liner:
	PlaceStringInCell(pXLSheet, L'I', 53, L"Propellant Weight (g):");
	PlaceStringInCell(pXLSheet, L'L', 53, L"=(L36-(L38*L37))");

	// ISP:
	PlaceStringInCell(pXLSheet, L'I', 55, L"ISP:");
	PlaceStringInCell(pXLSheet, L'L', 55, L"=L52/(9.8*(L53/1000))");

	// Burn Rate:
	PlaceStringInCell(pXLSheet, L'I', 56, L"Burn Rate:");
	PlaceStringInCell(pXLSheet, L'L', 56, L"=(L44/L45)");

	//
	// Make the INPUT area GREEN:
	Excel::RangePtr pVariableRange = pXLSheet->Range[_variant_t(L"I35:L40")];
	_ASSERT(pVariableRange);
	if(nullptr == pVariableRange)
	{
		return false;
	}
	Excel::InteriorPtr pIntVarRange = pVariableRange->Interior;
	_ASSERT(pIntVarRange);
	if(nullptr == pIntVarRange)
	{
		return false;
	}
	pIntVarRange->Pattern = xlSolid;
	pIntVarRange->PatternColorIndex = Excel::xlAutomatic;
	pIntVarRange->Color = 5287936;
	pIntVarRange->TintAndShade = 0;
	pIntVarRange->PatternTintAndShade = 0;

	//
	// Output Area
	Excel::RangePtr pCalcRange = pXLSheet->Range[_variant_t(L"I43:L56")];
	_ASSERT(pCalcRange);
	if(nullptr == pCalcRange)
	{
		return false;
	}
	Excel::InteriorPtr pIntCalcRange = pCalcRange->Interior;
	_ASSERT(pIntCalcRange);
	if(nullptr == pIntCalcRange)
	{
		return false;
	}
	pIntCalcRange->PatternColorIndex = Excel::xlAutomatic;
	pIntCalcRange->Color = 7373816;
	pIntCalcRange->TintAndShade = 0;
	pIntCalcRange->PatternTintAndShade = 0;

	return true;
}