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 return i >> e;
00049 }
00050 started = true;
00051 if ( c == '=' )
00052 break;
00053 e.key += spaces;
00054 e.key += c;
00055 spaces = "";
00056 }
00057
00058
00059 started = false;
00060 bool backslash = false;
00061
00062 while ( i.peek() != EOF ) {
00063 c = i.get();
00064 if ( c == '\n' ) {
00065 if ( backslash )
00066 e.value += '\\';
00067 return i;
00068 }
00069 if ( !started && isspace( c ) )
00070 continue;
00071 started = true;
00072 if ( backslash ) {
00073 if ( c == '\\' ) e.value += '\\';
00074 else if ( c == 'n' ) e.value += '\n';
00075 else if ( c == 't' ) e.value += '\t';
00076 else if ( c == 'r' ) e.value += '\r';
00077 else if ( c == 's' ) e.value += ' ';
00078 else { e.value += '\\'; e.value += c; }
00079 backslash = false;
00080 continue;
00081 }
00082 if ( c == '\\' ) {
00083 backslash = true;
00084 continue;
00085 }
00086 e.value += c;
00087 }
00088 return i;
00089 }
00090
00091 inline std::istream &operator >>( std::istream &i, File::Group &g )
00092 {
00093 bool started = false; char c;
00094 g.name = "";
00095 while ( i.peek() != EOF ) {
00096 c = i.get();
00097 if ( !started && isspace( c ) )
00098 continue;
00099 if ( !started && c == '#' ) {
00100 while( i.peek() != EOF && i.get() != '\n' );
00101 return i >> g;
00102 }
00103 if ( !started && c == '[' ) {
00104 started = true;
00105 continue;
00106 }
00107 if ( started && c == ']' ) {
00108 while( i.peek() != EOF && i.get() != '\n' );
00109 break;
00110 }
00111 g.name += c;
00112 }
00113 while ( i.peek() != EOF ) {
00114 File::Entry e;
00115 i >> e;
00116 g.entries[ e.key ] = e;
00117 }
00118 return i;
00119 }
00120
00121 inline std::istream &operator >>( std::istream &i, File &f )
00122 {
00123 while ( i.peek() != EOF ) {
00124 File::Group g;
00125 i >> g;
00126 f.groups[ g.name ] = g;
00127 }
00128 return i;
00129 }
00130
00131 }
00132 }
00133 }
00134
00135 #endif