⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vmfileparser.cpp

📁 TOOL (Tiny Object Oriented Language) is an easily-embedded, object-oriented, C++-like-language inter
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include "../../../stdafx.h"
#include "VMFileParser.h"

// required STL headers
#include <algorithm>

// using declarations
using namespace std;

/*
using std::exception;
using std::find_if;
using std::for_each;
using std::ifstream;
using std::istream;
using std::ostream;
using std::string;
using std::vector;
*/

// local functions and function objects

// Counts the number of columns in an istream denoted by delim.
static int CountCols(std::istream& is, const char& delim)
{
  int nCols = 1;
  do
  {
    if (is.peek() == delim)
      nCols++;
  } while (is.get() != '\n');

  return nCols;
}

// A function object that adds things to a vector.
class AddTo
{
public:
  AddTo(vector<vector<string> >& rTarget) : pvvStrTarget(&rTarget) {}
  AddTo(vector<vector<double> >& rTarget) : pvvTarget(&rTarget)    {}
  AddTo(vector<string>& rTarget)          : pvStrTarget(&rTarget)  {}
  AddTo(vector<double>& rTarget)          : pvTarget(&rTarget)     {}

  void operator()(const vector<string>& rSource)
    { pvvStrTarget->push_back(rSource); }

  void operator()(const vector<double>& rSource)
    { pvvTarget->push_back(rSource);    }

  void operator()(const string& rSource)
    { pvStrTarget->push_back(rSource);  }

  void operator()(const double& rSource)
    { pvTarget->push_back(rSource);     }

private:
  vector<vector<string> >* pvvStrTarget;
  vector<vector<double> >* pvvTarget;
  vector<string>*          pvStrTarget;
  vector<double>*          pvTarget;
};

// A function object designed to be used as a predicate
// for remove_if(). Returns true if names match, false if 
// they don't.
class ByName:
  public std::unary_function<std::string, bool>
{  
public:
  ByName(const char* szName) : m_szName(szName) {}

  bool operator()(const std::string& szVarName) const
  {
    return (szVarName == m_szName);
  }

private: 
  std::string m_szName;
};

// end local stuff

// The default constructor.  Instantiates an instance of VMFileParser and 
// initialize data members to default values.
VMFileParser::VMFileParser(void)
{
  m_delim       = DEFAULT_DELIMITER;
  m_dwReadFlags = RF_READ_AS_DOUBLE;
  m_reserve     = DEFAULT_RESERVE;
  m_szError     = "";
}

// Copy constructor.  Instantiates an instance of VMFileParser with the
// contents of another VMFileParser.
VMFileParser::VMFileParser(const VMFileParser& df)
{
  *this = df;
}

// Quasi-Copy constructor.  Instantiates an instance of VMFileParser with the
// contents of another VMFileParser as defined by the DF_SELECTION.
VMFileParser::VMFileParser(const DF_SELECTION& dfs)
{
  m_delim       = DEFAULT_DELIMITER;
  m_dwReadFlags = RF_READ_AS_DOUBLE;
  m_reserve     = DEFAULT_RESERVE;
  m_szError     = "";

  *this = dfs;
}

// Misc. constructor.  Instantiates an instance of VMFileParser with the
// specified read flags.
VMFileParser::VMFileParser(const int& dwReadFlags)
{
  m_delim       = DEFAULT_DELIMITER;
  m_dwReadFlags = dwReadFlags;
  m_reserve     = DEFAULT_RESERVE;
  m_szError     = "";
}
  
// Misc. constructor.  Instantiates an instance of VMFileParser and reads the
// specified file with the specified read flags.
VMFileParser::VMFileParser(const char* szFilename, const int& dwReadFlags /* = RF_READ_AS_DOUBLE */)
{
  m_delim       = DEFAULT_DELIMITER;
  m_dwReadFlags = dwReadFlags;
  m_reserve     = DEFAULT_RESERVE;
  m_szError     = "";

  this->ReadFile(szFilename);
}

// Returns a VMFileParser with one variable created with the specified name and data.
// Assumes readflag RF_READ_AS_DOUBLE.
VMFileParser VMFileParser::FromVector(const char* szVariableName, const std::vector<double>& vData)
{
  VMFileParser retDF;

  retDF.m_vstrVariableNames.push_back(szVariableName);
  retDF.m_vstrSourceFilenames.push_back(retDF.m_szFilename);
  
  retDF.m_v2dData.push_back(vector<double>());
  retDF.m_v2dData.back().reserve(retDF.m_reserve);

  for_each
  (
    vData.begin(),
    vData.end(),
    AddTo(retDF.m_v2dData)
  );

  return retDF;
}

