Mail-Box-Parser-C
view release on metacpan or search on metacpan
int boxnr;
CODE:
box = new_mailbox(name);
box->file = fh;
boxnr = take_box_slot(box);
/*fprintf(stderr, "Open with filehande is done.\n");*/
RETVAL = boxnr;
OUTPUT:
RETVAL
#
# close_file
#
void
MBPC_close_file(int boxnr)
PREINIT:
Mailbox * box;
Separator * sep;
CODE:
box = get_box(boxnr);
if(box==NULL) return;
free_box_slot(boxnr);
if(box->file != NULL)
{ fclose(box->file);
box->file = NULL;
}
sep = box->separators;
while(sep!=NULL)
{ Separator * next = sep->next;
Safefree(sep->line);
Safefree(sep);
sep = next;
}
Safefree(box->filename);
Safefree(box);
#
# push_separator
#
void
MBPC_push_separator(int boxnr, char *line_start)
PREINIT:
Mailbox *box;
Separator *sep;
PPCODE:
box = get_box(boxnr);
if(box==NULL) return;
/*fprintf(stderr, "separator %s\n", line_start);*/
New(0, sep, 1, Separator);
sep->length = strlen(line_start);
/*fprintf(stderr, "separator %ld\n", (long)sep->length+1);*/
New(0, sep->line, sep->length+1, char);
strcpy(sep->line, line_start);
sep->next = box->separators;
box->separators = sep;
if(strncmp(sep->line, "From ", sep->length)==0)
box->strip_gt++;
#
# pop_separator
#
SV *
MBPC_pop_separator(int boxnr)
PREINIT:
Mailbox *box;
Separator *old;
CODE:
box = get_box(boxnr);
if(box==NULL) XSRETURN_UNDEF;
old = box->separators;
if(old==NULL) XSRETURN_UNDEF;
if(strncmp(old->line, "From ", old->length)==0)
box->strip_gt--;
/*fprintf(stderr, "pop sep %s\n", old->line);*/
box->separators = old->next;
RETVAL = newSVpv(old->line, old->length);
Safefree(old->line);
Safefree(old);
OUTPUT:
RETVAL
#
# get_position
#
long
MBPC_get_position(int boxnr)
PREINIT:
Mailbox *box;
CODE:
box = get_box(boxnr);
if(box==NULL) RETVAL = 0;
else RETVAL = file_position(box);
OUTPUT:
RETVAL
#
# set_position
#
int
MBPC_set_position(int boxnr, long where)
PREINIT:
Mailbox *box;
CODE:
box = get_box(boxnr);
if(box==NULL) RETVAL = 0;
else RETVAL = goto_position(box, where)==0;
OUTPUT:
RETVAL
#
# read_header
# Returns (begin, end, list-of-fields)
# Where
# begin and end represent file-locations before resp after the header
# each field is a ref to an array with a name/content pair, representing
# one line.
#
void
MBPC_read_header(int boxnr)
PREINIT:
Mailbox * box;
SV * name;
SV * content;
SV * end;
PPCODE:
box = get_box(boxnr);
if(box==NULL || box->file==NULL) return;
XPUSHs(sv_2mortal(newSViv((IV)file_position(box))));
XPUSHs(end = sv_newmortal());
while(read_header_line(box, &name, &content))
{ AV * field = newAV();
av_push(field, name); /* av_push does not increase refcount */
av_push(field, content);
XPUSHs(sv_2mortal(newRV_noinc((SV *)field)));
}
/*fprintf(stderr, "Header has been read\n");*/
sv_setiv(end, (IV)file_position(box));
#
# in_dosmode
#
int
MBPC_in_dosmode(int boxnr)
PREINIT:
Mailbox *box;
CODE:
box = get_box(boxnr);
if(box==NULL)
XSRETURN_UNDEF;
RETVAL = box->dosmode;
OUTPUT:
RETVAL
#
# read_separator
# Return a line with the last defined separator. Empty lines before this
# are permitted, but no other lines.
#
void
MBPC_read_separator(int boxnr)
PREINIT:
Mailbox *box;
Separator *sep;
char *line;
PPCODE:
box = get_box(boxnr);
if(box==NULL)
XSRETURN_EMPTY;
sep = box->separators; /* Never success when there is no sep */
if(sep==NULL)
XSRETURN_EMPTY;
line = get_one_line(box); /* Get first real line. */
while(line!=NULL && line[0]=='\n' && line[1]==EOL)
line = get_one_line(box);
if(line==NULL) /* EOF reached. */
XSRETURN_EMPTY;
if(strncmp(sep->line, line, sep->length)!=0)
{ box->keep_line = 1;
return;
}
EXTEND(SP, 2);
PUSHs(sv_2mortal(newSViv(box->line_start)));
PUSHs(sv_2mortal(newSVpv(line, strlen(line))));
#
# body_as_string
# Read the whole body into one scalar, and return it.
# When lines need a post-processing, we read line-by-line. Otherwise
# we can read the block as a whole.
#
void
MBPC_body_as_string(int boxnr, int expect_chars, int expect_lines)
PREINIT:
Mailbox *box;
SV *result;
char **lines;
int nr_lines = 0;
int nr_chars = 0;
int line_nr;
long begin;
PPCODE:
box = get_box(boxnr);
if(box==NULL)
XSRETURN_EMPTY;
begin = file_position(box);
if(!box->dosmode && !box->strip_gt && expect_chars >=0)
{
long end = begin + expect_chars;
if(is_good_end(box, end))
{ EXTEND(SP, 3);
PUSHs(sv_2mortal(newSViv(begin)));
PUSHs(sv_2mortal(newSViv(file_position(box))));
PUSHs(sv_2mortal(take_scalar(box, begin, end)));
XSRETURN(3);
}
}
lines = read_stripped_lines(box, expect_chars, expect_lines,
&nr_chars, &nr_lines);
if(lines==NULL)
XSRETURN_EMPTY;
/* Join the strings. */
result = newSVpv("",0);
SvGROW(result, (unsigned int)nr_chars);
for(line_nr=0; line_nr<nr_lines; line_nr++)
{ sv_catpv(result, lines[line_nr]);
Safefree(lines[line_nr]);
}
skip_empty_lines(box);
Safefree(lines);
EXTEND(SP, 3);
PUSHs(sv_2mortal(newSViv(begin)));
PUSHs(sv_2mortal(newSViv(file_position(box))));
PUSHs(sv_2mortal(result));
#
# body_as_list
# Read the whole body into a list of scalars.
#
void
MBPC_body_as_list(int boxnr, int expect_chars, int expect_lines)
PREINIT:
Mailbox *box;
char **lines;
int nr_lines = 0;
int nr_chars = 0;
int line_nr;
long begin;
AV * results;
PPCODE:
box = get_box(boxnr);
if(box==NULL)
XSRETURN_EMPTY;
begin = file_position(box);
lines = read_stripped_lines(box, expect_chars, expect_lines,
&nr_chars, &nr_lines);
if(lines==NULL) return;
XPUSHs(sv_2mortal(newSViv(begin)));
XPUSHs(sv_2mortal(newSViv(file_position(box))));
/* Allocating the lines for real. */
results = (AV *)sv_2mortal((SV *)newAV());
av_extend(results, nr_lines);
for(line_nr=0; line_nr<nr_lines; line_nr++)
{ char *line = lines[line_nr];
av_push(results, newSVpv(line, 0));
Safefree(line);
}
XPUSHs(sv_2mortal(newRV((SV *)results)));
skip_empty_lines(box);
Safefree(lines);
#
# body_as_file
# Read the whole body into a file.
#
void
MBPC_body_as_file(int boxnr, FILE *out, int expect_chars, int expect_lines)
PREINIT:
Mailbox *box;
char **lines;
int nr_lines=0;
int nr_chars=0;
int line_nr;
long begin;
PPCODE:
box = get_box(boxnr);
if(box==NULL)
XSRETURN_EMPTY;
begin = file_position(box);
lines = read_stripped_lines(box, expect_chars, expect_lines,
&nr_chars, &nr_lines);
if(lines==NULL)
XSRETURN_EMPTY;
EXTEND(SP, 3);
PUSHs(sv_2mortal(newSViv((IV)begin)));
PUSHs(sv_2mortal(newSViv((IV)file_position(box))));
PUSHs(sv_2mortal(newSViv((IV)nr_lines)));
/* write the lines to file. */
for(line_nr=0; line_nr<nr_lines; line_nr++)
{ fprintf(out, "%s", lines[line_nr]);
Safefree(lines[line_nr]);
}
skip_empty_lines(box);
Safefree(lines);
#
# body_delayed
# Skip the whole body, only counting chars and lines.
#
void
MBPC_body_delayed(int boxnr, int expect_chars, int expect_lines)
PREINIT:
Mailbox *box;
int nr_lines = 0;
int nr_chars = 0;
long begin;
PPCODE:
box = get_box(boxnr);
if(box==NULL)
XSRETURN_EMPTY;
begin = file_position(box);
if(expect_chars >=0)
{
long end = begin + expect_chars;
if(is_good_end(box, end))
{ /* Accept new end */
goto_position(box, end);
EXTEND(SP, 4);
PUSHs(sv_2mortal(newSViv((IV)begin)));
PUSHs(sv_2mortal(newSViv((IV)end)));
PUSHs(sv_2mortal(newSViv((IV)expect_chars)));
PUSHs(sv_2mortal(newSViv((IV)expect_lines)));
skip_empty_lines(box);
XSRETURN(4);
}
}
if(scan_stripped_lines(box, expect_chars, expect_lines,
&nr_chars, &nr_lines))
{ EXTEND(SP, 4);
PUSHs(sv_2mortal(newSViv((IV)begin)));
PUSHs(sv_2mortal(newSViv((IV)file_position(box))));
PUSHs(sv_2mortal(newSViv((IV)nr_chars)));
PUSHs(sv_2mortal(newSViv((IV)nr_lines)));
skip_empty_lines(box);
}
#
# get_filehandle
#
FILE *
MBPC_get_filehandle(int boxnr)
PREINIT:
Mailbox * box;
CODE:
box = get_box(boxnr);
if(box==NULL) XSRETURN_UNDEF;
RETVAL = box->file;
OUTPUT:
RETVAL
( run in 2.195 seconds using v1.01-cache-2.11-cpan-5511b514fd6 )