From 0f262fd10d337db0ec435d840b541d629879ce9f Mon Sep 17 00:00:00 2001 From: Tim Moore Date: Wed, 20 May 2009 13:29:54 +0200 Subject: [PATCH] Add CSV syntax support to the grapher * grapher/GraphData.hxx (CSVData): new class * grapher/GraphData.cxx (commaSplit): new function (ioCallback): handle CSV definition and data --- grapher/GraphData.hxx | 7 ++++ grapher/StapParser.cxx | 80 ++++++++++++++++++++++++++++++++++++------ grapher/StapParser.hxx | 1 + 3 files changed, 78 insertions(+), 10 deletions(-) diff --git a/grapher/GraphData.hxx b/grapher/GraphData.hxx index 0f3b0b314..2c0783c6d 100644 --- a/grapher/GraphData.hxx +++ b/grapher/GraphData.hxx @@ -3,6 +3,7 @@ #include #include +#include namespace systemtap { @@ -40,5 +41,11 @@ namespace systemtap } }; }; + + struct CSVData + { + typedef std::pair > Element; + std::vector elements; + }; } #endif diff --git a/grapher/StapParser.cxx b/grapher/StapParser.cxx index 2bf26324f..c973b0aa8 100644 --- a/grapher/StapParser.cxx +++ b/grapher/StapParser.cxx @@ -4,8 +4,32 @@ namespace systemtap { +using namespace std; + +vector commaSplit(const string& inStr, size_t pos = 0) +{ + size_t found = pos; + vector result; + while (1) + { + + size_t commaPos = inStr.find(',', found); + string token + = inStr.substr(found, (commaPos == string::npos + ? string::npos + : commaPos - 1 - found)); + result.push_back(token); + if (commaPos != string::npos) + found = commaPos + 1; + else + break; + } + return result; +} + bool StapParser::ioCallback(Glib::IOCondition ioCondition) { + using namespace std; if ((ioCondition & Glib::IO_IN) == 0) return true; char buf[256]; @@ -18,8 +42,8 @@ bool StapParser::ioCallback(Glib::IOCondition ioCondition) } buf[bytes_read] = '\0'; _buffer += buf; - std::string::size_type ret = std::string::npos; - while ((ret = _buffer.find('\n')) != std::string::npos) + string::size_type ret = string::npos; + while ((ret = _buffer.find('\n')) != string::npos) { Glib::ustring dataString(_buffer, 0, ret); if (dataString[0] == '%') @@ -62,17 +86,53 @@ bool StapParser::ioCallback(Glib::IOCondition ioCondition) _dataSets.insert(std::make_pair(setName, dataSet)); _widget.addGraphData(dataSet); } + else if ((found = dataString.find("%CSV:") == 0)) + { + vector tokens = commaSplit(dataString, found + 5); + for (vector::iterator tokIter = tokens.begin(), + e = tokens.end(); + tokIter != e; + ++tokIter) + { + DataMap::iterator setIter = _dataSets.find(*tokIter); + if (setIter != _dataSets.end()) + _csv.elements.push_back(CSVData::Element(*tokIter, + setIter->second)); + } + } } else { - std::string dataSet; - double time; - double data; - std::istringstream stream(dataString); - stream >> dataSet >> time >> data; - DataMap::iterator itr = _dataSets.find(dataSet); - if (itr != _dataSets.end()) - itr->second->data.push_back(std::make_pair(time, data)); + if (!_csv.elements.empty()) + { + vector tokens = commaSplit(dataString); + int i = 0; + double time; + vector::iterator tokIter = tokens.begin(); + std::istringstream timeStream(*tokIter++); + timeStream >> time; + for (vector::iterator e = tokens.end(); + tokIter != e; + ++tokIter, ++i) + { + std::istringstream stream(*tokIter); + double data; + stream >> data; + _csv.elements[i].second + ->data.push_back(std::make_pair(time, data)); + } + } + else + { + std::string dataSet; + double time; + double data; + std::istringstream stream(dataString); + stream >> dataSet >> time >> data; + DataMap::iterator itr = _dataSets.find(dataSet); + if (itr != _dataSets.end()) + itr->second->data.push_back(std::make_pair(time, data)); + } } _buffer.erase(0, ret + 1); } diff --git a/grapher/StapParser.hxx b/grapher/StapParser.hxx index a94b0a9b9..624accc78 100644 --- a/grapher/StapParser.hxx +++ b/grapher/StapParser.hxx @@ -9,6 +9,7 @@ class StapParser std::string _buffer; typedef std::map > DataMap; DataMap _dataSets; + CSVData _csv; Gtk::Window& _win; GraphWidget& _widget; public: -- 2.43.5