yipo
11/27/2017 - 5:24 PM

Report for Jaspal

Report for Jaspal

#include <chrono>
#include <ctime>

#include <iomanip>
#include <iostream>
#include <sstream>

#include <map>
#include <string>
#include <vector>

using namespace std;
using sys_clock = chrono::system_clock;

class jaspal_report
{
public:
    jaspal_report(istream &is)
    {
        while (is.peek() != EOF) parse_block(is);
    }

private:
    void parse_block(istream &is)
    {
        string title;
        getline(is, title);

        string subtitle;
        getline(is, subtitle);

        string header;
        getline(is, header);

        header.resize(header.rfind(',')); // Remove the last column ('total').
        const auto header_cols = parse_header(istringstream(header));

        string row;
        while (getline(is, row) && parse_row(istringstream(row), header_cols));

        string empty;
        getline(is, empty);
    }

    vector<sys_clock::time_point> parse_header(istream &is)
    {
        string server;
        getline(is, server, ',');

        string service;
        getline(is, service, ',');

        string device;
        getline(is, device, ',');

        string counter;
        getline(is, counter, ',');

        vector<sys_clock::time_point> cols;

        string buf, to;
        while (getline(is, buf, ','))
        {
            tm t = { 0 };

            istringstream iss(buf);
            iss >> get_time(&t, "%Y/%m/%d %R");
            if (iss >> to) iss >> get_time(&t, "%R");

            cols.push_back(sys_clock::from_time_t(mktime(&t)));
        }

        return cols;
    }

    bool parse_row(istream &is, const vector<sys_clock::time_point> &cols)
    {
        string server;
        getline(is, server, ',');

        if (server.empty()) return false;

        string service;
        getline(is, service, ',');

        string device;
        getline(is, device, ',');

        string counter;
        getline(is, counter, ',');

        for (const auto col : cols)
        {
            string buf;
            getline(is, buf, ',');

            int value;
            istringstream(buf) >> value;

            m_table[make_tuple(col, server)] += value; // Add up the value from different counters of the same server.
        }

        return true;
    }

    void dump(ostream &os) const
    {
        os << "Datetime,Branch Code,In" << endl;

        for (const auto pair : m_table)
        {
            sys_clock::time_point datetime;
            string server;

            tie(datetime, server) = pair.first;
            int value = pair.second;

            time_t t = sys_clock::to_time_t(datetime);
            os << put_time(localtime(&t), "%m-%d-%y %R") << "," << server << "," << value << endl;
        }
    }

    friend ostream &operator <<(ostream &os, const jaspal_report &report)
    {
        report.dump(os);
        return os;
    }

private:
    map<tuple<sys_clock::time_point, string>, int> m_table;
};

int main()
{
    cout << jaspal_report(cin);
    return 0;
}