Commit 8a16ff17a4ce3a48af63ccc19a2b4ec81b8ec148

Authored by knodlseder
1 parent 5c2d8182

initial version

include/GCsv.hpp 0 → 100644
  1 +/***************************************************************************
  2 + * GCsv.hpp - Column separated values table class *
  3 + * ----------------------------------------------------------------------- *
  4 + * copyright (C) 2010 by Jurgen Knodlseder *
  5 + * ----------------------------------------------------------------------- *
  6 + * *
  7 + * This program is free software; you can redistribute it and/or modify *
  8 + * it under the terms of the GNU General Public License as published by *
  9 + * the Free Software Foundation; either version 2 of the License, or *
  10 + * (at your option) any later version. *
  11 + * *
  12 + ***************************************************************************/
  13 +/**
  14 + * @file GCsv.hpp
  15 + * @brief Column separated values table class definition
  16 + * @author J. Knodlseder
  17 + */
  18 +
  19 +#ifndef GCsv_HPP
  20 +#define GCsv_HPP
  21 +
  22 +/* __ Includes ___________________________________________________________ */
  23 +#include <vector>
  24 +#include <string>
  25 +#include <iostream>
  26 +#include "GLog.hpp"
  27 +
  28 +
  29 +/***********************************************************************//**
  30 + * @class GCsv
  31 + *
  32 + * @brief Column separated values table class definition
  33 + ***************************************************************************/
  34 +class GCsv {
  35 +
  36 + // I/O friends
  37 + friend std::ostream& operator<< (std::ostream& os, const GCsv& csv);
  38 + friend GLog& operator<< (GLog& log, const GCsv& csv);
  39 +
  40 +public:
  41 + // Constructors and destructors
  42 + GCsv(void);
  43 + GCsv(const std::string& filename, std::string sep = " ");
  44 + GCsv(const GCsv& csv);
  45 + virtual ~GCsv(void);
  46 +
  47 + // Operators
  48 + GCsv& operator= (const GCsv& csv);
  49 + std::string& operator() (const int& row, const int& col);
  50 + const std::string& operator() (const int& row, const int& col) const;
  51 +
  52 + // Methods
  53 + void clear(void);
  54 + GCsv* clone(void) const;
  55 + std::string string(const int& row, const int& col) const;
  56 + double real(const int& row, const int& col) const;
  57 + int integer(const int& row, const int& col) const;
  58 + void load(const std::string& filename, std::string sep = " ");
  59 + int ncols(void) const { return m_cols; }
  60 + int nrows(void) const { return m_rows; }
  61 + int size(void) const { return m_rows*m_cols; }
  62 + std::string print(void) const;
  63 +
  64 +protected:
  65 + // Protected methods
  66 + void init_members(void);
  67 + void copy_members(const GCsv& csv);
  68 + void free_members(void);
  69 +
  70 + // Protected data members
  71 + int m_cols; //!< Number of columns
  72 + int m_rows; //!< Number of rows
  73 + std::vector<std::vector<std::string> > m_data; //!< CSV table data
  74 +};
  75 +
  76 +#endif /* GCsv_HPP */
