Functions | |
int | di_parser_rfc822_read (char *begin, size_t size, di_parser_info *fieldinfo, di_parser_read_entry_new entry_new, di_parser_read_entry_finish entry_finish, void *user_data) |
int | di_parser_rfc822_read_file (const char *file, di_parser_info *fieldinfo, di_parser_read_entry_new entry_new, di_parser_read_entry_finish entry_finish, void *user_data) |
int | di_parser_rfc822_write_file (const char *file, di_parser_info *fieldinfo, di_parser_write_entry_next entry_next, void *user_data) |
int di_parser_rfc822_read | ( | char * | begin, | |
size_t | size, | |||
di_parser_info * | fieldinfo, | |||
di_parser_read_entry_new | entry_new, | |||
di_parser_read_entry_finish | entry_finish, | |||
void * | user_data | |||
) |
Parse a rfc822 formated file
begin | begin of memory segment | |
size | size of memory segment | |
fieldinfo | parser info | |
entry_new | function which is called before each entry, may return the new entry or return NULL | |
entry_finish | function which is called after each entry, return non-0 aborts the parsing | |
user_data | user_data for parser functions |
References di_hash_table_lookup(), di_warning, di_parser_info::modifier, di_parser_fieldinfo::read, di_rstring::size, di_rstring::string, di_parser_info::table, and di_parser_info::wildcard.
Referenced by di_parser_rfc822_read_file().
{ char *cur, *end; char *field_begin, *field_end; #if MODIFIER char *field_modifier_begin, *field_modifier_end; #endif char *value_begin, *value_end; #ifndef HAVE_MEMRCHR char *temp; #endif int nr = 0; size_t readsize; size_t field_size; #if MODIFIER size_t field_modifier_size; #endif size_t value_size; const di_parser_fieldinfo *fip = NULL; di_rstring field_string; di_rstring field_modifier_string; di_rstring value_string; void *act = NULL; cur = begin; end = begin + size; while (cur < end) { if (*cur == '\n') { cur++; continue; } nr++; if (entry_new) act = entry_new (user_data); else act = NULL; while (1) { field_begin = cur; readsize = end - field_begin < READSIZE ? end - field_begin : READSIZE; if (!readsize) break; field_end = memchr (cur, ':', readsize); #if MODIFIER field_modifier_end = field_end; #endif if (!field_end) { di_warning ("parser_rfc822: Iek! Don't find end of field!"); return -1; } field_size = field_end - field_begin; #if MODIFIER #ifdef HAVE_MEMRCHR if ((field_modifier_begin = memrchr (field_begin, '-', field_end - field_begin))) field_modifier_begin++; if (field_modifier_begin) #else field_modifier_begin = field_begin; while ((temp = memchr (field_modifier_begin, '-', field_end - field_modifier_begin))) field_modifier_begin = temp + 1; if (field_modifier_begin != field_begin) #endif { field_modifier_size = field_modifier_end - field_modifier_begin; } else { field_modifier_begin = 0; field_modifier_size = 0; } #endif value_begin = field_end + 1; while (value_begin < end && (*value_begin == ' ' || *value_begin == '\t')) value_begin++; readsize = end - field_begin < READSIZE ? end - field_begin : READSIZE; value_end = memchr (field_begin, '\n', readsize); if (!value_end) { di_warning ("parser_rfc822: Iek! Don't find end of value!"); return -1; } if (value_end < field_end) { di_warning ("parser_rfc822: Iek! Don't find end of field, it seems to be after the end of the line!"); return -1; } /* while (isblank (value_end[1])) FIXME: C99 */ while (value_end[1] == ' ' || value_end[1] == '\t') { readsize = end - value_end + 1 < READSIZE ? end - value_end + 1 : READSIZE; if ((value_end = memchr (value_end + 1, '\n', readsize)) == NULL) { di_warning ("Iek! Don't find end of large value\n"); return -1; } } value_size = value_end - value_begin; field_string.string = field_begin; field_string.size = field_size; value_string.string = value_begin; value_string.size = value_size; fip = di_hash_table_lookup (info->table, &field_string); if (fip) { fip->read (&act, fip, NULL, &value_string, user_data); goto next; } #if MODIFIER if (info->wildcard) goto wildcard; else if (!info->modifier) goto next; field_string.size = field_size - field_modifier_size - 1; fip = di_hash_table_lookup (info->table, &field_string); if (fip) { field_modifier_string.string = field_modifier_begin; field_modifier_string.size = field_modifier_size; fip->read (&act, fip, &field_modifier_string, &value_string, user_data); goto next; } #endif if (!info->wildcard) goto next; #if MODIFIER wildcard: #endif field_string.size = 0; fip = di_hash_table_lookup (info->table, &field_string); if (fip) { field_modifier_string.string = field_begin; field_modifier_string.size = field_size; fip->read (&act, fip, &field_modifier_string, &value_string, user_data); } next: cur = value_end + 1; if (cur >= end || *cur == '\n') break; } if (entry_finish && entry_finish (act, user_data)) return -1; } return nr; }
int di_parser_rfc822_read_file | ( | const char * | file, | |
di_parser_info * | fieldinfo, | |||
di_parser_read_entry_new | entry_new, | |||
di_parser_read_entry_finish | entry_finish, | |||
void * | user_data | |||
) |
Parse a rfc822 formated file
file | filename | |
fieldinfo | parser info | |
entry_new | function which is called before each entry, may return the new entry or return NULL | |
entry_finish | function which is called after each entry, return non-0 aborts the parsing | |
user_data | user_data for parser functions |
References di_parser_rfc822_read().
Referenced by di_release_read_file().
{ struct stat statbuf; char *begin; int fd, ret = -1; if ((fd = open (file, O_RDONLY)) < 0) return ret; if (fstat (fd, &statbuf)) goto cleanup; if (!statbuf.st_size) { ret = 0; goto cleanup; } if (!(begin = mmap (NULL, statbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0))) goto cleanup; madvise (begin, statbuf.st_size, MADV_SEQUENTIAL); ret = di_parser_rfc822_read (begin, statbuf.st_size, info, entry_new, entry_finish, user_data); munmap (begin, statbuf.st_size); cleanup: close (fd); return ret; }
int di_parser_rfc822_write_file | ( | const char * | file, | |
di_parser_info * | fieldinfo, | |||
di_parser_write_entry_next | entry_next, | |||
void * | user_data | |||
) |
Dump a rfc822 formated file
file | filename | |
fieldinfo | parser info | |
entry_next | function which is called to gather the next entry | |
user_data | user_data for parser functions |
References di_slist_node::data, di_slist::head, di_parser_info::list, di_slist_node::next, and di_parser_fieldinfo::write.
{ int nr = 0; const di_parser_fieldinfo *fip; void *act = NULL, *state_data = NULL; di_slist_node *node; FILE *f; char tmpfile[PATH_MAX]; if (!strncmp (file, "-", 1)) { tmpfile[0] = '\0'; f = stdout; } else { snprintf (tmpfile, sizeof (tmpfile), "%s.tmp", file); f = fopen (tmpfile, "w"); } if (!f) return -1; while (1) { act = entry_next (&state_data, user_data); if (!act) break; nr++; for (node = info->list.head; node; node = node->next) { fip = node->data; if (fip->write) fip->write (&act, fip, callback, f, user_data); } fputc ('\n', f); } if (*tmpfile) { fclose (f); if (rename (tmpfile, file)) return -1; } return nr; }