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
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 ;
00049 return i >> e;
00050 }
00051 started = true;
00052 if ( c == '=' )
00053 break;
00054 e.key += spaces;
00055 e.key += c;
00056 spaces = "";
00057 }
00058
00059
00060 started = false;
00061 bool backslash = false;
00062
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 ) {
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 ;
00103 return i >> g;
00104 }
00105 if ( !started && c == '[' ) {
00106 started = true;
00107 continue;
00108 }
00109 if ( started && c == ']' ) {
00110 while( i.peek() != EOF && i.get() != '\n' )
00111 ;
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