File: FileWordGenerator.cpp

package info (click to toggle)
dasher 4.11%2Bgit20130508.adc653-2
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 40,248 kB
  • ctags: 5,158
  • sloc: xml: 185,479; cpp: 32,301; sh: 11,207; makefile: 828; ansic: 483
file content (69 lines) | stat: -rw-r--r-- 2,216 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#include "FileWordGenerator.h"

using namespace Dasher;

CFileWordGenerator::CFileWordGenerator(CMessageDisplay *pMsgs, const CAlphInfo *pAlph, const CAlphabetMap *pAlphMap)
  : CWordGeneratorBase(pAlph,pAlphMap), AbstractParser(pMsgs) {
}

bool CFileWordGenerator::Parse(const std::string &strDesc, istream &in, bool bUser) {
  //non-file streams not supported (yet)
  DASHER_ASSERT(false);
  return false;
}

bool CFileWordGenerator::ParseFile(const std::string &sPath, bool bUser) {
  if (bUser && !m_bAcceptUser) return false;
  m_sFileHandle.close();
  m_vLineIndices.clear();
  m_sPath=sPath;
  m_sFileHandle.open(m_sPath.c_str());
  if(m_sFileHandle.fail()) {
    m_sPath="";
    return false;
  }
  /*The hard way:
  m_vLineIndices.push_back(0);
  streampos pos=0;
  char buf[1024];
  for (int read = m_sFileHandle.read(buf,1024).gcount();;) {
    for (int i=0; i<read-1; i++) {
      if (buf[i]=='\r') {
        if (buf[i+1]=='\n') i++;
      } else if (buf[i]!='\n') continue;
      m_vLineIndices.push_back(pos+i);
    }
    if (read!=1024) break;
    //haven't checked final byte; might be \r and need \n from next read
    pos+=read-1;
    buf[0]=buf[read-1];
    read = m_sFileHandle.read(&buf[1],1023).gcount()+1;
  }
  */
  //The easy way - TODO will this work with Windows line endings?
  for (std::string buf; m_sFileHandle.good();) {
    streampos pos = m_sFileHandle.tellg();
    std::getline(m_sFileHandle, buf);
    if (!buf.empty()) m_vLineIndices.push_back(pos);
  }
  return true;
}

std::string CFileWordGenerator::GetLine() {
  if (m_vLineIndices.empty()) return "";
  if (m_sFileHandle.eof() && !m_sFileHandle.bad()) {
    //no error has occurred, but we've reached the end of file. So reset state as we're about to seek...
    m_sFileHandle.clear();
  }  
  int i = rand() % m_vLineIndices.size();
  m_sFileHandle.seekg(m_vLineIndices[i]);
  m_vLineIndices.erase(m_vLineIndices.begin()+i);
  //TODO: call DashIntf::Message, and return "", instead?
  if (!m_sFileHandle.good()) throw std::runtime_error("File I/O error reading "+m_sPath);
  string sRes;
  std::getline(m_sFileHandle, sRes);
  DASHER_ASSERT(!sRes.empty()); //shouldn't have stored index of empty string
  return sRes;
}