// sets one VMFileParser equal to another VMFileParser.
VMFileParser& VMFileParser::operator=(const VMFileParser& df)
{
  m_delim               = df.m_delim;
  m_dwReadFlags         = df.m_dwReadFlags;
  m_reserve             = df.m_reserve;
  m_szFilename          = df.m_szFilename;
  m_szError             = df.m_szError;
    m_vstrVariableNames   = df.m_vstrVariableNames;
  m_vstrSourceFilenames = df.m_vstrSourceFilenames;
  m_v2dStrData          = df.m_v2dStrData;
  m_v2dData             = df.m_v2dData;

  return *this;
}

// sets one VMFileParser equal to a selection of another VMFileParser.
VMFileParser& VMFileParser::operator=(const DF_SELECTION& dfs)
{
  // clear data vectors
  vector<string>().swap(m_vstrVariableNames);
  vector<string>().swap(m_vstrSourceFilenames);
  vector<vector<double> >().swap(m_v2dData);
  vector<vector<string> >().swap(m_v2dStrData);

  // set the read flags
  m_dwReadFlags = dfs.pDataFile->m_dwReadFlags;

  // normalize the selection
  int firstVar  = dfs.iVar[0]  < dfs.iVar[1]  ? dfs.iVar[0]  : dfs.iVar[1];
  int lastVar   = dfs.iVar[1]  > dfs.iVar[0]  ? dfs.iVar[1]  : dfs.iVar[0];
  int firstSamp = dfs.iSamp[0] < dfs.iSamp[1] ? dfs.iSamp[0] : dfs.iSamp[1];
  int lastSamp  = dfs.iSamp[1] > dfs.iSamp[0] ? dfs.iSamp[1] : dfs.iSamp[0];

  // push_back new variable names
  for(int iVar=firstVar; iVar<=lastVar; iVar++)
  {
    m_vstrVariableNames.push_back(dfs.pDataFile->m_vstrVariableNames.at(iVar).c_str());
    m_vstrSourceFilenames.push_back(dfs.pDataFile->m_vstrSourceFilenames.at(iVar).c_str());

    if(dfs.pDataFile->m_dwReadFlags & RF_READ_AS_DOUBLE)
      m_v2dData.push_back(vector<double>());

    else if(dfs.pDataFile->m_dwReadFlags & RF_READ_AS_STRING)
      m_v2dStrData.push_back(vector<string>());
  }

  // fill up the data
  for(int iSamp = firstSamp; iSamp<=lastSamp; iSamp++)
  {
    for(iVar = firstVar; iVar<=lastVar; iVar++)
    {
      if(dfs.pDataFile->m_dwReadFlags & RF_READ_AS_DOUBLE)
      {
        try  
        { 
          m_v2dData.at(iVar-firstVar).push_back(dfs.pDataFile->m_v2dData.at(iVar).at(iSamp)); 
        }
        catch(...) {}
      }

      else if(dfs.pDataFile->m_dwReadFlags & RF_READ_AS_STRING)
      {
        try  
        {  
          m_v2dStrData.at(iVar-firstVar).push_back(dfs.pDataFile->m_v2dStrData.at(iVar).at(iSamp).c_str()); 
        }
        catch(...) {}
      }
    }
  }

  return *this;
}

// adds one VMFileParser to another VMFileParser
VMFileParser& VMFileParser::operator+=(const VMFileParser& df)
{
  for_each
  (
    df.m_vstrVariableNames.begin(),
    df.m_vstrVariableNames.end(),
    AddTo(m_vstrVariableNames)
  );

  for_each
  (
    df.m_vstrSourceFilenames.begin(),
    df.m_vstrSourceFilenames.end(),
    AddTo(m_vstrSourceFilenames)
  );

  for_each
  (
    df.m_v2dData.begin(),
    df.m_v2dData.end(),
    AddTo(m_v2dData)
  );

  for_each
  (
    df.m_v2dStrData.begin(),
    df.m_v2dStrData.end(),
    AddTo(m_v2dStrData)
  );

  return *this;
}

// adds VMFileParser(s) together
VMFileParser VMFileParser::operator+ (const VMFileParser& df) const
{
  return VMFileParser(*this) += df;
}

// returns a DF_SELECTION based on the coordinates passed.
DF_SELECTION VMFileParser::operator()(const int& left, const int& top, const int& right, const int& bottom)
{
  DF_SELECTION dfs;

  dfs.iSamp[0]  = top;
  dfs.iSamp[1]  = bottom;
  dfs.iVar[0]   = left;
  dfs.iVar[1]   = right;
  dfs.pDataFile = this;

  return dfs;
}

