00044 {
00045
char *cur, *end;
00046
char *field_begin, *field_end;
00047
#if MODIFIER
00048
char *field_modifier_begin, *field_modifier_end;
00049
#endif
00050
char *value_begin, *value_end;
00051
#ifndef HAVE_MEMRCHR
00052
char *temp;
00053
#endif
00054
int nr = 0;
00055 size_t readsize;
00056 size_t field_size;
00057
#if MODIFIER
00058
size_t field_modifier_size;
00059
#endif
00060
size_t value_size;
00061
const di_parser_fieldinfo *fip = NULL;
00062
di_rstring field_string;
00063
di_rstring field_modifier_string;
00064
di_rstring value_string;
00065
void *act = NULL;
00066
00067 cur = begin;
00068 end = begin + size;
00069
00070
while (cur < end)
00071 {
00072 nr++;
00073
00074
if (entry_new)
00075 act = entry_new (user_data);
00076
else
00077 act = NULL;
00078
00079
while (1)
00080 {
00081 field_begin = cur;
00082 readsize = end - field_begin < READSIZE ? end - field_begin : READSIZE;
00083
if (!readsize)
00084
break;
00085 field_end = memchr (cur,
':', readsize);
00086
#if MODIFIER
00087
field_modifier_end = field_end;
00088
#endif
00089
if (!field_end)
00090 {
00091
di_warning (
"parser_rfc822: Iek! Don't find end of field!");
00092
return -1;
00093 }
00094 field_size = field_end - field_begin;
00095
00096
#if MODIFIER
00097
#ifdef HAVE_MEMRCHR
00098
if ((field_modifier_begin = memrchr (field_begin,
'-', field_end - field_begin)))
00099 field_modifier_begin++;
00100
if (field_modifier_begin)
00101
#else
00102
field_modifier_begin = field_begin;
00103
while ((temp = memchr (field_modifier_begin,
'-', field_end - field_modifier_begin)))
00104 field_modifier_begin = temp + 1;
00105
if (field_modifier_begin != field_begin)
00106
#endif
00107
{
00108 field_modifier_size = field_modifier_end - field_modifier_begin;
00109 }
00110
else
00111 {
00112 field_modifier_begin = 0;
00113 field_modifier_size = 0;
00114 }
00115
#endif
00116
00117 value_begin = field_end + 1;
00118
while (value_begin < end && (*value_begin ==
' ' || *value_begin ==
'\t'))
00119 value_begin++;
00120 readsize = end - field_begin < READSIZE ? end - field_begin : READSIZE;
00121 value_end = memchr (field_begin,
'\n', readsize);
00122
if (!value_end)
00123 {
00124
di_warning (
"parser_rfc822: Iek! Don't find end of value!");
00125
return -1;
00126 }
00127
if (value_end < field_end)
00128 {
00129
di_warning (
"parser_rfc822: Iek! Don't find end of field, it seems to be after the end of the line!");
00130
return -1;
00131 }
00132
00133
00134
while (value_end[1] ==
' ' || value_end[1] ==
'\t')
00135 {
00136 readsize = end - value_end + 1 < READSIZE ? end - value_end + 1 : READSIZE;
00137
if ((value_end = memchr (value_end + 1,
'\n', readsize)) == NULL)
00138 {
00139
di_warning (
"Iek! Don't find end of large value\n");
00140
return -1;
00141 }
00142 }
00143 value_size = value_end - value_begin;
00144
00145 field_string.
string = field_begin;
00146 field_string.
size = field_size;
00147 value_string.
string = value_begin;
00148 value_string.
size = value_size;
00149
00150 fip =
di_hash_table_lookup (info->table, &field_string);
00151
00152
if (fip)
00153 {
00154 fip->
read (&act, fip, NULL, &value_string, user_data);
00155
goto next;
00156 }
00157
00158
#if MODIFIER
00159
if (info->wildcard)
00160
goto wildcard;
00161
else if (!info->modifier)
00162
goto next;
00163
00164 field_string.
size = field_size - field_modifier_size - 1;
00165
00166 fip =
di_hash_table_lookup (info->table, &field_string);
00167
00168
if (fip)
00169 {
00170 field_modifier_string.
string = field_modifier_begin;
00171 field_modifier_string.
size = field_modifier_size;
00172
00173 fip->
read (&act, fip, &field_modifier_string, &value_string, user_data);
00174
00175
goto next;
00176 }
00177
#endif
00178
00179
if (!info->wildcard)
00180
goto next;
00181
00182
#if MODIFIER
00183
wildcard:
00184
#endif
00185
field_string.
size = 0;
00186
00187 fip =
di_hash_table_lookup (info->table, &field_string);
00188
00189
if (fip)
00190 {
00191 field_modifier_string.
string = field_begin;
00192 field_modifier_string.
size = field_size;
00193
00194 fip->
read (&act, fip, &field_modifier_string, &value_string, user_data);
00195 }
00196
00197 next:
00198 cur = value_end + 1;
00199
if (cur >= end)
00200
break;
00201
if (*cur ==
'\n')
00202 {
00203
while (cur < end && *++cur ==
'\n');
00204
break;
00205 }
00206 }
00207
00208
if (entry_finish && entry_finish (act, user_data))
00209
return -1;
00210 }
00211
00212
return nr;
00213 }