... ...
pyext/GCsv.i 0 → 100644
  1 +/***************************************************************************
  2 + * GCsv.i - Column separated values table class *
  3 + * ----------------------------------------------------------------------- *
  4 + * copyright (C) 2010 by Jurgen Knodlseder *
  5 + * ----------------------------------------------------------------------- *
  6 + * *
  7 + * This program is free software; you can redistribute it and/or modify *
  8 + * it under the terms of the GNU General Public License as published by *
  9 + * the Free Software Foundation; either version 2 of the License, or *
  10 + * (at your option) any later version. *
  11 + * *
  12 + ***************************************************************************/
  13 +/**
  14 + * @file GCsv.hpp
  15 + * @brief Column separated values table class Python bindings
  16 + * @author J. Knodlseder
  17 + */
  18 +%{
  19 +/* Put headers and other declarations here that are needed for compilation */
  20 +#include "GCsv.hpp"
  21 +%}
  22 +%include stl.i
  23 +
  24 +/***********************************************************************//**
  25 + * @brief Tuple to index conversion to provide element access.
  26 + *
  27 + * The following function provides conversion between a Python tuple and
  28 + * an integer array. This allows table element access via tuples, such as in
  29 + * a[3,5] = 10.0 or c = a[2,9]. Note that the typemap will be globally
  30 + * defined after inclusing of this file.
  31 + ***************************************************************************/
  32 +%{
  33 +static int csv_tuple(PyObject *input, int *ptr) {
  34 + if (PySequence_Check(input)) {
  35 + int size = PyObject_Length(input);
  36 + if (size > 2) {
  37 + PyErr_SetString(PyExc_ValueError,"Too many arguments in tuple");
  38 + return 0;
  39 + }
  40 + for (int i = 0; i < size; i++) {
  41 + PyObject *o = PySequence_GetItem(input,i);
  42 + if (!PyInt_Check(o)) {
  43 + Py_XDECREF(o);
  44 + PyErr_SetString(PyExc_ValueError,"Expecting a tuple of integers");
  45 + return 0;
  46 + }
  47 + ptr[i] = (int)PyInt_AsLong(o);
  48 + Py_DECREF(o);
  49 + }
  50 + return 1;
  51 + }
  52 + else {
  53 + ptr[0] = 1;
  54 + if (!PyInt_Check(input)) {
  55 + PyErr_SetString(PyExc_ValueError,"Expecting an integer");
  56 + return 0;
  57 + }
  58 + ptr[1] = (int)PyInt_AsLong(input);
  59 + return 1;
  60 + }
  61 +}
  62 +%}
  63 +%typemap(in) int GCsvInx[ANY](int temp[2]) {
  64 + if (!csv_tuple($input,temp)) {
  65 + return NULL;
  66 + }
  67 + $1 = &temp[0];
  68 +}
  69 +
  70 +
  71 +/***********************************************************************//**
  72 + * @class GCsv
  73 + *
  74 + * @brief Column separated values table class definition
  75 + ***************************************************************************/
  76 +class GCsv {
  77 +public:
  78 + // Constructors and destructors
  79 + GCsv(void);
  80 + GCsv(const std::string& filename, std::string sep = " ");
  81 + GCsv(const GCsv& csv);
  82 + virtual ~GCsv(void);
  83 +
  84 + // Methods
  85 + void clear(void);
  86 + GCsv* clone(void) const;
  87 + std::string string(const int& row, const int& col) const;
  88 + double real(const int& row, const int& col) const;
  89 + int integer(const int& row, const int& col) const;
  90 + void load(const std::string& filename, std::string sep = " ");
  91 + int ncols(void) const { return m_cols; }
  92 + int nrows(void) const { return m_rows; }
  93 + int size(void) const { return m_rows*m_cols; }
  94 +};
  95 +
  96 +
  97 +/***********************************************************************//**
  98 + * @brief GCsv class extension
  99 + ***************************************************************************/
  100 +%extend GCsv {
  101 + char *__str__() {
  102 + static std::string result = self->print();
  103 + return ((char*)result.c_str());
  104 + }
  105 + std::string __getitem__(int GCsvInx[]) {
  106 + return (*self)(GCsvInx[0], GCsvInx[1]);
  107 + }
  108 + void __setitem__(int GCsvInx[], std::string value) {
  109 + (*self)(GCsvInx[0], GCsvInx[1]) = value;
  110 + }
  111 + GCsv copy() {
  112 + return (*self);
  113 + }
  114 +};