int VMFileParser::operator()(const int& iVariable, const int& iSample, char* lpStr)
{
  int retVal = 0;

  if(m_dwReadFlags & RF_READ_AS_STRING)
  {
    try
    {
      strcpy(lpStr,m_v2dStrData.at(iVariable).at(iSample).c_str());
      retVal = static_cast<int>(m_v2dStrData.at(iVariable).at(iSample).length());
    }

    catch(const exception& e) 
    {  
      m_szError = e.what(); 
      retVal = -1;
    }
    
    catch(...) 
    { 
      m_szError = ERRORCODES[1]; 
      retVal = -1;
    }
  }

  else
  {
    m_szError = ERRORCODES[3];
    retVal = -1;
  }

  return retVal;
}


// Creates a VMFileParser in STRING mode from a vector with a supplied variable name.
VMFileParser VMFileParser::FromVector(const char* szVariableName, const std::vector<string>& vData)
{
  VMFileParser retDF(RF_READ_AS_STRING);

  retDF.m_vstrVariableNames.push_back(szVariableName);
  retDF.m_vstrSourceFilenames.push_back(retDF.m_szFilename);
  
  retDF.m_v2dStrData.push_back(vector<string>());
  retDF.m_v2dStrData.back().reserve(retDF.m_reserve);

  for_each
  (
    vData.begin(),
    vData.end(),
    AddTo(retDF.m_v2dStrData)
  );

  return retDF;
}

// destructor
VMFileParser::~VMFileParser(void)
{
  this->ClearData();
}

// Reads the specified file.
// Returns true if successful, false if an error occurred.
bool VMFileParser::ReadFile(const char* szFilename, const unsigned& dwReadFlags)
{
  try
  {
    m_szFilename  = szFilename;
    m_dwReadFlags = dwReadFlags;

    std::ifstream inFile;
    inFile.open(szFilename);

    if(inFile.rdstate() & std::ios::failbit)
    {
      inFile.close();
      m_szError = ERRORCODES[7]; 
      m_szError += "\nDetails: ";
      m_szError += szFilename;
      return false;
    }

    inFile >> *this;
            
    inFile.close();
    return true;
  }

  catch(const exception& e)
  {
    m_szError = e.what();
  }

  catch(...)
  {
    m_szError = ERRORCODES[0];
  }

  return false;
}


// reads the data from the stream and returns the stream when done.
std::istream& operator>>(std::istream& inFile, VMFileParser& df)
{
  try
  {  
    if(!(df.m_dwReadFlags & RF_APPEND_DATA))
      df.ClearData();

    // count the number of variables
    int nVars = CountCols(inFile, df.m_delim.at(0));
      
    // make sure data columns are equal to nVars
    // in order to prevent mis-aligned data
    inFile.ignore(MAX_LINE_BUFFER,'\n');
      
    if(CountCols(inFile, df.m_delim.at(0)) != nVars)
    {
      df.m_szError = ERRORCODES[8];
      throw exception(df.m_szError.c_str());
    }

    // rewind the file
    inFile.seekg(0);
        
    int iVar = 0;
    int varOffset = df.GetNumberOfVariables();
  
    char buff[MAX_FIELD_BUFFER] = {0};

    for(iVar=0; iVar<nVars; iVar++)
    {
      inFile.getline(buff, sizeof buff, (iVar == nVars-1) ? '\n' : df.m_delim.at(0));  
      df.m_vstrVariableNames.push_back(buff);
      df.m_vstrSourceFilenames.push_back(df.m_szFilename);

      if(df.m_dwReadFlags & RF_READ_AS_DOUBLE)
      {
        df.m_v2dData.push_back(vector<double>());
        df.m_v2dData.back().reserve(df.m_reserve);
      }

      else if(df.m_dwReadFlags & RF_READ_AS_STRING)
      {
        df.m_v2dStrData.push_back(vector<string>());
        df.m_v2dStrData.back().reserve(df.m_reserve);
      }
    }
          
    do
    {
      for(iVar=0; iVar<nVars; iVar++)
      {
        inFile.getline(buff, sizeof(buff), (iVar == nVars-1) ? '\n' : df.m_delim.at(0));  

        // make sure we didn't pick up extra junk @ eof.
        if(/*!inFile.eof() &&*/ buff[0] != '\n')
        {
          if(df.m_dwReadFlags & RF_READ_AS_DOUBLE)
            df.m_v2dData.at(iVar+varOffset).push_back(atof(buff));

          else if(df.m_dwReadFlags & RF_READ_AS_STRING)
            df.m_v2dStrData.at(iVar+varOffset).push_back(buff);
        }
      }  

    }while(!inFile.eof());

    if(df.m_vstrVariableNames.back().find("\n")!=-1)
      df.m_vstrVariableNames.back().resize(df.m_vstrVariableNames.back().length()-1);
  }

  catch(const exception& e) 
  { 
    df.m_szError = e.what();
    throw e; 
  }
  
  catch(...) 
  { 
    df.m_szError = ERRORCODES[0];
    throw exception(df.m_szError.c_str());
  }

  return inFile;
}

