diff options
Diffstat (limited to 'src/table_handler.cpp')
-rw-r--r-- | src/table_handler.cpp | 141 |
1 files changed, 141 insertions, 0 deletions
diff --git a/src/table_handler.cpp b/src/table_handler.cpp new file mode 100644 index 0000000..7d3c185 --- /dev/null +++ b/src/table_handler.cpp @@ -0,0 +1,141 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "table_handler.hpp" + +namespace ixion { + +table_handler::entry::entry() : + name(empty_string_id), range(abs_range_t::invalid), totals_row_count(0) {} + +table_handler::~table_handler() {} + +abs_range_t table_handler::get_range( + const abs_address_t& pos, string_id_t column_first, string_id_t column_last, + table_areas_t areas) const +{ + entries_type::const_iterator it = m_entries.begin(), it_end = m_entries.end(); + for (; it != it_end; ++it) + { + const entry& e = *it->second; + if (!e.range.contains(pos)) + continue; + + return get_column_range(e, column_first, column_last, areas); + } + + return abs_range_t(abs_range_t::invalid); +} + +abs_range_t table_handler::get_range( + string_id_t table, string_id_t column_first, string_id_t column_last, + table_areas_t areas) const +{ + entries_type::const_iterator it = m_entries.find(table); + if (it == m_entries.end()) + // Table name not found. + return abs_range_t(abs_range_t::invalid); + + const entry& e = *it->second; + return get_column_range(e, column_first, column_last, areas); +} + +void table_handler::insert(std::unique_ptr<entry>& p) +{ + if (!p) + return; + + string_id_t name = p->name; + m_entries.insert( + entries_type::value_type( + name, std::unique_ptr<entry>(p.release()))); +} + +void adjust_table_area(abs_range_t& range, const table_handler::entry& e, table_areas_t areas) +{ + bool headers = (areas & table_area_headers); + bool data = (areas & table_area_data); + bool totals = (areas & table_area_totals); + + if (headers) + { + if (data) + { + if (totals) + { + // All areas. + return; + } + + // Headers + data areas + range.last.row -= e.totals_row_count; + return; + } + + // Headers only. + range.last.row = range.first.row; + return; + } + + // No header row. + --range.first.row; + + if (data) + { + if (totals) + { + // Data + totals areas + return; + } + + // Data area only. + range.last.row -= e.totals_row_count; + return; + } + + // Totals area only. + if (e.totals_row_count <= 0) + { + range = abs_range_t(abs_range_t::invalid); + return; + } + + range.first.row = range.last.row; + range.first.row -= e.totals_row_count - 1; +} + +abs_range_t table_handler::get_column_range( + const entry& e, string_id_t column_first, string_id_t column_last, table_areas_t areas) const +{ + if (column_first == empty_string_id) + { + // Area specifiers only. + abs_range_t ret = e.range; + adjust_table_area(ret, e, areas); + return ret; + } + + for (size_t i = 0, n = e.columns.size(); i < n; ++i) + { + if (e.columns[i] == column_first) + { + // Matching column name found. + abs_range_t ret = e.range; + col_t col = e.range.first.column + i; + ret.first.column = col; + ret.last.column = col; + adjust_table_area(ret, e, areas); + return ret; + } + } + + return abs_range_t(abs_range_t::invalid); +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |