00001
00002
00003 #include <string>
00004 #include <ctype.h>
00005 #include "logrecord.h"
00006 #include "date.h"
00007
00008
00009 bool
00010 LogRecord::parse_line(const string& line) {
00011
00012
00013
00014
00015 return parse_date(line) && parse_path(line) && parse_domain(line);
00016 }
00017
00018
00019 bool
00020 LogRecord::parse_date(const string& line) {
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 string::size_type date_start(line.find_first_of('['));
00031 string::size_type date_end(line.find_first_of(' ',date_start));
00032 string date_string(line,date_start+1,date_end - date_start-1);
00033
00034
00035
00036
00037
00038
00039
00040 for (string::size_type i=0; i<date_string.size(); ++i)
00041 if (date_string[i]=='/')
00042 date_string[i] = '-';
00043
00044
00045
00046
00047
00048 date_string.replace(date_string.find_first_of(':'),1," ");
00049
00050
00051
00052
00053
00054 try {
00055 Date d(date_string);
00056 date_.set(d.year(),d.month(),d.day(),d.hours());
00057 }
00058 catch (exception& e) {
00059 cerr << "LogRecord::parse_date failed: " << e.what() << endl;
00060 return false;
00061 }
00062 return true;
00063 }
00064
00066
00067
00068 static inline int
00069 hexdigit(char c) {
00070 if (isdigit(c))
00071 return c - '0';
00072 else if (isupper(c))
00073 return c - 'A' + 10;
00074 else
00075 return c - 'a' +10;
00076 }
00077
00078
00079 void
00080 www_decode(string& s) {
00081 unsigned int i(0);
00082 unsigned int j(0);
00083 unsigned int len(s.size());
00084 for (i=0; (i<len); ++i,++j)
00085 switch (s[i]) {
00086
00087 case '%':
00088 if ((i+2<len) && isxdigit(s[i+1]) && isxdigit(s[i+2])) {
00089 s[j] = hexdigit(s[i+1])* 16 + hexdigit(s[i+2]);
00090 i += 2;
00091 }
00092 else
00093 s[j] = s[i];
00094 break;
00095 default: s[j] = s[i]; break;
00096 }
00097 s.resize(j);
00098 }
00100
00101
00102 bool
00103 LogRecord::parse_path(const string& line) {
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113 string::size_type path_start(line.find_first_of('\"'));
00114 if (path_start==string::npos)
00115 return false;
00116
00117
00118
00119
00120
00121 path_start = line.find_first_of(' ',path_start);
00122 if (path_start==string::npos)
00123 return false;
00124 ++path_start;
00125
00126
00127
00128
00129
00130
00131 string::size_type path_end = line.find_first_of("#? ",path_start);
00132 if (path_end==string::npos)
00133 return false;
00134
00135 if (path_end==path_start)
00136 return false;
00137
00138 string path_string(line,path_start,path_end - path_start);
00139
00140
00141 www_decode(path_string);
00142
00143 return path_.parse(path_string);
00144 }
00145
00146
00147 bool
00148 LogRecord::parse_domain(const string& line) {
00149
00150
00151
00152
00153
00154
00155 string::size_type domain_start(0);
00156 string::size_type domain_end(line.find_first_of(' '));
00157 if (domain_end==string::npos)
00158 return false;
00159 string domain_string(line,domain_start,domain_end);
00160
00161 return domain_.parse(domain_string);
00162 }