... ...
src/support/GCsv.cpp 0 → 100644
  1 +/***************************************************************************
  2 + * GCsv.cpp - Column separated values table class *
  3 + * ----------------------------------------------------------------------- *
  4 + * copyright (C) 2010 by Jurgen Knodlseder *
  5 + * ----------------------------------------------------------------------- *
  6 + * *
  7 + * This program is free software; you can redistribute it and/or modify *
  8 + * it under the terms of the GNU General Public License as published by *
  9 + * the Free Software Foundation; either version 2 of the License, or *
  10 + * (at your option) any later version. *
  11 + * *
  12 + ***************************************************************************/
  13 +/**
  14 + * @file GCsv.cpp
  15 + * @brief Column separated values table class implementation
  16 + * @author J. Knodlseder
  17 + */
  18 +
  19 +/* __ Includes ___________________________________________________________ */
  20 +#ifdef HAVE_CONFIG_H
  21 +#include <config.h>
  22 +#endif
  23 +#include "GCsv.hpp"
  24 +#include "GTools.hpp"
  25 +#include "GException.hpp"
  26 +
  27 +/* __ Method name definitions ____________________________________________ */
  28 +#define G_ACCESS "GCsv::operator() (int&, int&)"
  29 +#define G_LOAD "GCsv::load(std::string&, std::string)"
  30 +
  31 +/* __ Macros _____________________________________________________________ */
  32 +
  33 +/* __ Coding definitions _________________________________________________ */
  34 +
  35 +/* __ Debug definitions __________________________________________________ */
  36 +
  37 +
  38 +/*==========================================================================
  39 + = =
  40 + = Constructors/destructors =
  41 + = =
  42 + ==========================================================================*/
  43 +
  44 +/***********************************************************************//**
  45 + * @brief Void constructor
  46 + ***************************************************************************/
  47 +GCsv::GCsv(void)
  48 +{
  49 + // Initialise private members
  50 + init_members();
  51 +
  52 + // Return
  53 + return;
  54 +}
  55 +
  56 +
  57 +/***********************************************************************//**
  58 + * @brief File constructor
  59 + *
  60 + * @param[in] filename Filename.
  61 + * @param[in] sep Column separator (default is whitespace).
  62 + ***************************************************************************/
  63 +GCsv::GCsv(const std::string& filename, std::string sep)
  64 +{
  65 + // Initialise private
  66 + init_members();
  67 +
  68 + // Load CSV table
  69 + load(filename, sep);
  70 +
  71 + // Return
  72 + return;
  73 +}
  74 +
  75 +
  76 +/***********************************************************************//**
  77 + * @brief Copy constructor
  78 + *
  79 + * @param[in] csv Column separated values table.
  80 + ***************************************************************************/
  81 +GCsv::GCsv(const GCsv& csv)
  82 +{
  83 + // Initialise private
  84 + init_members();
  85 +
  86 + // Copy members
  87 + copy_members(csv);
  88 +
  89 + // Return
  90 + return;
  91 +}
  92 +
  93 +
  94 +/***********************************************************************//**
  95 + * @brief Destructor
  96 + ***************************************************************************/
  97 +GCsv::~GCsv(void)
  98 +{
  99 + // Free members
  100 + free_members();
  101 +
  102 + // Return
  103 + return;
  104 +}
  105 +
  106 +
  107 +/*==========================================================================
  108 + = =
  109 + = Operators =
  110 + = =
  111 + ==========================================================================*/
  112 +
  113 +/***********************************************************************//**
  114 + * @brief Assignment operator
  115 + *
  116 + * @param[in] csv Column separated values table.
  117 + ***************************************************************************/
  118 +GCsv& GCsv::operator= (const GCsv& csv)
  119 +{
  120 + // Execute only if object is not identical
  121 + if (this != &csv) {
  122 +
  123 + // Free members
  124 + free_members();
  125 +
  126 + // Initialise private members for clean destruction
  127 + init_members();
  128 +
  129 + // Copy members
  130 + copy_members(csv);
  131 +
  132 + } // endif: object was not identical
  133 +
  134 + // Return
  135 + return *this;
  136 +}
  137 +
  138 +
  139 +/***********************************************************************//**
  140 + * @brief Table element access operator
  141 + *
  142 + * @param[in] row Table row.
  143 + * @param[in] col Table column.
  144 + ***************************************************************************/
  145 +std::string& GCsv::operator() (const int& row, const int& col)
  146 +{
  147 + // Perform range check
  148 + #if defined(G_RANGE_CHECK)
  149 + if (row < 0 || row >= m_rows || col < 0 || col >= m_cols)
  150 + throw GException::out_of_range(G_ACCESS, row, col, m_rows-1, m_cols-1);
  151 + #endif
  152 +
  153 + // Return element
  154 + return m_data[row][col];
  155 +}
  156 +
  157 +
  158 +/***********************************************************************//**
  159 + * @brief Table element access operator (const version)
  160 + *
  161 + * @param[in] row Table row.
  162 + * @param[in] col Table column.
  163 + ***************************************************************************/
  164 +const std::string& GCsv::operator() (const int& row, const int& col) const
  165 +{
  166 + // Perform range check
  167 + #if defined(G_RANGE_CHECK)
  168 + if (row < 0 || row >= m_rows || col < 0 || col >= m_cols)
  169 + throw GException::out_of_range(G_ACCESS, row, col, m_rows, m_cols);
  170 + #endif
  171 +
  172 + // Return element
  173 + return m_data[row][col];
  174 +}
  175 +
  176 +
  177 +/*==========================================================================
  178 + = =
  179 + = Public methods =
  180 + = =
  181 + ==========================================================================*/
  182 +
  183 +/***********************************************************************//**
  184 + * @brief Clear instance
  185 + *
  186 + * This method properly resets the object to an initial state.
  187 + ***************************************************************************/
  188 +void GCsv::clear(void)
  189 +{
  190 + // Free class members
  191 + free_members();
  192 +
  193 + // Initialise members
  194 + init_members();
  195 +
  196 + // Return
  197 + return;
  198 +}
  199 +
  200 +
  201 +/***********************************************************************//**
  202 + * @brief Clone instance
  203 + **************************************************************************/
  204 +GCsv* GCsv::clone(void) const
  205 +{
  206 + return new GCsv(*this);
  207 +}
  208 +
  209 +
  210 +/***********************************************************************//**
  211 + * @brief Get string value
  212 + *
  213 + * @param[in] row Table row.
  214 + * @param[in] col Table column.
  215 + *
  216 + * Returns value of specified row and column as string.
  217 + ***************************************************************************/
  218 +std::string GCsv::string(const int& row, const int& col) const
  219 +{
  220 + // Return value
  221 + return (*this)(row, col);
  222 +}
  223 +
  224 +
  225 +/***********************************************************************//**
  226 + * @brief Get double precision value
  227 + *
  228 + * @param[in] row Table row.
  229 + * @param[in] col Table column.
  230 + *
  231 + * Returns value of specified row and column as double precision.
  232 + ***************************************************************************/
  233 +double GCsv::real(const int& row, const int& col) const
  234 +{
  235 + // Convert element into double
  236 + double value = todouble((*this)(row, col));
  237 +
  238 + // Return value
  239 + return value;
  240 +}
  241 +
  242 +
  243 +/***********************************************************************//**
  244 + * @brief Get integer value
  245 + *
  246 + * @param[in] row Table row.
  247 + * @param[in] col Table column.
  248 + *
  249 + * Returns value of specified row and column as integer.
  250 + ***************************************************************************/
  251 +int GCsv::integer(const int& row, const int& col) const
  252 +{
  253 + // Convert element into int
  254 + int value = toint((*this)(row, col));
  255 +
  256 + // Return value
  257 + return value;
  258 +}
  259 +
  260 +
  261 +/***********************************************************************//**
  262 + * @brief Load CSV table
  263 + *
  264 + * @param[in] filename Filename.
  265 + * @param[in] sep Column separator (default is whitespace).
  266 + *
  267 + * @exception GException::file_not_found
  268 + * CSV table file not found.
  269 + * @exception GException::cvs_bad_columns
  270 + * Inconsistent columns encountered in CSV table file.
  271 + **************************************************************************/
  272 +void GCsv::load(const std::string& filename, std::string sep)
  273 +{
  274 + // Clear instance
  275 + clear();
  276 +
  277 + // If no seperator is given then assume a whitespace
  278 + if (sep.length() == 0)
  279 + sep = " ";
  280 +
  281 + // Allocate line buffer
  282 + const int n = 10000;
  283 + char line[n];
  284 +
  285 + // Open CSV table (read-only
  286 + FILE* fptr = fopen(filename.c_str(), "r");
  287 + if (fptr == NULL)
  288 + throw GException::file_not_found(G_LOAD, filename);
  289 +
  290 + // Read lines
  291 + int iline = 0;
  292 + while (fgets(line, n, fptr) != NULL) {
  293 +
  294 + // Increment line counter
  295 + iline++;
  296 +
  297 + // Get line with leading and trailing whitespace removed
  298 + std::string sline = strip_whitespace(std::string(line));
  299 +
  300 + // If line is empty or if it contains a single linefeed then skip the line
  301 + if (sline.length() == 0 || (sline.length() == 1 && sline[0] == '\n'))
  302 + continue;
  303 +
  304 + // Split line in elements
  305 + std::vector<std::string> elements = split(sline, sep);
  306 +
  307 + // If this is the first valid line then simply store the elements
  308 + if (m_data.size() == 0) {
  309 + m_data.push_back(elements);
  310 + m_cols = elements.size();
  311 + }
  312 +
  313 + // ... otherwise check table consistency and add elements
  314 + else {
  315 + // Check table consistency
  316 + if (m_cols != elements.size())
  317 + throw GException::cvs_bad_columns(G_LOAD, filename,
  318 + iline, m_cols, elements.size());
  319 +
  320 + // Append elements
  321 + m_data.push_back(elements);
  322 + }
  323 +
  324 + // Increment number of rows
  325 + m_rows++;
  326 +
  327 + } // endwhile: looped over lines
  328 +
  329 + // Close file
  330 + fclose(fptr);
  331 +
  332 + // Return
  333 + return;
  334 +}
  335 +
  336 +
  337 +/***********************************************************************//**
  338 + * @brief Print class information
  339 + ***************************************************************************/
  340 +std::string GCsv::print(void) const
  341 +{
  342 + // Initialise result string
  343 + std::string result;
  344 +
  345 + // Append header
  346 + result.append("=== GCsv ===");
  347 + result.append("\n"+parformat("Number of columns")+str(m_cols));
  348 + result.append("\n"+parformat("Number of rows")+str(m_rows));
  349 +
  350 + // Return result
  351 + return result;
  352 +}
  353 +
  354 +
  355 +/*==========================================================================
  356 + = =
  357 + = Private methods =
  358 + = =
  359 + ==========================================================================*/
  360 +
  361 +/***********************************************************************//**
  362 + * @brief Initialise class members
  363 + ***************************************************************************/
  364 +void GCsv::init_members(void)
  365 +{
  366 + // Initialise members
  367 + m_cols = 0;
  368 + m_rows = 0;
  369 + m_data.clear();
  370 +
  371 + // Return
  372 + return;
  373 +}
  374 +
  375 +
  376 +/***********************************************************************//**
  377 + * @brief Copy class members
  378 + *
  379 + * @param[in] csv Column separated values table.
  380 + ***************************************************************************/
  381 +void GCsv::copy_members(const GCsv& csv)
  382 +{
  383 + // Copy members
  384 + m_cols = csv.m_cols;
  385 + m_rows = csv.m_rows;
  386 + m_data = csv.m_data;
  387 +
  388 + // Return
  389 + return;
  390 +}
  391 +
  392 +
  393 +/***********************************************************************//**
  394 + * @brief Delete class members
  395 + ***************************************************************************/
  396 +void GCsv::free_members(void)
  397 +{
  398 + // Return
  399 + return;
  400 +}
  401 +
  402 +
  403 +/*==========================================================================
  404 + = =
  405 + = Friends =
  406 + = =
  407 + ==========================================================================*/
  408 +
  409 +/***********************************************************************//**
  410 + * @brief Output operator
  411 + *
  412 + * @param[in] os Output stream.
  413 + * @param[in] csv Column separated values table.
  414 + ***************************************************************************/
  415 +std::ostream& operator<< (std::ostream& os, const GCsv& csv)
  416 +{
  417 + // Write CSV in output stream
  418 + os << csv.print();
  419 +
  420 + // Return output stream
  421 + return os;
  422 +}
  423 +
  424 +
  425 +/***********************************************************************//**
  426 + * @brief Log operator
  427 + *
  428 + * @param[in] log Logger.
  429 + * @param[in] csv Column separated values table.
  430 + ***************************************************************************/
  431 +GLog& operator<< (GLog& log, const GCsv& csv)
  432 +{
  433 + // Write CSV into logger
  434 + log << csv.print();
  435 +
  436 + // Return logger
  437 + return log;
  438 +}
... ...