Added yp2::PlainFile class which reads Unix-style plain text files.
[metaproxy-moved-to-github.git] / src / plainfile.cpp
1 /* $Id: plainfile.cpp,v 1.1 2006-01-25 11:27:19 adam Exp $
2    Copyright (c) 2005, Index Data.
3
4 %LICENSE%
5  */
6
7 #include "config.hpp"
8
9 #include <cstdlib>
10 #include <string>
11 #include <iostream>
12 #include <fstream>
13
14 #include "util.hpp"
15
16 #define PLAINFILE_MAX_LINE 256
17
18 namespace yp2 {
19     class PlainFile::Rep {
20         friend class PlainFile;
21         Rep();
22         void close();
23         int lineno;
24         std::ifstream *fh;
25     };
26 }
27
28 yp2::PlainFile::Rep::Rep() : lineno(1)
29 {
30     fh = 0;
31 }
32
33 yp2::PlainFile::PlainFile() : m_p(new Rep)
34 {
35 }
36
37 void yp2::PlainFile::Rep::close()
38 {
39     delete fh;
40     fh = 0;
41     lineno = 0;
42 }
43
44 yp2::PlainFile::~PlainFile()
45 {
46     m_p->close();
47 }
48
49 bool yp2::PlainFile::open(const std::string &fname)
50 {
51     m_p->close();
52
53     std::ifstream *new_file = new std::ifstream(fname.c_str());
54     if (! *new_file)
55     {
56         delete new_file;
57         return false;
58     }
59     m_p->fh = new_file;
60     return true;
61 }
62
63 bool yp2::PlainFile::getline(std::vector<std::string> &args)
64 {
65     args.clear();
66
67     if (!m_p->fh)
68         return false;  // no file at all.
69
70     char line_cstr[PLAINFILE_MAX_LINE];
71     while (true)
72     {
73         if (m_p->fh->eof())
74         {
75             m_p->close();   // might as well close it now
76             return false;
77         }
78         
79         m_p->lineno++;
80         m_p->fh->getline(line_cstr, PLAINFILE_MAX_LINE-1);
81         char first = line_cstr[0];
82         if (first && !strchr("# \t", first))
83             break;
84         // comment or blank line.. read next.
85     }
86     const char *cp = line_cstr;
87     while (true)
88     {
89         // skip whitespace
90         while (*cp && strchr(" \t", *cp))
91             cp++;
92         if (*cp == '\0')
93             break;
94         const char *cp0 = cp;
95         while (*cp && !strchr(" \t", *cp))
96             cp++;
97         std::string arg(cp0, cp - cp0);
98         args.push_back(arg);
99     }
100     return true;
101 }
102
103 /*
104  * Local variables:
105  * c-basic-offset: 4
106  * indent-tabs-mode: nil
107  * c-file-style: "stroustrup"
108  * End:
109  * vim: shiftwidth=4 tabstop=8 expandtab
110  */