std::ostream& operator << (std::ostream& outFile, const VMFileParser& df)
{
  try
  {
    int nVars = static_cast<int>(df.m_vstrVariableNames.size());
    int iVar  = 0;

    for(iVar = 0; iVar<nVars; iVar++)
      outFile << df.m_vstrVariableNames.at(iVar).c_str() << ((iVar==nVars-1) ? "\n" : df.m_delim.c_str());

    int nSamps = df.GetLargestVectorSize_();

    for(int iSamp = 0; iSamp<nSamps; iSamp++)
    {
      for(iVar = 0; iVar<nVars; iVar++)
      {
        if(df.m_dwReadFlags & RF_READ_AS_DOUBLE)
        {
          try  { outFile << df.m_v2dData.at(iVar).at(iSamp); }
          catch(...) {}
        }

        else if(df.m_dwReadFlags & RF_READ_AS_STRING)
        {
          try  { outFile << df.m_v2dStrData.at(iVar).at(iSamp).c_str(); }
          catch(...) {}
        }

        outFile << ((iVar==nVars-1) ? "\n" : df.m_delim.c_str());
      }
    }
  }

  // catch and re-throw any exceptions
  catch(const exception& e) { throw e; }
  catch(...) { throw exception(ERRORCODES[0]); }

  return outFile;
}

std::ostream& operator << (std::ostream& os, const DF_SELECTION& dfs)
{
  try
  {
    int firstVar  = dfs.iVar[0]  < dfs.iVar[1]  ? dfs.iVar[0]  : dfs.iVar[1];
    int lastVar   = dfs.iVar[1]  > dfs.iVar[0]  ? dfs.iVar[1]  : dfs.iVar[0];
    int firstSamp = dfs.iSamp[0] < dfs.iSamp[1] ? dfs.iSamp[0] : dfs.iSamp[1];
    int lastSamp  = dfs.iSamp[1] > dfs.iSamp[0] ? dfs.iSamp[1] : dfs.iSamp[0];

    for(int iVar=firstVar; iVar<=lastVar; iVar++)
      os << dfs.pDataFile->m_vstrVariableNames.at(iVar).c_str() << ((iVar==lastVar) ? "\n" : dfs.pDataFile->m_delim.c_str());

    for(int iSamp = firstSamp; iSamp<=lastSamp; iSamp++)
    {
      for(iVar = firstVar; iVar<=lastVar; iVar++)
      {
        if(dfs.pDataFile->m_dwReadFlags & RF_READ_AS_DOUBLE)
        {
          try  { os << dfs.pDataFile->m_v2dData.at(iVar).at(iSamp); }
          catch(...) {}
        }

        else if(dfs.pDataFile->m_dwReadFlags & RF_READ_AS_STRING)
        {
          try  { os << dfs.pDataFile->m_v2dStrData.at(iVar).at(iSamp).c_str(); }
          catch(...) {}
        }

        os << ((iVar==lastVar) ? "\n" : dfs.pDataFile->m_delim.c_str());
      }
    }
  }

  // catch and re-throw any exceptions
  catch(const exception& e) { throw e; }
  catch(...) { throw exception(ERRORCODES[0]); }

  return os;
}

bool VMFileParser::SetData(const int&  iVariable, const int& iSample, const double& value)
{
  try
  {
    m_v2dData.at(iVariable).at(iSample) = value;
    return true;
  }

  catch(const exception& e) { m_szError = e.what(); }
  catch(...) { m_szError = ERRORCODES[0]; }
  return false;
}

bool VMFileParser::SetData(const int&  iVariable, const int& iSample, const char* szValue)
{
  try
  {
    m_v2dStrData.at(iVariable).at(iSample) = szValue;
    return true;
  }

  catch(const exception& e) { m_szError = e.what(); }
  catch(...) { m_szError = ERRORCODES[0]; }
  return false;
}

bool VMFileParser::AppendData(const int& iVariable, const double& value)
{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -