libept
desktopfile.h
Go to the documentation of this file.
1 
2 
3 #include <iostream>
4 #include <string>
5 #include <map>
6 
7 #ifndef EPT_CORE_DESKTOPFILE_H
8 #define EPT_CORE_DESKTOPFILE_H
9 
10 namespace ept {
11 namespace core {
12 namespace desktop {
13 
14 struct File {
15  struct Entry {
16  std::string key;
17  std::string value;
18  };
19  typedef std::map< std::string, Entry > EntryMap;
20 
21  struct Group {
22  std::string name;
24  Entry &entry( std::string k ) { return entries[ k ]; }
25  };
26 
27  typedef std::map< std::string, Group > GroupMap;
29  Group &group( std::string k ) { return groups[ k ]; }
30 };
31 
32 inline std::istream &operator >>( std::istream &i, File::Entry &e )
33 {
34  std::string spaces = ""; char c; bool started = false;
35 
36  e.key = "";
37  // read key
38  while ( i.peek() != EOF ) {
39  c = i.get();
40  if ( !started && c == '\n' )
41  return i >> e;
42  if ( isspace( c ) ) {
43  spaces += c;
44  continue;
45  }
46  if ( !started && c == '#' ) {
47  while ( i.peek() != EOF && i.get() != '\n' )
48  ; // read till eol
49  return i >> e; // restart reading
50  }
51  started = true;
52  if ( c == '=' )
53  break;
54  e.key += spaces;
55  e.key += c;
56  spaces = "";
57  }
58  // std::cerr << "read key: " << e.key << std::endl;
59 
60  started = false;
61  bool backslash = false;
62  // read value
63  while ( i.peek() != EOF ) {
64  c = i.get();
65  if ( c == '\n' ) {
66  if ( backslash )
67  e.value += '\\';
68  return i;
69  }
70  if ( !started && isspace( c ) )
71  continue;
72  started = true;
73  if ( backslash ) { // interpret escape sequences
74  if ( c == '\\' ) e.value += '\\';
75  else if ( c == 'n' ) e.value += '\n';
76  else if ( c == 't' ) e.value += '\t';
77  else if ( c == 'r' ) e.value += '\r';
78  else if ( c == 's' ) e.value += ' ';
79  else { e.value += '\\'; e.value += c; }
80  backslash = false;
81  continue;
82  }
83  if ( c == '\\' ) {
84  backslash = true;
85  continue;
86  }
87  e.value += c;
88  }
89  return i;
90 }
91 
92 inline std::istream &operator >>( std::istream &i, File::Group &g )
93 {
94  bool started = false; char c;
95  g.name = "";
96  while ( i.peek() != EOF ) {
97  c = i.get();
98  if ( !started && isspace( c ) )
99  continue;
100  if ( !started && c == '#' ) {
101  while( i.peek() != EOF && i.get() != '\n' )
102  ; // read till eol
103  return i >> g; // restart reading
104  }
105  if ( !started && c == '[' ) {
106  started = true;
107  continue;
108  }
109  if ( started && c == ']' ) {
110  while( i.peek() != EOF && i.get() != '\n' )
111  ; // read till eol
112  break;
113  }
114  g.name += c;
115  }
116  while ( i.peek() != EOF ) {
117  File::Entry e;
118  i >> e;
119  g.entries[ e.key ] = e;
120  }
121  return i;
122 }
123 
124 inline std::istream &operator >>( std::istream &i, File &f )
125 {
126  while ( i.peek() != EOF ) {
127  File::Group g;
128  i >> g;
129  f.groups[ g.name ] = g;
130  }
131  return i;
132 }
133 
134 }
135 }
136 }
137 
138 #endif