libept
|
00001 00002 00003 #include <iostream> 00004 #include <string> 00005 #include <map> 00006 00007 #ifndef EPT_CORE_DESKTOPFILE_H 00008 #define EPT_CORE_DESKTOPFILE_H 00009 00010 namespace ept { 00011 namespace core { 00012 namespace desktop { 00013 00014 struct File { 00015 struct Entry { 00016 std::string key; 00017 std::string value; 00018 }; 00019 typedef std::map< std::string, Entry > EntryMap; 00020 00021 struct Group { 00022 std::string name; 00023 EntryMap entries; 00024 Entry &entry( std::string k ) { return entries[ k ]; } 00025 }; 00026 00027 typedef std::map< std::string, Group > GroupMap; 00028 GroupMap groups; 00029 Group &group( std::string k ) { return groups[ k ]; } 00030 }; 00031 00032 inline std::istream &operator >>( std::istream &i, File::Entry &e ) 00033 { 00034 std::string spaces = ""; char c; bool started = false; 00035 00036 e.key = ""; 00037 // read key 00038 while ( i.peek() != EOF ) { 00039 c = i.get(); 00040 if ( !started && c == '\n' ) 00041 return i >> e; 00042 if ( isspace( c ) ) { 00043 spaces += c; 00044 continue; 00045 } 00046 if ( !started && c == '#' ) { 00047 while ( i.peek() != EOF && i.get() != '\n' ) 00048 ; // read till eol 00049 return i >> e; // restart reading 00050 } 00051 started = true; 00052 if ( c == '=' ) 00053 break; 00054 e.key += spaces; 00055 e.key += c; 00056 spaces = ""; 00057 } 00058 // std::cerr << "read key: " << e.key << std::endl; 00059 00060 started = false; 00061 bool backslash = false; 00062 // read value 00063 while ( i.peek() != EOF ) { 00064 c = i.get(); 00065 if ( c == '\n' ) { 00066 if ( backslash ) 00067 e.value += '\\'; 00068 return i; 00069 } 00070 if ( !started && isspace( c ) ) 00071 continue; 00072 started = true; 00073 if ( backslash ) { // interpret escape sequences 00074 if ( c == '\\' ) e.value += '\\'; 00075 else if ( c == 'n' ) e.value += '\n'; 00076 else if ( c == 't' ) e.value += '\t'; 00077 else if ( c == 'r' ) e.value += '\r'; 00078 else if ( c == 's' ) e.value += ' '; 00079 else { e.value += '\\'; e.value += c; } 00080 backslash = false; 00081 continue; 00082 } 00083 if ( c == '\\' ) { 00084 backslash = true; 00085 continue; 00086 } 00087 e.value += c; 00088 } 00089 return i; 00090 } 00091 00092 inline std::istream &operator >>( std::istream &i, File::Group &g ) 00093 { 00094 bool started = false; char c; 00095 g.name = ""; 00096 while ( i.peek() != EOF ) { 00097 c = i.get(); 00098 if ( !started && isspace( c ) ) 00099 continue; 00100 if ( !started && c == '#' ) { 00101 while( i.peek() != EOF && i.get() != '\n' ) 00102 ; // read till eol 00103 return i >> g; // restart reading 00104 } 00105 if ( !started && c == '[' ) { 00106 started = true; 00107 continue; 00108 } 00109 if ( started && c == ']' ) { 00110 while( i.peek() != EOF && i.get() != '\n' ) 00111 ; // read till eol 00112 break; 00113 } 00114 g.name += c; 00115 } 00116 while ( i.peek() != EOF ) { 00117 File::Entry e; 00118 i >> e; 00119 g.entries[ e.key ] = e; 00120 } 00121 return i; 00122 } 00123 00124 inline std::istream &operator >>( std::istream &i, File &f ) 00125 { 00126 while ( i.peek() != EOF ) { 00127 File::Group g; 00128 i >> g; 00129 f.groups[ g.name ] = g; 00130 } 00131 return i; 00132 } 00133 00134 } 00135 } 00136 } 00137 00138 #endif