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 && isspace (*++value_begin));
00119 readsize = end - field_begin < READSIZE ? end - field_begin : READSIZE;
00120 value_end = memchr (field_begin,
'\n', readsize);
00121
if (!value_end)
00122 {
00123
di_warning (
"parser_rfc822: Iek! Don't find end of value!");
00124
return -1;
00125 }
00126
if (value_end < field_end)
00127 {
00128
di_warning (
"parser_rfc822: Iek! Don't find end of field, it seems to be after the end of the line!");
00129
return -1;
00130 }
00131
00132
00133
while (value_end[1] ==
' ' || value_end[1] ==
'\t')
00134 {
00135 readsize = end - value_end + 1 < READSIZE ? end - value_end + 1 : READSIZE;
00136
if ((value_end = memchr (value_end + 1,
'\n', readsize)) == NULL)
00137 {
00138
di_warning (
"Iek! Don't find end of large value\n");
00139
return -1;
00140 }
00141 }
00142 value_size = value_end - value_begin;
00143
00144 field_string.
string = field_begin;
00145 field_string.
size = field_size;
00146 value_string.
string = value_begin;
00147 value_string.
size = value_size;
00148
00149 fip =
di_hash_table_lookup (info->table, &field_string);
00150
00151
if (fip)
00152 {
00153 fip->
read (&act, fip, NULL, &value_string, user_data);
00154
goto next;
00155 }
00156
00157
#if MODIFIER
00158
if (info->wildcard)
00159
goto wildcard;
00160
else if (!info->modifier)
00161
goto next;
00162
00163 field_string.
size = field_size - field_modifier_size - 1;
00164
00165 fip =
di_hash_table_lookup (info->table, &field_string);
00166
00167
if (fip)
00168 {
00169 field_modifier_string.
string = field_modifier_begin;
00170 field_modifier_string.
size = field_modifier_size;
00171
00172 fip->
read (&act, fip, &field_modifier_string, &value_string, user_data);
00173
00174
goto next;
00175 }
00176
#endif
00177
00178
if (!info->wildcard)
00179
goto next;
00180
00181
#if MODIFIER
00182
wildcard:
00183
#endif
00184
field_string.
size = 0;
00185
00186 fip =
di_hash_table_lookup (info->table, &field_string);
00187
00188
if (fip)
00189 {
00190 field_modifier_string.
string = field_begin;
00191 field_modifier_string.
size = field_size;
00192
00193 fip->
read (&act, fip, &field_modifier_string, &value_string, user_data);
00194 }
00195
00196 next:
00197 cur = value_end + 1;
00198
if (cur >= end)
00199
break;
00200
if (*cur ==
'\n')
00201 {
00202
while (cur < end && *++cur ==
'\n');
00203
break;
00204 }
00205 }
00206
00207
if (entry_finish && entry_finish (act, user_data))
00208
return -1;
00209 }
00210
00211
return nr;
00212 }